* makefile.w32-in (WINS_UPDATES): Fix typo in previous change.
[emacs.git] / lisp / whitespace.el
bloba66bd9360f3527c71edb30abed1cc42e310aea48
1 ;;; whitespace.el --- minor mode to visualize TAB, (HARD) SPACE, NEWLINE
3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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: 12.0
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 ;; The trailing spaces are not highlighted while point is at end of line.
64 ;; Also the spaces at beginning of buffer are not highlighted while point is at
65 ;; beginning of buffer; and the spaces at end of buffer are not highlighted
66 ;; while point is at end of buffer.
68 ;; There are two ways of using whitespace: local and global.
70 ;; * Local whitespace affects only the current buffer.
72 ;; * Global whitespace affects all current and future buffers. That
73 ;; is, if you turn on global whitespace and then create a new
74 ;; buffer, the new buffer will also have whitespace on. The
75 ;; `whitespace-global-modes' variable controls which major-mode will
76 ;; be automagically turned on.
78 ;; You can mix the local and global usage without any conflict. But
79 ;; local whitespace has priority over global whitespace. Whitespace
80 ;; mode is active in a buffer if you have enabled it in that buffer or
81 ;; if you have enabled it globally.
83 ;; When global and local whitespace are on:
85 ;; * if local whitespace is turned off, whitespace is turned off for
86 ;; the current buffer only.
88 ;; * if global whitespace is turned off, whitespace continues on only
89 ;; in the buffers in which local whitespace is on.
91 ;; To use whitespace, insert in your ~/.emacs:
93 ;; (require 'whitespace-mode)
95 ;; Or autoload at least one of the commands`whitespace-mode',
96 ;; `whitespace-toggle-options', `global-whitespace-mode' or
97 ;; `global-whitespace-toggle-options'. For example:
99 ;; (autoload 'whitespace-mode "whitespace"
100 ;; "Toggle whitespace visualization." t)
101 ;; (autoload 'whitespace-toggle-options "whitespace"
102 ;; "Toggle local `whitespace-mode' options." t)
104 ;; whitespace was inspired by:
106 ;; whitespace.el Rajesh Vaidheeswarran <rv@gnu.org>
107 ;; Warn about and clean bogus whitespaces in the file
108 ;; (inspired the idea to warn and clean some blanks)
109 ;; This was the original `whitespace.el' which was replaced by
110 ;; `blank-mode.el'. And later `blank-mode.el' was renamed to
111 ;; `whitespace.el'.
113 ;; show-whitespace-mode.el Aurelien Tisne <aurelien.tisne@free.fr>
114 ;; Simple mode to highlight whitespaces
115 ;; (inspired the idea to use font-lock)
117 ;; whitespace-mode.el Lawrence Mitchell <wence@gmx.li>
118 ;; Major mode for editing Whitespace
119 ;; (inspired the idea to use display table)
121 ;; visws.el Miles Bader <miles@gnu.org>
122 ;; Make whitespace visible
123 ;; (handle display table, his code was modified, but the main
124 ;; idea was kept)
127 ;; Using whitespace
128 ;; ----------------
130 ;; There is no problem if you mix local and global minor mode usage.
132 ;; * LOCAL whitespace:
133 ;; + To toggle whitespace options locally, type:
135 ;; M-x whitespace-toggle-options RET
137 ;; + To activate whitespace locally, type:
139 ;; C-u 1 M-x whitespace-mode RET
141 ;; + To deactivate whitespace locally, type:
143 ;; C-u 0 M-x whitespace-mode RET
145 ;; + To toggle whitespace locally, type:
147 ;; M-x whitespace-mode RET
149 ;; * GLOBAL whitespace:
150 ;; + To toggle whitespace options globally, type:
152 ;; M-x global-whitespace-toggle-options RET
154 ;; + To activate whitespace globally, type:
156 ;; C-u 1 M-x global-whitespace-mode RET
158 ;; + To deactivate whitespace globally, type:
160 ;; C-u 0 M-x global-whitespace-mode RET
162 ;; + To toggle whitespace globally, type:
164 ;; M-x global-whitespace-mode RET
166 ;; There are also the following useful commands:
168 ;; `whitespace-newline-mode'
169 ;; Toggle NEWLINE minor mode visualization ("nl" on modeline).
171 ;; `global-whitespace-newline-mode'
172 ;; Toggle NEWLINE global minor mode visualization ("NL" on modeline).
174 ;; `whitespace-report'
175 ;; Report some blank problems in buffer.
177 ;; `whitespace-report-region'
178 ;; Report some blank problems in a region.
180 ;; `whitespace-cleanup'
181 ;; Cleanup some blank problems in all buffer or at region.
183 ;; `whitespace-cleanup-region'
184 ;; Cleanup some blank problems at region.
186 ;; The problems, which are cleaned up, are:
188 ;; 1. empty lines at beginning of buffer.
189 ;; 2. empty lines at end of buffer.
190 ;; If `whitespace-style' includes the value `empty', remove all
191 ;; empty lines at beginning and/or end of buffer.
193 ;; 3. 8 or more SPACEs at beginning of line.
194 ;; If `whitespace-style' includes the value `indentation':
195 ;; replace 8 or more SPACEs at beginning of line by TABs, if
196 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
197 ;; SPACEs.
198 ;; If `whitespace-style' includes the value `indentation::tab',
199 ;; replace 8 or more SPACEs at beginning of line by TABs.
200 ;; If `whitespace-style' includes the value `indentation::space',
201 ;; replace TABs by SPACEs.
203 ;; 4. SPACEs before TAB.
204 ;; If `whitespace-style' includes the value `space-before-tab':
205 ;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
206 ;; otherwise, replace TABs by SPACEs.
207 ;; If `whitespace-style' includes the value
208 ;; `space-before-tab::tab', replace SPACEs by TABs.
209 ;; If `whitespace-style' includes the value
210 ;; `space-before-tab::space', replace TABs by SPACEs.
212 ;; 5. SPACEs or TABs at end of line.
213 ;; If `whitespace-style' includes the value `trailing', remove all
214 ;; SPACEs or TABs at end of line.
216 ;; 6. 8 or more SPACEs after TAB.
217 ;; If `whitespace-style' includes the value `space-after-tab':
218 ;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
219 ;; otherwise, replace TABs by SPACEs.
220 ;; If `whitespace-style' includes the value `space-after-tab::tab',
221 ;; replace SPACEs by TABs.
222 ;; If `whitespace-style' includes the value
223 ;; `space-after-tab::space', replace TABs by SPACEs.
226 ;; Hooks
227 ;; -----
229 ;; whitespace has the following hook variables:
231 ;; `whitespace-mode-hook'
232 ;; It is evaluated always when whitespace is turned on locally.
234 ;; `global-whitespace-mode-hook'
235 ;; It is evaluated always when whitespace is turned on globally.
237 ;; `whitespace-load-hook'
238 ;; It is evaluated after whitespace package is loaded.
241 ;; Options
242 ;; -------
244 ;; Below it's shown a brief description of whitespace options, please,
245 ;; see the options declaration in the code for a long documentation.
247 ;; `whitespace-style' Specify which kind of blank is
248 ;; visualized.
250 ;; `whitespace-space' Face used to visualize SPACE.
252 ;; `whitespace-hspace' Face used to visualize HARD SPACE.
254 ;; `whitespace-tab' Face used to visualize TAB.
256 ;; `whitespace-newline' Face used to visualize NEWLINE char
257 ;; mapping.
259 ;; `whitespace-trailing' Face used to visualize trailing
260 ;; blanks.
262 ;; `whitespace-line' Face used to visualize "long" lines.
264 ;; `whitespace-space-before-tab' Face used to visualize SPACEs
265 ;; before TAB.
267 ;; `whitespace-indentation' Face used to visualize 8 or more
268 ;; SPACEs at beginning of line.
270 ;; `whitespace-empty' Face used to visualize empty lines at
271 ;; beginning and/or end of buffer.
273 ;; `whitespace-space-after-tab' Face used to visualize 8 or more
274 ;; SPACEs after TAB.
276 ;; `whitespace-space-regexp' Specify SPACE characters regexp.
278 ;; `whitespace-hspace-regexp' Specify HARD SPACE characters regexp.
280 ;; `whitespace-tab-regexp' Specify TAB characters regexp.
282 ;; `whitespace-trailing-regexp' Specify trailing characters regexp.
284 ;; `whitespace-space-before-tab-regexp' Specify SPACEs before TAB
285 ;; regexp.
287 ;; `whitespace-indentation-regexp' Specify regexp for 8 or more
288 ;; SPACEs at beginning of line.
290 ;; `whitespace-empty-at-bob-regexp' Specify regexp for empty lines
291 ;; at beginning of buffer.
293 ;; `whitespace-empty-at-eob-regexp' Specify regexp for empty lines
294 ;; at end of buffer.
296 ;; `whitespace-space-after-tab-regexp' Specify regexp for 8 or more
297 ;; SPACEs after TAB.
299 ;; `whitespace-line-column' Specify column beyond which the line
300 ;; is highlighted.
302 ;; `whitespace-display-mappings' Specify an alist of mappings
303 ;; for displaying characters.
305 ;; `whitespace-global-modes' Modes for which global
306 ;; `whitespace-mode' is automagically
307 ;; turned on.
309 ;; `whitespace-action' Specify which action is taken when a
310 ;; buffer is visited or written.
313 ;; Acknowledgements
314 ;; ----------------
316 ;; Thanks to David Reitter <david.reitter@gmail.com> for suggesting a
317 ;; `whitespace-newline' initialization with low contrast relative to
318 ;; the background color.
320 ;; Thanks to Stephen Deasey <sdeasey@gmail.com> for the
321 ;; `indent-tabs-mode' usage suggestion.
323 ;; Thanks to Eric Cooper <ecc@cmu.edu> for the suggestion to have hook
324 ;; actions when buffer is written as the original whitespace package
325 ;; had.
327 ;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
328 ;; lines tail. See EightyColumnRule (EmacsWiki).
330 ;; Thanks to Juri Linkov <juri@jurta.org> for suggesting:
331 ;; * `define-minor-mode'.
332 ;; * `global-whitespace-*' name for global commands.
334 ;; Thanks to Robert J. Chassell <bob@gnu.org> for doc fix and testing.
336 ;; Thanks to Drew Adams <drew.adams@oracle.com> for toggle commands
337 ;; suggestion.
339 ;; Thanks to Antti Kaihola <antti.kaihola@linux-aktivaattori.org> for
340 ;; helping to fix `find-file-hooks' reference.
342 ;; Thanks to Andreas Roehler <andreas.roehler@easy-emacs.de> for
343 ;; indicating defface byte-compilation warnings.
345 ;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight
346 ;; "long" lines. See EightyColumnRule (EmacsWiki).
348 ;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
349 ;; NEWLINE character mapping.
351 ;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
352 ;; whitespace-mode.el on XEmacs.
354 ;; Thanks to Miles Bader <miles@gnu.org> for handling display table via
355 ;; visws.el (his code was modified, but the main idea was kept).
357 ;; Thanks to:
358 ;; Rajesh Vaidheeswarran <rv@gnu.org> (original) whitespace.el
359 ;; Aurelien Tisne <aurelien.tisne@free.fr> show-whitespace-mode.el
360 ;; Lawrence Mitchell <wence@gmx.li> whitespace-mode.el
361 ;; Miles Bader <miles@gnu.org> visws.el
362 ;; And to all people who contributed with them.
365 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
367 ;;; code:
370 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
371 ;;;; User Variables:
374 ;;; Interface to the command system
377 (defgroup whitespace nil
378 "Visualize blanks (TAB, (HARD) SPACE and NEWLINE)."
379 :link '(emacs-library-link :tag "Source Lisp File" "whitespace.el")
380 :version "23.1"
381 :group 'wp
382 :group 'data)
385 (defcustom whitespace-style
386 '(tabs spaces trailing lines space-before-tab newline
387 indentation empty space-after-tab
388 space-mark tab-mark newline-mark)
389 "Specify which kind of blank is visualized.
391 It's a list containing some or all of the following values:
393 trailing trailing blanks are visualized via faces.
395 tabs TABs are visualized via faces.
397 spaces SPACEs and HARD SPACEs are visualized via
398 faces.
400 lines lines whose have columns beyond
401 `whitespace-line-column' are highlighted via
402 faces .
403 Whole line is highlighted.
404 It has precedence over `lines-tail' (see
405 below).
407 lines-tail lines whose have columns beyond
408 `whitespace-line-column' are highlighted via
409 faces.
410 But only the part of line which goes
411 beyond `whitespace-line-column' column.
412 It has effect only if `lines' (see above)
413 is not present in `whitespace-style'.
415 newline NEWLINEs are visualized via faces.
417 empty empty lines at beginning and/or end of buffer
418 are visualized via faces.
420 indentation::tab 8 or more SPACEs at beginning of line are
421 visualized via faces.
423 indentation::space TABs at beginning of line are visualized via
424 faces.
426 indentation 8 or more SPACEs at beginning of line are
427 visualized, if `indent-tabs-mode' (which see)
428 is non-nil; otherwise, TABs at beginning of
429 line are visualized via faces.
431 space-after-tab::tab 8 or more SPACEs after a TAB are
432 visualized via faces.
434 space-after-tab::space TABs are visualized when 8 or more
435 SPACEs occur after a TAB, via faces.
437 space-after-tab 8 or more SPACEs after a TAB are
438 visualized, if `indent-tabs-mode'
439 (which see) is non-nil; otherwise,
440 the TABs are visualized via faces.
442 space-before-tab::tab SPACEs before TAB are visualized via
443 faces.
445 space-before-tab::space TABs are visualized when SPACEs occur
446 before TAB, via faces.
448 space-before-tab SPACEs before TAB are visualized, if
449 `indent-tabs-mode' (which see) is
450 non-nil; otherwise, the TABs are
451 visualized via faces.
453 space-mark SPACEs and HARD SPACEs are visualized via
454 display table.
456 tab-mark TABs are visualized via display table.
458 newline-mark NEWLINEs are visualized via display table.
460 Any other value is ignored.
462 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs via faces and
463 via display table.
465 There is an evaluation order for some values, if some values are
466 included in `whitespace-style' list. For example, if
467 indentation, indentation::tab and/or indentation::space are
468 included in `whitespace-style' list. The evaluation order for
469 these values is:
471 * For indentation:
472 1. indentation
473 2. indentation::tab
474 3. indentation::space
476 * For SPACEs after TABs:
477 1. space-after-tab
478 2. space-after-tab::tab
479 3. space-after-tab::space
481 * For SPACEs before TABs:
482 1. space-before-tab
483 2. space-before-tab::tab
484 3. space-before-tab::space
486 So, for example, if indentation and indentation::space are
487 included in `whitespace-style' list, the indentation value is
488 evaluated instead of indentation::space value.
490 See also `whitespace-display-mappings' for documentation."
491 :type '(repeat :tag "Kind of Blank"
492 (choice :tag "Kind of Blank Face"
493 (const :tag "(Face) Trailing TABs, SPACEs and HARD SPACEs"
494 trailing)
495 (const :tag "(Face) SPACEs and HARD SPACEs"
496 spaces)
497 (const :tag "(Face) TABs" tabs)
498 (const :tag "(Face) Lines" lines)
499 (const :tag "(Face) SPACEs before TAB"
500 space-before-tab)
501 (const :tag "(Face) NEWLINEs" newline)
502 (const :tag "(Face) Indentation SPACEs"
503 indentation)
504 (const :tag "(Face) Empty Lines At BOB And/Or EOB"
505 empty)
506 (const :tag "(Face) SPACEs after TAB"
507 space-after-tab)
508 (const :tag "(Mark) SPACEs and HARD SPACEs"
509 space-mark)
510 (const :tag "(Mark) TABs" tab-mark)
511 (const :tag "(Mark) NEWLINEs" newline-mark)))
512 :group 'whitespace)
515 (defcustom whitespace-space 'whitespace-space
516 "Symbol face used to visualize SPACE.
518 Used when `whitespace-style' includes the value `spaces'."
519 :type 'face
520 :group 'whitespace)
523 (defface whitespace-space
524 '((((class color) (background dark))
525 (:background "grey20" :foreground "aquamarine3"))
526 (((class color) (background light))
527 (:background "LightYellow" :foreground "aquamarine3"))
528 (t (:inverse-video t)))
529 "Face used to visualize SPACE."
530 :group 'whitespace)
533 (defcustom whitespace-hspace 'whitespace-hspace
534 "Symbol face used to visualize HARD SPACE.
536 Used when `whitespace-style' includes the value `spaces'."
537 :type 'face
538 :group 'whitespace)
541 (defface whitespace-hspace ; 'nobreak-space
542 '((((class color) (background dark))
543 (:background "grey24" :foreground "aquamarine3"))
544 (((class color) (background light))
545 (:background "LemonChiffon3" :foreground "aquamarine3"))
546 (t (:inverse-video t)))
547 "Face used to visualize HARD SPACE."
548 :group 'whitespace)
551 (defcustom whitespace-tab 'whitespace-tab
552 "Symbol face used to visualize TAB.
554 Used when `whitespace-style' includes the value `tabs'."
555 :type 'face
556 :group 'whitespace)
559 (defface whitespace-tab
560 '((((class color) (background dark))
561 (:background "grey22" :foreground "aquamarine3"))
562 (((class color) (background light))
563 (:background "beige" :foreground "aquamarine3"))
564 (t (:inverse-video t)))
565 "Face used to visualize TAB."
566 :group 'whitespace)
569 (defcustom whitespace-newline 'whitespace-newline
570 "Symbol face used to visualize NEWLINE char mapping.
572 See `whitespace-display-mappings'.
574 Used when `whitespace-style' includes the values `newline-mark'
575 and `newline'."
576 :type 'face
577 :group 'whitespace)
580 (defface whitespace-newline
581 '((((class color) (background dark))
582 (:foreground "darkgray" :bold nil))
583 (((class color) (background light))
584 (:foreground "lightgray" :bold nil))
585 (t (:underline t :bold nil)))
586 "Face used to visualize NEWLINE char mapping.
588 See `whitespace-display-mappings'."
589 :group 'whitespace)
592 (defcustom whitespace-trailing 'whitespace-trailing
593 "Symbol face used to visualize trailing blanks.
595 Used when `whitespace-style' includes the value `trailing'."
596 :type 'face
597 :group 'whitespace)
600 (defface whitespace-trailing ; 'trailing-whitespace
601 '((((class mono)) (:inverse-video t :bold t :underline t))
602 (t (:background "red1" :foreground "yellow" :bold t)))
603 "Face used to visualize trailing blanks."
604 :group 'whitespace)
607 (defcustom whitespace-line 'whitespace-line
608 "Symbol face used to visualize \"long\" lines.
610 See `whitespace-line-column'.
612 Used when `whitespace-style' includes the value `line'."
613 :type 'face
614 :group 'whitespace)
617 (defface whitespace-line
618 '((((class mono)) (:inverse-video t :bold t :underline t))
619 (t (:background "gray20" :foreground "violet")))
620 "Face used to visualize \"long\" lines.
622 See `whitespace-line-column'."
623 :group 'whitespace)
626 (defcustom whitespace-space-before-tab 'whitespace-space-before-tab
627 "Symbol face used to visualize SPACEs before TAB.
629 Used when `whitespace-style' includes the value `space-before-tab'."
630 :type 'face
631 :group 'whitespace)
634 (defface whitespace-space-before-tab
635 '((((class mono)) (:inverse-video t :bold t :underline t))
636 (t (:background "DarkOrange" :foreground "firebrick")))
637 "Face used to visualize SPACEs before TAB."
638 :group 'whitespace)
641 (defcustom whitespace-indentation 'whitespace-indentation
642 "Symbol face used to visualize 8 or more SPACEs at beginning of line.
644 Used when `whitespace-style' includes the value `indentation'."
645 :type 'face
646 :group 'whitespace)
649 (defface whitespace-indentation
650 '((((class mono)) (:inverse-video t :bold t :underline t))
651 (t (:background "yellow" :foreground "firebrick")))
652 "Face used to visualize 8 or more SPACEs at beginning of line."
653 :group 'whitespace)
656 (defcustom whitespace-empty 'whitespace-empty
657 "Symbol face used to visualize empty lines at beginning and/or end of buffer.
659 Used when `whitespace-style' includes the value `empty'."
660 :type 'face
661 :group 'whitespace)
664 (defface whitespace-empty
665 '((((class mono)) (:inverse-video t :bold t :underline t))
666 (t (:background "yellow" :foreground "firebrick")))
667 "Face used to visualize empty lines at beginning and/or end of buffer."
668 :group 'whitespace)
671 (defcustom whitespace-space-after-tab 'whitespace-space-after-tab
672 "Symbol face used to visualize 8 or more SPACEs after TAB.
674 Used when `whitespace-style' includes the value `space-after-tab'."
675 :type 'face
676 :group 'whitespace)
679 (defface whitespace-space-after-tab
680 '((((class mono)) (:inverse-video t :bold t :underline t))
681 (t (:background "yellow" :foreground "firebrick")))
682 "Face used to visualize 8 or more SPACEs after TAB."
683 :group 'whitespace)
686 (defcustom whitespace-hspace-regexp
687 "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
688 "Specify HARD SPACE characters regexp.
690 If you're using `mule' package, there may be other characters besides:
692 \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
694 that should be considered HARD SPACE.
696 Here are some examples:
698 \"\\\\(^\\xA0+\\\\)\" \
699 visualize only leading HARD SPACEs.
700 \"\\\\(\\xA0+$\\\\)\" \
701 visualize only trailing HARD SPACEs.
702 \"\\\\(^\\xA0+\\\\|\\xA0+$\\\\)\" \
703 visualize leading and/or trailing HARD SPACEs.
704 \"\\t\\\\(\\xA0+\\\\)\\t\" \
705 visualize only HARD SPACEs between TABs.
707 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
708 Use exactly one pair of enclosing \\\\( and \\\\).
710 Used when `whitespace-style' includes `spaces'."
711 :type '(regexp :tag "HARD SPACE Chars")
712 :group 'whitespace)
715 (defcustom whitespace-space-regexp "\\( +\\)"
716 "Specify SPACE characters regexp.
718 If you're using `mule' package, there may be other characters
719 besides \" \" that should be considered SPACE.
721 Here are some examples:
723 \"\\\\(^ +\\\\)\" visualize only leading SPACEs.
724 \"\\\\( +$\\\\)\" visualize only trailing SPACEs.
725 \"\\\\(^ +\\\\| +$\\\\)\" \
726 visualize leading and/or trailing SPACEs.
727 \"\\t\\\\( +\\\\)\\t\" visualize only SPACEs between TABs.
729 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
730 Use exactly one pair of enclosing \\\\( and \\\\).
732 Used when `whitespace-style' includes `spaces'."
733 :type '(regexp :tag "SPACE Chars")
734 :group 'whitespace)
737 (defcustom whitespace-tab-regexp "\\(\t+\\)"
738 "Specify TAB characters regexp.
740 If you're using `mule' package, there may be other characters
741 besides \"\\t\" that should be considered TAB.
743 Here are some examples:
745 \"\\\\(^\\t+\\\\)\" visualize only leading TABs.
746 \"\\\\(\\t+$\\\\)\" visualize only trailing TABs.
747 \"\\\\(^\\t+\\\\|\\t+$\\\\)\" \
748 visualize leading and/or trailing TABs.
749 \" \\\\(\\t+\\\\) \" visualize only TABs between SPACEs.
751 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
752 Use exactly one pair of enclosing \\\\( and \\\\).
754 Used when `whitespace-style' includes `tabs'."
755 :type '(regexp :tag "TAB Chars")
756 :group 'whitespace)
759 (defcustom whitespace-trailing-regexp
760 "\\(\\(\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)$"
761 "Specify trailing characters regexp.
763 If you're using `mule' package, there may be other characters besides:
765 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
766 \"\\xF20\"
768 that should be considered blank.
770 NOTE: Enclose always by \"\\\\(\" and \"\\\\)$\" the elements to highlight.
771 Use exactly one pair of enclosing elements above.
773 Used when `whitespace-style' includes `trailing'."
774 :type '(regexp :tag "Trailing Chars")
775 :group 'whitespace)
778 (defcustom whitespace-space-before-tab-regexp "\\( +\\)\\(\t+\\)"
779 "Specify SPACEs before TAB regexp.
781 If you're using `mule' package, there may be other characters besides:
783 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
784 \"\\xF20\"
786 that should be considered blank.
788 Used when `whitespace-style' includes `space-before-tab',
789 `space-before-tab::tab' or `space-before-tab::space'."
790 :type '(regexp :tag "SPACEs Before TAB")
791 :group 'whitespace)
794 (defcustom whitespace-indentation-regexp
795 '("^\t*\\(\\( \\{%d\\}\\)+\\)[^\n\t]"
796 . "^ *\\(\t+\\)[^\n]")
797 "Specify regexp for 8 or more SPACEs at beginning of line.
799 It is a cons where the cons car is used for SPACEs visualization
800 and the cons cdr is used for TABs visualization.
802 If you're using `mule' package, there may be other characters besides:
804 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
805 \"\\xF20\"
807 that should be considered blank.
809 Used when `whitespace-style' includes `indentation',
810 `indentation::tab' or `indentation::space'."
811 :type '(cons (regexp :tag "Indentation SPACEs")
812 (regexp :tag "Indentation TABs"))
813 :group 'whitespace)
816 (defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
817 "Specify regexp for empty lines at beginning 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 Beginning Of Buffer")
828 :group 'whitespace)
831 (defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
832 "Specify regexp for empty lines at end of buffer.
834 If you're using `mule' package, there may be other characters besides:
836 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
837 \"\\xF20\"
839 that should be considered blank.
841 Used when `whitespace-style' includes `empty'."
842 :type '(regexp :tag "Empty Lines At End Of Buffer")
843 :group 'whitespace)
846 (defcustom whitespace-space-after-tab-regexp
847 '("\t+\\(\\( \\{%d\\}\\)+\\)"
848 . "\\(\t+\\) +")
849 "Specify regexp for 8 or more SPACEs after TAB.
851 It is a cons where the cons car is used for SPACEs visualization
852 and the cons cdr is used for TABs visualization.
854 If you're using `mule' package, there may be other characters besides:
856 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
857 \"\\xF20\"
859 that should be considered blank.
861 Used when `whitespace-style' includes `space-after-tab',
862 `space-after-tab::tab' or `space-after-tab::space'."
863 :type '(regexp :tag "SPACEs After TAB")
864 :group 'whitespace)
867 (defcustom whitespace-line-column 80
868 "Specify column beyond which the line is highlighted.
870 Used when `whitespace-style' includes `lines' or `lines-tail'."
871 :type '(integer :tag "Line Length")
872 :group 'whitespace)
875 ;; Hacked from `visible-whitespace-mappings' in visws.el
876 (defcustom whitespace-display-mappings
878 (space-mark ?\ [?\u00B7] [?.]) ; space - centered dot
879 (space-mark ?\xA0 [?\u00A4] [?_]) ; hard space - currency
880 (space-mark ?\x8A0 [?\x8A4] [?_]) ; hard space - currency
881 (space-mark ?\x920 [?\x924] [?_]) ; hard space - currency
882 (space-mark ?\xE20 [?\xE24] [?_]) ; hard space - currency
883 (space-mark ?\xF20 [?\xF24] [?_]) ; hard space - currency
884 ;; NEWLINE is displayed using the face `whitespace-newline'
885 (newline-mark ?\n [?$ ?\n]) ; eol - dollar sign
886 ;; (newline-mark ?\n [?\u21B5 ?\n] [?$ ?\n]) ; eol - downwards arrow
887 ;; (newline-mark ?\n [?\u00B6 ?\n] [?$ ?\n]) ; eol - pilcrow
888 ;; (newline-mark ?\n [?\x8AF ?\n] [?$ ?\n]) ; eol - overscore
889 ;; (newline-mark ?\n [?\x8AC ?\n] [?$ ?\n]) ; eol - negation
890 ;; (newline-mark ?\n [?\x8B0 ?\n] [?$ ?\n]) ; eol - grade
892 ;; WARNING: the mapping below has a problem.
893 ;; When a TAB occupies exactly one column, it will display the
894 ;; character ?\xBB at that column followed by a TAB which goes to
895 ;; the next TAB column.
896 ;; If this is a problem for you, please, comment the line below.
897 (tab-mark ?\t [?\u00BB ?\t] [?\\ ?\t]) ; tab - left quote mark
899 "Specify an alist of mappings for displaying characters.
901 Each element has the following form:
903 (KIND CHAR VECTOR...)
905 Where:
907 KIND is the kind of character.
908 It can be one of the following symbols:
910 tab-mark for TAB character
912 space-mark for SPACE or HARD SPACE character
914 newline-mark for NEWLINE character
916 CHAR is the character to be mapped.
918 VECTOR is a vector of characters to be displayed in place of CHAR.
919 The first display vector that can be displayed is used;
920 if no display vector for a mapping can be displayed, then
921 that character is displayed unmodified.
923 The NEWLINE character is displayed using the face given by
924 `whitespace-newline' variable.
926 Used when `whitespace-style' includes `tab-mark', `space-mark' or
927 `newline-mark'."
928 :type '(repeat
929 (list :tag "Character Mapping"
930 (choice :tag "Char Kind"
931 (const :tag "Tab" tab-mark)
932 (const :tag "Space" space-mark)
933 (const :tag "Newline" newline-mark))
934 (character :tag "Char")
935 (repeat :inline t :tag "Vector List"
936 (vector :tag ""
937 (repeat :inline t
938 :tag "Vector Characters"
939 (character :tag "Char"))))))
940 :group 'whitespace)
943 (defcustom whitespace-global-modes t
944 "Modes for which global `whitespace-mode' is automagically turned on.
946 Global `whitespace-mode' is controlled by the command
947 `global-whitespace-mode'.
949 If nil, means no modes have `whitespace-mode' automatically
950 turned on.
952 If t, all modes that support `whitespace-mode' have it
953 automatically turned on.
955 Else it should be a list of `major-mode' symbol names for which
956 `whitespace-mode' should be automatically turned on. The sense
957 of the list is negated if it begins with `not'. For example:
959 (c-mode c++-mode)
961 means that `whitespace-mode' is turned on for buffers in C and
962 C++ modes only."
963 :type '(choice :tag "Global Modes"
964 (const :tag "None" nil)
965 (const :tag "All" t)
966 (set :menu-tag "Mode Specific" :tag "Modes"
967 :value (not)
968 (const :tag "Except" not)
969 (repeat :inline t
970 (symbol :tag "Mode"))))
971 :group 'whitespace)
974 (defcustom whitespace-action nil
975 "Specify which action is taken when a buffer is visited or written.
977 It's a list containing some or all of the following values:
979 nil no action is taken.
981 cleanup cleanup any bogus whitespace always when local
982 whitespace is turned on.
983 See `whitespace-cleanup' and
984 `whitespace-cleanup-region'.
986 report-on-bogus report if there is any bogus whitespace always
987 when local whitespace is turned on.
989 auto-cleanup cleanup any bogus whitespace when buffer is
990 written.
991 See `whitespace-cleanup' and
992 `whitespace-cleanup-region'.
994 abort-on-bogus abort if there is any bogus whitespace and the
995 buffer is written.
997 warn-if-read-only give a warning if `cleanup' or `auto-cleanup'
998 is included in `whitespace-action' and the
999 buffer is read-only.
1001 Any other value is treated as nil."
1002 :type '(choice :tag "Actions"
1003 (const :tag "None" nil)
1004 (repeat :tag "Action List"
1005 (choice :tag "Action"
1006 (const :tag "Cleanup When On" cleanup)
1007 (const :tag "Report On Bogus" report-on-bogus)
1008 (const :tag "Auto Cleanup" auto-cleanup)
1009 (const :tag "Abort On Bogus" abort-on-bogus)
1010 (const :tag "Warn If Read-Only" warn-if-read-only))))
1011 :group 'whitespace)
1014 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1015 ;;;; User commands - Local mode
1018 ;;;###autoload
1019 (define-minor-mode whitespace-mode
1020 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
1022 If ARG is null, toggle whitespace visualization.
1023 If ARG is a number greater than zero, turn on visualization;
1024 otherwise, turn off visualization.
1025 Only useful with a windowing system.
1027 See also `whitespace-style', `whitespace-newline' and
1028 `whitespace-display-mappings'."
1029 :lighter " ws"
1030 :init-value nil
1031 :global nil
1032 :group 'whitespace
1033 (cond
1034 (noninteractive ; running a batch job
1035 (setq whitespace-mode nil))
1036 (whitespace-mode ; whitespace-mode on
1037 (whitespace-turn-on)
1038 (whitespace-action-when-on))
1039 (t ; whitespace-mode off
1040 (whitespace-turn-off))))
1043 ;;;###autoload
1044 (define-minor-mode whitespace-newline-mode
1045 "Toggle NEWLINE minor mode visualization (\"nl\" on modeline).
1047 If ARG is null, toggle NEWLINE visualization.
1048 If ARG is a number greater than zero, turn on visualization;
1049 otherwise, turn off visualization.
1050 Only useful with a windowing system.
1052 Use `whitespace-newline-mode' only for NEWLINE visualization
1053 exclusively. For other visualizations, including NEWLINE
1054 visualization together with (HARD) SPACEs and/or TABs, please,
1055 use `whitespace-mode'.
1057 See also `whitespace-newline' and `whitespace-display-mappings'."
1058 :lighter " nl"
1059 :init-value nil
1060 :global nil
1061 :group 'whitespace
1062 (let ((whitespace-style '(newline-mark newline)))
1063 (whitespace-mode whitespace-newline-mode)
1064 ;; sync states (running a batch job)
1065 (setq whitespace-newline-mode whitespace-mode)))
1068 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1069 ;;;; User commands - Global mode
1072 ;;;###autoload
1073 (define-minor-mode global-whitespace-mode
1074 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
1076 If ARG is null, toggle whitespace visualization.
1077 If ARG is a number greater than zero, turn on visualization;
1078 otherwise, turn off visualization.
1079 Only useful with a windowing system.
1081 See also `whitespace-style', `whitespace-newline' and
1082 `whitespace-display-mappings'."
1083 :lighter " WS"
1084 :init-value nil
1085 :global t
1086 :group 'whitespace
1087 (cond
1088 (noninteractive ; running a batch job
1089 (setq global-whitespace-mode nil))
1090 (global-whitespace-mode ; global-whitespace-mode on
1091 (save-excursion
1092 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1093 (dolist (buffer (buffer-list)) ; adjust all local mode
1094 (set-buffer buffer)
1095 (unless whitespace-mode
1096 (whitespace-turn-on-if-enabled)))))
1097 (t ; global-whitespace-mode off
1098 (save-excursion
1099 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1100 (dolist (buffer (buffer-list)) ; adjust all local mode
1101 (set-buffer buffer)
1102 (unless whitespace-mode
1103 (whitespace-turn-off)))))))
1106 (defun whitespace-turn-on-if-enabled ()
1107 (when (cond
1108 ((eq whitespace-global-modes t))
1109 ((listp whitespace-global-modes)
1110 (if (eq (car-safe whitespace-global-modes) 'not)
1111 (not (memq major-mode (cdr whitespace-global-modes)))
1112 (memq major-mode whitespace-global-modes)))
1113 (t nil))
1114 (let (inhibit-quit)
1115 ;; Don't turn on whitespace mode if...
1117 ;; ...we don't have a display (we're running a batch job)
1118 noninteractive
1119 ;; ...or if the buffer is invisible (name starts with a space)
1120 (eq (aref (buffer-name) 0) ?\ )
1121 ;; ...or if the buffer is temporary (name starts with *)
1122 (and (eq (aref (buffer-name) 0) ?*)
1123 ;; except the scratch buffer.
1124 (not (string= (buffer-name) "*scratch*")))
1125 ;; Otherwise, turn on whitespace mode.
1126 (whitespace-turn-on)))))
1129 ;;;###autoload
1130 (define-minor-mode global-whitespace-newline-mode
1131 "Toggle NEWLINE global minor mode visualization (\"NL\" on modeline).
1133 If ARG is null, toggle NEWLINE visualization.
1134 If ARG is a number greater than zero, turn on visualization;
1135 otherwise, turn off visualization.
1136 Only useful with a windowing system.
1138 Use `global-whitespace-newline-mode' only for NEWLINE
1139 visualization exclusively. For other visualizations, including
1140 NEWLINE visualization together with (HARD) SPACEs and/or TABs,
1141 please, use `global-whitespace-mode'.
1143 See also `whitespace-newline' and `whitespace-display-mappings'."
1144 :lighter " NL"
1145 :init-value nil
1146 :global t
1147 :group 'whitespace
1148 (let ((whitespace-style '(newline-mark newline)))
1149 (global-whitespace-mode global-whitespace-newline-mode)
1150 ;; sync states (running a batch job)
1151 (setq global-whitespace-newline-mode global-whitespace-mode)))
1154 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1155 ;;;; User commands - Toggle
1158 (defconst whitespace-style-value-list
1159 '(tabs
1160 spaces
1161 trailing
1162 lines
1163 lines-tail
1164 newline
1165 empty
1166 indentation
1167 indentation::tab
1168 indentation::space
1169 space-after-tab
1170 space-after-tab::tab
1171 space-after-tab::space
1172 space-before-tab
1173 space-before-tab::tab
1174 space-before-tab::space
1175 help-newline ; value used by `whitespace-insert-option-mark'
1176 tab-mark
1177 space-mark
1178 newline-mark
1180 "List of valid `whitespace-style' values.")
1183 (defconst whitespace-toggle-option-alist
1184 '((?t . tabs)
1185 (?s . spaces)
1186 (?r . trailing)
1187 (?l . lines)
1188 (?L . lines-tail)
1189 (?n . newline)
1190 (?e . empty)
1191 (?\C-i . indentation)
1192 (?I . indentation::tab)
1193 (?i . indentation::space)
1194 (?\C-a . space-after-tab)
1195 (?A . space-after-tab::tab)
1196 (?a . space-after-tab::space)
1197 (?\C-b . space-before-tab)
1198 (?B . space-before-tab::tab)
1199 (?b . space-before-tab::space)
1200 (?T . tab-mark)
1201 (?S . space-mark)
1202 (?N . newline-mark)
1203 (?x . whitespace-style)
1205 "Alist of toggle options.
1207 Each element has the form:
1209 (CHAR . SYMBOL)
1211 Where:
1213 CHAR is a char which the user will have to type.
1215 SYMBOL is a valid symbol associated with CHAR.
1216 See `whitespace-style-value-list'.")
1219 (defvar whitespace-active-style nil
1220 "Used to save locally `whitespace-style' value.")
1222 (defvar whitespace-indent-tabs-mode indent-tabs-mode
1223 "Used to save locally `indent-tabs-mode' value.")
1225 (defvar whitespace-tab-width tab-width
1226 "Used to save locally `tab-width' value.")
1228 (defvar whitespace-point (point)
1229 "Used to save locally current point value.
1230 Used by `whitespace-trailing-regexp' function (which see).")
1232 (defvar whitespace-font-lock-refontify nil
1233 "Used to save locally the font-lock refontify state.
1234 Used by `whitespace-post-command-hook' function (which see).")
1237 ;;;###autoload
1238 (defun whitespace-toggle-options (arg)
1239 "Toggle local `whitespace-mode' options.
1241 If local whitespace-mode is off, toggle the option given by ARG
1242 and turn on local whitespace-mode.
1244 If local whitespace-mode is on, toggle the option given by ARG
1245 and restart local whitespace-mode.
1247 Interactively, it reads one of the following chars:
1249 CHAR MEANING
1250 (VIA FACES)
1251 t toggle TAB visualization
1252 s toggle SPACE and HARD SPACE visualization
1253 r toggle trailing blanks visualization
1254 l toggle \"long lines\" visualization
1255 L toggle \"long lines\" tail visualization
1256 n toggle NEWLINE visualization
1257 e toggle empty line at bob and/or eob visualization
1258 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1259 I toggle indentation SPACEs visualization
1260 i toggle indentation TABs visualization
1261 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1262 A toggle SPACEs after TAB: SPACEs visualization
1263 a toggle SPACEs after TAB: TABs visualization
1264 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1265 B toggle SPACEs before TAB: SPACEs visualization
1266 b toggle SPACEs before TAB: TABs visualization
1268 (VIA DISPLAY TABLE)
1269 T toggle TAB visualization
1270 S toggle SPACEs before TAB visualization
1271 N toggle NEWLINE visualization
1273 x restore `whitespace-style' value
1274 ? display brief help
1276 Non-interactively, ARG should be a symbol or a list of symbols.
1277 The valid symbols are:
1279 tabs toggle TAB visualization
1280 spaces toggle SPACE and HARD SPACE visualization
1281 trailing toggle trailing blanks visualization
1282 lines toggle \"long lines\" visualization
1283 lines-tail toggle \"long lines\" tail visualization
1284 newline toggle NEWLINE visualization
1285 empty toggle empty line at bob and/or eob visualization
1286 indentation toggle indentation SPACEs visualization
1287 indentation::tab toggle indentation SPACEs visualization
1288 indentation::space toggle indentation TABs visualization
1289 space-after-tab toggle SPACEs after TAB visualization
1290 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1291 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1292 space-before-tab toggle SPACEs before TAB visualization
1293 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1294 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1296 tab-mark toggle TAB visualization
1297 space-mark toggle SPACEs before TAB visualization
1298 newline-mark toggle NEWLINE visualization
1300 whitespace-style restore `whitespace-style' value
1302 Only useful with a windowing system.
1304 See `whitespace-style' and `indent-tabs-mode' for documentation."
1305 (interactive (whitespace-interactive-char t))
1306 (let ((whitespace-style
1307 (whitespace-toggle-list t arg whitespace-active-style)))
1308 (whitespace-mode 0)
1309 (whitespace-mode 1)))
1312 (defvar whitespace-toggle-style nil
1313 "Used to toggle the global `whitespace-style' value.")
1316 ;;;###autoload
1317 (defun global-whitespace-toggle-options (arg)
1318 "Toggle global `whitespace-mode' options.
1320 If global whitespace-mode is off, toggle the option given by ARG
1321 and turn on global whitespace-mode.
1323 If global whitespace-mode is on, toggle the option given by ARG
1324 and restart global whitespace-mode.
1326 Interactively, it accepts one of the following chars:
1328 CHAR MEANING
1329 (VIA FACES)
1330 t toggle TAB visualization
1331 s toggle SPACE and HARD SPACE visualization
1332 r toggle trailing blanks visualization
1333 l toggle \"long lines\" visualization
1334 L toggle \"long lines\" tail visualization
1335 n toggle NEWLINE visualization
1336 e toggle empty line at bob and/or eob visualization
1337 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1338 I toggle indentation SPACEs visualization
1339 i toggle indentation TABs visualization
1340 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1341 A toggle SPACEs after TAB: SPACEs visualization
1342 a toggle SPACEs after TAB: TABs visualization
1343 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1344 B toggle SPACEs before TAB: SPACEs visualization
1345 b toggle SPACEs before TAB: TABs visualization
1347 (VIA DISPLAY TABLE)
1348 T toggle TAB visualization
1349 S toggle SPACEs before TAB visualization
1350 N toggle NEWLINE visualization
1352 x restore `whitespace-style' value
1353 ? display brief help
1355 Non-interactively, ARG should be a symbol or a list of symbols.
1356 The valid symbols are:
1358 tabs toggle TAB visualization
1359 spaces toggle SPACE and HARD SPACE visualization
1360 trailing toggle trailing blanks visualization
1361 lines toggle \"long lines\" visualization
1362 lines-tail toggle \"long lines\" tail visualization
1363 newline toggle NEWLINE visualization
1364 empty toggle empty line at bob and/or eob visualization
1365 indentation toggle indentation SPACEs visualization
1366 indentation::tab toggle indentation SPACEs visualization
1367 indentation::space toggle indentation TABs visualization
1368 space-after-tab toggle SPACEs after TAB visualization
1369 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1370 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1371 space-before-tab toggle SPACEs before TAB visualization
1372 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1373 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1375 tab-mark toggle TAB visualization
1376 space-mark toggle SPACEs before TAB visualization
1377 newline-mark toggle NEWLINE visualization
1379 whitespace-style restore `whitespace-style' value
1381 Only useful with a windowing system.
1383 See `whitespace-style' and `indent-tabs-mode' for documentation."
1384 (interactive (whitespace-interactive-char nil))
1385 (let ((whitespace-style
1386 (whitespace-toggle-list nil arg whitespace-toggle-style)))
1387 (setq whitespace-toggle-style whitespace-style)
1388 (global-whitespace-mode 0)
1389 (global-whitespace-mode 1)))
1392 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1393 ;;;; User commands - Cleanup
1396 ;;;###autoload
1397 (defun whitespace-cleanup ()
1398 "Cleanup some blank problems in all buffer or at region.
1400 It usually applies to the whole buffer, but in transient mark
1401 mode when the mark is active, it applies to the region. It also
1402 applies to the region when it is not in transient mark mode, the
1403 mark is active and \\[universal-argument] was pressed just before
1404 calling `whitespace-cleanup' interactively.
1406 See also `whitespace-cleanup-region'.
1408 The problems cleaned up are:
1410 1. empty lines at beginning of buffer.
1411 2. empty lines at end of buffer.
1412 If `whitespace-style' includes the value `empty', remove all
1413 empty lines at beginning and/or end of buffer.
1415 3. 8 or more SPACEs at beginning of line.
1416 If `whitespace-style' includes the value `indentation':
1417 replace 8 or more SPACEs at beginning of line by TABs, if
1418 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1419 SPACEs.
1420 If `whitespace-style' includes the value `indentation::tab',
1421 replace 8 or more SPACEs at beginning of line by TABs.
1422 If `whitespace-style' includes the value `indentation::space',
1423 replace TABs by SPACEs.
1425 4. SPACEs before TAB.
1426 If `whitespace-style' includes the value `space-before-tab':
1427 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1428 otherwise, replace TABs by SPACEs.
1429 If `whitespace-style' includes the value
1430 `space-before-tab::tab', replace SPACEs by TABs.
1431 If `whitespace-style' includes the value
1432 `space-before-tab::space', replace TABs by SPACEs.
1434 5. SPACEs or TABs at end of line.
1435 If `whitespace-style' includes the value `trailing', remove
1436 all SPACEs or TABs at end of line.
1438 6. 8 or more SPACEs after TAB.
1439 If `whitespace-style' includes the value `space-after-tab':
1440 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1441 otherwise, replace TABs by SPACEs.
1442 If `whitespace-style' includes the value
1443 `space-after-tab::tab', replace SPACEs by TABs.
1444 If `whitespace-style' includes the value
1445 `space-after-tab::space', replace TABs by SPACEs.
1447 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1448 documentation."
1449 (interactive "@")
1450 (cond
1451 ;; read-only buffer
1452 (buffer-read-only
1453 (whitespace-warn-read-only "cleanup"))
1454 ;; region active
1455 ((and (or transient-mark-mode
1456 current-prefix-arg)
1457 mark-active)
1458 ;; PROBLEMs 1 and 2 are not handled in region
1459 ;; PROBLEM 3: 8 or more SPACEs at bol
1460 ;; PROBLEM 4: SPACEs before TAB
1461 ;; PROBLEM 5: SPACEs or TABs at eol
1462 ;; PROBLEM 6: 8 or more SPACEs after TAB
1463 (whitespace-cleanup-region (region-beginning) (region-end)))
1464 ;; whole buffer
1466 (save-excursion
1467 (save-match-data
1468 ;; PROBLEM 1: empty lines at bob
1469 ;; PROBLEM 2: empty lines at eob
1470 ;; ACTION: remove all empty lines at bob and/or eob
1471 (when (memq 'empty whitespace-style)
1472 (let (overwrite-mode) ; enforce no overwrite
1473 (goto-char (point-min))
1474 (when (re-search-forward
1475 whitespace-empty-at-bob-regexp nil t)
1476 (delete-region (match-beginning 1) (match-end 1)))
1477 (when (re-search-forward
1478 whitespace-empty-at-eob-regexp nil t)
1479 (delete-region (match-beginning 1) (match-end 1)))))))
1480 ;; PROBLEM 3: 8 or more SPACEs at bol
1481 ;; PROBLEM 4: SPACEs before TAB
1482 ;; PROBLEM 5: SPACEs or TABs at eol
1483 ;; PROBLEM 6: 8 or more SPACEs after TAB
1484 (whitespace-cleanup-region (point-min) (point-max)))))
1487 ;;;###autoload
1488 (defun whitespace-cleanup-region (start end)
1489 "Cleanup some blank problems at region.
1491 The problems cleaned up are:
1493 1. 8 or more SPACEs at beginning of line.
1494 If `whitespace-style' includes the value `indentation':
1495 replace 8 or more SPACEs at beginning of line by TABs, if
1496 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1497 SPACEs.
1498 If `whitespace-style' includes the value `indentation::tab',
1499 replace 8 or more SPACEs at beginning of line by TABs.
1500 If `whitespace-style' includes the value `indentation::space',
1501 replace TABs by SPACEs.
1503 2. SPACEs before TAB.
1504 If `whitespace-style' includes the value `space-before-tab':
1505 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1506 otherwise, replace TABs by SPACEs.
1507 If `whitespace-style' includes the value
1508 `space-before-tab::tab', replace SPACEs by TABs.
1509 If `whitespace-style' includes the value
1510 `space-before-tab::space', replace TABs by SPACEs.
1512 3. SPACEs or TABs at end of line.
1513 If `whitespace-style' includes the value `trailing', remove
1514 all SPACEs or TABs at end of line.
1516 4. 8 or more SPACEs after TAB.
1517 If `whitespace-style' includes the value `space-after-tab':
1518 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1519 otherwise, replace TABs by SPACEs.
1520 If `whitespace-style' includes the value
1521 `space-after-tab::tab', replace SPACEs by TABs.
1522 If `whitespace-style' includes the value
1523 `space-after-tab::space', replace TABs by SPACEs.
1525 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1526 documentation."
1527 (interactive "@r")
1528 (if buffer-read-only
1529 ;; read-only buffer
1530 (whitespace-warn-read-only "cleanup region")
1531 ;; non-read-only buffer
1532 (let ((rstart (min start end))
1533 (rend (copy-marker (max start end)))
1534 (indent-tabs-mode whitespace-indent-tabs-mode)
1535 (tab-width whitespace-tab-width)
1536 overwrite-mode ; enforce no overwrite
1537 tmp)
1538 (save-excursion
1539 (save-match-data
1540 ;; PROBLEM 1: 8 or more SPACEs at bol
1541 (cond
1542 ;; ACTION: replace 8 or more SPACEs at bol by TABs, if
1543 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1544 ;; by SPACEs.
1545 ((memq 'indentation whitespace-style)
1546 (let ((regexp (whitespace-indentation-regexp)))
1547 (goto-char rstart)
1548 (while (re-search-forward regexp rend t)
1549 (setq tmp (current-indentation))
1550 (goto-char (match-beginning 0))
1551 (delete-horizontal-space)
1552 (unless (eolp)
1553 (indent-to tmp)))))
1554 ;; ACTION: replace 8 or more SPACEs at bol by TABs.
1555 ((memq 'indentation::tab whitespace-style)
1556 (whitespace-replace-action
1557 'tabify rstart rend
1558 (whitespace-indentation-regexp 'tab) 0))
1559 ;; ACTION: replace TABs by SPACEs.
1560 ((memq 'indentation::space whitespace-style)
1561 (whitespace-replace-action
1562 'untabify rstart rend
1563 (whitespace-indentation-regexp 'space) 0)))
1564 ;; PROBLEM 3: SPACEs or TABs at eol
1565 ;; ACTION: remove all SPACEs or TABs at eol
1566 (when (memq 'trailing whitespace-style)
1567 (whitespace-replace-action
1568 'delete-region rstart rend
1569 whitespace-trailing-regexp 1))
1570 ;; PROBLEM 4: 8 or more SPACEs after TAB
1571 (cond
1572 ;; ACTION: replace 8 or more SPACEs by TABs, if
1573 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1574 ;; by SPACEs.
1575 ((memq 'space-after-tab whitespace-style)
1576 (whitespace-replace-action
1577 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1578 rstart rend (whitespace-space-after-tab-regexp) 1))
1579 ;; ACTION: replace 8 or more SPACEs by TABs.
1580 ((memq 'space-after-tab::tab whitespace-style)
1581 (whitespace-replace-action
1582 'tabify rstart rend
1583 (whitespace-space-after-tab-regexp 'tab) 1))
1584 ;; ACTION: replace TABs by SPACEs.
1585 ((memq 'space-after-tab::space whitespace-style)
1586 (whitespace-replace-action
1587 'untabify rstart rend
1588 (whitespace-space-after-tab-regexp 'space) 1)))
1589 ;; PROBLEM 2: SPACEs before TAB
1590 (cond
1591 ;; ACTION: replace SPACEs before TAB by TABs, if
1592 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1593 ;; by SPACEs.
1594 ((memq 'space-before-tab whitespace-style)
1595 (whitespace-replace-action
1596 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1597 rstart rend whitespace-space-before-tab-regexp
1598 (if whitespace-indent-tabs-mode 1 2)))
1599 ;; ACTION: replace SPACEs before TAB by TABs.
1600 ((memq 'space-before-tab::tab whitespace-style)
1601 (whitespace-replace-action
1602 'tabify rstart rend
1603 whitespace-space-before-tab-regexp 1))
1604 ;; ACTION: replace TABs by SPACEs.
1605 ((memq 'space-before-tab::space whitespace-style)
1606 (whitespace-replace-action
1607 'untabify rstart rend
1608 whitespace-space-before-tab-regexp 2)))))
1609 (set-marker rend nil)))) ; point marker to nowhere
1612 (defun whitespace-replace-action (action rstart rend regexp index)
1613 "Do ACTION in the string matched by REGEXP between RSTART and REND.
1615 INDEX is the level group matched by REGEXP and used by ACTION.
1617 See also `tab-width'."
1618 (goto-char rstart)
1619 (while (re-search-forward regexp rend t)
1620 (goto-char (match-end index))
1621 (funcall action (match-beginning index) (match-end index))))
1624 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1625 ;;;; User command - report
1628 (defun whitespace-regexp (regexp &optional kind)
1629 "Return REGEXP depending on `whitespace-indent-tabs-mode'."
1630 (cond
1631 ((or (eq kind 'tab)
1632 whitespace-indent-tabs-mode)
1633 (format (car regexp) whitespace-tab-width))
1634 ((or (eq kind 'space)
1635 (not whitespace-indent-tabs-mode))
1636 (cdr regexp))))
1639 (defun whitespace-indentation-regexp (&optional kind)
1640 "Return the indentation regexp depending on `whitespace-indent-tabs-mode'."
1641 (whitespace-regexp whitespace-indentation-regexp kind))
1644 (defun whitespace-space-after-tab-regexp (&optional kind)
1645 "Return the space-after-tab regexp depending on `whitespace-indent-tabs-mode'."
1646 (whitespace-regexp whitespace-space-after-tab-regexp kind))
1649 (defconst whitespace-report-list
1650 (list
1651 (cons 'empty whitespace-empty-at-bob-regexp)
1652 (cons 'empty whitespace-empty-at-eob-regexp)
1653 (cons 'trailing whitespace-trailing-regexp)
1654 (cons 'indentation nil)
1655 (cons 'indentation::tab nil)
1656 (cons 'indentation::space nil)
1657 (cons 'space-before-tab whitespace-space-before-tab-regexp)
1658 (cons 'space-before-tab::tab whitespace-space-before-tab-regexp)
1659 (cons 'space-before-tab::space whitespace-space-before-tab-regexp)
1660 (cons 'space-after-tab nil)
1661 (cons 'space-after-tab::tab nil)
1662 (cons 'space-after-tab::space nil)
1664 "List of whitespace bogus symbol and corresponding regexp.")
1667 (defconst whitespace-report-text
1668 '( ;; `indent-tabs-mode' has non-nil value
1670 Whitespace Report
1672 Current Setting Whitespace Problem
1674 empty [] [] empty lines at beginning of buffer
1675 empty [] [] empty lines at end of buffer
1676 trailing [] [] SPACEs or TABs at end of line
1677 indentation [] [] 8 or more SPACEs at beginning of line
1678 indentation::tab [] [] 8 or more SPACEs at beginning of line
1679 indentation::space [] [] TABs at beginning of line
1680 space-before-tab [] [] SPACEs before TAB
1681 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1682 space-before-tab::space [] [] SPACEs before TAB: TABs
1683 space-after-tab [] [] 8 or more SPACEs after TAB
1684 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1685 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1687 indent-tabs-mode =
1688 tab-width = \n\n"
1689 . ;; `indent-tabs-mode' has nil value
1691 Whitespace Report
1693 Current Setting Whitespace Problem
1695 empty [] [] empty lines at beginning of buffer
1696 empty [] [] empty lines at end of buffer
1697 trailing [] [] SPACEs or TABs at end of line
1698 indentation [] [] TABs at beginning of line
1699 indentation::tab [] [] 8 or more SPACEs at beginning of line
1700 indentation::space [] [] TABs at beginning of line
1701 space-before-tab [] [] SPACEs before TAB
1702 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1703 space-before-tab::space [] [] SPACEs before TAB: TABs
1704 space-after-tab [] [] 8 or more SPACEs after TAB
1705 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1706 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1708 indent-tabs-mode =
1709 tab-width = \n\n")
1710 "Text for whitespace bogus report.
1712 It is a cons of strings, where the car part is used when
1713 `indent-tabs-mode' is non-nil, and the cdr part is used when
1714 `indent-tabs-mode' is nil.")
1717 (defconst whitespace-report-buffer-name "*Whitespace Report*"
1718 "The buffer name for whitespace bogus report.")
1721 ;;;###autoload
1722 (defun whitespace-report (&optional force report-if-bogus)
1723 "Report some whitespace problems in buffer.
1725 Return nil if there is no whitespace problem; otherwise, return
1726 non-nil.
1728 If FORCE is non-nil or \\[universal-argument] was pressed just
1729 before calling `whitespace-report' interactively, it forces
1730 `whitespace-style' to have:
1732 empty
1733 trailing
1734 indentation
1735 space-before-tab
1736 space-after-tab
1738 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1739 whitespace problems in buffer.
1741 Report if some of the following whitespace problems exist:
1743 * If `indent-tabs-mode' is non-nil:
1744 empty 1. empty lines at beginning of buffer.
1745 empty 2. empty lines at end of buffer.
1746 trailing 3. SPACEs or TABs at end of line.
1747 indentation 4. 8 or more SPACEs at beginning of line.
1748 space-before-tab 5. SPACEs before TAB.
1749 space-after-tab 6. 8 or more SPACEs after TAB.
1751 * If `indent-tabs-mode' is nil:
1752 empty 1. empty lines at beginning of buffer.
1753 empty 2. empty lines at end of buffer.
1754 trailing 3. SPACEs or TABs at end of line.
1755 indentation 4. TABS at beginning of line.
1756 space-before-tab 5. SPACEs before TAB.
1757 space-after-tab 6. 8 or more SPACEs after TAB.
1759 See `whitespace-style' for documentation.
1760 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1761 cleaning up these problems."
1762 (interactive (list current-prefix-arg))
1763 (whitespace-report-region (point-min) (point-max)
1764 force report-if-bogus))
1767 ;;;###autoload
1768 (defun whitespace-report-region (start end &optional force report-if-bogus)
1769 "Report some whitespace problems in a region.
1771 Return nil if there is no whitespace problem; otherwise, return
1772 non-nil.
1774 If FORCE is non-nil or \\[universal-argument] was pressed just
1775 before calling `whitespace-report-region' interactively, it
1776 forces `whitespace-style' to have:
1778 empty
1779 indentation
1780 space-before-tab
1781 trailing
1782 space-after-tab
1784 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1785 whitespace problems in buffer.
1787 Report if some of the following whitespace problems exist:
1789 * If `indent-tabs-mode' is non-nil:
1790 empty 1. empty lines at beginning of buffer.
1791 empty 2. empty lines at end of buffer.
1792 trailing 3. SPACEs or TABs at end of line.
1793 indentation 4. 8 or more SPACEs at beginning of line.
1794 space-before-tab 5. SPACEs before TAB.
1795 space-after-tab 6. 8 or more SPACEs after TAB.
1797 * If `indent-tabs-mode' is nil:
1798 empty 1. empty lines at beginning of buffer.
1799 empty 2. empty lines at end of buffer.
1800 trailing 3. SPACEs or TABs at end of line.
1801 indentation 4. TABS at beginning of line.
1802 space-before-tab 5. SPACEs before TAB.
1803 space-after-tab 6. 8 or more SPACEs after TAB.
1805 See `whitespace-style' for documentation.
1806 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1807 cleaning up these problems."
1808 (interactive "r")
1809 (setq force (or current-prefix-arg force))
1810 (save-excursion
1811 (save-match-data
1812 (let* ((has-bogus nil)
1813 (rstart (min start end))
1814 (rend (max start end))
1815 (bogus-list
1816 (mapcar
1817 #'(lambda (option)
1818 (when force
1819 (add-to-list 'whitespace-style (car option)))
1820 (goto-char rstart)
1821 (let ((regexp
1822 (cond
1823 ((eq (car option) 'indentation)
1824 (whitespace-indentation-regexp))
1825 ((eq (car option) 'indentation::tab)
1826 (whitespace-indentation-regexp 'tab))
1827 ((eq (car option) 'indentation::space)
1828 (whitespace-indentation-regexp 'space))
1829 ((eq (car option) 'space-after-tab)
1830 (whitespace-space-after-tab-regexp))
1831 ((eq (car option) 'space-after-tab::tab)
1832 (whitespace-space-after-tab-regexp 'tab))
1833 ((eq (car option) 'space-after-tab::space)
1834 (whitespace-space-after-tab-regexp 'space))
1836 (cdr option)))))
1837 (and (re-search-forward regexp rend t)
1838 (setq has-bogus t))))
1839 whitespace-report-list)))
1840 (when (if report-if-bogus has-bogus t)
1841 (whitespace-kill-buffer whitespace-report-buffer-name)
1842 ;; `whitespace-indent-tabs-mode' is local to current buffer
1843 ;; `whitespace-tab-width' is local to current buffer
1844 (let ((ws-indent-tabs-mode whitespace-indent-tabs-mode)
1845 (ws-tab-width whitespace-tab-width))
1846 (with-current-buffer (get-buffer-create
1847 whitespace-report-buffer-name)
1848 (erase-buffer)
1849 (insert (if ws-indent-tabs-mode
1850 (car whitespace-report-text)
1851 (cdr whitespace-report-text)))
1852 (goto-char (point-min))
1853 (forward-line 3)
1854 (dolist (option whitespace-report-list)
1855 (forward-line 1)
1856 (whitespace-mark-x
1857 27 (memq (car option) whitespace-style))
1858 (whitespace-mark-x 7 (car bogus-list))
1859 (setq bogus-list (cdr bogus-list)))
1860 (forward-line 1)
1861 (whitespace-insert-value ws-indent-tabs-mode)
1862 (whitespace-insert-value ws-tab-width)
1863 (when has-bogus
1864 (goto-char (point-max))
1865 (insert " Type `M-x whitespace-cleanup'"
1866 " to cleanup the buffer.\n\n"
1867 " Type `M-x whitespace-cleanup-region'"
1868 " to cleanup a region.\n\n"))
1869 (whitespace-display-window (current-buffer)))))
1870 has-bogus))))
1873 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1874 ;;;; Internal functions
1877 (defvar whitespace-font-lock-mode nil
1878 "Used to remember whether a buffer had font lock mode on or not.")
1880 (defvar whitespace-font-lock nil
1881 "Used to remember whether a buffer initially had font lock on or not.")
1883 (defvar whitespace-font-lock-keywords nil
1884 "Used to save locally `font-lock-keywords' value.")
1887 (defconst whitespace-help-text
1889 Whitespace Toggle Options
1891 FACES
1892 [] t - toggle TAB visualization
1893 [] s - toggle SPACE and HARD SPACE visualization
1894 [] r - toggle trailing blanks visualization
1895 [] l - toggle \"long lines\" visualization
1896 [] L - toggle \"long lines\" tail visualization
1897 [] n - toggle NEWLINE visualization
1898 [] e - toggle empty line at bob and/or eob visualization
1899 [] C-i - toggle indentation SPACEs visualization (via `indent-tabs-mode')
1900 [] I - toggle indentation SPACEs visualization
1901 [] i - toggle indentation TABs visualization
1902 [] C-a - toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1903 [] A - toggle SPACEs after TAB: SPACEs visualization
1904 [] a - toggle SPACEs after TAB: TABs visualization
1905 [] C-b - toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1906 [] B - toggle SPACEs before TAB: SPACEs visualization
1907 [] b - toggle SPACEs before TAB: TABs visualization
1909 DISPLAY TABLE
1910 [] T - toggle TAB visualization
1911 [] S - toggle SPACE and HARD SPACE visualization
1912 [] N - toggle NEWLINE visualization
1914 x - restore `whitespace-style' value
1916 ? - display this text\n\n"
1917 "Text for whitespace toggle options.")
1920 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1921 "The buffer name for whitespace toggle options.")
1924 (defun whitespace-insert-value (value)
1925 "Insert VALUE at column 20 of next line."
1926 (forward-line 1)
1927 (move-to-column 20 t)
1928 (insert (format "%s" value)))
1931 (defun whitespace-mark-x (nchars condition)
1932 "Insert the mark ('X' or ' ') after NCHARS depending on CONDITION."
1933 (forward-char nchars)
1934 (insert (if condition "X" " ")))
1937 (defun whitespace-insert-option-mark (the-list the-value)
1938 "Insert the option mark ('X' or ' ') in toggle options buffer."
1939 (goto-char (point-min))
1940 (forward-line 2)
1941 (dolist (sym the-list)
1942 (if (eq sym 'help-newline)
1943 (forward-line 2)
1944 (forward-line 1)
1945 (whitespace-mark-x 2 (memq sym the-value)))))
1948 (defun whitespace-help-on (style)
1949 "Display the whitespace toggle options."
1950 (unless (get-buffer whitespace-help-buffer-name)
1951 (delete-other-windows)
1952 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
1953 (save-excursion
1954 (set-buffer buffer)
1955 (erase-buffer)
1956 (insert whitespace-help-text)
1957 (whitespace-insert-option-mark
1958 whitespace-style-value-list style)
1959 (whitespace-display-window buffer)))))
1962 (defun whitespace-display-window (buffer)
1963 "Display BUFFER in a new window."
1964 (goto-char (point-min))
1965 (set-buffer-modified-p nil)
1966 (let ((size (- (window-height)
1967 (max window-min-height
1968 (1+ (count-lines (point-min)
1969 (point-max)))))))
1970 (when (<= size 0)
1971 (kill-buffer buffer)
1972 (error "Frame height is too small; \
1973 can't split window to display whitespace toggle options"))
1974 (set-window-buffer (split-window nil size) buffer)))
1977 (defun whitespace-kill-buffer (buffer-name)
1978 "Kill buffer BUFFER-NAME and windows related with it."
1979 (let ((buffer (get-buffer buffer-name)))
1980 (when buffer
1981 (delete-windows-on buffer)
1982 (kill-buffer buffer))))
1985 (defun whitespace-help-off ()
1986 "Remove the buffer and window of the whitespace toggle options."
1987 (whitespace-kill-buffer whitespace-help-buffer-name))
1990 (defun whitespace-interactive-char (local-p)
1991 "Interactive function to read a char and return a symbol.
1993 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1994 uses a global context.
1996 It accepts one of the following chars:
1998 CHAR MEANING
1999 (VIA FACES)
2000 t toggle TAB visualization
2001 s toggle SPACE and HARD SPACE visualization
2002 r toggle trailing blanks visualization
2003 l toggle \"long lines\" visualization
2004 L toggle \"long lines\" tail visualization
2005 n toggle NEWLINE visualization
2006 e toggle empty line at bob and/or eob visualization
2007 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
2008 I toggle indentation SPACEs visualization
2009 i toggle indentation TABs visualization
2010 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
2011 A toggle SPACEs after TAB: SPACEs visualization
2012 a toggle SPACEs after TAB: TABs visualization
2013 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
2014 B toggle SPACEs before TAB: SPACEs visualization
2015 b toggle SPACEs before TAB: TABs visualization
2017 (VIA DISPLAY TABLE)
2018 T toggle TAB visualization
2019 S toggle SPACE and HARD SPACE visualization
2020 N toggle NEWLINE visualization
2022 x restore `whitespace-style' value
2023 ? display brief help
2025 See also `whitespace-toggle-option-alist'."
2026 (let* ((is-off (not (if local-p
2027 whitespace-mode
2028 global-whitespace-mode)))
2029 (style (cond (is-off whitespace-style) ; use default value
2030 (local-p whitespace-active-style)
2031 (t whitespace-toggle-style)))
2032 (prompt
2033 (format "Whitespace Toggle %s (type ? for further options)-"
2034 (if local-p "Local" "Global")))
2035 ch sym)
2036 ;; read a valid option and get the corresponding symbol
2037 (save-window-excursion
2038 (condition-case data
2039 (progn
2040 (while
2041 ;; while condition
2042 (progn
2043 (setq ch (read-char prompt))
2044 (not
2045 (setq sym
2046 (cdr
2047 (assq ch whitespace-toggle-option-alist)))))
2048 ;; while body
2049 (if (eq ch ?\?)
2050 (whitespace-help-on style)
2051 (ding)))
2052 (whitespace-help-off)
2053 (message " ")) ; clean echo area
2054 ;; handler
2055 ((quit error)
2056 (whitespace-help-off)
2057 (error (error-message-string data)))))
2058 (list sym))) ; return the apropriate symbol
2061 (defun whitespace-toggle-list (local-p arg the-list)
2062 "Toggle options in THE-LIST based on list ARG.
2064 If LOCAL-P is non-nil, it uses a local context; otherwise, it
2065 uses a global context.
2067 ARG is a list of options to be toggled.
2069 THE-LIST is a list of options. This list will be toggled and the
2070 resultant list will be returned."
2071 (unless (if local-p whitespace-mode global-whitespace-mode)
2072 (setq the-list whitespace-style))
2073 (setq the-list (copy-sequence the-list)) ; keep original list
2074 (dolist (sym (if (listp arg) arg (list arg)))
2075 (cond
2076 ;; ignore help value
2077 ((eq sym 'help-newline))
2078 ;; restore default values
2079 ((eq sym 'whitespace-style)
2080 (setq the-list whitespace-style))
2081 ;; toggle valid values
2082 ((memq sym whitespace-style-value-list)
2083 (setq the-list (if (memq sym the-list)
2084 (delq sym the-list)
2085 (cons sym the-list))))))
2086 the-list)
2089 (defvar whitespace-display-table nil
2090 "Used to save a local display table.")
2092 (defvar whitespace-display-table-was-local nil
2093 "Used to remember whether a buffer initially had a local display table.")
2096 (defun whitespace-turn-on ()
2097 "Turn on whitespace visualization."
2098 ;; prepare local hooks
2099 (add-hook 'write-file-functions 'whitespace-write-file-hook nil t)
2100 ;; create whitespace local buffer environment
2101 (set (make-local-variable 'whitespace-font-lock-mode) nil)
2102 (set (make-local-variable 'whitespace-font-lock) nil)
2103 (set (make-local-variable 'whitespace-font-lock-keywords) nil)
2104 (set (make-local-variable 'whitespace-display-table) nil)
2105 (set (make-local-variable 'whitespace-display-table-was-local) nil)
2106 (set (make-local-variable 'whitespace-active-style)
2107 (if (listp whitespace-style)
2108 whitespace-style
2109 (list whitespace-style)))
2110 (set (make-local-variable 'whitespace-indent-tabs-mode)
2111 indent-tabs-mode)
2112 (set (make-local-variable 'whitespace-tab-width)
2113 tab-width)
2114 ;; turn on whitespace
2115 (when whitespace-active-style
2116 (whitespace-color-on)
2117 (whitespace-display-char-on)))
2120 (defun whitespace-turn-off ()
2121 "Turn off whitespace visualization."
2122 (remove-hook 'write-file-functions 'whitespace-write-file-hook t)
2123 (when whitespace-active-style
2124 (whitespace-color-off)
2125 (whitespace-display-char-off)))
2128 (defun whitespace-style-face-p ()
2129 "Return t if there is some visualization via face."
2130 (or (memq 'tabs whitespace-active-style)
2131 (memq 'spaces whitespace-active-style)
2132 (memq 'trailing whitespace-active-style)
2133 (memq 'lines whitespace-active-style)
2134 (memq 'lines-tail whitespace-active-style)
2135 (memq 'newline whitespace-active-style)
2136 (memq 'empty whitespace-active-style)
2137 (memq 'indentation whitespace-active-style)
2138 (memq 'indentation::tab whitespace-active-style)
2139 (memq 'indentation::space whitespace-active-style)
2140 (memq 'space-after-tab whitespace-active-style)
2141 (memq 'space-after-tab::tab whitespace-active-style)
2142 (memq 'space-after-tab::space whitespace-active-style)
2143 (memq 'space-before-tab whitespace-active-style)
2144 (memq 'space-before-tab::tab whitespace-active-style)
2145 (memq 'space-before-tab::space whitespace-active-style)))
2148 (defun whitespace-color-on ()
2149 "Turn on color visualization."
2150 (when (whitespace-style-face-p)
2151 (unless whitespace-font-lock
2152 (setq whitespace-font-lock t
2153 whitespace-font-lock-keywords
2154 (copy-sequence font-lock-keywords)))
2155 ;; save current point and refontify when necessary
2156 (set (make-local-variable 'whitespace-point)
2157 (point))
2158 (set (make-local-variable 'whitespace-font-lock-refontify)
2159 nil)
2160 (add-hook 'post-command-hook #'whitespace-post-command-hook nil t)
2161 ;; turn off font lock
2162 (set (make-local-variable 'whitespace-font-lock-mode)
2163 font-lock-mode)
2164 (font-lock-mode 0)
2165 ;; add whitespace-mode color into font lock
2166 (when (memq 'spaces whitespace-active-style)
2167 (font-lock-add-keywords
2169 (list
2170 ;; Show SPACEs
2171 (list #'whitespace-space-regexp 1 whitespace-space t)
2172 ;; Show HARD SPACEs
2173 (list whitespace-hspace-regexp 1 whitespace-hspace t))
2175 (when (memq 'tabs whitespace-active-style)
2176 (font-lock-add-keywords
2178 (list
2179 ;; Show TABs
2180 (list #'whitespace-tab-regexp 1 whitespace-tab t))
2182 (when (memq 'trailing whitespace-active-style)
2183 (font-lock-add-keywords
2185 (list
2186 ;; Show trailing blanks
2187 (list #'whitespace-trailing-regexp 1 whitespace-trailing t))
2189 (when (or (memq 'lines whitespace-active-style)
2190 (memq 'lines-tail whitespace-active-style))
2191 (font-lock-add-keywords
2193 (list
2194 ;; Show "long" lines
2195 (list
2196 (format
2197 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
2198 whitespace-tab-width (1- whitespace-tab-width)
2199 (/ whitespace-line-column whitespace-tab-width)
2200 (let ((rem (% whitespace-line-column whitespace-tab-width)))
2201 (if (zerop rem)
2203 (format ".\\{%d\\}" rem))))
2204 (if (memq 'lines whitespace-active-style)
2205 0 ; whole line
2206 2) ; line tail
2207 whitespace-line t))
2209 (cond
2210 ((memq 'space-before-tab whitespace-active-style)
2211 (font-lock-add-keywords
2213 (list
2214 ;; Show SPACEs before TAB (indent-tabs-mode)
2215 (list whitespace-space-before-tab-regexp
2216 (if whitespace-indent-tabs-mode 1 2)
2217 whitespace-space-before-tab t))
2219 ((memq 'space-before-tab::tab whitespace-active-style)
2220 (font-lock-add-keywords
2222 (list
2223 ;; Show SPACEs before TAB (SPACEs)
2224 (list whitespace-space-before-tab-regexp
2225 1 whitespace-space-before-tab t))
2227 ((memq 'space-before-tab::space whitespace-active-style)
2228 (font-lock-add-keywords
2230 (list
2231 ;; Show SPACEs before TAB (TABs)
2232 (list whitespace-space-before-tab-regexp
2233 2 whitespace-space-before-tab t))
2234 t)))
2235 (cond
2236 ((memq 'indentation whitespace-active-style)
2237 (font-lock-add-keywords
2239 (list
2240 ;; Show indentation SPACEs (indent-tabs-mode)
2241 (list (whitespace-indentation-regexp)
2242 1 whitespace-indentation t))
2244 ((memq 'indentation::tab whitespace-active-style)
2245 (font-lock-add-keywords
2247 (list
2248 ;; Show indentation SPACEs (SPACEs)
2249 (list (whitespace-indentation-regexp 'tab)
2250 1 whitespace-indentation t))
2252 ((memq 'indentation::space whitespace-active-style)
2253 (font-lock-add-keywords
2255 (list
2256 ;; Show indentation SPACEs (TABs)
2257 (list (whitespace-indentation-regexp 'space)
2258 1 whitespace-indentation t))
2259 t)))
2260 (when (memq 'empty whitespace-active-style)
2261 (font-lock-add-keywords
2263 (list
2264 ;; Show empty lines at beginning of buffer
2265 (list #'whitespace-empty-at-bob-regexp
2266 1 whitespace-empty t))
2268 (font-lock-add-keywords
2270 (list
2271 ;; Show empty lines at end of buffer
2272 (list #'whitespace-empty-at-eob-regexp
2273 1 whitespace-empty t))
2275 (cond
2276 ((memq 'space-after-tab whitespace-active-style)
2277 (font-lock-add-keywords
2279 (list
2280 ;; Show SPACEs after TAB (indent-tabs-mode)
2281 (list (whitespace-space-after-tab-regexp)
2282 1 whitespace-space-after-tab t))
2284 ((memq 'space-after-tab::tab whitespace-active-style)
2285 (font-lock-add-keywords
2287 (list
2288 ;; Show SPACEs after TAB (SPACEs)
2289 (list (whitespace-space-after-tab-regexp 'tab)
2290 1 whitespace-space-after-tab t))
2292 ((memq 'space-after-tab::space whitespace-active-style)
2293 (font-lock-add-keywords
2295 (list
2296 ;; Show SPACEs after TAB (TABs)
2297 (list (whitespace-space-after-tab-regexp 'space)
2298 1 whitespace-space-after-tab t))
2299 t)))
2300 ;; now turn on font lock and highlight blanks
2301 (font-lock-mode 1)))
2304 (defun whitespace-color-off ()
2305 "Turn off color visualization."
2306 ;; turn off font lock
2307 (when (whitespace-style-face-p)
2308 (font-lock-mode 0)
2309 (remove-hook 'post-command-hook #'whitespace-post-command-hook)
2310 (when whitespace-font-lock
2311 (setq whitespace-font-lock nil
2312 font-lock-keywords whitespace-font-lock-keywords))
2313 ;; restore original font lock state
2314 (font-lock-mode whitespace-font-lock-mode)))
2317 (defun whitespace-trailing-regexp (limit)
2318 "Match trailing spaces which do not contain the point at end of line."
2319 (let ((status t))
2320 (while (if (re-search-forward whitespace-trailing-regexp limit t)
2321 (save-match-data
2322 (= whitespace-point (match-end 1))) ;; loop if point at eol
2323 (setq status nil))) ;; end of buffer
2324 status))
2327 (defun whitespace-empty-at-bob-regexp (limit)
2328 "Match spaces at beginning of buffer which do not contain the point at \
2329 beginning of buffer."
2330 (and (/= whitespace-point 1)
2331 (re-search-forward whitespace-empty-at-bob-regexp limit t)))
2334 (defun whitespace-empty-at-eob-regexp (limit)
2335 "Match spaces at end of buffer which do not contain the point at end of \
2336 buffer."
2337 (and (/= whitespace-point (1+ (buffer-size)))
2338 (re-search-forward whitespace-empty-at-eob-regexp limit t)))
2341 (defun whitespace-space-regexp (limit)
2342 "Match spaces."
2343 (setq whitespace-font-lock-refontify t)
2344 (re-search-forward whitespace-space-regexp limit t))
2347 (defun whitespace-tab-regexp (limit)
2348 "Match tabs."
2349 (setq whitespace-font-lock-refontify t)
2350 (re-search-forward whitespace-tab-regexp limit t))
2353 (defun whitespace-post-command-hook ()
2354 "Save current point into `whitespace-point' variable.
2355 Also refontify when necessary."
2356 (setq whitespace-point (point))
2357 (let ((refontify (or (eolp) ; end of line
2358 (= whitespace-point 1)))) ; beginning of buffer
2359 (when (or whitespace-font-lock-refontify refontify)
2360 (setq whitespace-font-lock-refontify refontify)
2361 (jit-lock-refontify))))
2364 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2365 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
2368 (defun whitespace-style-mark-p ()
2369 "Return t if there is some visualization via display table."
2370 (or (memq 'tab-mark whitespace-active-style)
2371 (memq 'space-mark whitespace-active-style)
2372 (memq 'newline-mark whitespace-active-style)))
2375 (defsubst whitespace-char-valid-p (char)
2376 ;; This check should be improved!!!
2377 (or (< char 256)
2378 (characterp char)))
2381 (defun whitespace-display-vector-p (vec)
2382 "Return true if every character in vector VEC can be displayed."
2383 (let ((i (length vec)))
2384 (when (> i 0)
2385 (while (and (>= (setq i (1- i)) 0)
2386 (whitespace-char-valid-p (aref vec i))))
2387 (< i 0))))
2390 (defun whitespace-display-char-on ()
2391 "Turn on character display mapping."
2392 (when (and whitespace-display-mappings
2393 (whitespace-style-mark-p))
2394 (let (vecs vec)
2395 ;; Remember whether a buffer has a local display table.
2396 (unless whitespace-display-table-was-local
2397 (setq whitespace-display-table-was-local t
2398 whitespace-display-table
2399 (copy-sequence buffer-display-table)))
2400 (unless buffer-display-table
2401 (setq buffer-display-table (make-display-table)))
2402 (dolist (entry whitespace-display-mappings)
2403 ;; check if it is to display this mark
2404 (when (memq (car entry) whitespace-style)
2405 ;; Get a displayable mapping.
2406 (setq vecs (cddr entry))
2407 (while (and vecs
2408 (not (whitespace-display-vector-p (car vecs))))
2409 (setq vecs (cdr vecs)))
2410 ;; Display a valid mapping.
2411 (when vecs
2412 (setq vec (copy-sequence (car vecs)))
2413 ;; NEWLINE char
2414 (when (and (eq (cadr entry) ?\n)
2415 (memq 'newline whitespace-active-style))
2416 ;; Only insert face bits on NEWLINE char mapping to avoid
2417 ;; obstruction of other faces like TABs and (HARD) SPACEs
2418 ;; faces, font-lock faces, etc.
2419 (dotimes (i (length vec))
2420 (or (eq (aref vec i) ?\n)
2421 (aset vec i
2422 (make-glyph-code (aref vec i)
2423 whitespace-newline)))))
2424 ;; Display mapping
2425 (aset buffer-display-table (cadr entry) vec)))))))
2428 (defun whitespace-display-char-off ()
2429 "Turn off character display mapping."
2430 (and whitespace-display-mappings
2431 (whitespace-style-mark-p)
2432 whitespace-display-table-was-local
2433 (setq whitespace-display-table-was-local nil
2434 buffer-display-table whitespace-display-table)))
2437 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2438 ;;;; Hook
2441 (defun whitespace-action-when-on ()
2442 "Action to be taken always when local whitespace is turned on."
2443 (cond ((memq 'cleanup whitespace-action)
2444 (whitespace-cleanup))
2445 ((memq 'report-on-bogus whitespace-action)
2446 (whitespace-report nil t))))
2449 (defun whitespace-write-file-hook ()
2450 "Action to be taken when buffer is written.
2451 It should be added buffer-locally to `write-file-functions'."
2452 (cond ((memq 'auto-cleanup whitespace-action)
2453 (whitespace-cleanup))
2454 ((memq 'abort-on-bogus whitespace-action)
2455 (when (whitespace-report nil t)
2456 (error "Abort write due to whitespace problems in %s"
2457 (buffer-name)))))
2458 nil) ; continue hook processing
2461 (defun whitespace-warn-read-only (msg)
2462 "Warn if buffer is read-only."
2463 (when (memq 'warn-if-read-only whitespace-action)
2464 (message "Can't %s: %s is read-only" msg (buffer-name))))
2467 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2470 (defun whitespace-unload-function ()
2471 "Unload the whitespace library."
2472 (global-whitespace-mode -1)
2473 ;; be sure all local whitespace mode is turned off
2474 (save-current-buffer
2475 (dolist (buf (buffer-list))
2476 (set-buffer buf)
2477 (whitespace-mode -1)))
2478 nil) ; continue standard unloading
2481 (provide 'whitespace)
2484 (run-hooks 'whitespace-load-hook)
2487 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
2488 ;;; whitespace.el ends here