diff options
| author | Tino Calancha | 2017-02-02 19:13:05 +0900 |
|---|---|---|
| committer | Tino Calancha | 2017-02-02 19:13:05 +0900 |
| commit | 8e871aef10455eefc34790a9ec011c6fec5e93fe (patch) | |
| tree | 37af01d0672a78348691b9de7560d516c725826a | |
| parent | 141b085674e2945cc0c42bbe35548c368d1b023e (diff) | |
| download | emacs-8e871aef10455eefc34790a9ec011c6fec5e93fe.tar.gz emacs-8e871aef10455eefc34790a9ec011c6fec5e93fe.zip | |
Allow occur command to operate on the region
See discussion in:
https://lists.gnu.org/archive/html/emacs-devel/2016-12/msg01084.html
* lisp/replace.el (occur--region-start, occur--region-end)
(occur--matches-threshold): New variables.
(occur-engine): Use them.
(occur): Idem.
Add optional arg REGION; if non-nil occur applies in that region.
* doc/lispintro/emacs-lisp-intro.texi (Keybindings): Update manual
* doc/emacs/search.texi (Other Repeating Search): Idem.
; etc/NEWS: Add entry for the new feature.
| -rw-r--r-- | doc/emacs/search.texi | 14 | ||||
| -rw-r--r-- | doc/lispintro/emacs-lisp-intro.texi | 8 | ||||
| -rw-r--r-- | etc/NEWS | 3 | ||||
| -rw-r--r-- | lisp/replace.el | 47 |
4 files changed, 55 insertions, 17 deletions
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index b7282589735..2a67619678b 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi | |||
| @@ -1670,8 +1670,9 @@ replacing regexp matches in file names. | |||
| 1670 | Here are some other commands that find matches for a regular | 1670 | Here are some other commands that find matches for a regular |
| 1671 | expression. They all ignore case in matching, if the pattern contains | 1671 | expression. They all ignore case in matching, if the pattern contains |
| 1672 | no upper-case letters and @code{case-fold-search} is non-@code{nil}. | 1672 | no upper-case letters and @code{case-fold-search} is non-@code{nil}. |
| 1673 | Aside from @code{occur} and its variants, all operate on the text from | 1673 | Aside from @code{multi-occur} and @code{multi-occur-in-matching-buffers}, |
| 1674 | point to the end of the buffer, or on the region if it is active. | 1674 | which always search the whole buffer, all operate on the text from point |
| 1675 | to the end of the buffer, or on the region if it is active. | ||
| 1675 | 1676 | ||
| 1676 | @findex list-matching-lines | 1677 | @findex list-matching-lines |
| 1677 | @findex occur | 1678 | @findex occur |
| @@ -1721,11 +1722,10 @@ Prompt for a regexp, and display a list showing each line in the | |||
| 1721 | buffer that contains a match for it. If you type @kbd{M-n} at the | 1722 | buffer that contains a match for it. If you type @kbd{M-n} at the |
| 1722 | prompt, you can reuse search strings from previous incremental | 1723 | prompt, you can reuse search strings from previous incremental |
| 1723 | searches. The text that matched is highlighted using the @code{match} | 1724 | searches. The text that matched is highlighted using the @code{match} |
| 1724 | face. To limit the search to part of the buffer, narrow to that part | 1725 | face. A numeric argument @var{n} specifies that @var{n} lines of |
| 1725 | (@pxref{Narrowing}). A numeric argument @var{n} specifies that | 1726 | context are to be displayed before and after each matching line. |
| 1726 | @var{n} lines of context are to be displayed before and after each | 1727 | The default number of context lines is specified by the variable |
| 1727 | matching line. The default number of context lines is specified by | 1728 | @code{list-matching-lines-default-context-lines}. |
| 1728 | the variable @code{list-matching-lines-default-context-lines}. | ||
| 1729 | 1729 | ||
| 1730 | You can also run @kbd{M-s o} when an incremental search is active; | 1730 | You can also run @kbd{M-s o} when an incremental search is active; |
| 1731 | this uses the current search string. | 1731 | this uses the current search string. |
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index 830c072cf5e..36d767737df 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi | |||
| @@ -17151,9 +17151,11 @@ Here is another keybinding, with a comment: | |||
| 17151 | 17151 | ||
| 17152 | @findex occur | 17152 | @findex occur |
| 17153 | The @code{occur} command shows all the lines in the current buffer | 17153 | The @code{occur} command shows all the lines in the current buffer |
| 17154 | that contain a match for a regular expression. Matching lines are | 17154 | that contain a match for a regular expression. When the region is |
| 17155 | shown in a buffer called @file{*Occur*}. That buffer serves as a menu | 17155 | active, @code{occur} restricts matches to such region. Otherwise it |
| 17156 | to jump to occurrences. | 17156 | uses the entire buffer. |
| 17157 | Matching lines are shown in a buffer called @file{*Occur*}. | ||
| 17158 | That buffer serves as a menu to jump to occurrences. | ||
| 17157 | 17159 | ||
| 17158 | @findex global-unset-key | 17160 | @findex global-unset-key |
| 17159 | @cindex Unbinding key | 17161 | @cindex Unbinding key |
| @@ -311,6 +311,9 @@ substituted by a home directory by writing it as "/foo:/:/~/file". | |||
| 311 | * Editing Changes in Emacs 26.1 | 311 | * Editing Changes in Emacs 26.1 |
| 312 | 312 | ||
| 313 | +++ | 313 | +++ |
| 314 | ** The 'occur' command can now operate on the region. | ||
| 315 | |||
| 316 | +++ | ||
| 314 | ** New bindings for 'query-replace-map'. | 317 | ** New bindings for 'query-replace-map'. |
| 315 | 'undo', undo the last replacement; bound to 'u'. | 318 | 'undo', undo the last replacement; bound to 'u'. |
| 316 | 'undo-all', undo all replacements; bound to 'U'. | 319 | 'undo-all', undo all replacements; bound to 'U'. |
diff --git a/lisp/replace.el b/lisp/replace.el index ff917344453..0a8e4804858 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -1360,7 +1360,12 @@ invoke `occur'." | |||
| 1360 | "*") | 1360 | "*") |
| 1361 | (or unique-p (not interactive-p))))) | 1361 | (or unique-p (not interactive-p))))) |
| 1362 | 1362 | ||
| 1363 | (defun occur (regexp &optional nlines) | 1363 | ;; Region limits when `occur' applies on a region. |
| 1364 | (defvar occur--region-start nil) | ||
| 1365 | (defvar occur--region-end nil) | ||
| 1366 | (defvar occur--matches-threshold nil) | ||
| 1367 | |||
| 1368 | (defun occur (regexp &optional nlines region) | ||
| 1364 | "Show all lines in the current buffer containing a match for REGEXP. | 1369 | "Show all lines in the current buffer containing a match for REGEXP. |
| 1365 | If a match spreads across multiple lines, all those lines are shown. | 1370 | If a match spreads across multiple lines, all those lines are shown. |
| 1366 | 1371 | ||
| @@ -1369,6 +1374,11 @@ before if NLINES is negative. | |||
| 1369 | NLINES defaults to `list-matching-lines-default-context-lines'. | 1374 | NLINES defaults to `list-matching-lines-default-context-lines'. |
| 1370 | Interactively it is the prefix arg. | 1375 | Interactively it is the prefix arg. |
| 1371 | 1376 | ||
| 1377 | Optional arg REGION, if non-nil, mean restrict search to the | ||
| 1378 | specified region. Otherwise search the entire buffer. | ||
| 1379 | REGION must be a list of (START . END) positions as returned by | ||
| 1380 | `region-bounds'. | ||
| 1381 | |||
| 1372 | The lines are shown in a buffer named `*Occur*'. | 1382 | The lines are shown in a buffer named `*Occur*'. |
| 1373 | It serves as a menu to find any of the occurrences in this buffer. | 1383 | It serves as a menu to find any of the occurrences in this buffer. |
| 1374 | \\<occur-mode-map>\\[describe-mode] in that buffer will explain how. | 1384 | \\<occur-mode-map>\\[describe-mode] in that buffer will explain how. |
| @@ -1386,8 +1396,24 @@ For example, providing \"defun\\s +\\(\\S +\\)\" for REGEXP and | |||
| 1386 | program. When there is no parenthesized subexpressions in REGEXP | 1396 | program. When there is no parenthesized subexpressions in REGEXP |
| 1387 | the entire match is collected. In any case the searched buffer | 1397 | the entire match is collected. In any case the searched buffer |
| 1388 | is not modified." | 1398 | is not modified." |
| 1389 | (interactive (occur-read-primary-args)) | 1399 | (interactive |
| 1390 | (occur-1 regexp nlines (list (current-buffer)))) | 1400 | (nconc (occur-read-primary-args) |
| 1401 | (and (use-region-p) (list (region-bounds))))) | ||
| 1402 | (let* ((start (and (caar region) (max (caar region) (point-min)))) | ||
| 1403 | (end (and (cdar region) (min (cdar region) (point-max)))) | ||
| 1404 | (in-region-p (or start end))) | ||
| 1405 | (when in-region-p | ||
| 1406 | (or start (setq start (point-min))) | ||
| 1407 | (or end (setq end (point-max)))) | ||
| 1408 | (let ((occur--region-start start) | ||
| 1409 | (occur--region-end end) | ||
| 1410 | (occur--matches-threshold | ||
| 1411 | (and in-region-p | ||
| 1412 | (line-number-at-pos (min start end))))) | ||
| 1413 | (save-excursion ; If no matches `occur-1' doesn't restore the point. | ||
| 1414 | (and in-region-p (narrow-to-region start end)) | ||
| 1415 | (occur-1 regexp nlines (list (current-buffer))) | ||
| 1416 | (and in-region-p (widen)))))) | ||
| 1391 | 1417 | ||
| 1392 | (defvar ido-ignore-item-temp-list) | 1418 | (defvar ido-ignore-item-temp-list) |
| 1393 | 1419 | ||
| @@ -1545,13 +1571,15 @@ See also `multi-occur'." | |||
| 1545 | (let ((global-lines 0) ;; total count of matching lines | 1571 | (let ((global-lines 0) ;; total count of matching lines |
| 1546 | (global-matches 0) ;; total count of matches | 1572 | (global-matches 0) ;; total count of matches |
| 1547 | (coding nil) | 1573 | (coding nil) |
| 1548 | (case-fold-search case-fold)) | 1574 | (case-fold-search case-fold) |
| 1575 | (in-region-p (and occur--region-start occur--region-end))) | ||
| 1549 | ;; Map over all the buffers | 1576 | ;; Map over all the buffers |
| 1550 | (dolist (buf buffers) | 1577 | (dolist (buf buffers) |
| 1551 | (when (buffer-live-p buf) | 1578 | (when (buffer-live-p buf) |
| 1552 | (let ((lines 0) ;; count of matching lines | 1579 | (let ((lines 0) ;; count of matching lines |
| 1553 | (matches 0) ;; count of matches | 1580 | (matches 0) ;; count of matches |
| 1554 | (curr-line 1) ;; line count | 1581 | (curr-line ;; line count |
| 1582 | (or occur--matches-threshold 1)) | ||
| 1555 | (prev-line nil) ;; line number of prev match endpt | 1583 | (prev-line nil) ;; line number of prev match endpt |
| 1556 | (prev-after-lines nil) ;; context lines of prev match | 1584 | (prev-after-lines nil) ;; context lines of prev match |
| 1557 | (matchbeg 0) | 1585 | (matchbeg 0) |
| @@ -1684,7 +1712,7 @@ See also `multi-occur'." | |||
| 1684 | (let ((beg (point)) | 1712 | (let ((beg (point)) |
| 1685 | end) | 1713 | end) |
| 1686 | (insert (propertize | 1714 | (insert (propertize |
| 1687 | (format "%d match%s%s%s in buffer: %s\n" | 1715 | (format "%d match%s%s%s in buffer: %s%s\n" |
| 1688 | matches (if (= matches 1) "" "es") | 1716 | matches (if (= matches 1) "" "es") |
| 1689 | ;; Don't display the same number of lines | 1717 | ;; Don't display the same number of lines |
| 1690 | ;; and matches in case of 1 match per line. | 1718 | ;; and matches in case of 1 match per line. |
| @@ -1694,7 +1722,12 @@ See also `multi-occur'." | |||
| 1694 | ;; Don't display regexp for multi-buffer. | 1722 | ;; Don't display regexp for multi-buffer. |
| 1695 | (if (> (length buffers) 1) | 1723 | (if (> (length buffers) 1) |
| 1696 | "" (occur-regexp-descr regexp)) | 1724 | "" (occur-regexp-descr regexp)) |
| 1697 | (buffer-name buf)) | 1725 | (buffer-name buf) |
| 1726 | (if in-region-p | ||
| 1727 | (format " within region: %d-%d" | ||
| 1728 | occur--region-start | ||
| 1729 | occur--region-end) | ||
| 1730 | "")) | ||
| 1698 | 'read-only t)) | 1731 | 'read-only t)) |
| 1699 | (setq end (point)) | 1732 | (setq end (point)) |
| 1700 | (add-text-properties beg end `(occur-title ,buf)) | 1733 | (add-text-properties beg end `(occur-title ,buf)) |