Skip to content

Commit

Permalink
Merge pull request #1217 from mychris/patch/vi-scroll-commands
Browse files Browse the repository at this point in the history
Adds vi-mode scroll commands with universal arguments.
  • Loading branch information
cxxxr authored Jan 1, 2024
2 parents 491cf30 + 2718cc2 commit d3aa2e6
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 5 deletions.
13 changes: 10 additions & 3 deletions extensions/vi-mode/binds.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,16 @@
(define-key *motion-keymap* "T" 'vi-find-char-backward-after)
(define-key *motion-keymap* ";" 'vi-find-char-repeat)
(define-key *motion-keymap* "," 'vi-find-char-repeat-backward)
(define-key *motion-keymap* "z z" 'recenter)
(define-key *motion-keymap* "Z Z" 'vi-write-quit)
(define-key *motion-keymap* "Z Q" 'vi-quit)
(define-key *normal-keymap* "z z" 'vi-scroll-line-to-center)
(define-key *normal-keymap* "z ." 'vi-scroll-line-to-center-back-to-indentation)
(define-key *normal-keymap* "z t" 'vi-scroll-line-to-top)
(define-key *normal-keymap* "z Return" 'vi-scroll-line-to-top-back-to-indentation)
(define-key *normal-keymap* "z b" 'vi-scroll-line-to-bottom)
(define-key *normal-keymap* "z -" 'vi-scroll-line-to-bottom-back-to-indentation)
(define-key *normal-keymap* "z +" 'vi-scroll-bottom-line-to-top)
(define-key *normal-keymap* "z ^" 'vi-scroll-top-line-to-bottom)
(define-key *normal-keymap* "Z Z" 'vi-write-quit)
(define-key *normal-keymap* "Z Q" 'vi-quit)
(define-key *motion-keymap* "C-w s" 'split-active-window-vertically)
(define-key *motion-keymap* "C-w C-s" 'split-active-window-vertically)
(define-key *motion-keymap* "C-w w" 'next-window)
Expand Down
56 changes: 55 additions & 1 deletion extensions/vi-mode/commands.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
(:import-from :lem-vi-mode/window
:move-to-window-top
:move-to-window-middle
:move-to-window-bottom)
:move-to-window-bottom
:move-to-window-bottom-below
:move-to-window-top-above
:scroll-line)
(:import-from :lem-vi-mode/utils
:kill-region-without-appending)
(:import-from :lem/isearch
Expand Down Expand Up @@ -53,6 +56,14 @@
:vi-move-to-window-top
:vi-move-to-window-middle
:vi-move-to-window-bottom
:vi-scroll-line-to-center
:vi-scroll-line-to-center-back-to-indentation
:vi-scroll-line-to-top
:vi-scroll-line-to-top-back-to-indentation
:vi-scroll-line-to-bottom
:vi-scroll-line-to-bottom-back-to-indentation
:vi-scroll-bottom-line-to-top
:vi-scroll-top-line-to-bottom
:vi-back-to-indentation
:vi-indent
:vi-substitute
Expand Down Expand Up @@ -273,6 +284,49 @@
:jump t)
(move-to-window-bottom))

(define-command vi-scroll-line-to-center (&optional n) ("P")
"Scroll line number N (or the current line) to the center of the screen."
(scroll-line n :center))

(define-command vi-scroll-line-to-center-back-to-indentation (&optional n) ("P")
"Scroll line number N (or the current line) to the center of the screen.
Move the cursor to the first non-blank character of the line."
(scroll-line n :center)
(vi-back-to-indentation))

(define-command vi-scroll-line-to-top (&optional n) ("P")
"Scroll line number N (or the current line) to the top of the screen."
(scroll-line n :top))

(define-command vi-scroll-line-to-top-back-to-indentation (&optional n) ("P")
"Scroll line number N (or the current line) to the top of the screen.
Move the cursor to the first non-blank character of the line."
(scroll-line n :top)
(vi-back-to-indentation))

(define-command vi-scroll-line-to-bottom (&optional n) ("P")
"Scroll line number N (or the current line) to the bottom of the screen."
(scroll-line n :bottom))

(define-command vi-scroll-line-to-bottom-back-to-indentation (&optional n) ("P")
"Scroll line number N (or the current line) to the bottom of the screen.
Move the cursor to the first non-blank character of the line."
(scroll-line n :bottom)
(vi-back-to-indentation))

(define-command vi-scroll-bottom-line-to-top (&optional n) ("P")
(unless n
(move-to-window-bottom-below))
(vi-scroll-line-to-top-back-to-indentation n))

(define-command vi-scroll-top-line-to-bottom (&optional n) ("P")
(if n
(progn
(vi-scroll-line-to-bottom n)
(vi-move-to-window-top))
(move-to-window-top-above))
(vi-scroll-line-to-bottom-back-to-indentation nil))

(define-command vi-back-to-indentation () ()
(vi-move-to-beginning-of-line)
(skip-whitespace-forward (current-point) t))
Expand Down
9 changes: 8 additions & 1 deletion extensions/vi-mode/utils.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
(:import-from :cl-ppcre)
(:export :change-directory
:expand-filename-modifiers
:kill-region-without-appending))
:kill-region-without-appending
:save-column))
(in-package :lem-vi-mode/utils)

(defvar *previous-cwd* nil)
Expand Down Expand Up @@ -65,3 +66,9 @@
(rotatef start end))
(let ((killed-string (delete-character start (count-characters start end))))
(copy-to-clipboard-with-killring killed-string)))

(defmacro save-column (&body body)
(let ((column (gensym "COLUMN")))
`(let ((,column (point-column (current-point))))
(unwind-protect (progn ,@body)
(move-to-column (current-point) ,column)))))
35 changes: 35 additions & 0 deletions extensions/vi-mode/window.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
:lem)
(:import-from :lem-vi-mode/options
:option-value)
(:import-from :lem-vi-mode/utils
:save-column)
(:import-from :lem-core
:window-height-without-modeline)
(:export :move-to-window-top
:move-to-window-middle
:move-to-window-bottom
:move-to-window-bottom-below
:move-to-window-top-above
:scroll-line
:adjust-window-scroll))
(in-package :lem-vi-mode/window)

Expand Down Expand Up @@ -55,6 +60,36 @@
(when (window-has-following-lines-p window)
(previous-line (scroll-offset)))))

(defun move-to-window-bottom-below ()
(let ((window (current-window)))
(move-point (current-point) (window-end-point window))
(when (window-has-following-lines-p window)
(next-line 1))))

(defun move-to-window-top-above ()
(let ((window (current-window)))
(move-point (current-point) (window-start-point window))
(when (window-has-leading-lines-p window)
(previous-line 1))))

(defun scroll-line (line-number scroll-position)
"Scroll the line LINE-NUMBER to SCROLL-POSITION of the screen.
If LINE-NUMBER is NIL, scroll the current line.
SCROLL-POSITION can be one of :TOP :CENTER :BOTTOM.
The SCROLL-POSITION is influenced by the scrolloff option."
(clear-screens-of-window-list)
(when line-number
(save-column
(goto-line line-number)))
(let* ((window (current-window))
(scrolloff (scroll-offset window)))
(case scroll-position
(:top (window-recenter window :line scrolloff :from-bottom nil))
(:center (window-recenter window :line nil :from-bottom nil))
(:bottom (window-recenter window :line scrolloff :from-bottom t))))
(redraw-display)
t)

(defun adjust-window-scroll ()
(let* ((window (current-window))
(window-height (window-height* window))
Expand Down

0 comments on commit d3aa2e6

Please sign in to comment.