From: Pierre Neidhardt Date: Sat, 17 Oct 2020 11:16:24 +0000 (+0200) Subject: New shell-mode command to narrow to the command under point X-Git-Tag: emacs-28.0.90~5583 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=9eb61be2dafcb4159888e90449091927cbad508a;p=emacs.git New shell-mode command to narrow to the command under point * lisp/shell.el (shell--prompt-end-position) (shell--prompt-begin-position): Helper functions. * lisp/shell.el (shell-narrow-to-prompt): New command and keystroke (bug#41784). --- diff --git a/etc/NEWS b/etc/NEWS index 1838b6b38a7..0519451e969 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1143,6 +1143,11 @@ window after starting). This variable defaults to nil. ** Miscellaneous +--- +*** New command in 'shell-mode': 'narrow-to-prompt'. +This is bound to 'C-x n d' in 'shell-mode' buffers, and narrows to the +command line under point (and any following output). + --- *** New user option 'compilation-search-all-directories'. When doing parallel builds, directories and compilation errors may diff --git a/lisp/shell.el b/lisp/shell.el index 226bdf4d919..43ad58774b8 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -334,6 +334,7 @@ Thus, this does not include the shell's current directory.") (define-key map "\t" 'completion-at-point) (define-key map (kbd "M-RET") 'shell-resync-dirs) (define-key map "\M-?" 'comint-dynamic-list-filename-completions) + (define-key map (kbd "C-x n d") 'shell-narrow-to-prompt) (define-key map [menu-bar completion] (cons "Complete" (copy-keymap (lookup-key comint-mode-map [menu-bar completion])))) @@ -1366,6 +1367,48 @@ Returns t if successful." (let ((f (shell-c-a-p-replace-by-expanded-directory))) (if f (funcall f)))) +(defun shell--prompt-begin-position () + ;; We need this convoluted function because `looking-at-p' does not work on + ;; multiline regexps _and_ `re-search-backward' skips the current line. + (save-excursion + (let ((old-point (point))) + (max + (save-excursion + ;; Right result if not on prompt. + (call-interactively #'comint-previous-prompt) + (re-search-backward comint-prompt-regexp) + (point)) + (save-excursion + ;; Right result if on first char after prompt. + (re-search-backward comint-prompt-regexp) + (point)) + (save-excursion + ;; Right result if on prompt. + (call-interactively #'comint-next-prompt) + (re-search-backward comint-prompt-regexp) + (if (<= (point) old-point) + (point) + (point-min))))))) + +(defun shell--prompt-end-position () + (save-excursion + (goto-char (shell--prompt-begin-position)) + (comint-next-prompt 1) + (point))) + +(defun shell-narrow-to-prompt () + "Narrow buffer to the command line (and any following command output) at point." + (interactive) + (let ((begin (shell--prompt-begin-position))) + (narrow-to-region + begin + (save-excursion + (goto-char (shell--prompt-end-position)) + (call-interactively #'comint-next-prompt) + (if (= begin (shell--prompt-begin-position)) + (point-max) + (shell--prompt-begin-position)))))) + (provide 'shell) ;;; shell.el ends here