Switch to recommended form of GPLv3 permissions notice.
[emacs.git] / lisp / whitespace.el
blob8053483b70d3f0800819d292536f6b1d7b4d4fdc
1 ;;; whitespace.el --- minor mode to visualize TAB, (HARD) SPACE, NEWLINE
3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
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.1
10 ;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
12 ;; This file is part of GNU Emacs.
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.
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.
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/>.
27 ;;; Commentary:
29 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31 ;; Introduction
32 ;; ------------
34 ;; This package is a minor mode to visualize blanks (TAB, (HARD) SPACE
35 ;; and NEWLINE).
37 ;; whitespace uses two ways to visualize blanks: faces and display
38 ;; table.
40 ;; * Faces are used to highlight the background with a color.
41 ;; whitespace uses font-lock to highlight blank characters.
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).
47 ;; The `whitespace-style' variable selects which way blanks are
48 ;; visualized.
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.
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).
63 ;; There are two ways of using whitespace: local and global.
65 ;; * Local whitespace affects only the current buffer.
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.
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.
78 ;; When global and local whitespace are on:
80 ;; * if local whitespace is turned off, whitespace is turned off for
81 ;; the current buffer only.
83 ;; * if global whitespace is turned off, whitespace continues on only
84 ;; in the buffers in which local whitespace is on.
86 ;; To use whitespace, insert in your ~/.emacs:
88 ;; (require 'whitespace-mode)
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:
94 ;; (autoload 'whitespace-mode "whitespace"
95 ;; "Toggle whitespace visualization." t)
96 ;; (autoload 'whitespace-toggle-options "whitespace"
97 ;; "Toggle local `whitespace-mode' options." t)
99 ;; whitespace was inspired by:
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'.
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)
112 ;; whitespace-mode.el Lawrence Mitchell <wence@gmx.li>
113 ;; Major mode for editing Whitespace
114 ;; (inspired the idea to use display table)
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)
122 ;; Using whitespace
123 ;; ----------------
125 ;; There is no problem if you mix local and global minor mode usage.
127 ;; * LOCAL whitespace:
128 ;; + To toggle whitespace options locally, type:
130 ;; M-x whitespace-toggle-options RET
132 ;; + To activate whitespace locally, type:
134 ;; C-u 1 M-x whitespace-mode RET
136 ;; + To deactivate whitespace locally, type:
138 ;; C-u 0 M-x whitespace-mode RET
140 ;; + To toggle whitespace locally, type:
142 ;; M-x whitespace-mode RET
144 ;; * GLOBAL whitespace:
145 ;; + To toggle whitespace options globally, type:
147 ;; M-x global-whitespace-toggle-options RET
149 ;; + To activate whitespace globally, type:
151 ;; C-u 1 M-x global-whitespace-mode RET
153 ;; + To deactivate whitespace globally, type:
155 ;; C-u 0 M-x global-whitespace-mode RET
157 ;; + To toggle whitespace globally, type:
159 ;; M-x global-whitespace-mode RET
161 ;; There are also the following useful commands:
163 ;; `whitespace-report'
164 ;; Report some blank problems in buffer.
166 ;; `whitespace-report-region'
167 ;; Report some blank problems in a region.
169 ;; `whitespace-cleanup'
170 ;; Cleanup some blank problems in all buffer or at region.
172 ;; `whitespace-cleanup-region'
173 ;; Cleanup some blank problems at region.
175 ;; The problems, which are cleaned up, are:
177 ;; 1. empty lines at beginning of buffer.
178 ;; 2. empty lines at end of buffer.
179 ;; If `whitespace-style' includes the value `empty', remove all
180 ;; empty lines at beginning and/or end of buffer.
182 ;; 3. 8 or more SPACEs at beginning of line.
183 ;; If `whitespace-style' includes the value `indentation':
184 ;; replace 8 or more SPACEs at beginning of line by TABs, if
185 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
186 ;; SPACEs.
187 ;; If `whitespace-style' includes the value `indentation::tab',
188 ;; replace 8 or more SPACEs at beginning of line by TABs.
189 ;; If `whitespace-style' includes the value `indentation::space',
190 ;; replace TABs by SPACEs.
192 ;; 4. SPACEs before TAB.
193 ;; If `whitespace-style' includes the value `space-before-tab':
194 ;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
195 ;; otherwise, replace TABs by SPACEs.
196 ;; If `whitespace-style' includes the value
197 ;; `space-before-tab::tab', replace SPACEs by TABs.
198 ;; If `whitespace-style' includes the value
199 ;; `space-before-tab::space', replace TABs by SPACEs.
201 ;; 5. SPACEs or TABs at end of line.
202 ;; If `whitespace-style' includes the value `trailing', remove all
203 ;; SPACEs or TABs at end of line.
205 ;; 6. 8 or more SPACEs after TAB.
206 ;; If `whitespace-style' includes the value `space-after-tab':
207 ;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
208 ;; otherwise, replace TABs by SPACEs.
209 ;; If `whitespace-style' includes the value `space-after-tab::tab',
210 ;; replace SPACEs by TABs.
211 ;; If `whitespace-style' includes the value
212 ;; `space-after-tab::space', replace TABs by SPACEs.
215 ;; Hooks
216 ;; -----
218 ;; whitespace has the following hook variables:
220 ;; `whitespace-mode-hook'
221 ;; It is evaluated always when whitespace is turned on locally.
223 ;; `global-whitespace-mode-hook'
224 ;; It is evaluated always when whitespace is turned on globally.
226 ;; `whitespace-load-hook'
227 ;; It is evaluated after whitespace package is loaded.
230 ;; Options
231 ;; -------
233 ;; Below it's shown a brief description of whitespace options, please,
234 ;; see the options declaration in the code for a long documentation.
236 ;; `whitespace-style' Specify which kind of blank is
237 ;; visualized.
239 ;; `whitespace-space' Face used to visualize SPACE.
241 ;; `whitespace-hspace' Face used to visualize HARD SPACE.
243 ;; `whitespace-tab' Face used to visualize TAB.
245 ;; `whitespace-newline' Face used to visualize NEWLINE char
246 ;; mapping.
248 ;; `whitespace-trailing' Face used to visualize trailing
249 ;; blanks.
251 ;; `whitespace-line' Face used to visualize "long" lines.
253 ;; `whitespace-space-before-tab' Face used to visualize SPACEs
254 ;; before TAB.
256 ;; `whitespace-indentation' Face used to visualize 8 or more
257 ;; SPACEs at beginning of line.
259 ;; `whitespace-empty' Face used to visualize empty lines at
260 ;; beginning and/or end of buffer.
262 ;; `whitespace-space-after-tab' Face used to visualize 8 or more
263 ;; SPACEs after TAB.
265 ;; `whitespace-space-regexp' Specify SPACE characters regexp.
267 ;; `whitespace-hspace-regexp' Specify HARD SPACE characters regexp.
269 ;; `whitespace-tab-regexp' Specify TAB characters regexp.
271 ;; `whitespace-trailing-regexp' Specify trailing characters regexp.
273 ;; `whitespace-space-before-tab-regexp' Specify SPACEs before TAB
274 ;; regexp.
276 ;; `whitespace-indentation-regexp' Specify regexp for 8 or more
277 ;; SPACEs at beginning of line.
279 ;; `whitespace-empty-at-bob-regexp' Specify regexp for empty lines
280 ;; at beginning of buffer.
282 ;; `whitespace-empty-at-eob-regexp' Specify regexp for empty lines
283 ;; at end of buffer.
285 ;; `whitespace-space-after-tab-regexp' Specify regexp for 8 or more
286 ;; SPACEs after TAB.
288 ;; `whitespace-line-column' Specify column beyond which the line
289 ;; is highlighted.
291 ;; `whitespace-display-mappings' Specify an alist of mappings
292 ;; for displaying characters.
294 ;; `whitespace-global-modes' Modes for which global
295 ;; `whitespace-mode' is automagically
296 ;; turned on.
298 ;; `whitespace-action' Specify which action is taken when a
299 ;; buffer is visited, killed or written.
302 ;; Acknowledgements
303 ;; ----------------
305 ;; Thanks to Stephen Deasey <sdeasey@gmail.com> for the
306 ;; `indent-tabs-mode' usage suggestion.
308 ;; Thanks to Eric Cooper <ecc@cmu.edu> for the suggestion to have hook
309 ;; actions when buffer is written or killed as the original whitespace
310 ;; package had.
312 ;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
313 ;; lines tail. See EightyColumnRule (EmacsWiki).
315 ;; Thanks to Juri Linkov <juri@jurta.org> for suggesting:
316 ;; * `define-minor-mode'.
317 ;; * `global-whitespace-*' name for global commands.
319 ;; Thanks to Robert J. Chassell <bob@gnu.org> for doc fix and testing.
321 ;; Thanks to Drew Adams <drew.adams@oracle.com> for toggle commands
322 ;; suggestion.
324 ;; Thanks to Antti Kaihola <antti.kaihola@linux-aktivaattori.org> for
325 ;; helping to fix `find-file-hooks' reference.
327 ;; Thanks to Andreas Roehler <andreas.roehler@easy-emacs.de> for
328 ;; indicating defface byte-compilation warnings.
330 ;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight
331 ;; "long" lines. See EightyColumnRule (EmacsWiki).
333 ;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
334 ;; newline character mapping.
336 ;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
337 ;; whitespace-mode.el on XEmacs.
339 ;; Thanks to Miles Bader <miles@gnu.org> for handling display table via
340 ;; visws.el (his code was modified, but the main idea was kept).
342 ;; Thanks to:
343 ;; Rajesh Vaidheeswarran <rv@gnu.org> (original) whitespace.el
344 ;; Aurelien Tisne <aurelien.tisne@free.fr> show-whitespace-mode.el
345 ;; Lawrence Mitchell <wence@gmx.li> whitespace-mode.el
346 ;; Miles Bader <miles@gnu.org> visws.el
347 ;; And to all people who contributed with them.
350 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
352 ;;; code:
355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
356 ;;;; User Variables:
359 ;;; Interface to the command system
362 (defgroup whitespace nil
363 "Visualize blanks (TAB, (HARD) SPACE and NEWLINE)."
364 :link '(emacs-library-link :tag "Source Lisp File" "whitespace.el")
365 :version "23.1"
366 :group 'wp
367 :group 'data)
370 (defcustom whitespace-style
371 '(tabs spaces trailing lines space-before-tab newline
372 indentation empty space-after-tab
373 space-mark tab-mark newline-mark)
374 "*Specify which kind of blank is visualized.
376 It's a list containing some or all of the following values:
378 trailing trailing blanks are visualized via faces.
380 tabs TABs are visualized via faces.
382 spaces SPACEs and HARD SPACEs are visualized via
383 faces.
385 lines lines whose have columns beyond
386 `whitespace-line-column' are highlighted via
387 faces .
388 Whole line is highlighted.
389 It has precedence over `lines-tail' (see
390 below).
392 lines-tail lines whose have columns beyond
393 `whitespace-line-column' are highlighted via
394 faces.
395 But only the part of line which goes
396 beyond `whitespace-line-column' column.
397 It has effect only if `lines' (see above)
398 is not present in `whitespace-style'.
400 newline NEWLINEs are visualized via faces.
402 empty empty lines at beginning and/or end of buffer
403 are visualized via faces.
405 indentation::tab 8 or more SPACEs at beginning of line are
406 visualized via faces.
408 indentation::space TABs at beginning of line are visualized via
409 faces.
411 indentation 8 or more SPACEs at beginning of line are
412 visualized, if `indent-tabs-mode' (which see)
413 is non-nil; otherwise, TABs at beginning of
414 line are visualized via faces.
416 space-after-tab::tab 8 or more SPACEs after a TAB are
417 visualized via faces.
419 space-after-tab::space TABs are visualized when occurs 8 or
420 more SPACEs after a TAB via faces.
422 space-after-tab 8 or more SPACEs after a TAB are
423 visualized, if `indent-tabs-mode'
424 (which see) is non-nil; otherwise,
425 the TABs are visualized via faces.
427 space-before-tab::tab SPACEs before TAB are visualized via
428 faces.
430 space-before-tab::space TABs are visualized when occurs SPACEs
431 before TAB via faces.
433 space-before-tab SPACEs before TAB are visualized, if
434 `indent-tabs-mode' (which see) is
435 non-nil; otherwise, the TABs are
436 visualized via faces.
438 space-mark SPACEs and HARD SPACEs are visualized via
439 display table.
441 tab-mark TABs are visualized via display table.
443 newline-mark NEWLINEs are visualized via display table.
445 Any other value is ignored.
447 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs via faces and
448 via display table.
450 There is an evaluation order for some values, if some values are
451 included in `whitespace-style' list. For example, if
452 indentation, indentation::tab and/or indentation::space are
453 included in `whitespace-style' list. The evaluation order for
454 these values is:
456 * For indentation:
457 1. indentation
458 2. indentation::tab
459 3. indentation::space
461 * For SPACEs after TABs:
462 1. space-after-tab
463 2. space-after-tab::tab
464 3. space-after-tab::space
466 * For SPACEs before TABs:
467 1. space-before-tab
468 2. space-before-tab::tab
469 3. space-before-tab::space
471 So, for example, if indentation and indentation::space are
472 included in `whitespace-style' list, the indentation value is
473 evaluated instead of indentation::space value.
475 See also `whitespace-display-mappings' for documentation."
476 :type '(repeat :tag "Kind of Blank"
477 (choice :tag "Kind of Blank Face"
478 (const :tag "(Face) Trailing TABs, SPACEs and HARD SPACEs"
479 trailing)
480 (const :tag "(Face) SPACEs and HARD SPACEs"
481 spaces)
482 (const :tag "(Face) TABs" tabs)
483 (const :tag "(Face) Lines" lines)
484 (const :tag "(Face) SPACEs before TAB"
485 space-before-tab)
486 (const :tag "(Face) NEWLINEs" newline)
487 (const :tag "(Face) Indentation SPACEs"
488 indentation)
489 (const :tag "(Face) Empty Lines At BOB And/Or EOB"
490 empty)
491 (const :tag "(Face) SPACEs after TAB"
492 space-after-tab)
493 (const :tag "(Mark) SPACEs and HARD SPACEs"
494 space-mark)
495 (const :tag "(Mark) TABs" tab-mark)
496 (const :tag "(Mark) NEWLINEs" newline-mark)))
497 :group 'whitespace)
500 (defcustom whitespace-space 'whitespace-space
501 "*Symbol face used to visualize SPACE.
503 Used when `whitespace-style' includes the value `spaces'."
504 :type 'face
505 :group 'whitespace)
508 (defface whitespace-space
509 '((((class color) (background dark))
510 (:background "grey20" :foreground "aquamarine3"))
511 (((class color) (background light))
512 (:background "LightYellow" :foreground "aquamarine3"))
513 (t (:inverse-video t)))
514 "Face used to visualize SPACE."
515 :group 'whitespace)
518 (defcustom whitespace-hspace 'whitespace-hspace
519 "*Symbol face used to visualize HARD SPACE.
521 Used when `whitespace-style' includes the value `spaces'."
522 :type 'face
523 :group 'whitespace)
526 (defface whitespace-hspace ; 'nobreak-space
527 '((((class color) (background dark))
528 (:background "grey24" :foreground "aquamarine3"))
529 (((class color) (background light))
530 (:background "LemonChiffon3" :foreground "aquamarine3"))
531 (t (:inverse-video t)))
532 "Face used to visualize HARD SPACE."
533 :group 'whitespace)
536 (defcustom whitespace-tab 'whitespace-tab
537 "*Symbol face used to visualize TAB.
539 Used when `whitespace-style' includes the value `tabs'."
540 :type 'face
541 :group 'whitespace)
544 (defface whitespace-tab
545 '((((class color) (background dark))
546 (:background "grey22" :foreground "aquamarine3"))
547 (((class color) (background light))
548 (:background "beige" :foreground "aquamarine3"))
549 (t (:inverse-video t)))
550 "Face used to visualize TAB."
551 :group 'whitespace)
554 (defcustom whitespace-newline 'whitespace-newline
555 "*Symbol face used to visualize NEWLINE char mapping.
557 See `whitespace-display-mappings'.
559 Used when `whitespace-style' includes the values `newline-mark'
560 and `newline'."
561 :type 'face
562 :group 'whitespace)
565 (defface whitespace-newline
566 '((((class color) (background dark))
567 (:background "grey26" :foreground "aquamarine3" :bold t))
568 (((class color) (background light))
569 (:background "linen" :foreground "aquamarine3" :bold t))
570 (t (:bold t :underline t)))
571 "Face used to visualize NEWLINE char mapping.
573 See `whitespace-display-mappings'."
574 :group 'whitespace)
577 (defcustom whitespace-trailing 'whitespace-trailing
578 "*Symbol face used to visualize trailing blanks.
580 Used when `whitespace-style' includes the value `trailing'."
581 :type 'face
582 :group 'whitespace)
585 (defface whitespace-trailing ; 'trailing-whitespace
586 '((((class mono)) (:inverse-video t :bold t :underline t))
587 (t (:background "red1" :foreground "yellow" :bold t)))
588 "Face used to visualize trailing blanks."
589 :group 'whitespace)
592 (defcustom whitespace-line 'whitespace-line
593 "*Symbol face used to visualize \"long\" lines.
595 See `whitespace-line-column'.
597 Used when `whitespace-style' includes the value `line'."
598 :type 'face
599 :group 'whitespace)
602 (defface whitespace-line
603 '((((class mono)) (:inverse-video t :bold t :underline t))
604 (t (:background "gray20" :foreground "violet")))
605 "Face used to visualize \"long\" lines.
607 See `whitespace-line-column'."
608 :group 'whitespace)
611 (defcustom whitespace-space-before-tab 'whitespace-space-before-tab
612 "*Symbol face used to visualize SPACEs before TAB.
614 Used when `whitespace-style' includes the value `space-before-tab'."
615 :type 'face
616 :group 'whitespace)
619 (defface whitespace-space-before-tab
620 '((((class mono)) (:inverse-video t :bold t :underline t))
621 (t (:background "DarkOrange" :foreground "firebrick")))
622 "Face used to visualize SPACEs before TAB."
623 :group 'whitespace)
626 (defcustom whitespace-indentation 'whitespace-indentation
627 "*Symbol face used to visualize 8 or more SPACEs at beginning of line.
629 Used when `whitespace-style' includes the value `indentation'."
630 :type 'face
631 :group 'whitespace)
634 (defface whitespace-indentation
635 '((((class mono)) (:inverse-video t :bold t :underline t))
636 (t (:background "yellow" :foreground "firebrick")))
637 "Face used to visualize 8 or more SPACEs at beginning of line."
638 :group 'whitespace)
641 (defcustom whitespace-empty 'whitespace-empty
642 "*Symbol face used to visualize empty lines at beginning and/or end of buffer.
644 Used when `whitespace-style' includes the value `empty'."
645 :type 'face
646 :group 'whitespace)
649 (defface whitespace-empty
650 '((((class mono)) (:inverse-video t :bold t :underline t))
651 (t (:background "yellow" :foreground "firebrick")))
652 "Face used to visualize empty lines at beginning and/or end of buffer."
653 :group 'whitespace)
656 (defcustom whitespace-space-after-tab 'whitespace-space-after-tab
657 "*Symbol face used to visualize 8 or more SPACEs after TAB.
659 Used when `whitespace-style' includes the value `space-after-tab'."
660 :type 'face
661 :group 'whitespace)
664 (defface whitespace-space-after-tab
665 '((((class mono)) (:inverse-video t :bold t :underline t))
666 (t (:background "yellow" :foreground "firebrick")))
667 "Face used to visualize 8 or more SPACEs after TAB."
668 :group 'whitespace)
671 (defcustom whitespace-hspace-regexp
672 "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
673 "*Specify HARD SPACE characters regexp.
675 If you're using `mule' package, there may be other characters besides:
677 \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
679 that should be considered HARD SPACE.
681 Here are some examples:
683 \"\\\\(^\\xA0+\\\\)\" \
684 visualize only leading HARD SPACEs.
685 \"\\\\(\\xA0+$\\\\)\" \
686 visualize only trailing HARD SPACEs.
687 \"\\\\(^\\xA0+\\\\|\\xA0+$\\\\)\" \
688 visualize leading and/or trailing HARD SPACEs.
689 \"\\t\\\\(\\xA0+\\\\)\\t\" \
690 visualize only HARD SPACEs between TABs.
692 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
693 Use exactly one pair of enclosing \\\\( and \\\\).
695 Used when `whitespace-style' includes `spaces'."
696 :type '(regexp :tag "HARD SPACE Chars")
697 :group 'whitespace)
700 (defcustom whitespace-space-regexp "\\( +\\)"
701 "*Specify SPACE characters regexp.
703 If you're using `mule' package, there may be other characters
704 besides \" \" that should be considered SPACE.
706 Here are some examples:
708 \"\\\\(^ +\\\\)\" visualize only leading SPACEs.
709 \"\\\\( +$\\\\)\" visualize only trailing SPACEs.
710 \"\\\\(^ +\\\\| +$\\\\)\" \
711 visualize leading and/or trailing SPACEs.
712 \"\\t\\\\( +\\\\)\\t\" visualize only SPACEs between TABs.
714 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
715 Use exactly one pair of enclosing \\\\( and \\\\).
717 Used when `whitespace-style' includes `spaces'."
718 :type '(regexp :tag "SPACE Chars")
719 :group 'whitespace)
722 (defcustom whitespace-tab-regexp "\\(\t+\\)"
723 "*Specify TAB characters regexp.
725 If you're using `mule' package, there may be other characters
726 besides \"\\t\" that should be considered TAB.
728 Here are some examples:
730 \"\\\\(^\\t+\\\\)\" visualize only leading TABs.
731 \"\\\\(\\t+$\\\\)\" visualize only trailing TABs.
732 \"\\\\(^\\t+\\\\|\\t+$\\\\)\" \
733 visualize leading and/or trailing TABs.
734 \" \\\\(\\t+\\\\) \" visualize only TABs between SPACEs.
736 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
737 Use exactly one pair of enclosing \\\\( and \\\\).
739 Used when `whitespace-style' includes `tabs'."
740 :type '(regexp :tag "TAB Chars")
741 :group 'whitespace)
744 (defcustom whitespace-trailing-regexp
745 "\\(\\(\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)$"
746 "*Specify trailing characters regexp.
748 If you're using `mule' package, there may be other characters besides:
750 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
751 \"\\xF20\"
753 that should be considered blank.
755 NOTE: Enclose always by \"\\\\(\" and \"\\\\)$\" the elements to highlight.
756 Use exactly one pair of enclosing elements above.
758 Used when `whitespace-style' includes `trailing'."
759 :type '(regexp :tag "Trailing Chars")
760 :group 'whitespace)
763 (defcustom whitespace-space-before-tab-regexp "\\( +\\)\\(\t+\\)"
764 "*Specify SPACEs before TAB regexp.
766 If you're using `mule' package, there may be other characters besides:
768 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
769 \"\\xF20\"
771 that should be considered blank.
773 Used when `whitespace-style' includes `space-before-tab',
774 `space-before-tab::tab' or `space-before-tab::space'."
775 :type '(regexp :tag "SPACEs Before TAB")
776 :group 'whitespace)
779 (defcustom whitespace-indentation-regexp
780 '("^\t*\\(\\( \\{%d\\}\\)+\\)[^\n\t]"
781 . "^ *\\(\t+\\)[^\n]")
782 "*Specify regexp for 8 or more SPACEs at beginning of line.
784 It is a cons where the cons car is used for SPACEs visualization
785 and the cons cdr is used for TABs visualization.
787 If you're using `mule' package, there may be other characters besides:
789 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
790 \"\\xF20\"
792 that should be considered blank.
794 Used when `whitespace-style' includes `indentation',
795 `indentation::tab' or `indentation::space'."
796 :type '(cons (regexp :tag "Indentation SPACEs")
797 (regexp :tag "Indentation TABs"))
798 :group 'whitespace)
801 (defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
802 "*Specify regexp for empty lines at beginning of buffer.
804 If you're using `mule' package, there may be other characters besides:
806 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
807 \"\\xF20\"
809 that should be considered blank.
811 Used when `whitespace-style' includes `empty'."
812 :type '(regexp :tag "Empty Lines At Beginning Of Buffer")
813 :group 'whitespace)
816 (defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
817 "*Specify regexp for empty lines at end of buffer.
819 If you're using `mule' package, there may be other characters besides:
821 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
822 \"\\xF20\"
824 that should be considered blank.
826 Used when `whitespace-style' includes `empty'."
827 :type '(regexp :tag "Empty Lines At End Of Buffer")
828 :group 'whitespace)
831 (defcustom whitespace-space-after-tab-regexp
832 '("\t+\\(\\( \\{%d\\}\\)+\\)"
833 . "\\(\t+\\) +")
834 "*Specify regexp for 8 or more SPACEs after TAB.
836 It is a cons where the cons car is used for SPACEs visualization
837 and the cons cdr is used for TABs visualization.
839 If you're using `mule' package, there may be other characters besides:
841 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
842 \"\\xF20\"
844 that should be considered blank.
846 Used when `whitespace-style' includes `space-after-tab',
847 `space-after-tab::tab' or `space-after-tab::space'."
848 :type '(regexp :tag "SPACEs After TAB")
849 :group 'whitespace)
852 (defcustom whitespace-line-column 80
853 "*Specify column beyond which the line is highlighted.
855 Used when `whitespace-style' includes `lines' or `lines-tail'."
856 :type '(integer :tag "Line Length")
857 :group 'whitespace)
860 ;; Hacked from `visible-whitespace-mappings' in visws.el
861 (defcustom whitespace-display-mappings
863 (space-mark ?\ [?\xB7] [?.]) ; space - centered dot
864 (space-mark ?\xA0 [?\xA4] [?_]) ; hard space - currency
865 (space-mark ?\x8A0 [?\x8A4] [?_]) ; hard space - currency
866 (space-mark ?\x920 [?\x924] [?_]) ; hard space - currency
867 (space-mark ?\xE20 [?\xE24] [?_]) ; hard space - currency
868 (space-mark ?\xF20 [?\xF24] [?_]) ; hard space - currency
869 ;; NEWLINE is displayed using the face `whitespace-newline'
870 (newline-mark ?\n [?$ ?\n]) ; eol - dollar sign
871 ;; (newline-mark ?\n [?\u21B5 ?\n] [?$ ?\n]) ; eol - downwards arrow
872 ;; (newline-mark ?\n [?\xB6 ?\n] [?$ ?\n]) ; eol - pilcrow
873 ;; (newline-mark ?\n [?\x8AF ?\n] [?$ ?\n]) ; eol - overscore
874 ;; (newline-mark ?\n [?\x8AC ?\n] [?$ ?\n]) ; eol - negation
875 ;; (newline-mark ?\n [?\x8B0 ?\n] [?$ ?\n]) ; eol - grade
877 ;; WARNING: the mapping below has a problem.
878 ;; When a TAB occupies exactly one column, it will display the
879 ;; character ?\xBB at that column followed by a TAB which goes to
880 ;; the next TAB column.
881 ;; If this is a problem for you, please, comment the line below.
882 (tab-mark ?\t [?\xBB ?\t] [?\\ ?\t]) ; tab - left quote mark
884 "*Specify an alist of mappings for displaying characters.
886 Each element has the following form:
888 (KIND CHAR VECTOR...)
890 Where:
892 KIND is the kind of character.
893 It can be one of the following symbols:
895 tab-mark for TAB character
897 space-mark for SPACE or HARD SPACE character
899 newline-mark for NEWLINE character
901 CHAR is the character to be mapped.
903 VECTOR is a vector of characters to be displayed in place of CHAR.
904 The first display vector that can be displayed is used;
905 if no display vector for a mapping can be displayed, then
906 that character is displayed unmodified.
908 The NEWLINE character is displayed using the face given by
909 `whitespace-newline' variable.
911 Used when `whitespace-style' includes `tab-mark', `space-mark' or
912 `newline-mark'."
913 :type '(repeat
914 (list :tag "Character Mapping"
915 (choice :tag "Char Kind"
916 (const :tag "Tab" tab-mark)
917 (const :tag "Space" space-mark)
918 (const :tag "Newline" newline-mark))
919 (character :tag "Char")
920 (repeat :inline t :tag "Vector List"
921 (vector :tag ""
922 (repeat :inline t
923 :tag "Vector Characters"
924 (character :tag "Char"))))))
925 :group 'whitespace)
928 (defcustom whitespace-global-modes t
929 "*Modes for which global `whitespace-mode' is automagically turned on.
931 Global `whitespace-mode' is controlled by the command
932 `global-whitespace-mode'.
934 If nil, means no modes have `whitespace-mode' automatically
935 turned on.
937 If t, all modes that support `whitespace-mode' have it
938 automatically turned on.
940 Else it should be a list of `major-mode' symbol names for which
941 `whitespace-mode' should be automatically turned on. The sense
942 of the list is negated if it begins with `not'. For example:
944 (c-mode c++-mode)
946 means that `whitespace-mode' is turned on for buffers in C and
947 C++ modes only."
948 :type '(choice :tag "Global Modes"
949 (const :tag "None" nil)
950 (const :tag "All" t)
951 (set :menu-tag "Mode Specific" :tag "Modes"
952 :value (not)
953 (const :tag "Except" not)
954 (repeat :inline t
955 (symbol :tag "Mode"))))
956 :group 'whitespace)
959 (defcustom whitespace-action nil
960 "*Specify which action is taken when a buffer is visited, killed or written.
962 It's a list containing some or all of the following values:
964 nil no action is taken.
966 cleanup cleanup any bogus whitespace always when local
967 whitespace is turned on.
968 See `whitespace-cleanup' and
969 `whitespace-cleanup-region'.
971 report-on-bogus report if there is any bogus whitespace always
972 when local whitespace is turned on.
974 auto-cleanup cleanup any bogus whitespace when buffer is
975 written or killed.
976 See `whitespace-cleanup' and
977 `whitespace-cleanup-region'.
979 abort-on-bogus abort if there is any bogus whitespace and the
980 buffer is written or killed.
982 Any other value is treated as nil."
983 :type '(choice :tag "Actions"
984 (const :tag "None" nil)
985 (repeat :tag "Action List"
986 (choice :tag "Action"
987 (const :tag "Cleanup When On" cleanup)
988 (const :tag "Report On Bogus" report-on-bogus)
989 (const :tag "Auto Cleanup" auto-cleanup)
990 (const :tag "Abort On Bogus" abort-on-bogus))))
991 :group 'whitespace)
994 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
995 ;;;; User commands - Local mode
998 ;;;###autoload
999 (define-minor-mode whitespace-mode
1000 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
1002 If ARG is null, toggle whitespace visualization.
1003 If ARG is a number greater than zero, turn on visualization;
1004 otherwise, turn off visualization.
1005 Only useful with a windowing system."
1006 :lighter " ws"
1007 :init-value nil
1008 :global nil
1009 :group 'whitespace
1010 (cond
1011 (noninteractive ; running a batch job
1012 (setq whitespace-mode nil))
1013 (whitespace-mode ; whitespace-mode on
1014 (whitespace-turn-on)
1015 (whitespace-action-when-on))
1016 (t ; whitespace-mode off
1017 (whitespace-turn-off))))
1020 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1021 ;;;; User commands - Global mode
1024 ;;;###autoload
1025 (define-minor-mode global-whitespace-mode
1026 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
1028 If ARG is null, toggle whitespace visualization.
1029 If ARG is a number greater than zero, turn on visualization;
1030 otherwise, turn off visualization.
1031 Only useful with a windowing system."
1032 :lighter " WS"
1033 :init-value nil
1034 :global t
1035 :group 'whitespace
1036 (cond
1037 (noninteractive ; running a batch job
1038 (setq global-whitespace-mode nil))
1039 (global-whitespace-mode ; global-whitespace-mode on
1040 (save-excursion
1041 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1042 (dolist (buffer (buffer-list)) ; adjust all local mode
1043 (set-buffer buffer)
1044 (unless whitespace-mode
1045 (whitespace-turn-on-if-enabled)))))
1046 (t ; global-whitespace-mode off
1047 (save-excursion
1048 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1049 (dolist (buffer (buffer-list)) ; adjust all local mode
1050 (set-buffer buffer)
1051 (unless whitespace-mode
1052 (whitespace-turn-off)))))))
1055 (defun whitespace-turn-on-if-enabled ()
1056 (when (cond
1057 ((eq whitespace-global-modes t))
1058 ((listp whitespace-global-modes)
1059 (if (eq (car-safe whitespace-global-modes) 'not)
1060 (not (memq major-mode (cdr whitespace-global-modes)))
1061 (memq major-mode whitespace-global-modes)))
1062 (t nil))
1063 (let (inhibit-quit)
1064 ;; Don't turn on whitespace mode if...
1066 ;; ...we don't have a display (we're running a batch job)
1067 noninteractive
1068 ;; ...or if the buffer is invisible (name starts with a space)
1069 (eq (aref (buffer-name) 0) ?\ )
1070 ;; ...or if the buffer is temporary (name starts with *)
1071 (and (eq (aref (buffer-name) 0) ?*)
1072 ;; except the scratch buffer.
1073 (not (string= (buffer-name) "*scratch*")))
1074 ;; Otherwise, turn on whitespace mode.
1075 (whitespace-turn-on)))))
1078 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1079 ;;;; User commands - Toggle
1082 (defconst whitespace-style-value-list
1083 '(tabs
1084 spaces
1085 trailing
1086 lines
1087 lines-tail
1088 newline
1089 empty
1090 indentation
1091 indentation::tab
1092 indentation::space
1093 space-after-tab
1094 space-after-tab::tab
1095 space-after-tab::space
1096 space-before-tab
1097 space-before-tab::tab
1098 space-before-tab::space
1099 help-newline ; value used by `whitespace-insert-option-mark'
1100 tab-mark
1101 space-mark
1102 newline-mark
1104 "List of valid `whitespace-style' values.")
1107 (defconst whitespace-toggle-option-alist
1108 '((?t . tabs)
1109 (?s . spaces)
1110 (?r . trailing)
1111 (?l . lines)
1112 (?L . lines-tail)
1113 (?n . newline)
1114 (?e . empty)
1115 (?\C-i . indentation)
1116 (?I . indentation::tab)
1117 (?i . indentation::space)
1118 (?\C-a . space-after-tab)
1119 (?A . space-after-tab::tab)
1120 (?a . space-after-tab::space)
1121 (?\C-b . space-before-tab)
1122 (?B . space-before-tab::tab)
1123 (?b . space-before-tab::space)
1124 (?T . tab-mark)
1125 (?S . space-mark)
1126 (?N . newline-mark)
1127 (?x . whitespace-style)
1129 "Alist of toggle options.
1131 Each element has the form:
1133 (CHAR . SYMBOL)
1135 Where:
1137 CHAR is a char which the user will have to type.
1139 SYMBOL is a valid symbol associated with CHAR.
1140 See `whitespace-style-value-list'.")
1143 (defvar whitespace-active-style nil
1144 "Used to save locally `whitespace-style' value.")
1146 (defvar whitespace-indent-tabs-mode indent-tabs-mode
1147 "Used to save locally `indent-tabs-mode' value.")
1149 (defvar whitespace-tab-width tab-width
1150 "Used to save locally `tab-width' value.")
1153 ;;;###autoload
1154 (defun whitespace-toggle-options (arg)
1155 "Toggle local `whitespace-mode' options.
1157 If local whitespace-mode is off, toggle the option given by ARG
1158 and turn on local whitespace-mode.
1160 If local whitespace-mode is on, toggle the option given by ARG
1161 and restart local whitespace-mode.
1163 Interactively, it reads one of the following chars:
1165 CHAR MEANING
1166 (VIA FACES)
1167 t toggle TAB visualization
1168 s toggle SPACE and HARD SPACE visualization
1169 r toggle trailing blanks visualization
1170 l toggle \"long lines\" visualization
1171 L toggle \"long lines\" tail visualization
1172 n toggle NEWLINE visualization
1173 e toggle empty line at bob and/or eob visualization
1174 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1175 I toggle indentation SPACEs visualization
1176 i toggle indentation TABs visualization
1177 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1178 A toggle SPACEs after TAB: SPACEs visualization
1179 a toggle SPACEs after TAB: TABs visualization
1180 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1181 B toggle SPACEs before TAB: SPACEs visualization
1182 b toggle SPACEs before TAB: TABs visualization
1184 (VIA DISPLAY TABLE)
1185 T toggle TAB visualization
1186 S toggle SPACEs before TAB visualization
1187 N toggle NEWLINE visualization
1189 x restore `whitespace-style' value
1190 ? display brief help
1192 Non-interactively, ARG should be a symbol or a list of symbols.
1193 The valid symbols are:
1195 tabs toggle TAB visualization
1196 spaces toggle SPACE and HARD SPACE visualization
1197 trailing toggle trailing blanks visualization
1198 lines toggle \"long lines\" visualization
1199 lines-tail toggle \"long lines\" tail visualization
1200 newline toggle NEWLINE visualization
1201 empty toggle empty line at bob and/or eob visualization
1202 indentation toggle indentation SPACEs visualization
1203 indentation::tab toggle indentation SPACEs visualization
1204 indentation::space toggle indentation TABs visualization
1205 space-after-tab toggle SPACEs after TAB visualization
1206 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1207 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1208 space-before-tab toggle SPACEs before TAB visualization
1209 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1210 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1212 tab-mark toggle TAB visualization
1213 space-mark toggle SPACEs before TAB visualization
1214 newline-mark toggle NEWLINE visualization
1216 whitespace-style restore `whitespace-style' value
1218 Only useful with a windowing system.
1220 See `whitespace-style' and `indent-tabs-mode' for documentation."
1221 (interactive (whitespace-interactive-char t))
1222 (let ((whitespace-style
1223 (whitespace-toggle-list t arg whitespace-active-style)))
1224 (whitespace-mode 0)
1225 (whitespace-mode 1)))
1228 (defvar whitespace-toggle-style nil
1229 "Used to toggle the global `whitespace-style' value.")
1232 ;;;###autoload
1233 (defun global-whitespace-toggle-options (arg)
1234 "Toggle global `whitespace-mode' options.
1236 If global whitespace-mode is off, toggle the option given by ARG
1237 and turn on global whitespace-mode.
1239 If global whitespace-mode is on, toggle the option given by ARG
1240 and restart global whitespace-mode.
1242 Interactively, it accepts one of the following chars:
1244 CHAR MEANING
1245 (VIA FACES)
1246 t toggle TAB visualization
1247 s toggle SPACE and HARD SPACE visualization
1248 r toggle trailing blanks visualization
1249 l toggle \"long lines\" visualization
1250 L toggle \"long lines\" tail visualization
1251 n toggle NEWLINE visualization
1252 e toggle empty line at bob and/or eob visualization
1253 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1254 I toggle indentation SPACEs visualization
1255 i toggle indentation TABs visualization
1256 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1257 A toggle SPACEs after TAB: SPACEs visualization
1258 a toggle SPACEs after TAB: TABs visualization
1259 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1260 B toggle SPACEs before TAB: SPACEs visualization
1261 b toggle SPACEs before TAB: TABs visualization
1263 (VIA DISPLAY TABLE)
1264 T toggle TAB visualization
1265 S toggle SPACEs before TAB visualization
1266 N toggle NEWLINE visualization
1268 x restore `whitespace-style' value
1269 ? display brief help
1271 Non-interactively, ARG should be a symbol or a list of symbols.
1272 The valid symbols are:
1274 tabs toggle TAB visualization
1275 spaces toggle SPACE and HARD SPACE visualization
1276 trailing toggle trailing blanks visualization
1277 lines toggle \"long lines\" visualization
1278 lines-tail toggle \"long lines\" tail visualization
1279 newline toggle NEWLINE visualization
1280 empty toggle empty line at bob and/or eob visualization
1281 indentation toggle indentation SPACEs visualization
1282 indentation::tab toggle indentation SPACEs visualization
1283 indentation::space toggle indentation TABs visualization
1284 space-after-tab toggle SPACEs after TAB visualization
1285 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1286 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1287 space-before-tab toggle SPACEs before TAB visualization
1288 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1289 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1291 tab-mark toggle TAB visualization
1292 space-mark toggle SPACEs before TAB visualization
1293 newline-mark toggle NEWLINE visualization
1295 whitespace-style restore `whitespace-style' value
1297 Only useful with a windowing system.
1299 See `whitespace-style' and `indent-tabs-mode' for documentation."
1300 (interactive (whitespace-interactive-char nil))
1301 (let ((whitespace-style
1302 (whitespace-toggle-list nil arg whitespace-toggle-style)))
1303 (setq whitespace-toggle-style whitespace-style)
1304 (global-whitespace-mode 0)
1305 (global-whitespace-mode 1)))
1308 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1309 ;;;; User commands - Cleanup
1312 ;;;###autoload
1313 (defun whitespace-cleanup ()
1314 "Cleanup some blank problems in all buffer or at region.
1316 It usually applies to the whole buffer, but in transient mark
1317 mode when the mark is active, it applies to the region. It also
1318 applies to the region when it is not in transiente mark mode, the
1319 mark is active and \\[universal-argument] was pressed just before
1320 calling `whitespace-cleanup' interactively.
1322 See also `whitespace-cleanup-region'.
1324 The problems cleaned up are:
1326 1. empty lines at beginning of buffer.
1327 2. empty lines at end of buffer.
1328 If `whitespace-style' includes the value `empty', remove all
1329 empty lines at beginning and/or end of buffer.
1331 3. 8 or more SPACEs at beginning of line.
1332 If `whitespace-style' includes the value `indentation':
1333 replace 8 or more SPACEs at beginning of line by TABs, if
1334 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1335 SPACEs.
1336 If `whitespace-style' includes the value `indentation::tab',
1337 replace 8 or more SPACEs at beginning of line by TABs.
1338 If `whitespace-style' includes the value `indentation::space',
1339 replace TABs by SPACEs.
1341 4. SPACEs before TAB.
1342 If `whitespace-style' includes the value `space-before-tab':
1343 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1344 otherwise, replace TABs by SPACEs.
1345 If `whitespace-style' includes the value
1346 `space-before-tab::tab', replace SPACEs by TABs.
1347 If `whitespace-style' includes the value
1348 `space-before-tab::space', replace TABs by SPACEs.
1350 5. SPACEs or TABs at end of line.
1351 If `whitespace-style' includes the value `trailing', remove
1352 all SPACEs or TABs at end of line.
1354 6. 8 or more SPACEs after TAB.
1355 If `whitespace-style' includes the value `space-after-tab':
1356 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1357 otherwise, replace TABs by SPACEs.
1358 If `whitespace-style' includes the value
1359 `space-after-tab::tab', replace SPACEs by TABs.
1360 If `whitespace-style' includes the value
1361 `space-after-tab::space', replace TABs by SPACEs.
1363 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1364 documentation."
1365 (interactive "@*")
1366 (if (and (or transient-mark-mode
1367 current-prefix-arg)
1368 mark-active)
1369 ;; region active
1370 ;; PROBLEMs 1 and 2 are not handled in region
1371 ;; PROBLEM 3: 8 or more SPACEs at bol
1372 ;; PROBLEM 4: SPACEs before TAB
1373 ;; PROBLEM 5: SPACEs or TABs at eol
1374 ;; PROBLEM 6: 8 or more SPACEs after TAB
1375 (whitespace-cleanup-region (region-beginning) (region-end))
1376 ;; whole buffer
1377 (save-excursion
1378 (save-match-data
1379 ;; PROBLEM 1: empty lines at bob
1380 ;; PROBLEM 2: empty lines at eob
1381 ;; ACTION: remove all empty lines at bob and/or eob
1382 (when (memq 'empty whitespace-style)
1383 (let (overwrite-mode) ; enforce no overwrite
1384 (goto-char (point-min))
1385 (when (re-search-forward
1386 whitespace-empty-at-bob-regexp nil t)
1387 (delete-region (match-beginning 1) (match-end 1)))
1388 (when (re-search-forward
1389 whitespace-empty-at-eob-regexp nil t)
1390 (delete-region (match-beginning 1) (match-end 1)))))))
1391 ;; PROBLEM 3: 8 or more SPACEs at bol
1392 ;; PROBLEM 4: SPACEs before TAB
1393 ;; PROBLEM 5: SPACEs or TABs at eol
1394 ;; PROBLEM 6: 8 or more SPACEs after TAB
1395 (whitespace-cleanup-region (point-min) (point-max))))
1398 ;;;###autoload
1399 (defun whitespace-cleanup-region (start end)
1400 "Cleanup some blank problems at region.
1402 The problems cleaned up are:
1404 1. 8 or more SPACEs at beginning of line.
1405 If `whitespace-style' includes the value `indentation':
1406 replace 8 or more SPACEs at beginning of line by TABs, if
1407 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1408 SPACEs.
1409 If `whitespace-style' includes the value `indentation::tab',
1410 replace 8 or more SPACEs at beginning of line by TABs.
1411 If `whitespace-style' includes the value `indentation::space',
1412 replace TABs by SPACEs.
1414 2. SPACEs before TAB.
1415 If `whitespace-style' includes the value `space-before-tab':
1416 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1417 otherwise, replace TABs by SPACEs.
1418 If `whitespace-style' includes the value
1419 `space-before-tab::tab', replace SPACEs by TABs.
1420 If `whitespace-style' includes the value
1421 `space-before-tab::space', replace TABs by SPACEs.
1423 3. SPACEs or TABs at end of line.
1424 If `whitespace-style' includes the value `trailing', remove
1425 all SPACEs or TABs at end of line.
1427 4. 8 or more SPACEs after TAB.
1428 If `whitespace-style' includes the value `space-after-tab':
1429 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1430 otherwise, replace TABs by SPACEs.
1431 If `whitespace-style' includes the value
1432 `space-after-tab::tab', replace SPACEs by TABs.
1433 If `whitespace-style' includes the value
1434 `space-after-tab::space', replace TABs by SPACEs.
1436 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1437 documentation."
1438 (interactive "@*r")
1439 (let ((rstart (min start end))
1440 (rend (copy-marker (max start end)))
1441 (indent-tabs-mode whitespace-indent-tabs-mode)
1442 (tab-width whitespace-tab-width)
1443 overwrite-mode ; enforce no overwrite
1444 tmp)
1445 (save-excursion
1446 (save-match-data
1447 ;; PROBLEM 1: 8 or more SPACEs at bol
1448 (cond
1449 ;; ACTION: replace 8 or more SPACEs at bol by TABs, if
1450 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1451 ;; SPACEs.
1452 ((memq 'indentation whitespace-style)
1453 (let ((regexp (whitespace-indentation-regexp)))
1454 (goto-char rstart)
1455 (while (re-search-forward regexp rend t)
1456 (setq tmp (current-indentation))
1457 (goto-char (match-beginning 0))
1458 (delete-horizontal-space)
1459 (unless (eolp)
1460 (indent-to tmp)))))
1461 ;; ACTION: replace 8 or more SPACEs at bol by TABs.
1462 ((memq 'indentation::tab whitespace-style)
1463 (whitespace-replace-action
1464 'tabify rstart rend
1465 (whitespace-indentation-regexp 'tab) 0))
1466 ;; ACTION: replace TABs by SPACEs.
1467 ((memq 'indentation::space whitespace-style)
1468 (whitespace-replace-action
1469 'untabify rstart rend
1470 (whitespace-indentation-regexp 'space) 0)))
1471 ;; PROBLEM 3: SPACEs or TABs at eol
1472 ;; ACTION: remove all SPACEs or TABs at eol
1473 (when (memq 'trailing whitespace-style)
1474 (whitespace-replace-action
1475 'delete-region rstart rend
1476 whitespace-trailing-regexp 1))
1477 ;; PROBLEM 4: 8 or more SPACEs after TAB
1478 (cond
1479 ;; ACTION: replace 8 or more SPACEs by TABs, if
1480 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1481 ;; SPACEs.
1482 ((memq 'space-after-tab whitespace-style)
1483 (whitespace-replace-action
1484 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1485 rstart rend (whitespace-space-after-tab-regexp) 1))
1486 ;; ACTION: replace 8 or more SPACEs by TABs.
1487 ((memq 'space-after-tab::tab whitespace-style)
1488 (whitespace-replace-action
1489 'tabify rstart rend
1490 (whitespace-space-after-tab-regexp 'tab) 1))
1491 ;; ACTION: replace TABs by SPACEs.
1492 ((memq 'space-after-tab::space whitespace-style)
1493 (whitespace-replace-action
1494 'untabify rstart rend
1495 (whitespace-space-after-tab-regexp 'space) 1)))
1496 ;; PROBLEM 2: SPACEs before TAB
1497 (cond
1498 ;; ACTION: replace SPACEs before TAB by TABs, if
1499 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1500 ;; SPACEs.
1501 ((memq 'space-before-tab whitespace-style)
1502 (whitespace-replace-action
1503 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1504 rstart rend whitespace-space-before-tab-regexp
1505 (if whitespace-indent-tabs-mode 1 2)))
1506 ;; ACTION: replace SPACEs before TAB by TABs.
1507 ((memq 'space-before-tab::tab whitespace-style)
1508 (whitespace-replace-action
1509 'tabify rstart rend
1510 whitespace-space-before-tab-regexp 1))
1511 ;; ACTION: replace TABs by SPACEs.
1512 ((memq 'space-before-tab::space whitespace-style)
1513 (whitespace-replace-action
1514 'untabify rstart rend
1515 whitespace-space-before-tab-regexp 2)))))
1516 (set-marker rend nil))) ; point marker to nowhere
1519 (defun whitespace-replace-action (action rstart rend regexp index)
1520 "Do ACTION in the string matched by REGEXP between RSTART and REND.
1522 INDEX is the level group matched by REGEXP and used by ACTION.
1524 See also `tab-width'."
1525 (goto-char rstart)
1526 (while (re-search-forward regexp rend t)
1527 (goto-char (match-end index))
1528 (funcall action (match-beginning index) (match-end index))))
1531 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1532 ;;;; User command - report
1535 (defun whitespace-regexp (regexp &optional kind)
1536 "Return REGEXP depending on `whitespace-indent-tabs-mode'."
1537 (cond
1538 ((or (eq kind 'tab)
1539 whitespace-indent-tabs-mode)
1540 (format (car regexp) whitespace-tab-width))
1541 ((or (eq kind 'space)
1542 (not whitespace-indent-tabs-mode))
1543 (cdr regexp))))
1546 (defun whitespace-indentation-regexp (&optional kind)
1547 "Return the indentation regexp depending on `whitespace-indent-tabs-mode'."
1548 (whitespace-regexp whitespace-indentation-regexp kind))
1551 (defun whitespace-space-after-tab-regexp (&optional kind)
1552 "Return the space-after-tab regexp depending on `whitespace-indent-tabs-mode'."
1553 (whitespace-regexp whitespace-space-after-tab-regexp kind))
1556 (defconst whitespace-report-list
1557 (list
1558 (cons 'empty whitespace-empty-at-bob-regexp)
1559 (cons 'empty whitespace-empty-at-eob-regexp)
1560 (cons 'trailing whitespace-trailing-regexp)
1561 (cons 'indentation nil)
1562 (cons 'indentation::tab nil)
1563 (cons 'indentation::space nil)
1564 (cons 'space-before-tab whitespace-space-before-tab-regexp)
1565 (cons 'space-before-tab::tab whitespace-space-before-tab-regexp)
1566 (cons 'space-before-tab::space whitespace-space-before-tab-regexp)
1567 (cons 'space-after-tab nil)
1568 (cons 'space-after-tab::tab nil)
1569 (cons 'space-after-tab::space nil)
1571 "List of whitespace bogus symbol and corresponding regexp.")
1574 (defconst whitespace-report-text
1575 '( ;; `indent-tabs-mode' has non-nil value
1577 Whitespace Report
1579 Current Setting Whitespace Problem
1581 empty [] [] empty lines at beginning of buffer
1582 empty [] [] empty lines at end of buffer
1583 trailing [] [] SPACEs or TABs at end of line
1584 indentation [] [] 8 or more SPACEs at beginning of line
1585 indentation::tab [] [] 8 or more SPACEs at beginning of line
1586 indentation::space [] [] TABs at beginning of line
1587 space-before-tab [] [] SPACEs before TAB
1588 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1589 space-before-tab::space [] [] SPACEs before TAB: TABs
1590 space-after-tab [] [] 8 or more SPACEs after TAB
1591 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1592 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1594 indent-tabs-mode =
1595 tab-width = \n\n"
1596 . ;; `indent-tabs-mode' has nil value
1598 Whitespace Report
1600 Current Setting Whitespace Problem
1602 empty [] [] empty lines at beginning of buffer
1603 empty [] [] empty lines at end of buffer
1604 trailing [] [] SPACEs or TABs at end of line
1605 indentation [] [] TABs at beginning of line
1606 indentation::tab [] [] 8 or more SPACEs at beginning of line
1607 indentation::space [] [] TABs at beginning of line
1608 space-before-tab [] [] SPACEs before TAB
1609 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1610 space-before-tab::space [] [] SPACEs before TAB: TABs
1611 space-after-tab [] [] 8 or more SPACEs after TAB
1612 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1613 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1615 indent-tabs-mode =
1616 tab-width = \n\n")
1617 "Text for whitespace bogus report.
1619 It is a cons of strings, where the car part is used when
1620 `indent-tabs-mode' is non-nil, and the cdr part is used when
1621 `indent-tabs-mode' is nil.")
1624 (defconst whitespace-report-buffer-name "*Whitespace Report*"
1625 "The buffer name for whitespace bogus report.")
1628 ;;;###autoload
1629 (defun whitespace-report (&optional force report-if-bogus)
1630 "Report some whitespace problems in buffer.
1632 Return nil if there is no whitespace problem; otherwise, return
1633 non-nil.
1635 If FORCE is non-nil or \\[universal-argument] was pressed just
1636 before calling `whitespace-report' interactively, it forces
1637 `whitespace-style' to have:
1639 empty
1640 trailing
1641 indentation
1642 space-before-tab
1643 space-after-tab
1645 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1646 whitespace problems in buffer.
1648 Report if some of the following whitespace problems exist:
1650 * If `indent-tabs-mode' is non-nil:
1651 empty 1. empty lines at beginning of buffer.
1652 empty 2. empty lines at end of buffer.
1653 trailing 3. SPACEs or TABs at end of line.
1654 indentation 4. 8 or more SPACEs at beginning of line.
1655 space-before-tab 5. SPACEs before TAB.
1656 space-after-tab 6. 8 or more SPACEs after TAB.
1658 * If `indent-tabs-mode' is nil:
1659 empty 1. empty lines at beginning of buffer.
1660 empty 2. empty lines at end of buffer.
1661 trailing 3. SPACEs or TABs at end of line.
1662 indentation 4. TABS at beginning of line.
1663 space-before-tab 5. SPACEs before TAB.
1664 space-after-tab 6. 8 or more SPACEs after TAB.
1666 See `whitespace-style' for documentation.
1667 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1668 cleaning up these problems."
1669 (interactive (list current-prefix-arg))
1670 (whitespace-report-region (point-min) (point-max)
1671 force report-if-bogus))
1674 ;;;###autoload
1675 (defun whitespace-report-region (start end &optional force report-if-bogus)
1676 "Report some whitespace problems in a region.
1678 Return nil if there is no whitespace problem; otherwise, return
1679 non-nil.
1681 If FORCE is non-nil or \\[universal-argument] was pressed just
1682 before calling `whitespace-report-region' interactively, it
1683 forces `whitespace-style' to have:
1685 empty
1686 indentation
1687 space-before-tab
1688 trailing
1689 space-after-tab
1691 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1692 whitespace problems in buffer.
1694 Report if some of the following whitespace problems exist:
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.
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.
1712 See `whitespace-style' for documentation.
1713 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1714 cleaning up these problems."
1715 (interactive "r")
1716 (setq force (or current-prefix-arg force))
1717 (save-excursion
1718 (save-match-data
1719 (let* ((has-bogus nil)
1720 (rstart (min start end))
1721 (rend (max start end))
1722 (bogus-list
1723 (mapcar
1724 #'(lambda (option)
1725 (when force
1726 (add-to-list 'whitespace-style (car option)))
1727 (goto-char rstart)
1728 (let ((regexp
1729 (cond
1730 ((eq (car option) 'indentation)
1731 (whitespace-indentation-regexp))
1732 ((eq (car option) 'indentation::tab)
1733 (whitespace-indentation-regexp 'tab))
1734 ((eq (car option) 'indentation::space)
1735 (whitespace-indentation-regexp 'space))
1736 ((eq (car option) 'space-after-tab)
1737 (whitespace-space-after-tab-regexp))
1738 ((eq (car option) 'space-after-tab::tab)
1739 (whitespace-space-after-tab-regexp 'tab))
1740 ((eq (car option) 'space-after-tab::space)
1741 (whitespace-space-after-tab-regexp 'space))
1743 (cdr option)))))
1744 (and (re-search-forward regexp rend t)
1745 (setq has-bogus t))))
1746 whitespace-report-list)))
1747 (when (if report-if-bogus has-bogus t)
1748 (whitespace-kill-buffer whitespace-report-buffer-name)
1749 ;; `whitespace-indent-tabs-mode' is local to current buffer
1750 ;; `whitespace-tab-width' is local to current buffer
1751 (let ((ws-indent-tabs-mode whitespace-indent-tabs-mode)
1752 (ws-tab-width whitespace-tab-width))
1753 (with-current-buffer (get-buffer-create
1754 whitespace-report-buffer-name)
1755 (erase-buffer)
1756 (insert (if ws-indent-tabs-mode
1757 (car whitespace-report-text)
1758 (cdr whitespace-report-text)))
1759 (goto-char (point-min))
1760 (forward-line 3)
1761 (dolist (option whitespace-report-list)
1762 (forward-line 1)
1763 (whitespace-mark-x
1764 27 (memq (car option) whitespace-style))
1765 (whitespace-mark-x 7 (car bogus-list))
1766 (setq bogus-list (cdr bogus-list)))
1767 (forward-line 1)
1768 (whitespace-insert-value ws-indent-tabs-mode)
1769 (whitespace-insert-value ws-tab-width)
1770 (when has-bogus
1771 (goto-char (point-max))
1772 (insert " Type `M-x whitespace-cleanup'"
1773 " to cleanup the buffer.\n\n"
1774 " Type `M-x whitespace-cleanup-region'"
1775 " to cleanup a region.\n\n"))
1776 (whitespace-display-window (current-buffer)))))
1777 has-bogus))))
1780 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1781 ;;;; Internal functions
1784 (defvar whitespace-font-lock-mode nil
1785 "Used to remember whether a buffer had font lock mode on or not.")
1787 (defvar whitespace-font-lock nil
1788 "Used to remember whether a buffer initially had font lock on or not.")
1790 (defvar whitespace-font-lock-keywords nil
1791 "Used to save locally `font-lock-keywords' value.")
1794 (defconst whitespace-help-text
1796 Whitespace Toggle Options
1798 FACES
1799 [] t - toggle TAB visualization
1800 [] s - toggle SPACE and HARD SPACE visualization
1801 [] r - toggle trailing blanks visualization
1802 [] l - toggle \"long lines\" visualization
1803 [] L - toggle \"long lines\" tail visualization
1804 [] n - toggle NEWLINE visualization
1805 [] e - toggle empty line at bob and/or eob visualization
1806 [] C-i - toggle indentation SPACEs visualization (via `indent-tabs-mode')
1807 [] I - toggle indentation SPACEs visualization
1808 [] i - toggle indentation TABs visualization
1809 [] C-a - toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1810 [] A - toggle SPACEs after TAB: SPACEs visualization
1811 [] a - toggle SPACEs after TAB: TABs visualization
1812 [] C-b - toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1813 [] B - toggle SPACEs before TAB: SPACEs visualization
1814 [] b - toggle SPACEs before TAB: TABs visualization
1816 DISPLAY TABLE
1817 [] T - toggle TAB visualization
1818 [] S - toggle SPACE and HARD SPACE visualization
1819 [] N - toggle NEWLINE visualization
1821 x - restore `whitespace-style' value
1823 ? - display this text\n\n"
1824 "Text for whitespace toggle options.")
1827 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1828 "The buffer name for whitespace toggle options.")
1831 (defun whitespace-insert-value (value)
1832 "Insert VALUE at column 20 of next line."
1833 (forward-line 1)
1834 (move-to-column 20 t)
1835 (insert (format "%s" value)))
1838 (defun whitespace-mark-x (nchars condition)
1839 "Insert the mark ('X' or ' ') after NCHARS depending on CONDITION."
1840 (forward-char nchars)
1841 (insert (if condition "X" " ")))
1844 (defun whitespace-insert-option-mark (the-list the-value)
1845 "Insert the option mark ('X' or ' ') in toggle options buffer."
1846 (goto-char (point-min))
1847 (forward-line 2)
1848 (dolist (sym the-list)
1849 (if (eq sym 'help-newline)
1850 (forward-line 2)
1851 (forward-line 1)
1852 (whitespace-mark-x 2 (memq sym the-value)))))
1855 (defun whitespace-help-on (style)
1856 "Display the whitespace toggle options."
1857 (unless (get-buffer whitespace-help-buffer-name)
1858 (delete-other-windows)
1859 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
1860 (save-excursion
1861 (set-buffer buffer)
1862 (erase-buffer)
1863 (insert whitespace-help-text)
1864 (whitespace-insert-option-mark
1865 whitespace-style-value-list style)
1866 (whitespace-display-window buffer)))))
1869 (defun whitespace-display-window (buffer)
1870 "Display BUFFER in a new window."
1871 (goto-char (point-min))
1872 (set-buffer-modified-p nil)
1873 (let ((size (- (window-height)
1874 (max window-min-height
1875 (1+ (count-lines (point-min)
1876 (point-max)))))))
1877 (when (<= size 0)
1878 (kill-buffer buffer)
1879 (error "Frame height is too small; \
1880 can't split window to display whitespace toggle options"))
1881 (set-window-buffer (split-window nil size) buffer)))
1884 (defun whitespace-kill-buffer (buffer-name)
1885 "Kill buffer BUFFER-NAME and windows related with it."
1886 (let ((buffer (get-buffer buffer-name)))
1887 (when buffer
1888 (delete-windows-on buffer)
1889 (kill-buffer buffer))))
1892 (defun whitespace-help-off ()
1893 "Remove the buffer and window of the whitespace toggle options."
1894 (whitespace-kill-buffer whitespace-help-buffer-name))
1897 (defun whitespace-interactive-char (local-p)
1898 "Interactive function to read a char and return a symbol.
1900 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1901 uses a global context.
1903 It accepts one of the following chars:
1905 CHAR MEANING
1906 (VIA FACES)
1907 t toggle TAB visualization
1908 s toggle SPACE and HARD SPACE visualization
1909 r toggle trailing blanks visualization
1910 l toggle \"long lines\" visualization
1911 L toggle \"long lines\" tail visualization
1912 n toggle NEWLINE visualization
1913 e toggle empty line at bob and/or eob visualization
1914 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1915 I toggle indentation SPACEs visualization
1916 i toggle indentation TABs visualization
1917 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1918 A toggle SPACEs after TAB: SPACEs visualization
1919 a toggle SPACEs after TAB: TABs visualization
1920 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1921 B toggle SPACEs before TAB: SPACEs visualization
1922 b toggle SPACEs before TAB: TABs visualization
1924 (VIA DISPLAY TABLE)
1925 T toggle TAB visualization
1926 S toggle SPACE and HARD SPACE visualization
1927 N toggle NEWLINE visualization
1929 x restore `whitespace-style' value
1930 ? display brief help
1932 See also `whitespace-toggle-option-alist'."
1933 (let* ((is-off (not (if local-p
1934 whitespace-mode
1935 global-whitespace-mode)))
1936 (style (cond (is-off whitespace-style) ; use default value
1937 (local-p whitespace-active-style)
1938 (t whitespace-toggle-style)))
1939 (prompt
1940 (format "Whitespace Toggle %s (type ? for further options)-"
1941 (if local-p "Local" "Global")))
1942 ch sym)
1943 ;; read a valid option and get the corresponding symbol
1944 (save-window-excursion
1945 (condition-case data
1946 (progn
1947 (while
1948 ;; while condition
1949 (progn
1950 (setq ch (read-char prompt))
1951 (not
1952 (setq sym
1953 (cdr
1954 (assq ch whitespace-toggle-option-alist)))))
1955 ;; while body
1956 (if (eq ch ?\?)
1957 (whitespace-help-on style)
1958 (ding)))
1959 (whitespace-help-off)
1960 (message " ")) ; clean echo area
1961 ;; handler
1962 ((quit error)
1963 (whitespace-help-off)
1964 (error (error-message-string data)))))
1965 (list sym))) ; return the apropriate symbol
1968 (defun whitespace-toggle-list (local-p arg the-list)
1969 "Toggle options in THE-LIST based on list ARG.
1971 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1972 uses a global context.
1974 ARG is a list of options to be toggled.
1976 THE-LIST is a list of options. This list will be toggled and the
1977 resultant list will be returned."
1978 (unless (if local-p whitespace-mode global-whitespace-mode)
1979 (setq the-list whitespace-style))
1980 (setq the-list (copy-sequence the-list)) ; keep original list
1981 (dolist (sym (if (listp arg) arg (list arg)))
1982 (cond
1983 ;; ignore help value
1984 ((eq sym 'help-newline))
1985 ;; restore default values
1986 ((eq sym 'whitespace-style)
1987 (setq the-list whitespace-style))
1988 ;; toggle valid values
1989 ((memq sym whitespace-style-value-list)
1990 (setq the-list (if (memq sym the-list)
1991 (delq sym the-list)
1992 (cons sym the-list))))))
1993 the-list)
1996 (defvar whitespace-display-table nil
1997 "Used to save a local display table.")
1999 (defvar whitespace-display-table-was-local nil
2000 "Used to remember whether a buffer initially had a local display table.")
2003 (defun whitespace-turn-on ()
2004 "Turn on whitespace visualization."
2005 ;; prepare local hooks
2006 (whitespace-add-local-hook)
2007 ;; create whitespace local buffer environment
2008 (set (make-local-variable 'whitespace-font-lock-mode) nil)
2009 (set (make-local-variable 'whitespace-font-lock) nil)
2010 (set (make-local-variable 'whitespace-font-lock-keywords) nil)
2011 (set (make-local-variable 'whitespace-display-table) nil)
2012 (set (make-local-variable 'whitespace-display-table-was-local) nil)
2013 (set (make-local-variable 'whitespace-active-style)
2014 (if (listp whitespace-style)
2015 whitespace-style
2016 (list whitespace-style)))
2017 (set (make-local-variable 'whitespace-indent-tabs-mode)
2018 indent-tabs-mode)
2019 (set (make-local-variable 'whitespace-tab-width)
2020 tab-width)
2021 ;; turn on whitespace
2022 (when whitespace-active-style
2023 (whitespace-color-on)
2024 (whitespace-display-char-on)))
2027 (defun whitespace-turn-off ()
2028 "Turn off whitespace visualization."
2029 (whitespace-remove-local-hook)
2030 (when whitespace-active-style
2031 (whitespace-color-off)
2032 (whitespace-display-char-off)))
2035 (defun whitespace-style-face-p ()
2036 "Return t if there is some visualization via face."
2037 (or (memq 'tabs whitespace-active-style)
2038 (memq 'spaces whitespace-active-style)
2039 (memq 'trailing whitespace-active-style)
2040 (memq 'lines whitespace-active-style)
2041 (memq 'lines-tail whitespace-active-style)
2042 (memq 'newline whitespace-active-style)
2043 (memq 'empty whitespace-active-style)
2044 (memq 'indentation whitespace-active-style)
2045 (memq 'indentation::tab whitespace-active-style)
2046 (memq 'indentation::space whitespace-active-style)
2047 (memq 'space-after-tab whitespace-active-style)
2048 (memq 'space-after-tab::tab whitespace-active-style)
2049 (memq 'space-after-tab::space whitespace-active-style)
2050 (memq 'space-before-tab whitespace-active-style)
2051 (memq 'space-before-tab::tab whitespace-active-style)
2052 (memq 'space-before-tab::space whitespace-active-style)))
2055 (defun whitespace-color-on ()
2056 "Turn on color visualization."
2057 (when (whitespace-style-face-p)
2058 (unless whitespace-font-lock
2059 (setq whitespace-font-lock t
2060 whitespace-font-lock-keywords
2061 (copy-sequence font-lock-keywords)))
2062 ;; turn off font lock
2063 (set (make-local-variable 'whitespace-font-lock-mode)
2064 font-lock-mode)
2065 (font-lock-mode 0)
2066 ;; add whitespace-mode color into font lock
2067 (when (memq 'spaces whitespace-active-style)
2068 (font-lock-add-keywords
2070 (list
2071 ;; Show SPACEs
2072 (list whitespace-space-regexp 1 whitespace-space t)
2073 ;; Show HARD SPACEs
2074 (list whitespace-hspace-regexp 1 whitespace-hspace t))
2076 (when (memq 'tabs whitespace-active-style)
2077 (font-lock-add-keywords
2079 (list
2080 ;; Show TABs
2081 (list whitespace-tab-regexp 1 whitespace-tab t))
2083 (when (memq 'trailing whitespace-active-style)
2084 (font-lock-add-keywords
2086 (list
2087 ;; Show trailing blanks
2088 (list whitespace-trailing-regexp 1 whitespace-trailing t))
2090 (when (or (memq 'lines whitespace-active-style)
2091 (memq 'lines-tail whitespace-active-style))
2092 (font-lock-add-keywords
2094 (list
2095 ;; Show "long" lines
2096 (list
2097 (format
2098 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
2099 whitespace-tab-width (1- whitespace-tab-width)
2100 (/ whitespace-line-column tab-width)
2101 (let ((rem (% whitespace-line-column whitespace-tab-width)))
2102 (if (zerop rem)
2104 (format ".\\{%d\\}" rem))))
2105 (if (memq 'lines whitespace-active-style)
2106 0 ; whole line
2107 2) ; line tail
2108 whitespace-line t))
2110 (cond
2111 ((memq 'space-before-tab whitespace-active-style)
2112 (font-lock-add-keywords
2114 (list
2115 ;; Show SPACEs before TAB (indent-tabs-mode)
2116 (list whitespace-space-before-tab-regexp
2117 (if whitespace-indent-tabs-mode 1 2)
2118 whitespace-space-before-tab t))
2120 ((memq 'space-before-tab::tab whitespace-active-style)
2121 (font-lock-add-keywords
2123 (list
2124 ;; Show SPACEs before TAB (SPACEs)
2125 (list whitespace-space-before-tab-regexp
2126 1 whitespace-space-before-tab t))
2128 ((memq 'space-before-tab::space whitespace-active-style)
2129 (font-lock-add-keywords
2131 (list
2132 ;; Show SPACEs before TAB (TABs)
2133 (list whitespace-space-before-tab-regexp
2134 2 whitespace-space-before-tab t))
2135 t)))
2136 (cond
2137 ((memq 'indentation whitespace-active-style)
2138 (font-lock-add-keywords
2140 (list
2141 ;; Show indentation SPACEs (indent-tabs-mode)
2142 (list (whitespace-indentation-regexp)
2143 1 whitespace-indentation t))
2145 ((memq 'indentation::tab whitespace-active-style)
2146 (font-lock-add-keywords
2148 (list
2149 ;; Show indentation SPACEs (SPACEs)
2150 (list (whitespace-indentation-regexp 'tab)
2151 1 whitespace-indentation t))
2153 ((memq 'indentation::space whitespace-active-style)
2154 (font-lock-add-keywords
2156 (list
2157 ;; Show indentation SPACEs (TABs)
2158 (list (whitespace-indentation-regexp 'space)
2159 1 whitespace-indentation t))
2160 t)))
2161 (when (memq 'empty whitespace-active-style)
2162 (font-lock-add-keywords
2164 (list
2165 ;; Show empty lines at beginning of buffer
2166 (list whitespace-empty-at-bob-regexp
2167 1 whitespace-empty t))
2169 (font-lock-add-keywords
2171 (list
2172 ;; Show empty lines at end of buffer
2173 (list whitespace-empty-at-eob-regexp
2174 1 whitespace-empty t))
2176 (cond
2177 ((memq 'space-after-tab whitespace-active-style)
2178 (font-lock-add-keywords
2180 (list
2181 ;; Show SPACEs after TAB (indent-tabs-mode)
2182 (list (whitespace-space-after-tab-regexp)
2183 1 whitespace-space-after-tab t))
2185 ((memq 'space-after-tab::tab whitespace-active-style)
2186 (font-lock-add-keywords
2188 (list
2189 ;; Show SPACEs after TAB (SPACEs)
2190 (list (whitespace-space-after-tab-regexp 'tab)
2191 1 whitespace-space-after-tab t))
2193 ((memq 'space-after-tab::space whitespace-active-style)
2194 (font-lock-add-keywords
2196 (list
2197 ;; Show SPACEs after TAB (TABs)
2198 (list (whitespace-space-after-tab-regexp 'space)
2199 1 whitespace-space-after-tab t))
2200 t)))
2201 ;; now turn on font lock and highlight blanks
2202 (font-lock-mode 1)))
2205 (defun whitespace-color-off ()
2206 "Turn off color visualization."
2207 ;; turn off font lock
2208 (when (whitespace-style-face-p)
2209 (font-lock-mode 0)
2210 (when whitespace-font-lock
2211 (setq whitespace-font-lock nil
2212 font-lock-keywords whitespace-font-lock-keywords))
2213 ;; restore original font lock state
2214 (font-lock-mode whitespace-font-lock-mode)))
2217 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2218 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
2221 (defun whitespace-style-mark-p ()
2222 "Return t if there is some visualization via display table."
2223 (or (memq 'tab-mark whitespace-active-style)
2224 (memq 'space-mark whitespace-active-style)
2225 (memq 'newline-mark whitespace-active-style)))
2228 (defsubst whitespace-char-valid-p (char)
2229 ;; This check should be improved!!!
2230 (or (< char 256)
2231 (characterp char)))
2234 (defun whitespace-display-vector-p (vec)
2235 "Return true if every character in vector VEC can be displayed."
2236 (let ((i (length vec)))
2237 (when (> i 0)
2238 (while (and (>= (setq i (1- i)) 0)
2239 (whitespace-char-valid-p (aref vec i))))
2240 (< i 0))))
2243 (defun whitespace-display-char-on ()
2244 "Turn on character display mapping."
2245 (when (and whitespace-display-mappings
2246 (whitespace-style-mark-p))
2247 (let (vecs vec)
2248 ;; Remember whether a buffer has a local display table.
2249 (unless whitespace-display-table-was-local
2250 (setq whitespace-display-table-was-local t
2251 whitespace-display-table
2252 (copy-sequence buffer-display-table)))
2253 (unless buffer-display-table
2254 (setq buffer-display-table (make-display-table)))
2255 (dolist (entry whitespace-display-mappings)
2256 ;; check if it is to display this mark
2257 (when (memq (car entry) whitespace-style)
2258 ;; Get a displayable mapping.
2259 (setq vecs (cddr entry))
2260 (while (and vecs
2261 (not (whitespace-display-vector-p (car vecs))))
2262 (setq vecs (cdr vecs)))
2263 ;; Display a valid mapping.
2264 (when vecs
2265 (setq vec (copy-sequence (car vecs)))
2266 ;; NEWLINE char
2267 (when (and (eq (cadr entry) ?\n)
2268 (memq 'newline whitespace-active-style))
2269 ;; Only insert face bits on NEWLINE char mapping to avoid
2270 ;; obstruction of other faces like TABs and (HARD) SPACEs
2271 ;; faces, font-lock faces, etc.
2272 (dotimes (i (length vec))
2273 (or (eq (aref vec i) ?\n)
2274 (aset vec i
2275 (make-glyph-code (aref vec i)
2276 whitespace-newline)))))
2277 ;; Display mapping
2278 (aset buffer-display-table (cadr entry) vec)))))))
2281 (defun whitespace-display-char-off ()
2282 "Turn off character display mapping."
2283 (and whitespace-display-mappings
2284 (whitespace-style-mark-p)
2285 whitespace-display-table-was-local
2286 (setq whitespace-display-table-was-local nil
2287 buffer-display-table whitespace-display-table)))
2290 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2291 ;;;; Hook
2294 (defun whitespace-action-when-on ()
2295 "Action to be taken always when local whitespace is turned on."
2296 (cond ((memq 'cleanup whitespace-action)
2297 (whitespace-cleanup))
2298 ((memq 'report-on-bogus whitespace-action)
2299 (whitespace-report nil t))))
2302 (defun whitespace-add-local-hook ()
2303 "Add some whitespace hooks locally."
2304 (add-hook 'write-file-functions 'whitespace-write-file-hook nil t)
2305 (add-hook 'kill-buffer-hook 'whitespace-kill-buffer-hook nil t))
2308 (defun whitespace-remove-local-hook ()
2309 "Remove some whitespace hooks locally."
2310 (remove-hook 'write-file-functions 'whitespace-write-file-hook t)
2311 (remove-hook 'kill-buffer-hook 'whitespace-kill-buffer-hook t))
2314 (defun whitespace-write-file-hook ()
2315 "Action to be taken when buffer is written.
2316 It should be added buffer-locally to `write-file-functions'."
2317 (when (whitespace-action)
2318 (error "Abort write due to whitespace problems in %s"
2319 (buffer-name)))
2320 nil) ; continue hook processing
2323 (defun whitespace-kill-buffer-hook ()
2324 "Action to be taken when buffer is killed.
2325 It should be added buffer-locally to `kill-buffer-hook'."
2326 (whitespace-action)
2327 nil) ; continue hook processing
2330 (defun whitespace-action ()
2331 "Action to be taken when buffer is killed or written.
2332 Return t when the action should be aborted."
2333 (cond ((memq 'auto-cleanup whitespace-action)
2334 (whitespace-cleanup)
2335 nil)
2336 ((memq 'abort-on-bogus whitespace-action)
2337 (whitespace-report nil t))
2339 nil)))
2342 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2345 (defun whitespace-unload-function ()
2346 "Unload the whitespace library."
2347 (global-whitespace-mode -1)
2348 ;; be sure all local whitespace mode is turned off
2349 (save-current-buffer
2350 (dolist (buf (buffer-list))
2351 (set-buffer buf)
2352 (whitespace-mode -1)))
2353 nil) ; continue standard unloading
2356 (provide 'whitespace)
2359 (run-hooks 'whitespace-load-hook)
2362 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
2363 ;;; whitespace.el ends here