aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/replace.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/replace.el')
-rw-r--r--lisp/replace.el115
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.
1315Set 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.
1309If the face doesn't differ from the default face, 1322If 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.
1365If a match spreads across multiple lines, all those lines are shown. 1386If a match spreads across multiple lines, all those lines are shown.
1366 1387
@@ -1369,9 +1390,17 @@ before if NLINES is negative.
1369NLINES defaults to `list-matching-lines-default-context-lines'. 1390NLINES defaults to `list-matching-lines-default-context-lines'.
1370Interactively it is the prefix arg. 1391Interactively it is the prefix arg.
1371 1392
1393Optional arg REGION, if non-nil, mean restrict search to the
1394specified region. Otherwise search the entire buffer.
1395REGION must be a list of (START . END) positions as returned by
1396`region-bounds'.
1397
1372The lines are shown in a buffer named `*Occur*'. 1398The lines are shown in a buffer named `*Occur*'.
1373It serves as a menu to find any of the occurrences in this buffer. 1399It 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.
1401If `list-matching-lines-jump-to-current-line' is non-nil, then show
1402the current line highlighted with `list-matching-lines-current-line-face'
1403and set point at the first match after such line.
1375 1404
1376If REGEXP contains upper case characters (excluding those preceded by `\\') 1405If REGEXP contains upper case characters (excluding those preceded by `\\')
1377and `search-upper-case' is non-nil, the matching is case-sensitive. 1406and `search-upper-case' is non-nil, the matching is case-sensitive.
@@ -1386,8 +1415,30 @@ For example, providing \"defun\\s +\\(\\S +\\)\" for REGEXP and
1386program. When there is no parenthesized subexpressions in REGEXP 1415program. When there is no parenthesized subexpressions in REGEXP
1387the entire match is collected. In any case the searched buffer 1416the entire match is collected. In any case the searched buffer
1388is not modified." 1417is 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))