(whitespace): Set :version tag to 23.1.
[emacs.git] / lisp / whitespace.el
blobfcd5a79cb99468ab3ff4ac300dc707afebcbe680
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: 9.2
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' and `whitespace-chars' variables are used to
50 ;; 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-cleanup'
166 ;; Cleanup some blank problems in all buffer or at region.
168 ;; `whitespace-cleanup-region'
169 ;; Cleanup some blank problems at region.
171 ;; `whitespace-buffer'
172 ;; Turn on `whitespace-mode' forcing some settings.
174 ;; The problems, which are cleaned up, are:
176 ;; 1. empty lines at beginning of buffer.
177 ;; 2. empty lines at end of buffer.
178 ;; If `whitespace-chars' includes the value `empty', remove all
179 ;; empty lines at beginning and/or end of buffer.
181 ;; 3. 8 or more SPACEs at beginning of line.
182 ;; If `whitespace-chars' includes the value `indentation', replace 8
183 ;; or more SPACEs at beginning of line by TABs.
185 ;; 4. SPACEs before TAB.
186 ;; If `whitespace-chars' includes the value `space-before-tab',
187 ;; replace SPACEs by TABs.
189 ;; 5. SPACEs or TABs at end of line.
190 ;; If `whitespace-chars' includes the value `trailing', remove all
191 ;; SPACEs or TABs at end of line."
193 ;; 6. 8 or more SPACEs after TAB.
194 ;; If `whitespace-chars' includes the value `space-after-tab',
195 ;; replace SPACEs by TABs.
198 ;; Hooks
199 ;; -----
201 ;; whitespace has the following hook variables:
203 ;; `whitespace-mode-hook'
204 ;; It is evaluated always when whitespace is turned on locally.
206 ;; `global-whitespace-mode-hook'
207 ;; It is evaluated always when whitespace is turned on globally.
209 ;; `whitespace-load-hook'
210 ;; It is evaluated after whitespace package is loaded.
213 ;; Options
214 ;; -------
216 ;; Below it's shown a brief description of whitespace options, please,
217 ;; see the options declaration in the code for a long documentation.
219 ;; `whitespace-style' Specify the visualization style.
221 ;; `whitespace-chars' Specify which kind of blank is
222 ;; visualized.
224 ;; `whitespace-space' Face used to visualize SPACE.
226 ;; `whitespace-hspace' Face used to visualize HARD SPACE.
228 ;; `whitespace-tab' Face used to visualize TAB.
230 ;; `whitespace-newline' Face used to visualize NEWLINE char
231 ;; mapping.
233 ;; `whitespace-trailing' Face used to visualize trailing
234 ;; blanks.
236 ;; `whitespace-line' Face used to visualize "long" lines.
238 ;; `whitespace-space-before-tab' Face used to visualize SPACEs
239 ;; before TAB.
241 ;; `whitespace-indentation' Face used to visualize 8 or more
242 ;; SPACEs at beginning of line.
244 ;; `whitespace-empty' Face used to visualize empty lines at
245 ;; beginning and/or end of buffer.
247 ;; `whitespace-space-after-tab' Face used to visualize 8 or more
248 ;; SPACEs after TAB.
250 ;; `whitespace-space-regexp' Specify SPACE characters regexp.
252 ;; `whitespace-hspace-regexp' Specify HARD SPACE characters regexp.
254 ;; `whitespace-tab-regexp' Specify TAB characters regexp.
256 ;; `whitespace-trailing-regexp' Specify trailing characters regexp.
258 ;; `whitespace-space-before-tab-regexp' Specify SPACEs before TAB
259 ;; regexp.
261 ;; `whitespace-indentation-regexp' Specify regexp for 8 or more
262 ;; SPACEs at beginning of line.
264 ;; `whitespace-empty-at-bob-regexp' Specify regexp for empty lines
265 ;; at beginning of buffer.
267 ;; `whitespace-empty-at-eob-regexp' Specify regexp for empty lines
268 ;; at end of buffer.
270 ;; `whitespace-space-after-tab-regexp' Specify regexp for 8 or more
271 ;; SPACEs after TAB.
273 ;; `whitespace-line-column' Specify column beyond which the line
274 ;; is highlighted.
276 ;; `whitespace-display-mappings' Specify an alist of mappings
277 ;; for displaying characters.
279 ;; `whitespace-global-modes' Modes for which global `whitespace-mode' is
280 ;; automagically turned on.
283 ;; Acknowledgements
284 ;; ----------------
286 ;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
287 ;; lines tail. See EightyColumnRule (EmacsWiki).
289 ;; Thanks to Juri Linkov <juri@jurta.org> for suggesting:
290 ;; * `define-minor-mode'.
291 ;; * `global-whitespace-*' name for global commands.
293 ;; Thanks to Robert J. Chassell <bob@gnu.org> for doc fix and testing.
295 ;; Thanks to Drew Adams <drew.adams@oracle.com> for toggle commands
296 ;; suggestion.
298 ;; Thanks to Antti Kaihola <antti.kaihola@linux-aktivaattori.org> for
299 ;; helping to fix `find-file-hooks' reference.
301 ;; Thanks to Andreas Roehler <andreas.roehler@easy-emacs.de> for
302 ;; indicating defface byte-compilation warnings.
304 ;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight
305 ;; "long" lines. See EightyColumnRule (EmacsWiki).
307 ;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
308 ;; newline character mapping.
310 ;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
311 ;; whitespace-mode.el on XEmacs.
313 ;; Thanks to Miles Bader <miles@gnu.org> for handling display table via
314 ;; visws.el (his code was modified, but the main idea was kept).
316 ;; Thanks to:
317 ;; Rajesh Vaidheeswarran <rv@gnu.org> (original) whitespace.el
318 ;; Aurelien Tisne <aurelien.tisne@free.fr> show-whitespace-mode.el
319 ;; Lawrence Mitchell <wence@gmx.li> whitespace-mode.el
320 ;; Miles Bader <miles@gnu.org> visws.el
321 ;; And to all people who contributed with them.
324 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
326 ;;; code:
329 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
330 ;;;; User Variables:
333 ;;; Interface to the command system
336 (defgroup whitespace nil
337 "Visualize blanks (TAB, (HARD) SPACE and NEWLINE)."
338 :link '(emacs-library-link :tag "Source Lisp File" "whitespace.el")
339 :version "23.1"
340 :group 'wp
341 :group 'data)
344 (defcustom whitespace-style '(mark color)
345 "*Specify the visualization style.
347 It's a list containing some or all of the following values:
349 mark display mappings are visualized.
351 color faces are visualized.
353 Any other value is ignored.
355 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
357 See also `whitespace-display-mappings' for documentation."
358 :type '(repeat :tag "Style of Blank"
359 (choice :tag "Style of Blank"
360 (const :tag "Display Table" mark)
361 (const :tag "Faces" color)))
362 :group 'whitespace)
365 (defcustom whitespace-chars
366 '(tabs spaces trailing lines space-before-tab newline
367 indentation empty space-after-tab)
368 "*Specify which kind of blank is visualized.
370 It's a list containing some or all of the following values:
372 trailing trailing blanks are visualized.
374 tabs TABs are visualized.
376 spaces SPACEs and HARD SPACEs are visualized.
378 lines lines whose have columns beyond
379 `whitespace-line-column' are highlighted.
380 Whole line is highlighted.
381 It has precedence over
382 `lines-tail' (see below).
384 lines-tail lines whose have columns beyond
385 `whitespace-line-column' are highlighted.
386 But only the part of line which goes
387 beyond `whitespace-line-column' column.
388 It has effect only if `lines' (see above)
389 is not present in `whitespace-chars'.
391 space-before-tab SPACEs before TAB are visualized.
393 newline NEWLINEs are visualized.
395 indentation 8 or more SPACEs at beginning of line are
396 visualized.
398 empty empty lines at beginning and/or end of buffer
399 are visualized.
401 space-after-tab 8 or more SPACEs after a TAB are visualized.
403 Any other value is ignored.
405 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
407 Used when `whitespace-style' includes the value `color'.
408 Used also when `whitespace-chars' includes `newline',
409 and `whitespace-style' includes `mark'."
410 :type '(repeat :tag "Kind of Blank"
411 (choice :tag "Kind of Blank"
412 (const :tag "Trailing TABs, SPACEs and HARD SPACEs"
413 trailing)
414 (const :tag "SPACEs and HARD SPACEs" spaces)
415 (const :tag "TABs" tabs)
416 (const :tag "Lines" lines)
417 (const :tag "SPACEs before TAB"
418 space-before-tab)
419 (const :tag "NEWLINEs" newline)
420 (const :tag "Indentation SPACEs" indentation)
421 (const :tag "Empty Lines At BOB And/Or EOB"
422 empty)
423 (const :tag "SPACEs after TAB"
424 space-after-tab)))
425 :group 'whitespace)
428 (defcustom whitespace-space 'whitespace-space
429 "*Symbol face used to visualize SPACE.
431 Used when `whitespace-style' includes the value `color'."
432 :type 'face
433 :group 'whitespace)
436 (defface whitespace-space
437 '((((class color) (background dark))
438 (:background "grey20" :foreground "aquamarine3"))
439 (((class color) (background light))
440 (:background "LightYellow" :foreground "aquamarine3"))
441 (t (:inverse-video t)))
442 "Face used to visualize SPACE."
443 :group 'whitespace)
446 (defcustom whitespace-hspace 'whitespace-hspace
447 "*Symbol face used to visualize HARD SPACE.
449 Used when `whitespace-style' includes the value `color'."
450 :type 'face
451 :group 'whitespace)
454 (defface whitespace-hspace ; 'nobreak-space
455 '((((class color) (background dark))
456 (:background "grey24" :foreground "aquamarine3"))
457 (((class color) (background light))
458 (:background "LemonChiffon3" :foreground "aquamarine3"))
459 (t (:inverse-video t)))
460 "Face used to visualize HARD SPACE."
461 :group 'whitespace)
464 (defcustom whitespace-tab 'whitespace-tab
465 "*Symbol face used to visualize TAB.
467 Used when `whitespace-style' includes the value `color'."
468 :type 'face
469 :group 'whitespace)
472 (defface whitespace-tab
473 '((((class color) (background dark))
474 (:background "grey22" :foreground "aquamarine3"))
475 (((class color) (background light))
476 (:background "beige" :foreground "aquamarine3"))
477 (t (:inverse-video t)))
478 "Face used to visualize TAB."
479 :group 'whitespace)
482 (defcustom whitespace-newline 'whitespace-newline
483 "*Symbol face used to visualize NEWLINE char mapping.
485 See `whitespace-display-mappings'.
487 Used when `whitespace-style' includes the values `mark'
488 and `color', and `whitespace-chars' includes `newline'."
489 :type 'face
490 :group 'whitespace)
493 (defface whitespace-newline
494 '((((class color) (background dark))
495 (:background "grey26" :foreground "aquamarine3" :bold t))
496 (((class color) (background light))
497 (:background "linen" :foreground "aquamarine3" :bold t))
498 (t (:bold t :underline t)))
499 "Face used to visualize NEWLINE char mapping.
501 See `whitespace-display-mappings'."
502 :group 'whitespace)
505 (defcustom whitespace-trailing 'whitespace-trailing
506 "*Symbol face used to visualize traling blanks.
508 Used when `whitespace-style' includes the value `color'."
509 :type 'face
510 :group 'whitespace)
513 (defface whitespace-trailing ; 'trailing-whitespace
514 '((((class mono)) (:inverse-video t :bold t :underline t))
515 (t (:background "red1" :foreground "yellow" :bold t)))
516 "Face used to visualize trailing blanks."
517 :group 'whitespace)
520 (defcustom whitespace-line 'whitespace-line
521 "*Symbol face used to visualize \"long\" lines.
523 See `whitespace-line-column'.
525 Used when `whitespace-style' includes the value `color'."
526 :type 'face
527 :group 'whitespace)
530 (defface whitespace-line
531 '((((class mono)) (:inverse-video t :bold t :underline t))
532 (t (:background "gray20" :foreground "violet")))
533 "Face used to visualize \"long\" lines.
535 See `whitespace-line-column'."
536 :group 'whitespace)
539 (defcustom whitespace-space-before-tab 'whitespace-space-before-tab
540 "*Symbol face used to visualize SPACEs before TAB.
542 Used when `whitespace-style' includes the value `color'."
543 :type 'face
544 :group 'whitespace)
547 (defface whitespace-space-before-tab
548 '((((class mono)) (:inverse-video t :bold t :underline t))
549 (t (:background "DarkOrange" :foreground "firebrick")))
550 "Face used to visualize SPACEs before TAB."
551 :group 'whitespace)
554 (defcustom whitespace-indentation 'whitespace-indentation
555 "*Symbol face used to visualize 8 or more SPACEs at beginning of line.
557 Used when `whitespace-style' includes the value `color'."
558 :type 'face
559 :group 'whitespace)
562 (defface whitespace-indentation
563 '((((class mono)) (:inverse-video t :bold t :underline t))
564 (t (:background "yellow" :foreground "firebrick")))
565 "Face used to visualize 8 or more SPACEs at beginning of line."
566 :group 'whitespace)
569 (defcustom whitespace-empty 'whitespace-empty
570 "*Symbol face used to visualize empty lines at beginning and/or end of buffer.
572 Used when `whitespace-style' includes the value `color'."
573 :type 'face
574 :group 'whitespace)
577 (defface whitespace-empty
578 '((((class mono)) (:inverse-video t :bold t :underline t))
579 (t (:background "yellow" :foreground "firebrick")))
580 "Face used to visualize empty lines at beginning and/or end of buffer."
581 :group 'whitespace)
584 (defcustom whitespace-space-after-tab 'whitespace-space-after-tab
585 "*Symbol face used to visualize 8 or more SPACEs after TAB.
587 Used when `whitespace-style' includes the value `color'."
588 :type 'face
589 :group 'whitespace)
592 (defface whitespace-space-after-tab
593 '((((class mono)) (:inverse-video t :bold t :underline t))
594 (t (:background "yellow" :foreground "firebrick")))
595 "Face used to visualize 8 or more SPACEs after TAB."
596 :group 'whitespace)
599 (defcustom whitespace-hspace-regexp
600 "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
601 "*Specify HARD SPACE characters regexp.
603 If you're using `mule' package, there may be other characters besides:
605 \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
607 that should be considered HARD SPACE.
609 Here are some examples:
611 \"\\\\(^\\xA0+\\\\)\" \
612 visualize only leading HARD SPACEs.
613 \"\\\\(\\xA0+$\\\\)\" \
614 visualize only trailing HARD SPACEs.
615 \"\\\\(^\\xA0+\\\\|\\xA0+$\\\\)\" \
616 visualize leading and/or trailing HARD SPACEs.
617 \"\\t\\\\(\\xA0+\\\\)\\t\" \
618 visualize only HARD SPACEs between TABs.
620 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
621 Use exactly one pair of enclosing \\\\( and \\\\).
623 Used when `whitespace-style' includes the value `color',
624 and `whitespace-chars' includes `spaces'."
625 :type '(regexp :tag "HARD SPACE Chars")
626 :group 'whitespace)
629 (defcustom whitespace-space-regexp "\\( +\\)"
630 "*Specify SPACE characters regexp.
632 If you're using `mule' package, there may be other characters
633 besides \" \" that should be considered SPACE.
635 Here are some examples:
637 \"\\\\(^ +\\\\)\" visualize only leading SPACEs.
638 \"\\\\( +$\\\\)\" visualize only trailing SPACEs.
639 \"\\\\(^ +\\\\| +$\\\\)\" \
640 visualize leading and/or trailing SPACEs.
641 \"\\t\\\\( +\\\\)\\t\" visualize only SPACEs between TABs.
643 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
644 Use exactly one pair of enclosing \\\\( and \\\\).
646 Used when `whitespace-style' includes the value `color',
647 and `whitespace-chars' includes `spaces'."
648 :type '(regexp :tag "SPACE Chars")
649 :group 'whitespace)
652 (defcustom whitespace-tab-regexp "\\(\t+\\)"
653 "*Specify TAB characters regexp.
655 If you're using `mule' package, there may be other characters
656 besides \"\\t\" that should be considered TAB.
658 Here are some examples:
660 \"\\\\(^\\t+\\\\)\" visualize only leading TABs.
661 \"\\\\(\\t+$\\\\)\" visualize only trailing TABs.
662 \"\\\\(^\\t+\\\\|\\t+$\\\\)\" \
663 visualize leading and/or trailing TABs.
664 \" \\\\(\\t+\\\\) \" visualize only TABs between SPACEs.
666 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
667 Use exactly one pair of enclosing \\\\( and \\\\).
669 Used when `whitespace-style' includes the value `color',
670 and `whitespace-chars' includes `tabs'."
671 :type '(regexp :tag "TAB Chars")
672 :group 'whitespace)
675 (defcustom whitespace-trailing-regexp
676 "\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20"
677 "*Specify trailing characters regexp.
679 If you're using `mule' package, there may be other characters besides:
681 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
682 \"\\xF20\"
684 that should be considered blank.
686 NOTE: DO NOT enclose by \\\\( and \\\\) the elements to highlight.
687 `whitespace-mode' surrounds this regexp by \"\\\\(\\\\(\" and
688 \"\\\\)+\\\\)$\".
690 Used when `whitespace-style' includes the value `color',
691 and `whitespace-chars' includes `trailing'."
692 :type '(regexp :tag "Trailing Chars")
693 :group 'whitespace)
696 (defcustom whitespace-space-before-tab-regexp "\\( +\\)\t"
697 "*Specify SPACEs before TAB regexp.
699 If you're using `mule' package, there may be other characters besides:
701 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
702 \"\\xF20\"
704 that should be considered blank.
706 Used when `whitespace-style' includes the value `color',
707 and `whitespace-chars' includes `space-before-tab'."
708 :type '(regexp :tag "SPACEs Before TAB")
709 :group 'whitespace)
712 (defcustom whitespace-indentation-regexp
713 "^\t*\\(\\( \\{8\\}\\)+\\)[^\n\t]"
714 "*Specify regexp for 8 or more SPACEs at beginning of line.
716 If you're using `mule' package, there may be other characters besides:
718 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
719 \"\\xF20\"
721 that should be considered blank.
723 Used when `whitespace-style' includes the value `color',
724 and `whitespace-chars' includes `indentation'."
725 :type '(regexp :tag "Indentation SPACEs")
726 :group 'whitespace)
729 (defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
730 "*Specify regexp for empty lines at beginning of buffer.
732 If you're using `mule' package, there may be other characters besides:
734 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
735 \"\\xF20\"
737 that should be considered blank.
739 Used when `whitespace-style' includes the value `color',
740 and `whitespace-chars' includes `empty'."
741 :type '(regexp :tag "Empty Lines At Beginning Of Buffer")
742 :group 'whitespace)
745 (defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
746 "*Specify regexp for empty lines at end of buffer.
748 If you're using `mule' package, there may be other characters besides:
750 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
751 \"\\xF20\"
753 that should be considered blank.
755 Used when `whitespace-style' includes the value `color',
756 and `whitespace-chars' includes `empty'."
757 :type '(regexp :tag "Empty Lines At End Of Buffer")
758 :group 'whitespace)
761 (defcustom whitespace-space-after-tab-regexp "\t\\(\\( \\{8\\}\\)+\\)"
762 "*Specify regexp for 8 or more SPACEs after TAB.
764 If you're using `mule' package, there may be other characters besides:
766 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
767 \"\\xF20\"
769 that should be considered blank.
771 Used when `whitespace-style' includes the value `color',
772 and `whitespace-chars' includes `space-after-tab'."
773 :type '(regexp :tag "SPACEs After TAB")
774 :group 'whitespace)
777 (defcustom whitespace-line-column 80
778 "*Specify column beyond which the line is highlighted.
780 Used when `whitespace-style' includes the value `color',
781 and `whitespace-chars' includes `lines' or `lines-tail'."
782 :type '(integer :tag "Line Length")
783 :group 'whitespace)
786 ;; Hacked from `visible-whitespace-mappings' in visws.el
787 (defcustom whitespace-display-mappings
788 ;; Due to limitations of glyph representation, the char code can not
789 ;; be above ?\x1FFFF. Probably, this will be fixed after Emacs
790 ;; unicode merging.
792 (?\ [?\xB7] [?.]) ; space - centered dot
793 (?\xA0 [?\xA4] [?_]) ; hard space - currency
794 (?\x8A0 [?\x8A4] [?_]) ; hard space - currency
795 (?\x920 [?\x924] [?_]) ; hard space - currency
796 (?\xE20 [?\xE24] [?_]) ; hard space - currency
797 (?\xF20 [?\xF24] [?_]) ; hard space - currency
798 ;; NEWLINE is displayed using the face `whitespace-newline'
799 (?\n [?$ ?\n]) ; end-of-line - dollar sign
800 ;; (?\n [?\u21B5 ?\n] [?$ ?\n]) ; end-of-line - downwards arrow
801 ;; (?\n [?\xB6 ?\n] [?$ ?\n]) ; end-of-line - pilcrow
802 ;; (?\n [?\x8AF ?\n] [?$ ?\n]) ; end-of-line - overscore
803 ;; (?\n [?\x8AC ?\n] [?$ ?\n]) ; end-of-line - negation
804 ;; (?\n [?\x8B0 ?\n] [?$ ?\n]) ; end-of-line - grade
806 ;; WARNING: the mapping below has a problem.
807 ;; When a TAB occupies exactly one column, it will display the
808 ;; character ?\xBB at that column followed by a TAB which goes to
809 ;; the next TAB column.
810 ;; If this is a problem for you, please, comment the line below.
811 (?\t [?\xBB ?\t] [?\\ ?\t]) ; tab - left quote mark
813 "*Specify an alist of mappings for displaying characters.
815 Each element has the following form:
817 (CHAR VECTOR...)
819 Where:
821 CHAR is the character to be mapped.
823 VECTOR is a vector of characters to be displayed in place of CHAR.
824 The first display vector that can be displayed is used;
825 if no display vector for a mapping can be displayed, then
826 that character is displayed unmodified.
828 The NEWLINE character is displayed using the face given by
829 `whitespace-newline' variable. The characters in the vector to
830 be displayed will not have this face applied if the character
831 code is above #x1FFFF.
833 Used when `whitespace-style' includes the value `mark'."
834 :type '(repeat
835 (list :tag "Character Mapping"
836 (character :tag "Char")
837 (repeat :inline t :tag "Vector List"
838 (vector :tag ""
839 (repeat :inline t
840 :tag "Vector Characters"
841 (character :tag "Char"))))))
842 :group 'whitespace)
845 (defcustom whitespace-global-modes t
846 "*Modes for which global `whitespace-mode' is automagically turned on.
848 Global `whitespace-mode' is controlled by the command
849 `global-whitespace-mode'.
851 If nil, means no modes have `whitespace-mode' automatically
852 turned on.
854 If t, all modes that support `whitespace-mode' have it
855 automatically turned on.
857 Else it should be a list of `major-mode' symbol names for which
858 `whitespace-mode' should be automatically turned on. The sense
859 of the list is negated if it begins with `not'. For example:
861 (c-mode c++-mode)
863 means that `whitespace-mode' is turned on for buffers in C and
864 C++ modes only."
865 :type '(choice (const :tag "None" nil)
866 (const :tag "All" t)
867 (set :menu-tag "Mode Specific" :tag "Modes"
868 :value (not)
869 (const :tag "Except" not)
870 (repeat :inline t
871 (symbol :tag "Mode"))))
872 :group 'whitespace)
875 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
876 ;;;; User commands - Local mode
879 ;;;###autoload
880 (define-minor-mode whitespace-mode
881 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
883 If ARG is null, toggle whitespace visualization.
884 If ARG is a number greater than zero, turn on visualization;
885 otherwise, turn off visualization.
886 Only useful with a windowing system."
887 :lighter " ws"
888 :init-value nil
889 :global nil
890 :group 'whitespace
891 (cond
892 (noninteractive ; running a batch job
893 (setq whitespace-mode nil))
894 (whitespace-mode ; whitespace-mode on
895 (whitespace-turn-on))
896 (t ; whitespace-mode off
897 (whitespace-turn-off))))
900 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
901 ;;;; User commands - Global mode
904 (define-minor-mode global-whitespace-mode
905 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
907 If ARG is null, toggle whitespace visualization.
908 If ARG is a number greater than zero, turn on visualization;
909 otherwise, turn off visualization.
910 Only useful with a windowing system."
911 :lighter " WS"
912 :init-value nil
913 :global t
914 :group 'whitespace
915 (cond
916 (noninteractive ; running a batch job
917 (setq global-whitespace-mode nil))
918 (global-whitespace-mode ; global-whitespace-mode on
919 (save-excursion
920 (if (boundp 'find-file-hook)
921 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled t)
922 (add-hook 'find-file-hooks 'whitespace-turn-on-if-enabled t))
923 (dolist (buffer (buffer-list)) ; adjust all local mode
924 (set-buffer buffer)
925 (unless whitespace-mode
926 (whitespace-turn-on-if-enabled)))))
927 (t ; global-whitespace-mode off
928 (save-excursion
929 (if (boundp 'find-file-hook)
930 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
931 (remove-hook 'find-file-hooks 'whitespace-turn-on-if-enabled))
932 (dolist (buffer (buffer-list)) ; adjust all local mode
933 (set-buffer buffer)
934 (when (or (not whitespace-mode)
935 ;; whitespace is being unloaded
936 (bound-and-true-p unload-function-defs-list))
937 (whitespace-turn-off)))))))
940 (defun whitespace-turn-on-if-enabled ()
941 (when (cond
942 ((eq whitespace-global-modes t))
943 ((listp whitespace-global-modes)
944 (if (eq (car-safe whitespace-global-modes) 'not)
945 (not (memq major-mode (cdr whitespace-global-modes)))
946 (memq major-mode whitespace-global-modes)))
947 (t nil))
948 (let (inhibit-quit)
949 ;; Don't turn on whitespace mode if...
951 ;; ...we don't have a display (we're running a batch job)
952 noninteractive
953 ;; ...or if the buffer is invisible (name starts with a space)
954 (eq (aref (buffer-name) 0) ?\ )
955 ;; ...or if the buffer is temporary (name starts with *)
956 (and (eq (aref (buffer-name) 0) ?*)
957 ;; except the scratch buffer.
958 (not (string= (buffer-name) "*scratch*")))
959 ;; Otherwise, turn on whitespace mode.
960 (whitespace-turn-on)))))
963 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
964 ;;;; User commands - Toggle
967 (defconst whitespace-chars-value-list
968 '(tabs
969 spaces
970 trailing
971 space-before-tab
972 lines
973 lines-tail
974 newline
975 indentation
976 empty
977 space-after-tab
979 "List of valid `whitespace-chars' values.")
982 (defconst whitespace-style-value-list
983 '(color
984 mark
986 "List of valid `whitespace-style' values.")
989 (defconst whitespace-toggle-option-alist
990 '((?t . tabs)
991 (?s . spaces)
992 (?r . trailing)
993 (?b . space-before-tab)
994 (?l . lines)
995 (?L . lines-tail)
996 (?n . newline)
997 (?i . indentation)
998 (?e . empty)
999 (?a . space-after-tab)
1000 (?c . color)
1001 (?m . mark)
1002 (?x . whitespace-chars)
1003 (?z . whitespace-style)
1005 "Alist of toggle options.
1007 Each element has the form:
1009 (CHAR . SYMBOL)
1011 Where:
1013 CHAR is a char which the user will have to type.
1015 SYMBOL is a valid symbol associated with CHAR.
1016 See `whitespace-chars-value-list' and
1017 `whitespace-style-value-list'.")
1020 (defvar whitespace-active-chars nil
1021 "Used to save locally `whitespace-chars' value.")
1022 (make-variable-buffer-local 'whitespace-active-chars)
1024 (defvar whitespace-active-style nil
1025 "Used to save locally `whitespace-style' value.")
1026 (make-variable-buffer-local 'whitespace-active-style)
1029 ;;;###autoload
1030 (defun whitespace-toggle-options (arg)
1031 "Toggle local `whitespace-mode' options.
1033 If local whitespace-mode is off, toggle the option given by ARG
1034 and turn on local whitespace-mode.
1036 If local whitespace-mode is on, toggle the option given by ARG
1037 and restart local whitespace-mode.
1039 Interactively, it reads one of the following chars:
1041 CHAR MEANING
1042 t toggle TAB visualization
1043 s toggle SPACE and HARD SPACE visualization
1044 r toggle trailing blanks visualization
1045 b toggle SPACEs before TAB visualization
1046 l toggle \"long lines\" visualization
1047 L toggle \"long lines\" tail visualization
1048 n toggle NEWLINE visualization
1049 i toggle indentation SPACEs visualization
1050 e toggle empty line at bob and/or eob visualization
1051 a toggle SPACEs after TAB visualization
1052 c toggle color faces
1053 m toggle visual mark
1054 x restore `whitespace-chars' value
1055 z restore `whitespace-style' value
1056 ? display brief help
1058 Non-interactively, ARG should be a symbol or a list of symbols.
1059 The valid symbols are:
1061 tabs toggle TAB visualization
1062 spaces toggle SPACE and HARD SPACE visualization
1063 trailing toggle trailing blanks visualization
1064 space-before-tab toggle SPACEs before TAB visualization
1065 lines toggle \"long lines\" visualization
1066 lines-tail toggle \"long lines\" tail visualization
1067 newline toggle NEWLINE visualization
1068 indentation toggle indentation SPACEs visualization
1069 empty toggle empty line at bob and/or eob visualization
1070 space-after-tab toggle SPACEs after TAB visualization
1071 color toggle color faces
1072 mark toggle visual mark
1073 whitespace-chars restore `whitespace-chars' value
1074 whitespace-style restore `whitespace-style' value
1076 Only useful with a windowing system."
1077 (interactive (whitespace-interactive-char t))
1078 (let ((whitespace-chars
1079 (whitespace-toggle-list
1080 t arg whitespace-active-chars whitespace-chars
1081 'whitespace-chars whitespace-chars-value-list))
1082 (whitespace-style
1083 (whitespace-toggle-list
1084 t arg whitespace-active-style whitespace-style
1085 'whitespace-style whitespace-style-value-list)))
1086 (whitespace-mode 0)
1087 (whitespace-mode 1)))
1090 (defvar whitespace-toggle-chars nil
1091 "Used to toggle the global `whitespace-chars' value.")
1092 (defvar whitespace-toggle-style nil
1093 "Used to toggle the global `whitespace-style' value.")
1096 ;;;###autoload
1097 (defun global-whitespace-toggle-options (arg)
1098 "Toggle global `whitespace-mode' options.
1100 If global whitespace-mode is off, toggle the option given by ARG
1101 and turn on global whitespace-mode.
1103 If global whitespace-mode is on, toggle the option given by ARG
1104 and restart global whitespace-mode.
1106 Interactively, it accepts one of the following chars:
1108 CHAR MEANING
1109 t toggle TAB visualization
1110 s toggle SPACE and HARD SPACE visualization
1111 r toggle trailing blanks visualization
1112 b toggle SPACEs before TAB visualization
1113 l toggle \"long lines\" visualization
1114 L toggle \"long lines\" tail visualization
1115 n toggle NEWLINE visualization
1116 i toggle indentation SPACEs visualization
1117 e toggle empty line at bob and/or eob visualization
1118 a toggle SPACEs after TAB visualization
1119 c toggle color faces
1120 m toggle visual mark
1121 x restore `whitespace-chars' value
1122 z restore `whitespace-style' value
1123 ? display brief help
1125 Non-interactively, ARG should be a symbol or a list of symbols.
1126 The valid symbols are:
1128 tabs toggle TAB visualization
1129 spaces toggle SPACE and HARD SPACE visualization
1130 trailing toggle trailing blanks visualization
1131 space-before-tab toggle SPACEs before TAB visualization
1132 lines toggle \"long lines\" visualization
1133 lines-tail toggle \"long lines\" tail visualization
1134 newline toggle NEWLINE visualization
1135 indentation toggle indentation SPACEs visualization
1136 empty toggle empty line at bob and/or eob visualization
1137 space-after-tab toggle SPACEs after TAB visualization
1138 color toggle color faces
1139 mark toggle visual mark
1140 whitespace-chars restore `whitespace-chars' value
1141 whitespace-style restore `whitespace-style' value
1143 Only useful with a windowing system."
1144 (interactive (whitespace-interactive-char nil))
1145 (let ((whitespace-chars
1146 (whitespace-toggle-list
1147 nil arg whitespace-toggle-chars whitespace-chars
1148 'whitespace-chars whitespace-chars-value-list))
1149 (whitespace-style
1150 (whitespace-toggle-list
1151 nil arg whitespace-toggle-style whitespace-style
1152 'whitespace-style whitespace-style-value-list)))
1153 (setq whitespace-toggle-chars whitespace-chars
1154 whitespace-toggle-style whitespace-style)
1155 (global-whitespace-mode 0)
1156 (global-whitespace-mode 1)))
1159 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1160 ;;;; User commands - Cleanup
1163 ;;;###autoload
1164 (defun whitespace-cleanup ()
1165 "Cleanup some blank problems in all buffer or at region.
1167 It usually applies to the whole buffer, but in transient mark
1168 mode when the mark is active, it applies to the region. It also
1169 applies to the region when it is not in transiente mark mode, the
1170 mark is active and \\[universal-argument] was pressed just before calling
1171 `whitespace-cleanup' interactively.
1173 See also `whitespace-cleanup-region'.
1175 The problems cleaned up are:
1177 1. empty lines at beginning of buffer.
1178 2. empty lines at end of buffer.
1179 If `whitespace-chars' includes the value `empty', remove all
1180 empty lines at beginning and/or end of buffer.
1182 3. 8 or more SPACEs at beginning of line.
1183 If `whitespace-chars' includes the value `indentation', replace
1184 8 or more SPACEs at beginning of line by TABs.
1186 4. SPACEs before TAB.
1187 If `whitespace-chars' includes the value `space-before-tab',
1188 replace SPACEs by TABs.
1190 5. SPACEs or TABs at end of line.
1191 If `whitespace-chars' includes the value `trailing', remove all
1192 SPACEs or TABs at end of line.
1194 6. 8 or more SPACEs after TAB.
1195 If `whitespace-chars' includes the value `space-after-tab',
1196 replace SPACEs by TABs."
1197 (interactive "@*")
1198 (if (and (or transient-mark-mode
1199 current-prefix-arg)
1200 mark-active)
1201 ;; region active
1202 ;; problems 1 and 2 are not handled in region
1203 ;; problem 3: 8 or more SPACEs at bol
1204 ;; problem 4: SPACEs before TAB
1205 ;; problem 5: SPACEs or TABs at eol
1206 ;; problem 6: 8 or more SPACEs after TAB
1207 (whitespace-cleanup-region (region-beginning) (region-end))
1208 ;; whole buffer
1209 (save-excursion
1210 (save-match-data
1211 ;; problem 1: empty lines at bob
1212 ;; problem 2: empty lines at eob
1213 ;; action: remove all empty lines at bob and/or eob
1214 (when (memq 'empty whitespace-chars)
1215 (let (overwrite-mode) ; enforce no overwrite
1216 (goto-char (point-min))
1217 (when (re-search-forward
1218 whitespace-empty-at-bob-regexp nil t)
1219 (delete-region (match-beginning 1) (match-end 1)))
1220 (when (re-search-forward
1221 whitespace-empty-at-eob-regexp nil t)
1222 (delete-region (match-beginning 1) (match-end 1)))))))
1223 ;; problem 3: 8 or more SPACEs at bol
1224 ;; problem 4: SPACEs before TAB
1225 ;; problem 5: SPACEs or TABs at eol
1226 ;; problem 6: 8 or more SPACEs after TAB
1227 (whitespace-cleanup-region (point-min) (point-max))))
1230 ;;;###autoload
1231 (defun whitespace-cleanup-region (start end)
1232 "Cleanup some blank problems at region.
1234 The problems cleaned up are:
1236 1. 8 or more SPACEs at beginning of line.
1237 If `whitespace-chars' includes the value `indentation', replace
1238 8 or more SPACEs at beginning of line by TABs.
1240 2. SPACEs before TAB.
1241 If `whitespace-chars' includes the value `space-before-tab',
1242 replace SPACEs by TABs.
1244 3. SPACEs or TABs at end of line.
1245 If `whitespace-chars' includes the value `trailing', remove all
1246 SPACEs or TABs at end of line.
1248 4. 8 or more SPACEs after TAB.
1249 If `whitespace-chars' includes the value `space-after-tab',
1250 replace SPACEs by TABs."
1251 (interactive "@*r")
1252 (let ((rstart (min start end))
1253 (rend (copy-marker (max start end)))
1254 (tab-width 8) ; assure TAB width
1255 (indent-tabs-mode t) ; always insert TABs
1256 overwrite-mode ; enforce no overwrite
1257 tmp)
1258 (save-excursion
1259 (save-match-data
1260 ;; problem 1: 8 or more SPACEs at bol
1261 ;; action: replace 8 or more SPACEs at bol by TABs
1262 (when (memq 'indentation whitespace-chars)
1263 (goto-char rstart)
1264 (while (re-search-forward
1265 whitespace-indentation-regexp rend t)
1266 (setq tmp (current-indentation))
1267 (delete-horizontal-space)
1268 (unless (eolp)
1269 (indent-to tmp))))
1270 ;; problem 3: SPACEs or TABs at eol
1271 ;; action: remove all SPACEs or TABs at eol
1272 (when (memq 'trailing whitespace-chars)
1273 (let ((regexp (concat "\\(\\(" whitespace-trailing-regexp
1274 "\\)+\\)$")))
1275 (goto-char rstart)
1276 (while (re-search-forward regexp rend t)
1277 (delete-region (match-beginning 1) (match-end 1)))))
1278 ;; problem 4: 8 or more SPACEs after TAB
1279 ;; action: replace 8 or more SPACEs by TABs
1280 (when (memq 'space-after-tab whitespace-chars)
1281 (whitespace-replace-spaces-by-tabs
1282 rstart rend whitespace-space-after-tab-regexp))
1283 ;; problem 2: SPACEs before TAB
1284 ;; action: replace SPACEs before TAB by TABs
1285 (when (memq 'space-before-tab whitespace-chars)
1286 (whitespace-replace-spaces-by-tabs
1287 rstart rend whitespace-space-before-tab-regexp))))
1288 (set-marker rend nil))) ; point marker to nowhere
1291 (defun whitespace-replace-spaces-by-tabs (rstart rend regexp)
1292 "Replace all SPACEs by TABs matched by REGEXP between RSTART and REND."
1293 (goto-char rstart)
1294 (while (re-search-forward regexp rend t)
1295 (goto-char (match-beginning 1))
1296 (let* ((scol (current-column))
1297 (ecol (save-excursion
1298 (goto-char (match-end 1))
1299 (current-column))))
1300 (delete-region (match-beginning 1) (match-end 1))
1301 (insert-char ?\t
1302 (/ (- (- ecol (% ecol 8)) ; prev end col
1303 (- scol (% scol 8))) ; prev start col
1304 8)))))
1307 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1308 ;;;; User command - old whitespace compatibility
1311 ;;;###autoload
1312 (defun whitespace-buffer ()
1313 "Turn on `whitespace-mode' forcing some settings.
1315 It forces `whitespace-style' to have `color'.
1317 It also forces `whitespace-chars' to have:
1319 trailing
1320 indentation
1321 space-before-tab
1322 empty
1323 space-after-tab
1325 So, it is possible to visualize the following problems:
1327 empty 1. empty lines at beginning of buffer.
1328 empty 2. empty lines at end of buffer.
1329 indentation 3. 8 or more SPACEs at beginning of line.
1330 space-before-tab 4. SPACEs before TAB.
1331 trailing 5. SPACEs or TABs at end of line.
1332 space-after-tab 6. 8 or more SPACEs after TAB.
1334 See `whitespace-chars' and `whitespace-style' for documentation.
1335 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1336 cleaning up these problems."
1337 (interactive)
1338 (whitespace-mode 0) ; assure is off
1339 ;; keep original values
1340 (let ((whitespace-style (copy-sequence whitespace-style))
1341 (whitespace-chars (copy-sequence whitespace-chars)))
1342 ;; adjust options for whitespace bogus blanks
1343 (add-to-list 'whitespace-style 'color)
1344 (mapc #'(lambda (option)
1345 (add-to-list 'whitespace-chars option))
1346 '(trailing
1347 indentation
1348 space-before-tab
1349 empty
1350 space-after-tab))
1351 (whitespace-mode 1))) ; turn on
1354 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1355 ;;;; Internal functions
1358 (defvar whitespace-font-lock-mode nil
1359 "Used to remember whether a buffer had font lock mode on or not.")
1360 (make-variable-buffer-local 'whitespace-font-lock-mode)
1362 (defvar whitespace-font-lock nil
1363 "Used to remember whether a buffer initially had font lock on or not.")
1364 (make-variable-buffer-local 'whitespace-font-lock)
1366 (defvar whitespace-font-lock-keywords nil
1367 "Used to save locally `font-lock-keywords' value.")
1368 (make-variable-buffer-local 'whitespace-font-lock-keywords)
1371 (defconst whitespace-help-text
1373 whitespace-mode toggle options:
1375 [] t - toggle TAB visualization
1376 [] s - toggle SPACE and HARD SPACE visualization
1377 [] r - toggle trailing blanks visualization
1378 [] b - toggle SPACEs before TAB visualization
1379 [] l - toggle \"long lines\" visualization
1380 [] L - toggle \"long lines\" tail visualization
1381 [] n - toggle NEWLINE visualization
1382 [] i - toggle indentation SPACEs visualization
1383 [] e - toggle empty line at bob and/or eob visualization
1384 [] a - toggle SPACEs after TAB visualization
1386 [] c - toggle color faces
1387 [] m - toggle visual mark
1389 x - restore `whitespace-chars' value
1390 z - restore `whitespace-style' value
1392 ? - display this text\n\n"
1393 "Text for whitespace toggle options.")
1396 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1397 "The buffer name for whitespace toggle options.")
1400 (defun whitespace-insert-option-mark (the-list the-value)
1401 "Insert the option mark ('X' or ' ') in toggle options buffer."
1402 (forward-line 1)
1403 (dolist (sym the-list)
1404 (forward-line 1)
1405 (forward-char 2)
1406 (insert (if (memq sym the-value) "X" " "))))
1409 (defun whitespace-help-on (chars style)
1410 "Display the whitespace toggle options."
1411 (unless (get-buffer whitespace-help-buffer-name)
1412 (delete-other-windows)
1413 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
1414 (save-excursion
1415 (set-buffer buffer)
1416 (erase-buffer)
1417 (insert whitespace-help-text)
1418 (goto-char (point-min))
1419 (whitespace-insert-option-mark
1420 whitespace-chars-value-list chars)
1421 (whitespace-insert-option-mark
1422 whitespace-style-value-list style)
1423 (goto-char (point-min))
1424 (set-buffer-modified-p nil)
1425 (let ((size (- (window-height)
1426 (max window-min-height
1427 (1+ (count-lines (point-min)
1428 (point-max)))))))
1429 (when (<= size 0)
1430 (kill-buffer buffer)
1431 (error "Frame height is too small; \
1432 can't split window to display whitespace toggle options"))
1433 (set-window-buffer (split-window nil size) buffer))))))
1436 (defun whitespace-help-off ()
1437 "Remove the buffer and window of the whitespace toggle options."
1438 (let ((buffer (get-buffer whitespace-help-buffer-name)))
1439 (when buffer
1440 (delete-windows-on buffer)
1441 (kill-buffer buffer))))
1444 (defun whitespace-interactive-char (local-p)
1445 "Interactive function to read a char and return a symbol.
1447 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1448 uses a global context.
1450 It accepts one of the following chars:
1452 CHAR MEANING
1453 t toggle TAB visualization
1454 s toggle SPACE and HARD SPACE visualization
1455 r toggle trailing blanks visualization
1456 b toggle SPACEs before TAB visualization
1457 l toggle \"long lines\" visualization
1458 L toggle \"long lines\" tail visualization
1459 n toggle NEWLINE visualization
1460 i toggle indentation SPACEs visualization
1461 e toggle empty line at bob and/or eob visualization
1462 a toggle SPACEs after TAB visualization
1463 c toggle color faces
1464 m toggle visual mark
1465 x restore `whitespace-chars' value
1466 z restore `whitespace-style' value
1467 ? display brief help
1469 See also `whitespace-toggle-option-alist'."
1470 (let* ((is-off (not (if local-p
1471 whitespace-mode
1472 global-whitespace-mode)))
1473 (chars (cond (is-off whitespace-chars) ; use default value
1474 (local-p whitespace-active-chars)
1475 (t whitespace-toggle-chars)))
1476 (style (cond (is-off whitespace-style) ; use default value
1477 (local-p whitespace-active-style)
1478 (t whitespace-toggle-style)))
1479 (prompt
1480 (format "Whitespace Toggle %s (type ? for further options)-"
1481 (if local-p "Local" "Global")))
1482 ch sym)
1483 ;; read a valid option and get the corresponding symbol
1484 (save-window-excursion
1485 (condition-case data
1486 (progn
1487 (while
1488 ;; while condition
1489 (progn
1490 (setq ch (read-char prompt))
1491 (not
1492 (setq sym
1493 (cdr
1494 (assq ch whitespace-toggle-option-alist)))))
1495 ;; while body
1496 (if (eq ch ?\?)
1497 (whitespace-help-on chars style)
1498 (ding)))
1499 (whitespace-help-off)
1500 (message " ")) ; clean echo area
1501 ;; handler
1502 ((quit error)
1503 (whitespace-help-off)
1504 (error (error-message-string data)))))
1505 (list sym))) ; return the apropriate symbol
1508 (defun whitespace-toggle-list (local-p arg the-list default-list
1509 sym-restore sym-list)
1510 "Toggle options in THE-LIST based on list ARG.
1512 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1513 uses a global context.
1515 ARG is a list of options to be toggled.
1517 THE-LIST is a list of options. This list will be toggled and the
1518 resultant list will be returned.
1520 DEFAULT-LIST is the default list of options. It is used to
1521 restore the options in THE-LIST.
1523 SYM-RESTORE is the symbol which indicates to restore the options
1524 in THE-LIST.
1526 SYM-LIST is a list of valid options, used to check if the ARG's
1527 options are valid."
1528 (unless (if local-p whitespace-mode global-whitespace-mode)
1529 (setq the-list default-list))
1530 (setq the-list (copy-sequence the-list)) ; keep original list
1531 (dolist (sym (if (listp arg) arg (list arg)))
1532 (cond
1533 ;; restore default values
1534 ((eq sym sym-restore)
1535 (setq the-list default-list))
1536 ;; toggle valid values
1537 ((memq sym sym-list)
1538 (setq the-list (if (memq sym the-list)
1539 (delq sym the-list)
1540 (cons sym the-list))))))
1541 the-list)
1544 (defun whitespace-turn-on ()
1545 "Turn on whitespace visualization."
1546 (setq whitespace-active-style (if (listp whitespace-style)
1547 whitespace-style
1548 (list whitespace-style)))
1549 (setq whitespace-active-chars (if (listp whitespace-chars)
1550 whitespace-chars
1551 (list whitespace-chars)))
1552 (when (memq 'color whitespace-active-style)
1553 (whitespace-color-on))
1554 (when (memq 'mark whitespace-active-style)
1555 (whitespace-display-char-on)))
1558 (defun whitespace-turn-off ()
1559 "Turn off whitespace visualization."
1560 (when (memq 'color whitespace-active-style)
1561 (whitespace-color-off))
1562 (when (memq 'mark whitespace-active-style)
1563 (whitespace-display-char-off)))
1566 (defun whitespace-color-on ()
1567 "Turn on color visualization."
1568 (when whitespace-active-chars
1569 (unless whitespace-font-lock
1570 (setq whitespace-font-lock t
1571 whitespace-font-lock-keywords
1572 (copy-sequence font-lock-keywords)))
1573 ;; turn off font lock
1574 (setq whitespace-font-lock-mode font-lock-mode)
1575 (font-lock-mode 0)
1576 ;; add whitespace-mode color into font lock
1577 (when (memq 'spaces whitespace-active-chars)
1578 (font-lock-add-keywords
1580 (list
1581 ;; Show SPACEs
1582 (list whitespace-space-regexp 1 whitespace-space t)
1583 ;; Show HARD SPACEs
1584 (list whitespace-hspace-regexp 1 whitespace-hspace t))
1586 (when (memq 'tabs whitespace-active-chars)
1587 (font-lock-add-keywords
1589 (list
1590 ;; Show TABs
1591 (list whitespace-tab-regexp 1 whitespace-tab t))
1593 (when (memq 'trailing whitespace-active-chars)
1594 (font-lock-add-keywords
1596 (list
1597 ;; Show trailing blanks
1598 (list (concat "\\(\\(" whitespace-trailing-regexp "\\)+\\)$")
1599 1 whitespace-trailing t))
1601 (when (or (memq 'lines whitespace-active-chars)
1602 (memq 'lines-tail whitespace-active-chars))
1603 (font-lock-add-keywords
1605 (list
1606 ;; Show "long" lines
1607 (list
1608 (format
1609 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
1610 tab-width (1- tab-width)
1611 (/ whitespace-line-column tab-width)
1612 (let ((rem (% whitespace-line-column tab-width)))
1613 (if (zerop rem)
1615 (format ".\\{%d\\}" rem))))
1616 (if (memq 'lines whitespace-active-chars)
1617 0 ; whole line
1618 2) ; line tail
1619 whitespace-line t))
1621 (when (memq 'space-before-tab whitespace-active-chars)
1622 (font-lock-add-keywords
1624 (list
1625 ;; Show SPACEs before TAB
1626 (list whitespace-space-before-tab-regexp
1627 1 whitespace-space-before-tab t))
1629 (when (memq 'indentation whitespace-active-chars)
1630 (font-lock-add-keywords
1632 (list
1633 ;; Show indentation SPACEs
1634 (list whitespace-indentation-regexp
1635 1 whitespace-indentation t))
1637 (when (memq 'empty whitespace-active-chars)
1638 (font-lock-add-keywords
1640 (list
1641 ;; Show empty lines at beginning of buffer
1642 (list whitespace-empty-at-bob-regexp
1643 1 whitespace-empty t))
1645 (font-lock-add-keywords
1647 (list
1648 ;; Show empty lines at end of buffer
1649 (list whitespace-empty-at-eob-regexp
1650 1 whitespace-empty t))
1652 (when (memq 'space-after-tab whitespace-active-chars)
1653 (font-lock-add-keywords
1655 (list
1656 ;; Show SPACEs after TAB
1657 (list whitespace-space-after-tab-regexp
1658 1 whitespace-space-after-tab t))
1660 ;; now turn on font lock and highlight blanks
1661 (font-lock-mode 1)))
1664 (defun whitespace-color-off ()
1665 "Turn off color visualization."
1666 (when whitespace-active-chars
1667 ;; turn off font lock
1668 (font-lock-mode 0)
1669 (when whitespace-font-lock
1670 (setq whitespace-font-lock nil
1671 font-lock-keywords whitespace-font-lock-keywords))
1672 ;; restore original font lock state
1673 (font-lock-mode whitespace-font-lock-mode)))
1676 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1677 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
1680 (defvar whitespace-display-table nil
1681 "Used to save a local display table.")
1682 (make-variable-buffer-local 'whitespace-display-table)
1684 (defvar whitespace-display-table-was-local nil
1685 "Used to remember whether a buffer initially had a local display table.")
1686 (make-variable-buffer-local 'whitespace-display-table-was-local)
1689 (defsubst whitespace-char-valid-p (char)
1690 ;; This check should be improved!!!
1691 (or (< char 256)
1692 (char-valid-p char)))
1695 (defun whitespace-display-vector-p (vec)
1696 "Return true if every character in vector VEC can be displayed."
1697 (let ((i (length vec)))
1698 (when (> i 0)
1699 (while (and (>= (setq i (1- i)) 0)
1700 (whitespace-char-valid-p (aref vec i))))
1701 (< i 0))))
1704 (defun whitespace-display-char-on ()
1705 "Turn on character display mapping."
1706 (when whitespace-display-mappings
1707 (let (vecs vec)
1708 ;; Remember whether a buffer has a local display table.
1709 (unless whitespace-display-table-was-local
1710 (setq whitespace-display-table-was-local t
1711 whitespace-display-table
1712 (copy-sequence buffer-display-table)))
1713 (unless buffer-display-table
1714 (setq buffer-display-table (make-display-table)))
1715 (dolist (entry whitespace-display-mappings)
1716 (setq vecs (cdr entry))
1717 ;; Get a displayable mapping.
1718 (while (and vecs
1719 (not (whitespace-display-vector-p (car vecs))))
1720 (setq vecs (cdr vecs)))
1721 ;; Display a valid mapping.
1722 (when vecs
1723 (setq vec (copy-sequence (car vecs)))
1724 (cond
1725 ;; Any char except newline
1726 ((not (eq (car entry) ?\n))
1727 (aset buffer-display-table (car entry) vec))
1728 ;; Newline char - display it
1729 ((memq 'newline whitespace-active-chars)
1730 ;; Only insert face bits on NEWLINE char mapping to avoid
1731 ;; obstruction of other faces like TABs and (HARD) SPACEs
1732 ;; faces, font-lock faces, etc.
1733 (when (memq 'color whitespace-active-style)
1734 (dotimes (i (length vec))
1735 ;; Due to limitations of glyph representation, the char
1736 ;; code can not be above ?\x1FFFF. Probably, this will
1737 ;; be fixed after Emacs unicode merging.
1738 (or (eq (aref vec i) ?\n)
1739 (> (aref vec i) #x1FFFF)
1740 (aset vec i
1741 (make-glyph-code (aref vec i)
1742 whitespace-newline)))))
1743 ;; Display mapping
1744 (aset buffer-display-table (car entry) vec))
1745 ;; Newline char - don't display it
1747 ;; Do nothing
1748 )))))))
1751 (defun whitespace-display-char-off ()
1752 "Turn off character display mapping."
1753 (and whitespace-display-mappings
1754 whitespace-display-table-was-local
1755 (setq whitespace-display-table-was-local nil
1756 buffer-display-table whitespace-display-table)))
1759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1762 (defun whitespace-unload-function ()
1763 "Unload the Whitespace library."
1764 (global-whitespace-mode -1)
1765 ;; continue standard unloading
1766 nil)
1768 (provide 'whitespace)
1771 (run-hooks 'whitespace-load-hook)
1774 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
1775 ;;; whitespace.el ends here