1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-26 07:33:47 +00:00

Limit the amount of text we examine when looking for password prompts

Both Comint and Eshell do this, and it can significantly slow down
commands that write a lot of output (bug#71576).

* lisp/comint.el (comint-password-prompt-max-length): New variable...
(comint-watch-for-password-prompt): ... use it.  Additionally, use the
matched result for the Emacs-based password prompt.

* lisp/eshell/esh-mode.el (eshell-password-prompt-max-length): New
variable...
(eshell-watch-for-password-prompt): ... use it.

* etc/NEWS: Announce this change.
This commit is contained in:
Jim Porter 2024-06-15 11:03:33 -07:00
parent 72f2b01e31
commit 1a55e957ae
3 changed files with 62 additions and 33 deletions

View File

@ -1002,9 +1002,16 @@ more information on this notation.
---
*** Performance improvements for interactive output in Eshell.
Interactive output in Eshell should now be significantly faster,
especially for built-in commands that can print large amounts of output
(e.g. "cat"). In addition, these commands can now update the display
periodically to show their progress.
especially for commands that can print large amounts of output
(e.g. "cat"). For external commands, Eshell saves time by only looking
for password prompts in the last 256 characters of each block of output.
To restore the previous behavior when checking for password prompts, set
'eshell-password-prompt-max-length' to 'most-positive-fixnum'.
---
*** Eshell built-in commands can now display progress.
Eshell built-in commands like "cat" and "ls" now update the display
periodically while running to show their progress.
+++
*** New special reference type '#<marker POSITION BUFFER>'.
@ -1160,6 +1167,14 @@ environment variable 'HISTFILE'.
In a 'shell' buffer, this user option is connection-local.
---
*** Performance improvements for interactive output.
Interactive output in Shell mode now scans more selectively for password
prompts by only examining the last 256 characters of each block of
output, reducing the time spent when printing large amounts of output.
To restore the old behavior, set 'comint-password-prompt-max-length' to
'most-positive-fixnum'.
** Make mode
*** The Makefile browser is now obsolete.

View File

@ -426,6 +426,11 @@ This is used by `comint-watch-for-password-prompt'."
:type 'regexp
:group 'comint)
(defvar comint-password-prompt-max-length 256
"The maximum amount of text to examine when matching password prompts.
This is used by `comint-watch-for-password-prompt' to reduce the amount
of time spent searching for password prompts.")
;; Here are the per-interpreter hooks.
(defvar comint-get-old-input (function comint-get-old-input-default)
"Function that returns old text in Comint mode.
@ -2563,23 +2568,26 @@ to detect the need to (prompt and) send a password. Ignores any
carriage returns (\\r) in STRING.
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)))
;; 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")
(when (get-buffer-process (current-buffer))
(comint-send-invisible
(string-trim string "[ \n\r\t\v\f\b\a]+" "\n+")))))))
(current-buffer))))
(let ((string (string-limit string comint-password-prompt-max-length t))
prompt)
(when (let ((case-fold-search t))
(string-match comint-password-prompt-regexp
(string-replace "\r" "" string)))
(setq prompt (string-trim (match-string 0 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")
(when (get-buffer-process (current-buffer))
(comint-send-invisible prompt))))))
(current-buffer)))))
;; Low-level process communication

View File

@ -198,6 +198,11 @@ This is used by `eshell-watch-for-password-prompt'."
:type 'directory
:group 'eshell)
(defvar eshell-password-prompt-max-length 256
"The maximum amount of text to examine when matching password prompts.
This is used by `eshell-watch-for-password-prompt' to reduce the amount
of time spent searching for password prompts.")
(defvar eshell-first-time-p t
"A variable which is non-nil the first time Eshell is loaded.")
@ -949,19 +954,20 @@ buffer's process if STRING contains a password prompt defined by
This function could be in the list `eshell-output-filter-functions'."
(when (eshell-head-process)
(save-excursion
(let ((case-fold-search t))
(goto-char eshell-last-output-block-begin)
(beginning-of-line)
(if (re-search-forward eshell-password-prompt-regexp
eshell-last-output-end t)
;; 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
(eshell-send-invisible)))
(current-buffer)))))))
(goto-char (max eshell-last-output-block-begin
(- eshell-last-output-end
eshell-password-prompt-max-length)))
(when (let ((case-fold-search t))
(re-search-forward eshell-password-prompt-regexp
eshell-last-output-end t))
;; 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
(eshell-send-invisible)))
(current-buffer))))))
(custom-add-option 'eshell-output-filter-functions
'eshell-watch-for-password-prompt)