From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Kangas Newsgroups: gmane.emacs.bugs Subject: bug#71576: 30.0.50; [PATCH] Improve performance of Comint/Eshell password prompt handling Date: Sun, 16 Jun 2024 03:53:46 -0700 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33031"; mail-complaints-to="usenet@ciao.gmane.io" To: Jim Porter , 71576@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Jun 16 12:55:19 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sInXX-0008C2-QH for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 16 Jun 2024 12:55:18 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sInXL-0002r7-NU; Sun, 16 Jun 2024 06:55:03 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sInXJ-0002qd-Hv for bug-gnu-emacs@gnu.org; Sun, 16 Jun 2024 06:55:01 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sInXJ-0007Lg-92 for bug-gnu-emacs@gnu.org; Sun, 16 Jun 2024 06:55:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1sInXK-0005RZ-Hr for bug-gnu-emacs@gnu.org; Sun, 16 Jun 2024 06:55:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Stefan Kangas Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 16 Jun 2024 10:55:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 71576 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 71576-submit@debbugs.gnu.org id=B71576.171853530020909 (code B ref 71576); Sun, 16 Jun 2024 10:55:02 +0000 Original-Received: (at 71576) by debbugs.gnu.org; 16 Jun 2024 10:55:00 +0000 Original-Received: from localhost ([127.0.0.1]:46113 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sInXE-0005R4-BB for submit@debbugs.gnu.org; Sun, 16 Jun 2024 06:54:59 -0400 Original-Received: from mail-ed1-f42.google.com ([209.85.208.42]:59837) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sInXC-0005Qh-MK for 71576@debbugs.gnu.org; Sun, 16 Jun 2024 06:54:55 -0400 Original-Received: by mail-ed1-f42.google.com with SMTP id 4fb4d7f45d1cf-579fa270e53so5252309a12.3 for <71576@debbugs.gnu.org>; Sun, 16 Jun 2024 03:54:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718535227; x=1719140027; darn=debbugs.gnu.org; h=content-transfer-encoding:to:subject:message-id:date:mime-version :references:in-reply-to:from:from:to:cc:subject:date:message-id :reply-to; bh=Qvmo5Qvb0n62wqfLIxuqMWs1uhql93pvQ1cZYuHW/Eo=; b=X8/8Nxx7ZgC+Pw7Za3ai+aHcOFqvEyCzqPhxQGdMCpiYlULl5cSxByJzR1suT5a56Q ZIMrEWaRMdBQM6GH2AXPCF9nbtlwtkBHGENt1Qs4huOBv+0aA3pQbsUV0uamJky/d5O9 t4x6NaMV7/JAiUg+50nKjEiSLqTzbk86+9ccpNmepvEGKvyaeJz8FV8IUA0hZXAzmtkZ JHLxv8QiC9UxxufQQY1W9agCi69uKczqGXq1zibsNWAcL64QxdnNLQPIVMc3Y6iLwahd pGDaxTapUTa3ICBo4wJ3v82gQzg9lvg1WIyR5yUfAic6wO98cRZUMddaV56Nc3WlU3Um j7wQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718535227; x=1719140027; h=content-transfer-encoding:to:subject:message-id:date:mime-version :references:in-reply-to:from:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=Qvmo5Qvb0n62wqfLIxuqMWs1uhql93pvQ1cZYuHW/Eo=; b=FQ91A6nAzzh2oecrF24EaKDVI3qxYWRQfQT/E6daRUnoxqmI+N7tuq89AklMqdcUOd RJ9zxMUflq4EC04xDns3Y/H2oCqpvHtPpzMpamKPqYnjZiqOcq8NfGVzLaTMA7yw3UC9 ASRatoXW86RL+5vOSCsNCwj5P82/cKvW+1sVXcqTP3XOwiMRSVtO2iWvAC/ty53Asdk1 o8iVEIMP/BtVEMZN4AZRrVQVQnd8aAgqTWMkJ1/X1P57GSc57jaKuqPuajjlJciivwPK mPVjBot0Xw1PujQf7KUG70UOdLSXCJGtzsXHNJJGOJd7IAlCFtSEvkdbYUoCtawjX1gN Qemg== X-Forwarded-Encrypted: i=1; AJvYcCWnJqrTEp9MI28oADP+jdh0EadrFMG0gobP6Dba0mQ6LDpAkx+ES8c0kZXivSUrgqyVhLRkMspLxdVWW5Qee24vWAbXfWc= X-Gm-Message-State: AOJu0Yz+xp0rFYqFP6Fcq4L6QHoP5xyx2CGom2RWlHbqEc/0XEHIHeBZ qRnPCR3ItMtDeYhgJuAzWjr7BsMaugfPMKXr4+mPyZwCraTk+WUYHIAyElPWVu9gBbx00HS0aF8 d+aotzYIXOsPJ8JWxkXGjMTqP5f0= X-Google-Smtp-Source: AGHT+IEynqKQt7uc3QUUvFco6oETUL84a0a5bsURekF02ZLqfuUkbKxBeVG9hPImq82SR33llsNzylflTWvvr1YsppA= X-Received: by 2002:a50:d6d3:0:b0:57c:6d9a:914e with SMTP id 4fb4d7f45d1cf-57cbd69e7abmr6175378a12.30.1718535227362; Sun, 16 Jun 2024 03:53:47 -0700 (PDT) Original-Received: from 753933720722 named unknown by gmailapi.google.com with HTTPREST; Sun, 16 Jun 2024 03:53:46 -0700 In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:287332 Archived-At: Jim Porter writes: > I've added NEWS entries for this, although maybe this isn't something > that really needs to be announced. Still, I figured it was worth > mentioning in the unlikely case that the new behavior could cause some > problem with (very!) long password prompts. > > I'm also totally fine with letting this patch wait for Emacs 31 if > there's any concern about the code. It's not a big change, but maybe > it's worth erring on the side of stability. Thanks. I'd be okay with putting this patch in Emacs 30, but let's see what other people think. > From 197ec6368e6d2678f8f1601dc1a9800855df0943 Mon Sep 17 00:00:00 2001 > From: Jim Porter > Date: Sat, 15 Jun 2024 11:03:33 -0700 > Subject: [PATCH] Limit the amount of text we examine when looking for pas= sword > prompts > > Both Comint and Eshell do this, and it can significantly slow down > commands that write a lot of output. > > * lisp/comint.el (comint-password-prompt-max-length): New option... > (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 > option... > (eshell-watch-for-password-prompt): ... use it. > > * etc/NEWS: Announce this change. > --- > etc/NEWS | 21 +++++++++++++++--- > lisp/comint.el | 49 +++++++++++++++++++++++++++-------------- > lisp/eshell/esh-mode.el | 41 +++++++++++++++++++++++----------- > 3 files changed, 78 insertions(+), 33 deletions(-) > > diff --git a/etc/NEWS b/etc/NEWS > index b2fdbc4a88f..1cf5025910c 100644 > --- a/etc/NEWS > +++ b/etc/NEWS > @@ -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 change the amount of text to examine, customize > +'eshell-password-prompt-max-length'. > + > +--- > +*** 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 '#'. > @@ -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 change the amount of text to examine, customize > +'comint-password-prompt-max-length'. > + > ** Make mode > > *** The Makefile browser is now obsolete. > diff --git a/lisp/comint.el b/lisp/comint.el > index 3804932e01c..b8a12074fb7 100644 > --- a/lisp/comint.el > +++ b/lisp/comint.el > @@ -426,6 +426,18 @@ comint-password-prompt-regexp > :type 'regexp > :group 'comint) > > +(defcustom comint-password-prompt-max-length 256 > + "The maximum amount of text to examine when matching password prompts. > +When non-nil, only examine the last N characters of a block of output. > +If nil, examine all the output. > + > +This is used by `comint-watch-for-password-prompt' to reduce the amount > +of time spent searching for password prompts." > + :version "30.1" > + :type '(choice natnum > + (const :tag "Examine all output" nil)) > + :group 'comint) If this is hardcoded in Tramp, are we sure that we need this as an option? I'd suggest making it into a defconst or defvar instead. > + > ;; 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 +2575,26 @@ comint-watch-for-password-prompt > 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))))) > =0C > ;; Low-level process communication > > diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el > index ec1a07b7e2f..5603fef90a4 100644 > --- a/lisp/eshell/esh-mode.el > +++ b/lisp/eshell/esh-mode.el > @@ -182,6 +182,18 @@ eshell-password-prompt-regexp > :type 'regexp > :version "27.1") > > +(defcustom eshell-password-prompt-max-length 256 > + "The maximum amount of text to examine when matching password prompts. > +When non-nil, only examine the last N characters of a block of output. > +If nil, examine all the output. > + > +This is used by `eshell-watch-for-password-prompt' to reduce the amount > +of time spent searching for password prompts." > + :version "30.1" > + :type '(choice natnum > + (const :tag "Examine all output" nil)) > + :group 'comint) > + > (defcustom eshell-skip-prompt-function nil > "A function called from beginning of line to skip the prompt." > :type '(choice (const nil) function)) > @@ -949,19 +961,22 @@ eshell-watch-for-password-prompt > 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 (if eshell-password-prompt-max-length > + (max eshell-last-output-block-begin > + (- eshell-last-output-end > + eshell-password-prompt-max-length)) > + eshell-last-output-block-begin)) > + (when (let ((case-fold-search t)) > + (re-search-forward eshell-password-prompt-regexp > + eshell-last-output-end t)) Could this be simplified using re-search-backward with the BOUND argument instead? > + ;; 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) > -- > 2.25.1