Skip to content

Commit 83b7f44

Browse files
committed
Add keyboard scrolling in copy mode
Scroll through scrollback with C-n/C-p at buffer edges (line by line), M-v/C-v (page at a time), and mouse wheel. The scroll functions now do an immediate redraw in copy mode instead of going through the debounced path which skips copy-mode redraws.
1 parent bb683ac commit 83b7f44

1 file changed

Lines changed: 64 additions & 4 deletions

File tree

ghostel.el

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -671,16 +671,67 @@ pasted using bracketed paste."
671671
(interactive "e")
672672
(when ghostel--term
673673
(ghostel--scroll ghostel--term -3)
674-
(setq ghostel--force-next-redraw t)
675-
(ghostel--invalidate)))
674+
(if ghostel--copy-mode-active
675+
(let ((inhibit-read-only t))
676+
(ghostel--redraw ghostel--term))
677+
(setq ghostel--force-next-redraw t)
678+
(ghostel--invalidate))))
676679

677680
(defun ghostel--scroll-down (&optional _event)
678681
"Scroll the terminal viewport down."
679682
(interactive "e")
680683
(when ghostel--term
681684
(ghostel--scroll ghostel--term 3)
682-
(setq ghostel--force-next-redraw t)
683-
(ghostel--invalidate)))
685+
(if ghostel--copy-mode-active
686+
(let ((inhibit-read-only t))
687+
(ghostel--redraw ghostel--term))
688+
(setq ghostel--force-next-redraw t)
689+
(ghostel--invalidate))))
690+
691+
(defun ghostel-copy-mode-scroll-up ()
692+
"Scroll the terminal viewport up by a page in copy mode."
693+
(interactive)
694+
(when ghostel--term
695+
(let ((height (count-lines (point-min) (point-max))))
696+
(ghostel--scroll ghostel--term (- 2 height))
697+
(let ((inhibit-read-only t))
698+
(ghostel--redraw ghostel--term)))))
699+
700+
(defun ghostel-copy-mode-scroll-down ()
701+
"Scroll the terminal viewport down by a page in copy mode."
702+
(interactive)
703+
(when ghostel--term
704+
(let ((height (count-lines (point-min) (point-max))))
705+
(ghostel--scroll ghostel--term (- height 2))
706+
(let ((inhibit-read-only t))
707+
(ghostel--redraw ghostel--term)))))
708+
709+
(defun ghostel-copy-mode-previous-line ()
710+
"Move to the previous line, scrolling the viewport if at the top."
711+
(interactive)
712+
(if (= (line-number-at-pos) 1)
713+
(when ghostel--term
714+
(let ((col (current-column)))
715+
(ghostel--scroll ghostel--term -1)
716+
(let ((inhibit-read-only t))
717+
(ghostel--redraw ghostel--term))
718+
(goto-char (point-min))
719+
(move-to-column col)))
720+
(forward-line -1)))
721+
722+
(defun ghostel-copy-mode-next-line ()
723+
"Move to the next line, scrolling the viewport if at the bottom."
724+
(interactive)
725+
(if (>= (line-number-at-pos) (line-number-at-pos (point-max)))
726+
(when ghostel--term
727+
(let ((col (current-column)))
728+
(ghostel--scroll ghostel--term 1)
729+
(let ((inhibit-read-only t))
730+
(ghostel--redraw ghostel--term))
731+
(goto-char (point-max))
732+
(beginning-of-line)
733+
(move-to-column col)))
734+
(forward-line 1)))
684735

685736
;;; Mouse input
686737

@@ -754,6 +805,15 @@ pasted using bracketed paste."
754805
;; Prompt navigation works in copy mode too
755806
(define-key map (kbd "C-c C-n") #'ghostel-next-prompt)
756807
(define-key map (kbd "C-c C-p") #'ghostel-previous-prompt)
808+
;; Scrollback
809+
(define-key map (kbd "<mouse-4>") #'ghostel--scroll-up)
810+
(define-key map (kbd "<mouse-5>") #'ghostel--scroll-down)
811+
(define-key map (kbd "<wheel-up>") #'ghostel--scroll-up)
812+
(define-key map (kbd "<wheel-down>") #'ghostel--scroll-down)
813+
(define-key map (kbd "M-v") #'ghostel-copy-mode-scroll-up)
814+
(define-key map (kbd "C-v") #'ghostel-copy-mode-scroll-down)
815+
(define-key map (kbd "C-n") #'ghostel-copy-mode-next-line)
816+
(define-key map (kbd "C-p") #'ghostel-copy-mode-previous-line)
757817
map)
758818
"Keymap for `ghostel-copy-mode'.
759819
Standard Emacs navigation works.

0 commit comments

Comments
 (0)