aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/replace.el
diff options
context:
space:
mode:
authorTino Calancha2020-05-31 12:31:27 +0200
committerTino Calancha2020-05-31 12:31:27 +0200
commitabe7c22da96694ced1bc80ec7eb9eb8a662a568b (patch)
treefe3b5f03fd32b3ab65738a27e0721052cc250940 /lisp/replace.el
parent780f674a82a90c4e3e32583059b498bfa57e4a06 (diff)
downloademacs-abe7c22da96694ced1bc80ec7eb9eb8a662a568b.tar.gz
emacs-abe7c22da96694ced1bc80ec7eb9eb8a662a568b.zip
occur: Add bindings for next-error-no-select
Make the navigation in the occur buffer closer to the navigation in the compilation buffer. Add bindings to navigate the occur matches (Bug#39121). Honor `next-error-highlight' and `next-error-highlight-no-select' when navigating the occurrences. * lisp/replace.el (occur-highlight-regexp, occur-highlight-overlay): New variables. (occur-1): Set `occur-highlight-regexp' to the searched regexp. (occur-goto-locus-delete-o, occur--highlight-occurrence): New defuns. (occur-mode-display-occurrence, occur-mode-goto-occurrence): Use `occur--highlight-occurrence'. (occur-mode-map): Bind n to `next-error-no-select' and p to `previous-error-no-select' * etc/NEWS (Changes in Specialized Modes and Packages in Emacs 28.1): Announce this change. * test/lisp/replace-tests.el (replace-tests-with-highlighted-occurrence): Add helper macro. (occur-highlight-occurrence): Add test.
Diffstat (limited to 'lisp/replace.el')
-rw-r--r--lisp/replace.el72
1 files changed, 71 insertions, 1 deletions
diff --git a/lisp/replace.el b/lisp/replace.el
index f3a71f87fec..69092c16f96 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -757,6 +757,13 @@ which will run faster and will not set the mark or print anything."
757Maximum length of the history list is determined by the value 757Maximum length of the history list is determined by the value
758of `history-length', which see.") 758of `history-length', which see.")
759 759
760(defvar occur-highlight-regexp t
761 "Regexp matching part of visited source lines to highlight temporarily.
762Highlight entire line if t; don't highlight source lines if nil.")
763
764(defvar occur-highlight-overlay nil
765 "Overlay used to temporarily highlight occur matches.")
766
760(defvar occur-collect-regexp-history '("\\1") 767(defvar occur-collect-regexp-history '("\\1")
761 "History of regexp for occur's collect operation") 768 "History of regexp for occur's collect operation")
762 769
@@ -1113,6 +1120,8 @@ a previously found match."
1113 (define-key map "\C-m" 'occur-mode-goto-occurrence) 1120 (define-key map "\C-m" 'occur-mode-goto-occurrence)
1114 (define-key map "o" 'occur-mode-goto-occurrence-other-window) 1121 (define-key map "o" 'occur-mode-goto-occurrence-other-window)
1115 (define-key map "\C-o" 'occur-mode-display-occurrence) 1122 (define-key map "\C-o" 'occur-mode-display-occurrence)
1123 (define-key map "n" 'next-error-no-select)
1124 (define-key map "p" 'previous-error-no-select)
1116 (define-key map "\M-n" 'occur-next) 1125 (define-key map "\M-n" 'occur-next)
1117 (define-key map "\M-p" 'occur-prev) 1126 (define-key map "\M-p" 'occur-prev)
1118 (define-key map "r" 'occur-rename-buffer) 1127 (define-key map "r" 'occur-rename-buffer)
@@ -1261,9 +1270,12 @@ If not invoked by a mouse click, go to occurrence on the current line."
1261 (with-current-buffer (window-buffer (posn-window (event-end event))) 1270 (with-current-buffer (window-buffer (posn-window (event-end event)))
1262 (save-excursion 1271 (save-excursion
1263 (goto-char (posn-point (event-end event))) 1272 (goto-char (posn-point (event-end event)))
1264 (occur-mode-find-occurrence)))))) 1273 (occur-mode-find-occurrence)))))
1274 (regexp occur-highlight-regexp))
1265 (pop-to-buffer (marker-buffer pos)) 1275 (pop-to-buffer (marker-buffer pos))
1266 (goto-char pos) 1276 (goto-char pos)
1277 (let ((end-mk (save-excursion (re-search-forward regexp nil t))))
1278 (occur--highlight-occurrence pos end-mk))
1267 (when buffer (next-error-found buffer (current-buffer))) 1279 (when buffer (next-error-found buffer (current-buffer)))
1268 (run-hooks 'occur-mode-find-occurrence-hook))) 1280 (run-hooks 'occur-mode-find-occurrence-hook)))
1269 1281
@@ -1277,17 +1289,74 @@ If not invoked by a mouse click, go to occurrence on the current line."
1277 (next-error-found buffer (current-buffer)) 1289 (next-error-found buffer (current-buffer))
1278 (run-hooks 'occur-mode-find-occurrence-hook))) 1290 (run-hooks 'occur-mode-find-occurrence-hook)))
1279 1291
1292;; Stolen from compile.el
1293(defun occur-goto-locus-delete-o ()
1294 (delete-overlay occur-highlight-overlay)
1295 ;; Get rid of timer and hook that would try to do this again.
1296 (if (timerp next-error-highlight-timer)
1297 (cancel-timer next-error-highlight-timer))
1298 (remove-hook 'pre-command-hook
1299 #'occur-goto-locus-delete-o))
1300
1301;; Highlight the current visited occurrence.
1302;; Adapted from `compilation-goto-locus'.
1303(defun occur--highlight-occurrence (mk end-mk)
1304 (let ((highlight-regexp occur-highlight-regexp))
1305 (if (timerp next-error-highlight-timer)
1306 (cancel-timer next-error-highlight-timer))
1307 (unless occur-highlight-overlay
1308 (setq occur-highlight-overlay
1309 (make-overlay (point-min) (point-min)))
1310 (overlay-put occur-highlight-overlay 'face 'next-error))
1311 (with-current-buffer (marker-buffer mk)
1312 (save-excursion
1313 (if end-mk (goto-char end-mk) (end-of-line))
1314 (let ((end (point)))
1315 (if mk (goto-char mk) (beginning-of-line))
1316 (if (and (stringp highlight-regexp)
1317 (re-search-forward highlight-regexp end t))
1318 (progn
1319 (goto-char (match-beginning 0))
1320 (move-overlay occur-highlight-overlay
1321 (match-beginning 0) (match-end 0)
1322 (current-buffer)))
1323 (move-overlay occur-highlight-overlay
1324 (point) end (current-buffer)))
1325 (if (or (eq next-error-highlight t)
1326 (numberp next-error-highlight))
1327 ;; We want highlighting: delete overlay on next input.
1328 (add-hook 'pre-command-hook
1329 #'occur-goto-locus-delete-o)
1330 ;; We don't want highlighting: delete overlay now.
1331 (delete-overlay occur-highlight-overlay))
1332 ;; We want highlighting for a limited time:
1333 ;; set up a timer to delete it.
1334 (when (numberp next-error-highlight)
1335 (setq next-error-highlight-timer
1336 (run-at-time next-error-highlight nil
1337 'occur-goto-locus-delete-o))))))
1338 (when (eq next-error-highlight 'fringe-arrow)
1339 ;; We want a fringe arrow (instead of highlighting).
1340 (setq next-error-overlay-arrow-position
1341 (copy-marker (line-beginning-position))))))
1342
1280(defun occur-mode-display-occurrence () 1343(defun occur-mode-display-occurrence ()
1281 "Display in another window the occurrence the current line describes." 1344 "Display in another window the occurrence the current line describes."
1282 (interactive) 1345 (interactive)
1283 (let ((buffer (current-buffer)) 1346 (let ((buffer (current-buffer))
1284 (pos (occur-mode-find-occurrence)) 1347 (pos (occur-mode-find-occurrence))
1348 (regexp occur-highlight-regexp)
1349 (next-error-highlight next-error-highlight-no-select)
1350 (display-buffer-overriding-action
1351 '(nil (inhibit-same-window . t)))
1285 window) 1352 window)
1286 (setq window (display-buffer (marker-buffer pos) t)) 1353 (setq window (display-buffer (marker-buffer pos) t))
1287 ;; This is the way to set point in the proper window. 1354 ;; This is the way to set point in the proper window.
1288 (save-selected-window 1355 (save-selected-window
1289 (select-window window) 1356 (select-window window)
1290 (goto-char pos) 1357 (goto-char pos)
1358 (let ((end-mk (save-excursion (re-search-forward regexp nil t))))
1359 (occur--highlight-occurrence pos end-mk))
1291 (next-error-found buffer (current-buffer)) 1360 (next-error-found buffer (current-buffer))
1292 (run-hooks 'occur-mode-find-occurrence-hook)))) 1361 (run-hooks 'occur-mode-find-occurrence-hook))))
1293 1362
@@ -1612,6 +1681,7 @@ See also `multi-occur'."
1612 (buffer-undo-list t) 1681 (buffer-undo-list t)
1613 (occur--final-pos nil)) 1682 (occur--final-pos nil))
1614 (erase-buffer) 1683 (erase-buffer)
1684 (set (make-local-variable 'occur-highlight-regexp) regexp)
1615 (let ((count 1685 (let ((count
1616 (if (stringp nlines) 1686 (if (stringp nlines)
1617 ;; Treat nlines as a regexp to collect. 1687 ;; Treat nlines as a regexp to collect.