From 791397f051aa6533f6f8c58d3a75ac77bc21f90b Mon Sep 17 00:00:00 2001 From: Ivan Prikaznov <77636647+Prikaz98@users.noreply.github.com> Date: Mon, 10 Feb 2025 12:11:06 +0100 Subject: [PATCH] recenter-top-bottom (emacs-mode) (#1767) * recenter-top-bottom Emacs default behavior of (C-l recenter-top-bottom) * fix: window-recenter-top-bottom should return smt * return prev keymap * removed unused variable --- src/commands/window.lisp | 7 +++++++ src/internal-packages.lisp | 1 + src/window/virtual-line.lisp | 14 ++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/src/commands/window.lisp b/src/commands/window.lisp index 19b0da718..8337c0c5f 100644 --- a/src/commands/window.lisp +++ b/src/commands/window.lisp @@ -124,6 +124,13 @@ (redraw-display) t) +(define-command recenter-top-bottom (p) (:universal-nil) + "Scroll so that the cursor is in the middle/top/bottom." + (clear-screens-of-window-list) + (unless p (window-recenter-top-bottom (current-window))) + (redraw-display) + t) + (define-command split-active-window-vertically (&optional n) (:universal-nil) "Split the current window vertically." (split-window-vertically (current-window) :height n) diff --git a/src/internal-packages.lisp b/src/internal-packages.lisp index 41c2416f7..724edba1d 100644 --- a/src/internal-packages.lisp +++ b/src/internal-packages.lisp @@ -353,6 +353,7 @@ ;; virtual-line (:export :window-recenter + :window-recenter-top-bottom :window-cursor-x :window-cursor-y :backward-line-wrap diff --git a/src/window/virtual-line.lisp b/src/window/virtual-line.lisp index 381c69783..3d314759b 100644 --- a/src/window/virtual-line.lisp +++ b/src/window/virtual-line.lisp @@ -21,6 +21,20 @@ If FROM-BOTTOM is T, start counting from the bottom." (window-scroll window n) n))) +(defun window-recenter-top-bottom (window) + "In first call recenter WINDOW to the middle line. +If cursor is already in the middle of WINDOW then move cursor in the top position. +If cursor is on top then move move WINDOW to the bottom." + (let* ((line (window-cursor-y window)) + (window-height (window-height-without-modeline window)) + (middle (floor window-height 2)) + (scrolloff (min (floor (/ (window-height window) 2)) 0)) + (top 0)) + (cond + ((= line middle) (window-recenter window :line scrolloff :from-bottom nil)) + ((= line top) (window-recenter window :line scrolloff :from-bottom t)) + (t (window-recenter window :line nil :from-bottom nil))))) + (defun %calc-window-cursor-x (point window) "Return (values cur-x next). the 'next' is a flag if the cursor goes to next line because it is at the end of width."