From a32eea60ac90d367435860fe3a10bf843e6f497c Mon Sep 17 00:00:00 2001 From: Lars Magne Ingebrigtsen Date: Sun, 3 Apr 2016 19:46:50 +0200 Subject: [PATCH] Add `r'/`l' grep command history commands * doc/emacs/building.texi (Grep Searching): Mention the `r'/`l' commands. * lisp/progmodes/grep.el (grep-forward-history): New command. (grep-backward-history): Ditto. (grep--save-buffers): New function. (grep): Use it to record the history. (grep--command-history, grep--history-inhibit) (grep--history-place): New internal variables for the grep history (bug#22627). --- doc/emacs/building.texi | 7 ++++++ etc/NEWS | 5 +++++ lisp/progmodes/grep.el | 47 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi index 03fa0ed83b2..059c7cae89c 100644 --- a/doc/emacs/building.texi +++ b/doc/emacs/building.texi @@ -390,6 +390,13 @@ is called with the file name as the parameter and should return non-nil if the buffer is to be saved), and any other non-@code{nil} value means that all buffers should be saved without asking. + In addition to the normal compilation mode commands (for +next/previous match and so on), two additional commands are available +for accessing the @command{grep} command history. @kbd{l} +(@code{grep-backward-history}) will re-run successively the previous +@command{grep} commands, and @kbd{r} (@code{grep-forward-history} +will go ``forward'' in the command history. + @findex grep-find @findex find-grep The command @kbd{M-x grep-find} (also available as @kbd{M-x diff --git a/etc/NEWS b/etc/NEWS index d878228720e..88e101ee0f0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -57,6 +57,10 @@ has been added. They are: 'file-attribute-type', ** The new function 'buffer-hash' has been added, and can be used to compute a fash, non-consing hash of the contents of a buffer. ++++ +** The grep mode now has a command history that you can access via the +`r' and `l' commands. + --- ** 'fill-paragraph' no longer marks the buffer as changed unless it actually changed something. @@ -1807,6 +1811,7 @@ behavior, set 'diff-switches' to '-c'. dynamically. Any third-party code that changes these templates should be updated accordingly. ++++ ** The grep/rgrep/lgrep functions will now ask about saving files before running. This is controlled by the 'grep-save-buffers' variable. diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 2b44b58f245..7ce787e7284 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -271,6 +271,8 @@ See `compilation-error-screen-columns'" (define-key map "{" 'compilation-previous-file) (define-key map "}" 'compilation-next-file) (define-key map "\t" 'compilation-next-error) + (define-key map "r" 'grep-forward-history) + (define-key map "l" 'grep-backward-history) (define-key map [backtab] 'compilation-previous-error) ;; Set up the menu-bar @@ -309,6 +311,12 @@ See `compilation-error-screen-columns'" (define-key map [menu-bar grep compilation-next-error] '(menu-item "Next Match" next-error :help "Visit the next match and corresponding location")) + (define-key map [menu-bar grep grep-backward-history] + '(menu-item "Previous Command" grep-backward-history + :help "Run the previous grep command from the command history")) + (define-key map [menu-bar grep grep-forward-history] + '(menu-item "Next Command" grep-forward-history + :help "Run the next grep command from the command history")) map) "Keymap for grep buffers. `compilation-minor-mode-map' is a cdr of this.") @@ -744,6 +752,43 @@ This function is called from `compilation-filter-hook'." grep-error-screen-columns) (add-hook 'compilation-filter-hook 'grep-filter nil t)) +(defvar grep--command-history nil) +(defvar grep--history-inhibit nil) +(defvar grep--history-place 0) + +(defun grep--save-history (command) + (unless grep--history-inhibit + (push (cons default-directory command) grep--command-history) + (setq grep--history-place 0) + ;; Don't let the history grow without bounds. + (when (> (length grep--command-history) 100) + (setcdr (nthcdr 100 grep--command-history) nil)))) + +(defun grep-forward-history () + "Go to the next result in the grep command history. +Also see `grep-backward-history'." + (interactive) + (let ((elem (and (> grep--history-place 0) + (nth (1- grep--history-place) grep--command-history))) + (grep--history-inhibit t)) + (unless elem + (error "Nothing further in the command history")) + (cl-decf grep--history-place) + (let ((default-directory (car elem))) + (grep (cdr elem))))) + +(defun grep-backward-history () + "Go to the previous result in the grep command history. +Also see `grep-forward-history'." + (interactive) + (let ((elem (nth (1+ grep--history-place) grep--command-history)) + (grep--history-inhibit t)) + (unless elem + (error "Nothing further in the command history")) + (cl-incf grep--history-place) + (let ((default-directory (car elem))) + (grep (cdr elem))))) + (defun grep--save-buffers () (when grep-save-buffers (save-some-buffers (and (not (eq grep-save-buffers 'ask)) @@ -780,7 +825,7 @@ list is empty)." (if current-prefix-arg default grep-command) 'grep-history (if current-prefix-arg nil default)))))) - + (grep--save-history command-args) (grep--save-buffers) ;; Setting process-setup-function makes exit-message-function work ;; even when async processes aren't supported. -- 2.39.2