|
34 | 34 |
|
35 | 35 | (require 'cl-lib) |
36 | 36 |
|
| 37 | +(defgroup better-scroll nil |
| 38 | + "Improve user experience when scrolling window." |
| 39 | + :prefix "better-scroll-" |
| 40 | + :group 'tool |
| 41 | + :link '(url-link :tag "Repository" "https://github.com/jcs-elpa/better-scroll")) |
| 42 | + |
| 43 | +(defcustom better-scroll-align-type 'center |
| 44 | + "Type of scroll's aligment to cursor position." |
| 45 | + :type '(choice (const :tag "center" center) |
| 46 | + (const :tag "relative" relative)) |
| 47 | + :group 'better-scroll) |
| 48 | + |
| 49 | +;;; Util |
| 50 | + |
| 51 | +(defun better-scroll--goto-line (ln) |
| 52 | + "Goto LN line number." |
| 53 | + (goto-char (point-min)) (forward-line (1- ln))) |
| 54 | + |
37 | 55 | (defun better-scroll--recenter-positions (type) |
38 | 56 | "Return the recenter position value by TYPE." |
39 | 57 | (cl-case type (top '(top)) (middle '(middle)) (bottom '(bottom)))) |
|
48 | 66 | (let ((recenter-positions (better-scroll--recenter-positions type))) |
49 | 67 | (move-to-window-line-top-bottom))) |
50 | 68 |
|
| 69 | +(defun better-scroll--first-display-line () |
| 70 | + "Return the first display line number." |
| 71 | + (save-excursion (move-to-window-line 0) (line-number-at-pos nil t))) |
| 72 | + |
| 73 | +(defun better-scroll--line-diff-to-first () |
| 74 | + "Difference of first display line number and current line number." |
| 75 | + (- (line-number-at-pos nil t) (better-scroll--first-display-line))) |
| 76 | + |
| 77 | +;;; Core |
| 78 | + |
| 79 | +(defun better-scroll--do-relative (rel-ln) |
| 80 | + "Do the relative line action by REL-LN." |
| 81 | + (better-scroll--goto-line (+ (better-scroll--first-display-line) rel-ln))) |
| 82 | + |
| 83 | +(defun better-scroll--do-by-type (rel-ln) |
| 84 | + "Do scroll action by passing all needed params, REL-LN." |
| 85 | + (cl-case better-scroll-align-type |
| 86 | + ('center |
| 87 | + (better-scroll--move-to-window-line-top-bottom 'middle) |
| 88 | + (when (= (point) (point-max)) (better-scroll--recenter-top-bottom 'middle))) |
| 89 | + ('relative (better-scroll--do-relative rel-ln)))) |
| 90 | + |
51 | 91 | ;;;###autoload |
52 | 92 | (defun better-scroll-down () |
53 | 93 | "Scroll down." |
54 | 94 | (interactive) |
55 | | - (scroll-down) |
56 | | - (better-scroll--move-to-window-line-top-bottom 'middle)) |
| 95 | + (let ((rel-ln (better-scroll--line-diff-to-first))) |
| 96 | + (scroll-down) (better-scroll--do-by-type rel-ln))) |
57 | 97 |
|
58 | 98 | ;;;###autoload |
59 | 99 | (defun better-scroll-up () |
60 | 100 | "Scroll up." |
61 | 101 | (interactive) |
62 | | - (scroll-up) |
63 | | - (better-scroll--move-to-window-line-top-bottom 'middle) |
64 | | - (when (= (point) (point-max)) (better-scroll--recenter-top-bottom 'middle))) |
| 102 | + (let ((rel-ln (better-scroll--line-diff-to-first))) |
| 103 | + (scroll-up) (better-scroll--do-by-type rel-ln))) |
65 | 104 |
|
66 | 105 | ;;;###autoload |
67 | 106 | (defun better-scroll-down-other-window () |
|
0 commit comments