]> code.delx.au - gnu-emacs/blob - lisp/whitespace.el
* net/tramp.el (tramp-handle-start-file-process): Set
[gnu-emacs] / lisp / whitespace.el
1 ;;; whitespace.el --- minor mode to visualize TAB, (HARD) SPACE, NEWLINE
2
3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5
6 ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br>
7 ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br>
8 ;; Keywords: data, wp
9 ;; Version: 11.2
10 ;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
11
12 ;; This file is part of GNU Emacs.
13
14 ;; GNU Emacs is free software: you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation, either version 3 of the License, or
17 ;; (at your option) any later version.
18
19 ;; GNU Emacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
23
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
26
27 ;;; Commentary:
28
29 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30 ;;
31 ;; Introduction
32 ;; ------------
33 ;;
34 ;; This package is a minor mode to visualize blanks (TAB, (HARD) SPACE
35 ;; and NEWLINE).
36 ;;
37 ;; whitespace uses two ways to visualize blanks: faces and display
38 ;; table.
39 ;;
40 ;; * Faces are used to highlight the background with a color.
41 ;; whitespace uses font-lock to highlight blank characters.
42 ;;
43 ;; * Display table changes the way a character is displayed, that is,
44 ;; it provides a visual mark for characters, for example, at the end
45 ;; of line (?\xB6), at SPACEs (?\xB7) and at TABs (?\xBB).
46 ;;
47 ;; The `whitespace-style' variable selects which way blanks are
48 ;; visualized.
49 ;;
50 ;; Note that when whitespace is turned on, whitespace saves the
51 ;; font-lock state, that is, if font-lock is on or off. And
52 ;; whitespace restores the font-lock state when it is turned off. So,
53 ;; if whitespace is turned on and font-lock is off, whitespace also
54 ;; turns on the font-lock to highlight blanks, but the font-lock will
55 ;; be turned off when whitespace is turned off. Thus, turn on
56 ;; font-lock before whitespace is on, if you want that font-lock
57 ;; continues on after whitespace is turned off.
58 ;;
59 ;; When whitespace is on, it takes care of highlighting some special
60 ;; characters over the default mechanism of `nobreak-char-display'
61 ;; (which see) and `show-trailing-whitespace' (which see).
62 ;;
63 ;; There are two ways of using whitespace: local and global.
64 ;;
65 ;; * Local whitespace affects only the current buffer.
66 ;;
67 ;; * Global whitespace affects all current and future buffers. That
68 ;; is, if you turn on global whitespace and then create a new
69 ;; buffer, the new buffer will also have whitespace on. The
70 ;; `whitespace-global-modes' variable controls which major-mode will
71 ;; be automagically turned on.
72 ;;
73 ;; You can mix the local and global usage without any conflict. But
74 ;; local whitespace has priority over global whitespace. Whitespace
75 ;; mode is active in a buffer if you have enabled it in that buffer or
76 ;; if you have enabled it globally.
77 ;;
78 ;; When global and local whitespace are on:
79 ;;
80 ;; * if local whitespace is turned off, whitespace is turned off for
81 ;; the current buffer only.
82 ;;
83 ;; * if global whitespace is turned off, whitespace continues on only
84 ;; in the buffers in which local whitespace is on.
85 ;;
86 ;; To use whitespace, insert in your ~/.emacs:
87 ;;
88 ;; (require 'whitespace-mode)
89 ;;
90 ;; Or autoload at least one of the commands`whitespace-mode',
91 ;; `whitespace-toggle-options', `global-whitespace-mode' or
92 ;; `global-whitespace-toggle-options'. For example:
93 ;;
94 ;; (autoload 'whitespace-mode "whitespace"
95 ;; "Toggle whitespace visualization." t)
96 ;; (autoload 'whitespace-toggle-options "whitespace"
97 ;; "Toggle local `whitespace-mode' options." t)
98 ;;
99 ;; whitespace was inspired by:
100 ;;
101 ;; whitespace.el Rajesh Vaidheeswarran <rv@gnu.org>
102 ;; Warn about and clean bogus whitespaces in the file
103 ;; (inspired the idea to warn and clean some blanks)
104 ;; This was the original `whitespace.el' which was replaced by
105 ;; `blank-mode.el'. And later `blank-mode.el' was renamed to
106 ;; `whitespace.el'.
107 ;;
108 ;; show-whitespace-mode.el Aurelien Tisne <aurelien.tisne@free.fr>
109 ;; Simple mode to highlight whitespaces
110 ;; (inspired the idea to use font-lock)
111 ;;
112 ;; whitespace-mode.el Lawrence Mitchell <wence@gmx.li>
113 ;; Major mode for editing Whitespace
114 ;; (inspired the idea to use display table)
115 ;;
116 ;; visws.el Miles Bader <miles@gnu.org>
117 ;; Make whitespace visible
118 ;; (handle display table, his code was modified, but the main
119 ;; idea was kept)
120 ;;
121 ;;
122 ;; Using whitespace
123 ;; ----------------
124 ;;
125 ;; There is no problem if you mix local and global minor mode usage.
126 ;;
127 ;; * LOCAL whitespace:
128 ;; + To toggle whitespace options locally, type:
129 ;;
130 ;; M-x whitespace-toggle-options RET
131 ;;
132 ;; + To activate whitespace locally, type:
133 ;;
134 ;; C-u 1 M-x whitespace-mode RET
135 ;;
136 ;; + To deactivate whitespace locally, type:
137 ;;
138 ;; C-u 0 M-x whitespace-mode RET
139 ;;
140 ;; + To toggle whitespace locally, type:
141 ;;
142 ;; M-x whitespace-mode RET
143 ;;
144 ;; * GLOBAL whitespace:
145 ;; + To toggle whitespace options globally, type:
146 ;;
147 ;; M-x global-whitespace-toggle-options RET
148 ;;
149 ;; + To activate whitespace globally, type:
150 ;;
151 ;; C-u 1 M-x global-whitespace-mode RET
152 ;;
153 ;; + To deactivate whitespace globally, type:
154 ;;
155 ;; C-u 0 M-x global-whitespace-mode RET
156 ;;
157 ;; + To toggle whitespace globally, type:
158 ;;
159 ;; M-x global-whitespace-mode RET
160 ;;
161 ;; There are also the following useful commands:
162 ;;
163 ;; `whitespace-newline-mode'
164 ;; Toggle newline minor mode visualization ("nl" on modeline).
165 ;;
166 ;; `global-whitespace-newline-mode'
167 ;; Toggle newline global minor mode visualization ("NL" on modeline).
168 ;;
169 ;; `whitespace-report'
170 ;; Report some blank problems in buffer.
171 ;;
172 ;; `whitespace-report-region'
173 ;; Report some blank problems in a region.
174 ;;
175 ;; `whitespace-cleanup'
176 ;; Cleanup some blank problems in all buffer or at region.
177 ;;
178 ;; `whitespace-cleanup-region'
179 ;; Cleanup some blank problems at region.
180 ;;
181 ;; The problems, which are cleaned up, are:
182 ;;
183 ;; 1. empty lines at beginning of buffer.
184 ;; 2. empty lines at end of buffer.
185 ;; If `whitespace-style' includes the value `empty', remove all
186 ;; empty lines at beginning and/or end of buffer.
187 ;;
188 ;; 3. 8 or more SPACEs at beginning of line.
189 ;; If `whitespace-style' includes the value `indentation':
190 ;; replace 8 or more SPACEs at beginning of line by TABs, if
191 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
192 ;; SPACEs.
193 ;; If `whitespace-style' includes the value `indentation::tab',
194 ;; replace 8 or more SPACEs at beginning of line by TABs.
195 ;; If `whitespace-style' includes the value `indentation::space',
196 ;; replace TABs by SPACEs.
197 ;;
198 ;; 4. SPACEs before TAB.
199 ;; If `whitespace-style' includes the value `space-before-tab':
200 ;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
201 ;; otherwise, replace TABs by SPACEs.
202 ;; If `whitespace-style' includes the value
203 ;; `space-before-tab::tab', replace SPACEs by TABs.
204 ;; If `whitespace-style' includes the value
205 ;; `space-before-tab::space', replace TABs by SPACEs.
206 ;;
207 ;; 5. SPACEs or TABs at end of line.
208 ;; If `whitespace-style' includes the value `trailing', remove all
209 ;; SPACEs or TABs at end of line.
210 ;;
211 ;; 6. 8 or more SPACEs after TAB.
212 ;; If `whitespace-style' includes the value `space-after-tab':
213 ;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
214 ;; otherwise, replace TABs by SPACEs.
215 ;; If `whitespace-style' includes the value `space-after-tab::tab',
216 ;; replace SPACEs by TABs.
217 ;; If `whitespace-style' includes the value
218 ;; `space-after-tab::space', replace TABs by SPACEs.
219 ;;
220 ;;
221 ;; Hooks
222 ;; -----
223 ;;
224 ;; whitespace has the following hook variables:
225 ;;
226 ;; `whitespace-mode-hook'
227 ;; It is evaluated always when whitespace is turned on locally.
228 ;;
229 ;; `global-whitespace-mode-hook'
230 ;; It is evaluated always when whitespace is turned on globally.
231 ;;
232 ;; `whitespace-load-hook'
233 ;; It is evaluated after whitespace package is loaded.
234 ;;
235 ;;
236 ;; Options
237 ;; -------
238 ;;
239 ;; Below it's shown a brief description of whitespace options, please,
240 ;; see the options declaration in the code for a long documentation.
241 ;;
242 ;; `whitespace-style' Specify which kind of blank is
243 ;; visualized.
244 ;;
245 ;; `whitespace-space' Face used to visualize SPACE.
246 ;;
247 ;; `whitespace-hspace' Face used to visualize HARD SPACE.
248 ;;
249 ;; `whitespace-tab' Face used to visualize TAB.
250 ;;
251 ;; `whitespace-newline' Face used to visualize NEWLINE char
252 ;; mapping.
253 ;;
254 ;; `whitespace-trailing' Face used to visualize trailing
255 ;; blanks.
256 ;;
257 ;; `whitespace-line' Face used to visualize "long" lines.
258 ;;
259 ;; `whitespace-space-before-tab' Face used to visualize SPACEs
260 ;; before TAB.
261 ;;
262 ;; `whitespace-indentation' Face used to visualize 8 or more
263 ;; SPACEs at beginning of line.
264 ;;
265 ;; `whitespace-empty' Face used to visualize empty lines at
266 ;; beginning and/or end of buffer.
267 ;;
268 ;; `whitespace-space-after-tab' Face used to visualize 8 or more
269 ;; SPACEs after TAB.
270 ;;
271 ;; `whitespace-space-regexp' Specify SPACE characters regexp.
272 ;;
273 ;; `whitespace-hspace-regexp' Specify HARD SPACE characters regexp.
274 ;;
275 ;; `whitespace-tab-regexp' Specify TAB characters regexp.
276 ;;
277 ;; `whitespace-trailing-regexp' Specify trailing characters regexp.
278 ;;
279 ;; `whitespace-space-before-tab-regexp' Specify SPACEs before TAB
280 ;; regexp.
281 ;;
282 ;; `whitespace-indentation-regexp' Specify regexp for 8 or more
283 ;; SPACEs at beginning of line.
284 ;;
285 ;; `whitespace-empty-at-bob-regexp' Specify regexp for empty lines
286 ;; at beginning of buffer.
287 ;;
288 ;; `whitespace-empty-at-eob-regexp' Specify regexp for empty lines
289 ;; at end of buffer.
290 ;;
291 ;; `whitespace-space-after-tab-regexp' Specify regexp for 8 or more
292 ;; SPACEs after TAB.
293 ;;
294 ;; `whitespace-line-column' Specify column beyond which the line
295 ;; is highlighted.
296 ;;
297 ;; `whitespace-display-mappings' Specify an alist of mappings
298 ;; for displaying characters.
299 ;;
300 ;; `whitespace-global-modes' Modes for which global
301 ;; `whitespace-mode' is automagically
302 ;; turned on.
303 ;;
304 ;; `whitespace-action' Specify which action is taken when a
305 ;; buffer is visited, killed or written.
306 ;;
307 ;;
308 ;; Acknowledgements
309 ;; ----------------
310 ;;
311 ;; Thanks to Stephen Deasey <sdeasey@gmail.com> for the
312 ;; `indent-tabs-mode' usage suggestion.
313 ;;
314 ;; Thanks to Eric Cooper <ecc@cmu.edu> for the suggestion to have hook
315 ;; actions when buffer is written or killed as the original whitespace
316 ;; package had.
317 ;;
318 ;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
319 ;; lines tail. See EightyColumnRule (EmacsWiki).
320 ;;
321 ;; Thanks to Juri Linkov <juri@jurta.org> for suggesting:
322 ;; * `define-minor-mode'.
323 ;; * `global-whitespace-*' name for global commands.
324 ;;
325 ;; Thanks to Robert J. Chassell <bob@gnu.org> for doc fix and testing.
326 ;;
327 ;; Thanks to Drew Adams <drew.adams@oracle.com> for toggle commands
328 ;; suggestion.
329 ;;
330 ;; Thanks to Antti Kaihola <antti.kaihola@linux-aktivaattori.org> for
331 ;; helping to fix `find-file-hooks' reference.
332 ;;
333 ;; Thanks to Andreas Roehler <andreas.roehler@easy-emacs.de> for
334 ;; indicating defface byte-compilation warnings.
335 ;;
336 ;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight
337 ;; "long" lines. See EightyColumnRule (EmacsWiki).
338 ;;
339 ;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
340 ;; newline character mapping.
341 ;;
342 ;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
343 ;; whitespace-mode.el on XEmacs.
344 ;;
345 ;; Thanks to Miles Bader <miles@gnu.org> for handling display table via
346 ;; visws.el (his code was modified, but the main idea was kept).
347 ;;
348 ;; Thanks to:
349 ;; Rajesh Vaidheeswarran <rv@gnu.org> (original) whitespace.el
350 ;; Aurelien Tisne <aurelien.tisne@free.fr> show-whitespace-mode.el
351 ;; Lawrence Mitchell <wence@gmx.li> whitespace-mode.el
352 ;; Miles Bader <miles@gnu.org> visws.el
353 ;; And to all people who contributed with them.
354 ;;
355 ;;
356 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
357
358 ;;; code:
359
360 \f
361 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
362 ;;;; User Variables:
363
364
365 ;;; Interface to the command system
366
367
368 (defgroup whitespace nil
369 "Visualize blanks (TAB, (HARD) SPACE and NEWLINE)."
370 :link '(emacs-library-link :tag "Source Lisp File" "whitespace.el")
371 :version "23.1"
372 :group 'wp
373 :group 'data)
374
375
376 (defcustom whitespace-style
377 '(tabs spaces trailing lines space-before-tab newline
378 indentation empty space-after-tab
379 space-mark tab-mark newline-mark)
380 "*Specify which kind of blank is visualized.
381
382 It's a list containing some or all of the following values:
383
384 trailing trailing blanks are visualized via faces.
385
386 tabs TABs are visualized via faces.
387
388 spaces SPACEs and HARD SPACEs are visualized via
389 faces.
390
391 lines lines whose have columns beyond
392 `whitespace-line-column' are highlighted via
393 faces .
394 Whole line is highlighted.
395 It has precedence over `lines-tail' (see
396 below).
397
398 lines-tail lines whose have columns beyond
399 `whitespace-line-column' are highlighted via
400 faces.
401 But only the part of line which goes
402 beyond `whitespace-line-column' column.
403 It has effect only if `lines' (see above)
404 is not present in `whitespace-style'.
405
406 newline NEWLINEs are visualized via faces.
407
408 empty empty lines at beginning and/or end of buffer
409 are visualized via faces.
410
411 indentation::tab 8 or more SPACEs at beginning of line are
412 visualized via faces.
413
414 indentation::space TABs at beginning of line are visualized via
415 faces.
416
417 indentation 8 or more SPACEs at beginning of line are
418 visualized, if `indent-tabs-mode' (which see)
419 is non-nil; otherwise, TABs at beginning of
420 line are visualized via faces.
421
422 space-after-tab::tab 8 or more SPACEs after a TAB are
423 visualized via faces.
424
425 space-after-tab::space TABs are visualized when occurs 8 or
426 more SPACEs after a TAB via faces.
427
428 space-after-tab 8 or more SPACEs after a TAB are
429 visualized, if `indent-tabs-mode'
430 (which see) is non-nil; otherwise,
431 the TABs are visualized via faces.
432
433 space-before-tab::tab SPACEs before TAB are visualized via
434 faces.
435
436 space-before-tab::space TABs are visualized when occurs SPACEs
437 before TAB via faces.
438
439 space-before-tab SPACEs before TAB are visualized, if
440 `indent-tabs-mode' (which see) is
441 non-nil; otherwise, the TABs are
442 visualized via faces.
443
444 space-mark SPACEs and HARD SPACEs are visualized via
445 display table.
446
447 tab-mark TABs are visualized via display table.
448
449 newline-mark NEWLINEs are visualized via display table.
450
451 Any other value is ignored.
452
453 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs via faces and
454 via display table.
455
456 There is an evaluation order for some values, if some values are
457 included in `whitespace-style' list. For example, if
458 indentation, indentation::tab and/or indentation::space are
459 included in `whitespace-style' list. The evaluation order for
460 these values is:
461
462 * For indentation:
463 1. indentation
464 2. indentation::tab
465 3. indentation::space
466
467 * For SPACEs after TABs:
468 1. space-after-tab
469 2. space-after-tab::tab
470 3. space-after-tab::space
471
472 * For SPACEs before TABs:
473 1. space-before-tab
474 2. space-before-tab::tab
475 3. space-before-tab::space
476
477 So, for example, if indentation and indentation::space are
478 included in `whitespace-style' list, the indentation value is
479 evaluated instead of indentation::space value.
480
481 See also `whitespace-display-mappings' for documentation."
482 :type '(repeat :tag "Kind of Blank"
483 (choice :tag "Kind of Blank Face"
484 (const :tag "(Face) Trailing TABs, SPACEs and HARD SPACEs"
485 trailing)
486 (const :tag "(Face) SPACEs and HARD SPACEs"
487 spaces)
488 (const :tag "(Face) TABs" tabs)
489 (const :tag "(Face) Lines" lines)
490 (const :tag "(Face) SPACEs before TAB"
491 space-before-tab)
492 (const :tag "(Face) NEWLINEs" newline)
493 (const :tag "(Face) Indentation SPACEs"
494 indentation)
495 (const :tag "(Face) Empty Lines At BOB And/Or EOB"
496 empty)
497 (const :tag "(Face) SPACEs after TAB"
498 space-after-tab)
499 (const :tag "(Mark) SPACEs and HARD SPACEs"
500 space-mark)
501 (const :tag "(Mark) TABs" tab-mark)
502 (const :tag "(Mark) NEWLINEs" newline-mark)))
503 :group 'whitespace)
504
505
506 (defcustom whitespace-space 'whitespace-space
507 "*Symbol face used to visualize SPACE.
508
509 Used when `whitespace-style' includes the value `spaces'."
510 :type 'face
511 :group 'whitespace)
512
513
514 (defface whitespace-space
515 '((((class color) (background dark))
516 (:background "grey20" :foreground "aquamarine3"))
517 (((class color) (background light))
518 (:background "LightYellow" :foreground "aquamarine3"))
519 (t (:inverse-video t)))
520 "Face used to visualize SPACE."
521 :group 'whitespace)
522
523
524 (defcustom whitespace-hspace 'whitespace-hspace
525 "*Symbol face used to visualize HARD SPACE.
526
527 Used when `whitespace-style' includes the value `spaces'."
528 :type 'face
529 :group 'whitespace)
530
531
532 (defface whitespace-hspace ; 'nobreak-space
533 '((((class color) (background dark))
534 (:background "grey24" :foreground "aquamarine3"))
535 (((class color) (background light))
536 (:background "LemonChiffon3" :foreground "aquamarine3"))
537 (t (:inverse-video t)))
538 "Face used to visualize HARD SPACE."
539 :group 'whitespace)
540
541
542 (defcustom whitespace-tab 'whitespace-tab
543 "*Symbol face used to visualize TAB.
544
545 Used when `whitespace-style' includes the value `tabs'."
546 :type 'face
547 :group 'whitespace)
548
549
550 (defface whitespace-tab
551 '((((class color) (background dark))
552 (:background "grey22" :foreground "aquamarine3"))
553 (((class color) (background light))
554 (:background "beige" :foreground "aquamarine3"))
555 (t (:inverse-video t)))
556 "Face used to visualize TAB."
557 :group 'whitespace)
558
559
560 (defcustom whitespace-newline 'whitespace-newline
561 "*Symbol face used to visualize NEWLINE char mapping.
562
563 See `whitespace-display-mappings'.
564
565 Used when `whitespace-style' includes the values `newline-mark'
566 and `newline'."
567 :type 'face
568 :group 'whitespace)
569
570
571 (defface whitespace-newline
572 '((((class color) (background dark))
573 (:background "grey26" :foreground "aquamarine3" :bold t))
574 (((class color) (background light))
575 (:background "linen" :foreground "aquamarine3" :bold t))
576 (t (:bold t :underline t)))
577 "Face used to visualize NEWLINE char mapping.
578
579 See `whitespace-display-mappings'."
580 :group 'whitespace)
581
582
583 (defcustom whitespace-trailing 'whitespace-trailing
584 "*Symbol face used to visualize trailing blanks.
585
586 Used when `whitespace-style' includes the value `trailing'."
587 :type 'face
588 :group 'whitespace)
589
590
591 (defface whitespace-trailing ; 'trailing-whitespace
592 '((((class mono)) (:inverse-video t :bold t :underline t))
593 (t (:background "red1" :foreground "yellow" :bold t)))
594 "Face used to visualize trailing blanks."
595 :group 'whitespace)
596
597
598 (defcustom whitespace-line 'whitespace-line
599 "*Symbol face used to visualize \"long\" lines.
600
601 See `whitespace-line-column'.
602
603 Used when `whitespace-style' includes the value `line'."
604 :type 'face
605 :group 'whitespace)
606
607
608 (defface whitespace-line
609 '((((class mono)) (:inverse-video t :bold t :underline t))
610 (t (:background "gray20" :foreground "violet")))
611 "Face used to visualize \"long\" lines.
612
613 See `whitespace-line-column'."
614 :group 'whitespace)
615
616
617 (defcustom whitespace-space-before-tab 'whitespace-space-before-tab
618 "*Symbol face used to visualize SPACEs before TAB.
619
620 Used when `whitespace-style' includes the value `space-before-tab'."
621 :type 'face
622 :group 'whitespace)
623
624
625 (defface whitespace-space-before-tab
626 '((((class mono)) (:inverse-video t :bold t :underline t))
627 (t (:background "DarkOrange" :foreground "firebrick")))
628 "Face used to visualize SPACEs before TAB."
629 :group 'whitespace)
630
631
632 (defcustom whitespace-indentation 'whitespace-indentation
633 "*Symbol face used to visualize 8 or more SPACEs at beginning of line.
634
635 Used when `whitespace-style' includes the value `indentation'."
636 :type 'face
637 :group 'whitespace)
638
639
640 (defface whitespace-indentation
641 '((((class mono)) (:inverse-video t :bold t :underline t))
642 (t (:background "yellow" :foreground "firebrick")))
643 "Face used to visualize 8 or more SPACEs at beginning of line."
644 :group 'whitespace)
645
646
647 (defcustom whitespace-empty 'whitespace-empty
648 "*Symbol face used to visualize empty lines at beginning and/or end of buffer.
649
650 Used when `whitespace-style' includes the value `empty'."
651 :type 'face
652 :group 'whitespace)
653
654
655 (defface whitespace-empty
656 '((((class mono)) (:inverse-video t :bold t :underline t))
657 (t (:background "yellow" :foreground "firebrick")))
658 "Face used to visualize empty lines at beginning and/or end of buffer."
659 :group 'whitespace)
660
661
662 (defcustom whitespace-space-after-tab 'whitespace-space-after-tab
663 "*Symbol face used to visualize 8 or more SPACEs after TAB.
664
665 Used when `whitespace-style' includes the value `space-after-tab'."
666 :type 'face
667 :group 'whitespace)
668
669
670 (defface whitespace-space-after-tab
671 '((((class mono)) (:inverse-video t :bold t :underline t))
672 (t (:background "yellow" :foreground "firebrick")))
673 "Face used to visualize 8 or more SPACEs after TAB."
674 :group 'whitespace)
675
676
677 (defcustom whitespace-hspace-regexp
678 "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
679 "*Specify HARD SPACE characters regexp.
680
681 If you're using `mule' package, there may be other characters besides:
682
683 \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
684
685 that should be considered HARD SPACE.
686
687 Here are some examples:
688
689 \"\\\\(^\\xA0+\\\\)\" \
690 visualize only leading HARD SPACEs.
691 \"\\\\(\\xA0+$\\\\)\" \
692 visualize only trailing HARD SPACEs.
693 \"\\\\(^\\xA0+\\\\|\\xA0+$\\\\)\" \
694 visualize leading and/or trailing HARD SPACEs.
695 \"\\t\\\\(\\xA0+\\\\)\\t\" \
696 visualize only HARD SPACEs between TABs.
697
698 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
699 Use exactly one pair of enclosing \\\\( and \\\\).
700
701 Used when `whitespace-style' includes `spaces'."
702 :type '(regexp :tag "HARD SPACE Chars")
703 :group 'whitespace)
704
705
706 (defcustom whitespace-space-regexp "\\( +\\)"
707 "*Specify SPACE characters regexp.
708
709 If you're using `mule' package, there may be other characters
710 besides \" \" that should be considered SPACE.
711
712 Here are some examples:
713
714 \"\\\\(^ +\\\\)\" visualize only leading SPACEs.
715 \"\\\\( +$\\\\)\" visualize only trailing SPACEs.
716 \"\\\\(^ +\\\\| +$\\\\)\" \
717 visualize leading and/or trailing SPACEs.
718 \"\\t\\\\( +\\\\)\\t\" visualize only SPACEs between TABs.
719
720 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
721 Use exactly one pair of enclosing \\\\( and \\\\).
722
723 Used when `whitespace-style' includes `spaces'."
724 :type '(regexp :tag "SPACE Chars")
725 :group 'whitespace)
726
727
728 (defcustom whitespace-tab-regexp "\\(\t+\\)"
729 "*Specify TAB characters regexp.
730
731 If you're using `mule' package, there may be other characters
732 besides \"\\t\" that should be considered TAB.
733
734 Here are some examples:
735
736 \"\\\\(^\\t+\\\\)\" visualize only leading TABs.
737 \"\\\\(\\t+$\\\\)\" visualize only trailing TABs.
738 \"\\\\(^\\t+\\\\|\\t+$\\\\)\" \
739 visualize leading and/or trailing TABs.
740 \" \\\\(\\t+\\\\) \" visualize only TABs between SPACEs.
741
742 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
743 Use exactly one pair of enclosing \\\\( and \\\\).
744
745 Used when `whitespace-style' includes `tabs'."
746 :type '(regexp :tag "TAB Chars")
747 :group 'whitespace)
748
749
750 (defcustom whitespace-trailing-regexp
751 "\\(\\(\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)$"
752 "*Specify trailing characters regexp.
753
754 If you're using `mule' package, there may be other characters besides:
755
756 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
757 \"\\xF20\"
758
759 that should be considered blank.
760
761 NOTE: Enclose always by \"\\\\(\" and \"\\\\)$\" the elements to highlight.
762 Use exactly one pair of enclosing elements above.
763
764 Used when `whitespace-style' includes `trailing'."
765 :type '(regexp :tag "Trailing Chars")
766 :group 'whitespace)
767
768
769 (defcustom whitespace-space-before-tab-regexp "\\( +\\)\\(\t+\\)"
770 "*Specify SPACEs before TAB regexp.
771
772 If you're using `mule' package, there may be other characters besides:
773
774 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
775 \"\\xF20\"
776
777 that should be considered blank.
778
779 Used when `whitespace-style' includes `space-before-tab',
780 `space-before-tab::tab' or `space-before-tab::space'."
781 :type '(regexp :tag "SPACEs Before TAB")
782 :group 'whitespace)
783
784
785 (defcustom whitespace-indentation-regexp
786 '("^\t*\\(\\( \\{%d\\}\\)+\\)[^\n\t]"
787 . "^ *\\(\t+\\)[^\n]")
788 "*Specify regexp for 8 or more SPACEs at beginning of line.
789
790 It is a cons where the cons car is used for SPACEs visualization
791 and the cons cdr is used for TABs visualization.
792
793 If you're using `mule' package, there may be other characters besides:
794
795 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
796 \"\\xF20\"
797
798 that should be considered blank.
799
800 Used when `whitespace-style' includes `indentation',
801 `indentation::tab' or `indentation::space'."
802 :type '(cons (regexp :tag "Indentation SPACEs")
803 (regexp :tag "Indentation TABs"))
804 :group 'whitespace)
805
806
807 (defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
808 "*Specify regexp for empty lines at beginning of buffer.
809
810 If you're using `mule' package, there may be other characters besides:
811
812 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
813 \"\\xF20\"
814
815 that should be considered blank.
816
817 Used when `whitespace-style' includes `empty'."
818 :type '(regexp :tag "Empty Lines At Beginning Of Buffer")
819 :group 'whitespace)
820
821
822 (defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
823 "*Specify regexp for empty lines at end of buffer.
824
825 If you're using `mule' package, there may be other characters besides:
826
827 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
828 \"\\xF20\"
829
830 that should be considered blank.
831
832 Used when `whitespace-style' includes `empty'."
833 :type '(regexp :tag "Empty Lines At End Of Buffer")
834 :group 'whitespace)
835
836
837 (defcustom whitespace-space-after-tab-regexp
838 '("\t+\\(\\( \\{%d\\}\\)+\\)"
839 . "\\(\t+\\) +")
840 "*Specify regexp for 8 or more SPACEs after TAB.
841
842 It is a cons where the cons car is used for SPACEs visualization
843 and the cons cdr is used for TABs visualization.
844
845 If you're using `mule' package, there may be other characters besides:
846
847 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
848 \"\\xF20\"
849
850 that should be considered blank.
851
852 Used when `whitespace-style' includes `space-after-tab',
853 `space-after-tab::tab' or `space-after-tab::space'."
854 :type '(regexp :tag "SPACEs After TAB")
855 :group 'whitespace)
856
857
858 (defcustom whitespace-line-column 80
859 "*Specify column beyond which the line is highlighted.
860
861 Used when `whitespace-style' includes `lines' or `lines-tail'."
862 :type '(integer :tag "Line Length")
863 :group 'whitespace)
864
865
866 ;; Hacked from `visible-whitespace-mappings' in visws.el
867 (defcustom whitespace-display-mappings
868 '(
869 (space-mark ?\ [?\xB7] [?.]) ; space - centered dot
870 (space-mark ?\xA0 [?\xA4] [?_]) ; hard space - currency
871 (space-mark ?\x8A0 [?\x8A4] [?_]) ; hard space - currency
872 (space-mark ?\x920 [?\x924] [?_]) ; hard space - currency
873 (space-mark ?\xE20 [?\xE24] [?_]) ; hard space - currency
874 (space-mark ?\xF20 [?\xF24] [?_]) ; hard space - currency
875 ;; NEWLINE is displayed using the face `whitespace-newline'
876 (newline-mark ?\n [?$ ?\n]) ; eol - dollar sign
877 ;; (newline-mark ?\n [?\u21B5 ?\n] [?$ ?\n]) ; eol - downwards arrow
878 ;; (newline-mark ?\n [?\xB6 ?\n] [?$ ?\n]) ; eol - pilcrow
879 ;; (newline-mark ?\n [?\x8AF ?\n] [?$ ?\n]) ; eol - overscore
880 ;; (newline-mark ?\n [?\x8AC ?\n] [?$ ?\n]) ; eol - negation
881 ;; (newline-mark ?\n [?\x8B0 ?\n] [?$ ?\n]) ; eol - grade
882 ;;
883 ;; WARNING: the mapping below has a problem.
884 ;; When a TAB occupies exactly one column, it will display the
885 ;; character ?\xBB at that column followed by a TAB which goes to
886 ;; the next TAB column.
887 ;; If this is a problem for you, please, comment the line below.
888 (tab-mark ?\t [?\xBB ?\t] [?\\ ?\t]) ; tab - left quote mark
889 )
890 "*Specify an alist of mappings for displaying characters.
891
892 Each element has the following form:
893
894 (KIND CHAR VECTOR...)
895
896 Where:
897
898 KIND is the kind of character.
899 It can be one of the following symbols:
900
901 tab-mark for TAB character
902
903 space-mark for SPACE or HARD SPACE character
904
905 newline-mark for NEWLINE character
906
907 CHAR is the character to be mapped.
908
909 VECTOR is a vector of characters to be displayed in place of CHAR.
910 The first display vector that can be displayed is used;
911 if no display vector for a mapping can be displayed, then
912 that character is displayed unmodified.
913
914 The NEWLINE character is displayed using the face given by
915 `whitespace-newline' variable.
916
917 Used when `whitespace-style' includes `tab-mark', `space-mark' or
918 `newline-mark'."
919 :type '(repeat
920 (list :tag "Character Mapping"
921 (choice :tag "Char Kind"
922 (const :tag "Tab" tab-mark)
923 (const :tag "Space" space-mark)
924 (const :tag "Newline" newline-mark))
925 (character :tag "Char")
926 (repeat :inline t :tag "Vector List"
927 (vector :tag ""
928 (repeat :inline t
929 :tag "Vector Characters"
930 (character :tag "Char"))))))
931 :group 'whitespace)
932
933
934 (defcustom whitespace-global-modes t
935 "*Modes for which global `whitespace-mode' is automagically turned on.
936
937 Global `whitespace-mode' is controlled by the command
938 `global-whitespace-mode'.
939
940 If nil, means no modes have `whitespace-mode' automatically
941 turned on.
942
943 If t, all modes that support `whitespace-mode' have it
944 automatically turned on.
945
946 Else it should be a list of `major-mode' symbol names for which
947 `whitespace-mode' should be automatically turned on. The sense
948 of the list is negated if it begins with `not'. For example:
949
950 (c-mode c++-mode)
951
952 means that `whitespace-mode' is turned on for buffers in C and
953 C++ modes only."
954 :type '(choice :tag "Global Modes"
955 (const :tag "None" nil)
956 (const :tag "All" t)
957 (set :menu-tag "Mode Specific" :tag "Modes"
958 :value (not)
959 (const :tag "Except" not)
960 (repeat :inline t
961 (symbol :tag "Mode"))))
962 :group 'whitespace)
963
964
965 (defcustom whitespace-action nil
966 "*Specify which action is taken when a buffer is visited, killed or written.
967
968 It's a list containing some or all of the following values:
969
970 nil no action is taken.
971
972 cleanup cleanup any bogus whitespace always when local
973 whitespace is turned on.
974 See `whitespace-cleanup' and
975 `whitespace-cleanup-region'.
976
977 report-on-bogus report if there is any bogus whitespace always
978 when local whitespace is turned on.
979
980 auto-cleanup cleanup any bogus whitespace when buffer is
981 written or killed.
982 See `whitespace-cleanup' and
983 `whitespace-cleanup-region'.
984
985 abort-on-bogus abort if there is any bogus whitespace and the
986 buffer is written or killed.
987
988 Any other value is treated as nil."
989 :type '(choice :tag "Actions"
990 (const :tag "None" nil)
991 (repeat :tag "Action List"
992 (choice :tag "Action"
993 (const :tag "Cleanup When On" cleanup)
994 (const :tag "Report On Bogus" report-on-bogus)
995 (const :tag "Auto Cleanup" auto-cleanup)
996 (const :tag "Abort On Bogus" abort-on-bogus))))
997 :group 'whitespace)
998
999 \f
1000 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1001 ;;;; User commands - Local mode
1002
1003
1004 ;;;###autoload
1005 (define-minor-mode whitespace-mode
1006 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
1007
1008 If ARG is null, toggle whitespace visualization.
1009 If ARG is a number greater than zero, turn on visualization;
1010 otherwise, turn off visualization.
1011 Only useful with a windowing system."
1012 :lighter " ws"
1013 :init-value nil
1014 :global nil
1015 :group 'whitespace
1016 (cond
1017 (noninteractive ; running a batch job
1018 (setq whitespace-mode nil))
1019 (whitespace-mode ; whitespace-mode on
1020 (whitespace-turn-on)
1021 (whitespace-action-when-on))
1022 (t ; whitespace-mode off
1023 (whitespace-turn-off))))
1024
1025
1026 ;;;###autoload
1027 (define-minor-mode whitespace-newline-mode
1028 "Toggle newline minor mode visualization (\"nl\" on modeline).
1029
1030 If ARG is null, toggle newline visualization.
1031 If ARG is a number greater than zero, turn on visualization;
1032 otherwise, turn off visualization.
1033 Only useful with a windowing system.
1034
1035 See also `whitespace-newline'."
1036 :lighter " nl"
1037 :init-value nil
1038 :global nil
1039 :group 'whitespace
1040 (let ((whitespace-style '(newline-mark newline)))
1041 (whitespace-mode whitespace-newline-mode)
1042 ;; sync states (running a batch job)
1043 (setq whitespace-newline-mode whitespace-mode)))
1044
1045 \f
1046 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1047 ;;;; User commands - Global mode
1048
1049
1050 ;;;###autoload
1051 (define-minor-mode global-whitespace-mode
1052 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
1053
1054 If ARG is null, toggle whitespace visualization.
1055 If ARG is a number greater than zero, turn on visualization;
1056 otherwise, turn off visualization.
1057 Only useful with a windowing system."
1058 :lighter " WS"
1059 :init-value nil
1060 :global t
1061 :group 'whitespace
1062 (cond
1063 (noninteractive ; running a batch job
1064 (setq global-whitespace-mode nil))
1065 (global-whitespace-mode ; global-whitespace-mode on
1066 (save-excursion
1067 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1068 (dolist (buffer (buffer-list)) ; adjust all local mode
1069 (set-buffer buffer)
1070 (unless whitespace-mode
1071 (whitespace-turn-on-if-enabled)))))
1072 (t ; global-whitespace-mode off
1073 (save-excursion
1074 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1075 (dolist (buffer (buffer-list)) ; adjust all local mode
1076 (set-buffer buffer)
1077 (unless whitespace-mode
1078 (whitespace-turn-off)))))))
1079
1080
1081 (defun whitespace-turn-on-if-enabled ()
1082 (when (cond
1083 ((eq whitespace-global-modes t))
1084 ((listp whitespace-global-modes)
1085 (if (eq (car-safe whitespace-global-modes) 'not)
1086 (not (memq major-mode (cdr whitespace-global-modes)))
1087 (memq major-mode whitespace-global-modes)))
1088 (t nil))
1089 (let (inhibit-quit)
1090 ;; Don't turn on whitespace mode if...
1091 (or
1092 ;; ...we don't have a display (we're running a batch job)
1093 noninteractive
1094 ;; ...or if the buffer is invisible (name starts with a space)
1095 (eq (aref (buffer-name) 0) ?\ )
1096 ;; ...or if the buffer is temporary (name starts with *)
1097 (and (eq (aref (buffer-name) 0) ?*)
1098 ;; except the scratch buffer.
1099 (not (string= (buffer-name) "*scratch*")))
1100 ;; Otherwise, turn on whitespace mode.
1101 (whitespace-turn-on)))))
1102
1103
1104 ;;;###autoload
1105 (define-minor-mode global-whitespace-newline-mode
1106 "Toggle newline global minor mode visualization (\"NL\" on modeline).
1107
1108 If ARG is null, toggle newline visualization.
1109 If ARG is a number greater than zero, turn on visualization;
1110 otherwise, turn off visualization.
1111 Only useful with a windowing system.
1112
1113 See also `whitespace-newline'."
1114 :lighter " NL"
1115 :init-value nil
1116 :global t
1117 :group 'whitespace
1118 (let ((whitespace-style '(newline-mark newline)))
1119 (global-whitespace-mode global-whitespace-newline-mode)
1120 ;; sync states (running a batch job)
1121 (setq global-whitespace-newline-mode global-whitespace-mode)))
1122
1123 \f
1124 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1125 ;;;; User commands - Toggle
1126
1127
1128 (defconst whitespace-style-value-list
1129 '(tabs
1130 spaces
1131 trailing
1132 lines
1133 lines-tail
1134 newline
1135 empty
1136 indentation
1137 indentation::tab
1138 indentation::space
1139 space-after-tab
1140 space-after-tab::tab
1141 space-after-tab::space
1142 space-before-tab
1143 space-before-tab::tab
1144 space-before-tab::space
1145 help-newline ; value used by `whitespace-insert-option-mark'
1146 tab-mark
1147 space-mark
1148 newline-mark
1149 )
1150 "List of valid `whitespace-style' values.")
1151
1152
1153 (defconst whitespace-toggle-option-alist
1154 '((?t . tabs)
1155 (?s . spaces)
1156 (?r . trailing)
1157 (?l . lines)
1158 (?L . lines-tail)
1159 (?n . newline)
1160 (?e . empty)
1161 (?\C-i . indentation)
1162 (?I . indentation::tab)
1163 (?i . indentation::space)
1164 (?\C-a . space-after-tab)
1165 (?A . space-after-tab::tab)
1166 (?a . space-after-tab::space)
1167 (?\C-b . space-before-tab)
1168 (?B . space-before-tab::tab)
1169 (?b . space-before-tab::space)
1170 (?T . tab-mark)
1171 (?S . space-mark)
1172 (?N . newline-mark)
1173 (?x . whitespace-style)
1174 )
1175 "Alist of toggle options.
1176
1177 Each element has the form:
1178
1179 (CHAR . SYMBOL)
1180
1181 Where:
1182
1183 CHAR is a char which the user will have to type.
1184
1185 SYMBOL is a valid symbol associated with CHAR.
1186 See `whitespace-style-value-list'.")
1187
1188
1189 (defvar whitespace-active-style nil
1190 "Used to save locally `whitespace-style' value.")
1191
1192 (defvar whitespace-indent-tabs-mode indent-tabs-mode
1193 "Used to save locally `indent-tabs-mode' value.")
1194
1195 (defvar whitespace-tab-width tab-width
1196 "Used to save locally `tab-width' value.")
1197
1198
1199 ;;;###autoload
1200 (defun whitespace-toggle-options (arg)
1201 "Toggle local `whitespace-mode' options.
1202
1203 If local whitespace-mode is off, toggle the option given by ARG
1204 and turn on local whitespace-mode.
1205
1206 If local whitespace-mode is on, toggle the option given by ARG
1207 and restart local whitespace-mode.
1208
1209 Interactively, it reads one of the following chars:
1210
1211 CHAR MEANING
1212 (VIA FACES)
1213 t toggle TAB visualization
1214 s toggle SPACE and HARD SPACE visualization
1215 r toggle trailing blanks visualization
1216 l toggle \"long lines\" visualization
1217 L toggle \"long lines\" tail visualization
1218 n toggle NEWLINE visualization
1219 e toggle empty line at bob and/or eob visualization
1220 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1221 I toggle indentation SPACEs visualization
1222 i toggle indentation TABs visualization
1223 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1224 A toggle SPACEs after TAB: SPACEs visualization
1225 a toggle SPACEs after TAB: TABs visualization
1226 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1227 B toggle SPACEs before TAB: SPACEs visualization
1228 b toggle SPACEs before TAB: TABs visualization
1229
1230 (VIA DISPLAY TABLE)
1231 T toggle TAB visualization
1232 S toggle SPACEs before TAB visualization
1233 N toggle NEWLINE visualization
1234
1235 x restore `whitespace-style' value
1236 ? display brief help
1237
1238 Non-interactively, ARG should be a symbol or a list of symbols.
1239 The valid symbols are:
1240
1241 tabs toggle TAB visualization
1242 spaces toggle SPACE and HARD SPACE visualization
1243 trailing toggle trailing blanks visualization
1244 lines toggle \"long lines\" visualization
1245 lines-tail toggle \"long lines\" tail visualization
1246 newline toggle NEWLINE visualization
1247 empty toggle empty line at bob and/or eob visualization
1248 indentation toggle indentation SPACEs visualization
1249 indentation::tab toggle indentation SPACEs visualization
1250 indentation::space toggle indentation TABs visualization
1251 space-after-tab toggle SPACEs after TAB visualization
1252 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1253 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1254 space-before-tab toggle SPACEs before TAB visualization
1255 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1256 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1257
1258 tab-mark toggle TAB visualization
1259 space-mark toggle SPACEs before TAB visualization
1260 newline-mark toggle NEWLINE visualization
1261
1262 whitespace-style restore `whitespace-style' value
1263
1264 Only useful with a windowing system.
1265
1266 See `whitespace-style' and `indent-tabs-mode' for documentation."
1267 (interactive (whitespace-interactive-char t))
1268 (let ((whitespace-style
1269 (whitespace-toggle-list t arg whitespace-active-style)))
1270 (whitespace-mode 0)
1271 (whitespace-mode 1)))
1272
1273
1274 (defvar whitespace-toggle-style nil
1275 "Used to toggle the global `whitespace-style' value.")
1276
1277
1278 ;;;###autoload
1279 (defun global-whitespace-toggle-options (arg)
1280 "Toggle global `whitespace-mode' options.
1281
1282 If global whitespace-mode is off, toggle the option given by ARG
1283 and turn on global whitespace-mode.
1284
1285 If global whitespace-mode is on, toggle the option given by ARG
1286 and restart global whitespace-mode.
1287
1288 Interactively, it accepts one of the following chars:
1289
1290 CHAR MEANING
1291 (VIA FACES)
1292 t toggle TAB visualization
1293 s toggle SPACE and HARD SPACE visualization
1294 r toggle trailing blanks visualization
1295 l toggle \"long lines\" visualization
1296 L toggle \"long lines\" tail visualization
1297 n toggle NEWLINE visualization
1298 e toggle empty line at bob and/or eob visualization
1299 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1300 I toggle indentation SPACEs visualization
1301 i toggle indentation TABs visualization
1302 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1303 A toggle SPACEs after TAB: SPACEs visualization
1304 a toggle SPACEs after TAB: TABs visualization
1305 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1306 B toggle SPACEs before TAB: SPACEs visualization
1307 b toggle SPACEs before TAB: TABs visualization
1308
1309 (VIA DISPLAY TABLE)
1310 T toggle TAB visualization
1311 S toggle SPACEs before TAB visualization
1312 N toggle NEWLINE visualization
1313
1314 x restore `whitespace-style' value
1315 ? display brief help
1316
1317 Non-interactively, ARG should be a symbol or a list of symbols.
1318 The valid symbols are:
1319
1320 tabs toggle TAB visualization
1321 spaces toggle SPACE and HARD SPACE visualization
1322 trailing toggle trailing blanks visualization
1323 lines toggle \"long lines\" visualization
1324 lines-tail toggle \"long lines\" tail visualization
1325 newline toggle NEWLINE visualization
1326 empty toggle empty line at bob and/or eob visualization
1327 indentation toggle indentation SPACEs visualization
1328 indentation::tab toggle indentation SPACEs visualization
1329 indentation::space toggle indentation TABs visualization
1330 space-after-tab toggle SPACEs after TAB visualization
1331 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1332 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1333 space-before-tab toggle SPACEs before TAB visualization
1334 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1335 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1336
1337 tab-mark toggle TAB visualization
1338 space-mark toggle SPACEs before TAB visualization
1339 newline-mark toggle NEWLINE visualization
1340
1341 whitespace-style restore `whitespace-style' value
1342
1343 Only useful with a windowing system.
1344
1345 See `whitespace-style' and `indent-tabs-mode' for documentation."
1346 (interactive (whitespace-interactive-char nil))
1347 (let ((whitespace-style
1348 (whitespace-toggle-list nil arg whitespace-toggle-style)))
1349 (setq whitespace-toggle-style whitespace-style)
1350 (global-whitespace-mode 0)
1351 (global-whitespace-mode 1)))
1352
1353 \f
1354 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1355 ;;;; User commands - Cleanup
1356
1357
1358 ;;;###autoload
1359 (defun whitespace-cleanup ()
1360 "Cleanup some blank problems in all buffer or at region.
1361
1362 It usually applies to the whole buffer, but in transient mark
1363 mode when the mark is active, it applies to the region. It also
1364 applies to the region when it is not in transiente mark mode, the
1365 mark is active and \\[universal-argument] was pressed just before
1366 calling `whitespace-cleanup' interactively.
1367
1368 See also `whitespace-cleanup-region'.
1369
1370 The problems cleaned up are:
1371
1372 1. empty lines at beginning of buffer.
1373 2. empty lines at end of buffer.
1374 If `whitespace-style' includes the value `empty', remove all
1375 empty lines at beginning and/or end of buffer.
1376
1377 3. 8 or more SPACEs at beginning of line.
1378 If `whitespace-style' includes the value `indentation':
1379 replace 8 or more SPACEs at beginning of line by TABs, if
1380 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1381 SPACEs.
1382 If `whitespace-style' includes the value `indentation::tab',
1383 replace 8 or more SPACEs at beginning of line by TABs.
1384 If `whitespace-style' includes the value `indentation::space',
1385 replace TABs by SPACEs.
1386
1387 4. SPACEs before TAB.
1388 If `whitespace-style' includes the value `space-before-tab':
1389 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1390 otherwise, replace TABs by SPACEs.
1391 If `whitespace-style' includes the value
1392 `space-before-tab::tab', replace SPACEs by TABs.
1393 If `whitespace-style' includes the value
1394 `space-before-tab::space', replace TABs by SPACEs.
1395
1396 5. SPACEs or TABs at end of line.
1397 If `whitespace-style' includes the value `trailing', remove
1398 all SPACEs or TABs at end of line.
1399
1400 6. 8 or more SPACEs after TAB.
1401 If `whitespace-style' includes the value `space-after-tab':
1402 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1403 otherwise, replace TABs by SPACEs.
1404 If `whitespace-style' includes the value
1405 `space-after-tab::tab', replace SPACEs by TABs.
1406 If `whitespace-style' includes the value
1407 `space-after-tab::space', replace TABs by SPACEs.
1408
1409 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1410 documentation."
1411 (interactive "@*")
1412 (if (and (or transient-mark-mode
1413 current-prefix-arg)
1414 mark-active)
1415 ;; region active
1416 ;; PROBLEMs 1 and 2 are not handled in region
1417 ;; PROBLEM 3: 8 or more SPACEs at bol
1418 ;; PROBLEM 4: SPACEs before TAB
1419 ;; PROBLEM 5: SPACEs or TABs at eol
1420 ;; PROBLEM 6: 8 or more SPACEs after TAB
1421 (whitespace-cleanup-region (region-beginning) (region-end))
1422 ;; whole buffer
1423 (save-excursion
1424 (save-match-data
1425 ;; PROBLEM 1: empty lines at bob
1426 ;; PROBLEM 2: empty lines at eob
1427 ;; ACTION: remove all empty lines at bob and/or eob
1428 (when (memq 'empty whitespace-style)
1429 (let (overwrite-mode) ; enforce no overwrite
1430 (goto-char (point-min))
1431 (when (re-search-forward
1432 whitespace-empty-at-bob-regexp nil t)
1433 (delete-region (match-beginning 1) (match-end 1)))
1434 (when (re-search-forward
1435 whitespace-empty-at-eob-regexp nil t)
1436 (delete-region (match-beginning 1) (match-end 1)))))))
1437 ;; PROBLEM 3: 8 or more SPACEs at bol
1438 ;; PROBLEM 4: SPACEs before TAB
1439 ;; PROBLEM 5: SPACEs or TABs at eol
1440 ;; PROBLEM 6: 8 or more SPACEs after TAB
1441 (whitespace-cleanup-region (point-min) (point-max))))
1442
1443
1444 ;;;###autoload
1445 (defun whitespace-cleanup-region (start end)
1446 "Cleanup some blank problems at region.
1447
1448 The problems cleaned up are:
1449
1450 1. 8 or more SPACEs at beginning of line.
1451 If `whitespace-style' includes the value `indentation':
1452 replace 8 or more SPACEs at beginning of line by TABs, if
1453 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1454 SPACEs.
1455 If `whitespace-style' includes the value `indentation::tab',
1456 replace 8 or more SPACEs at beginning of line by TABs.
1457 If `whitespace-style' includes the value `indentation::space',
1458 replace TABs by SPACEs.
1459
1460 2. SPACEs before TAB.
1461 If `whitespace-style' includes the value `space-before-tab':
1462 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1463 otherwise, replace TABs by SPACEs.
1464 If `whitespace-style' includes the value
1465 `space-before-tab::tab', replace SPACEs by TABs.
1466 If `whitespace-style' includes the value
1467 `space-before-tab::space', replace TABs by SPACEs.
1468
1469 3. SPACEs or TABs at end of line.
1470 If `whitespace-style' includes the value `trailing', remove
1471 all SPACEs or TABs at end of line.
1472
1473 4. 8 or more SPACEs after TAB.
1474 If `whitespace-style' includes the value `space-after-tab':
1475 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1476 otherwise, replace TABs by SPACEs.
1477 If `whitespace-style' includes the value
1478 `space-after-tab::tab', replace SPACEs by TABs.
1479 If `whitespace-style' includes the value
1480 `space-after-tab::space', replace TABs by SPACEs.
1481
1482 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1483 documentation."
1484 (interactive "@*r")
1485 (let ((rstart (min start end))
1486 (rend (copy-marker (max start end)))
1487 (indent-tabs-mode whitespace-indent-tabs-mode)
1488 (tab-width whitespace-tab-width)
1489 overwrite-mode ; enforce no overwrite
1490 tmp)
1491 (save-excursion
1492 (save-match-data
1493 ;; PROBLEM 1: 8 or more SPACEs at bol
1494 (cond
1495 ;; ACTION: replace 8 or more SPACEs at bol by TABs, if
1496 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1497 ;; SPACEs.
1498 ((memq 'indentation whitespace-style)
1499 (let ((regexp (whitespace-indentation-regexp)))
1500 (goto-char rstart)
1501 (while (re-search-forward regexp rend t)
1502 (setq tmp (current-indentation))
1503 (goto-char (match-beginning 0))
1504 (delete-horizontal-space)
1505 (unless (eolp)
1506 (indent-to tmp)))))
1507 ;; ACTION: replace 8 or more SPACEs at bol by TABs.
1508 ((memq 'indentation::tab whitespace-style)
1509 (whitespace-replace-action
1510 'tabify rstart rend
1511 (whitespace-indentation-regexp 'tab) 0))
1512 ;; ACTION: replace TABs by SPACEs.
1513 ((memq 'indentation::space whitespace-style)
1514 (whitespace-replace-action
1515 'untabify rstart rend
1516 (whitespace-indentation-regexp 'space) 0)))
1517 ;; PROBLEM 3: SPACEs or TABs at eol
1518 ;; ACTION: remove all SPACEs or TABs at eol
1519 (when (memq 'trailing whitespace-style)
1520 (whitespace-replace-action
1521 'delete-region rstart rend
1522 whitespace-trailing-regexp 1))
1523 ;; PROBLEM 4: 8 or more SPACEs after TAB
1524 (cond
1525 ;; ACTION: replace 8 or more SPACEs by TABs, if
1526 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1527 ;; SPACEs.
1528 ((memq 'space-after-tab whitespace-style)
1529 (whitespace-replace-action
1530 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1531 rstart rend (whitespace-space-after-tab-regexp) 1))
1532 ;; ACTION: replace 8 or more SPACEs by TABs.
1533 ((memq 'space-after-tab::tab whitespace-style)
1534 (whitespace-replace-action
1535 'tabify rstart rend
1536 (whitespace-space-after-tab-regexp 'tab) 1))
1537 ;; ACTION: replace TABs by SPACEs.
1538 ((memq 'space-after-tab::space whitespace-style)
1539 (whitespace-replace-action
1540 'untabify rstart rend
1541 (whitespace-space-after-tab-regexp 'space) 1)))
1542 ;; PROBLEM 2: SPACEs before TAB
1543 (cond
1544 ;; ACTION: replace SPACEs before TAB by TABs, if
1545 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1546 ;; SPACEs.
1547 ((memq 'space-before-tab whitespace-style)
1548 (whitespace-replace-action
1549 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1550 rstart rend whitespace-space-before-tab-regexp
1551 (if whitespace-indent-tabs-mode 1 2)))
1552 ;; ACTION: replace SPACEs before TAB by TABs.
1553 ((memq 'space-before-tab::tab whitespace-style)
1554 (whitespace-replace-action
1555 'tabify rstart rend
1556 whitespace-space-before-tab-regexp 1))
1557 ;; ACTION: replace TABs by SPACEs.
1558 ((memq 'space-before-tab::space whitespace-style)
1559 (whitespace-replace-action
1560 'untabify rstart rend
1561 whitespace-space-before-tab-regexp 2)))))
1562 (set-marker rend nil))) ; point marker to nowhere
1563
1564
1565 (defun whitespace-replace-action (action rstart rend regexp index)
1566 "Do ACTION in the string matched by REGEXP between RSTART and REND.
1567
1568 INDEX is the level group matched by REGEXP and used by ACTION.
1569
1570 See also `tab-width'."
1571 (goto-char rstart)
1572 (while (re-search-forward regexp rend t)
1573 (goto-char (match-end index))
1574 (funcall action (match-beginning index) (match-end index))))
1575
1576 \f
1577 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1578 ;;;; User command - report
1579
1580
1581 (defun whitespace-regexp (regexp &optional kind)
1582 "Return REGEXP depending on `whitespace-indent-tabs-mode'."
1583 (cond
1584 ((or (eq kind 'tab)
1585 whitespace-indent-tabs-mode)
1586 (format (car regexp) whitespace-tab-width))
1587 ((or (eq kind 'space)
1588 (not whitespace-indent-tabs-mode))
1589 (cdr regexp))))
1590
1591
1592 (defun whitespace-indentation-regexp (&optional kind)
1593 "Return the indentation regexp depending on `whitespace-indent-tabs-mode'."
1594 (whitespace-regexp whitespace-indentation-regexp kind))
1595
1596
1597 (defun whitespace-space-after-tab-regexp (&optional kind)
1598 "Return the space-after-tab regexp depending on `whitespace-indent-tabs-mode'."
1599 (whitespace-regexp whitespace-space-after-tab-regexp kind))
1600
1601
1602 (defconst whitespace-report-list
1603 (list
1604 (cons 'empty whitespace-empty-at-bob-regexp)
1605 (cons 'empty whitespace-empty-at-eob-regexp)
1606 (cons 'trailing whitespace-trailing-regexp)
1607 (cons 'indentation nil)
1608 (cons 'indentation::tab nil)
1609 (cons 'indentation::space nil)
1610 (cons 'space-before-tab whitespace-space-before-tab-regexp)
1611 (cons 'space-before-tab::tab whitespace-space-before-tab-regexp)
1612 (cons 'space-before-tab::space whitespace-space-before-tab-regexp)
1613 (cons 'space-after-tab nil)
1614 (cons 'space-after-tab::tab nil)
1615 (cons 'space-after-tab::space nil)
1616 )
1617 "List of whitespace bogus symbol and corresponding regexp.")
1618
1619
1620 (defconst whitespace-report-text
1621 '( ;; `indent-tabs-mode' has non-nil value
1622 "\
1623 Whitespace Report
1624
1625 Current Setting Whitespace Problem
1626
1627 empty [] [] empty lines at beginning of buffer
1628 empty [] [] empty lines at end of buffer
1629 trailing [] [] SPACEs or TABs at end of line
1630 indentation [] [] 8 or more SPACEs at beginning of line
1631 indentation::tab [] [] 8 or more SPACEs at beginning of line
1632 indentation::space [] [] TABs at beginning of line
1633 space-before-tab [] [] SPACEs before TAB
1634 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1635 space-before-tab::space [] [] SPACEs before TAB: TABs
1636 space-after-tab [] [] 8 or more SPACEs after TAB
1637 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1638 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1639
1640 indent-tabs-mode =
1641 tab-width = \n\n"
1642 . ;; `indent-tabs-mode' has nil value
1643 "\
1644 Whitespace Report
1645
1646 Current Setting Whitespace Problem
1647
1648 empty [] [] empty lines at beginning of buffer
1649 empty [] [] empty lines at end of buffer
1650 trailing [] [] SPACEs or TABs at end of line
1651 indentation [] [] TABs at beginning of line
1652 indentation::tab [] [] 8 or more SPACEs at beginning of line
1653 indentation::space [] [] TABs at beginning of line
1654 space-before-tab [] [] SPACEs before TAB
1655 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1656 space-before-tab::space [] [] SPACEs before TAB: TABs
1657 space-after-tab [] [] 8 or more SPACEs after TAB
1658 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1659 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1660
1661 indent-tabs-mode =
1662 tab-width = \n\n")
1663 "Text for whitespace bogus report.
1664
1665 It is a cons of strings, where the car part is used when
1666 `indent-tabs-mode' is non-nil, and the cdr part is used when
1667 `indent-tabs-mode' is nil.")
1668
1669
1670 (defconst whitespace-report-buffer-name "*Whitespace Report*"
1671 "The buffer name for whitespace bogus report.")
1672
1673
1674 ;;;###autoload
1675 (defun whitespace-report (&optional force report-if-bogus)
1676 "Report some whitespace problems in buffer.
1677
1678 Return nil if there is no whitespace problem; otherwise, return
1679 non-nil.
1680
1681 If FORCE is non-nil or \\[universal-argument] was pressed just
1682 before calling `whitespace-report' interactively, it forces
1683 `whitespace-style' to have:
1684
1685 empty
1686 trailing
1687 indentation
1688 space-before-tab
1689 space-after-tab
1690
1691 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1692 whitespace problems in buffer.
1693
1694 Report if some of the following whitespace problems exist:
1695
1696 * If `indent-tabs-mode' is non-nil:
1697 empty 1. empty lines at beginning of buffer.
1698 empty 2. empty lines at end of buffer.
1699 trailing 3. SPACEs or TABs at end of line.
1700 indentation 4. 8 or more SPACEs at beginning of line.
1701 space-before-tab 5. SPACEs before TAB.
1702 space-after-tab 6. 8 or more SPACEs after TAB.
1703
1704 * If `indent-tabs-mode' is nil:
1705 empty 1. empty lines at beginning of buffer.
1706 empty 2. empty lines at end of buffer.
1707 trailing 3. SPACEs or TABs at end of line.
1708 indentation 4. TABS at beginning of line.
1709 space-before-tab 5. SPACEs before TAB.
1710 space-after-tab 6. 8 or more SPACEs after TAB.
1711
1712 See `whitespace-style' for documentation.
1713 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1714 cleaning up these problems."
1715 (interactive (list current-prefix-arg))
1716 (whitespace-report-region (point-min) (point-max)
1717 force report-if-bogus))
1718
1719
1720 ;;;###autoload
1721 (defun whitespace-report-region (start end &optional force report-if-bogus)
1722 "Report some whitespace problems in a region.
1723
1724 Return nil if there is no whitespace problem; otherwise, return
1725 non-nil.
1726
1727 If FORCE is non-nil or \\[universal-argument] was pressed just
1728 before calling `whitespace-report-region' interactively, it
1729 forces `whitespace-style' to have:
1730
1731 empty
1732 indentation
1733 space-before-tab
1734 trailing
1735 space-after-tab
1736
1737 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1738 whitespace problems in buffer.
1739
1740 Report if some of the following whitespace problems exist:
1741
1742 * If `indent-tabs-mode' is non-nil:
1743 empty 1. empty lines at beginning of buffer.
1744 empty 2. empty lines at end of buffer.
1745 trailing 3. SPACEs or TABs at end of line.
1746 indentation 4. 8 or more SPACEs at beginning of line.
1747 space-before-tab 5. SPACEs before TAB.
1748 space-after-tab 6. 8 or more SPACEs after TAB.
1749
1750 * If `indent-tabs-mode' is nil:
1751 empty 1. empty lines at beginning of buffer.
1752 empty 2. empty lines at end of buffer.
1753 trailing 3. SPACEs or TABs at end of line.
1754 indentation 4. TABS at beginning of line.
1755 space-before-tab 5. SPACEs before TAB.
1756 space-after-tab 6. 8 or more SPACEs after TAB.
1757
1758 See `whitespace-style' for documentation.
1759 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1760 cleaning up these problems."
1761 (interactive "r")
1762 (setq force (or current-prefix-arg force))
1763 (save-excursion
1764 (save-match-data
1765 (let* ((has-bogus nil)
1766 (rstart (min start end))
1767 (rend (max start end))
1768 (bogus-list
1769 (mapcar
1770 #'(lambda (option)
1771 (when force
1772 (add-to-list 'whitespace-style (car option)))
1773 (goto-char rstart)
1774 (let ((regexp
1775 (cond
1776 ((eq (car option) 'indentation)
1777 (whitespace-indentation-regexp))
1778 ((eq (car option) 'indentation::tab)
1779 (whitespace-indentation-regexp 'tab))
1780 ((eq (car option) 'indentation::space)
1781 (whitespace-indentation-regexp 'space))
1782 ((eq (car option) 'space-after-tab)
1783 (whitespace-space-after-tab-regexp))
1784 ((eq (car option) 'space-after-tab::tab)
1785 (whitespace-space-after-tab-regexp 'tab))
1786 ((eq (car option) 'space-after-tab::space)
1787 (whitespace-space-after-tab-regexp 'space))
1788 (t
1789 (cdr option)))))
1790 (and (re-search-forward regexp rend t)
1791 (setq has-bogus t))))
1792 whitespace-report-list)))
1793 (when (if report-if-bogus has-bogus t)
1794 (whitespace-kill-buffer whitespace-report-buffer-name)
1795 ;; `whitespace-indent-tabs-mode' is local to current buffer
1796 ;; `whitespace-tab-width' is local to current buffer
1797 (let ((ws-indent-tabs-mode whitespace-indent-tabs-mode)
1798 (ws-tab-width whitespace-tab-width))
1799 (with-current-buffer (get-buffer-create
1800 whitespace-report-buffer-name)
1801 (erase-buffer)
1802 (insert (if ws-indent-tabs-mode
1803 (car whitespace-report-text)
1804 (cdr whitespace-report-text)))
1805 (goto-char (point-min))
1806 (forward-line 3)
1807 (dolist (option whitespace-report-list)
1808 (forward-line 1)
1809 (whitespace-mark-x
1810 27 (memq (car option) whitespace-style))
1811 (whitespace-mark-x 7 (car bogus-list))
1812 (setq bogus-list (cdr bogus-list)))
1813 (forward-line 1)
1814 (whitespace-insert-value ws-indent-tabs-mode)
1815 (whitespace-insert-value ws-tab-width)
1816 (when has-bogus
1817 (goto-char (point-max))
1818 (insert " Type `M-x whitespace-cleanup'"
1819 " to cleanup the buffer.\n\n"
1820 " Type `M-x whitespace-cleanup-region'"
1821 " to cleanup a region.\n\n"))
1822 (whitespace-display-window (current-buffer)))))
1823 has-bogus))))
1824
1825 \f
1826 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1827 ;;;; Internal functions
1828
1829
1830 (defvar whitespace-font-lock-mode nil
1831 "Used to remember whether a buffer had font lock mode on or not.")
1832
1833 (defvar whitespace-font-lock nil
1834 "Used to remember whether a buffer initially had font lock on or not.")
1835
1836 (defvar whitespace-font-lock-keywords nil
1837 "Used to save locally `font-lock-keywords' value.")
1838
1839
1840 (defconst whitespace-help-text
1841 "\
1842 Whitespace Toggle Options
1843
1844 FACES
1845 [] t - toggle TAB visualization
1846 [] s - toggle SPACE and HARD SPACE visualization
1847 [] r - toggle trailing blanks visualization
1848 [] l - toggle \"long lines\" visualization
1849 [] L - toggle \"long lines\" tail visualization
1850 [] n - toggle NEWLINE visualization
1851 [] e - toggle empty line at bob and/or eob visualization
1852 [] C-i - toggle indentation SPACEs visualization (via `indent-tabs-mode')
1853 [] I - toggle indentation SPACEs visualization
1854 [] i - toggle indentation TABs visualization
1855 [] C-a - toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1856 [] A - toggle SPACEs after TAB: SPACEs visualization
1857 [] a - toggle SPACEs after TAB: TABs visualization
1858 [] C-b - toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1859 [] B - toggle SPACEs before TAB: SPACEs visualization
1860 [] b - toggle SPACEs before TAB: TABs visualization
1861
1862 DISPLAY TABLE
1863 [] T - toggle TAB visualization
1864 [] S - toggle SPACE and HARD SPACE visualization
1865 [] N - toggle NEWLINE visualization
1866
1867 x - restore `whitespace-style' value
1868
1869 ? - display this text\n\n"
1870 "Text for whitespace toggle options.")
1871
1872
1873 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1874 "The buffer name for whitespace toggle options.")
1875
1876
1877 (defun whitespace-insert-value (value)
1878 "Insert VALUE at column 20 of next line."
1879 (forward-line 1)
1880 (move-to-column 20 t)
1881 (insert (format "%s" value)))
1882
1883
1884 (defun whitespace-mark-x (nchars condition)
1885 "Insert the mark ('X' or ' ') after NCHARS depending on CONDITION."
1886 (forward-char nchars)
1887 (insert (if condition "X" " ")))
1888
1889
1890 (defun whitespace-insert-option-mark (the-list the-value)
1891 "Insert the option mark ('X' or ' ') in toggle options buffer."
1892 (goto-char (point-min))
1893 (forward-line 2)
1894 (dolist (sym the-list)
1895 (if (eq sym 'help-newline)
1896 (forward-line 2)
1897 (forward-line 1)
1898 (whitespace-mark-x 2 (memq sym the-value)))))
1899
1900
1901 (defun whitespace-help-on (style)
1902 "Display the whitespace toggle options."
1903 (unless (get-buffer whitespace-help-buffer-name)
1904 (delete-other-windows)
1905 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
1906 (save-excursion
1907 (set-buffer buffer)
1908 (erase-buffer)
1909 (insert whitespace-help-text)
1910 (whitespace-insert-option-mark
1911 whitespace-style-value-list style)
1912 (whitespace-display-window buffer)))))
1913
1914
1915 (defun whitespace-display-window (buffer)
1916 "Display BUFFER in a new window."
1917 (goto-char (point-min))
1918 (set-buffer-modified-p nil)
1919 (let ((size (- (window-height)
1920 (max window-min-height
1921 (1+ (count-lines (point-min)
1922 (point-max)))))))
1923 (when (<= size 0)
1924 (kill-buffer buffer)
1925 (error "Frame height is too small; \
1926 can't split window to display whitespace toggle options"))
1927 (set-window-buffer (split-window nil size) buffer)))
1928
1929
1930 (defun whitespace-kill-buffer (buffer-name)
1931 "Kill buffer BUFFER-NAME and windows related with it."
1932 (let ((buffer (get-buffer buffer-name)))
1933 (when buffer
1934 (delete-windows-on buffer)
1935 (kill-buffer buffer))))
1936
1937
1938 (defun whitespace-help-off ()
1939 "Remove the buffer and window of the whitespace toggle options."
1940 (whitespace-kill-buffer whitespace-help-buffer-name))
1941
1942
1943 (defun whitespace-interactive-char (local-p)
1944 "Interactive function to read a char and return a symbol.
1945
1946 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1947 uses a global context.
1948
1949 It accepts one of the following chars:
1950
1951 CHAR MEANING
1952 (VIA FACES)
1953 t toggle TAB visualization
1954 s toggle SPACE and HARD SPACE visualization
1955 r toggle trailing blanks visualization
1956 l toggle \"long lines\" visualization
1957 L toggle \"long lines\" tail visualization
1958 n toggle NEWLINE visualization
1959 e toggle empty line at bob and/or eob visualization
1960 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1961 I toggle indentation SPACEs visualization
1962 i toggle indentation TABs visualization
1963 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1964 A toggle SPACEs after TAB: SPACEs visualization
1965 a toggle SPACEs after TAB: TABs visualization
1966 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1967 B toggle SPACEs before TAB: SPACEs visualization
1968 b toggle SPACEs before TAB: TABs visualization
1969
1970 (VIA DISPLAY TABLE)
1971 T toggle TAB visualization
1972 S toggle SPACE and HARD SPACE visualization
1973 N toggle NEWLINE visualization
1974
1975 x restore `whitespace-style' value
1976 ? display brief help
1977
1978 See also `whitespace-toggle-option-alist'."
1979 (let* ((is-off (not (if local-p
1980 whitespace-mode
1981 global-whitespace-mode)))
1982 (style (cond (is-off whitespace-style) ; use default value
1983 (local-p whitespace-active-style)
1984 (t whitespace-toggle-style)))
1985 (prompt
1986 (format "Whitespace Toggle %s (type ? for further options)-"
1987 (if local-p "Local" "Global")))
1988 ch sym)
1989 ;; read a valid option and get the corresponding symbol
1990 (save-window-excursion
1991 (condition-case data
1992 (progn
1993 (while
1994 ;; while condition
1995 (progn
1996 (setq ch (read-char prompt))
1997 (not
1998 (setq sym
1999 (cdr
2000 (assq ch whitespace-toggle-option-alist)))))
2001 ;; while body
2002 (if (eq ch ?\?)
2003 (whitespace-help-on style)
2004 (ding)))
2005 (whitespace-help-off)
2006 (message " ")) ; clean echo area
2007 ;; handler
2008 ((quit error)
2009 (whitespace-help-off)
2010 (error (error-message-string data)))))
2011 (list sym))) ; return the apropriate symbol
2012
2013
2014 (defun whitespace-toggle-list (local-p arg the-list)
2015 "Toggle options in THE-LIST based on list ARG.
2016
2017 If LOCAL-P is non-nil, it uses a local context; otherwise, it
2018 uses a global context.
2019
2020 ARG is a list of options to be toggled.
2021
2022 THE-LIST is a list of options. This list will be toggled and the
2023 resultant list will be returned."
2024 (unless (if local-p whitespace-mode global-whitespace-mode)
2025 (setq the-list whitespace-style))
2026 (setq the-list (copy-sequence the-list)) ; keep original list
2027 (dolist (sym (if (listp arg) arg (list arg)))
2028 (cond
2029 ;; ignore help value
2030 ((eq sym 'help-newline))
2031 ;; restore default values
2032 ((eq sym 'whitespace-style)
2033 (setq the-list whitespace-style))
2034 ;; toggle valid values
2035 ((memq sym whitespace-style-value-list)
2036 (setq the-list (if (memq sym the-list)
2037 (delq sym the-list)
2038 (cons sym the-list))))))
2039 the-list)
2040
2041
2042 (defvar whitespace-display-table nil
2043 "Used to save a local display table.")
2044
2045 (defvar whitespace-display-table-was-local nil
2046 "Used to remember whether a buffer initially had a local display table.")
2047
2048
2049 (defun whitespace-turn-on ()
2050 "Turn on whitespace visualization."
2051 ;; prepare local hooks
2052 (whitespace-add-local-hook)
2053 ;; create whitespace local buffer environment
2054 (set (make-local-variable 'whitespace-font-lock-mode) nil)
2055 (set (make-local-variable 'whitespace-font-lock) nil)
2056 (set (make-local-variable 'whitespace-font-lock-keywords) nil)
2057 (set (make-local-variable 'whitespace-display-table) nil)
2058 (set (make-local-variable 'whitespace-display-table-was-local) nil)
2059 (set (make-local-variable 'whitespace-active-style)
2060 (if (listp whitespace-style)
2061 whitespace-style
2062 (list whitespace-style)))
2063 (set (make-local-variable 'whitespace-indent-tabs-mode)
2064 indent-tabs-mode)
2065 (set (make-local-variable 'whitespace-tab-width)
2066 tab-width)
2067 ;; turn on whitespace
2068 (when whitespace-active-style
2069 (whitespace-color-on)
2070 (whitespace-display-char-on)))
2071
2072
2073 (defun whitespace-turn-off ()
2074 "Turn off whitespace visualization."
2075 (whitespace-remove-local-hook)
2076 (when whitespace-active-style
2077 (whitespace-color-off)
2078 (whitespace-display-char-off)))
2079
2080
2081 (defun whitespace-style-face-p ()
2082 "Return t if there is some visualization via face."
2083 (or (memq 'tabs whitespace-active-style)
2084 (memq 'spaces whitespace-active-style)
2085 (memq 'trailing whitespace-active-style)
2086 (memq 'lines whitespace-active-style)
2087 (memq 'lines-tail whitespace-active-style)
2088 (memq 'newline whitespace-active-style)
2089 (memq 'empty whitespace-active-style)
2090 (memq 'indentation whitespace-active-style)
2091 (memq 'indentation::tab whitespace-active-style)
2092 (memq 'indentation::space whitespace-active-style)
2093 (memq 'space-after-tab whitespace-active-style)
2094 (memq 'space-after-tab::tab whitespace-active-style)
2095 (memq 'space-after-tab::space whitespace-active-style)
2096 (memq 'space-before-tab whitespace-active-style)
2097 (memq 'space-before-tab::tab whitespace-active-style)
2098 (memq 'space-before-tab::space whitespace-active-style)))
2099
2100
2101 (defun whitespace-color-on ()
2102 "Turn on color visualization."
2103 (when (whitespace-style-face-p)
2104 (unless whitespace-font-lock
2105 (setq whitespace-font-lock t
2106 whitespace-font-lock-keywords
2107 (copy-sequence font-lock-keywords)))
2108 ;; turn off font lock
2109 (set (make-local-variable 'whitespace-font-lock-mode)
2110 font-lock-mode)
2111 (font-lock-mode 0)
2112 ;; add whitespace-mode color into font lock
2113 (when (memq 'spaces whitespace-active-style)
2114 (font-lock-add-keywords
2115 nil
2116 (list
2117 ;; Show SPACEs
2118 (list whitespace-space-regexp 1 whitespace-space t)
2119 ;; Show HARD SPACEs
2120 (list whitespace-hspace-regexp 1 whitespace-hspace t))
2121 t))
2122 (when (memq 'tabs whitespace-active-style)
2123 (font-lock-add-keywords
2124 nil
2125 (list
2126 ;; Show TABs
2127 (list whitespace-tab-regexp 1 whitespace-tab t))
2128 t))
2129 (when (memq 'trailing whitespace-active-style)
2130 (font-lock-add-keywords
2131 nil
2132 (list
2133 ;; Show trailing blanks
2134 (list whitespace-trailing-regexp 1 whitespace-trailing t))
2135 t))
2136 (when (or (memq 'lines whitespace-active-style)
2137 (memq 'lines-tail whitespace-active-style))
2138 (font-lock-add-keywords
2139 nil
2140 (list
2141 ;; Show "long" lines
2142 (list
2143 (format
2144 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
2145 whitespace-tab-width (1- whitespace-tab-width)
2146 (/ whitespace-line-column tab-width)
2147 (let ((rem (% whitespace-line-column whitespace-tab-width)))
2148 (if (zerop rem)
2149 ""
2150 (format ".\\{%d\\}" rem))))
2151 (if (memq 'lines whitespace-active-style)
2152 0 ; whole line
2153 2) ; line tail
2154 whitespace-line t))
2155 t))
2156 (cond
2157 ((memq 'space-before-tab whitespace-active-style)
2158 (font-lock-add-keywords
2159 nil
2160 (list
2161 ;; Show SPACEs before TAB (indent-tabs-mode)
2162 (list whitespace-space-before-tab-regexp
2163 (if whitespace-indent-tabs-mode 1 2)
2164 whitespace-space-before-tab t))
2165 t))
2166 ((memq 'space-before-tab::tab whitespace-active-style)
2167 (font-lock-add-keywords
2168 nil
2169 (list
2170 ;; Show SPACEs before TAB (SPACEs)
2171 (list whitespace-space-before-tab-regexp
2172 1 whitespace-space-before-tab t))
2173 t))
2174 ((memq 'space-before-tab::space whitespace-active-style)
2175 (font-lock-add-keywords
2176 nil
2177 (list
2178 ;; Show SPACEs before TAB (TABs)
2179 (list whitespace-space-before-tab-regexp
2180 2 whitespace-space-before-tab t))
2181 t)))
2182 (cond
2183 ((memq 'indentation whitespace-active-style)
2184 (font-lock-add-keywords
2185 nil
2186 (list
2187 ;; Show indentation SPACEs (indent-tabs-mode)
2188 (list (whitespace-indentation-regexp)
2189 1 whitespace-indentation t))
2190 t))
2191 ((memq 'indentation::tab whitespace-active-style)
2192 (font-lock-add-keywords
2193 nil
2194 (list
2195 ;; Show indentation SPACEs (SPACEs)
2196 (list (whitespace-indentation-regexp 'tab)
2197 1 whitespace-indentation t))
2198 t))
2199 ((memq 'indentation::space whitespace-active-style)
2200 (font-lock-add-keywords
2201 nil
2202 (list
2203 ;; Show indentation SPACEs (TABs)
2204 (list (whitespace-indentation-regexp 'space)
2205 1 whitespace-indentation t))
2206 t)))
2207 (when (memq 'empty whitespace-active-style)
2208 (font-lock-add-keywords
2209 nil
2210 (list
2211 ;; Show empty lines at beginning of buffer
2212 (list whitespace-empty-at-bob-regexp
2213 1 whitespace-empty t))
2214 t)
2215 (font-lock-add-keywords
2216 nil
2217 (list
2218 ;; Show empty lines at end of buffer
2219 (list whitespace-empty-at-eob-regexp
2220 1 whitespace-empty t))
2221 t))
2222 (cond
2223 ((memq 'space-after-tab whitespace-active-style)
2224 (font-lock-add-keywords
2225 nil
2226 (list
2227 ;; Show SPACEs after TAB (indent-tabs-mode)
2228 (list (whitespace-space-after-tab-regexp)
2229 1 whitespace-space-after-tab t))
2230 t))
2231 ((memq 'space-after-tab::tab whitespace-active-style)
2232 (font-lock-add-keywords
2233 nil
2234 (list
2235 ;; Show SPACEs after TAB (SPACEs)
2236 (list (whitespace-space-after-tab-regexp 'tab)
2237 1 whitespace-space-after-tab t))
2238 t))
2239 ((memq 'space-after-tab::space whitespace-active-style)
2240 (font-lock-add-keywords
2241 nil
2242 (list
2243 ;; Show SPACEs after TAB (TABs)
2244 (list (whitespace-space-after-tab-regexp 'space)
2245 1 whitespace-space-after-tab t))
2246 t)))
2247 ;; now turn on font lock and highlight blanks
2248 (font-lock-mode 1)))
2249
2250
2251 (defun whitespace-color-off ()
2252 "Turn off color visualization."
2253 ;; turn off font lock
2254 (when (whitespace-style-face-p)
2255 (font-lock-mode 0)
2256 (when whitespace-font-lock
2257 (setq whitespace-font-lock nil
2258 font-lock-keywords whitespace-font-lock-keywords))
2259 ;; restore original font lock state
2260 (font-lock-mode whitespace-font-lock-mode)))
2261
2262 \f
2263 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2264 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
2265
2266
2267 (defun whitespace-style-mark-p ()
2268 "Return t if there is some visualization via display table."
2269 (or (memq 'tab-mark whitespace-active-style)
2270 (memq 'space-mark whitespace-active-style)
2271 (memq 'newline-mark whitespace-active-style)))
2272
2273
2274 (defsubst whitespace-char-valid-p (char)
2275 ;; This check should be improved!!!
2276 (or (< char 256)
2277 (characterp char)))
2278
2279
2280 (defun whitespace-display-vector-p (vec)
2281 "Return true if every character in vector VEC can be displayed."
2282 (let ((i (length vec)))
2283 (when (> i 0)
2284 (while (and (>= (setq i (1- i)) 0)
2285 (whitespace-char-valid-p (aref vec i))))
2286 (< i 0))))
2287
2288
2289 (defun whitespace-display-char-on ()
2290 "Turn on character display mapping."
2291 (when (and whitespace-display-mappings
2292 (whitespace-style-mark-p))
2293 (let (vecs vec)
2294 ;; Remember whether a buffer has a local display table.
2295 (unless whitespace-display-table-was-local
2296 (setq whitespace-display-table-was-local t
2297 whitespace-display-table
2298 (copy-sequence buffer-display-table)))
2299 (unless buffer-display-table
2300 (setq buffer-display-table (make-display-table)))
2301 (dolist (entry whitespace-display-mappings)
2302 ;; check if it is to display this mark
2303 (when (memq (car entry) whitespace-style)
2304 ;; Get a displayable mapping.
2305 (setq vecs (cddr entry))
2306 (while (and vecs
2307 (not (whitespace-display-vector-p (car vecs))))
2308 (setq vecs (cdr vecs)))
2309 ;; Display a valid mapping.
2310 (when vecs
2311 (setq vec (copy-sequence (car vecs)))
2312 ;; NEWLINE char
2313 (when (and (eq (cadr entry) ?\n)
2314 (memq 'newline whitespace-active-style))
2315 ;; Only insert face bits on NEWLINE char mapping to avoid
2316 ;; obstruction of other faces like TABs and (HARD) SPACEs
2317 ;; faces, font-lock faces, etc.
2318 (dotimes (i (length vec))
2319 (or (eq (aref vec i) ?\n)
2320 (aset vec i
2321 (make-glyph-code (aref vec i)
2322 whitespace-newline)))))
2323 ;; Display mapping
2324 (aset buffer-display-table (cadr entry) vec)))))))
2325
2326
2327 (defun whitespace-display-char-off ()
2328 "Turn off character display mapping."
2329 (and whitespace-display-mappings
2330 (whitespace-style-mark-p)
2331 whitespace-display-table-was-local
2332 (setq whitespace-display-table-was-local nil
2333 buffer-display-table whitespace-display-table)))
2334
2335 \f
2336 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2337 ;;;; Hook
2338
2339
2340 (defun whitespace-action-when-on ()
2341 "Action to be taken always when local whitespace is turned on."
2342 (cond ((memq 'cleanup whitespace-action)
2343 (whitespace-cleanup))
2344 ((memq 'report-on-bogus whitespace-action)
2345 (whitespace-report nil t))))
2346
2347
2348 (defun whitespace-add-local-hook ()
2349 "Add some whitespace hooks locally."
2350 (add-hook 'write-file-functions 'whitespace-write-file-hook nil t)
2351 (add-hook 'kill-buffer-hook 'whitespace-kill-buffer-hook nil t))
2352
2353
2354 (defun whitespace-remove-local-hook ()
2355 "Remove some whitespace hooks locally."
2356 (remove-hook 'write-file-functions 'whitespace-write-file-hook t)
2357 (remove-hook 'kill-buffer-hook 'whitespace-kill-buffer-hook t))
2358
2359
2360 (defun whitespace-write-file-hook ()
2361 "Action to be taken when buffer is written.
2362 It should be added buffer-locally to `write-file-functions'."
2363 (when (whitespace-action)
2364 (error "Abort write due to whitespace problems in %s"
2365 (buffer-name)))
2366 nil) ; continue hook processing
2367
2368
2369 (defun whitespace-kill-buffer-hook ()
2370 "Action to be taken when buffer is killed.
2371 It should be added buffer-locally to `kill-buffer-hook'."
2372 (whitespace-action)
2373 nil) ; continue hook processing
2374
2375
2376 (defun whitespace-action ()
2377 "Action to be taken when buffer is killed or written.
2378 Return t when the action should be aborted."
2379 (cond ((memq 'auto-cleanup whitespace-action)
2380 (whitespace-cleanup)
2381 nil)
2382 ((memq 'abort-on-bogus whitespace-action)
2383 (whitespace-report nil t))
2384 (t
2385 nil)))
2386
2387 \f
2388 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2389
2390
2391 (defun whitespace-unload-function ()
2392 "Unload the whitespace library."
2393 (global-whitespace-mode -1)
2394 ;; be sure all local whitespace mode is turned off
2395 (save-current-buffer
2396 (dolist (buf (buffer-list))
2397 (set-buffer buf)
2398 (whitespace-mode -1)))
2399 nil) ; continue standard unloading
2400
2401
2402 (provide 'whitespace)
2403
2404
2405 (run-hooks 'whitespace-load-hook)
2406
2407
2408 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
2409 ;;; whitespace.el ends here