Regenerate ldefs-boot.el.
[emacs.git] / lisp / whitespace.el
blob183698a28f3676aad829b7f0eb0468cfcad0d8f4
1 ;;; whitespace.el --- minor mode to visualize TAB, (HARD) SPACE, NEWLINE
3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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.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 ;; 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)
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 which 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 which 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 they 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.
1026 See also `whitespace-style', `whitespace-newline' and
1027 `whitespace-display-mappings'."
1028 :lighter " ws"
1029 :init-value nil
1030 :global nil
1031 :group 'whitespace
1032 (cond
1033 (noninteractive ; running a batch job
1034 (setq whitespace-mode nil))
1035 (whitespace-mode ; whitespace-mode on
1036 (whitespace-turn-on)
1037 (whitespace-action-when-on))
1038 (t ; whitespace-mode off
1039 (whitespace-turn-off))))
1042 ;;;###autoload
1043 (define-minor-mode whitespace-newline-mode
1044 "Toggle NEWLINE minor mode visualization (\"nl\" on modeline).
1046 If ARG is null, toggle NEWLINE visualization.
1047 If ARG is a number greater than zero, turn on visualization;
1048 otherwise, turn off visualization.
1050 Use `whitespace-newline-mode' only for NEWLINE visualization
1051 exclusively. For other visualizations, including NEWLINE
1052 visualization together with (HARD) SPACEs and/or TABs, please,
1053 use `whitespace-mode'.
1055 See also `whitespace-newline' and `whitespace-display-mappings'."
1056 :lighter " nl"
1057 :init-value nil
1058 :global nil
1059 :group 'whitespace
1060 (let ((whitespace-style '(newline-mark newline)))
1061 (whitespace-mode whitespace-newline-mode)
1062 ;; sync states (running a batch job)
1063 (setq whitespace-newline-mode whitespace-mode)))
1066 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1067 ;;;; User commands - Global mode
1070 ;;;###autoload
1071 (define-minor-mode global-whitespace-mode
1072 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
1074 If ARG is null, toggle whitespace visualization.
1075 If ARG is a number greater than zero, turn on visualization;
1076 otherwise, turn off visualization.
1078 See also `whitespace-style', `whitespace-newline' and
1079 `whitespace-display-mappings'."
1080 :lighter " WS"
1081 :init-value nil
1082 :global t
1083 :group 'whitespace
1084 (cond
1085 (noninteractive ; running a batch job
1086 (setq global-whitespace-mode nil))
1087 (global-whitespace-mode ; global-whitespace-mode on
1088 (save-excursion
1089 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1090 (dolist (buffer (buffer-list)) ; adjust all local mode
1091 (set-buffer buffer)
1092 (unless whitespace-mode
1093 (whitespace-turn-on-if-enabled)))))
1094 (t ; global-whitespace-mode off
1095 (save-excursion
1096 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1097 (dolist (buffer (buffer-list)) ; adjust all local mode
1098 (set-buffer buffer)
1099 (unless whitespace-mode
1100 (whitespace-turn-off)))))))
1103 (defun whitespace-turn-on-if-enabled ()
1104 (when (cond
1105 ((eq whitespace-global-modes t))
1106 ((listp whitespace-global-modes)
1107 (if (eq (car-safe whitespace-global-modes) 'not)
1108 (not (memq major-mode (cdr whitespace-global-modes)))
1109 (memq major-mode whitespace-global-modes)))
1110 (t nil))
1111 (let (inhibit-quit)
1112 ;; Don't turn on whitespace mode if...
1114 ;; ...we don't have a display (we're running a batch job)
1115 noninteractive
1116 ;; ...or if the buffer is invisible (name starts with a space)
1117 (eq (aref (buffer-name) 0) ?\ )
1118 ;; ...or if the buffer is temporary (name starts with *)
1119 (and (eq (aref (buffer-name) 0) ?*)
1120 ;; except the scratch buffer.
1121 (not (string= (buffer-name) "*scratch*")))
1122 ;; Otherwise, turn on whitespace mode.
1123 (whitespace-turn-on)))))
1126 ;;;###autoload
1127 (define-minor-mode global-whitespace-newline-mode
1128 "Toggle NEWLINE global minor mode visualization (\"NL\" on modeline).
1130 If ARG is null, toggle NEWLINE visualization.
1131 If ARG is a number greater than zero, turn on visualization;
1132 otherwise, turn off visualization.
1134 Use `global-whitespace-newline-mode' only for NEWLINE
1135 visualization exclusively. For other visualizations, including
1136 NEWLINE visualization together with (HARD) SPACEs and/or TABs,
1137 please use `global-whitespace-mode'.
1139 See also `whitespace-newline' and `whitespace-display-mappings'."
1140 :lighter " NL"
1141 :init-value nil
1142 :global t
1143 :group 'whitespace
1144 (let ((whitespace-style '(newline-mark newline)))
1145 (global-whitespace-mode global-whitespace-newline-mode)
1146 ;; sync states (running a batch job)
1147 (setq global-whitespace-newline-mode global-whitespace-mode)))
1150 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1151 ;;;; User commands - Toggle
1154 (defconst whitespace-style-value-list
1155 '(tabs
1156 spaces
1157 trailing
1158 lines
1159 lines-tail
1160 newline
1161 empty
1162 indentation
1163 indentation::tab
1164 indentation::space
1165 space-after-tab
1166 space-after-tab::tab
1167 space-after-tab::space
1168 space-before-tab
1169 space-before-tab::tab
1170 space-before-tab::space
1171 help-newline ; value used by `whitespace-insert-option-mark'
1172 tab-mark
1173 space-mark
1174 newline-mark
1176 "List of valid `whitespace-style' values.")
1179 (defconst whitespace-toggle-option-alist
1180 '((?t . tabs)
1181 (?s . spaces)
1182 (?r . trailing)
1183 (?l . lines)
1184 (?L . lines-tail)
1185 (?n . newline)
1186 (?e . empty)
1187 (?\C-i . indentation)
1188 (?I . indentation::tab)
1189 (?i . indentation::space)
1190 (?\C-a . space-after-tab)
1191 (?A . space-after-tab::tab)
1192 (?a . space-after-tab::space)
1193 (?\C-b . space-before-tab)
1194 (?B . space-before-tab::tab)
1195 (?b . space-before-tab::space)
1196 (?T . tab-mark)
1197 (?S . space-mark)
1198 (?N . newline-mark)
1199 (?x . whitespace-style)
1201 "Alist of toggle options.
1203 Each element has the form:
1205 (CHAR . SYMBOL)
1207 Where:
1209 CHAR is a char which the user will have to type.
1211 SYMBOL is a valid symbol associated with CHAR.
1212 See `whitespace-style-value-list'.")
1215 (defvar whitespace-active-style nil
1216 "Used to save locally `whitespace-style' value.")
1218 (defvar whitespace-indent-tabs-mode indent-tabs-mode
1219 "Used to save locally `indent-tabs-mode' value.")
1221 (defvar whitespace-tab-width tab-width
1222 "Used to save locally `tab-width' value.")
1224 (defvar whitespace-point (point)
1225 "Used to save locally current point value.
1226 Used by `whitespace-trailing-regexp' function (which see).")
1228 (defvar whitespace-font-lock-refontify nil
1229 "Used to save locally the font-lock refontify state.
1230 Used by `whitespace-post-command-hook' function (which see).")
1233 ;;;###autoload
1234 (defun whitespace-toggle-options (arg)
1235 "Toggle local `whitespace-mode' options.
1237 If local whitespace-mode is off, toggle the option given by ARG
1238 and turn on local whitespace-mode.
1240 If local whitespace-mode is on, toggle the option given by ARG
1241 and restart local whitespace-mode.
1243 Interactively, it reads one of the following chars:
1245 CHAR MEANING
1246 (VIA FACES)
1247 t toggle TAB visualization
1248 s toggle SPACE and HARD SPACE visualization
1249 r toggle trailing blanks visualization
1250 l toggle \"long lines\" visualization
1251 L toggle \"long lines\" tail visualization
1252 n toggle NEWLINE visualization
1253 e toggle empty line at bob and/or eob visualization
1254 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1255 I toggle indentation SPACEs visualization
1256 i toggle indentation TABs visualization
1257 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1258 A toggle SPACEs after TAB: SPACEs visualization
1259 a toggle SPACEs after TAB: TABs visualization
1260 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1261 B toggle SPACEs before TAB: SPACEs visualization
1262 b toggle SPACEs before TAB: TABs visualization
1264 (VIA DISPLAY TABLE)
1265 T toggle TAB visualization
1266 S toggle SPACEs before TAB visualization
1267 N toggle NEWLINE visualization
1269 x restore `whitespace-style' value
1270 ? display brief help
1272 Non-interactively, ARG should be a symbol or a list of symbols.
1273 The valid symbols are:
1275 tabs toggle TAB visualization
1276 spaces toggle SPACE and HARD SPACE visualization
1277 trailing toggle trailing blanks visualization
1278 lines toggle \"long lines\" visualization
1279 lines-tail toggle \"long lines\" tail visualization
1280 newline toggle NEWLINE visualization
1281 empty toggle empty line at bob and/or eob visualization
1282 indentation toggle indentation SPACEs visualization
1283 indentation::tab toggle indentation SPACEs visualization
1284 indentation::space toggle indentation TABs visualization
1285 space-after-tab toggle SPACEs after TAB visualization
1286 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1287 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1288 space-before-tab toggle SPACEs before TAB visualization
1289 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1290 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1292 tab-mark toggle TAB visualization
1293 space-mark toggle SPACEs before TAB visualization
1294 newline-mark toggle NEWLINE visualization
1296 whitespace-style restore `whitespace-style' value
1298 See `whitespace-style' and `indent-tabs-mode' for documentation."
1299 (interactive (whitespace-interactive-char t))
1300 (let ((whitespace-style
1301 (whitespace-toggle-list t arg whitespace-active-style)))
1302 (whitespace-mode 0)
1303 (whitespace-mode 1)))
1306 (defvar whitespace-toggle-style nil
1307 "Used to toggle the global `whitespace-style' value.")
1310 ;;;###autoload
1311 (defun global-whitespace-toggle-options (arg)
1312 "Toggle global `whitespace-mode' options.
1314 If global whitespace-mode is off, toggle the option given by ARG
1315 and turn on global whitespace-mode.
1317 If global whitespace-mode is on, toggle the option given by ARG
1318 and restart global whitespace-mode.
1320 Interactively, it accepts one of the following chars:
1322 CHAR MEANING
1323 (VIA FACES)
1324 t toggle TAB visualization
1325 s toggle SPACE and HARD SPACE visualization
1326 r toggle trailing blanks visualization
1327 l toggle \"long lines\" visualization
1328 L toggle \"long lines\" tail visualization
1329 n toggle NEWLINE visualization
1330 e toggle empty line at bob and/or eob visualization
1331 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1332 I toggle indentation SPACEs visualization
1333 i toggle indentation TABs visualization
1334 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1335 A toggle SPACEs after TAB: SPACEs visualization
1336 a toggle SPACEs after TAB: TABs visualization
1337 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1338 B toggle SPACEs before TAB: SPACEs visualization
1339 b toggle SPACEs before TAB: TABs visualization
1341 (VIA DISPLAY TABLE)
1342 T toggle TAB visualization
1343 S toggle SPACEs before TAB visualization
1344 N toggle NEWLINE visualization
1346 x restore `whitespace-style' value
1347 ? display brief help
1349 Non-interactively, ARG should be a symbol or a list of symbols.
1350 The valid symbols are:
1352 tabs toggle TAB visualization
1353 spaces toggle SPACE and HARD SPACE visualization
1354 trailing toggle trailing blanks visualization
1355 lines toggle \"long lines\" visualization
1356 lines-tail toggle \"long lines\" tail visualization
1357 newline toggle NEWLINE visualization
1358 empty toggle empty line at bob and/or eob visualization
1359 indentation toggle indentation SPACEs visualization
1360 indentation::tab toggle indentation SPACEs visualization
1361 indentation::space toggle indentation TABs visualization
1362 space-after-tab toggle SPACEs after TAB visualization
1363 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1364 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1365 space-before-tab toggle SPACEs before TAB visualization
1366 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1367 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1369 tab-mark toggle TAB visualization
1370 space-mark toggle SPACEs before TAB visualization
1371 newline-mark toggle NEWLINE visualization
1373 whitespace-style restore `whitespace-style' value
1375 See `whitespace-style' and `indent-tabs-mode' for documentation."
1376 (interactive (whitespace-interactive-char nil))
1377 (let ((whitespace-style
1378 (whitespace-toggle-list nil arg whitespace-toggle-style)))
1379 (setq whitespace-toggle-style whitespace-style)
1380 (global-whitespace-mode 0)
1381 (global-whitespace-mode 1)))
1384 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1385 ;;;; User commands - Cleanup
1388 ;;;###autoload
1389 (defun whitespace-cleanup ()
1390 "Cleanup some blank problems in all buffer or at region.
1392 It usually applies to the whole buffer, but in transient mark
1393 mode when the mark is active, it applies to the region. It also
1394 applies to the region when it is not in transient mark mode, the
1395 mark is active and \\[universal-argument] was pressed just before
1396 calling `whitespace-cleanup' interactively.
1398 See also `whitespace-cleanup-region'.
1400 The problems cleaned up are:
1402 1. empty lines at beginning of buffer.
1403 2. empty lines at end of buffer.
1404 If `whitespace-style' includes the value `empty', remove all
1405 empty lines at beginning and/or end of buffer.
1407 3. 8 or more SPACEs at beginning of line.
1408 If `whitespace-style' includes the value `indentation':
1409 replace 8 or more SPACEs at beginning of line by TABs, if
1410 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1411 SPACEs.
1412 If `whitespace-style' includes the value `indentation::tab',
1413 replace 8 or more SPACEs at beginning of line by TABs.
1414 If `whitespace-style' includes the value `indentation::space',
1415 replace TABs by SPACEs.
1417 4. SPACEs before TAB.
1418 If `whitespace-style' includes the value `space-before-tab':
1419 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1420 otherwise, replace TABs by SPACEs.
1421 If `whitespace-style' includes the value
1422 `space-before-tab::tab', replace SPACEs by TABs.
1423 If `whitespace-style' includes the value
1424 `space-before-tab::space', replace TABs by SPACEs.
1426 5. SPACEs or TABs at end of line.
1427 If `whitespace-style' includes the value `trailing', remove
1428 all SPACEs or TABs at end of line.
1430 6. 8 or more SPACEs after TAB.
1431 If `whitespace-style' includes the value `space-after-tab':
1432 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1433 otherwise, replace TABs by SPACEs.
1434 If `whitespace-style' includes the value
1435 `space-after-tab::tab', replace SPACEs by TABs.
1436 If `whitespace-style' includes the value
1437 `space-after-tab::space', replace TABs by SPACEs.
1439 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1440 documentation."
1441 (interactive "@")
1442 (cond
1443 ;; read-only buffer
1444 (buffer-read-only
1445 (whitespace-warn-read-only "cleanup"))
1446 ;; region active
1447 ((and (or transient-mark-mode
1448 current-prefix-arg)
1449 mark-active)
1450 ;; PROBLEMs 1 and 2 are not handled in region
1451 ;; PROBLEM 3: 8 or more SPACEs at bol
1452 ;; PROBLEM 4: SPACEs before TAB
1453 ;; PROBLEM 5: SPACEs or TABs at eol
1454 ;; PROBLEM 6: 8 or more SPACEs after TAB
1455 (whitespace-cleanup-region (region-beginning) (region-end)))
1456 ;; whole buffer
1458 (save-excursion
1459 (save-match-data
1460 ;; PROBLEM 1: empty lines at bob
1461 ;; PROBLEM 2: empty lines at eob
1462 ;; ACTION: remove all empty lines at bob and/or eob
1463 (when (memq 'empty whitespace-style)
1464 (let (overwrite-mode) ; enforce no overwrite
1465 (goto-char (point-min))
1466 (when (re-search-forward
1467 whitespace-empty-at-bob-regexp nil t)
1468 (delete-region (match-beginning 1) (match-end 1)))
1469 (when (re-search-forward
1470 whitespace-empty-at-eob-regexp nil t)
1471 (delete-region (match-beginning 1) (match-end 1)))))))
1472 ;; PROBLEM 3: 8 or more SPACEs at bol
1473 ;; PROBLEM 4: SPACEs before TAB
1474 ;; PROBLEM 5: SPACEs or TABs at eol
1475 ;; PROBLEM 6: 8 or more SPACEs after TAB
1476 (whitespace-cleanup-region (point-min) (point-max)))))
1479 ;;;###autoload
1480 (defun whitespace-cleanup-region (start end)
1481 "Cleanup some blank problems at region.
1483 The problems cleaned up are:
1485 1. 8 or more SPACEs at beginning of line.
1486 If `whitespace-style' includes the value `indentation':
1487 replace 8 or more SPACEs at beginning of line by TABs, if
1488 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1489 SPACEs.
1490 If `whitespace-style' includes the value `indentation::tab',
1491 replace 8 or more SPACEs at beginning of line by TABs.
1492 If `whitespace-style' includes the value `indentation::space',
1493 replace TABs by SPACEs.
1495 2. SPACEs before TAB.
1496 If `whitespace-style' includes the value `space-before-tab':
1497 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1498 otherwise, replace TABs by SPACEs.
1499 If `whitespace-style' includes the value
1500 `space-before-tab::tab', replace SPACEs by TABs.
1501 If `whitespace-style' includes the value
1502 `space-before-tab::space', replace TABs by SPACEs.
1504 3. SPACEs or TABs at end of line.
1505 If `whitespace-style' includes the value `trailing', remove
1506 all SPACEs or TABs at end of line.
1508 4. 8 or more SPACEs after TAB.
1509 If `whitespace-style' includes the value `space-after-tab':
1510 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1511 otherwise, replace TABs by SPACEs.
1512 If `whitespace-style' includes the value
1513 `space-after-tab::tab', replace SPACEs by TABs.
1514 If `whitespace-style' includes the value
1515 `space-after-tab::space', replace TABs by SPACEs.
1517 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1518 documentation."
1519 (interactive "@r")
1520 (if buffer-read-only
1521 ;; read-only buffer
1522 (whitespace-warn-read-only "cleanup region")
1523 ;; non-read-only buffer
1524 (let ((rstart (min start end))
1525 (rend (copy-marker (max start end)))
1526 (indent-tabs-mode whitespace-indent-tabs-mode)
1527 (tab-width whitespace-tab-width)
1528 overwrite-mode ; enforce no overwrite
1529 tmp)
1530 (save-excursion
1531 (save-match-data
1532 ;; PROBLEM 1: 8 or more SPACEs at bol
1533 (cond
1534 ;; ACTION: replace 8 or more SPACEs at bol by TABs, if
1535 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1536 ;; by SPACEs.
1537 ((memq 'indentation whitespace-style)
1538 (let ((regexp (whitespace-indentation-regexp)))
1539 (goto-char rstart)
1540 (while (re-search-forward regexp rend t)
1541 (setq tmp (current-indentation))
1542 (goto-char (match-beginning 0))
1543 (delete-horizontal-space)
1544 (unless (eolp)
1545 (indent-to tmp)))))
1546 ;; ACTION: replace 8 or more SPACEs at bol by TABs.
1547 ((memq 'indentation::tab whitespace-style)
1548 (whitespace-replace-action
1549 'tabify rstart rend
1550 (whitespace-indentation-regexp 'tab) 0))
1551 ;; ACTION: replace TABs by SPACEs.
1552 ((memq 'indentation::space whitespace-style)
1553 (whitespace-replace-action
1554 'untabify rstart rend
1555 (whitespace-indentation-regexp 'space) 0)))
1556 ;; PROBLEM 3: SPACEs or TABs at eol
1557 ;; ACTION: remove all SPACEs or TABs at eol
1558 (when (memq 'trailing whitespace-style)
1559 (whitespace-replace-action
1560 'delete-region rstart rend
1561 whitespace-trailing-regexp 1))
1562 ;; PROBLEM 4: 8 or more SPACEs after TAB
1563 (cond
1564 ;; ACTION: replace 8 or more SPACEs by TABs, if
1565 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1566 ;; by SPACEs.
1567 ((memq 'space-after-tab whitespace-style)
1568 (whitespace-replace-action
1569 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1570 rstart rend (whitespace-space-after-tab-regexp) 1))
1571 ;; ACTION: replace 8 or more SPACEs by TABs.
1572 ((memq 'space-after-tab::tab whitespace-style)
1573 (whitespace-replace-action
1574 'tabify rstart rend
1575 (whitespace-space-after-tab-regexp 'tab) 1))
1576 ;; ACTION: replace TABs by SPACEs.
1577 ((memq 'space-after-tab::space whitespace-style)
1578 (whitespace-replace-action
1579 'untabify rstart rend
1580 (whitespace-space-after-tab-regexp 'space) 1)))
1581 ;; PROBLEM 2: SPACEs before TAB
1582 (cond
1583 ;; ACTION: replace SPACEs before TAB by TABs, if
1584 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1585 ;; by SPACEs.
1586 ((memq 'space-before-tab whitespace-style)
1587 (whitespace-replace-action
1588 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1589 rstart rend whitespace-space-before-tab-regexp
1590 (if whitespace-indent-tabs-mode 1 2)))
1591 ;; ACTION: replace SPACEs before TAB by TABs.
1592 ((memq 'space-before-tab::tab whitespace-style)
1593 (whitespace-replace-action
1594 'tabify rstart rend
1595 whitespace-space-before-tab-regexp 1))
1596 ;; ACTION: replace TABs by SPACEs.
1597 ((memq 'space-before-tab::space whitespace-style)
1598 (whitespace-replace-action
1599 'untabify rstart rend
1600 whitespace-space-before-tab-regexp 2)))))
1601 (set-marker rend nil)))) ; point marker to nowhere
1604 (defun whitespace-replace-action (action rstart rend regexp index)
1605 "Do ACTION in the string matched by REGEXP between RSTART and REND.
1607 INDEX is the level group matched by REGEXP and used by ACTION.
1609 See also `tab-width'."
1610 (goto-char rstart)
1611 (while (re-search-forward regexp rend t)
1612 (goto-char (match-end index))
1613 (funcall action (match-beginning index) (match-end index))))
1616 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1617 ;;;; User command - report
1620 (defun whitespace-regexp (regexp &optional kind)
1621 "Return REGEXP depending on `whitespace-indent-tabs-mode'."
1622 (cond
1623 ((or (eq kind 'tab)
1624 whitespace-indent-tabs-mode)
1625 (format (car regexp) whitespace-tab-width))
1626 ((or (eq kind 'space)
1627 (not whitespace-indent-tabs-mode))
1628 (cdr regexp))))
1631 (defun whitespace-indentation-regexp (&optional kind)
1632 "Return the indentation regexp depending on `whitespace-indent-tabs-mode'."
1633 (whitespace-regexp whitespace-indentation-regexp kind))
1636 (defun whitespace-space-after-tab-regexp (&optional kind)
1637 "Return the space-after-tab regexp depending on `whitespace-indent-tabs-mode'."
1638 (whitespace-regexp whitespace-space-after-tab-regexp kind))
1641 (defconst whitespace-report-list
1642 (list
1643 (cons 'empty whitespace-empty-at-bob-regexp)
1644 (cons 'empty whitespace-empty-at-eob-regexp)
1645 (cons 'trailing whitespace-trailing-regexp)
1646 (cons 'indentation nil)
1647 (cons 'indentation::tab nil)
1648 (cons 'indentation::space nil)
1649 (cons 'space-before-tab whitespace-space-before-tab-regexp)
1650 (cons 'space-before-tab::tab whitespace-space-before-tab-regexp)
1651 (cons 'space-before-tab::space whitespace-space-before-tab-regexp)
1652 (cons 'space-after-tab nil)
1653 (cons 'space-after-tab::tab nil)
1654 (cons 'space-after-tab::space nil)
1656 "List of whitespace bogus symbol and corresponding regexp.")
1659 (defconst whitespace-report-text
1660 '( ;; `indent-tabs-mode' has non-nil value
1662 Whitespace Report
1664 Current Setting Whitespace Problem
1666 empty [] [] empty lines at beginning of buffer
1667 empty [] [] empty lines at end of buffer
1668 trailing [] [] SPACEs or TABs at end of line
1669 indentation [] [] 8 or more SPACEs at beginning of line
1670 indentation::tab [] [] 8 or more SPACEs at beginning of line
1671 indentation::space [] [] TABs at beginning of line
1672 space-before-tab [] [] SPACEs before TAB
1673 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1674 space-before-tab::space [] [] SPACEs before TAB: TABs
1675 space-after-tab [] [] 8 or more SPACEs after TAB
1676 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1677 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1679 indent-tabs-mode =
1680 tab-width = \n\n"
1681 . ;; `indent-tabs-mode' has nil value
1683 Whitespace Report
1685 Current Setting Whitespace Problem
1687 empty [] [] empty lines at beginning of buffer
1688 empty [] [] empty lines at end of buffer
1689 trailing [] [] SPACEs or TABs at end of line
1690 indentation [] [] TABs at beginning of line
1691 indentation::tab [] [] 8 or more SPACEs at beginning of line
1692 indentation::space [] [] TABs at beginning of line
1693 space-before-tab [] [] SPACEs before TAB
1694 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1695 space-before-tab::space [] [] SPACEs before TAB: TABs
1696 space-after-tab [] [] 8 or more SPACEs after TAB
1697 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1698 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1700 indent-tabs-mode =
1701 tab-width = \n\n")
1702 "Text for whitespace bogus report.
1704 It is a cons of strings, where the car part is used when
1705 `indent-tabs-mode' is non-nil, and the cdr part is used when
1706 `indent-tabs-mode' is nil.")
1709 (defconst whitespace-report-buffer-name "*Whitespace Report*"
1710 "The buffer name for whitespace bogus report.")
1713 ;;;###autoload
1714 (defun whitespace-report (&optional force report-if-bogus)
1715 "Report some whitespace problems in buffer.
1717 Return nil if there is no whitespace problem; otherwise, return
1718 non-nil.
1720 If FORCE is non-nil or \\[universal-argument] was pressed just
1721 before calling `whitespace-report' interactively, it forces
1722 `whitespace-style' to have:
1724 empty
1725 trailing
1726 indentation
1727 space-before-tab
1728 space-after-tab
1730 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1731 whitespace problems in buffer.
1733 Report if some of the following whitespace problems exist:
1735 * If `indent-tabs-mode' is non-nil:
1736 empty 1. empty lines at beginning of buffer.
1737 empty 2. empty lines at end of buffer.
1738 trailing 3. SPACEs or TABs at end of line.
1739 indentation 4. 8 or more SPACEs at beginning of line.
1740 space-before-tab 5. SPACEs before TAB.
1741 space-after-tab 6. 8 or more SPACEs after TAB.
1743 * If `indent-tabs-mode' is 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. TABS at beginning of line.
1748 space-before-tab 5. SPACEs before TAB.
1749 space-after-tab 6. 8 or more SPACEs after TAB.
1751 See `whitespace-style' for documentation.
1752 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1753 cleaning up these problems."
1754 (interactive (list current-prefix-arg))
1755 (whitespace-report-region (point-min) (point-max)
1756 force report-if-bogus))
1759 ;;;###autoload
1760 (defun whitespace-report-region (start end &optional force report-if-bogus)
1761 "Report some whitespace problems in a region.
1763 Return nil if there is no whitespace problem; otherwise, return
1764 non-nil.
1766 If FORCE is non-nil or \\[universal-argument] was pressed just
1767 before calling `whitespace-report-region' interactively, it
1768 forces `whitespace-style' to have:
1770 empty
1771 indentation
1772 space-before-tab
1773 trailing
1774 space-after-tab
1776 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1777 whitespace problems in buffer.
1779 Report if some of the following whitespace problems exist:
1781 * If `indent-tabs-mode' is non-nil:
1782 empty 1. empty lines at beginning of buffer.
1783 empty 2. empty lines at end of buffer.
1784 trailing 3. SPACEs or TABs at end of line.
1785 indentation 4. 8 or more SPACEs at beginning of line.
1786 space-before-tab 5. SPACEs before TAB.
1787 space-after-tab 6. 8 or more SPACEs after TAB.
1789 * If `indent-tabs-mode' is 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. TABS at beginning of line.
1794 space-before-tab 5. SPACEs before TAB.
1795 space-after-tab 6. 8 or more SPACEs after TAB.
1797 See `whitespace-style' for documentation.
1798 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1799 cleaning up these problems."
1800 (interactive "r")
1801 (setq force (or current-prefix-arg force))
1802 (save-excursion
1803 (save-match-data
1804 (let* ((has-bogus nil)
1805 (rstart (min start end))
1806 (rend (max start end))
1807 (bogus-list
1808 (mapcar
1809 #'(lambda (option)
1810 (when force
1811 (add-to-list 'whitespace-style (car option)))
1812 (goto-char rstart)
1813 (let ((regexp
1814 (cond
1815 ((eq (car option) 'indentation)
1816 (whitespace-indentation-regexp))
1817 ((eq (car option) 'indentation::tab)
1818 (whitespace-indentation-regexp 'tab))
1819 ((eq (car option) 'indentation::space)
1820 (whitespace-indentation-regexp 'space))
1821 ((eq (car option) 'space-after-tab)
1822 (whitespace-space-after-tab-regexp))
1823 ((eq (car option) 'space-after-tab::tab)
1824 (whitespace-space-after-tab-regexp 'tab))
1825 ((eq (car option) 'space-after-tab::space)
1826 (whitespace-space-after-tab-regexp 'space))
1828 (cdr option)))))
1829 (and (re-search-forward regexp rend t)
1830 (setq has-bogus t))))
1831 whitespace-report-list)))
1832 (when (if report-if-bogus has-bogus t)
1833 (whitespace-kill-buffer whitespace-report-buffer-name)
1834 ;; `whitespace-indent-tabs-mode' is local to current buffer
1835 ;; `whitespace-tab-width' is local to current buffer
1836 (let ((ws-indent-tabs-mode whitespace-indent-tabs-mode)
1837 (ws-tab-width whitespace-tab-width))
1838 (with-current-buffer (get-buffer-create
1839 whitespace-report-buffer-name)
1840 (erase-buffer)
1841 (insert (if ws-indent-tabs-mode
1842 (car whitespace-report-text)
1843 (cdr whitespace-report-text)))
1844 (goto-char (point-min))
1845 (forward-line 3)
1846 (dolist (option whitespace-report-list)
1847 (forward-line 1)
1848 (whitespace-mark-x
1849 27 (memq (car option) whitespace-style))
1850 (whitespace-mark-x 7 (car bogus-list))
1851 (setq bogus-list (cdr bogus-list)))
1852 (forward-line 1)
1853 (whitespace-insert-value ws-indent-tabs-mode)
1854 (whitespace-insert-value ws-tab-width)
1855 (when has-bogus
1856 (goto-char (point-max))
1857 (insert " Type `M-x whitespace-cleanup'"
1858 " to cleanup the buffer.\n\n"
1859 " Type `M-x whitespace-cleanup-region'"
1860 " to cleanup a region.\n\n"))
1861 (whitespace-display-window (current-buffer)))))
1862 has-bogus))))
1865 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1866 ;;;; Internal functions
1869 (defvar whitespace-font-lock-mode nil
1870 "Used to remember whether a buffer had font lock mode on or not.")
1872 (defvar whitespace-font-lock nil
1873 "Used to remember whether a buffer initially had font lock on or not.")
1875 (defvar whitespace-font-lock-keywords nil
1876 "Used to save locally `font-lock-keywords' value.")
1879 (defconst whitespace-help-text
1881 Whitespace Toggle Options
1883 FACES
1884 [] t - toggle TAB visualization
1885 [] s - toggle SPACE and HARD SPACE visualization
1886 [] r - toggle trailing blanks visualization
1887 [] l - toggle \"long lines\" visualization
1888 [] L - toggle \"long lines\" tail visualization
1889 [] n - toggle NEWLINE visualization
1890 [] e - toggle empty line at bob and/or eob visualization
1891 [] C-i - toggle indentation SPACEs visualization (via `indent-tabs-mode')
1892 [] I - toggle indentation SPACEs visualization
1893 [] i - toggle indentation TABs visualization
1894 [] C-a - toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1895 [] A - toggle SPACEs after TAB: SPACEs visualization
1896 [] a - toggle SPACEs after TAB: TABs visualization
1897 [] C-b - toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1898 [] B - toggle SPACEs before TAB: SPACEs visualization
1899 [] b - toggle SPACEs before TAB: TABs visualization
1901 DISPLAY TABLE
1902 [] T - toggle TAB visualization
1903 [] S - toggle SPACE and HARD SPACE visualization
1904 [] N - toggle NEWLINE visualization
1906 x - restore `whitespace-style' value
1908 ? - display this text\n\n"
1909 "Text for whitespace toggle options.")
1912 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1913 "The buffer name for whitespace toggle options.")
1916 (defun whitespace-insert-value (value)
1917 "Insert VALUE at column 20 of next line."
1918 (forward-line 1)
1919 (move-to-column 20 t)
1920 (insert (format "%s" value)))
1923 (defun whitespace-mark-x (nchars condition)
1924 "Insert the mark ('X' or ' ') after NCHARS depending on CONDITION."
1925 (forward-char nchars)
1926 (insert (if condition "X" " ")))
1929 (defun whitespace-insert-option-mark (the-list the-value)
1930 "Insert the option mark ('X' or ' ') in toggle options buffer."
1931 (goto-char (point-min))
1932 (forward-line 2)
1933 (dolist (sym the-list)
1934 (if (eq sym 'help-newline)
1935 (forward-line 2)
1936 (forward-line 1)
1937 (whitespace-mark-x 2 (memq sym the-value)))))
1940 (defun whitespace-help-on (style)
1941 "Display the whitespace toggle options."
1942 (unless (get-buffer whitespace-help-buffer-name)
1943 (delete-other-windows)
1944 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
1945 (with-current-buffer buffer
1946 (erase-buffer)
1947 (insert whitespace-help-text)
1948 (whitespace-insert-option-mark
1949 whitespace-style-value-list style)
1950 (whitespace-display-window buffer)))))
1953 (defun whitespace-display-window (buffer)
1954 "Display BUFFER in a new window."
1955 (goto-char (point-min))
1956 (set-buffer-modified-p nil)
1957 (let ((size (- (window-height)
1958 (max window-min-height
1959 (1+ (count-lines (point-min)
1960 (point-max)))))))
1961 (when (<= size 0)
1962 (kill-buffer buffer)
1963 (error "Frame height is too small; \
1964 can't split window to display whitespace toggle options"))
1965 (set-window-buffer (split-window nil size) buffer)))
1968 (defun whitespace-kill-buffer (buffer-name)
1969 "Kill buffer BUFFER-NAME and windows related with it."
1970 (let ((buffer (get-buffer buffer-name)))
1971 (when buffer
1972 (delete-windows-on buffer)
1973 (kill-buffer buffer))))
1976 (defun whitespace-help-off ()
1977 "Remove the buffer and window of the whitespace toggle options."
1978 (whitespace-kill-buffer whitespace-help-buffer-name))
1981 (defun whitespace-interactive-char (local-p)
1982 "Interactive function to read a char and return a symbol.
1984 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1985 uses a global context.
1987 It accepts one of the following chars:
1989 CHAR MEANING
1990 (VIA FACES)
1991 t toggle TAB visualization
1992 s toggle SPACE and HARD SPACE visualization
1993 r toggle trailing blanks visualization
1994 l toggle \"long lines\" visualization
1995 L toggle \"long lines\" tail visualization
1996 n toggle NEWLINE visualization
1997 e toggle empty line at bob and/or eob visualization
1998 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1999 I toggle indentation SPACEs visualization
2000 i toggle indentation TABs visualization
2001 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
2002 A toggle SPACEs after TAB: SPACEs visualization
2003 a toggle SPACEs after TAB: TABs visualization
2004 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
2005 B toggle SPACEs before TAB: SPACEs visualization
2006 b toggle SPACEs before TAB: TABs visualization
2008 (VIA DISPLAY TABLE)
2009 T toggle TAB visualization
2010 S toggle SPACE and HARD SPACE visualization
2011 N toggle NEWLINE visualization
2013 x restore `whitespace-style' value
2014 ? display brief help
2016 See also `whitespace-toggle-option-alist'."
2017 (let* ((is-off (not (if local-p
2018 whitespace-mode
2019 global-whitespace-mode)))
2020 (style (cond (is-off whitespace-style) ; use default value
2021 (local-p whitespace-active-style)
2022 (t whitespace-toggle-style)))
2023 (prompt
2024 (format "Whitespace Toggle %s (type ? for further options)-"
2025 (if local-p "Local" "Global")))
2026 ch sym)
2027 ;; read a valid option and get the corresponding symbol
2028 (save-window-excursion
2029 (condition-case data
2030 (progn
2031 (while
2032 ;; while condition
2033 (progn
2034 (setq ch (read-char prompt))
2035 (not
2036 (setq sym
2037 (cdr
2038 (assq ch whitespace-toggle-option-alist)))))
2039 ;; while body
2040 (if (eq ch ?\?)
2041 (whitespace-help-on style)
2042 (ding)))
2043 (whitespace-help-off)
2044 (message " ")) ; clean echo area
2045 ;; handler
2046 ((quit error)
2047 (whitespace-help-off)
2048 (error (error-message-string data)))))
2049 (list sym))) ; return the appropriate symbol
2052 (defun whitespace-toggle-list (local-p arg the-list)
2053 "Toggle options in THE-LIST based on list ARG.
2055 If LOCAL-P is non-nil, it uses a local context; otherwise, it
2056 uses a global context.
2058 ARG is a list of options to be toggled.
2060 THE-LIST is a list of options. This list will be toggled and the
2061 resultant list will be returned."
2062 (unless (if local-p whitespace-mode global-whitespace-mode)
2063 (setq the-list whitespace-style))
2064 (setq the-list (copy-sequence the-list)) ; keep original list
2065 (dolist (sym (if (listp arg) arg (list arg)))
2066 (cond
2067 ;; ignore help value
2068 ((eq sym 'help-newline))
2069 ;; restore default values
2070 ((eq sym 'whitespace-style)
2071 (setq the-list whitespace-style))
2072 ;; toggle valid values
2073 ((memq sym whitespace-style-value-list)
2074 (setq the-list (if (memq sym the-list)
2075 (delq sym the-list)
2076 (cons sym the-list))))))
2077 the-list)
2080 (defvar whitespace-display-table nil
2081 "Used to save a local display table.")
2083 (defvar whitespace-display-table-was-local nil
2084 "Used to remember whether a buffer initially had a local display table.")
2087 (defun whitespace-turn-on ()
2088 "Turn on whitespace visualization."
2089 ;; prepare local hooks
2090 (add-hook 'write-file-functions 'whitespace-write-file-hook nil t)
2091 ;; create whitespace local buffer environment
2092 (set (make-local-variable 'whitespace-font-lock-mode) nil)
2093 (set (make-local-variable 'whitespace-font-lock) nil)
2094 (set (make-local-variable 'whitespace-font-lock-keywords) nil)
2095 (set (make-local-variable 'whitespace-display-table) nil)
2096 (set (make-local-variable 'whitespace-display-table-was-local) nil)
2097 (set (make-local-variable 'whitespace-active-style)
2098 (if (listp whitespace-style)
2099 whitespace-style
2100 (list whitespace-style)))
2101 (set (make-local-variable 'whitespace-indent-tabs-mode)
2102 indent-tabs-mode)
2103 (set (make-local-variable 'whitespace-tab-width)
2104 tab-width)
2105 ;; turn on whitespace
2106 (when whitespace-active-style
2107 (whitespace-color-on)
2108 (whitespace-display-char-on)))
2111 (defun whitespace-turn-off ()
2112 "Turn off whitespace visualization."
2113 (remove-hook 'write-file-functions 'whitespace-write-file-hook t)
2114 (when whitespace-active-style
2115 (whitespace-color-off)
2116 (whitespace-display-char-off)))
2119 (defun whitespace-style-face-p ()
2120 "Return t if there is some visualization via face."
2121 (or (memq 'tabs whitespace-active-style)
2122 (memq 'spaces whitespace-active-style)
2123 (memq 'trailing whitespace-active-style)
2124 (memq 'lines whitespace-active-style)
2125 (memq 'lines-tail whitespace-active-style)
2126 (memq 'newline whitespace-active-style)
2127 (memq 'empty whitespace-active-style)
2128 (memq 'indentation whitespace-active-style)
2129 (memq 'indentation::tab whitespace-active-style)
2130 (memq 'indentation::space whitespace-active-style)
2131 (memq 'space-after-tab whitespace-active-style)
2132 (memq 'space-after-tab::tab whitespace-active-style)
2133 (memq 'space-after-tab::space whitespace-active-style)
2134 (memq 'space-before-tab whitespace-active-style)
2135 (memq 'space-before-tab::tab whitespace-active-style)
2136 (memq 'space-before-tab::space whitespace-active-style)))
2139 (defun whitespace-color-on ()
2140 "Turn on color visualization."
2141 (when (whitespace-style-face-p)
2142 (unless whitespace-font-lock
2143 (setq whitespace-font-lock t
2144 whitespace-font-lock-keywords
2145 (copy-sequence font-lock-keywords)))
2146 ;; save current point and refontify when necessary
2147 (set (make-local-variable 'whitespace-point)
2148 (point))
2149 (set (make-local-variable 'whitespace-font-lock-refontify)
2150 nil)
2151 (add-hook 'post-command-hook #'whitespace-post-command-hook nil t)
2152 ;; turn off font lock
2153 (set (make-local-variable 'whitespace-font-lock-mode)
2154 font-lock-mode)
2155 (font-lock-mode 0)
2156 ;; add whitespace-mode color into font lock
2157 (when (memq 'spaces whitespace-active-style)
2158 (font-lock-add-keywords
2160 (list
2161 ;; Show SPACEs
2162 (list #'whitespace-space-regexp 1 whitespace-space t)
2163 ;; Show HARD SPACEs
2164 (list whitespace-hspace-regexp 1 whitespace-hspace t))
2166 (when (memq 'tabs whitespace-active-style)
2167 (font-lock-add-keywords
2169 (list
2170 ;; Show TABs
2171 (list #'whitespace-tab-regexp 1 whitespace-tab t))
2173 (when (memq 'trailing whitespace-active-style)
2174 (font-lock-add-keywords
2176 (list
2177 ;; Show trailing blanks
2178 (list #'whitespace-trailing-regexp 1 whitespace-trailing t))
2180 (when (or (memq 'lines whitespace-active-style)
2181 (memq 'lines-tail whitespace-active-style))
2182 (font-lock-add-keywords
2184 (list
2185 ;; Show "long" lines
2186 (list
2187 (format
2188 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
2189 whitespace-tab-width (1- whitespace-tab-width)
2190 (/ whitespace-line-column whitespace-tab-width)
2191 (let ((rem (% whitespace-line-column whitespace-tab-width)))
2192 (if (zerop rem)
2194 (format ".\\{%d\\}" rem))))
2195 (if (memq 'lines whitespace-active-style)
2196 0 ; whole line
2197 2) ; line tail
2198 whitespace-line t))
2200 (cond
2201 ((memq 'space-before-tab whitespace-active-style)
2202 (font-lock-add-keywords
2204 (list
2205 ;; Show SPACEs before TAB (indent-tabs-mode)
2206 (list whitespace-space-before-tab-regexp
2207 (if whitespace-indent-tabs-mode 1 2)
2208 whitespace-space-before-tab t))
2210 ((memq 'space-before-tab::tab whitespace-active-style)
2211 (font-lock-add-keywords
2213 (list
2214 ;; Show SPACEs before TAB (SPACEs)
2215 (list whitespace-space-before-tab-regexp
2216 1 whitespace-space-before-tab t))
2218 ((memq 'space-before-tab::space whitespace-active-style)
2219 (font-lock-add-keywords
2221 (list
2222 ;; Show SPACEs before TAB (TABs)
2223 (list whitespace-space-before-tab-regexp
2224 2 whitespace-space-before-tab t))
2225 t)))
2226 (cond
2227 ((memq 'indentation whitespace-active-style)
2228 (font-lock-add-keywords
2230 (list
2231 ;; Show indentation SPACEs (indent-tabs-mode)
2232 (list (whitespace-indentation-regexp)
2233 1 whitespace-indentation t))
2235 ((memq 'indentation::tab whitespace-active-style)
2236 (font-lock-add-keywords
2238 (list
2239 ;; Show indentation SPACEs (SPACEs)
2240 (list (whitespace-indentation-regexp 'tab)
2241 1 whitespace-indentation t))
2243 ((memq 'indentation::space whitespace-active-style)
2244 (font-lock-add-keywords
2246 (list
2247 ;; Show indentation SPACEs (TABs)
2248 (list (whitespace-indentation-regexp 'space)
2249 1 whitespace-indentation t))
2250 t)))
2251 (when (memq 'empty whitespace-active-style)
2252 (font-lock-add-keywords
2254 (list
2255 ;; Show empty lines at beginning of buffer
2256 (list #'whitespace-empty-at-bob-regexp
2257 1 whitespace-empty t))
2259 (font-lock-add-keywords
2261 (list
2262 ;; Show empty lines at end of buffer
2263 (list #'whitespace-empty-at-eob-regexp
2264 1 whitespace-empty t))
2266 (cond
2267 ((memq 'space-after-tab whitespace-active-style)
2268 (font-lock-add-keywords
2270 (list
2271 ;; Show SPACEs after TAB (indent-tabs-mode)
2272 (list (whitespace-space-after-tab-regexp)
2273 1 whitespace-space-after-tab t))
2275 ((memq 'space-after-tab::tab whitespace-active-style)
2276 (font-lock-add-keywords
2278 (list
2279 ;; Show SPACEs after TAB (SPACEs)
2280 (list (whitespace-space-after-tab-regexp 'tab)
2281 1 whitespace-space-after-tab t))
2283 ((memq 'space-after-tab::space whitespace-active-style)
2284 (font-lock-add-keywords
2286 (list
2287 ;; Show SPACEs after TAB (TABs)
2288 (list (whitespace-space-after-tab-regexp 'space)
2289 1 whitespace-space-after-tab t))
2290 t)))
2291 ;; now turn on font lock and highlight blanks
2292 (font-lock-mode 1)))
2295 (defun whitespace-color-off ()
2296 "Turn off color visualization."
2297 ;; turn off font lock
2298 (when (whitespace-style-face-p)
2299 (font-lock-mode 0)
2300 (remove-hook 'post-command-hook #'whitespace-post-command-hook)
2301 (when whitespace-font-lock
2302 (setq whitespace-font-lock nil
2303 font-lock-keywords whitespace-font-lock-keywords))
2304 ;; restore original font lock state
2305 (font-lock-mode whitespace-font-lock-mode)))
2308 (defun whitespace-trailing-regexp (limit)
2309 "Match trailing spaces which do not contain the point at end of line."
2310 (let ((status t))
2311 (while (if (re-search-forward whitespace-trailing-regexp limit t)
2312 (save-match-data
2313 (= whitespace-point (match-end 1))) ;; loop if point at eol
2314 (setq status nil))) ;; end of buffer
2315 status))
2318 (defun whitespace-empty-at-bob-regexp (limit)
2319 "Match spaces at beginning of buffer which do not contain the point at \
2320 beginning of buffer."
2321 (and (/= whitespace-point 1)
2322 (re-search-forward whitespace-empty-at-bob-regexp limit t)))
2325 (defun whitespace-empty-at-eob-regexp (limit)
2326 "Match spaces at end of buffer which do not contain the point at end of \
2327 buffer."
2328 (and (/= whitespace-point (1+ (buffer-size)))
2329 (re-search-forward whitespace-empty-at-eob-regexp limit t)))
2332 (defun whitespace-space-regexp (limit)
2333 "Match spaces."
2334 (setq whitespace-font-lock-refontify t)
2335 (re-search-forward whitespace-space-regexp limit t))
2338 (defun whitespace-tab-regexp (limit)
2339 "Match tabs."
2340 (setq whitespace-font-lock-refontify t)
2341 (re-search-forward whitespace-tab-regexp limit t))
2344 (defun whitespace-post-command-hook ()
2345 "Save current point into `whitespace-point' variable.
2346 Also refontify when necessary."
2347 (setq whitespace-point (point))
2348 (let ((refontify (or (eolp) ; end of line
2349 (= whitespace-point 1)))) ; beginning of buffer
2350 (when (or whitespace-font-lock-refontify refontify)
2351 (setq whitespace-font-lock-refontify refontify)
2352 (jit-lock-refontify))))
2355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2356 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
2359 (defun whitespace-style-mark-p ()
2360 "Return t if there is some visualization via display table."
2361 (or (memq 'tab-mark whitespace-active-style)
2362 (memq 'space-mark whitespace-active-style)
2363 (memq 'newline-mark whitespace-active-style)))
2366 (defsubst whitespace-char-valid-p (char)
2367 ;; This check should be improved!!!
2368 (or (< char 256)
2369 (characterp char)))
2372 (defun whitespace-display-vector-p (vec)
2373 "Return true if every character in vector VEC can be displayed."
2374 (let ((i (length vec)))
2375 (when (> i 0)
2376 (while (and (>= (setq i (1- i)) 0)
2377 (whitespace-char-valid-p (aref vec i))))
2378 (< i 0))))
2381 (defun whitespace-display-char-on ()
2382 "Turn on character display mapping."
2383 (when (and whitespace-display-mappings
2384 (whitespace-style-mark-p))
2385 (let (vecs vec)
2386 ;; Remember whether a buffer has a local display table.
2387 (unless whitespace-display-table-was-local
2388 (setq whitespace-display-table-was-local t
2389 whitespace-display-table
2390 (copy-sequence buffer-display-table)))
2391 ;; asure `buffer-display-table' is unique
2392 ;; when two or more windows are visible.
2393 (set (make-local-variable 'buffer-display-table)
2394 (copy-sequence buffer-display-table))
2395 (unless buffer-display-table
2396 (setq buffer-display-table (make-display-table)))
2397 (dolist (entry whitespace-display-mappings)
2398 ;; check if it is to display this mark
2399 (when (memq (car entry) whitespace-style)
2400 ;; Get a displayable mapping.
2401 (setq vecs (cddr entry))
2402 (while (and vecs
2403 (not (whitespace-display-vector-p (car vecs))))
2404 (setq vecs (cdr vecs)))
2405 ;; Display a valid mapping.
2406 (when vecs
2407 (setq vec (copy-sequence (car vecs)))
2408 ;; NEWLINE char
2409 (when (and (eq (cadr entry) ?\n)
2410 (memq 'newline whitespace-active-style))
2411 ;; Only insert face bits on NEWLINE char mapping to avoid
2412 ;; obstruction of other faces like TABs and (HARD) SPACEs
2413 ;; faces, font-lock faces, etc.
2414 (dotimes (i (length vec))
2415 (or (eq (aref vec i) ?\n)
2416 (aset vec i
2417 (make-glyph-code (aref vec i)
2418 whitespace-newline)))))
2419 ;; Display mapping
2420 (aset buffer-display-table (cadr entry) vec)))))))
2423 (defun whitespace-display-char-off ()
2424 "Turn off character display mapping."
2425 (and whitespace-display-mappings
2426 (whitespace-style-mark-p)
2427 whitespace-display-table-was-local
2428 (setq whitespace-display-table-was-local nil
2429 buffer-display-table whitespace-display-table)))
2432 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2433 ;;;; Hook
2436 (defun whitespace-action-when-on ()
2437 "Action to be taken always when local whitespace is turned on."
2438 (cond ((memq 'cleanup whitespace-action)
2439 (whitespace-cleanup))
2440 ((memq 'report-on-bogus whitespace-action)
2441 (whitespace-report nil t))))
2444 (defun whitespace-write-file-hook ()
2445 "Action to be taken when buffer is written.
2446 It should be added buffer-locally to `write-file-functions'."
2447 (cond ((memq 'auto-cleanup whitespace-action)
2448 (whitespace-cleanup))
2449 ((memq 'abort-on-bogus whitespace-action)
2450 (when (whitespace-report nil t)
2451 (error "Abort write due to whitespace problems in %s"
2452 (buffer-name)))))
2453 nil) ; continue hook processing
2456 (defun whitespace-warn-read-only (msg)
2457 "Warn if buffer is read-only."
2458 (when (memq 'warn-if-read-only whitespace-action)
2459 (message "Can't %s: %s is read-only" msg (buffer-name))))
2462 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2465 (defun whitespace-unload-function ()
2466 "Unload the whitespace library."
2467 (global-whitespace-mode -1)
2468 ;; be sure all local whitespace mode is turned off
2469 (save-current-buffer
2470 (dolist (buf (buffer-list))
2471 (set-buffer buf)
2472 (whitespace-mode -1)))
2473 nil) ; continue standard unloading
2476 (provide 'whitespace)
2479 (run-hooks 'whitespace-load-hook)
2482 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
2483 ;;; whitespace.el ends here