;;; comint.el --- general command interpreter in a window stuff -*- lexical-binding: t -*-
-;; Copyright (C) 1988, 1990, 1992-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1988, 1990, 1992-2013 Free Software Foundation, Inc.
;; Author: Olin Shivers <shivers@cs.cmu.edu>
;; Simon Marshall <simon@gnu.org>
`comint-kill-whole-line' or `comint-kill-region' with no
narrowing in effect. This way you will be certain that none of
the remaining prompts will be accidentally messed up. You may
-wish to put something like the following in your `.emacs' file:
+wish to put something like the following in your init file:
\(add-hook 'comint-mode-hook
(lambda ()
If there are no search errors, this function displays an overlay with
the Isearch prompt which replaces the original comint prompt.
Otherwise, it displays the standard Isearch message returned from
-`isearch-message'."
+the function `isearch-message'."
(if (not (and isearch-success (not isearch-error)))
;; Use standard function `isearch-message' when not in comint prompt,
;; or search fails, or has an error (like incomplete regexp).
(let ((echo-len (- comint-last-input-end
comint-last-input-start)))
;; Wait for all input to be echoed:
- (while (and (accept-process-output proc)
- (> (+ comint-last-input-end echo-len)
+ (while (and (> (+ comint-last-input-end echo-len)
(point-max))
+ (accept-process-output proc)
(zerop
(compare-buffer-substrings
nil comint-last-input-start
(if (and comint-scroll-to-bottom-on-input
(memq this-command '(self-insert-command comint-magic-space yank
hilit-yank)))
- (let* ((selected (selected-window))
- (current (current-buffer))
+ (let* ((current (current-buffer))
(process (get-buffer-process current))
(scroll comint-scroll-to-bottom-on-input))
(if (and process (< (point) (process-mark process)))
(lambda (window)
(if (and (eq (window-buffer window) current)
(or (eq scroll t) (eq scroll 'all)))
- (progn
- (select-window window)
- (goto-char (point-max))
- (select-window selected))))
+ (with-selected-window window
+ (goto-char (point-max)))))
nil t))))))
(defvar follow-mode)
((bound-and-true-p follow-mode)
(follow-comint-scroll-to-bottom))
(t
- (let ((selected (selected-window)))
- (dolist (w (get-buffer-window-list current nil t))
- (select-window w)
- (unwind-protect
- (progn
- (comint-adjust-point selected)
- ;; Optionally scroll to the bottom of the window.
- (and comint-scroll-show-maximum-output
- (eobp)
- (recenter (- -1 scroll-margin))))
- (select-window selected))))))
+ (dolist (w (get-buffer-window-list current nil t))
+ (comint-adjust-window-point w process)
+ ;; Optionally scroll to the bottom of the window.
+ (and comint-scroll-show-maximum-output
+ (eq (window-point w) (point-max))
+ (with-selected-window w
+ (recenter (- -1 scroll-margin)))))))
(set-buffer current))))
+
+(defun comint-adjust-window-point (window process)
+ "Move point in WINDOW based on Comint settings.
+For point adjustment use the process-mark of PROCESS."
+ (and (< (window-point window) (process-mark process))
+ (or (memq comint-move-point-for-output '(t all))
+ ;; Maybe user wants point to jump to end.
+ (eq comint-move-point-for-output
+ (if (eq (selected-window) window) 'this 'others))
+ ;; If point was at the end, keep it at end.
+ (and (marker-position comint-last-output-start)
+ (>= (window-point window) comint-last-output-start)))
+ (set-window-point window (process-mark process))))
+
+
+;; this function is nowhere used
(defun comint-adjust-point (selected)
"Move point in the selected window based on Comint settings.
SELECTED is the window that was originally selected."
(if (and buff
(buffer-modified-p buff)
(y-or-n-p (format "Save buffer %s first? " (buffer-name buff))))
- ;; save BUFF.
- (let ((old-buffer (current-buffer)))
- (set-buffer buff)
- (save-buffer)
- (set-buffer old-buffer)))))
+ (with-current-buffer buff
+ (save-buffer)))))
(defun comint-extract-string ()
"Return string around point, or nil."
(defun comint-unquote-filename (filename)
"Return FILENAME with quoted characters unquoted."
+ (declare (obsolete nil "24.3"))
(if (null comint-file-name-quote-list)
filename
(save-match-data
(replace-regexp-in-string "\\\\\\(.\\)" "\\1" filename t))))
-(make-obsolete 'comint-unquote-filename nil "24.3")
(defun comint--requote-argument (upos qstr)
;; See `completion-table-with-quoting'.
(complete-with-action action table string pred))))
(unless (zerop (length filesuffix))
(list :exit-function
- (lambda (_s finished)
- (when (memq finished '(sole finished))
+ (lambda (_s status)
+ (when (eq status 'finished)
(if (looking-at (regexp-quote filesuffix))
(goto-char (match-end 0))
(insert filesuffix)))))))))
(defun comint-dynamic-complete-as-filename ()
"Dynamically complete at point as a filename.
See `comint-dynamic-complete-filename'. Returns t if successful."
+ (declare (obsolete comint-filename-completion "24.1"))
(let ((data (comint--complete-file-name-data)))
(completion-in-region (nth 0 data) (nth 1 data) (nth 2 data))))
-(make-obsolete 'comint-dynamic-complete-as-filename
- 'comint-filename-completion "24.1")
(defun comint-replace-by-expanded-filename ()
"Dynamically expand and complete the filename at point.
Return `listed' if a completion listing was shown.
See also `comint-dynamic-complete-filename'."
+ (declare (obsolete completion-in-region "24.1"))
(let* ((completion-ignore-case (memq system-type '(ms-dos windows-nt cygwin)))
(minibuffer-p (window-minibuffer-p (selected-window)))
(suffix (cond ((not comint-completion-addsuffix) "")
(unless minibuffer-p
(message "Partially completed"))
'partial)))))))
-(make-obsolete 'comint-dynamic-simple-complete 'completion-in-region "24.1")
-
(defun comint-dynamic-list-filename-completions ()
"Display a list of possible completions for the filename at point."
This is useful, for instance, for insertion into Help mode buffers.
You probably want to set it locally to the output buffer.")
+(defvar comint-redirect-previous-input-string nil
+ "Last redirected line of text.
+Allows detection of the end of the redirection in case the
+completion string is split between two output segments.")
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(make-local-variable 'comint-redirect-completed)
(setq comint-redirect-completed nil)
+ (make-local-variable 'comint-redirect-previous-input-string)
+ (setq comint-redirect-previous-input-string "")
+
(setq mode-line-process
(if mode-line-process
(list (concat (elt mode-line-process 0) " Redirection"))
(defun comint-redirect-cleanup ()
"End a Comint redirection. See `comint-redirect-send-command'."
(interactive)
+ ;; 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)
;; Message
(and comint-redirect-verbose
- (message "Redirected output to buffer(s) %s"
- (mapconcat 'identity output-buffer-list " ")))
+ (message "Redirected output to buffer(s) %s" output-buffer-list))
;; If we see the prompt, tidy up
;; We'll look for the prompt in the original string, so nobody can
;; clobber it
- (and (string-match comint-redirect-finished-regexp input-string)
+ (and (string-match comint-redirect-finished-regexp
+ (concat comint-redirect-previous-input-string
+ input-string))
(progn
(and comint-redirect-verbose
(message "Redirection completed"))
(comint-redirect-cleanup)
(run-hooks 'comint-redirect-hook)))
+ (setq comint-redirect-previous-input-string input-string)
+
;; Echo input?
(if comint-redirect-echo-input
filtered-input-string