]> crepu.dev Git - config.git/blame - djavu-asus/elpa/highlight-indentation-20210221.1418/highlight-indentation.el
Actualizado el Readme
[config.git] / djavu-asus / elpa / highlight-indentation-20210221.1418 / highlight-indentation.el
CommitLineData
53e6db90
DC
1;;; highlight-indentation.el --- Minor modes for highlighting indentation
2;; Author: Anton Johansson <anton.johansson@gmail.com> - http://antonj.se
3;; Created: Dec 15 23:42:04 2010
4;; Version: 0.7.0
5;; URL: https://github.com/antonj/Highlight-Indentation-for-Emacs
6;;
7;; This program is free software; you can redistribute it and/or
8;; modify it under the terms of the GNU General Public License as
9;; published by the Free Software Foundation; either version 2 of
10;; the License, or (at your option) any later version.
11;;
12;; This program is distributed in the hope that it will be
13;; useful, but WITHOUT ANY WARRANTY; without even the implied
14;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15;; PURPOSE. See the GNU General Public License for more details.
16;;
17;;; Commentary:
18;; Customize `highlight-indentation-face', and
19;; `highlight-indentation-current-column-face' to suit your theme.
20
21;;; Code:
22
23(defgroup highlight-indentation nil
24 "Highlight Indentation"
25 :prefix "highlight-indentation-"
26 :group 'basic-faces)
27
28(defface highlight-indentation-face
29 ;; Fringe has non intrusive color in most color-themes
30 '((t :inherit fringe))
31 "Basic face for highlighting indentation guides."
32 :group 'highlight-indentation)
33
34(defcustom highlight-indentation-offset
35 (if (and (boundp 'standard-indent) standard-indent) standard-indent 2)
36 "Default indentation offset, used if no other can be found from
37 major mode. This value is always used by
38 `highlight-indentation-mode' if set buffer local. Set buffer
39 local with `highlight-indentation-set-offset'"
40 :type 'integer
41 :group 'highlight-indentation)
42
43(defcustom highlight-indentation-blank-lines nil
44 "Show indentation guides on blank lines. Experimental.
45
46Known issues:
47- Doesn't work well with completion popups that use overlays
48- Overlays on blank lines sometimes aren't cleaned up or updated perfectly
49 Can be refreshed by scrolling
50- Not yet implemented for highlight-indentation-current-column-mode
51- May not work perfectly near the bottom of the screen
52- Point appears after indent guides on blank lines"
53 :type 'boolean
54 :group 'highlight-indentation)
55
56(defvar highlight-indentation-overlay-priority 1)
57(defvar highlight-indentation-current-column-overlay-priority 2)
58
59(defconst highlight-indentation-hooks
60 '((after-change-functions (lambda (start end length)
61 (highlight-indentation-redraw-region
62 start end
63 'highlight-indentation-overlay
64 'highlight-indentation-put-overlays-region))
65 t t)
66 (window-scroll-functions (lambda (win start)
67 (highlight-indentation-redraw-window
68 win
69 'highlight-indentation-overlay
70 'highlight-indentation-put-overlays-region
71 start))
72 nil t)))
73
74(defun highlight-indentation-get-buffer-windows (&optional all-frames)
75 "Return a list of windows displaying the current buffer."
76 (get-buffer-window-list (current-buffer) 'no-minibuf all-frames))
77
78(defun highlight-indentation-delete-overlays-buffer (overlay)
79 "Delete all overlays in the current buffer."
80 (save-restriction
81 (widen)
82 (highlight-indentation-delete-overlays-region (point-min) (point-max) overlay)))
83
84(defun highlight-indentation-delete-overlays-region (start end overlay)
85 "Delete overlays between START and END."
86 (mapc #'(lambda (o)
87 (if (overlay-get o overlay) (delete-overlay o)))
88 (overlays-in start end)))
89
90(defun highlight-indentation-redraw-window (win overlay func &optional start)
91 "Redraw win starting from START."
92 (highlight-indentation-redraw-region (or start (window-start win)) (window-end win t) overlay func))
93
94(defun highlight-indentation-redraw-region (start end overlay func)
95 "Erase and read overlays between START and END."
96 (save-match-data
97 (save-excursion
98 (let ((inhibit-point-motion-hooks t)
99 (start (save-excursion (goto-char start) (beginning-of-line) (point)))
100
101 (end (save-excursion (goto-char end) (line-beginning-position 2))))
102 (highlight-indentation-delete-overlays-region start end overlay)
103 (funcall func start end overlay)))))
104
105(defun highlight-indentation-redraw-all-windows (overlay func &optional all-frames)
106 "Redraw the all windows showing the current buffer."
107 (dolist (win (highlight-indentation-get-buffer-windows all-frames))
108 (highlight-indentation-redraw-window win overlay func)))
109
110(defun highlight-indentation-put-overlays-region (start end overlay)
111 "Place overlays between START and END."
112 (goto-char end)
113 (let (o ;; overlay
114 (last-indent 0)
115 (last-char 0)
116 (pos (point))
117 (loop t))
118 (while (and loop
119 (>= pos start))
120 (save-excursion
121 (beginning-of-line)
122 (let ((c 0)
123 (cur-column (current-column)))
124 (while (and (setq c (char-after))
125 (integerp c)
126 (not (= 10 c)) ;; newline
127 (= 32 c)) ;; space
128 (when (= 0 (% cur-column highlight-indentation-offset))
129 (let ((p (point)))
130 (setq o (make-overlay p (+ p 1))))
131 (overlay-put o overlay t)
132 (overlay-put o 'priority highlight-indentation-overlay-priority)
133 (overlay-put o 'face 'highlight-indentation-face))
134 (forward-char)
135 (setq cur-column (current-column)))
136 (when (and highlight-indentation-blank-lines
137 (integerp c)
138 (or (= 10 c)
139 (= 13 c)))
140 (when (< cur-column last-indent)
141 (let ((column cur-column)
142 (s nil)
143 (show t)
144 num-spaces)
145 (while (< column last-indent)
146 (if (>= 0
147 (setq num-spaces
148 (%
149 (- last-indent column)
150 highlight-indentation-offset)))
151 (progn
152 (setq num-spaces (1- highlight-indentation-offset))
153 (setq show t))
154 (setq show nil))
155 (setq s (cons (concat
156 (if show
157 (propertize " "
158 'face
159 'highlight-indentation-face)
160 "")
161 (make-string num-spaces 32))
162 s))
163 (setq column (+ column num-spaces (if show 1 0))))
164 (setq s (apply 'concat (reverse s)))
165 (let ((p (point)))
166 (setq o (make-overlay p p)))
167 (overlay-put o overlay t)
168 (overlay-put o 'priority highlight-indentation-overlay-priority)
169 (overlay-put o 'after-string s))
170 (setq cur-column last-indent)))
171 (setq last-indent (* highlight-indentation-offset
172 (ceiling (/ (float cur-column)
173 highlight-indentation-offset))))))
174 (when (= pos start)
175 (setq loop nil))
176 (forward-line -1) ;; previous line
177 (setq pos (point)))))
178
179(defun highlight-indentation-guess-offset ()
180 "Get indentation offset of current buffer."
181 (cond ((and (eq major-mode 'python-mode) (boundp 'python-indent))
182 python-indent)
183 ((and (eq major-mode 'python-mode) (boundp 'py-indent-offset))
184 py-indent-offset)
185 ((and (eq major-mode 'python-mode) (boundp 'python-indent-offset))
186 python-indent-offset)
187 ((and (eq major-mode 'ruby-mode) (boundp 'ruby-indent-level))
188 ruby-indent-level)
189 ((and (eq major-mode 'scala-mode) (boundp 'scala-indent:step))
190 scala-indent:step)
191 ((and (eq major-mode 'scala-mode) (boundp 'scala-mode-indent:step))
192 scala-mode-indent:step)
193 ((and (or (eq major-mode 'scss-mode) (eq major-mode 'css-mode)) (boundp 'css-indent-offset))
194 css-indent-offset)
195 ((and (eq major-mode 'nxml-mode) (boundp 'nxml-child-indent))
196 nxml-child-indent)
197 ((and (eq major-mode 'coffee-mode) (boundp 'coffee-tab-width))
198 coffee-tab-width)
199 ((and (eq major-mode 'js-mode) (boundp 'js-indent-level))
200 js-indent-level)
201 ((and (eq major-mode 'js2-mode) (boundp 'js2-basic-offset))
202 js2-basic-offset)
203 ((and (fboundp 'derived-mode-class) (eq (derived-mode-class major-mode) 'sws-mode) (boundp 'sws-tab-width))
204 sws-tab-width)
205 ((and (eq major-mode 'web-mode) (boundp 'web-mode-markup-indent-offset))
206 web-mode-markup-indent-offset) ; other similar vars: web-mode-{css-indent,scripts}-offset
207 ((and (eq major-mode 'web-mode) (boundp 'web-mode-html-offset)) ; old var
208 web-mode-html-offset)
209 ((and (local-variable-p 'c-basic-offset) (boundp 'c-basic-offset))
210 c-basic-offset)
211 ((and (eq major-mode 'yaml-mode) (boundp 'yaml-indent-offset))
212 yaml-indent-offset)
213 ((and (eq major-mode 'elixir-mode) (boundp 'elixir-smie-indent-basic))
214 elixir-smie-indent-basic)
215 (t
216 (default-value 'highlight-indentation-offset))))
217
218;;;###autoload
219(define-minor-mode highlight-indentation-mode
220 "Highlight indentation minor mode highlights indentation based on spaces"
221 :lighter " ||"
222 (when (not highlight-indentation-mode) ;; OFF
223 (highlight-indentation-delete-overlays-buffer 'highlight-indentation-overlay)
224 (dolist (hook highlight-indentation-hooks)
225 (remove-hook (car hook) (nth 1 hook) (nth 3 hook))))
226
227 (when highlight-indentation-mode ;; ON
228 (when (not (local-variable-p 'highlight-indentation-offset))
229 (set (make-local-variable 'highlight-indentation-offset)
230 (highlight-indentation-guess-offset)))
231
232 ;; Setup hooks
233 (dolist (hook highlight-indentation-hooks)
234 (apply 'add-hook hook))
235 (highlight-indentation-redraw-all-windows 'highlight-indentation-overlay
236 'highlight-indentation-put-overlays-region)))
237
238;;;###autoload
239(defun highlight-indentation-set-offset (offset)
240 "Set indentation offset locally in buffer, will prevent
241highlight-indentation from trying to guess indentation offset
242from major mode"
243 (interactive
244 (if (and current-prefix-arg (not (consp current-prefix-arg)))
245 (list (prefix-numeric-value current-prefix-arg))
246 (list (read-number "Indentation offset: "))))
247 (set (make-local-variable 'highlight-indentation-offset) offset)
248 (when highlight-indentation-mode
249 (highlight-indentation-mode)))
250
251;;; This minor mode will highlight the indentation of the current line
252;;; as a vertical bar (grey background color) aligned with the column of the
253;;; first character of the current line.
254(defface highlight-indentation-current-column-face
255 ;; Fringe has non intrusive color in most color-themes
256 '((t (:background "black")))
257 "Basic face for highlighting indentation guides."
258 :group 'highlight-indentation)
259
260(defconst highlight-indentation-current-column-hooks
261 '((post-command-hook (lambda ()
262 (highlight-indentation-redraw-all-windows 'highlight-indentation-current-column-overlay
263 'highlight-indentation-current-column-put-overlays-region)) nil t)))
264
265(defun highlight-indentation-current-column-put-overlays-region (start end overlay)
266 "Place overlays between START and END."
267 (let (o ;; overlay
268 (last-indent 0)
269 (indent (save-excursion (back-to-indentation) (current-column)))
270 (pos start))
271 (goto-char start)
272 ;; (message "doing it %d" indent)
273 (while (< pos end)
274 (beginning-of-line)
275 (while (and (integerp (char-after))
276 (not (= 10 (char-after))) ;; newline
277 (= 32 (char-after))) ;; space
278 (when (= (current-column) indent)
279 (setq pos (point)
280 last-indent pos
281 o (make-overlay pos (+ pos 1)))
282 (overlay-put o overlay t)
283 (overlay-put o 'priority highlight-indentation-current-column-overlay-priority)
284 (overlay-put o 'face 'highlight-indentation-current-column-face))
285 (forward-char))
286 (forward-line) ;; Next line
287 (setq pos (point)))))
288
289;;;###autoload
290(define-minor-mode highlight-indentation-current-column-mode
291 "Highlight Indentation minor mode displays a vertical bar
292corresponding to the indentation of the current line"
293 :lighter " |"
294
295 (when (not highlight-indentation-current-column-mode) ;; OFF
296 (highlight-indentation-delete-overlays-buffer 'highlight-indentation-current-column-overlay)
297 (dolist (hook highlight-indentation-current-column-hooks)
298 (remove-hook (car hook) (nth 1 hook) (nth 3 hook))))
299
300 (when highlight-indentation-current-column-mode ;; ON
301 (when (not (local-variable-p 'highlight-indentation-offset))
302 (set (make-local-variable 'highlight-indentation-offset)
303 (highlight-indentation-guess-offset)))
304
305 ;; Setup hooks
306 (dolist (hook highlight-indentation-current-column-hooks)
307 (apply 'add-hook hook))
308 (highlight-indentation-redraw-all-windows 'highlight-indentation-current-column-overlay
309 'highlight-indentation-current-column-put-overlays-region)))
310
311(provide 'highlight-indentation)
312
313;;; highlight-indentation.el ends here