From 0472a32f0cb5811d4b989e32c0d8596a887934b8 Mon Sep 17 00:00:00 2001 From: sakurawald Date: Mon, 9 Dec 2024 14:39:48 +0800 Subject: [PATCH] feature: recenter line if jump target point is not inside window. (vi-mode) --- extensions/vi-mode/commands.lisp | 11 +++++++++-- extensions/vi-mode/window.lisp | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/extensions/vi-mode/commands.lisp b/extensions/vi-mode/commands.lisp index 81aa461d3..a9f0b3b80 100644 --- a/extensions/vi-mode/commands.lisp +++ b/extensions/vi-mode/commands.lisp @@ -1019,6 +1019,11 @@ on the same line or at eol if there are none." (line-start p)))))) (move-to-column (current-point) column t))) +(defun recenter-line-if-point-not-inside-window (point &optional (window (current-window))) + (when point + (unless (lem-vi-mode/window::point-inside-window-p point window) + (vi-scroll-line-to-center)))) + (define-command vi-jumps () () (line-end (current-point)) (lem:message-buffer (with-output-to-string (s) @@ -1026,11 +1031,13 @@ on the same line or at eol if there are none." (define-command vi-jump-back (&optional (n 1)) (:universal) (dotimes (i n) - (jump-back))) + (let ((target-point (jump-back))) + (recenter-line-if-point-not-inside-window target-point)))) (define-command vi-jump-next (&optional (n 1)) (:universal) (dotimes (i n) - (jump-next))) + (let ((target-point (jump-next))) + (recenter-line-if-point-not-inside-window target-point)))) (define-motion vi-jump-previous () () (:jump t) diff --git a/extensions/vi-mode/window.lisp b/extensions/vi-mode/window.lisp index 322d31522..68f9c47f0 100644 --- a/extensions/vi-mode/window.lisp +++ b/extensions/vi-mode/window.lisp @@ -31,6 +31,15 @@ (move-to-next-virtual-line point (1- (window-height* window)) window) point)) +(defun line-inside-window-p (line &optional (window (current-window))) + (let ((start-line-num (line-number-at-point (window-start-point window))) + (end-line-num (line-number-at-point (window-end-point window)))) + (and (>= line start-line-num) + (<= line end-line-num)))) + +(defun point-inside-window-p (point &optional (window (current-window))) + (line-inside-window-p (line-number-at-point point))) + (defun window-has-following-lines-p (&optional (window (current-window))) (let ((end-point (window-end-point window))) (with-point ((p end-point))