]> code.delx.au - gnu-emacs/blobdiff - lisp/comint.el
(comint-preinput-scroll-to-bottom): Added
[gnu-emacs] / lisp / comint.el
index c4f8630e851d781134dbe67e2a69c97babcee32e..771be5e5838d6c612eca7506f7c9cb81c0e4e279 100644 (file)
 ;;;     comint-input-send      - function         ...
 ;;;     comint-eol-on-send     - boolean          ...
 ;;;     comint-process-echoes   - boolean          ...
-;;;     comint-scroll-to-bottom-on-input - symbol For scroll behaviour
+;;;     comint-scroll-to-bottom-on-input - symbol For scroll behavior
 ;;;     comint-scroll-to-bottom-on-output - symbol    ...
 ;;;     comint-scroll-show-maximum-output - boolean   ...
 ;;;
 ;;; Comint mode non-buffer local variables:
 ;;;     comint-completion-addsuffix - boolean   For file name completion
-;;;     comint-completion-autolist  - boolean       behaviour
+;;;     comint-completion-autolist  - boolean       behavior
 ;;;     comint-completion-recexact  - boolean       ...
 
 (defvar comint-prompt-regexp "^"
@@ -161,7 +161,7 @@ This is a good thing to set in mode hooks.")
 
 (defvar comint-input-autoexpand 'history
   "*If non-nil, expand input command history references on completion.
-This mirrors the optional behaviour of the tcsh (its autoexpand and histlit).
+This mirrors the optional behavior of tcsh (its autoexpand and histlit).
 
 If the value is `input', then the expansion is seen on input.
 If the value is `history', then the expansion is only when inserting
@@ -172,7 +172,7 @@ This variable is buffer-local.")
 
 (defvar comint-input-ignoredups nil
   "*If non-nil, don't add input matching the last on the input ring.
-This mirrors the optional behaviour of the bash.
+This mirrors the optional behavior of bash.
 
 This variable is buffer-local.")
 
@@ -182,29 +182,33 @@ See also `comint-read-input-ring' and `comint-write-input-ring'.
 
 This variable is buffer-local, and is a good thing to set in mode hooks.")
 
-(defvar comint-scroll-to-bottom-on-input 'this
+(defvar comint-scroll-to-bottom-on-input nil
   "*Controls whether input to interpreter causes window to scroll.
 If nil, then do not scroll.  If t or `all', scroll all windows showing buffer.
 If `this', scroll only the selected window.
 
+The default is nil.
+
 See `comint-preinput-scroll-to-bottom'.  This variable is buffer-local.")
 
-(defvar comint-scroll-to-bottom-on-output 'this
+(defvar comint-scroll-to-bottom-on-output nil
   "*Controls whether interpreter output causes window to scroll.
 If nil, then do not scroll.  If t or `all', scroll all windows showing buffer.
 If `this', scroll only the selected window.
 If `others', scroll only those that are not the selected window.
+
+The default is nil.
+
 See variable `comint-scroll-show-maximum-output' and function
 `comint-postoutput-scroll-to-bottom'.  This variable is buffer-local.")
+
 (defvar comint-scroll-show-maximum-output t
   "*Controls how interpreter output causes window to scroll.
 If non-nil, then show the maximum output when the window is scrolled.
+
 See variable `comint-scroll-to-bottom-on-output' and function
 `comint-postoutput-scroll-to-bottom'.  This variable is buffer-local.")
+
 (defvar comint-input-ring-size 32
   "Size of input history ring.")
 
@@ -223,11 +227,6 @@ It returns the text to be submitted as process input.  The default is
 `comint-get-old-input-default', which grabs the current line, and strips off
 leading text matching `comint-prompt-regexp'.")
 
-(defvar comint-filename-prefix ""
-  "Prefix prepended to all absolute file names taken from process input.
-This is used by the completion functions, and by directory tracking in shell
-mode.")
-
 (defvar comint-after-partial-filename-command 'comint-after-partial-filename
   "Function that returns non-nil if point is after a file name.
 By default this is `comint-after-partial-filename'.
@@ -265,9 +264,10 @@ Thus it can, for instance, track cd/pushd/popd commands issued to a shell.")
 Takes one argument, the input.  If non-nil, the input may be saved on the input
 history list.  Default is to save anything that isn't all whitespace.")
 
-(defvar comint-output-filter-hook '(comint-postoutput-scroll-to-bottom) 
+(defvar comint-output-filter-functions '(comint-postoutput-scroll-to-bottom) 
   "Functions to call after output is inserted into the buffer.
-Possible function is `comint-postoutput-scroll-to-bottom'.
+One possible function is `comint-postoutput-scroll-to-bottom'.
+These functions get one argument, a string containing the text just inserted.
 
 This variable is buffer-local.")
 
@@ -309,7 +309,7 @@ This is to work around a bug in Emacs process signalling.")
 (put 'comint-input-ring 'permanent-local t)
 (put 'comint-input-ring-index 'permanent-local t)
 (put 'comint-input-autoexpand 'permanent-local t)
-(put 'comint-output-filter-hook 'permanent-local t)
+(put 'comint-output-filter-functions 'permanent-local t)
 (put 'comint-scroll-to-bottom-on-input 'permanent-local t)
 (put 'comint-scroll-to-bottom-on-output 'permanent-local t)
 (put 'comint-scroll-show-maximum-output 'permanent-local t)
@@ -341,7 +341,7 @@ Commands with no default key bindings include `send-invisible',
 `comint-magic-space'.
 
 Input to, and output from, the subprocess can cause the window to scroll to
-the end of the buffer.  See variables `comint-output-filter-hook',
+the end of the buffer.  See variables `comint-output-filter-functions',
 `comint-scroll-to-bottom-on-input', and `comint-scroll-to-bottom-on-output'.
 
 If you accidentally suspend your process, use \\[comint-continue-subjob]
@@ -388,9 +388,9 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
   (make-local-variable 'comint-scroll-to-bottom-on-input)
   (make-local-variable 'comint-scroll-to-bottom-on-output)
   (make-local-variable 'comint-scroll-show-maximum-output)
-  (make-local-variable 'before-change-function)
-  (setq before-change-function 'comint-preinput-scroll-to-bottom)
-  (make-local-variable 'comint-output-filter-hook)
+  (make-local-variable 'pre-command-hook)
+  (add-hook 'pre-command-hook 'comint-preinput-scroll-to-bottom)
+  (make-local-variable 'comint-output-filter-functions)
   (make-local-variable 'comint-ptyp)
   (make-local-variable 'comint-exec-hook)
   (make-local-variable 'comint-process-echoes)
@@ -426,7 +426,7 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
   ;; Menu bars:
   ;; completion:
   (define-key comint-mode-map [menu-bar completion] 
-    (cons "Completion" (make-sparse-keymap "Completion")))
+    (cons "Complete" (make-sparse-keymap "Complete")))
   (define-key comint-mode-map [menu-bar completion complete-expand]
     '("Expand File Name" . comint-replace-by-expanded-filename))
   (define-key comint-mode-map [menu-bar completion complete-listing]
@@ -443,11 +443,25 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
     '("Complete Before Point" . comint-dynamic-complete))
   ;; Input history:
   (define-key comint-mode-map [menu-bar input] 
-    (cons "Input" (make-sparse-keymap "Input")))
+    (cons "In/Out" (make-sparse-keymap "In/Out")))
+  (define-key comint-mode-map [menu-bar input kill-output]
+    '("Kill Current Output Group" . comint-kill-output))
+  (define-key comint-mode-map [menu-bar input next-prompt]
+    '("Forward Output Group" . comint-next-prompt))
+  (define-key comint-mode-map [menu-bar input previous-prompt]
+    '("Backward Output Group" . comint-previous-prompt))
+  (define-key comint-mode-map [menu-bar input show-maximum-output]
+    '("Show Maximum Output" . comint-show-maximum-output))
+  (define-key comint-mode-map [menu-bar input show-output]
+    '("Show Current Output Group" . comint-show-output))
   (define-key comint-mode-map [menu-bar input kill-input]
     '("Kill Current Input" . comint-kill-input))
   (define-key comint-mode-map [menu-bar input copy-input]
     '("Copy Old Input" . comint-copy-old-input))
+  (define-key comint-mode-map [menu-bar input forward-matching-history]
+    '("Forward Matching Input..." . comint-forward-matching-input))
+  (define-key comint-mode-map [menu-bar input backward-matching-history]
+    '("Backward Matching Input..." . comint-backward-matching-input))
   (define-key comint-mode-map [menu-bar input next-matching-history]
     '("Next Matching Input..." . comint-next-matching-input))
   (define-key comint-mode-map [menu-bar input previous-matching-history]
@@ -464,23 +478,6 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
     '("List Input History" . comint-dynamic-list-input-ring))
   (define-key comint-mode-map [menu-bar input expand-history]
     '("Expand History Before Point" . comint-replace-by-expanded-history))
-  ;; Output:
-  (define-key comint-mode-map [menu-bar output] 
-    (cons "Output" (make-sparse-keymap "Output")))
-  (define-key comint-mode-map [menu-bar output kill-output]
-    '("Kill Current Output Group" . comint-kill-output))
-  (define-key comint-mode-map [menu-bar input forward-matching-history]
-    '("Forward Matching Input..." . comint-forward-matching-input))
-  (define-key comint-mode-map [menu-bar input backward-matching-history]
-    '("Backward Matching Input..." . comint-backward-matching-input))
-  (define-key comint-mode-map [menu-bar output next-prompt]
-    '("Forward Output Group" . comint-next-prompt))
-  (define-key comint-mode-map [menu-bar output previous-prompt]
-    '("Backward Output Group" . comint-previous-prompt))
-  (define-key comint-mode-map [menu-bar output show-maximum-output]
-    '("Show Maximum Output" . comint-show-maximum-output))
-  (define-key comint-mode-map [menu-bar output show-output]
-    '("Show Current Output Group" . comint-show-output))
   ;; Signals
   (define-key comint-mode-map [menu-bar signals]
     (cons "Signals" (make-sparse-keymap "Signals")))
@@ -1103,65 +1100,69 @@ Similarly for Soar, Scheme, etc."
          (set-marker (process-mark proc) (point))
          ;; A kludge to prevent the delay between insert and process output
          ;; affecting the display.  A case for a comint-send-input-hook?
-         (run-hooks 'comint-output-filter-hook)))))
+         (let ((functions comint-output-filter-functions))
+           (while functions
+             (funcall (car functions) (concat input "\n"))
+             (setq functions (cdr functions))))))))
 
 ;; The purpose of using this filter for comint processes
 ;; is to keep comint-last-input-end from moving forward
 ;; when output is inserted.
 (defun comint-output-filter (process string)
   ;; First check for killed buffer
-  (if (not (comint-check-proc (process-buffer process)))
-      (message
-       "comint-output-filter: buffer %s received output with no process"
-       (process-buffer process))
-    (let ((obuf (current-buffer))
-         (opoint nil) (obeg nil) (oend nil))
-      (set-buffer (process-buffer process))
-      (setq opoint (point))
-      (setq obeg (point-min))
-      (setq oend (point-max))
-      (let ((buffer-read-only nil)
-           (nchars (length string))
-           (ostart nil))
-       (widen)
-       (goto-char (process-mark process))
-       (setq ostart (point))
-       (if (<= (point) opoint)
-           (setq opoint (+ opoint nchars)))
-       ;; Insert after old_begv, but before old_zv.
-       (if (< (point) obeg)
-           (setq obeg (+ obeg nchars)))
-       (if (<= (point) oend)
-           (setq oend (+ oend nchars)))
-       (insert-before-markers string)
-       ;; Don't insert initial prompt outside the top of the window.
-       (if (= (window-start (selected-window)) (point))
-           (set-window-start (selected-window) (- (point) (length string))))
-       (if (and comint-last-input-end
-                (marker-buffer comint-last-input-end)
-                (= (point) comint-last-input-end))
-           (set-marker comint-last-input-end (- comint-last-input-end nchars)))
-       (set-marker comint-last-output-start ostart)
-       (set-marker (process-mark process) (point))
-       (force-mode-line-update))
-
-      (narrow-to-region obeg oend)
-      (goto-char opoint)
-      (run-hooks 'comint-output-filter-hook)
-
-      (set-buffer obuf))))
-
-(defun comint-preinput-scroll-to-bottom (beg end)
+  (let ((oprocbuf (process-buffer process)))
+    (if (and oprocbuf (buffer-name oprocbuf))
+       (let ((obuf (current-buffer))
+             (opoint nil) (obeg nil) (oend nil))
+         (set-buffer oprocbuf)
+         (setq opoint (point))
+         (setq obeg (point-min))
+         (setq oend (point-max))
+         (let ((buffer-read-only nil)
+               (nchars (length string))
+               (ostart nil))
+           (widen)
+           (goto-char (process-mark process))
+           (setq ostart (point))
+           (if (<= (point) opoint)
+               (setq opoint (+ opoint nchars)))
+           ;; Insert after old_begv, but before old_zv.
+           (if (< (point) obeg)
+               (setq obeg (+ obeg nchars)))
+           (if (<= (point) oend)
+               (setq oend (+ oend nchars)))
+           (insert-before-markers string)
+           ;; Don't insert initial prompt outside the top of the window.
+           (if (= (window-start (selected-window)) (point))
+               (set-window-start (selected-window) (- (point) (length string))))
+           (if (and comint-last-input-end
+                    (marker-buffer comint-last-input-end)
+                    (= (point) comint-last-input-end))
+               (set-marker comint-last-input-end (- comint-last-input-end nchars)))
+           (set-marker comint-last-output-start ostart)
+           (set-marker (process-mark process) (point))
+           (force-mode-line-update))
+
+         (narrow-to-region obeg oend)
+         (goto-char opoint)
+         (let ((functions comint-output-filter-functions))
+           (while functions
+             (funcall (car functions) string)
+             (setq functions (cdr functions))))
+         (set-buffer obuf)))))
+
+(defun comint-preinput-scroll-to-bottom ()
   "Go to the end of buffer in all windows showing it.
 Movement occurs if point in the selected window is not after the process mark,
 and `this-command' is an insertion command.  Insertion commands recognised
-are `self-insert-command', `yank', `mouse-yank-at-click', and `hilit-yank'.
+are `self-insert-command', `comint-magic-space', `yank', `mouse-yank-at-click',
+and `hilit-yank'.
 Depends on the value of `comint-scroll-to-bottom-on-input'.
 
-This function should be bound to `before-change-function'."
+This function should be a pre-command hook."
   (if (and comint-scroll-to-bottom-on-input
-          (memq this-command '(self-insert-command yank mouse-yank-at-click
-                               hilit-yank)))
+          (memq this-command '(self-insert-command comint-magic-space yank
+                               mouse-yank-at-click hilit-yank)))
       (let* ((selected (selected-window))
             (current (current-buffer))
             (process (get-buffer-process current))
@@ -1179,30 +1180,39 @@ This function should be bound to `before-change-function'."
                     (select-window selected)))))
             'not-minibuf t)))))
 
-(defun comint-postoutput-scroll-to-bottom ()
+(defun comint-postoutput-scroll-to-bottom (string)
   "Go to the end of buffer in all windows showing it.
 Does not scroll if the current line is the last line in the buffer.
 Depends on the value of `comint-scroll-to-bottom-on-output' and
 `comint-scroll-show-maximum-output'.
 
-This function should be bound to `comint-output-filter-hook'."
+This function should be in the list `comint-output-filter-functions'."
   (let* ((selected (selected-window))
         (current (current-buffer))
         (process (get-buffer-process current))
         (scroll comint-scroll-to-bottom-on-output))
-    (if (and process scroll (not (window-minibuffer-p selected)))
+    (if (and process (not (window-minibuffer-p selected)))
        (walk-windows
         (function (lambda (window)
-          (if (and (eq (window-buffer window) current)
-                   (or (eq scroll t) (eq scroll 'all)
-                       (and (eq scroll 'this) (eq selected window))
-                       (and (eq scroll 'others) (not (eq selected window)))))
+          (if (eq (window-buffer window) current)
               (progn
                 (select-window window)
-                (if (not (save-excursion (end-of-line nil) (eobp)))
+                (if (or (eq scroll t) (eq scroll 'all)
+                        ;; Maybe user wants point to jump to the end.
+                        (and (eq scroll 'this) (eq selected window))
+                        (and (eq scroll 'others) (not (eq selected window)))
+                        ;; If point was at the end, keep it at the end.
+                        (and (>= (point)
+                                 (- (process-mark process) (length string)))
+                             (< (point) (process-mark process))))
                     (goto-char (process-mark process)))
-                (if comint-scroll-show-maximum-output
-                    (recenter -1))
+                ;; Optionally scroll so that the text
+                ;; ends at the bottom of the window.
+                (if (and comint-scroll-show-maximum-output
+                         (>= (point) (process-mark process)))
+                    (save-excursion
+                      (goto-char (point-max))
+                      (recenter -1)))
                 (select-window selected)))))
         'not-minibuf t))))
 
@@ -1702,15 +1712,15 @@ See `comint-prompt-regexp'."
 
 (defvar comint-completion-autolist nil
   "*If non-nil, automatically list possiblities on partial completion.
-This mirrors the optional behaviour of the tcsh.")
+This mirrors the optional behavior of tcsh.")
 
 (defvar comint-completion-addsuffix t
   "*If non-nil, add a `/' to completed directories, ` ' to file names.
-This mirrors the optional behaviour of the tcsh.")
+This mirrors the optional behavior of tcsh.")
 
 (defvar comint-completion-recexact nil
   "*If non-nil, use shortest completion if characters cannot be added.
-This mirrors the optional behaviour of the tcsh.
+This mirrors the optional behavior of tcsh.
 
 A non-nil value is useful if `comint-completion-autolist' is non-nil too.")