From d9c54a06a0883f6be111b498dc44a4fe38c7f49e Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sun, 8 May 2011 01:17:17 -0400 Subject: [PATCH] Perform grep-mode's buffer modifications in a process filter (Bug#7952) * progmodes/grep.el (grep-mode-font-lock-keywords): Remove buffer-changing entries. (grep-filter): New function. (grep-mode): Add it to compilation-filter-hook. * progmodes/compile.el (compilation-filter-hook) (compilation-filter-start): New defvars. (compilation-filter): Call compilation-filter-hook prior to updating the process mark. --- etc/NEWS | 8 ++++++- lisp/ChangeLog | 12 +++++++++++ lisp/progmodes/compile.el | 15 +++++++++++-- lisp/progmodes/grep.el | 44 +++++++++++++++++++-------------------- 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 319f5f8c958..9e9778c6ac1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -377,9 +377,15 @@ $ESHELL nor variable `explicit-shell-file-name' is set. ** comint and modes derived from it use the generic completion code. -** The compile.el mode can be used without font-lock-mode. +** Compilation mode + +*** Compilation mode can be used without font-lock-mode. `compilation-parse-errors-function' is now obsolete. +*** `compilation-filter-start' is let-bound to the start of the text +inserted by the compilation filter function, when calling +compilation-filter-hook. + ** The Landmark game is now invoked with `landmark', not `lm'. ** Prolog mode has been completely revamped, with lots of additional diff --git a/lisp/ChangeLog b/lisp/ChangeLog index d50712503f2..3df4ba354eb 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,15 @@ +2011-05-08 Chong Yidong + + * progmodes/grep.el (grep-mode-font-lock-keywords): Remove + buffer-changing entries. + (grep-filter): New function. + (grep-mode): Add it to compilation-filter-hook. + + * progmodes/compile.el (compilation-filter-hook) + (compilation-filter-start): New defvars. + (compilation-filter): Call compilation-filter-hook prior to + updating the process mark. + 2011-05-08 Stefan Monnier * emacs-lisp/eieio.el (defmethod): Fix typo in last change. diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index ec0830b3b1b..830de7d6244 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -64,6 +64,16 @@ the compilation to be killed, you can use this hook: integer) :group 'compilation) +(defvar compilation-filter-hook nil + "Hook run after `compilation-filter' has inserted a string into the buffer. +It is called with the variable `compilation-filter-start' bound +to the position of the start of the inserted text, and point at +its end.") + +(defvar compilation-filter-start nil + "Start of the text inserted by `compilation-filter'. +This is bound to a buffer position before running `compilation-filter-hook'.") + (defvar compilation-first-column 1 "*This is how compilers number the first column, usually 1 or 0.") @@ -2038,11 +2048,12 @@ and runs `compilation-filter-hook'." ;; If we are inserting at the end of the accessible part of the ;; buffer, keep the inserted text visible. (min (point-min-marker)) - (max (copy-marker (point-max) t))) + (max (copy-marker (point-max) t)) + (compilation-filter-start (marker-position (process-mark proc)))) (unwind-protect (progn (widen) - (goto-char (process-mark proc)) + (goto-char compilation-filter-start) ;; We used to use `insert-before-markers', so that windows with ;; point at `process-mark' scroll along with the output, but we ;; now use window-point-insertion-type instead. diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 58f2ee98f3c..12295efc2d1 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -1,4 +1,4 @@ -;;; grep.el --- run Grep as inferior of Emacs, parse match messages +;;; grep.el --- run `grep' and display the results ;; Copyright (C) 1985-1987, 1993-1999, 2001-2011 ;; Free Software Foundation, Inc. @@ -33,7 +33,7 @@ (defgroup grep nil - "Run grep as inferior of Emacs, parse error messages." + "Run `grep' and display the results." :group 'tools :group 'processes) @@ -399,26 +399,7 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t) (1 grep-error-face) (2 grep-error-face nil t)) - ("^.+?-[0-9]+-.*\n" (0 grep-context-face)) - ;; Highlight grep matches and delete markers. - ;; FIXME: Modifying the buffer text from font-lock is a bad idea! - ("\\(\033\\[01;31m\\)\\(.*?\\)\\(\033\\[[0-9]*m\\)" - ;; Refontification does not work after the markers have been - ;; deleted. So we use the font-lock-face property here as Font - ;; Lock does not clear that. - (2 (list 'face nil 'font-lock-face grep-match-face)) - ((lambda (bound)) - (progn - ;; Delete markers with `replace-match' because it updates - ;; the match-data, whereas `delete-region' would render it obsolete. - (syntax-ppss-flush-cache (match-beginning 0)) - (replace-match "" t t nil 3) - (replace-match "" t t nil 1)))) - ("\033\\[[0-9;]*[mK]" - ;; Delete all remaining escape sequences - ((lambda (bound)) - (syntax-ppss-flush-cache (match-beginning 0)) - (replace-match "" t t)))) + ("^.+?-[0-9]+-.*\n" (0 grep-context-face))) "Additional things to highlight in grep output. This gets tacked on the end of the generated expressions.") @@ -491,6 +472,22 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'." (cons msg code)))) (run-hooks 'grep-setup-hook)) +(defun grep-filter () + "Handle match highlighting escape sequences inserted by the grep process. +This function is called from `compilation-filter-hook'." + (save-excursion + (let ((end (point-marker))) + ;; Highlight grep matches and delete marking sequences. + (goto-char compilation-filter-start) + (while (re-search-forward "\033\\[01;31m\\(.*?\\)\033\\[[0-9]*m" end 1) + (replace-match (propertize (match-string 1) + 'face nil 'font-lock-face grep-match-face) + t t)) + ;; Delete all remaining escape sequences + (goto-char compilation-filter-start) + (while (re-search-forward "\033\\[[0-9;]*[mK]" end 1) + (replace-match "" t t))))) + (defun grep-probe (command args &optional func result) (let (process-file-side-effects) (equal (condition-case nil @@ -697,7 +694,8 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'." grep-regexp-alist) (set (make-local-variable 'compilation-process-setup-function) 'grep-process-setup) - (set (make-local-variable 'compilation-disable-input) t)) + (set (make-local-variable 'compilation-disable-input) t) + (add-hook 'compilation-filter-hook 'grep-filter nil t)) ;;;###autoload -- 2.39.5