]> code.delx.au - gnu-emacs/commitdiff
Use add/remove-function to manipulate process-filters.
authorStefan Monnier <monnier@iro.umontreal.ca>
Sat, 20 Apr 2013 16:24:04 +0000 (12:24 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Sat, 20 Apr 2013 16:24:04 +0000 (12:24 -0400)
* lisp/emacs-lisp/nadvice.el (advice--where-alist): Add :override.
(remove-function): Autoload.

* lisp/comint.el (comint-redirect-original-filter-function): Remove.
(comint-redirect-cleanup, comint-redirect-send-command-to-process):
* lisp/vc/vc-cvs.el (vc-cvs-annotate-process-filter,vc-cvs-annotate-command):
* lisp/progmodes/octave-inf.el (inferior-octave-send-list-and-digest):
* lisp/progmodes/prolog.el (prolog-consult-compile):
* lisp/progmodes/gdb-mi.el (gdb, gdb--check-interpreter):
Use add/remove-function instead.
* lisp/progmodes/gud.el (gud-tooltip-original-filter): Remove.
(gud-tooltip-process-output, gud-tooltip-tips):
Use add/remove-function instead.
* lisp/progmodes/xscheme.el (xscheme-previous-process-state): Remove.
(scheme-interaction-mode, exit-scheme-interaction-mode):
Use add/remove-function instead.

* lisp/vc/vc-dispatcher.el: Use lexical-binding.
(vc--process-sentinel): Rename from vc-process-sentinel.
Change last arg to be the code to run.  Don't use vc-previous-sentinel
and vc-sentinel-commands any more.
(vc-exec-after): Allow code to be a function.  Use add/remove-function.
(compilation-error-regexp-alist, view-old-buffer-read-only): Declare.

lisp/ChangeLog
lisp/comint.el
lisp/emacs-lisp/nadvice.el
lisp/progmodes/gdb-mi.el
lisp/progmodes/gud.el
lisp/progmodes/octave-inf.el
lisp/progmodes/prolog.el
lisp/progmodes/xscheme.el
lisp/vc/vc-cvs.el
lisp/vc/vc-dispatcher.el

index 9bb155b74da920e6e4994c7492231a29137b74b7..8758eb33e77f765211b591cc7c43eff0966cfcaa 100644 (file)
@@ -1,7 +1,33 @@
+2013-04-20  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * emacs-lisp/nadvice.el (advice--where-alist): Add :override.
+       (remove-function): Autoload.
+
+       * comint.el (comint-redirect-original-filter-function): Remove.
+       (comint-redirect-cleanup, comint-redirect-send-command-to-process):
+       * vc/vc-cvs.el (vc-cvs-annotate-process-filter,vc-cvs-annotate-command):
+       * progmodes/octave-inf.el (inferior-octave-send-list-and-digest):
+       * progmodes/prolog.el (prolog-consult-compile):
+       * progmodes/gdb-mi.el (gdb, gdb--check-interpreter):
+       Use add/remove-function instead.
+       * progmodes/gud.el (gud-tooltip-original-filter): Remove.
+       (gud-tooltip-process-output, gud-tooltip-tips):
+       Use add/remove-function instead.
+       * progmodes/xscheme.el (xscheme-previous-process-state): Remove.
+       (scheme-interaction-mode, exit-scheme-interaction-mode):
+       Use add/remove-function instead.
+
+       * vc/vc-dispatcher.el: Use lexical-binding.
+       (vc--process-sentinel): Rename from vc-process-sentinel.
+       Change last arg to be the code to run.  Don't use vc-previous-sentinel
+       and vc-sentinel-commands any more.
+       (vc-exec-after): Allow code to be a function.  Use add/remove-function.
+       (compilation-error-regexp-alist, view-old-buffer-read-only): Declare.
+
 2013-04-19 Masatake YAMATO  <yamato@redhat.com>
 
-       * progmodes/sh-script.el (sh-imenu-generic-expression): Handle
-       function names with a single character.   (Bug#11182)
+       * progmodes/sh-script.el (sh-imenu-generic-expression):
+       Handle function names with a single character.   (Bug#11182)
 
 2013-04-19  Dima Kogan  <dima@secretsauce.net>    (tiny change)
 
index 93db4e24f2a13b9d0362e46947d9a9bbe595322a..13a38e6e16e12e1872e311e978db739cb2bc7e04 100644 (file)
@@ -3491,11 +3491,6 @@ buffer.  The idea is that this regular expression should match a prompt
 string, and that there ought to be at least one copy of your prompt string
 in the process buffer already.")
 
-(defvar comint-redirect-original-filter-function nil
-  "The process filter that was in place when redirection is started.
-When redirection is completed, the process filter is restored to
-this value.")
-
 (defvar comint-redirect-subvert-readonly nil
   "Non-nil means `comint-redirect' can insert into read-only buffers.
 This works by binding `inhibit-read-only' around the insertion.
@@ -3558,8 +3553,8 @@ and does not normally need to be invoked by the end user or programmer."
   ;; Release the last redirected string
   (setq comint-redirect-previous-input-string nil)
   ;; Restore the process filter
-  (set-process-filter (get-buffer-process (current-buffer))
-                     comint-redirect-original-filter-function)
+  (remove-function (process-filter (get-buffer-process (current-buffer)))
+                   #'comint-redirect-filter)
   ;; Restore the mode line
   (setq mode-line-process comint-redirect-original-mode-line-process)
   ;; Set the completed flag
@@ -3701,10 +3696,8 @@ If NO-DISPLAY is non-nil, do not show the output buffer."
        comint-prompt-regexp             ; Finished Regexp
        echo)                            ; Echo input
 
-      ;; Set the filter
-      (setq comint-redirect-original-filter-function ; Save the old filter
-           (process-filter proc))
-      (set-process-filter proc 'comint-redirect-filter)
+      ;; Set the filter.
+      (add-function :override (process-filter proc) #'comint-redirect-filter)
 
       ;; Send the command
       (process-send-string (current-buffer) (concat command "\n"))
index a3dfb0326e6a1855e88b392aa73347cb01ec14df..12166553a143cce1022c5814faaf480a18901cc3 100644 (file)
@@ -41,6 +41,7 @@
   '((:around "\300\301\302\003#\207" 5)
     (:before "\300\301\002\"\210\300\302\002\"\207" 4)
     (:after "\300\302\002\"\300\301\003\"\210\207" 5)
+    (:override "\300\301\ 2\"\207" 4)
     (:after-until "\300\302\002\"\206\013\000\300\301\002\"\207" 4)
     (:after-while "\300\302\002\"\205\013\000\300\301\002\"\207" 4)
     (:before-until "\300\301\002\"\206\013\000\300\302\002\"\207" 4)
@@ -228,6 +229,7 @@ call OLDFUN here:
 `:before'      (lambda (&rest r) (apply FUNCTION r) (apply OLDFUN r))
 `:after'       (lambda (&rest r) (prog1 (apply OLDFUN r) (apply FUNCTION r)))
 `:around'      (lambda (&rest r) (apply FUNCTION OLDFUN r))
+`:override'    (lambda (&rest r) (apply FUNCTION r))
 `:before-while'        (lambda (&rest r) (and (apply FUNCTION r) (apply OLDFUN r)))
 `:before-until'        (lambda (&rest r) (or  (apply FUNCTION r) (apply OLDFUN r)))
 `:after-while' (lambda (&rest r) (and (apply OLDFUN r) (apply FUNCTION r)))
@@ -263,6 +265,7 @@ is also interactive.  There are 3 cases:
     (setf (gv-deref ref)
           (advice--make where function (gv-deref ref) props))))
 
+;;;###autoload
 (defmacro remove-function (place function)
   "Remove the FUNCTION piece of advice from PLACE.
 If FUNCTION was not added to PLACE, do nothing.
index f5e1abdd546644f8f7d8c467472caa0f440bca84..8e15ec6584e58369759e8707791d240ea9fbc286 100644 (file)
@@ -574,21 +574,20 @@ NOARG must be t when this macro is used outside `gud-def'"
     (concat (gdb-gud-context-command ,cmd1 ,noall) " " ,cmd2)
     ,(when (not noarg) 'arg)))
 
-(defun gdb--check-interpreter (proc string)
+(defun gdb--check-interpreter (filter proc string)
   (unless (zerop (length string))
-    (let ((filter (process-get proc 'gud-normal-filter)))
-      (set-process-filter proc filter)
-      (unless (memq (aref string 0) '(?^ ?~ ?@ ?& ?* ?=))
-        ;; Apparently we're not running with -i=mi.
-        (let ((msg "Error: you did not specify -i=mi on GDB's command line!"))
-          (message msg)
-          (setq string (concat (propertize msg 'font-lock-face 'error)
-                               "\n" string)))
-        ;; Use the old gud-gbd filter, not because it works, but because it
-        ;; will properly display GDB's answers rather than hanging waiting for
-        ;; answers that aren't coming.
-        (set (make-local-variable 'gud-marker-filter) #'gud-gdb-marker-filter))
-      (funcall filter proc string))))
+    (remove-function (process-filter proc) #'gdb--check-interpreter)
+    (unless (memq (aref string 0) '(?^ ?~ ?@ ?& ?* ?=))
+      ;; Apparently we're not running with -i=mi.
+      (let ((msg "Error: you did not specify -i=mi on GDB's command line!"))
+        (message msg)
+        (setq string (concat (propertize msg 'font-lock-face 'error)
+                             "\n" string)))
+      ;; Use the old gud-gbd filter, not because it works, but because it
+      ;; will properly display GDB's answers rather than hanging waiting for
+      ;; answers that aren't coming.
+      (set (make-local-variable 'gud-marker-filter) #'gud-gdb-marker-filter))
+    (funcall filter proc string)))
 
 (defvar gdb-control-level 0)
 
@@ -662,8 +661,7 @@ detailed description of this mode.
   ;; Setup a temporary process filter to warn when GDB was not started
   ;; with -i=mi.
   (let ((proc (get-buffer-process gud-comint-buffer)))
-    (process-put proc 'gud-normal-filter (process-filter proc))
-    (set-process-filter proc #'gdb--check-interpreter))
+    (add-function :around (process-filter proc) #'gdb--check-interpreter))
 
   (set (make-local-variable 'gud-minor-mode) 'gdbmi)
   (set (make-local-variable 'gdb-control-level) 0)
index 4e31c5e827c34cb8844c60e0442ee8978764df5c..6076f88dea60e7a09dc12d3565dee132de6dbc90 100644 (file)
@@ -3387,9 +3387,6 @@ ACTIVATEP non-nil means activate mouse motion events."
 
 ;;; Tips for `gud'
 
-(defvar gud-tooltip-original-filter nil
-  "Process filter to restore after GUD output has been received.")
-
 (defvar gud-tooltip-dereference nil
   "Non-nil means print expressions with a `*' in front of them.
 For C this would dereference a pointer expression.")
@@ -3423,7 +3420,7 @@ With arg, dereference expr if ARG is positive, otherwise do not dereference."
 ; gdb-mi.el gets round this problem.
 (defun gud-tooltip-process-output (process output)
   "Process debugger output and show it in a tooltip window."
-  (set-process-filter process gud-tooltip-original-filter)
+  (remove-function (process-filter process) #'gud-tooltip-process-output)
   (tooltip-show (tooltip-strip-prompt process output)
                (or gud-tooltip-echo-area tooltip-use-echo-area)))
 
@@ -3490,8 +3487,8 @@ so they have been disabled."))
                       (gdb-input
                       (concat cmd "\n")
                       `(lambda () (gdb-tooltip-print ,expr))))
-                 (setq gud-tooltip-original-filter (process-filter process))
-                 (set-process-filter process 'gud-tooltip-process-output)
+                  (add-function :override (process-filter process)
+                                #'gud-tooltip-process-output)
                  (gud-basic-call cmd))
                expr))))))))
 
index de7ca32befe250c88f72afb67a1c8476def7fba3..4a227db71648ce9e612965006ae1b9725c846929 100644 (file)
@@ -348,9 +348,9 @@ the rest to `inferior-octave-output-string'."
 The elements of LIST have to be strings and are sent one by one.  All
 output is passed to the filter `inferior-octave-output-digest'."
   (let* ((proc inferior-octave-process)
-        (filter (process-filter proc))
         string)
-    (set-process-filter proc 'inferior-octave-output-digest)
+    (add-function :override (process-filter proc)
+                  #'inferior-octave-output-digest)
     (setq inferior-octave-output-list nil)
     (unwind-protect
        (while (setq string (car list))
@@ -360,7 +360,8 @@ output is passed to the filter `inferior-octave-output-digest'."
          (while inferior-octave-receive-in-progress
            (accept-process-output proc))
          (setq list (cdr list)))
-      (set-process-filter proc filter))))
+      (remove-function (process-filter proc)
+                       #'inferior-octave-output-digest))))
 
 (defun inferior-octave-directory-tracker (string)
   "Tracks `cd' commands issued to the inferior Octave process.
index 85e4172c8fe003da6eb5f9d737caa90c9daa49b3..8971e97a44e6abe5eb29d66a6b6bc3f09abc7ae9 100644 (file)
@@ -1770,7 +1770,8 @@ This function must be called from the source code buffer."
                                              real-file))
     (with-current-buffer buffer
       (goto-char (point-max))
-      (set-process-filter process 'prolog-consult-compile-filter)
+      (add-function :override (process-filter process)
+                    #'prolog-consult-compile-filter)
       (process-send-string "prolog" command-string)
       ;; (prolog-build-prolog-command compilep file real-file first-line))
       (while (and prolog-process-flag
@@ -1781,7 +1782,8 @@ This function must be called from the source code buffer."
       (insert (if compilep
                   "\nCompilation finished.\n"
                 "\nConsulted.\n"))
-      (set-process-filter process old-filter))))
+      (remove-function (process-filter process)
+                       #'prolog-consult-compile-filter))))
 
 (defvar compilation-error-list)
 
index 2ad44b4b1c84647b3f6a802b43077e5d78a8cd7f..37c3cd37a6c9c0de7eb2188c43d454402b3ba342 100644 (file)
@@ -35,7 +35,6 @@
 ;;;; Internal Variables
 
 (defvar xscheme-previous-mode)
-(defvar xscheme-previous-process-state)
 (defvar xscheme-last-input-end)
 
 (defvar xscheme-process-command-line nil
@@ -388,8 +387,6 @@ with no args, if that value is non-nil.
   (if (not preserve)
       (let ((previous-mode major-mode))
         (kill-all-local-variables)
-        (make-local-variable 'xscheme-process-name)
-        (make-local-variable 'xscheme-previous-process-state)
         (make-local-variable 'xscheme-runlight-string)
         (make-local-variable 'xscheme-runlight)
         (set (make-local-variable 'xscheme-previous-mode) previous-mode)
@@ -397,35 +394,29 @@ with no args, if that value is non-nil.
           (set (make-local-variable 'xscheme-buffer-name) (buffer-name buffer))
           (set (make-local-variable 'xscheme-last-input-end) (make-marker))
           (let ((process (get-buffer-process buffer)))
-            (if process
-                (progn
-                  (setq xscheme-process-name (process-name process))
-                  (setq xscheme-previous-process-state
-                        (cons (process-filter process)
-                              (process-sentinel process)))
-                 (xscheme-process-filter-initialize t)
-                 (xscheme-mode-line-initialize xscheme-buffer-name)
-                 (set-process-sentinel process 'xscheme-process-sentinel)
-                 (set-process-filter process 'xscheme-process-filter))
-                (setq xscheme-previous-process-state (cons nil nil)))))))
+            (when process
+              (setq-local xscheme-process-name (process-name process))
+              ;; FIXME: Use add-function!
+              (xscheme-process-filter-initialize t)
+              (xscheme-mode-line-initialize xscheme-buffer-name)
+              (add-function :override (process-sentinel process)
+                            #'xscheme-process-sentinel)
+              (add-function :override (process-filter process)
+                            #'xscheme-process-filter))))))
   (scheme-interaction-mode-initialize)
   (scheme-mode-variables)
   (run-mode-hooks 'scheme-mode-hook 'scheme-interaction-mode-hook))
 
 (defun exit-scheme-interaction-mode ()
-  "Take buffer out of scheme interaction mode"
+  "Take buffer out of scheme interaction mode."
   (interactive)
   (if (not (derived-mode-p 'scheme-interaction-mode))
       (error "Buffer not in scheme interaction mode"))
-  (let ((previous-state xscheme-previous-process-state))
-    (funcall xscheme-previous-mode)
-    (let ((process (get-buffer-process (current-buffer))))
-      (if process
-         (progn
-           (if (eq (process-filter process) 'xscheme-process-filter)
-               (set-process-filter process (car previous-state)))
-           (if (eq (process-sentinel process) 'xscheme-process-sentinel)
-               (set-process-sentinel process (cdr previous-state))))))))
+  (funcall xscheme-previous-mode)
+  (let ((process (get-buffer-process (current-buffer))))
+    (when process
+      (remove-function (process-sentinel process) #'xscheme-process-sentinel)
+      (remove-function (process-filter process) #'xscheme-process-filter))))
 
 (defvar scheme-interaction-mode-commands-alist nil)
 (defvar scheme-interaction-mode-map nil)
index 407e691439bdea0f25b2afda823708f59c76516a..334683898be1e138da35f016ffcafccf71f0fb6d 100644 (file)
@@ -562,14 +562,13 @@ Will fail unless you have administrative privileges on the repo."
 
 (defconst vc-cvs-annotate-first-line-re "^[0-9]")
 
-(defun vc-cvs-annotate-process-filter (process string)
+(defun vc-cvs-annotate-process-filter (filter process string)
   (setq string (concat (process-get process 'output) string))
   (if (not (string-match vc-cvs-annotate-first-line-re string))
       ;; Still waiting for the first real line.
       (process-put process 'output string)
-    (let ((vc-filter (process-get process 'vc-filter)))
-      (set-process-filter process vc-filter)
-      (funcall vc-filter process (substring string (match-beginning 0))))))
+    (remove-function (process-filter process) #'vc-cvs-annotate-process-filter)
+    (funcall filter process (substring string (match-beginning 0)))))
 
 (defun vc-cvs-annotate-command (file buffer &optional revision)
   "Execute \"cvs annotate\" on FILE, inserting the contents in BUFFER.
@@ -583,9 +582,8 @@ Optional arg REVISION is a revision to annotate from."
   (let ((proc (get-buffer-process buffer)))
     (if proc
         ;; If running asynchronously, use a process filter.
-        (progn
-          (process-put proc 'vc-filter (process-filter proc))
-          (set-process-filter proc 'vc-cvs-annotate-process-filter))
+        (add-function :around (process-filter proc)
+                      #'vc-cvs-annotate-process-filter)
       (with-current-buffer buffer
         (goto-char (point-min))
         (re-search-forward vc-cvs-annotate-first-line-re)
index ed61adec1fe990af3e9f5e21222b0b55b076d302..309cf50404c9d188e5f4c37717041e71c5c11ab1 100644 (file)
@@ -1,4 +1,4 @@
-;;; vc-dispatcher.el -- generic command-dispatcher facility.
+;;; vc-dispatcher.el -- generic command-dispatcher facility.  -*- lexical-binding: t -*-
 
 ;; Copyright (C) 2008-2013 Free Software Foundation, Inc.
 
@@ -182,32 +182,29 @@ Another is that undo information is not kept."
 
 (defvar vc-sentinel-movepoint)          ;Dynamically scoped.
 
-(defun vc-process-sentinel (p s)
-  (let ((previous (process-get p 'vc-previous-sentinel))
-        (buf (process-buffer p)))
+(defun vc--process-sentinel (p code)
+  (let ((buf (process-buffer p)))
     ;; Impatient users sometime kill "slow" buffers; check liveness
     ;; to avoid "error in process sentinel: Selecting deleted buffer".
     (when (buffer-live-p buf)
-      (when previous (funcall previous p s))
       (with-current-buffer buf
         (setq mode-line-process
               (let ((status (process-status p)))
                 ;; Leave mode-line uncluttered, normally.
                 (unless (eq 'exit status)
                   (format " (%s)" status))))
-        (let (vc-sentinel-movepoint)
+        (let (vc-sentinel-movepoint
+              (m (process-mark p)))
           ;; Normally, we want async code such as sentinels to not move point.
           (save-excursion
-            (goto-char (process-mark p))
-            (let ((cmds (process-get p 'vc-sentinel-commands)))
-              (process-put p 'vc-sentinel-commands nil)
-              (dolist (cmd cmds)
+            (goto-char m)
                 ;; Each sentinel may move point and the next one should be run
                 ;; at that new point.  We could get the same result by having
                 ;; each sentinel read&set process-mark, but since `cmd' needs
                 ;; to work both for async and sync processes, this would be
                 ;; difficult to achieve.
-                (vc-exec-after cmd))))
+            (vc-exec-after code)
+            (move-marker m (point)))
           ;; But sometimes the sentinels really want to move point.
           (when vc-sentinel-movepoint
            (let ((win (get-buffer-window (current-buffer) 0)))
@@ -226,7 +223,9 @@ Another is that undo information is not kept."
 (defun vc-exec-after (code)
   "Eval CODE when the current buffer's process is done.
 If the current buffer has no process, just evaluate CODE.
-Else, add CODE to the process' sentinel."
+Else, add CODE to the process' sentinel.
+CODE can be either a function of no arguments, or an expression
+to evaluate."
   (let ((proc (get-buffer-process (current-buffer))))
     (cond
      ;; If there's no background process, just execute the code.
@@ -237,20 +236,14 @@ Else, add CODE to the process' sentinel."
      ((or (null proc) (eq (process-status proc) 'exit))
       ;; Make sure we've read the process's output before going further.
       (when proc (accept-process-output proc))
-      (eval code))
+      (if (functionp code) (funcall code) (eval code)))
      ;; If a process is running, add CODE to the sentinel
      ((eq (process-status proc) 'run)
       (vc-set-mode-line-busy-indicator)
-      (let ((previous (process-sentinel proc)))
-        (unless (eq previous 'vc-process-sentinel)
-          (process-put proc 'vc-previous-sentinel previous))
-        (set-process-sentinel proc 'vc-process-sentinel))
-      (process-put proc 'vc-sentinel-commands
-                   ;; We keep the code fragments in the order given
-                   ;; so that vc-diff-finish's message shows up in
-                   ;; the presence of non-nil vc-command-messages.
-                   (append (process-get proc 'vc-sentinel-commands)
-                           (list code))))
+      (letrec ((fun (lambda (p _msg)
+                      (remove-function (process-sentinel p) fun)
+                      (vc--process-sentinel p code))))
+        (add-function :after (process-sentinel proc) fun)))
      (t (error "Unexpected process state"))))
   nil)
 
@@ -388,6 +381,8 @@ Display the buffer in some window, but don't select it."
        (set-window-start window new-window-start))
     buffer))
 
+(defvar compilation-error-regexp-alist)
+
 (defun vc-compilation-mode (backend)
   "Setup `compilation-mode' after with the appropriate `compilation-error-regexp-alist'."
   (let* ((error-regexp-alist
@@ -479,7 +474,7 @@ Used by `vc-restore-buffer-context' to later restore the context."
                         (vc-position-context (mark-marker))))
        ;; Make the right thing happen in transient-mark-mode.
        (mark-active nil))
-    (list point-context mark-context nil)))
+    (list point-context mark-context)))
 
 (defun vc-restore-buffer-context (context)
   "Restore point/mark, and reparse any affected compilation buffers.
@@ -518,6 +513,8 @@ ARG and NO-CONFIRM are passed on to `revert-buffer'."
 (make-variable-buffer-local 'vc-mode-line-hook)
 (put 'vc-mode-line-hook 'permanent-local t)
 
+(defvar view-old-buffer-read-only)
+
 (defun vc-resynch-window (file &optional keep noquery reset-vc-info)
   "If FILE is in the current buffer, either revert or unvisit it.
 The choice between revert (to see expanded keywords) and unvisit