diff options
Diffstat (limited to 'lisp/comint.el')
-rw-r--r-- | lisp/comint.el | 142 |
1 files changed, 108 insertions, 34 deletions
diff --git a/lisp/comint.el b/lisp/comint.el index 782833cc8fd..3da61fb992f 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -385,10 +385,12 @@ This variable is buffer-local." "\\(?: [[:alpha:]]+ .+\\)?[[:blank:]]*[::៖][[:space:]]*\\'" ;; The ccrypt encryption dialogue doesn't end with a colon, so ;; treat it specially. - "\\|^Enter encryption key: (repeat) *\\'") + "\\|^Enter encryption key: (repeat) *\\'" + ;; openssh-8.6p1 format: "(user@host) Password:". + "\\|^([^)@ \t\n]+@[^)@ \t\n]+) Password: *\\'") "Regexp matching prompts for passwords in the inferior process. This is used by `comint-watch-for-password-prompt'." - :version "28.1" + :version "29.1" :type 'regexp :group 'comint) @@ -728,6 +730,8 @@ Entry to this mode runs the hooks on `comint-mode-hook'." (or (file-remote-p default-directory) "")) (setq-local comint-accum-marker (make-marker)) (setq-local font-lock-defaults '(nil t)) + (add-function :filter-return (local 'filter-buffer-substring-function) + #'comint--unmark-string-as-output) (add-hook 'change-major-mode-hook 'font-lock-defontify nil t) (add-hook 'isearch-mode-hook 'comint-history-isearch-setup nil t) (add-hook 'completion-at-point-functions 'comint-completion-at-point nil t) @@ -889,12 +893,13 @@ series of processes in the same Comint buffer. The hook ;; and there is no way for us to define it here. ;; Some programs that use terminfo get very confused ;; if TERM is not a valid terminal type. - (if (and (boundp 'system-uses-terminfo) system-uses-terminfo) - (list (format "TERM=%s" comint-terminfo-terminal) - "TERMCAP=" - (format "COLUMNS=%d" (window-width))) - (list "TERM=emacs" - (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width))))) + (with-connection-local-variables + (if system-uses-terminfo + (list (format "TERM=%s" comint-terminfo-terminal) + "TERMCAP=" + (format "COLUMNS=%d" (window-width))) + (list "TERM=emacs" + (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width)))))) (defun comint-nonblank-p (str) "Return non-nil if STR contains non-whitespace syntax." @@ -1105,7 +1110,8 @@ See also `comint-read-input-ring'." (use-local-map keymap)) (forward-line 3) (while (search-backward "completion" nil 'move) - (replace-match "history reference"))) + (replace-match (apply #'propertize "history reference" + (text-properties-at (point)))))) (sit-for 0) (message "Hit space to flush") (setq comint-dynamic-list-input-ring-window-conf conf) @@ -1510,6 +1516,7 @@ Intended to be added to `isearch-mode-hook' in `comint-mode'." #'comint-history-isearch-wrap) (setq-local isearch-push-state-function #'comint-history-isearch-push-state) + (setq-local isearch-lazy-count nil) (add-hook 'isearch-mode-end-hook 'comint-history-isearch-end nil t))) (defun comint-history-isearch-end () @@ -1521,6 +1528,7 @@ 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) + (kill-local-variable 'isearch-lazy-count) (remove-hook 'isearch-mode-end-hook 'comint-history-isearch-end t) (unless isearch-suspended (custom-reevaluate-setting 'comint-history-isearch))) @@ -1812,7 +1820,8 @@ Ignore duplicates if `comint-input-ignoredups' is non-nil." (ring-insert comint-input-ring cmd))) (defconst comint--prompt-rear-nonsticky - '(field inhibit-line-move-field-capture read-only font-lock-face) + '( field inhibit-line-move-field-capture read-only font-lock-face + insert-in-front-hooks) "Text properties we set on the prompt and don't want to leak past it.") (defun comint-send-input (&optional no-newline artificial) @@ -1904,6 +1913,14 @@ Similarly for Soar, Scheme, etc." (delete-region pmark start) copy)))) + ;; Delete and reinsert input. This seems like a no-op, except + ;; for the resulting entries in the undo list: undoing this + ;; insertion will delete the region, moving the process mark + ;; back to its original position. + (let ((inhibit-read-only t)) + (delete-region pmark (point)) + (insert input)) + (unless no-newline (insert ?\n)) @@ -1947,7 +1964,7 @@ Similarly for Soar, Scheme, etc." ;; in case we get output amidst sending the input. (set-marker comint-last-input-start pmark) (set-marker comint-last-input-end (point)) - (set-marker (process-mark proc) (point)) + (set-marker pmark (point)) ;; clear the "accumulation" marker (set-marker comint-accum-marker nil) (let ((comint-input-sender-no-newline no-newline)) @@ -2022,7 +2039,7 @@ the start, the cdr to the end of the last prompt recognized.") Freezes the `font-lock-face' text property in place." (when comint-last-prompt (with-silent-modifications - (font-lock-prepend-text-property + (font-lock-append-text-property (car comint-last-prompt) (cdr comint-last-prompt) 'font-lock-face 'comint-highlight-prompt)) @@ -2141,14 +2158,7 @@ Make backspaces delete the previous character." (goto-char (process-mark process)) ; In case a filter moved it. (unless comint-use-prompt-regexp - (with-silent-modifications - (add-text-properties comint-last-output-start (point) - `(rear-nonsticky - ,comint--prompt-rear-nonsticky - front-sticky - (field inhibit-line-move-field-capture) - field output - inhibit-line-move-field-capture t)))) + (comint--mark-as-output comint-last-output-start (point))) ;; Highlight the prompt, where we define `prompt' to mean ;; the most recent output that doesn't end with a newline. @@ -2180,6 +2190,46 @@ Make backspaces delete the previous character." ,comint--prompt-rear-nonsticky))) (goto-char saved-point))))))) +(defun comint--mark-as-output (beg end) + (with-silent-modifications + (add-text-properties + beg end + `(rear-nonsticky + ,comint--prompt-rear-nonsticky + front-sticky + (field inhibit-line-move-field-capture) + field output + inhibit-line-move-field-capture t + ;; Text inserted by a user in the middle of process output + ;; should be marked as output. This is needed for commands + ;; such as `yank' or `just-one-space' which don't use + ;; `insert-and-inherit' and thus bypass default text property + ;; inheritance. + insert-in-front-hooks + (,#'comint--mark-as-output ,#'comint--mark-yanked-as-output))))) + +(defun comint--mark-yanked-as-output (beg end) + ;; `yank' removes the field text property from the text it inserts + ;; due to `yank-excluded-properties', so arrange for this text + ;; property to be reapplied in the `after-change-functions'. + (let (fun) + (setq + fun + (lambda (beg1 end1 _len1) + (remove-hook 'after-change-functions fun t) + (when (and (= beg beg1) + (= end end1)) + (comint--mark-as-output beg1 end1)))) + (add-hook 'after-change-functions fun nil t))) + +(defun comint--unmark-string-as-output (string) + (remove-list-of-text-properties + 0 (length string) + '( rear-nonsticky front-sticky field + inhibit-line-move-field-capture insert-in-front-hooks) + string) + string) + (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, @@ -2455,11 +2505,19 @@ This function could be in the list `comint-output-filter-functions'." (when (let ((case-fold-search t)) (string-match comint-password-prompt-regexp (string-replace "\r" "" string))) - (let ((comint--prompt-recursion-depth (1+ comint--prompt-recursion-depth))) - (if (> comint--prompt-recursion-depth 10) - (message "Password prompt recursion too deep") - (comint-send-invisible - (string-trim string "[ \n\r\t\v\f\b\a]+" "\n+")))))) + ;; Use `run-at-time' in order not to pause execution of the + ;; process filter with a minibuffer + (run-at-time + 0 nil + (lambda (current-buf) + (with-current-buffer current-buf + (let ((comint--prompt-recursion-depth + (1+ comint--prompt-recursion-depth))) + (if (> comint--prompt-recursion-depth 10) + (message "Password prompt recursion too deep") + (comint-send-invisible + (string-trim string "[ \n\r\t\v\f\b\a]+" "\n+")))))) + (current-buffer)))) ;; Low-level process communication @@ -3136,8 +3194,8 @@ inside of a \"[...]\" (see `skip-chars-forward'), plus all non-ASCII characters. (while (not giveup) (let ((startpoint (point))) (skip-chars-backward (concat "\\\\" word-chars)) - (if (and comint-file-name-quote-list - (eq (char-before (1- (point))) ?\\)) + (if (and (eq (char-before (1- (point))) ?\\) + (memq (char-before) comint-file-name-quote-list)) (forward-char -2)) ;; FIXME: This isn't consistent with Bash, at least -- not ;; all non-ASCII chars should be word constituents. @@ -3509,6 +3567,20 @@ to send all the accumulated input, at once. The entire accumulated text becomes one item in the input history when you send it." (interactive) + (when-let* ((proc (get-buffer-process (current-buffer))) + (pmark (process-mark proc)) + ((or (marker-position comint-accum-marker) + (set-marker comint-accum-marker pmark) + t)) + ((>= (point) comint-accum-marker pmark))) + ;; Delete and reinsert input. This seems like a no-op, except for + ;; the resulting entries in the undo list: undoing this insertion + ;; will delete the region, moving the accumulation marker back to + ;; its original position. + (let ((text (buffer-substring comint-accum-marker (point))) + (inhibit-read-only t)) + (delete-region comint-accum-marker (point)) + (insert text))) (insert "\n") (set-marker comint-accum-marker (point)) (if comint-input-ring-index @@ -3906,10 +3978,12 @@ REGEXP-GROUP is the regular expression group in REGEXP to use." ;;; OSC escape sequences (Operating System Commands) ;;============================================================================ -;; Adding `comint-osc-process-output' to `comint-output-filter-functions' -;; enables the interpretation of OSC escape sequences. By default, only -;; OSC 8, for hyperlinks, is acted upon. Adding more entries to -;; `comint-osc-handlers' allows a customized treatment of further sequences. +;; Adding `comint-osc-process-output' to +;; `comint-output-filter-functions' enables the interpretation of OSC +;; escape sequences. By default, OSC 7 and 8 (for current directory +;; and hyperlinks respectively) are acted upon. Adding more entries +;; to `comint-osc-handlers' allows a customized treatment of further +;; sequences. (defvar-local comint-osc-handlers '(("7" . comint-osc-directory-tracker) ("8" . comint-osc-hyperlink-handler)) @@ -3954,9 +4028,9 @@ arguments, with point where the escape sequence was located." ;; Current directory tracking (OSC 7) -(declare-function url-host "url-parse.el") -(declare-function url-type "url-parse.el") -(declare-function url-filename "url-parse.el") +(declare-function url-host "url/url-parse.el") +(declare-function url-type "url/url-parse.el") +(declare-function url-filename "url/url-parse.el") (defun comint-osc-directory-tracker (_ text) "Update `default-directory' from OSC 7 escape sequences. |