diff options
Diffstat (limited to 'lisp/replace.el')
| -rw-r--r-- | lisp/replace.el | 115 |
1 files changed, 105 insertions, 10 deletions
diff --git a/lisp/replace.el b/lisp/replace.el index ff917344453..a825040a979 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -1304,6 +1304,19 @@ If the value is nil, don't highlight the buffer names specially." | |||
| 1304 | :type 'face | 1304 | :type 'face |
| 1305 | :group 'matching) | 1305 | :group 'matching) |
| 1306 | 1306 | ||
| 1307 | (defcustom list-matching-lines-current-line-face 'lazy-highlight | ||
| 1308 | "Face used by \\[list-matching-lines] to highlight the current line." | ||
| 1309 | :type 'face | ||
| 1310 | :group 'matching | ||
| 1311 | :version "26.1") | ||
| 1312 | |||
| 1313 | (defcustom list-matching-lines-jump-to-current-line nil | ||
| 1314 | "If non-nil, \\[list-matching-lines] shows the current line highlighted. | ||
| 1315 | Set the point right after such line when there are matches after it." | ||
| 1316 | :type 'boolean | ||
| 1317 | :group 'matching | ||
| 1318 | :version "26.1") | ||
| 1319 | |||
| 1307 | (defcustom list-matching-lines-prefix-face 'shadow | 1320 | (defcustom list-matching-lines-prefix-face 'shadow |
| 1308 | "Face used by \\[list-matching-lines] to show the prefix column. | 1321 | "Face used by \\[list-matching-lines] to show the prefix column. |
| 1309 | If the face doesn't differ from the default face, | 1322 | If the face doesn't differ from the default face, |
| @@ -1360,7 +1373,15 @@ invoke `occur'." | |||
| 1360 | "*") | 1373 | "*") |
| 1361 | (or unique-p (not interactive-p))))) | 1374 | (or unique-p (not interactive-p))))) |
| 1362 | 1375 | ||
| 1363 | (defun occur (regexp &optional nlines) | 1376 | ;; Region limits when `occur' applies on a region. |
| 1377 | (defvar occur--region-start nil) | ||
| 1378 | (defvar occur--region-end nil) | ||
| 1379 | (defvar occur--matches-threshold nil) | ||
| 1380 | (defvar occur--orig-line nil) | ||
| 1381 | (defvar occur--orig-line-str nil) | ||
| 1382 | (defvar occur--final-pos nil) | ||
| 1383 | |||
| 1384 | (defun occur (regexp &optional nlines region) | ||
| 1364 | "Show all lines in the current buffer containing a match for REGEXP. | 1385 | "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. | 1386 | If a match spreads across multiple lines, all those lines are shown. |
| 1366 | 1387 | ||
| @@ -1369,9 +1390,17 @@ before if NLINES is negative. | |||
| 1369 | NLINES defaults to `list-matching-lines-default-context-lines'. | 1390 | NLINES defaults to `list-matching-lines-default-context-lines'. |
| 1370 | Interactively it is the prefix arg. | 1391 | Interactively it is the prefix arg. |
| 1371 | 1392 | ||
| 1393 | Optional arg REGION, if non-nil, mean restrict search to the | ||
| 1394 | specified region. Otherwise search the entire buffer. | ||
| 1395 | REGION must be a list of (START . END) positions as returned by | ||
| 1396 | `region-bounds'. | ||
| 1397 | |||
| 1372 | The lines are shown in a buffer named `*Occur*'. | 1398 | The lines are shown in a buffer named `*Occur*'. |
| 1373 | It serves as a menu to find any of the occurrences in this buffer. | 1399 | 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. | 1400 | \\<occur-mode-map>\\[describe-mode] in that buffer will explain how. |
| 1401 | If `list-matching-lines-jump-to-current-line' is non-nil, then show | ||
| 1402 | the current line highlighted with `list-matching-lines-current-line-face' | ||
| 1403 | and set point at the first match after such line. | ||
| 1375 | 1404 | ||
| 1376 | If REGEXP contains upper case characters (excluding those preceded by `\\') | 1405 | If REGEXP contains upper case characters (excluding those preceded by `\\') |
| 1377 | and `search-upper-case' is non-nil, the matching is case-sensitive. | 1406 | and `search-upper-case' is non-nil, the matching is case-sensitive. |
| @@ -1386,8 +1415,30 @@ For example, providing \"defun\\s +\\(\\S +\\)\" for REGEXP and | |||
| 1386 | program. When there is no parenthesized subexpressions in REGEXP | 1415 | program. When there is no parenthesized subexpressions in REGEXP |
| 1387 | the entire match is collected. In any case the searched buffer | 1416 | the entire match is collected. In any case the searched buffer |
| 1388 | is not modified." | 1417 | is not modified." |
| 1389 | (interactive (occur-read-primary-args)) | 1418 | (interactive |
| 1390 | (occur-1 regexp nlines (list (current-buffer)))) | 1419 | (nconc (occur-read-primary-args) |
| 1420 | (and (use-region-p) (list (region-bounds))))) | ||
| 1421 | (let* ((start (and (caar region) (max (caar region) (point-min)))) | ||
| 1422 | (end (and (cdar region) (min (cdar region) (point-max)))) | ||
| 1423 | (in-region-p (or start end))) | ||
| 1424 | (when in-region-p | ||
| 1425 | (or start (setq start (point-min))) | ||
| 1426 | (or end (setq end (point-max)))) | ||
| 1427 | (let ((occur--region-start start) | ||
| 1428 | (occur--region-end end) | ||
| 1429 | (occur--matches-threshold | ||
| 1430 | (and in-region-p | ||
| 1431 | (line-number-at-pos (min start end)))) | ||
| 1432 | (occur--orig-line | ||
| 1433 | (line-number-at-pos (point))) | ||
| 1434 | (occur--orig-line-str | ||
| 1435 | (buffer-substring-no-properties | ||
| 1436 | (line-beginning-position) | ||
| 1437 | (line-end-position)))) | ||
| 1438 | (save-excursion ; If no matches `occur-1' doesn't restore the point. | ||
| 1439 | (and in-region-p (narrow-to-region start end)) | ||
| 1440 | (occur-1 regexp nlines (list (current-buffer))) | ||
| 1441 | (and in-region-p (widen)))))) | ||
| 1391 | 1442 | ||
| 1392 | (defvar ido-ignore-item-temp-list) | 1443 | (defvar ido-ignore-item-temp-list) |
| 1393 | 1444 | ||
| @@ -1482,7 +1533,8 @@ See also `multi-occur'." | |||
| 1482 | (occur-mode)) | 1533 | (occur-mode)) |
| 1483 | (let ((inhibit-read-only t) | 1534 | (let ((inhibit-read-only t) |
| 1484 | ;; Don't generate undo entries for creation of the initial contents. | 1535 | ;; Don't generate undo entries for creation of the initial contents. |
| 1485 | (buffer-undo-list t)) | 1536 | (buffer-undo-list t) |
| 1537 | (occur--final-pos nil)) | ||
| 1486 | (erase-buffer) | 1538 | (erase-buffer) |
| 1487 | (let ((count | 1539 | (let ((count |
| 1488 | (if (stringp nlines) | 1540 | (if (stringp nlines) |
| @@ -1534,6 +1586,10 @@ See also `multi-occur'." | |||
| 1534 | (if (= count 0) | 1586 | (if (= count 0) |
| 1535 | (kill-buffer occur-buf) | 1587 | (kill-buffer occur-buf) |
| 1536 | (display-buffer occur-buf) | 1588 | (display-buffer occur-buf) |
| 1589 | (when occur--final-pos | ||
| 1590 | (set-window-point | ||
| 1591 | (get-buffer-window occur-buf 'all-frames) | ||
| 1592 | occur--final-pos)) | ||
| 1537 | (setq next-error-last-buffer occur-buf) | 1593 | (setq next-error-last-buffer occur-buf) |
| 1538 | (setq buffer-read-only t) | 1594 | (setq buffer-read-only t) |
| 1539 | (set-buffer-modified-p nil) | 1595 | (set-buffer-modified-p nil) |
| @@ -1545,19 +1601,26 @@ See also `multi-occur'." | |||
| 1545 | (let ((global-lines 0) ;; total count of matching lines | 1601 | (let ((global-lines 0) ;; total count of matching lines |
| 1546 | (global-matches 0) ;; total count of matches | 1602 | (global-matches 0) ;; total count of matches |
| 1547 | (coding nil) | 1603 | (coding nil) |
| 1548 | (case-fold-search case-fold)) | 1604 | (case-fold-search case-fold) |
| 1605 | (in-region-p (and occur--region-start occur--region-end)) | ||
| 1606 | (multi-occur-p (cdr buffers))) | ||
| 1549 | ;; Map over all the buffers | 1607 | ;; Map over all the buffers |
| 1550 | (dolist (buf buffers) | 1608 | (dolist (buf buffers) |
| 1551 | (when (buffer-live-p buf) | 1609 | (when (buffer-live-p buf) |
| 1552 | (let ((lines 0) ;; count of matching lines | 1610 | (let ((lines 0) ;; count of matching lines |
| 1553 | (matches 0) ;; count of matches | 1611 | (matches 0) ;; count of matches |
| 1554 | (curr-line 1) ;; line count | 1612 | (curr-line ;; line count |
| 1613 | (or occur--matches-threshold 1)) | ||
| 1614 | (orig-line occur--orig-line) | ||
| 1615 | (orig-line-str occur--orig-line-str) | ||
| 1616 | (orig-line-shown-p) | ||
| 1555 | (prev-line nil) ;; line number of prev match endpt | 1617 | (prev-line nil) ;; line number of prev match endpt |
| 1556 | (prev-after-lines nil) ;; context lines of prev match | 1618 | (prev-after-lines nil) ;; context lines of prev match |
| 1557 | (matchbeg 0) | 1619 | (matchbeg 0) |
| 1558 | (origpt nil) | 1620 | (origpt nil) |
| 1559 | (begpt nil) | 1621 | (begpt nil) |
| 1560 | (endpt nil) | 1622 | (endpt nil) |
| 1623 | (finalpt nil) | ||
| 1561 | (marker nil) | 1624 | (marker nil) |
| 1562 | (curstring "") | 1625 | (curstring "") |
| 1563 | (ret nil) | 1626 | (ret nil) |
| @@ -1658,6 +1721,18 @@ See also `multi-occur'." | |||
| 1658 | (nth 0 ret)))) | 1721 | (nth 0 ret)))) |
| 1659 | ;; Actually insert the match display data | 1722 | ;; Actually insert the match display data |
| 1660 | (with-current-buffer out-buf | 1723 | (with-current-buffer out-buf |
| 1724 | (when (and list-matching-lines-jump-to-current-line | ||
| 1725 | (not multi-occur-p) | ||
| 1726 | (not orig-line-shown-p) | ||
| 1727 | (>= curr-line orig-line)) | ||
| 1728 | (insert | ||
| 1729 | (concat | ||
| 1730 | (propertize | ||
| 1731 | (format "%7d:%s" orig-line orig-line-str) | ||
| 1732 | 'face list-matching-lines-current-line-face | ||
| 1733 | 'mouse-face 'mode-line-highlight | ||
| 1734 | 'help-echo "Current line") "\n")) | ||
| 1735 | (setq orig-line-shown-p t finalpt (point))) | ||
| 1661 | (insert data))) | 1736 | (insert data))) |
| 1662 | (goto-char endpt)) | 1737 | (goto-char endpt)) |
| 1663 | (if endpt | 1738 | (if endpt |
| @@ -1671,6 +1746,18 @@ See also `multi-occur'." | |||
| 1671 | (forward-line 1)) | 1746 | (forward-line 1)) |
| 1672 | (goto-char (point-max))) | 1747 | (goto-char (point-max))) |
| 1673 | (setq prev-line (1- curr-line))) | 1748 | (setq prev-line (1- curr-line))) |
| 1749 | ;; Insert original line if haven't done yet. | ||
| 1750 | (when (and list-matching-lines-jump-to-current-line | ||
| 1751 | (not multi-occur-p) | ||
| 1752 | (not orig-line-shown-p)) | ||
| 1753 | (with-current-buffer out-buf | ||
| 1754 | (insert | ||
| 1755 | (concat | ||
| 1756 | (propertize | ||
| 1757 | (format "%7d:%s" orig-line orig-line-str) | ||
| 1758 | 'face list-matching-lines-current-line-face | ||
| 1759 | 'mouse-face 'mode-line-highlight | ||
| 1760 | 'help-echo "Current line") "\n")))) | ||
| 1674 | ;; Flush remaining context after-lines. | 1761 | ;; Flush remaining context after-lines. |
| 1675 | (when prev-after-lines | 1762 | (when prev-after-lines |
| 1676 | (with-current-buffer out-buf | 1763 | (with-current-buffer out-buf |
| @@ -1684,7 +1771,7 @@ See also `multi-occur'." | |||
| 1684 | (let ((beg (point)) | 1771 | (let ((beg (point)) |
| 1685 | end) | 1772 | end) |
| 1686 | (insert (propertize | 1773 | (insert (propertize |
| 1687 | (format "%d match%s%s%s in buffer: %s\n" | 1774 | (format "%d match%s%s%s in buffer: %s%s\n" |
| 1688 | matches (if (= matches 1) "" "es") | 1775 | matches (if (= matches 1) "" "es") |
| 1689 | ;; Don't display the same number of lines | 1776 | ;; Don't display the same number of lines |
| 1690 | ;; and matches in case of 1 match per line. | 1777 | ;; and matches in case of 1 match per line. |
| @@ -1694,13 +1781,21 @@ See also `multi-occur'." | |||
| 1694 | ;; Don't display regexp for multi-buffer. | 1781 | ;; Don't display regexp for multi-buffer. |
| 1695 | (if (> (length buffers) 1) | 1782 | (if (> (length buffers) 1) |
| 1696 | "" (occur-regexp-descr regexp)) | 1783 | "" (occur-regexp-descr regexp)) |
| 1697 | (buffer-name buf)) | 1784 | (buffer-name buf) |
| 1785 | (if in-region-p | ||
| 1786 | (format " within region: %d-%d" | ||
| 1787 | occur--region-start | ||
| 1788 | occur--region-end) | ||
| 1789 | "")) | ||
| 1698 | 'read-only t)) | 1790 | 'read-only t)) |
| 1699 | (setq end (point)) | 1791 | (setq end (point)) |
| 1700 | (add-text-properties beg end `(occur-title ,buf)) | 1792 | (add-text-properties beg end `(occur-title ,buf)) |
| 1701 | (when title-face | 1793 | (when title-face |
| 1702 | (add-face-text-property beg end title-face))) | 1794 | (add-face-text-property beg end title-face)) |
| 1703 | (goto-char (point-min))))))) | 1795 | (goto-char (if finalpt |
| 1796 | (setq occur--final-pos | ||
| 1797 | (cl-incf finalpt (- end beg))) | ||
| 1798 | (point-min))))))))) | ||
| 1704 | ;; Display total match count and regexp for multi-buffer. | 1799 | ;; Display total match count and regexp for multi-buffer. |
| 1705 | (when (and (not (zerop global-lines)) (> (length buffers) 1)) | 1800 | (when (and (not (zerop global-lines)) (> (length buffers) 1)) |
| 1706 | (goto-char (point-min)) | 1801 | (goto-char (point-min)) |