Change copyright to FSF, per the author's statement:
[emacs.git] / lisp / whitespace.el
blob5c65e24d40577aaf071835987583762680f428fb
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
183 ;; 8 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
280 ;; `whitespace-mode' is automagically
281 ;; turned on.
284 ;; Acknowledgements
285 ;; ----------------
287 ;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
288 ;; lines tail. See EightyColumnRule (EmacsWiki).
290 ;; Thanks to Juri Linkov <juri@jurta.org> for suggesting:
291 ;; * `define-minor-mode'.
292 ;; * `global-whitespace-*' name for global commands.
294 ;; Thanks to Robert J. Chassell <bob@gnu.org> for doc fix and testing.
296 ;; Thanks to Drew Adams <drew.adams@oracle.com> for toggle commands
297 ;; suggestion.
299 ;; Thanks to Antti Kaihola <antti.kaihola@linux-aktivaattori.org> for
300 ;; helping to fix `find-file-hooks' reference.
302 ;; Thanks to Andreas Roehler <andreas.roehler@easy-emacs.de> for
303 ;; indicating defface byte-compilation warnings.
305 ;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight
306 ;; "long" lines. See EightyColumnRule (EmacsWiki).
308 ;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
309 ;; newline character mapping.
311 ;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
312 ;; whitespace-mode.el on XEmacs.
314 ;; Thanks to Miles Bader <miles@gnu.org> for handling display table via
315 ;; visws.el (his code was modified, but the main idea was kept).
317 ;; Thanks to:
318 ;; Rajesh Vaidheeswarran <rv@gnu.org> (original) whitespace.el
319 ;; Aurelien Tisne <aurelien.tisne@free.fr> show-whitespace-mode.el
320 ;; Lawrence Mitchell <wence@gmx.li> whitespace-mode.el
321 ;; Miles Bader <miles@gnu.org> visws.el
322 ;; And to all people who contributed with them.
325 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
327 ;;; code:
330 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
331 ;;;; User Variables:
334 ;;; Interface to the command system
337 (defgroup whitespace nil
338 "Visualize blanks (TAB, (HARD) SPACE and NEWLINE)."
339 :link '(emacs-library-link :tag "Source Lisp File" "whitespace.el")
340 :version "23.1"
341 :group 'wp
342 :group 'data)
345 (defcustom whitespace-style '(mark color)
346 "*Specify the visualization style.
348 It's a list containing some or all of the following values:
350 mark display mappings are visualized.
352 color faces are visualized.
354 Any other value is ignored.
356 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
358 See also `whitespace-display-mappings' for documentation."
359 :type '(repeat :tag "Style of Blank"
360 (choice :tag "Style of Blank"
361 (const :tag "Display Table" mark)
362 (const :tag "Faces" color)))
363 :group 'whitespace)
366 (defcustom whitespace-chars
367 '(tabs spaces trailing lines space-before-tab newline
368 indentation empty space-after-tab)
369 "*Specify which kind of blank is visualized.
371 It's a list containing some or all of the following values:
373 trailing trailing blanks are visualized.
375 tabs TABs are visualized.
377 spaces SPACEs and HARD SPACEs are visualized.
379 lines lines whose have columns beyond
380 `whitespace-line-column' are highlighted.
381 Whole line is highlighted.
382 It has precedence over
383 `lines-tail' (see below).
385 lines-tail lines whose have columns beyond
386 `whitespace-line-column' are highlighted.
387 But only the part of line which goes
388 beyond `whitespace-line-column' column.
389 It has effect only if `lines' (see above)
390 is not present in `whitespace-chars'.
392 space-before-tab SPACEs before TAB are visualized.
394 newline NEWLINEs are visualized.
396 indentation 8 or more SPACEs at beginning of line are
397 visualized.
399 empty empty lines at beginning and/or end of buffer
400 are visualized.
402 space-after-tab 8 or more SPACEs after a TAB are visualized.
404 Any other value is ignored.
406 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
408 Used when `whitespace-style' includes the value `color'.
409 Used also when `whitespace-chars' includes `newline',
410 and `whitespace-style' includes `mark'."
411 :type '(repeat :tag "Kind of Blank"
412 (choice :tag "Kind of Blank"
413 (const :tag "Trailing TABs, SPACEs and HARD SPACEs"
414 trailing)
415 (const :tag "SPACEs and HARD SPACEs" spaces)
416 (const :tag "TABs" tabs)
417 (const :tag "Lines" lines)
418 (const :tag "SPACEs before TAB"
419 space-before-tab)
420 (const :tag "NEWLINEs" newline)
421 (const :tag "Indentation SPACEs" indentation)
422 (const :tag "Empty Lines At BOB And/Or EOB"
423 empty)
424 (const :tag "SPACEs after TAB"
425 space-after-tab)))
426 :group 'whitespace)
429 (defcustom whitespace-space 'whitespace-space
430 "*Symbol face used to visualize SPACE.
432 Used when `whitespace-style' includes the value `color'."
433 :type 'face
434 :group 'whitespace)
437 (defface whitespace-space
438 '((((class color) (background dark))
439 (:background "grey20" :foreground "aquamarine3"))
440 (((class color) (background light))
441 (:background "LightYellow" :foreground "aquamarine3"))
442 (t (:inverse-video t)))
443 "Face used to visualize SPACE."
444 :group 'whitespace)
447 (defcustom whitespace-hspace 'whitespace-hspace
448 "*Symbol face used to visualize HARD SPACE.
450 Used when `whitespace-style' includes the value `color'."
451 :type 'face
452 :group 'whitespace)
455 (defface whitespace-hspace ; 'nobreak-space
456 '((((class color) (background dark))
457 (:background "grey24" :foreground "aquamarine3"))
458 (((class color) (background light))
459 (:background "LemonChiffon3" :foreground "aquamarine3"))
460 (t (:inverse-video t)))
461 "Face used to visualize HARD SPACE."
462 :group 'whitespace)
465 (defcustom whitespace-tab 'whitespace-tab
466 "*Symbol face used to visualize TAB.
468 Used when `whitespace-style' includes the value `color'."
469 :type 'face
470 :group 'whitespace)
473 (defface whitespace-tab
474 '((((class color) (background dark))
475 (:background "grey22" :foreground "aquamarine3"))
476 (((class color) (background light))
477 (:background "beige" :foreground "aquamarine3"))
478 (t (:inverse-video t)))
479 "Face used to visualize TAB."
480 :group 'whitespace)
483 (defcustom whitespace-newline 'whitespace-newline
484 "*Symbol face used to visualize NEWLINE char mapping.
486 See `whitespace-display-mappings'.
488 Used when `whitespace-style' includes the values `mark'
489 and `color', and `whitespace-chars' includes `newline'."
490 :type 'face
491 :group 'whitespace)
494 (defface whitespace-newline
495 '((((class color) (background dark))
496 (:background "grey26" :foreground "aquamarine3" :bold t))
497 (((class color) (background light))
498 (:background "linen" :foreground "aquamarine3" :bold t))
499 (t (:bold t :underline t)))
500 "Face used to visualize NEWLINE char mapping.
502 See `whitespace-display-mappings'."
503 :group 'whitespace)
506 (defcustom whitespace-trailing 'whitespace-trailing
507 "*Symbol face used to visualize traling blanks.
509 Used when `whitespace-style' includes the value `color'."
510 :type 'face
511 :group 'whitespace)
514 (defface whitespace-trailing ; 'trailing-whitespace
515 '((((class mono)) (:inverse-video t :bold t :underline t))
516 (t (:background "red1" :foreground "yellow" :bold t)))
517 "Face used to visualize trailing blanks."
518 :group 'whitespace)
521 (defcustom whitespace-line 'whitespace-line
522 "*Symbol face used to visualize \"long\" lines.
524 See `whitespace-line-column'.
526 Used when `whitespace-style' includes the value `color'."
527 :type 'face
528 :group 'whitespace)
531 (defface whitespace-line
532 '((((class mono)) (:inverse-video t :bold t :underline t))
533 (t (:background "gray20" :foreground "violet")))
534 "Face used to visualize \"long\" lines.
536 See `whitespace-line-column'."
537 :group 'whitespace)
540 (defcustom whitespace-space-before-tab 'whitespace-space-before-tab
541 "*Symbol face used to visualize SPACEs before TAB.
543 Used when `whitespace-style' includes the value `color'."
544 :type 'face
545 :group 'whitespace)
548 (defface whitespace-space-before-tab
549 '((((class mono)) (:inverse-video t :bold t :underline t))
550 (t (:background "DarkOrange" :foreground "firebrick")))
551 "Face used to visualize SPACEs before TAB."
552 :group 'whitespace)
555 (defcustom whitespace-indentation 'whitespace-indentation
556 "*Symbol face used to visualize 8 or more SPACEs at beginning of line.
558 Used when `whitespace-style' includes the value `color'."
559 :type 'face
560 :group 'whitespace)
563 (defface whitespace-indentation
564 '((((class mono)) (:inverse-video t :bold t :underline t))
565 (t (:background "yellow" :foreground "firebrick")))
566 "Face used to visualize 8 or more SPACEs at beginning of line."
567 :group 'whitespace)
570 (defcustom whitespace-empty 'whitespace-empty
571 "*Symbol face used to visualize empty lines at beginning and/or end of buffer.
573 Used when `whitespace-style' includes the value `color'."
574 :type 'face
575 :group 'whitespace)
578 (defface whitespace-empty
579 '((((class mono)) (:inverse-video t :bold t :underline t))
580 (t (:background "yellow" :foreground "firebrick")))
581 "Face used to visualize empty lines at beginning and/or end of buffer."
582 :group 'whitespace)
585 (defcustom whitespace-space-after-tab 'whitespace-space-after-tab
586 "*Symbol face used to visualize 8 or more SPACEs after TAB.
588 Used when `whitespace-style' includes the value `color'."
589 :type 'face
590 :group 'whitespace)
593 (defface whitespace-space-after-tab
594 '((((class mono)) (:inverse-video t :bold t :underline t))
595 (t (:background "yellow" :foreground "firebrick")))
596 "Face used to visualize 8 or more SPACEs after TAB."
597 :group 'whitespace)
600 (defcustom whitespace-hspace-regexp
601 "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
602 "*Specify HARD SPACE characters regexp.
604 If you're using `mule' package, there may be other characters besides:
606 \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
608 that should be considered HARD SPACE.
610 Here are some examples:
612 \"\\\\(^\\xA0+\\\\)\" \
613 visualize only leading HARD SPACEs.
614 \"\\\\(\\xA0+$\\\\)\" \
615 visualize only trailing HARD SPACEs.
616 \"\\\\(^\\xA0+\\\\|\\xA0+$\\\\)\" \
617 visualize leading and/or trailing HARD SPACEs.
618 \"\\t\\\\(\\xA0+\\\\)\\t\" \
619 visualize only HARD SPACEs between TABs.
621 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
622 Use exactly one pair of enclosing \\\\( and \\\\).
624 Used when `whitespace-style' includes the value `color',
625 and `whitespace-chars' includes `spaces'."
626 :type '(regexp :tag "HARD SPACE Chars")
627 :group 'whitespace)
630 (defcustom whitespace-space-regexp "\\( +\\)"
631 "*Specify SPACE characters regexp.
633 If you're using `mule' package, there may be other characters
634 besides \" \" that should be considered SPACE.
636 Here are some examples:
638 \"\\\\(^ +\\\\)\" visualize only leading SPACEs.
639 \"\\\\( +$\\\\)\" visualize only trailing SPACEs.
640 \"\\\\(^ +\\\\| +$\\\\)\" \
641 visualize leading and/or trailing SPACEs.
642 \"\\t\\\\( +\\\\)\\t\" visualize only SPACEs between TABs.
644 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
645 Use exactly one pair of enclosing \\\\( and \\\\).
647 Used when `whitespace-style' includes the value `color',
648 and `whitespace-chars' includes `spaces'."
649 :type '(regexp :tag "SPACE Chars")
650 :group 'whitespace)
653 (defcustom whitespace-tab-regexp "\\(\t+\\)"
654 "*Specify TAB characters regexp.
656 If you're using `mule' package, there may be other characters
657 besides \"\\t\" that should be considered TAB.
659 Here are some examples:
661 \"\\\\(^\\t+\\\\)\" visualize only leading TABs.
662 \"\\\\(\\t+$\\\\)\" visualize only trailing TABs.
663 \"\\\\(^\\t+\\\\|\\t+$\\\\)\" \
664 visualize leading and/or trailing TABs.
665 \" \\\\(\\t+\\\\) \" visualize only TABs between SPACEs.
667 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
668 Use exactly one pair of enclosing \\\\( and \\\\).
670 Used when `whitespace-style' includes the value `color',
671 and `whitespace-chars' includes `tabs'."
672 :type '(regexp :tag "TAB Chars")
673 :group 'whitespace)
676 (defcustom whitespace-trailing-regexp
677 "\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20"
678 "*Specify trailing characters regexp.
680 If you're using `mule' package, there may be other characters besides:
682 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
683 \"\\xF20\"
685 that should be considered blank.
687 NOTE: DO NOT enclose by \\\\( and \\\\) the elements to highlight.
688 `whitespace-mode' surrounds this regexp by \"\\\\(\\\\(\" and
689 \"\\\\)+\\\\)$\".
691 Used when `whitespace-style' includes the value `color',
692 and `whitespace-chars' includes `trailing'."
693 :type '(regexp :tag "Trailing Chars")
694 :group 'whitespace)
697 (defcustom whitespace-space-before-tab-regexp "\\( +\\)\t"
698 "*Specify SPACEs before TAB regexp.
700 If you're using `mule' package, there may be other characters besides:
702 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
703 \"\\xF20\"
705 that should be considered blank.
707 Used when `whitespace-style' includes the value `color',
708 and `whitespace-chars' includes `space-before-tab'."
709 :type '(regexp :tag "SPACEs Before TAB")
710 :group 'whitespace)
713 (defcustom whitespace-indentation-regexp
714 "^\t*\\(\\( \\{8\\}\\)+\\)[^\n\t]"
715 "*Specify regexp for 8 or more SPACEs at beginning of line.
717 If you're using `mule' package, there may be other characters besides:
719 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
720 \"\\xF20\"
722 that should be considered blank.
724 Used when `whitespace-style' includes the value `color',
725 and `whitespace-chars' includes `indentation'."
726 :type '(regexp :tag "Indentation SPACEs")
727 :group 'whitespace)
730 (defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
731 "*Specify regexp for empty lines at beginning of buffer.
733 If you're using `mule' package, there may be other characters besides:
735 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
736 \"\\xF20\"
738 that should be considered blank.
740 Used when `whitespace-style' includes the value `color',
741 and `whitespace-chars' includes `empty'."
742 :type '(regexp :tag "Empty Lines At Beginning Of Buffer")
743 :group 'whitespace)
746 (defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
747 "*Specify regexp for empty lines at end of buffer.
749 If you're using `mule' package, there may be other characters besides:
751 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
752 \"\\xF20\"
754 that should be considered blank.
756 Used when `whitespace-style' includes the value `color',
757 and `whitespace-chars' includes `empty'."
758 :type '(regexp :tag "Empty Lines At End Of Buffer")
759 :group 'whitespace)
762 (defcustom whitespace-space-after-tab-regexp "\t\\(\\( \\{8\\}\\)+\\)"
763 "*Specify regexp for 8 or more SPACEs after TAB.
765 If you're using `mule' package, there may be other characters besides:
767 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
768 \"\\xF20\"
770 that should be considered blank.
772 Used when `whitespace-style' includes the value `color',
773 and `whitespace-chars' includes `space-after-tab'."
774 :type '(regexp :tag "SPACEs After TAB")
775 :group 'whitespace)
778 (defcustom whitespace-line-column 80
779 "*Specify column beyond which the line is highlighted.
781 Used when `whitespace-style' includes the value `color',
782 and `whitespace-chars' includes `lines' or `lines-tail'."
783 :type '(integer :tag "Line Length")
784 :group 'whitespace)
787 ;; Hacked from `visible-whitespace-mappings' in visws.el
788 (defcustom whitespace-display-mappings
789 ;; Due to limitations of glyph representation, the char code can not
790 ;; be above ?\x1FFFF. Probably, this will be fixed after Emacs
791 ;; unicode merging.
793 (?\ [?\xB7] [?.]) ; space - centered dot
794 (?\xA0 [?\xA4] [?_]) ; hard space - currency
795 (?\x8A0 [?\x8A4] [?_]) ; hard space - currency
796 (?\x920 [?\x924] [?_]) ; hard space - currency
797 (?\xE20 [?\xE24] [?_]) ; hard space - currency
798 (?\xF20 [?\xF24] [?_]) ; hard space - currency
799 ;; NEWLINE is displayed using the face `whitespace-newline'
800 (?\n [?$ ?\n]) ; end-of-line - dollar sign
801 ;; (?\n [?\u21B5 ?\n] [?$ ?\n]) ; end-of-line - downwards arrow
802 ;; (?\n [?\xB6 ?\n] [?$ ?\n]) ; end-of-line - pilcrow
803 ;; (?\n [?\x8AF ?\n] [?$ ?\n]) ; end-of-line - overscore
804 ;; (?\n [?\x8AC ?\n] [?$ ?\n]) ; end-of-line - negation
805 ;; (?\n [?\x8B0 ?\n] [?$ ?\n]) ; end-of-line - grade
807 ;; WARNING: the mapping below has a problem.
808 ;; When a TAB occupies exactly one column, it will display the
809 ;; character ?\xBB at that column followed by a TAB which goes to
810 ;; the next TAB column.
811 ;; If this is a problem for you, please, comment the line below.
812 (?\t [?\xBB ?\t] [?\\ ?\t]) ; tab - left quote mark
814 "*Specify an alist of mappings for displaying characters.
816 Each element has the following form:
818 (CHAR VECTOR...)
820 Where:
822 CHAR is the character to be mapped.
824 VECTOR is a vector of characters to be displayed in place of CHAR.
825 The first display vector that can be displayed is used;
826 if no display vector for a mapping can be displayed, then
827 that character is displayed unmodified.
829 The NEWLINE character is displayed using the face given by
830 `whitespace-newline' variable. The characters in the vector to
831 be displayed will not have this face applied if the character
832 code is above #x1FFFF.
834 Used when `whitespace-style' includes the value `mark'."
835 :type '(repeat
836 (list :tag "Character Mapping"
837 (character :tag "Char")
838 (repeat :inline t :tag "Vector List"
839 (vector :tag ""
840 (repeat :inline t
841 :tag "Vector Characters"
842 (character :tag "Char"))))))
843 :group 'whitespace)
846 (defcustom whitespace-global-modes t
847 "*Modes for which global `whitespace-mode' is automagically turned on.
849 Global `whitespace-mode' is controlled by the command
850 `global-whitespace-mode'.
852 If nil, means no modes have `whitespace-mode' automatically
853 turned on.
855 If t, all modes that support `whitespace-mode' have it
856 automatically turned on.
858 Else it should be a list of `major-mode' symbol names for which
859 `whitespace-mode' should be automatically turned on. The sense
860 of the list is negated if it begins with `not'. For example:
862 (c-mode c++-mode)
864 means that `whitespace-mode' is turned on for buffers in C and
865 C++ modes only."
866 :type '(choice (const :tag "None" nil)
867 (const :tag "All" t)
868 (set :menu-tag "Mode Specific" :tag "Modes"
869 :value (not)
870 (const :tag "Except" not)
871 (repeat :inline t
872 (symbol :tag "Mode"))))
873 :group 'whitespace)
876 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
877 ;;;; User commands - Local mode
880 ;;;###autoload
881 (define-minor-mode whitespace-mode
882 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
884 If ARG is null, toggle whitespace visualization.
885 If ARG is a number greater than zero, turn on visualization;
886 otherwise, turn off visualization.
887 Only useful with a windowing system."
888 :lighter " ws"
889 :init-value nil
890 :global nil
891 :group 'whitespace
892 (cond
893 (noninteractive ; running a batch job
894 (setq whitespace-mode nil))
895 (whitespace-mode ; whitespace-mode on
896 (whitespace-turn-on))
897 (t ; whitespace-mode off
898 (whitespace-turn-off))))
901 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
902 ;;;; User commands - Global mode
905 (define-minor-mode global-whitespace-mode
906 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
908 If ARG is null, toggle whitespace visualization.
909 If ARG is a number greater than zero, turn on visualization;
910 otherwise, turn off visualization.
911 Only useful with a windowing system."
912 :lighter " WS"
913 :init-value nil
914 :global t
915 :group 'whitespace
916 (cond
917 (noninteractive ; running a batch job
918 (setq global-whitespace-mode nil))
919 (global-whitespace-mode ; global-whitespace-mode on
920 (save-excursion
921 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled t)
922 (dolist (buffer (buffer-list)) ; adjust all local mode
923 (set-buffer buffer)
924 (unless whitespace-mode
925 (whitespace-turn-on-if-enabled)))))
926 (t ; global-whitespace-mode off
927 (save-excursion
928 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
929 (dolist (buffer (buffer-list)) ; adjust all local mode
930 (set-buffer buffer)
931 (unless whitespace-mode
932 (whitespace-turn-off)))))))
935 (defun whitespace-turn-on-if-enabled ()
936 (when (cond
937 ((eq whitespace-global-modes t))
938 ((listp whitespace-global-modes)
939 (if (eq (car-safe whitespace-global-modes) 'not)
940 (not (memq major-mode (cdr whitespace-global-modes)))
941 (memq major-mode whitespace-global-modes)))
942 (t nil))
943 (let (inhibit-quit)
944 ;; Don't turn on whitespace mode if...
946 ;; ...we don't have a display (we're running a batch job)
947 noninteractive
948 ;; ...or if the buffer is invisible (name starts with a space)
949 (eq (aref (buffer-name) 0) ?\ )
950 ;; ...or if the buffer is temporary (name starts with *)
951 (and (eq (aref (buffer-name) 0) ?*)
952 ;; except the scratch buffer.
953 (not (string= (buffer-name) "*scratch*")))
954 ;; Otherwise, turn on whitespace mode.
955 (whitespace-turn-on)))))
958 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
959 ;;;; User commands - Toggle
962 (defconst whitespace-chars-value-list
963 '(tabs
964 spaces
965 trailing
966 space-before-tab
967 lines
968 lines-tail
969 newline
970 indentation
971 empty
972 space-after-tab
974 "List of valid `whitespace-chars' values.")
977 (defconst whitespace-style-value-list
978 '(color
979 mark
981 "List of valid `whitespace-style' values.")
984 (defconst whitespace-toggle-option-alist
985 '((?t . tabs)
986 (?s . spaces)
987 (?r . trailing)
988 (?b . space-before-tab)
989 (?l . lines)
990 (?L . lines-tail)
991 (?n . newline)
992 (?i . indentation)
993 (?e . empty)
994 (?a . space-after-tab)
995 (?c . color)
996 (?m . mark)
997 (?x . whitespace-chars)
998 (?z . whitespace-style)
1000 "Alist of toggle options.
1002 Each element has the form:
1004 (CHAR . SYMBOL)
1006 Where:
1008 CHAR is a char which the user will have to type.
1010 SYMBOL is a valid symbol associated with CHAR.
1011 See `whitespace-chars-value-list' and
1012 `whitespace-style-value-list'.")
1015 (defvar whitespace-active-chars nil
1016 "Used to save locally `whitespace-chars' value.")
1017 (make-variable-buffer-local 'whitespace-active-chars)
1019 (defvar whitespace-active-style nil
1020 "Used to save locally `whitespace-style' value.")
1021 (make-variable-buffer-local 'whitespace-active-style)
1024 ;;;###autoload
1025 (defun whitespace-toggle-options (arg)
1026 "Toggle local `whitespace-mode' options.
1028 If local whitespace-mode is off, toggle the option given by ARG
1029 and turn on local whitespace-mode.
1031 If local whitespace-mode is on, toggle the option given by ARG
1032 and restart local whitespace-mode.
1034 Interactively, it reads one of the following chars:
1036 CHAR MEANING
1037 t toggle TAB visualization
1038 s toggle SPACE and HARD SPACE visualization
1039 r toggle trailing blanks visualization
1040 b toggle SPACEs before TAB visualization
1041 l toggle \"long lines\" visualization
1042 L toggle \"long lines\" tail visualization
1043 n toggle NEWLINE visualization
1044 i toggle indentation SPACEs visualization
1045 e toggle empty line at bob and/or eob visualization
1046 a toggle SPACEs after TAB visualization
1047 c toggle color faces
1048 m toggle visual mark
1049 x restore `whitespace-chars' value
1050 z restore `whitespace-style' value
1051 ? display brief help
1053 Non-interactively, ARG should be a symbol or a list of symbols.
1054 The valid symbols are:
1056 tabs toggle TAB visualization
1057 spaces toggle SPACE and HARD SPACE visualization
1058 trailing toggle trailing blanks visualization
1059 space-before-tab toggle SPACEs before TAB visualization
1060 lines toggle \"long lines\" visualization
1061 lines-tail toggle \"long lines\" tail visualization
1062 newline toggle NEWLINE visualization
1063 indentation toggle indentation SPACEs visualization
1064 empty toggle empty line at bob and/or eob visualization
1065 space-after-tab toggle SPACEs after TAB visualization
1066 color toggle color faces
1067 mark toggle visual mark
1068 whitespace-chars restore `whitespace-chars' value
1069 whitespace-style restore `whitespace-style' value
1071 Only useful with a windowing system."
1072 (interactive (whitespace-interactive-char t))
1073 (let ((whitespace-chars
1074 (whitespace-toggle-list
1075 t arg whitespace-active-chars whitespace-chars
1076 'whitespace-chars whitespace-chars-value-list))
1077 (whitespace-style
1078 (whitespace-toggle-list
1079 t arg whitespace-active-style whitespace-style
1080 'whitespace-style whitespace-style-value-list)))
1081 (whitespace-mode 0)
1082 (whitespace-mode 1)))
1085 (defvar whitespace-toggle-chars nil
1086 "Used to toggle the global `whitespace-chars' value.")
1087 (defvar whitespace-toggle-style nil
1088 "Used to toggle the global `whitespace-style' value.")
1091 ;;;###autoload
1092 (defun global-whitespace-toggle-options (arg)
1093 "Toggle global `whitespace-mode' options.
1095 If global whitespace-mode is off, toggle the option given by ARG
1096 and turn on global whitespace-mode.
1098 If global whitespace-mode is on, toggle the option given by ARG
1099 and restart global whitespace-mode.
1101 Interactively, it accepts one of the following chars:
1103 CHAR MEANING
1104 t toggle TAB visualization
1105 s toggle SPACE and HARD SPACE visualization
1106 r toggle trailing blanks visualization
1107 b toggle SPACEs before TAB visualization
1108 l toggle \"long lines\" visualization
1109 L toggle \"long lines\" tail visualization
1110 n toggle NEWLINE visualization
1111 i toggle indentation SPACEs visualization
1112 e toggle empty line at bob and/or eob visualization
1113 a toggle SPACEs after TAB visualization
1114 c toggle color faces
1115 m toggle visual mark
1116 x restore `whitespace-chars' value
1117 z restore `whitespace-style' value
1118 ? display brief help
1120 Non-interactively, ARG should be a symbol or a list of symbols.
1121 The valid symbols are:
1123 tabs toggle TAB visualization
1124 spaces toggle SPACE and HARD SPACE visualization
1125 trailing toggle trailing blanks visualization
1126 space-before-tab toggle SPACEs before TAB visualization
1127 lines toggle \"long lines\" visualization
1128 lines-tail toggle \"long lines\" tail visualization
1129 newline toggle NEWLINE visualization
1130 indentation toggle indentation SPACEs visualization
1131 empty toggle empty line at bob and/or eob visualization
1132 space-after-tab toggle SPACEs after TAB visualization
1133 color toggle color faces
1134 mark toggle visual mark
1135 whitespace-chars restore `whitespace-chars' value
1136 whitespace-style restore `whitespace-style' value
1138 Only useful with a windowing system."
1139 (interactive (whitespace-interactive-char nil))
1140 (let ((whitespace-chars
1141 (whitespace-toggle-list
1142 nil arg whitespace-toggle-chars whitespace-chars
1143 'whitespace-chars whitespace-chars-value-list))
1144 (whitespace-style
1145 (whitespace-toggle-list
1146 nil arg whitespace-toggle-style whitespace-style
1147 'whitespace-style whitespace-style-value-list)))
1148 (setq whitespace-toggle-chars whitespace-chars
1149 whitespace-toggle-style whitespace-style)
1150 (global-whitespace-mode 0)
1151 (global-whitespace-mode 1)))
1154 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1155 ;;;; User commands - Cleanup
1158 ;;;###autoload
1159 (defun whitespace-cleanup ()
1160 "Cleanup some blank problems in all buffer or at region.
1162 It usually applies to the whole buffer, but in transient mark
1163 mode when the mark is active, it applies to the region. It also
1164 applies to the region when it is not in transiente mark mode, the
1165 mark is active and \\[universal-argument] was pressed just before calling
1166 `whitespace-cleanup' interactively.
1168 See also `whitespace-cleanup-region'.
1170 The problems cleaned up are:
1172 1. empty lines at beginning of buffer.
1173 2. empty lines at end of buffer.
1174 If `whitespace-chars' includes the value `empty', remove all
1175 empty lines at beginning and/or end of buffer.
1177 3. 8 or more SPACEs at beginning of line.
1178 If `whitespace-chars' includes the value `indentation', replace
1179 8 or more SPACEs at beginning of line by TABs.
1181 4. SPACEs before TAB.
1182 If `whitespace-chars' includes the value `space-before-tab',
1183 replace SPACEs by TABs.
1185 5. SPACEs or TABs at end of line.
1186 If `whitespace-chars' includes the value `trailing', remove all
1187 SPACEs or TABs at end of line.
1189 6. 8 or more SPACEs after TAB.
1190 If `whitespace-chars' includes the value `space-after-tab',
1191 replace SPACEs by TABs."
1192 (interactive "@*")
1193 (if (and (or transient-mark-mode
1194 current-prefix-arg)
1195 mark-active)
1196 ;; region active
1197 ;; problems 1 and 2 are not handled in region
1198 ;; problem 3: 8 or more SPACEs at bol
1199 ;; problem 4: SPACEs before TAB
1200 ;; problem 5: SPACEs or TABs at eol
1201 ;; problem 6: 8 or more SPACEs after TAB
1202 (whitespace-cleanup-region (region-beginning) (region-end))
1203 ;; whole buffer
1204 (save-excursion
1205 (save-match-data
1206 ;; problem 1: empty lines at bob
1207 ;; problem 2: empty lines at eob
1208 ;; action: remove all empty lines at bob and/or eob
1209 (when (memq 'empty whitespace-chars)
1210 (let (overwrite-mode) ; enforce no overwrite
1211 (goto-char (point-min))
1212 (when (re-search-forward
1213 whitespace-empty-at-bob-regexp nil t)
1214 (delete-region (match-beginning 1) (match-end 1)))
1215 (when (re-search-forward
1216 whitespace-empty-at-eob-regexp nil t)
1217 (delete-region (match-beginning 1) (match-end 1)))))))
1218 ;; problem 3: 8 or more SPACEs at bol
1219 ;; problem 4: SPACEs before TAB
1220 ;; problem 5: SPACEs or TABs at eol
1221 ;; problem 6: 8 or more SPACEs after TAB
1222 (whitespace-cleanup-region (point-min) (point-max))))
1225 ;;;###autoload
1226 (defun whitespace-cleanup-region (start end)
1227 "Cleanup some blank problems at region.
1229 The problems cleaned up are:
1231 1. 8 or more SPACEs at beginning of line.
1232 If `whitespace-chars' includes the value `indentation', replace
1233 8 or more SPACEs at beginning of line by TABs.
1235 2. SPACEs before TAB.
1236 If `whitespace-chars' includes the value `space-before-tab',
1237 replace SPACEs by TABs.
1239 3. SPACEs or TABs at end of line.
1240 If `whitespace-chars' includes the value `trailing', remove all
1241 SPACEs or TABs at end of line.
1243 4. 8 or more SPACEs after TAB.
1244 If `whitespace-chars' includes the value `space-after-tab',
1245 replace SPACEs by TABs."
1246 (interactive "@*r")
1247 (let ((rstart (min start end))
1248 (rend (copy-marker (max start end)))
1249 (tab-width 8) ; assure TAB width
1250 (indent-tabs-mode t) ; always insert TABs
1251 overwrite-mode ; enforce no overwrite
1252 tmp)
1253 (save-excursion
1254 (save-match-data
1255 ;; problem 1: 8 or more SPACEs at bol
1256 ;; action: replace 8 or more SPACEs at bol by TABs
1257 (when (memq 'indentation whitespace-chars)
1258 (goto-char rstart)
1259 (while (re-search-forward
1260 whitespace-indentation-regexp rend t)
1261 (setq tmp (current-indentation))
1262 (delete-horizontal-space)
1263 (unless (eolp)
1264 (indent-to tmp))))
1265 ;; problem 3: SPACEs or TABs at eol
1266 ;; action: remove all SPACEs or TABs at eol
1267 (when (memq 'trailing whitespace-chars)
1268 (let ((regexp (concat "\\(\\(" whitespace-trailing-regexp
1269 "\\)+\\)$")))
1270 (goto-char rstart)
1271 (while (re-search-forward regexp rend t)
1272 (delete-region (match-beginning 1) (match-end 1)))))
1273 ;; problem 4: 8 or more SPACEs after TAB
1274 ;; action: replace 8 or more SPACEs by TABs
1275 (when (memq 'space-after-tab whitespace-chars)
1276 (whitespace-replace-spaces-by-tabs
1277 rstart rend whitespace-space-after-tab-regexp))
1278 ;; problem 2: SPACEs before TAB
1279 ;; action: replace SPACEs before TAB by TABs
1280 (when (memq 'space-before-tab whitespace-chars)
1281 (whitespace-replace-spaces-by-tabs
1282 rstart rend whitespace-space-before-tab-regexp))))
1283 (set-marker rend nil))) ; point marker to nowhere
1286 (defun whitespace-replace-spaces-by-tabs (rstart rend regexp)
1287 "Replace all SPACEs by TABs matched by REGEXP between RSTART and REND."
1288 (goto-char rstart)
1289 (while (re-search-forward regexp rend t)
1290 (goto-char (match-beginning 1))
1291 (let* ((scol (current-column))
1292 (ecol (save-excursion
1293 (goto-char (match-end 1))
1294 (current-column))))
1295 (delete-region (match-beginning 1) (match-end 1))
1296 (insert-char ?\t
1297 (/ (- (- ecol (% ecol 8)) ; prev end col
1298 (- scol (% scol 8))) ; prev start col
1299 8)))))
1302 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1303 ;;;; User command - old whitespace compatibility
1306 ;;;###autoload
1307 (defun whitespace-buffer ()
1308 "Turn on `whitespace-mode' forcing some settings.
1310 It forces `whitespace-style' to have `color'.
1312 It also forces `whitespace-chars' to have:
1314 trailing
1315 indentation
1316 space-before-tab
1317 empty
1318 space-after-tab
1320 So, it is possible to visualize the following problems:
1322 empty 1. empty lines at beginning of buffer.
1323 empty 2. empty lines at end of buffer.
1324 indentation 3. 8 or more SPACEs at beginning of line.
1325 space-before-tab 4. SPACEs before TAB.
1326 trailing 5. SPACEs or TABs at end of line.
1327 space-after-tab 6. 8 or more SPACEs after TAB.
1329 See `whitespace-chars' and `whitespace-style' for documentation.
1330 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1331 cleaning up these problems."
1332 (interactive)
1333 (whitespace-mode 0) ; assure is off
1334 ;; keep original values
1335 (let ((whitespace-style (copy-sequence whitespace-style))
1336 (whitespace-chars (copy-sequence whitespace-chars)))
1337 ;; adjust options for whitespace bogus blanks
1338 (add-to-list 'whitespace-style 'color)
1339 (mapc #'(lambda (option)
1340 (add-to-list 'whitespace-chars option))
1341 '(trailing
1342 indentation
1343 space-before-tab
1344 empty
1345 space-after-tab))
1346 (whitespace-mode 1))) ; turn on
1349 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1350 ;;;; Internal functions
1353 (defvar whitespace-font-lock-mode nil
1354 "Used to remember whether a buffer had font lock mode on or not.")
1355 (make-variable-buffer-local 'whitespace-font-lock-mode)
1357 (defvar whitespace-font-lock nil
1358 "Used to remember whether a buffer initially had font lock on or not.")
1359 (make-variable-buffer-local 'whitespace-font-lock)
1361 (defvar whitespace-font-lock-keywords nil
1362 "Used to save locally `font-lock-keywords' value.")
1363 (make-variable-buffer-local 'whitespace-font-lock-keywords)
1366 (defconst whitespace-help-text
1368 whitespace-mode toggle options:
1370 [] t - toggle TAB visualization
1371 [] s - toggle SPACE and HARD SPACE visualization
1372 [] r - toggle trailing blanks visualization
1373 [] b - toggle SPACEs before TAB visualization
1374 [] l - toggle \"long lines\" visualization
1375 [] L - toggle \"long lines\" tail visualization
1376 [] n - toggle NEWLINE visualization
1377 [] i - toggle indentation SPACEs visualization
1378 [] e - toggle empty line at bob and/or eob visualization
1379 [] a - toggle SPACEs after TAB visualization
1381 [] c - toggle color faces
1382 [] m - toggle visual mark
1384 x - restore `whitespace-chars' value
1385 z - restore `whitespace-style' value
1387 ? - display this text\n\n"
1388 "Text for whitespace toggle options.")
1391 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1392 "The buffer name for whitespace toggle options.")
1395 (defun whitespace-insert-option-mark (the-list the-value)
1396 "Insert the option mark ('X' or ' ') in toggle options buffer."
1397 (forward-line 1)
1398 (dolist (sym the-list)
1399 (forward-line 1)
1400 (forward-char 2)
1401 (insert (if (memq sym the-value) "X" " "))))
1404 (defun whitespace-help-on (chars style)
1405 "Display the whitespace toggle options."
1406 (unless (get-buffer whitespace-help-buffer-name)
1407 (delete-other-windows)
1408 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
1409 (save-excursion
1410 (set-buffer buffer)
1411 (erase-buffer)
1412 (insert whitespace-help-text)
1413 (goto-char (point-min))
1414 (whitespace-insert-option-mark
1415 whitespace-chars-value-list chars)
1416 (whitespace-insert-option-mark
1417 whitespace-style-value-list style)
1418 (goto-char (point-min))
1419 (set-buffer-modified-p nil)
1420 (let ((size (- (window-height)
1421 (max window-min-height
1422 (1+ (count-lines (point-min)
1423 (point-max)))))))
1424 (when (<= size 0)
1425 (kill-buffer buffer)
1426 (error "Frame height is too small; \
1427 can't split window to display whitespace toggle options"))
1428 (set-window-buffer (split-window nil size) buffer))))))
1431 (defun whitespace-help-off ()
1432 "Remove the buffer and window of the whitespace toggle options."
1433 (let ((buffer (get-buffer whitespace-help-buffer-name)))
1434 (when buffer
1435 (delete-windows-on buffer)
1436 (kill-buffer buffer))))
1439 (defun whitespace-interactive-char (local-p)
1440 "Interactive function to read a char and return a symbol.
1442 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1443 uses a global context.
1445 It accepts one of the following chars:
1447 CHAR MEANING
1448 t toggle TAB visualization
1449 s toggle SPACE and HARD SPACE visualization
1450 r toggle trailing blanks visualization
1451 b toggle SPACEs before TAB visualization
1452 l toggle \"long lines\" visualization
1453 L toggle \"long lines\" tail visualization
1454 n toggle NEWLINE visualization
1455 i toggle indentation SPACEs visualization
1456 e toggle empty line at bob and/or eob visualization
1457 a toggle SPACEs after TAB visualization
1458 c toggle color faces
1459 m toggle visual mark
1460 x restore `whitespace-chars' value
1461 z restore `whitespace-style' value
1462 ? display brief help
1464 See also `whitespace-toggle-option-alist'."
1465 (let* ((is-off (not (if local-p
1466 whitespace-mode
1467 global-whitespace-mode)))
1468 (chars (cond (is-off whitespace-chars) ; use default value
1469 (local-p whitespace-active-chars)
1470 (t whitespace-toggle-chars)))
1471 (style (cond (is-off whitespace-style) ; use default value
1472 (local-p whitespace-active-style)
1473 (t whitespace-toggle-style)))
1474 (prompt
1475 (format "Whitespace Toggle %s (type ? for further options)-"
1476 (if local-p "Local" "Global")))
1477 ch sym)
1478 ;; read a valid option and get the corresponding symbol
1479 (save-window-excursion
1480 (condition-case data
1481 (progn
1482 (while
1483 ;; while condition
1484 (progn
1485 (setq ch (read-char prompt))
1486 (not
1487 (setq sym
1488 (cdr
1489 (assq ch whitespace-toggle-option-alist)))))
1490 ;; while body
1491 (if (eq ch ?\?)
1492 (whitespace-help-on chars style)
1493 (ding)))
1494 (whitespace-help-off)
1495 (message " ")) ; clean echo area
1496 ;; handler
1497 ((quit error)
1498 (whitespace-help-off)
1499 (error (error-message-string data)))))
1500 (list sym))) ; return the apropriate symbol
1503 (defun whitespace-toggle-list (local-p arg the-list default-list
1504 sym-restore sym-list)
1505 "Toggle options in THE-LIST based on list ARG.
1507 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1508 uses a global context.
1510 ARG is a list of options to be toggled.
1512 THE-LIST is a list of options. This list will be toggled and the
1513 resultant list will be returned.
1515 DEFAULT-LIST is the default list of options. It is used to
1516 restore the options in THE-LIST.
1518 SYM-RESTORE is the symbol which indicates to restore the options
1519 in THE-LIST.
1521 SYM-LIST is a list of valid options, used to check if the ARG's
1522 options are valid."
1523 (unless (if local-p whitespace-mode global-whitespace-mode)
1524 (setq the-list default-list))
1525 (setq the-list (copy-sequence the-list)) ; keep original list
1526 (dolist (sym (if (listp arg) arg (list arg)))
1527 (cond
1528 ;; restore default values
1529 ((eq sym sym-restore)
1530 (setq the-list default-list))
1531 ;; toggle valid values
1532 ((memq sym sym-list)
1533 (setq the-list (if (memq sym the-list)
1534 (delq sym the-list)
1535 (cons sym the-list))))))
1536 the-list)
1539 (defun whitespace-turn-on ()
1540 "Turn on whitespace visualization."
1541 (setq whitespace-active-style (if (listp whitespace-style)
1542 whitespace-style
1543 (list whitespace-style)))
1544 (setq whitespace-active-chars (if (listp whitespace-chars)
1545 whitespace-chars
1546 (list whitespace-chars)))
1547 (when (memq 'color whitespace-active-style)
1548 (whitespace-color-on))
1549 (when (memq 'mark whitespace-active-style)
1550 (whitespace-display-char-on)))
1553 (defun whitespace-turn-off ()
1554 "Turn off whitespace visualization."
1555 (when (memq 'color whitespace-active-style)
1556 (whitespace-color-off))
1557 (when (memq 'mark whitespace-active-style)
1558 (whitespace-display-char-off)))
1561 (defun whitespace-color-on ()
1562 "Turn on color visualization."
1563 (when whitespace-active-chars
1564 (unless whitespace-font-lock
1565 (setq whitespace-font-lock t
1566 whitespace-font-lock-keywords
1567 (copy-sequence font-lock-keywords)))
1568 ;; turn off font lock
1569 (setq whitespace-font-lock-mode font-lock-mode)
1570 (font-lock-mode 0)
1571 ;; add whitespace-mode color into font lock
1572 (when (memq 'spaces whitespace-active-chars)
1573 (font-lock-add-keywords
1575 (list
1576 ;; Show SPACEs
1577 (list whitespace-space-regexp 1 whitespace-space t)
1578 ;; Show HARD SPACEs
1579 (list whitespace-hspace-regexp 1 whitespace-hspace t))
1581 (when (memq 'tabs whitespace-active-chars)
1582 (font-lock-add-keywords
1584 (list
1585 ;; Show TABs
1586 (list whitespace-tab-regexp 1 whitespace-tab t))
1588 (when (memq 'trailing whitespace-active-chars)
1589 (font-lock-add-keywords
1591 (list
1592 ;; Show trailing blanks
1593 (list (concat "\\(\\(" whitespace-trailing-regexp "\\)+\\)$")
1594 1 whitespace-trailing t))
1596 (when (or (memq 'lines whitespace-active-chars)
1597 (memq 'lines-tail whitespace-active-chars))
1598 (font-lock-add-keywords
1600 (list
1601 ;; Show "long" lines
1602 (list
1603 (format
1604 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
1605 tab-width (1- tab-width)
1606 (/ whitespace-line-column tab-width)
1607 (let ((rem (% whitespace-line-column tab-width)))
1608 (if (zerop rem)
1610 (format ".\\{%d\\}" rem))))
1611 (if (memq 'lines whitespace-active-chars)
1612 0 ; whole line
1613 2) ; line tail
1614 whitespace-line t))
1616 (when (memq 'space-before-tab whitespace-active-chars)
1617 (font-lock-add-keywords
1619 (list
1620 ;; Show SPACEs before TAB
1621 (list whitespace-space-before-tab-regexp
1622 1 whitespace-space-before-tab t))
1624 (when (memq 'indentation whitespace-active-chars)
1625 (font-lock-add-keywords
1627 (list
1628 ;; Show indentation SPACEs
1629 (list whitespace-indentation-regexp
1630 1 whitespace-indentation t))
1632 (when (memq 'empty whitespace-active-chars)
1633 (font-lock-add-keywords
1635 (list
1636 ;; Show empty lines at beginning of buffer
1637 (list whitespace-empty-at-bob-regexp
1638 1 whitespace-empty t))
1640 (font-lock-add-keywords
1642 (list
1643 ;; Show empty lines at end of buffer
1644 (list whitespace-empty-at-eob-regexp
1645 1 whitespace-empty t))
1647 (when (memq 'space-after-tab whitespace-active-chars)
1648 (font-lock-add-keywords
1650 (list
1651 ;; Show SPACEs after TAB
1652 (list whitespace-space-after-tab-regexp
1653 1 whitespace-space-after-tab t))
1655 ;; now turn on font lock and highlight blanks
1656 (font-lock-mode 1)))
1659 (defun whitespace-color-off ()
1660 "Turn off color visualization."
1661 (when whitespace-active-chars
1662 ;; turn off font lock
1663 (font-lock-mode 0)
1664 (when whitespace-font-lock
1665 (setq whitespace-font-lock nil
1666 font-lock-keywords whitespace-font-lock-keywords))
1667 ;; restore original font lock state
1668 (font-lock-mode whitespace-font-lock-mode)))
1671 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1672 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
1675 (defvar whitespace-display-table nil
1676 "Used to save a local display table.")
1677 (make-variable-buffer-local 'whitespace-display-table)
1679 (defvar whitespace-display-table-was-local nil
1680 "Used to remember whether a buffer initially had a local display table.")
1681 (make-variable-buffer-local 'whitespace-display-table-was-local)
1684 (defsubst whitespace-char-valid-p (char)
1685 ;; This check should be improved!!!
1686 (or (< char 256)
1687 (characterp char)))
1690 (defun whitespace-display-vector-p (vec)
1691 "Return true if every character in vector VEC can be displayed."
1692 (let ((i (length vec)))
1693 (when (> i 0)
1694 (while (and (>= (setq i (1- i)) 0)
1695 (whitespace-char-valid-p (aref vec i))))
1696 (< i 0))))
1699 (defun whitespace-display-char-on ()
1700 "Turn on character display mapping."
1701 (when whitespace-display-mappings
1702 (let (vecs vec)
1703 ;; Remember whether a buffer has a local display table.
1704 (unless whitespace-display-table-was-local
1705 (setq whitespace-display-table-was-local t
1706 whitespace-display-table
1707 (copy-sequence buffer-display-table)))
1708 (unless buffer-display-table
1709 (setq buffer-display-table (make-display-table)))
1710 (dolist (entry whitespace-display-mappings)
1711 (setq vecs (cdr entry))
1712 ;; Get a displayable mapping.
1713 (while (and vecs
1714 (not (whitespace-display-vector-p (car vecs))))
1715 (setq vecs (cdr vecs)))
1716 ;; Display a valid mapping.
1717 (when vecs
1718 (setq vec (copy-sequence (car vecs)))
1719 (cond
1720 ;; Any char except newline
1721 ((not (eq (car entry) ?\n))
1722 (aset buffer-display-table (car entry) vec))
1723 ;; Newline char - display it
1724 ((memq 'newline whitespace-active-chars)
1725 ;; Only insert face bits on NEWLINE char mapping to avoid
1726 ;; obstruction of other faces like TABs and (HARD) SPACEs
1727 ;; faces, font-lock faces, etc.
1728 (when (memq 'color whitespace-active-style)
1729 (dotimes (i (length vec))
1730 ;; Due to limitations of glyph representation, the char
1731 ;; code can not be above ?\x1FFFF. Probably, this will
1732 ;; be fixed after Emacs unicode merging.
1733 (or (eq (aref vec i) ?\n)
1734 (> (aref vec i) #x1FFFF)
1735 (aset vec i
1736 (make-glyph-code (aref vec i)
1737 whitespace-newline)))))
1738 ;; Display mapping
1739 (aset buffer-display-table (car entry) vec))
1740 ;; Newline char - don't display it
1742 ;; Do nothing
1743 )))))))
1746 (defun whitespace-display-char-off ()
1747 "Turn off character display mapping."
1748 (and whitespace-display-mappings
1749 whitespace-display-table-was-local
1750 (setq whitespace-display-table-was-local nil
1751 buffer-display-table whitespace-display-table)))
1754 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1757 (defun whitespace-unload-function ()
1758 "Unload the Whitespace library."
1759 (let (whitespace-mode) ;; so g-w-m thinks it is nil in all buffers
1760 (global-whitespace-mode -1))
1761 ;; continue standard unloading
1762 nil)
1764 (provide 'whitespace)
1767 (run-hooks 'whitespace-load-hook)
1770 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
1771 ;;; whitespace.el ends here