|
40 | 40 | :group 'tool |
41 | 41 | :link '(url-link :tag "Repository" "https://github.com/jcs-elpa/better-scroll")) |
42 | 42 |
|
| 43 | +(defcustom better-scroll-allow-boundry-movement t |
| 44 | + "Allow cursor moves to boundry point after moving to the beginning/end of buffer." |
| 45 | + :type 'boolean |
| 46 | + :group 'better-scroll) |
| 47 | + |
43 | 48 | (defcustom better-scroll-align-type 'center |
44 | 49 | "Type of scroll's aligment to cursor position." |
45 | 50 | :type '(choice (const :tag "center" center) |
|
48 | 53 |
|
49 | 54 | ;;; Util |
50 | 55 |
|
| 56 | +(defun better-scroll--goto-line (ln) |
| 57 | + "Goto LN line number." |
| 58 | + (goto-char (point-min)) (forward-line (1- ln))) |
| 59 | + |
51 | 60 | (defun better-scroll--recenter-positions (type) |
52 | 61 | "Return the recenter position value by TYPE." |
53 | 62 | (cl-case type (top '(top)) (middle '(middle)) (bottom '(bottom)))) |
|
62 | 71 | (let ((recenter-positions (better-scroll--recenter-positions type))) |
63 | 72 | (move-to-window-line-top-bottom))) |
64 | 73 |
|
| 74 | +(defun better-scroll--first-display-line () |
| 75 | + "Return the first display line number." |
| 76 | + (save-excursion (move-to-window-line 0) (line-number-at-pos nil t))) |
| 77 | + |
| 78 | +(defun better-scroll--line-diff-to-first () |
| 79 | + "Difference of first display line number and current line number." |
| 80 | + (- (line-number-at-pos nil t) (better-scroll--first-display-line))) |
| 81 | + |
65 | 82 | ;;; Core |
66 | 83 |
|
| 84 | +(defun better-scroll--do-relative (rel-ln) |
| 85 | + "Do the relative line action by REL-LN." |
| 86 | + (better-scroll--goto-line (+ (better-scroll--first-display-line) rel-ln))) |
| 87 | + |
| 88 | +(defun better-scroll--do-by-type (rel-ln) |
| 89 | + "Do scroll action by passing all needed params, REL-LN." |
| 90 | + (cl-case better-scroll-align-type |
| 91 | + ('center |
| 92 | + (better-scroll--move-to-window-line-top-bottom 'middle) |
| 93 | + (when (= (point) (point-max)) (better-scroll--recenter-top-bottom 'middle))) |
| 94 | + ('relative (better-scroll--do-relative rel-ln)))) |
| 95 | + |
| 96 | +(defun better-scroll--move-boundry (dc fnc) |
| 97 | + "Move boundry by direction (DC) and function (FNC)." |
| 98 | + (let ((prev-pt (point)) (prev-col (current-column))) |
| 99 | + (funcall fnc) |
| 100 | + (move-to-column prev-col) |
| 101 | + (when (and better-scroll-allow-boundry-movement (= (point) prev-pt)) |
| 102 | + (goto-char (cl-case dc ('down (point-min)) ('up (point-max))))))) |
| 103 | + |
67 | 104 | ;;;###autoload |
68 | 105 | (defun better-scroll-down () |
69 | 106 | "Scroll down." |
70 | 107 | (interactive) |
71 | | - (let ((scroll-preserve-screen-position (equal better-scroll-align-type 'relative))) |
72 | | - (scroll-down) |
73 | | - (when (equal better-scroll-align-type 'center) |
74 | | - (better-scroll--move-to-window-line-top-bottom 'middle)))) |
| 108 | + (better-scroll--move-boundry |
| 109 | + 'down |
| 110 | + (lambda () |
| 111 | + (let ((rel-ln (better-scroll--line-diff-to-first))) |
| 112 | + (ignore-errors (scroll-down)) |
| 113 | + (better-scroll--do-by-type rel-ln))))) |
75 | 114 |
|
76 | 115 | ;;;###autoload |
77 | 116 | (defun better-scroll-up () |
78 | 117 | "Scroll up." |
79 | 118 | (interactive) |
80 | | - (let ((scroll-preserve-screen-position (equal better-scroll-align-type 'relative))) |
81 | | - (scroll-up) |
82 | | - (when (equal better-scroll-align-type 'center) |
83 | | - (better-scroll--move-to-window-line-top-bottom 'middle) |
84 | | - (when (= (point) (point-max)) (better-scroll--recenter-top-bottom 'middle))))) |
| 119 | + (better-scroll--move-boundry |
| 120 | + 'up |
| 121 | + (lambda () |
| 122 | + (let ((rel-ln (better-scroll--line-diff-to-first))) |
| 123 | + (ignore-errors (scroll-up)) |
| 124 | + (better-scroll--do-by-type rel-ln))))) |
85 | 125 |
|
86 | 126 | ;;;###autoload |
87 | 127 | (defun better-scroll-down-other-window () |
|
0 commit comments