diff options
| author | Tak Ota | 2010-12-03 20:58:06 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2010-12-03 20:58:06 -0500 |
| commit | 15af15e54912d52e1840a257d0e01593e311b6d5 (patch) | |
| tree | 54a3a21774cc9396efed8e8fe82366e6d06abfee | |
| parent | b2e6e5bd1549cdda271e6a5370615cd72c8f4fd6 (diff) | |
| download | emacs-15af15e54912d52e1840a257d0e01593e311b6d5.tar.gz emacs-15af15e54912d52e1840a257d0e01593e311b6d5.zip | |
* lisp/replace.el: Add "collect" feature to occur.
(occur-collect-regexp-history): New var.
(occur-read-primary-args): Return a replace string for nlines, if needed.
(occur): Extend the meaning of nlines.
| -rw-r--r-- | lisp/ChangeLog | 7 | ||||
| -rw-r--r-- | lisp/replace.el | 82 |
2 files changed, 74 insertions, 15 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 141881a17a4..187a36a5f5d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2010-12-04 Tak Ota <Takaaki.Ota@am.sony.com> | ||
| 2 | |||
| 3 | * replace.el: Add "collect" feature to occur. | ||
| 4 | (occur-collect-regexp-history): New var. | ||
| 5 | (occur-read-primary-args): Return a replace string for nlines, if needed. | ||
| 6 | (occur): Extend the meaning of nlines. | ||
| 7 | |||
| 1 | 2010-12-04 Stefan Monnier <monnier@iro.umontreal.ca> | 8 | 2010-12-04 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 9 | ||
| 3 | * progmodes/which-func.el (which-func-ff-hook): Log the error message. | 10 | * progmodes/which-func.el (which-func-ff-hook): Log the error message. |
diff --git a/lisp/replace.el b/lisp/replace.el index baea2820433..28f3a845c2a 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -532,6 +532,9 @@ which will run faster and will not set the mark or print anything." | |||
| 532 | Maximum length of the history list is determined by the value | 532 | Maximum length of the history list is determined by the value |
| 533 | of `history-length', which see.") | 533 | of `history-length', which see.") |
| 534 | 534 | ||
| 535 | (defvar occur-collect-regexp-history '("\\1") | ||
| 536 | "History of regexp for occur's collect operation") | ||
| 537 | |||
| 535 | (defun read-regexp (prompt &optional default-value) | 538 | (defun read-regexp (prompt &optional default-value) |
| 536 | "Read regexp as a string using the regexp history and some useful defaults. | 539 | "Read regexp as a string using the regexp history and some useful defaults. |
| 537 | Prompt for a regular expression with PROMPT (without a colon and | 540 | Prompt for a regular expression with PROMPT (without a colon and |
| @@ -1007,10 +1010,25 @@ which means to discard all text properties." | |||
| 1007 | :version "22.1") | 1010 | :version "22.1") |
| 1008 | 1011 | ||
| 1009 | (defun occur-read-primary-args () | 1012 | (defun occur-read-primary-args () |
| 1010 | (list (read-regexp "List lines matching regexp" | 1013 | (let* ((perform-collect (consp current-prefix-arg)) |
| 1011 | (car regexp-history)) | 1014 | (regexp (read-regexp (if perform-collect |
| 1012 | (when current-prefix-arg | 1015 | "Collect strings matching regexp" |
| 1013 | (prefix-numeric-value current-prefix-arg)))) | 1016 | "List lines matching regexp") |
| 1017 | (car regexp-history)))) | ||
| 1018 | (list regexp | ||
| 1019 | (if perform-collect | ||
| 1020 | ;; Perform collect operation | ||
| 1021 | (if (zerop (regexp-opt-depth regexp)) | ||
| 1022 | ;; No subexpression so collect the entire match. | ||
| 1023 | "\\&" | ||
| 1024 | ;; Get the regexp for collection pattern. | ||
| 1025 | (let ((default (car occur-collect-regexp-history))) | ||
| 1026 | (read-string | ||
| 1027 | (format "Regexp to collect (default %s): " default) | ||
| 1028 | nil 'occur-collect-regexp-history default))) | ||
| 1029 | ;; Otherwise normal occur takes numerical prefix argument. | ||
| 1030 | (when current-prefix-arg | ||
| 1031 | (prefix-numeric-value current-prefix-arg)))))) | ||
| 1014 | 1032 | ||
| 1015 | (defun occur-rename-buffer (&optional unique-p interactive-p) | 1033 | (defun occur-rename-buffer (&optional unique-p interactive-p) |
| 1016 | "Rename the current *Occur* buffer to *Occur: original-buffer-name*. | 1034 | "Rename the current *Occur* buffer to *Occur: original-buffer-name*. |
| @@ -1043,7 +1061,18 @@ It serves as a menu to find any of the occurrences in this buffer. | |||
| 1043 | \\<occur-mode-map>\\[describe-mode] in that buffer will explain how. | 1061 | \\<occur-mode-map>\\[describe-mode] in that buffer will explain how. |
| 1044 | 1062 | ||
| 1045 | If REGEXP contains upper case characters (excluding those preceded by `\\') | 1063 | If REGEXP contains upper case characters (excluding those preceded by `\\') |
| 1046 | and `search-upper-case' is non-nil, the matching is case-sensitive." | 1064 | and `search-upper-case' is non-nil, the matching is case-sensitive. |
| 1065 | |||
| 1066 | When NLINES is a string or when the function is called | ||
| 1067 | interactively with prefix argument without a number (`C-u' alone | ||
| 1068 | as prefix) the matching strings are collected into the `*Occur*' | ||
| 1069 | buffer by using NLINES as a replacement regexp. NLINES may | ||
| 1070 | contain \\& and \\N which convention follows `replace-match'. | ||
| 1071 | For example, providing \"defun\\s +\\(\\S +\\)\" for REGEXP and | ||
| 1072 | \"\\1\" for NLINES collects all the function names in a lisp | ||
| 1073 | program. When there is no parenthesized subexpressions in REGEXP | ||
| 1074 | the entire match is collected. In any case the searched buffers | ||
| 1075 | are not modified." | ||
| 1047 | (interactive (occur-read-primary-args)) | 1076 | (interactive (occur-read-primary-args)) |
| 1048 | (occur-1 regexp nlines (list (current-buffer)))) | 1077 | (occur-1 regexp nlines (list (current-buffer)))) |
| 1049 | 1078 | ||
| @@ -1125,20 +1154,43 @@ See also `multi-occur'." | |||
| 1125 | (setq occur-buf (get-buffer-create buf-name)) | 1154 | (setq occur-buf (get-buffer-create buf-name)) |
| 1126 | 1155 | ||
| 1127 | (with-current-buffer occur-buf | 1156 | (with-current-buffer occur-buf |
| 1128 | (occur-mode) | 1157 | (if (stringp nlines) |
| 1158 | (fundamental-mode) ;; This is for collect opeartion. | ||
| 1159 | (occur-mode)) | ||
| 1129 | (let ((inhibit-read-only t) | 1160 | (let ((inhibit-read-only t) |
| 1130 | ;; Don't generate undo entries for creation of the initial contents. | 1161 | ;; Don't generate undo entries for creation of the initial contents. |
| 1131 | (buffer-undo-list t)) | 1162 | (buffer-undo-list t)) |
| 1132 | (erase-buffer) | 1163 | (erase-buffer) |
| 1133 | (let ((count (occur-engine | 1164 | (let ((count |
| 1134 | regexp active-bufs occur-buf | 1165 | (if (stringp nlines) |
| 1135 | (or nlines list-matching-lines-default-context-lines) | 1166 | ;; Treat nlines as a regexp to collect. |
| 1136 | (if (and case-fold-search search-upper-case) | 1167 | (let ((bufs active-bufs) |
| 1137 | (isearch-no-upper-case-p regexp t) | 1168 | (count 0)) |
| 1138 | case-fold-search) | 1169 | (while bufs |
| 1139 | list-matching-lines-buffer-name-face | 1170 | (with-current-buffer (car bufs) |
| 1140 | nil list-matching-lines-face | 1171 | (save-excursion |
| 1141 | (not (eq occur-excluded-properties t))))) | 1172 | (goto-char (point-min)) |
| 1173 | (while (re-search-forward regexp nil t) | ||
| 1174 | ;; Insert the replacement regexp. | ||
| 1175 | (let ((str (match-substitute-replacement nlines))) | ||
| 1176 | (if str | ||
| 1177 | (with-current-buffer occur-buf | ||
| 1178 | (insert str) | ||
| 1179 | (setq count (1+ count)) | ||
| 1180 | (or (zerop (current-column)) | ||
| 1181 | (insert "\n")))))))) | ||
| 1182 | (setq bufs (cdr bufs))) | ||
| 1183 | count) | ||
| 1184 | ;; Perform normal occur. | ||
| 1185 | (occur-engine | ||
| 1186 | regexp active-bufs occur-buf | ||
| 1187 | (or nlines list-matching-lines-default-context-lines) | ||
| 1188 | (if (and case-fold-search search-upper-case) | ||
| 1189 | (isearch-no-upper-case-p regexp t) | ||
| 1190 | case-fold-search) | ||
| 1191 | list-matching-lines-buffer-name-face | ||
| 1192 | nil list-matching-lines-face | ||
| 1193 | (not (eq occur-excluded-properties t)))))) | ||
| 1142 | (let* ((bufcount (length active-bufs)) | 1194 | (let* ((bufcount (length active-bufs)) |
| 1143 | (diff (- (length bufs) bufcount))) | 1195 | (diff (- (length bufs) bufcount))) |
| 1144 | (message "Searched %d buffer%s%s; %s match%s%s" | 1196 | (message "Searched %d buffer%s%s; %s match%s%s" |