-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathnlinum-relative.el
177 lines (148 loc) · 6.42 KB
/
nlinum-relative.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
;;; nlinum-relative.el --- Relative line number with nlinum -*- lexical-binding: t; -*-
;; Copyright (C) 2016 codefalling
;; Author: codefalling <[email protected]>
;; Keywords: convenience
;; Version: 0.1
;; Package-Requires: ((emacs "24.4") (nlinum "1.5"))
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
(require 'nlinum)
(defgroup nlinum-relative nil
"Show relative line numbers with nlinum."
:group 'convenience)
(defcustom nlinum-relative-current-symbol ""
"The symbol you want to show on the current line, by default it is empty.
You can use any string like \"->\". If this variable is empty string,
nlinum-releative will show the real line number at current line."
:type 'string
:group 'nlinum-relative)
(defcustom nlinum-relative-redisplay-delay 0.2
"nlinum-relative-mode only redisplay when idle with a delay, default value is 0.2"
:type 'number
:group 'nlinum-relative)
;;;; Faces
(defface nlinum-relative-current-face
'((t :inherit linum :foreground "#CAE682" :background "#444444" :weight bold))
"Face for displaying current line."
:group 'nlinum-relative)
(defcustom nlinum-relative-offset 0
"relative offset number, you set it to 1 if want 0, 2, 3, 4 etc"
:type 'number
:group 'nlinum-relative)
(defvar nlinum-relative--current-line 0
"Store current line number before jit-lock.")
(make-variable-buffer-local 'nlinum-relative--current-line)
(defvar nlinum-relative--store-format-function nlinum-format-function
"Store old `nlinum-relative-format-function'")
(defvar nlinum-relative--format-function
(lambda (line width)
(let* ((line-display (abs (- line nlinum-relative--current-line) ))
(is-current-line? (eq line-display 0))
(line-display (if is-current-line?
nlinum-relative--current-line
(+ nlinum-relative-offset line-display)))
(str (if (and (not (string-equal nlinum-relative-current-symbol "")) is-current-line?)
nlinum-relative-current-symbol (format nlinum-format line-display)))
)
(when (< (length str) width)
;; Left pad to try and right-align the line-numbers.
(setq str (concat (make-string (- width (length str)) ?\ ) str)))
(if is-current-line?
(put-text-property 0 width 'face 'nlinum-relative-current-face str)
(put-text-property 0 width 'face 'linum str))
str))
"nlinum-relative to replace nlinum-format-function")
(defun nlinum-relative--save-current-line ()
"Save current line before jit-lock"
(setq nlinum-relative--current-line (string-to-number (format-mode-line "%l")))
)
(defun nlinum-relative-reflush ()
"Reflush display on current window"
(nlinum--after-change)
(nlinum-relative--save-current-line)
(let* ((start (window-start))
(end (window-end))
(out-of-range? (< (point-max) end)) ;; out-of-range in magit commit window
(start (if out-of-range? (point-min) start))
(end (if out-of-range? (point-max) end))
)
(with-silent-modifications
(remove-text-properties
start end '(fontified)))
))
(setq nlinum-relative--timer nil)
(make-local-variable 'nlinum-relative--timer)
;;;###autoload
(defun nlinum-relative-on ()
"Turn ON nlinum-relative."
(interactive)
(when (not (bound-and-true-p nlinum-relative-mode)) (nlinum-relative-mode))
;; (advice-add 'jit-lock-fontify-now :before #'nlinum-relative--save-current-line)
(setq nlinum-format-function nlinum-relative--format-function)
(when nlinum-relative--timer
(cancel-timer nlinum-relative--timer)
(setq nlinum-relative--timer nil))
(setq nlinum-relative--timer (run-with-idle-timer nlinum-relative-redisplay-delay t 'nlinum-relative-reflush)))
;;;###autoload
(defun nlinum-relative-off ()
"Turn OFF nlinum-relative."
(interactive)
(advice-remove 'jit-lock-fontify-now #'nlinum-relative--save-current-line)
(setq nlinum-format-function nlinum-relative--store-format-function)
(nlinum-relative-reflush)
(when nlinum-relative--timer
(cancel-timer nlinum-relative--timer)
(setq nlinum-relative--timer nil)
))
;;;###autoload
(defun nlinum-relative-toggle ()
"Toggle between linum-relative and linum."
(interactive)
(if (eq nlinum-format-function nlinum-relative--format-function)
(nlinum-relative-off)
(nlinum-relative-on)))
;;;###autoload
(define-minor-mode nlinum-relative-mode
"Display relative line numbers for current buffer."
:group 'nlinum-relative
(if (bound-and-true-p nlinum-relative-mode)
(progn
(nlinum-relative-on)
(nlinum-mode 1))
(nlinum-relative-off)
))
;;;###autoload
(define-globalized-minor-mode global-nlinum-relative-mode nlinum-relative-mode
(lambda () (unless (minibufferp) (nlinum-relative-mode))))
;;;###autoload
(defun nlinum-relative-setup-evil ()
"Setup nlinum-relative-mode for evil"
(interactive)
(add-hook 'evil-insert-state-entry-hook
(lambda () (when (bound-and-true-p nlinum-relative-mode) (nlinum-relative-off))))
(add-hook 'evil-insert-state-exit-hook
(lambda () (when (bound-and-true-p nlinum-relative-mode) (nlinum-relative-on))))
(add-hook 'evil-normal-state-entry-hook
(lambda () (when (bound-and-true-p nlinum-relative-mode) (nlinum-relative-on))))
(add-hook 'evil-normal-state-exit-hook
(lambda () (when (bound-and-true-p nlinum-relative-mode) (nlinum-relative-off))))
(add-hook 'evil-visual-state-entry-hook
(lambda () (when (bound-and-true-p nlinum-relative-mode) (nlinum-relative-on))))
(add-hook 'evil-visual-state-exit-hook
(lambda () (when (bound-and-true-p nlinum-relative-mode) (nlinum-relative-off))))
(add-hook 'nlinum-relative-mode-hook (lambda ()
(when (evil-normal-state-p) (nlinum-relative-on))))
)
(provide 'nlinum-relative)
;;; nlinum-relative.el ends here