summaryrefslogtreecommitdiff
path: root/lisp/comint.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/comint.el')
-rw-r--r--lisp/comint.el115
1 files changed, 72 insertions, 43 deletions
diff --git a/lisp/comint.el b/lisp/comint.el
index 122291bcf9c..5928804fe73 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -78,7 +78,7 @@
;;
;; Not bound by default in comint-mode (some are in shell mode)
;; comint-run Run a program under comint-mode
-;; send-invisible Read a line w/o echo, and send to proc
+;; comint-send-invisible Read a line w/o echo, and send to proc
;; comint-dynamic-complete-filename Complete filename at point.
;; comint-dynamic-list-filename-completions List completions in help buffer.
;; comint-replace-by-expanded-filename Expand and complete filename at point;
@@ -263,6 +263,8 @@ See `comint-preinput-scroll-to-bottom'. This variable is buffer-local."
(const this))
:group 'comint)
+(defvaralias 'comint-scroll-to-bottom-on-output 'comint-move-point-for-output)
+
(defcustom comint-move-point-for-output nil
"Controls whether interpreter output moves point to the end of the output.
If nil, then output never moves point to the output.
@@ -295,8 +297,6 @@ end of the current logical (not visual) line after insertion."
(const :tag "Move to end of line" end-of-line))
:group 'comint)
-(defvaralias 'comint-scroll-to-bottom-on-output 'comint-move-point-for-output)
-
(defcustom comint-scroll-show-maximum-output t
"Controls how to scroll due to interpreter output.
This variable applies when point is at the end of the buffer
@@ -360,14 +360,15 @@ This variable is buffer-local."
"Kerberos" "CVS" "UNIX" " SMB" "LDAP" "PEM" "SUDO"
"[sudo]" "Repeat" "Bad" "Retype")
t)
- " +\\)"
+ ;; Allow for user name to precede password equivalent (Bug#31075).
+ " +.*\\)"
"\\(?:" (regexp-opt password-word-equivalents) "\\|Response\\)"
"\\(?:\\(?:, try\\)? *again\\| (empty for no passphrase)\\| (again)\\)?"
;; "[[:alpha:]]" used to be "for", which fails to match non-English.
- "\\(?: [[:alpha:]]+ .+\\)?[::៖]\\s *\\'")
+ "\\(?: [[:alpha:]]+ .+\\)?[[:blank:]]*[::៖][[:blank:]]*\\'")
"Regexp matching prompts for passwords in the inferior process.
This is used by `comint-watch-for-password-prompt'."
- :version "26.1"
+ :version "27.1"
:type 'regexp
:group 'comint)
@@ -429,9 +430,6 @@ See `comint-send-input'."
:type 'boolean
:group 'comint)
-(define-obsolete-variable-alias 'comint-use-prompt-regexp-instead-of-fields
- 'comint-use-prompt-regexp "22.1")
-
;; Note: If it is decided to purge comint-prompt-regexp from the source
;; entirely, searching for uses of this variable will help to identify
;; places that need attention.
@@ -635,7 +633,7 @@ Input ring history expansion can be achieved with the commands
Input ring expansion is controlled by the variable `comint-input-autoexpand',
and addition is controlled by the variable `comint-input-ignoredups'.
-Commands with no default key bindings include `send-invisible',
+Commands with no default key bindings include `comint-send-invisible',
`completion-at-point', `comint-dynamic-list-filename-completions', and
`comint-magic-space'.
@@ -1434,24 +1432,32 @@ If nil, Isearch operates on the whole comint buffer."
(defun comint-history-isearch-backward ()
"Search for a string backward in input history using Isearch."
(interactive)
- (let ((comint-history-isearch t))
- (isearch-backward nil t)))
+ (setq comint-history-isearch t)
+ (isearch-backward nil t))
(defun comint-history-isearch-backward-regexp ()
"Search for a regular expression backward in input history using Isearch."
(interactive)
- (let ((comint-history-isearch t))
- (isearch-backward-regexp nil t)))
+ (setq comint-history-isearch t)
+ (isearch-backward-regexp nil t))
(defvar-local comint-history-isearch-message-overlay nil)
(defun comint-history-isearch-setup ()
"Set up a comint for using Isearch to search the input history.
Intended to be added to `isearch-mode-hook' in `comint-mode'."
- (when (or (eq comint-history-isearch t)
- (and (eq comint-history-isearch 'dwim)
- ;; Point is at command line.
- (comint-after-pmark-p)))
+ (when (and
+ ;; Prompt is not empty like in Async Shell Command buffers
+ ;; or in finished shell buffers
+ (not (eq (save-excursion
+ (goto-char (comint-line-beginning-position))
+ (forward-line 0)
+ (point))
+ (comint-line-beginning-position)))
+ (or (eq comint-history-isearch t)
+ (and (eq comint-history-isearch 'dwim)
+ ;; Point is at command line.
+ (comint-after-pmark-p))))
(setq isearch-message-prefix-add "history ")
(setq-local isearch-search-fun-function
#'comint-history-isearch-search)
@@ -1472,7 +1478,9 @@ Intended to be added to `isearch-mode-hook' in `comint-mode'."
(setq isearch-message-function nil)
(setq isearch-wrap-function nil)
(setq isearch-push-state-function nil)
- (remove-hook 'isearch-mode-end-hook 'comint-history-isearch-end t))
+ (remove-hook 'isearch-mode-end-hook 'comint-history-isearch-end t)
+ (unless isearch-suspended
+ (custom-reevaluate-setting 'comint-history-isearch)))
(defun comint-goto-input (pos)
"Put input history item of the absolute history position POS."
@@ -1676,11 +1684,13 @@ characters), and are not considered to be delimiters."
(defun comint-arguments (string nth mth)
"Return from STRING the NTH to MTH arguments.
NTH and/or MTH can be nil, which means the last argument.
-Returned arguments are separated by single spaces.
-We assume whitespace separates arguments, except within quotes
-and except for a space or tab that immediately follows a backslash.
-Also, a run of one or more of a single character
-in `comint-delimiter-argument-list' is a separate argument.
+NTH and MTH can be negative to count from the end; -1 means
+the last argument.
+Returned arguments are separated by single spaces. We assume
+whitespace separates arguments, except within quotes and except
+for a space or tab that immediately follows a backslash. Also, a
+run of one or more of a single character in
+`comint-delimiter-argument-list' is a separate argument.
Argument 0 is the command name."
;; The first line handles ordinary characters and backslash-sequences
;; (except with w32 msdos-like shells, where backslashes are valid).
@@ -1702,7 +1712,7 @@ Argument 0 is the command name."
(count 0)
beg str quotes)
;; Build a list of all the args until we have as many as we want.
- (while (and (or (null mth) (<= count mth))
+ (while (and (or (null mth) (< mth 0) (<= count mth))
(string-match argpart string pos))
;; Apply the `literal' text property to backslash-escaped
;; characters, so that `comint-delim-arg' won't break them up.
@@ -1729,8 +1739,14 @@ Argument 0 is the command name."
args (if quotes (cons str args)
(nconc (comint-delim-arg str) args))))
(setq count (length args))
- (let ((n (or nth (1- count)))
- (m (if mth (1- (- count mth)) 0)))
+ (let ((n (cond
+ ((null nth) (1- count))
+ ((>= nth 0) nth)
+ (t (+ count nth))))
+ (m (cond
+ ((null mth) 0)
+ ((>= mth 0) (1- (- count mth)))
+ (t (1- (- mth))))))
(mapconcat
(function (lambda (a) a)) (nthcdr n (nreverse (nthcdr m args))) " "))))
@@ -2232,7 +2248,7 @@ This function could be on `comint-output-filter-functions' or bound to a key."
(error nil))
(while (re-search-forward "\r+$" pmark t)
(replace-match "" t t)))))
-(defalias 'shell-strip-ctrl-m 'comint-strip-ctrl-m)
+(define-obsolete-function-alias 'shell-strip-ctrl-m #'comint-strip-ctrl-m "27.1")
(defun comint-show-maximum-output ()
"Put the end of the buffer at the bottom of the window."
@@ -2281,8 +2297,10 @@ If this takes us past the end of the current line, don't skip at all."
(defun comint-after-pmark-p ()
"Return t if point is after the process output marker."
- (let ((pmark (process-mark (get-buffer-process (current-buffer)))))
- (<= (marker-position pmark) (point))))
+ (let ((process (get-buffer-process (current-buffer))))
+ (when process
+ (let ((pmark (process-mark process)))
+ (<= (marker-position pmark) (point))))))
(defun comint-simple-send (proc string)
"Default function for sending to PROC input STRING.
@@ -2340,9 +2358,9 @@ a buffer local variable."
;; These three functions are for entering text you don't want echoed or
;; saved -- typically passwords to ftp, telnet, or somesuch.
-;; Just enter m-x send-invisible and type in your line.
+;; Just enter m-x comint-send-invisible and type in your line.
-(defun send-invisible (&optional prompt)
+(defun comint-send-invisible (&optional prompt)
"Read a string without echoing.
Then send it to the process running in the current buffer.
The string is sent using `comint-input-sender'.
@@ -2365,18 +2383,19 @@ Security bug: your string can still be temporarily recovered with
(message "Warning: text will be echoed")))
(error "Buffer %s has no process" (current-buffer)))))
+(define-obsolete-function-alias 'send-invisible #'comint-send-invisible "27.1")
+
(defun comint-watch-for-password-prompt (string)
"Prompt in the minibuffer for password and send without echoing.
-This function uses `send-invisible' to read and send a password to the buffer's
-process if STRING contains a password prompt defined by
-`comint-password-prompt-regexp'.
+Looks for a match to `comint-password-prompt-regexp' in order
+to detect the need to (prompt and) send a password.
This function could be in the list `comint-output-filter-functions'."
(when (let ((case-fold-search t))
(string-match comint-password-prompt-regexp string))
(when (string-match "^[ \n\r\t\v\f\b\a]+" string)
(setq string (replace-match "" t t string)))
- (send-invisible string)))
+ (comint-send-invisible string)))
;; Low-level process communication
@@ -2643,8 +2662,17 @@ text matching `comint-prompt-regexp'."
(defvar-local comint-insert-previous-argument-last-start-pos nil)
(defvar-local comint-insert-previous-argument-last-index nil)
-;; Needs fixing:
-;; make comint-arguments understand negative indices as bash does
+(defcustom comint-insert-previous-argument-from-end nil
+ "If non-nil, `comint-insert-previous-argument' counts args from the end.
+If this variable is nil, the default, `comint-insert-previous-argument'
+counts the arguments from the beginning; if non-nil, it counts from
+the end instead. This allows to emulate the behavior of `ESC-NUM ESC-.'
+in both Bash and zsh: in Bash, `number' counts from the
+beginning (variable is nil), while in zsh, it counts from the end."
+ :type 'boolean
+ :group 'comint
+ :version "27.1")
+
(defun comint-insert-previous-argument (index)
"Insert the INDEXth argument from the previous Comint command-line at point.
Spaces are added at beginning and/or end of the inserted string if
@@ -2652,8 +2680,9 @@ necessary to ensure that it's separated from adjacent arguments.
Interactively, if no prefix argument is given, the last argument is inserted.
Repeated interactive invocations will cycle through the same argument
from progressively earlier commands (using the value of INDEX specified
-with the first command).
-This command is like `M-.' in bash."
+with the first command). Values of INDEX < 0 count from the end, so
+INDEX = -1 is the last argument. This command is like `M-.' in
+Bash and zsh."
(interactive "P")
(unless (null index)
(setq index (prefix-numeric-value index)))
@@ -2663,6 +2692,9 @@ This command is like `M-.' in bash."
(setq index comint-insert-previous-argument-last-index))
(t
;; This is a non-repeat invocation, so initialize state.
+ (when (and index
+ comint-insert-previous-argument-from-end)
+ (setq index (- index)))
(setq comint-input-ring-index nil)
(setq comint-insert-previous-argument-last-index index)
(when (null comint-insert-previous-argument-last-start-pos)
@@ -2678,9 +2710,6 @@ This command is like `M-.' in bash."
(set-marker comint-insert-previous-argument-last-start-pos (point))
;; Insert the argument.
(let ((input-string (comint-previous-input-string 0)))
- (when (string-match "[ \t\n]*&" input-string)
- ;; strip terminating '&'
- (setq input-string (substring input-string 0 (match-beginning 0))))
(insert (comint-arguments input-string index index)))
;; Make next invocation return arg from previous input
(setq comint-input-ring-index (1+ (or comint-input-ring-index 0)))