New command 'eat-narrow-to-shell-prompt'

* eat.el (eat--post-prompt): Put the 'eat--shell-prompt-begin'
text property at the beginning of shell prompt.
* eat.el (eat--correct-shell-prompt-mark-overlays): Don't try
to go outside accessible portion of buffer when the buffer is
narrowed.
* eat.el (eat-narrow-to-shell-prompt): New command.
* eat.el (eat-mode-map): Bind key sequence 'C-x n d' to
'eat-narrow-to-shell-prompt'.
* eat.el (eat--filter-buffer-substring): Remove all text
properties added on UI side before passing buffer substring to
'eat-term-filter-string'.
* eat.texi (Shell Integration): Document
'eat-narrow-to-shell-prompt'.
This commit is contained in:
Akib Azmain Turja 2023-04-09 17:20:49 +06:00
parent f7fd7694a9
commit c51446bafb
No known key found for this signature in database
GPG key ID: 5535FCF54D88616B
3 changed files with 76 additions and 20 deletions

View file

@ -1,6 +1,6 @@
#+title: Eat: Emulate A Terminal
Eat's name self-explainatory, it stands for "Emulate A Terminal". Eat
Eat's name self-explanatory, it stands for "Emulate A Terminal". Eat
is a terminal emulator. It can run most (if not all) full-screen
terminal programs, including Emacs.
@ -150,7 +150,7 @@ then Eat without byte-compilation). But it doesn't have a char mode
(however you can make a char mode spending some effort). And it too
flickers like Term, so despite being much faster that Eat, it seems to
be slow. If you need your terminal to handle huge bursts (megabytes)
of data, you should Vterm.
of data, you should use Vterm.
** Coterm + Shell

76
eat.el
View file

@ -26,7 +26,7 @@
;;; Commentary:
;; Eat's name self-explainary, it stands for "Emulate A Terminal".
;; Eat's name self-explanatory, it stands for "Emulate A Terminal".
;; Eat is a terminal emulator. It can run most (if not all)
;; full-screen terminal programs, including Emacs.
@ -4769,7 +4769,11 @@ If HOST isn't the host Emacs is running on, don't do anything."
(push ov eat--shell-prompt-mark-overlays))))))
(when eat--shell-prompt-begin
(when (< eat--shell-prompt-begin (point))
;; Put a text property to allow previous or next prompts.
;; Put a text property for `eat-narrow-to-shell-prompt'.
(put-text-property eat--shell-prompt-begin
(1+ eat--shell-prompt-begin)
'eat--shell-prompt-begin t)
;; Put a text property to allow shell prompt navigation.
(put-text-property (1- (point)) (point)
'eat--shell-prompt-end t)))
(setq eat--shell-prompt-begin nil))
@ -4785,23 +4789,27 @@ BUFFER is the terminal buffer."
(while-no-input
;; Delete all outdated overlays.
(dolist (ov eat--shell-prompt-mark-overlays)
(unless (eq (overlay-get ov 'eat--shell-prompt-mark-id)
(get-text-property (overlay-start ov)
'eat--shell-prompt-mark-id))
(unless (and (<= (point-min) (overlay-start ov)
(1- (point-max)))
(eq (overlay-get ov 'eat--shell-prompt-mark-id)
(get-text-property
(overlay-start ov)
'eat--shell-prompt-mark-id)))
(delete-overlay ov)
(setq eat--shell-prompt-mark-overlays
(delq ov eat--shell-prompt-mark-overlays))))
(save-excursion
;; Recreate overlays if needed.
(goto-char (eat-term-beginning eat--terminal))
(while (< (point) (eat-term-end eat--terminal))
(goto-char (max (eat-term-beginning eat--terminal)
(point-min)))
(while (< (point) (min (eat-term-end eat--terminal)
(point-max)))
(when (get-text-property
(point) 'eat--shell-prompt-mark-id)
(let ((ov (get-text-property
(point) 'eat--shell-prompt-mark-overlay)))
(unless
(and ov
(overlay-buffer ov)
(unless (and
ov (overlay-buffer ov)
(eq (overlay-get
ov 'eat--shell-prompt-mark-id)
(get-text-property
@ -4821,8 +4829,10 @@ BUFFER is the terminal buffer."
(push ov eat--shell-prompt-mark-overlays))))
(goto-char (or (next-single-property-change
(point) 'eat--shell-prompt-mark-id nil
(eat-term-end eat--terminal))
(eat-term-end eat--terminal)))))))))
(min (eat-term-end eat--terminal)
(point-max)))
(min (eat-term-end eat--terminal)
(point-max))))))))))
(defun eat--set-cmd (_ cmd)
"Add CMD to `shell-command-history'."
@ -4882,6 +4892,31 @@ prompt."
(unless next
(user-error "No next prompt")))))
(defun eat-narrow-to-shell-prompt ()
"Narrow buffer to the shell prompt and following output at point."
(interactive)
(widen)
(narrow-to-region
(save-excursion
(while (not (or (bobp) (get-text-property
(point) 'eat--shell-prompt-begin)))
(goto-char (or (previous-single-property-change
(point) 'eat--shell-prompt-begin)
(point-min))))
(point))
(save-excursion
(when (and (not (eobp))
(get-text-property (point) 'eat--shell-prompt-begin))
(goto-char (or (next-single-property-change
(point) 'eat--shell-prompt-begin)
(point-max))))
(while (not (or (eobp) (get-text-property
(point) 'eat--shell-prompt-begin)))
(goto-char (or (next-single-property-change
(point) 'eat--shell-prompt-begin)
(point-max))))
(point))))
;;;;; Input.
@ -5083,6 +5118,7 @@ STRING and ARG are passed to `yank-pop', which see."
(define-key map [?\C-c ?\C-k] #'eat-kill-process)
(define-key map [?\C-c ?\C-p] #'eat-previous-shell-prompt)
(define-key map [?\C-c ?\C-n] #'eat-next-shell-prompt)
(define-key map [?\C-x ?n ?d] #'eat-narrow-to-shell-prompt)
(define-key map [xterm-paste] #'ignore)
map)
"Keymap for Eat mode.")
@ -5275,7 +5311,16 @@ symbol `buffer', in which case the point of current buffer is set."
When DELETE is given and non-nil, delete the text between BEGIN and
END if it's safe to do so."
(let ((str (eat-term-filter-string (buffer-substring begin end))))
(let ((str (buffer-substring begin end)))
(remove-text-properties
0 (length str)
'( eat--before-string nil
eat--shell-prompt-mark-id nil
eat--shell-prompt-mark-overlay nil
eat--shell-prompt-begin nil
eat--shell-prompt-end nil)
str)
(setq str (eat-term-filter-string str))
(when (and delete
(or (not eat--terminal)
(and (<= (eat-term-end eat--terminal) begin)
@ -6102,9 +6147,8 @@ symbol `buffer', in which case the point of current buffer is set."
eat--eshell-char-mode)
(eat-term-display-beginning eat--terminal)
(save-restriction
(narrow-to-region
(eat-term-beginning eat--terminal)
(eat-term-end eat--terminal))
(narrow-to-region (eat-term-beginning eat--terminal)
(eat-term-end eat--terminal))
(let ((start-line (- (floor (window-screen-lines))
(line-number-at-pos (point-max)))))
(goto-char (point-min))

View file

@ -426,6 +426,17 @@ the previous shell prompt. @kbd{C-c C-n}, bound to
@command{eat-next-shell-prompt}, is the opposite, it goes to the next
shell prompt. This doesn't work in Eshell.
@cindex narrow to shell prompt
@cindex narrow to prompt
@cindex narrow, shell prompt
@cindex narrow, prompt
@kindex C-x n d @r{(``emacs mode'')}
@kindex C-x n d @r{(``semi-char mode'')}
@findex eat-narrow-to-shell-prompt
You can narrow (@pxref{Narrowing,,, emacs, GNU Emacs Manual}) down Eat
buffer to a shell prompt and its output (if any) using the key
sequence @kbd{C-x n d}, bound to @command{eat-narrow-to-shell-prompt}.
@cindex shell prompt annotation
@cindex annotation, shell prompt
@cindex annotate, shell prompt
@ -929,7 +940,8 @@ Due to some limitations, shell prompt annotations
(@pxref{Shell Integration}) can get messed up sometimes. Eat
automatically corrects them after each terminal redisplay. However,
this can have some performance impact when the terminal scrollback and
display is large enough. So Eat defers the correction.
display is large enough (unless the buffer is narrowed). So Eat
defers the correction.
@vindex eat-shell-prompt-annotation-delay
@defopt eat-shell-prompt-annotation-delay
@ -942,7 +954,7 @@ instantly, but this may cause the terminal to slow down in some cases.
@end defopt
The user options described in this chapter have reasonable default
values, but they may change anytime.
values, but the default values may change anytime.
@part Part IV:@* Recovering from Problems