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