(WINS_CEDET_SUBDIRS): List of subdirectories of cedet.
[emacs.git] / lisp / whitespace.el
blob118a151d67dc9683a08d747316b01db0cf20afe6
1 ;;; whitespace.el --- minor mode to visualize TAB, (HARD) SPACE, NEWLINE
3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
6 ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br>
7 ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br>
8 ;; Keywords: data, wp
9 ;; Version: 12.0
10 ;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
12 ;; This file is part of GNU Emacs.
14 ;; GNU Emacs is free software: you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation, either version 3 of the License, or
17 ;; (at your option) any later version.
19 ;; GNU Emacs is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
27 ;;; Commentary:
29 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31 ;; Introduction
32 ;; ------------
34 ;; This package is a minor mode to visualize blanks (TAB, (HARD) SPACE
35 ;; and NEWLINE).
37 ;; whitespace uses two ways to visualize blanks: faces and display
38 ;; table.
40 ;; * Faces are used to highlight the background with a color.
41 ;; whitespace uses font-lock to highlight blank characters.
43 ;; * Display table changes the way a character is displayed, that is,
44 ;; it provides a visual mark for characters, for example, at the end
45 ;; of line (?\xB6), at SPACEs (?\xB7) and at TABs (?\xBB).
47 ;; The `whitespace-style' variable selects which way blanks are
48 ;; visualized.
50 ;; Note that when whitespace is turned on, whitespace saves the
51 ;; font-lock state, that is, if font-lock is on or off. And
52 ;; whitespace restores the font-lock state when it is turned off. So,
53 ;; if whitespace is turned on and font-lock is off, whitespace also
54 ;; turns on the font-lock to highlight blanks, but the font-lock will
55 ;; be turned off when whitespace is turned off. Thus, turn on
56 ;; font-lock before whitespace is on, if you want that font-lock
57 ;; continues on after whitespace is turned off.
59 ;; When whitespace is on, it takes care of highlighting some special
60 ;; characters over the default mechanism of `nobreak-char-display'
61 ;; (which see) and `show-trailing-whitespace' (which see).
63 ;; There are two ways of using whitespace: local and global.
65 ;; * Local whitespace affects only the current buffer.
67 ;; * Global whitespace affects all current and future buffers. That
68 ;; is, if you turn on global whitespace and then create a new
69 ;; buffer, the new buffer will also have whitespace on. The
70 ;; `whitespace-global-modes' variable controls which major-mode will
71 ;; be automagically turned on.
73 ;; You can mix the local and global usage without any conflict. But
74 ;; local whitespace has priority over global whitespace. Whitespace
75 ;; mode is active in a buffer if you have enabled it in that buffer or
76 ;; if you have enabled it globally.
78 ;; When global and local whitespace are on:
80 ;; * if local whitespace is turned off, whitespace is turned off for
81 ;; the current buffer only.
83 ;; * if global whitespace is turned off, whitespace continues on only
84 ;; in the buffers in which local whitespace is on.
86 ;; To use whitespace, insert in your ~/.emacs:
88 ;; (require 'whitespace-mode)
90 ;; Or autoload at least one of the commands`whitespace-mode',
91 ;; `whitespace-toggle-options', `global-whitespace-mode' or
92 ;; `global-whitespace-toggle-options'. For example:
94 ;; (autoload 'whitespace-mode "whitespace"
95 ;; "Toggle whitespace visualization." t)
96 ;; (autoload 'whitespace-toggle-options "whitespace"
97 ;; "Toggle local `whitespace-mode' options." t)
99 ;; whitespace was inspired by:
101 ;; whitespace.el Rajesh Vaidheeswarran <rv@gnu.org>
102 ;; Warn about and clean bogus whitespaces in the file
103 ;; (inspired the idea to warn and clean some blanks)
104 ;; This was the original `whitespace.el' which was replaced by
105 ;; `blank-mode.el'. And later `blank-mode.el' was renamed to
106 ;; `whitespace.el'.
108 ;; show-whitespace-mode.el Aurelien Tisne <aurelien.tisne@free.fr>
109 ;; Simple mode to highlight whitespaces
110 ;; (inspired the idea to use font-lock)
112 ;; whitespace-mode.el Lawrence Mitchell <wence@gmx.li>
113 ;; Major mode for editing Whitespace
114 ;; (inspired the idea to use display table)
116 ;; visws.el Miles Bader <miles@gnu.org>
117 ;; Make whitespace visible
118 ;; (handle display table, his code was modified, but the main
119 ;; idea was kept)
122 ;; Using whitespace
123 ;; ----------------
125 ;; There is no problem if you mix local and global minor mode usage.
127 ;; * LOCAL whitespace:
128 ;; + To toggle whitespace options locally, type:
130 ;; M-x whitespace-toggle-options RET
132 ;; + To activate whitespace locally, type:
134 ;; C-u 1 M-x whitespace-mode RET
136 ;; + To deactivate whitespace locally, type:
138 ;; C-u 0 M-x whitespace-mode RET
140 ;; + To toggle whitespace locally, type:
142 ;; M-x whitespace-mode RET
144 ;; * GLOBAL whitespace:
145 ;; + To toggle whitespace options globally, type:
147 ;; M-x global-whitespace-toggle-options RET
149 ;; + To activate whitespace globally, type:
151 ;; C-u 1 M-x global-whitespace-mode RET
153 ;; + To deactivate whitespace globally, type:
155 ;; C-u 0 M-x global-whitespace-mode RET
157 ;; + To toggle whitespace globally, type:
159 ;; M-x global-whitespace-mode RET
161 ;; There are also the following useful commands:
163 ;; `whitespace-newline-mode'
164 ;; Toggle NEWLINE minor mode visualization ("nl" on modeline).
166 ;; `global-whitespace-newline-mode'
167 ;; Toggle NEWLINE global minor mode visualization ("NL" on modeline).
169 ;; `whitespace-report'
170 ;; Report some blank problems in buffer.
172 ;; `whitespace-report-region'
173 ;; Report some blank problems in a region.
175 ;; `whitespace-cleanup'
176 ;; Cleanup some blank problems in all buffer or at region.
178 ;; `whitespace-cleanup-region'
179 ;; Cleanup some blank problems at region.
181 ;; The problems, which are cleaned up, are:
183 ;; 1. empty lines at beginning of buffer.
184 ;; 2. empty lines at end of buffer.
185 ;; If `whitespace-style' includes the value `empty', remove all
186 ;; empty lines at beginning and/or end of buffer.
188 ;; 3. 8 or more SPACEs at beginning of line.
189 ;; If `whitespace-style' includes the value `indentation':
190 ;; replace 8 or more SPACEs at beginning of line by TABs, if
191 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
192 ;; SPACEs.
193 ;; If `whitespace-style' includes the value `indentation::tab',
194 ;; replace 8 or more SPACEs at beginning of line by TABs.
195 ;; If `whitespace-style' includes the value `indentation::space',
196 ;; replace TABs by SPACEs.
198 ;; 4. SPACEs before TAB.
199 ;; If `whitespace-style' includes the value `space-before-tab':
200 ;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
201 ;; otherwise, replace TABs by SPACEs.
202 ;; If `whitespace-style' includes the value
203 ;; `space-before-tab::tab', replace SPACEs by TABs.
204 ;; If `whitespace-style' includes the value
205 ;; `space-before-tab::space', replace TABs by SPACEs.
207 ;; 5. SPACEs or TABs at end of line.
208 ;; If `whitespace-style' includes the value `trailing', remove all
209 ;; SPACEs or TABs at end of line.
211 ;; 6. 8 or more SPACEs after TAB.
212 ;; If `whitespace-style' includes the value `space-after-tab':
213 ;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
214 ;; otherwise, replace TABs by SPACEs.
215 ;; If `whitespace-style' includes the value `space-after-tab::tab',
216 ;; replace SPACEs by TABs.
217 ;; If `whitespace-style' includes the value
218 ;; `space-after-tab::space', replace TABs by SPACEs.
221 ;; Hooks
222 ;; -----
224 ;; whitespace has the following hook variables:
226 ;; `whitespace-mode-hook'
227 ;; It is evaluated always when whitespace is turned on locally.
229 ;; `global-whitespace-mode-hook'
230 ;; It is evaluated always when whitespace is turned on globally.
232 ;; `whitespace-load-hook'
233 ;; It is evaluated after whitespace package is loaded.
236 ;; Options
237 ;; -------
239 ;; Below it's shown a brief description of whitespace options, please,
240 ;; see the options declaration in the code for a long documentation.
242 ;; `whitespace-style' Specify which kind of blank is
243 ;; visualized.
245 ;; `whitespace-space' Face used to visualize SPACE.
247 ;; `whitespace-hspace' Face used to visualize HARD SPACE.
249 ;; `whitespace-tab' Face used to visualize TAB.
251 ;; `whitespace-newline' Face used to visualize NEWLINE char
252 ;; mapping.
254 ;; `whitespace-trailing' Face used to visualize trailing
255 ;; blanks.
257 ;; `whitespace-line' Face used to visualize "long" lines.
259 ;; `whitespace-space-before-tab' Face used to visualize SPACEs
260 ;; before TAB.
262 ;; `whitespace-indentation' Face used to visualize 8 or more
263 ;; SPACEs at beginning of line.
265 ;; `whitespace-empty' Face used to visualize empty lines at
266 ;; beginning and/or end of buffer.
268 ;; `whitespace-space-after-tab' Face used to visualize 8 or more
269 ;; SPACEs after TAB.
271 ;; `whitespace-space-regexp' Specify SPACE characters regexp.
273 ;; `whitespace-hspace-regexp' Specify HARD SPACE characters regexp.
275 ;; `whitespace-tab-regexp' Specify TAB characters regexp.
277 ;; `whitespace-trailing-regexp' Specify trailing characters regexp.
279 ;; `whitespace-space-before-tab-regexp' Specify SPACEs before TAB
280 ;; regexp.
282 ;; `whitespace-indentation-regexp' Specify regexp for 8 or more
283 ;; SPACEs at beginning of line.
285 ;; `whitespace-empty-at-bob-regexp' Specify regexp for empty lines
286 ;; at beginning of buffer.
288 ;; `whitespace-empty-at-eob-regexp' Specify regexp for empty lines
289 ;; at end of buffer.
291 ;; `whitespace-space-after-tab-regexp' Specify regexp for 8 or more
292 ;; SPACEs after TAB.
294 ;; `whitespace-line-column' Specify column beyond which the line
295 ;; is highlighted.
297 ;; `whitespace-display-mappings' Specify an alist of mappings
298 ;; for displaying characters.
300 ;; `whitespace-global-modes' Modes for which global
301 ;; `whitespace-mode' is automagically
302 ;; turned on.
304 ;; `whitespace-action' Specify which action is taken when a
305 ;; buffer is visited or written.
308 ;; Acknowledgements
309 ;; ----------------
311 ;; Thanks to David Reitter <david.reitter@gmail.com> for suggesting a
312 ;; `whitespace-newline' initialization with low contrast relative to
313 ;; the background color.
315 ;; Thanks to Stephen Deasey <sdeasey@gmail.com> for the
316 ;; `indent-tabs-mode' usage suggestion.
318 ;; Thanks to Eric Cooper <ecc@cmu.edu> for the suggestion to have hook
319 ;; actions when buffer is written as the original whitespace package
320 ;; had.
322 ;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
323 ;; lines tail. See EightyColumnRule (EmacsWiki).
325 ;; Thanks to Juri Linkov <juri@jurta.org> for suggesting:
326 ;; * `define-minor-mode'.
327 ;; * `global-whitespace-*' name for global commands.
329 ;; Thanks to Robert J. Chassell <bob@gnu.org> for doc fix and testing.
331 ;; Thanks to Drew Adams <drew.adams@oracle.com> for toggle commands
332 ;; suggestion.
334 ;; Thanks to Antti Kaihola <antti.kaihola@linux-aktivaattori.org> for
335 ;; helping to fix `find-file-hooks' reference.
337 ;; Thanks to Andreas Roehler <andreas.roehler@easy-emacs.de> for
338 ;; indicating defface byte-compilation warnings.
340 ;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight
341 ;; "long" lines. See EightyColumnRule (EmacsWiki).
343 ;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
344 ;; NEWLINE character mapping.
346 ;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
347 ;; whitespace-mode.el on XEmacs.
349 ;; Thanks to Miles Bader <miles@gnu.org> for handling display table via
350 ;; visws.el (his code was modified, but the main idea was kept).
352 ;; Thanks to:
353 ;; Rajesh Vaidheeswarran <rv@gnu.org> (original) whitespace.el
354 ;; Aurelien Tisne <aurelien.tisne@free.fr> show-whitespace-mode.el
355 ;; Lawrence Mitchell <wence@gmx.li> whitespace-mode.el
356 ;; Miles Bader <miles@gnu.org> visws.el
357 ;; And to all people who contributed with them.
360 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
362 ;;; code:
365 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
366 ;;;; User Variables:
369 ;;; Interface to the command system
372 (defgroup whitespace nil
373 "Visualize blanks (TAB, (HARD) SPACE and NEWLINE)."
374 :link '(emacs-library-link :tag "Source Lisp File" "whitespace.el")
375 :version "23.1"
376 :group 'wp
377 :group 'data)
380 (defcustom whitespace-style
381 '(tabs spaces trailing lines space-before-tab newline
382 indentation empty space-after-tab
383 space-mark tab-mark newline-mark)
384 "Specify which kind of blank is visualized.
386 It's a list containing some or all of the following values:
388 trailing trailing blanks are visualized via faces.
390 tabs TABs are visualized via faces.
392 spaces SPACEs and HARD SPACEs are visualized via
393 faces.
395 lines lines whose have columns beyond
396 `whitespace-line-column' are highlighted via
397 faces .
398 Whole line is highlighted.
399 It has precedence over `lines-tail' (see
400 below).
402 lines-tail lines whose have columns beyond
403 `whitespace-line-column' are highlighted via
404 faces.
405 But only the part of line which goes
406 beyond `whitespace-line-column' column.
407 It has effect only if `lines' (see above)
408 is not present in `whitespace-style'.
410 newline NEWLINEs are visualized via faces.
412 empty empty lines at beginning and/or end of buffer
413 are visualized via faces.
415 indentation::tab 8 or more SPACEs at beginning of line are
416 visualized via faces.
418 indentation::space TABs at beginning of line are visualized via
419 faces.
421 indentation 8 or more SPACEs at beginning of line are
422 visualized, if `indent-tabs-mode' (which see)
423 is non-nil; otherwise, TABs at beginning of
424 line are visualized via faces.
426 space-after-tab::tab 8 or more SPACEs after a TAB are
427 visualized via faces.
429 space-after-tab::space TABs are visualized when 8 or more
430 SPACEs occur after a TAB, via faces.
432 space-after-tab 8 or more SPACEs after a TAB are
433 visualized, if `indent-tabs-mode'
434 (which see) is non-nil; otherwise,
435 the TABs are visualized via faces.
437 space-before-tab::tab SPACEs before TAB are visualized via
438 faces.
440 space-before-tab::space TABs are visualized when SPACEs occur
441 before TAB, via faces.
443 space-before-tab SPACEs before TAB are visualized, if
444 `indent-tabs-mode' (which see) is
445 non-nil; otherwise, the TABs are
446 visualized via faces.
448 space-mark SPACEs and HARD SPACEs are visualized via
449 display table.
451 tab-mark TABs are visualized via display table.
453 newline-mark NEWLINEs are visualized via display table.
455 Any other value is ignored.
457 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs via faces and
458 via display table.
460 There is an evaluation order for some values, if some values are
461 included in `whitespace-style' list. For example, if
462 indentation, indentation::tab and/or indentation::space are
463 included in `whitespace-style' list. The evaluation order for
464 these values is:
466 * For indentation:
467 1. indentation
468 2. indentation::tab
469 3. indentation::space
471 * For SPACEs after TABs:
472 1. space-after-tab
473 2. space-after-tab::tab
474 3. space-after-tab::space
476 * For SPACEs before TABs:
477 1. space-before-tab
478 2. space-before-tab::tab
479 3. space-before-tab::space
481 So, for example, if indentation and indentation::space are
482 included in `whitespace-style' list, the indentation value is
483 evaluated instead of indentation::space value.
485 See also `whitespace-display-mappings' for documentation."
486 :type '(repeat :tag "Kind of Blank"
487 (choice :tag "Kind of Blank Face"
488 (const :tag "(Face) Trailing TABs, SPACEs and HARD SPACEs"
489 trailing)
490 (const :tag "(Face) SPACEs and HARD SPACEs"
491 spaces)
492 (const :tag "(Face) TABs" tabs)
493 (const :tag "(Face) Lines" lines)
494 (const :tag "(Face) SPACEs before TAB"
495 space-before-tab)
496 (const :tag "(Face) NEWLINEs" newline)
497 (const :tag "(Face) Indentation SPACEs"
498 indentation)
499 (const :tag "(Face) Empty Lines At BOB And/Or EOB"
500 empty)
501 (const :tag "(Face) SPACEs after TAB"
502 space-after-tab)
503 (const :tag "(Mark) SPACEs and HARD SPACEs"
504 space-mark)
505 (const :tag "(Mark) TABs" tab-mark)
506 (const :tag "(Mark) NEWLINEs" newline-mark)))
507 :group 'whitespace)
510 (defcustom whitespace-space 'whitespace-space
511 "Symbol face used to visualize SPACE.
513 Used when `whitespace-style' includes the value `spaces'."
514 :type 'face
515 :group 'whitespace)
518 (defface whitespace-space
519 '((((class color) (background dark))
520 (:background "grey20" :foreground "aquamarine3"))
521 (((class color) (background light))
522 (:background "LightYellow" :foreground "aquamarine3"))
523 (t (:inverse-video t)))
524 "Face used to visualize SPACE."
525 :group 'whitespace)
528 (defcustom whitespace-hspace 'whitespace-hspace
529 "Symbol face used to visualize HARD SPACE.
531 Used when `whitespace-style' includes the value `spaces'."
532 :type 'face
533 :group 'whitespace)
536 (defface whitespace-hspace ; 'nobreak-space
537 '((((class color) (background dark))
538 (:background "grey24" :foreground "aquamarine3"))
539 (((class color) (background light))
540 (:background "LemonChiffon3" :foreground "aquamarine3"))
541 (t (:inverse-video t)))
542 "Face used to visualize HARD SPACE."
543 :group 'whitespace)
546 (defcustom whitespace-tab 'whitespace-tab
547 "Symbol face used to visualize TAB.
549 Used when `whitespace-style' includes the value `tabs'."
550 :type 'face
551 :group 'whitespace)
554 (defface whitespace-tab
555 '((((class color) (background dark))
556 (:background "grey22" :foreground "aquamarine3"))
557 (((class color) (background light))
558 (:background "beige" :foreground "aquamarine3"))
559 (t (:inverse-video t)))
560 "Face used to visualize TAB."
561 :group 'whitespace)
564 (defcustom whitespace-newline 'whitespace-newline
565 "Symbol face used to visualize NEWLINE char mapping.
567 See `whitespace-display-mappings'.
569 Used when `whitespace-style' includes the values `newline-mark'
570 and `newline'."
571 :type 'face
572 :group 'whitespace)
575 (defface whitespace-newline
576 '((((class color) (background dark))
577 (:foreground "darkgray" :bold nil))
578 (((class color) (background light))
579 (:foreground "lightgray" :bold nil))
580 (t (:underline t :bold nil)))
581 "Face used to visualize NEWLINE char mapping.
583 See `whitespace-display-mappings'."
584 :group 'whitespace)
587 (defcustom whitespace-trailing 'whitespace-trailing
588 "Symbol face used to visualize trailing blanks.
590 Used when `whitespace-style' includes the value `trailing'."
591 :type 'face
592 :group 'whitespace)
595 (defface whitespace-trailing ; 'trailing-whitespace
596 '((((class mono)) (:inverse-video t :bold t :underline t))
597 (t (:background "red1" :foreground "yellow" :bold t)))
598 "Face used to visualize trailing blanks."
599 :group 'whitespace)
602 (defcustom whitespace-line 'whitespace-line
603 "Symbol face used to visualize \"long\" lines.
605 See `whitespace-line-column'.
607 Used when `whitespace-style' includes the value `line'."
608 :type 'face
609 :group 'whitespace)
612 (defface whitespace-line
613 '((((class mono)) (:inverse-video t :bold t :underline t))
614 (t (:background "gray20" :foreground "violet")))
615 "Face used to visualize \"long\" lines.
617 See `whitespace-line-column'."
618 :group 'whitespace)
621 (defcustom whitespace-space-before-tab 'whitespace-space-before-tab
622 "Symbol face used to visualize SPACEs before TAB.
624 Used when `whitespace-style' includes the value `space-before-tab'."
625 :type 'face
626 :group 'whitespace)
629 (defface whitespace-space-before-tab
630 '((((class mono)) (:inverse-video t :bold t :underline t))
631 (t (:background "DarkOrange" :foreground "firebrick")))
632 "Face used to visualize SPACEs before TAB."
633 :group 'whitespace)
636 (defcustom whitespace-indentation 'whitespace-indentation
637 "Symbol face used to visualize 8 or more SPACEs at beginning of line.
639 Used when `whitespace-style' includes the value `indentation'."
640 :type 'face
641 :group 'whitespace)
644 (defface whitespace-indentation
645 '((((class mono)) (:inverse-video t :bold t :underline t))
646 (t (:background "yellow" :foreground "firebrick")))
647 "Face used to visualize 8 or more SPACEs at beginning of line."
648 :group 'whitespace)
651 (defcustom whitespace-empty 'whitespace-empty
652 "Symbol face used to visualize empty lines at beginning and/or end of buffer.
654 Used when `whitespace-style' includes the value `empty'."
655 :type 'face
656 :group 'whitespace)
659 (defface whitespace-empty
660 '((((class mono)) (:inverse-video t :bold t :underline t))
661 (t (:background "yellow" :foreground "firebrick")))
662 "Face used to visualize empty lines at beginning and/or end of buffer."
663 :group 'whitespace)
666 (defcustom whitespace-space-after-tab 'whitespace-space-after-tab
667 "Symbol face used to visualize 8 or more SPACEs after TAB.
669 Used when `whitespace-style' includes the value `space-after-tab'."
670 :type 'face
671 :group 'whitespace)
674 (defface whitespace-space-after-tab
675 '((((class mono)) (:inverse-video t :bold t :underline t))
676 (t (:background "yellow" :foreground "firebrick")))
677 "Face used to visualize 8 or more SPACEs after TAB."
678 :group 'whitespace)
681 (defcustom whitespace-hspace-regexp
682 "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
683 "Specify HARD SPACE characters regexp.
685 If you're using `mule' package, there may be other characters besides:
687 \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
689 that should be considered HARD SPACE.
691 Here are some examples:
693 \"\\\\(^\\xA0+\\\\)\" \
694 visualize only leading HARD SPACEs.
695 \"\\\\(\\xA0+$\\\\)\" \
696 visualize only trailing HARD SPACEs.
697 \"\\\\(^\\xA0+\\\\|\\xA0+$\\\\)\" \
698 visualize leading and/or trailing HARD SPACEs.
699 \"\\t\\\\(\\xA0+\\\\)\\t\" \
700 visualize only HARD SPACEs between TABs.
702 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
703 Use exactly one pair of enclosing \\\\( and \\\\).
705 Used when `whitespace-style' includes `spaces'."
706 :type '(regexp :tag "HARD SPACE Chars")
707 :group 'whitespace)
710 (defcustom whitespace-space-regexp "\\( +\\)"
711 "Specify SPACE characters regexp.
713 If you're using `mule' package, there may be other characters
714 besides \" \" that should be considered SPACE.
716 Here are some examples:
718 \"\\\\(^ +\\\\)\" visualize only leading SPACEs.
719 \"\\\\( +$\\\\)\" visualize only trailing SPACEs.
720 \"\\\\(^ +\\\\| +$\\\\)\" \
721 visualize leading and/or trailing SPACEs.
722 \"\\t\\\\( +\\\\)\\t\" visualize only SPACEs between TABs.
724 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
725 Use exactly one pair of enclosing \\\\( and \\\\).
727 Used when `whitespace-style' includes `spaces'."
728 :type '(regexp :tag "SPACE Chars")
729 :group 'whitespace)
732 (defcustom whitespace-tab-regexp "\\(\t+\\)"
733 "Specify TAB characters regexp.
735 If you're using `mule' package, there may be other characters
736 besides \"\\t\" that should be considered TAB.
738 Here are some examples:
740 \"\\\\(^\\t+\\\\)\" visualize only leading TABs.
741 \"\\\\(\\t+$\\\\)\" visualize only trailing TABs.
742 \"\\\\(^\\t+\\\\|\\t+$\\\\)\" \
743 visualize leading and/or trailing TABs.
744 \" \\\\(\\t+\\\\) \" visualize only TABs between SPACEs.
746 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
747 Use exactly one pair of enclosing \\\\( and \\\\).
749 Used when `whitespace-style' includes `tabs'."
750 :type '(regexp :tag "TAB Chars")
751 :group 'whitespace)
754 (defcustom whitespace-trailing-regexp
755 "\\(\\(\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)$"
756 "Specify trailing characters regexp.
758 If you're using `mule' package, there may be other characters besides:
760 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
761 \"\\xF20\"
763 that should be considered blank.
765 NOTE: Enclose always by \"\\\\(\" and \"\\\\)$\" the elements to highlight.
766 Use exactly one pair of enclosing elements above.
768 Used when `whitespace-style' includes `trailing'."
769 :type '(regexp :tag "Trailing Chars")
770 :group 'whitespace)
773 (defcustom whitespace-space-before-tab-regexp "\\( +\\)\\(\t+\\)"
774 "Specify SPACEs before TAB regexp.
776 If you're using `mule' package, there may be other characters besides:
778 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
779 \"\\xF20\"
781 that should be considered blank.
783 Used when `whitespace-style' includes `space-before-tab',
784 `space-before-tab::tab' or `space-before-tab::space'."
785 :type '(regexp :tag "SPACEs Before TAB")
786 :group 'whitespace)
789 (defcustom whitespace-indentation-regexp
790 '("^\t*\\(\\( \\{%d\\}\\)+\\)[^\n\t]"
791 . "^ *\\(\t+\\)[^\n]")
792 "Specify regexp for 8 or more SPACEs at beginning of line.
794 It is a cons where the cons car is used for SPACEs visualization
795 and the cons cdr is used for TABs visualization.
797 If you're using `mule' package, there may be other characters besides:
799 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
800 \"\\xF20\"
802 that should be considered blank.
804 Used when `whitespace-style' includes `indentation',
805 `indentation::tab' or `indentation::space'."
806 :type '(cons (regexp :tag "Indentation SPACEs")
807 (regexp :tag "Indentation TABs"))
808 :group 'whitespace)
811 (defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
812 "Specify regexp for empty lines at beginning of buffer.
814 If you're using `mule' package, there may be other characters besides:
816 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
817 \"\\xF20\"
819 that should be considered blank.
821 Used when `whitespace-style' includes `empty'."
822 :type '(regexp :tag "Empty Lines At Beginning Of Buffer")
823 :group 'whitespace)
826 (defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
827 "Specify regexp for empty lines at end of buffer.
829 If you're using `mule' package, there may be other characters besides:
831 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
832 \"\\xF20\"
834 that should be considered blank.
836 Used when `whitespace-style' includes `empty'."
837 :type '(regexp :tag "Empty Lines At End Of Buffer")
838 :group 'whitespace)
841 (defcustom whitespace-space-after-tab-regexp
842 '("\t+\\(\\( \\{%d\\}\\)+\\)"
843 . "\\(\t+\\) +")
844 "Specify regexp for 8 or more SPACEs after TAB.
846 It is a cons where the cons car is used for SPACEs visualization
847 and the cons cdr is used for TABs visualization.
849 If you're using `mule' package, there may be other characters besides:
851 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
852 \"\\xF20\"
854 that should be considered blank.
856 Used when `whitespace-style' includes `space-after-tab',
857 `space-after-tab::tab' or `space-after-tab::space'."
858 :type '(regexp :tag "SPACEs After TAB")
859 :group 'whitespace)
862 (defcustom whitespace-line-column 80
863 "Specify column beyond which the line is highlighted.
865 Used when `whitespace-style' includes `lines' or `lines-tail'."
866 :type '(integer :tag "Line Length")
867 :group 'whitespace)
870 ;; Hacked from `visible-whitespace-mappings' in visws.el
871 (defcustom whitespace-display-mappings
873 (space-mark ?\ [?\u00B7] [?.]) ; space - centered dot
874 (space-mark ?\xA0 [?\u00A4] [?_]) ; hard space - currency
875 (space-mark ?\x8A0 [?\x8A4] [?_]) ; hard space - currency
876 (space-mark ?\x920 [?\x924] [?_]) ; hard space - currency
877 (space-mark ?\xE20 [?\xE24] [?_]) ; hard space - currency
878 (space-mark ?\xF20 [?\xF24] [?_]) ; hard space - currency
879 ;; NEWLINE is displayed using the face `whitespace-newline'
880 (newline-mark ?\n [?$ ?\n]) ; eol - dollar sign
881 ;; (newline-mark ?\n [?\u21B5 ?\n] [?$ ?\n]) ; eol - downwards arrow
882 ;; (newline-mark ?\n [?\u00B6 ?\n] [?$ ?\n]) ; eol - pilcrow
883 ;; (newline-mark ?\n [?\x8AF ?\n] [?$ ?\n]) ; eol - overscore
884 ;; (newline-mark ?\n [?\x8AC ?\n] [?$ ?\n]) ; eol - negation
885 ;; (newline-mark ?\n [?\x8B0 ?\n] [?$ ?\n]) ; eol - grade
887 ;; WARNING: the mapping below has a problem.
888 ;; When a TAB occupies exactly one column, it will display the
889 ;; character ?\xBB at that column followed by a TAB which goes to
890 ;; the next TAB column.
891 ;; If this is a problem for you, please, comment the line below.
892 (tab-mark ?\t [?\u00BB ?\t] [?\\ ?\t]) ; tab - left quote mark
894 "Specify an alist of mappings for displaying characters.
896 Each element has the following form:
898 (KIND CHAR VECTOR...)
900 Where:
902 KIND is the kind of character.
903 It can be one of the following symbols:
905 tab-mark for TAB character
907 space-mark for SPACE or HARD SPACE character
909 newline-mark for NEWLINE character
911 CHAR is the character to be mapped.
913 VECTOR is a vector of characters to be displayed in place of CHAR.
914 The first display vector that can be displayed is used;
915 if no display vector for a mapping can be displayed, then
916 that character is displayed unmodified.
918 The NEWLINE character is displayed using the face given by
919 `whitespace-newline' variable.
921 Used when `whitespace-style' includes `tab-mark', `space-mark' or
922 `newline-mark'."
923 :type '(repeat
924 (list :tag "Character Mapping"
925 (choice :tag "Char Kind"
926 (const :tag "Tab" tab-mark)
927 (const :tag "Space" space-mark)
928 (const :tag "Newline" newline-mark))
929 (character :tag "Char")
930 (repeat :inline t :tag "Vector List"
931 (vector :tag ""
932 (repeat :inline t
933 :tag "Vector Characters"
934 (character :tag "Char"))))))
935 :group 'whitespace)
938 (defcustom whitespace-global-modes t
939 "Modes for which global `whitespace-mode' is automagically turned on.
941 Global `whitespace-mode' is controlled by the command
942 `global-whitespace-mode'.
944 If nil, means no modes have `whitespace-mode' automatically
945 turned on.
947 If t, all modes that support `whitespace-mode' have it
948 automatically turned on.
950 Else it should be a list of `major-mode' symbol names for which
951 `whitespace-mode' should be automatically turned on. The sense
952 of the list is negated if it begins with `not'. For example:
954 (c-mode c++-mode)
956 means that `whitespace-mode' is turned on for buffers in C and
957 C++ modes only."
958 :type '(choice :tag "Global Modes"
959 (const :tag "None" nil)
960 (const :tag "All" t)
961 (set :menu-tag "Mode Specific" :tag "Modes"
962 :value (not)
963 (const :tag "Except" not)
964 (repeat :inline t
965 (symbol :tag "Mode"))))
966 :group 'whitespace)
969 (defcustom whitespace-action nil
970 "Specify which action is taken when a buffer is visited or written.
972 It's a list containing some or all of the following values:
974 nil no action is taken.
976 cleanup cleanup any bogus whitespace always when local
977 whitespace is turned on.
978 See `whitespace-cleanup' and
979 `whitespace-cleanup-region'.
981 report-on-bogus report if there is any bogus whitespace always
982 when local whitespace is turned on.
984 auto-cleanup cleanup any bogus whitespace when buffer is
985 written.
986 See `whitespace-cleanup' and
987 `whitespace-cleanup-region'.
989 abort-on-bogus abort if there is any bogus whitespace and the
990 buffer is written.
992 warn-if-read-only give a warning if `cleanup' or `auto-cleanup'
993 is included in `whitespace-action' and the
994 buffer is read-only.
996 Any other value is treated as nil."
997 :type '(choice :tag "Actions"
998 (const :tag "None" nil)
999 (repeat :tag "Action List"
1000 (choice :tag "Action"
1001 (const :tag "Cleanup When On" cleanup)
1002 (const :tag "Report On Bogus" report-on-bogus)
1003 (const :tag "Auto Cleanup" auto-cleanup)
1004 (const :tag "Abort On Bogus" abort-on-bogus)
1005 (const :tag "Warn If Read-Only" warn-if-read-only))))
1006 :group 'whitespace)
1009 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1010 ;;;; User commands - Local mode
1013 ;;;###autoload
1014 (define-minor-mode whitespace-mode
1015 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
1017 If ARG is null, toggle whitespace visualization.
1018 If ARG is a number greater than zero, turn on visualization;
1019 otherwise, turn off visualization.
1020 Only useful with a windowing system.
1022 See also `whitespace-style', `whitespace-newline' and
1023 `whitespace-display-mappings'."
1024 :lighter " ws"
1025 :init-value nil
1026 :global nil
1027 :group 'whitespace
1028 (cond
1029 (noninteractive ; running a batch job
1030 (setq whitespace-mode nil))
1031 (whitespace-mode ; whitespace-mode on
1032 (whitespace-turn-on)
1033 (whitespace-action-when-on))
1034 (t ; whitespace-mode off
1035 (whitespace-turn-off))))
1038 ;;;###autoload
1039 (define-minor-mode whitespace-newline-mode
1040 "Toggle NEWLINE minor mode visualization (\"nl\" on modeline).
1042 If ARG is null, toggle NEWLINE visualization.
1043 If ARG is a number greater than zero, turn on visualization;
1044 otherwise, turn off visualization.
1045 Only useful with a windowing system.
1047 Use `whitespace-newline-mode' only for NEWLINE visualization
1048 exclusively. For other visualizations, including NEWLINE
1049 visualization together with (HARD) SPACEs and/or TABs, please,
1050 use `whitespace-mode'.
1052 See also `whitespace-newline' and `whitespace-display-mappings'."
1053 :lighter " nl"
1054 :init-value nil
1055 :global nil
1056 :group 'whitespace
1057 (let ((whitespace-style '(newline-mark newline)))
1058 (whitespace-mode whitespace-newline-mode)
1059 ;; sync states (running a batch job)
1060 (setq whitespace-newline-mode whitespace-mode)))
1063 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1064 ;;;; User commands - Global mode
1067 ;;;###autoload
1068 (define-minor-mode global-whitespace-mode
1069 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
1071 If ARG is null, toggle whitespace visualization.
1072 If ARG is a number greater than zero, turn on visualization;
1073 otherwise, turn off visualization.
1074 Only useful with a windowing system.
1076 See also `whitespace-style', `whitespace-newline' and
1077 `whitespace-display-mappings'."
1078 :lighter " WS"
1079 :init-value nil
1080 :global t
1081 :group 'whitespace
1082 (cond
1083 (noninteractive ; running a batch job
1084 (setq global-whitespace-mode nil))
1085 (global-whitespace-mode ; global-whitespace-mode on
1086 (save-excursion
1087 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1088 (dolist (buffer (buffer-list)) ; adjust all local mode
1089 (set-buffer buffer)
1090 (unless whitespace-mode
1091 (whitespace-turn-on-if-enabled)))))
1092 (t ; global-whitespace-mode off
1093 (save-excursion
1094 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1095 (dolist (buffer (buffer-list)) ; adjust all local mode
1096 (set-buffer buffer)
1097 (unless whitespace-mode
1098 (whitespace-turn-off)))))))
1101 (defun whitespace-turn-on-if-enabled ()
1102 (when (cond
1103 ((eq whitespace-global-modes t))
1104 ((listp whitespace-global-modes)
1105 (if (eq (car-safe whitespace-global-modes) 'not)
1106 (not (memq major-mode (cdr whitespace-global-modes)))
1107 (memq major-mode whitespace-global-modes)))
1108 (t nil))
1109 (let (inhibit-quit)
1110 ;; Don't turn on whitespace mode if...
1112 ;; ...we don't have a display (we're running a batch job)
1113 noninteractive
1114 ;; ...or if the buffer is invisible (name starts with a space)
1115 (eq (aref (buffer-name) 0) ?\ )
1116 ;; ...or if the buffer is temporary (name starts with *)
1117 (and (eq (aref (buffer-name) 0) ?*)
1118 ;; except the scratch buffer.
1119 (not (string= (buffer-name) "*scratch*")))
1120 ;; Otherwise, turn on whitespace mode.
1121 (whitespace-turn-on)))))
1124 ;;;###autoload
1125 (define-minor-mode global-whitespace-newline-mode
1126 "Toggle NEWLINE global minor mode visualization (\"NL\" on modeline).
1128 If ARG is null, toggle NEWLINE visualization.
1129 If ARG is a number greater than zero, turn on visualization;
1130 otherwise, turn off visualization.
1131 Only useful with a windowing system.
1133 Use `global-whitespace-newline-mode' only for NEWLINE
1134 visualization exclusively. For other visualizations, including
1135 NEWLINE visualization together with (HARD) SPACEs and/or TABs,
1136 please, use `global-whitespace-mode'.
1138 See also `whitespace-newline' and `whitespace-display-mappings'."
1139 :lighter " NL"
1140 :init-value nil
1141 :global t
1142 :group 'whitespace
1143 (let ((whitespace-style '(newline-mark newline)))
1144 (global-whitespace-mode global-whitespace-newline-mode)
1145 ;; sync states (running a batch job)
1146 (setq global-whitespace-newline-mode global-whitespace-mode)))
1149 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1150 ;;;; User commands - Toggle
1153 (defconst whitespace-style-value-list
1154 '(tabs
1155 spaces
1156 trailing
1157 lines
1158 lines-tail
1159 newline
1160 empty
1161 indentation
1162 indentation::tab
1163 indentation::space
1164 space-after-tab
1165 space-after-tab::tab
1166 space-after-tab::space
1167 space-before-tab
1168 space-before-tab::tab
1169 space-before-tab::space
1170 help-newline ; value used by `whitespace-insert-option-mark'
1171 tab-mark
1172 space-mark
1173 newline-mark
1175 "List of valid `whitespace-style' values.")
1178 (defconst whitespace-toggle-option-alist
1179 '((?t . tabs)
1180 (?s . spaces)
1181 (?r . trailing)
1182 (?l . lines)
1183 (?L . lines-tail)
1184 (?n . newline)
1185 (?e . empty)
1186 (?\C-i . indentation)
1187 (?I . indentation::tab)
1188 (?i . indentation::space)
1189 (?\C-a . space-after-tab)
1190 (?A . space-after-tab::tab)
1191 (?a . space-after-tab::space)
1192 (?\C-b . space-before-tab)
1193 (?B . space-before-tab::tab)
1194 (?b . space-before-tab::space)
1195 (?T . tab-mark)
1196 (?S . space-mark)
1197 (?N . newline-mark)
1198 (?x . whitespace-style)
1200 "Alist of toggle options.
1202 Each element has the form:
1204 (CHAR . SYMBOL)
1206 Where:
1208 CHAR is a char which the user will have to type.
1210 SYMBOL is a valid symbol associated with CHAR.
1211 See `whitespace-style-value-list'.")
1214 (defvar whitespace-active-style nil
1215 "Used to save locally `whitespace-style' value.")
1217 (defvar whitespace-indent-tabs-mode indent-tabs-mode
1218 "Used to save locally `indent-tabs-mode' value.")
1220 (defvar whitespace-tab-width tab-width
1221 "Used to save locally `tab-width' value.")
1223 (defvar whitespace-point (point)
1224 "Used to save locally current point value.
1225 Used by `whitespace-trailing-regexp' function (which see).")
1227 (defvar whitespace-font-lock-refontify nil
1228 "Used to save locally the font-lock refontify state.
1229 Used by `whitespace-post-command-hook' function (which see).")
1232 ;;;###autoload
1233 (defun whitespace-toggle-options (arg)
1234 "Toggle local `whitespace-mode' options.
1236 If local whitespace-mode is off, toggle the option given by ARG
1237 and turn on local whitespace-mode.
1239 If local whitespace-mode is on, toggle the option given by ARG
1240 and restart local whitespace-mode.
1242 Interactively, it reads one of the following chars:
1244 CHAR MEANING
1245 (VIA FACES)
1246 t toggle TAB visualization
1247 s toggle SPACE and HARD SPACE visualization
1248 r toggle trailing blanks visualization
1249 l toggle \"long lines\" visualization
1250 L toggle \"long lines\" tail visualization
1251 n toggle NEWLINE visualization
1252 e toggle empty line at bob and/or eob visualization
1253 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1254 I toggle indentation SPACEs visualization
1255 i toggle indentation TABs visualization
1256 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1257 A toggle SPACEs after TAB: SPACEs visualization
1258 a toggle SPACEs after TAB: TABs visualization
1259 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1260 B toggle SPACEs before TAB: SPACEs visualization
1261 b toggle SPACEs before TAB: TABs visualization
1263 (VIA DISPLAY TABLE)
1264 T toggle TAB visualization
1265 S toggle SPACEs before TAB visualization
1266 N toggle NEWLINE visualization
1268 x restore `whitespace-style' value
1269 ? display brief help
1271 Non-interactively, ARG should be a symbol or a list of symbols.
1272 The valid symbols are:
1274 tabs toggle TAB visualization
1275 spaces toggle SPACE and HARD SPACE visualization
1276 trailing toggle trailing blanks visualization
1277 lines toggle \"long lines\" visualization
1278 lines-tail toggle \"long lines\" tail visualization
1279 newline toggle NEWLINE visualization
1280 empty toggle empty line at bob and/or eob visualization
1281 indentation toggle indentation SPACEs visualization
1282 indentation::tab toggle indentation SPACEs visualization
1283 indentation::space toggle indentation TABs visualization
1284 space-after-tab toggle SPACEs after TAB visualization
1285 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1286 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1287 space-before-tab toggle SPACEs before TAB visualization
1288 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1289 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1291 tab-mark toggle TAB visualization
1292 space-mark toggle SPACEs before TAB visualization
1293 newline-mark toggle NEWLINE visualization
1295 whitespace-style restore `whitespace-style' value
1297 Only useful with a windowing system.
1299 See `whitespace-style' and `indent-tabs-mode' for documentation."
1300 (interactive (whitespace-interactive-char t))
1301 (let ((whitespace-style
1302 (whitespace-toggle-list t arg whitespace-active-style)))
1303 (whitespace-mode 0)
1304 (whitespace-mode 1)))
1307 (defvar whitespace-toggle-style nil
1308 "Used to toggle the global `whitespace-style' value.")
1311 ;;;###autoload
1312 (defun global-whitespace-toggle-options (arg)
1313 "Toggle global `whitespace-mode' options.
1315 If global whitespace-mode is off, toggle the option given by ARG
1316 and turn on global whitespace-mode.
1318 If global whitespace-mode is on, toggle the option given by ARG
1319 and restart global whitespace-mode.
1321 Interactively, it accepts one of the following chars:
1323 CHAR MEANING
1324 (VIA FACES)
1325 t toggle TAB visualization
1326 s toggle SPACE and HARD SPACE visualization
1327 r toggle trailing blanks visualization
1328 l toggle \"long lines\" visualization
1329 L toggle \"long lines\" tail visualization
1330 n toggle NEWLINE visualization
1331 e toggle empty line at bob and/or eob visualization
1332 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1333 I toggle indentation SPACEs visualization
1334 i toggle indentation TABs visualization
1335 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1336 A toggle SPACEs after TAB: SPACEs visualization
1337 a toggle SPACEs after TAB: TABs visualization
1338 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1339 B toggle SPACEs before TAB: SPACEs visualization
1340 b toggle SPACEs before TAB: TABs visualization
1342 (VIA DISPLAY TABLE)
1343 T toggle TAB visualization
1344 S toggle SPACEs before TAB visualization
1345 N toggle NEWLINE visualization
1347 x restore `whitespace-style' value
1348 ? display brief help
1350 Non-interactively, ARG should be a symbol or a list of symbols.
1351 The valid symbols are:
1353 tabs toggle TAB visualization
1354 spaces toggle SPACE and HARD SPACE visualization
1355 trailing toggle trailing blanks visualization
1356 lines toggle \"long lines\" visualization
1357 lines-tail toggle \"long lines\" tail visualization
1358 newline toggle NEWLINE visualization
1359 empty toggle empty line at bob and/or eob visualization
1360 indentation toggle indentation SPACEs visualization
1361 indentation::tab toggle indentation SPACEs visualization
1362 indentation::space toggle indentation TABs visualization
1363 space-after-tab toggle SPACEs after TAB visualization
1364 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1365 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1366 space-before-tab toggle SPACEs before TAB visualization
1367 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1368 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1370 tab-mark toggle TAB visualization
1371 space-mark toggle SPACEs before TAB visualization
1372 newline-mark toggle NEWLINE visualization
1374 whitespace-style restore `whitespace-style' value
1376 Only useful with a windowing system.
1378 See `whitespace-style' and `indent-tabs-mode' for documentation."
1379 (interactive (whitespace-interactive-char nil))
1380 (let ((whitespace-style
1381 (whitespace-toggle-list nil arg whitespace-toggle-style)))
1382 (setq whitespace-toggle-style whitespace-style)
1383 (global-whitespace-mode 0)
1384 (global-whitespace-mode 1)))
1387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1388 ;;;; User commands - Cleanup
1391 ;;;###autoload
1392 (defun whitespace-cleanup ()
1393 "Cleanup some blank problems in all buffer or at region.
1395 It usually applies to the whole buffer, but in transient mark
1396 mode when the mark is active, it applies to the region. It also
1397 applies to the region when it is not in transient mark mode, the
1398 mark is active and \\[universal-argument] was pressed just before
1399 calling `whitespace-cleanup' interactively.
1401 See also `whitespace-cleanup-region'.
1403 The problems cleaned up are:
1405 1. empty lines at beginning of buffer.
1406 2. empty lines at end of buffer.
1407 If `whitespace-style' includes the value `empty', remove all
1408 empty lines at beginning and/or end of buffer.
1410 3. 8 or more SPACEs at beginning of line.
1411 If `whitespace-style' includes the value `indentation':
1412 replace 8 or more SPACEs at beginning of line by TABs, if
1413 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1414 SPACEs.
1415 If `whitespace-style' includes the value `indentation::tab',
1416 replace 8 or more SPACEs at beginning of line by TABs.
1417 If `whitespace-style' includes the value `indentation::space',
1418 replace TABs by SPACEs.
1420 4. SPACEs before TAB.
1421 If `whitespace-style' includes the value `space-before-tab':
1422 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1423 otherwise, replace TABs by SPACEs.
1424 If `whitespace-style' includes the value
1425 `space-before-tab::tab', replace SPACEs by TABs.
1426 If `whitespace-style' includes the value
1427 `space-before-tab::space', replace TABs by SPACEs.
1429 5. SPACEs or TABs at end of line.
1430 If `whitespace-style' includes the value `trailing', remove
1431 all SPACEs or TABs at end of line.
1433 6. 8 or more SPACEs after TAB.
1434 If `whitespace-style' includes the value `space-after-tab':
1435 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1436 otherwise, replace TABs by SPACEs.
1437 If `whitespace-style' includes the value
1438 `space-after-tab::tab', replace SPACEs by TABs.
1439 If `whitespace-style' includes the value
1440 `space-after-tab::space', replace TABs by SPACEs.
1442 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1443 documentation."
1444 (interactive "@")
1445 (cond
1446 ;; read-only buffer
1447 (buffer-read-only
1448 (whitespace-warn-read-only "cleanup"))
1449 ;; region active
1450 ((and (or transient-mark-mode
1451 current-prefix-arg)
1452 mark-active)
1453 ;; PROBLEMs 1 and 2 are not handled in region
1454 ;; PROBLEM 3: 8 or more SPACEs at bol
1455 ;; PROBLEM 4: SPACEs before TAB
1456 ;; PROBLEM 5: SPACEs or TABs at eol
1457 ;; PROBLEM 6: 8 or more SPACEs after TAB
1458 (whitespace-cleanup-region (region-beginning) (region-end)))
1459 ;; whole buffer
1461 (save-excursion
1462 (save-match-data
1463 ;; PROBLEM 1: empty lines at bob
1464 ;; PROBLEM 2: empty lines at eob
1465 ;; ACTION: remove all empty lines at bob and/or eob
1466 (when (memq 'empty whitespace-style)
1467 (let (overwrite-mode) ; enforce no overwrite
1468 (goto-char (point-min))
1469 (when (re-search-forward
1470 whitespace-empty-at-bob-regexp nil t)
1471 (delete-region (match-beginning 1) (match-end 1)))
1472 (when (re-search-forward
1473 whitespace-empty-at-eob-regexp nil t)
1474 (delete-region (match-beginning 1) (match-end 1)))))))
1475 ;; PROBLEM 3: 8 or more SPACEs at bol
1476 ;; PROBLEM 4: SPACEs before TAB
1477 ;; PROBLEM 5: SPACEs or TABs at eol
1478 ;; PROBLEM 6: 8 or more SPACEs after TAB
1479 (whitespace-cleanup-region (point-min) (point-max)))))
1482 ;;;###autoload
1483 (defun whitespace-cleanup-region (start end)
1484 "Cleanup some blank problems at region.
1486 The problems cleaned up are:
1488 1. 8 or more SPACEs at beginning of line.
1489 If `whitespace-style' includes the value `indentation':
1490 replace 8 or more SPACEs at beginning of line by TABs, if
1491 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1492 SPACEs.
1493 If `whitespace-style' includes the value `indentation::tab',
1494 replace 8 or more SPACEs at beginning of line by TABs.
1495 If `whitespace-style' includes the value `indentation::space',
1496 replace TABs by SPACEs.
1498 2. SPACEs before TAB.
1499 If `whitespace-style' includes the value `space-before-tab':
1500 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1501 otherwise, replace TABs by SPACEs.
1502 If `whitespace-style' includes the value
1503 `space-before-tab::tab', replace SPACEs by TABs.
1504 If `whitespace-style' includes the value
1505 `space-before-tab::space', replace TABs by SPACEs.
1507 3. SPACEs or TABs at end of line.
1508 If `whitespace-style' includes the value `trailing', remove
1509 all SPACEs or TABs at end of line.
1511 4. 8 or more SPACEs after TAB.
1512 If `whitespace-style' includes the value `space-after-tab':
1513 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1514 otherwise, replace TABs by SPACEs.
1515 If `whitespace-style' includes the value
1516 `space-after-tab::tab', replace SPACEs by TABs.
1517 If `whitespace-style' includes the value
1518 `space-after-tab::space', replace TABs by SPACEs.
1520 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1521 documentation."
1522 (interactive "@r")
1523 (if buffer-read-only
1524 ;; read-only buffer
1525 (whitespace-warn-read-only "cleanup region")
1526 ;; non-read-only buffer
1527 (let ((rstart (min start end))
1528 (rend (copy-marker (max start end)))
1529 (indent-tabs-mode whitespace-indent-tabs-mode)
1530 (tab-width whitespace-tab-width)
1531 overwrite-mode ; enforce no overwrite
1532 tmp)
1533 (save-excursion
1534 (save-match-data
1535 ;; PROBLEM 1: 8 or more SPACEs at bol
1536 (cond
1537 ;; ACTION: replace 8 or more SPACEs at bol by TABs, if
1538 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1539 ;; by SPACEs.
1540 ((memq 'indentation whitespace-style)
1541 (let ((regexp (whitespace-indentation-regexp)))
1542 (goto-char rstart)
1543 (while (re-search-forward regexp rend t)
1544 (setq tmp (current-indentation))
1545 (goto-char (match-beginning 0))
1546 (delete-horizontal-space)
1547 (unless (eolp)
1548 (indent-to tmp)))))
1549 ;; ACTION: replace 8 or more SPACEs at bol by TABs.
1550 ((memq 'indentation::tab whitespace-style)
1551 (whitespace-replace-action
1552 'tabify rstart rend
1553 (whitespace-indentation-regexp 'tab) 0))
1554 ;; ACTION: replace TABs by SPACEs.
1555 ((memq 'indentation::space whitespace-style)
1556 (whitespace-replace-action
1557 'untabify rstart rend
1558 (whitespace-indentation-regexp 'space) 0)))
1559 ;; PROBLEM 3: SPACEs or TABs at eol
1560 ;; ACTION: remove all SPACEs or TABs at eol
1561 (when (memq 'trailing whitespace-style)
1562 (whitespace-replace-action
1563 'delete-region rstart rend
1564 whitespace-trailing-regexp 1))
1565 ;; PROBLEM 4: 8 or more SPACEs after TAB
1566 (cond
1567 ;; ACTION: replace 8 or more SPACEs by TABs, if
1568 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1569 ;; by SPACEs.
1570 ((memq 'space-after-tab whitespace-style)
1571 (whitespace-replace-action
1572 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1573 rstart rend (whitespace-space-after-tab-regexp) 1))
1574 ;; ACTION: replace 8 or more SPACEs by TABs.
1575 ((memq 'space-after-tab::tab whitespace-style)
1576 (whitespace-replace-action
1577 'tabify rstart rend
1578 (whitespace-space-after-tab-regexp 'tab) 1))
1579 ;; ACTION: replace TABs by SPACEs.
1580 ((memq 'space-after-tab::space whitespace-style)
1581 (whitespace-replace-action
1582 'untabify rstart rend
1583 (whitespace-space-after-tab-regexp 'space) 1)))
1584 ;; PROBLEM 2: SPACEs before TAB
1585 (cond
1586 ;; ACTION: replace SPACEs before TAB by TABs, if
1587 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1588 ;; by SPACEs.
1589 ((memq 'space-before-tab whitespace-style)
1590 (whitespace-replace-action
1591 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1592 rstart rend whitespace-space-before-tab-regexp
1593 (if whitespace-indent-tabs-mode 1 2)))
1594 ;; ACTION: replace SPACEs before TAB by TABs.
1595 ((memq 'space-before-tab::tab whitespace-style)
1596 (whitespace-replace-action
1597 'tabify rstart rend
1598 whitespace-space-before-tab-regexp 1))
1599 ;; ACTION: replace TABs by SPACEs.
1600 ((memq 'space-before-tab::space whitespace-style)
1601 (whitespace-replace-action
1602 'untabify rstart rend
1603 whitespace-space-before-tab-regexp 2)))))
1604 (set-marker rend nil)))) ; point marker to nowhere
1607 (defun whitespace-replace-action (action rstart rend regexp index)
1608 "Do ACTION in the string matched by REGEXP between RSTART and REND.
1610 INDEX is the level group matched by REGEXP and used by ACTION.
1612 See also `tab-width'."
1613 (goto-char rstart)
1614 (while (re-search-forward regexp rend t)
1615 (goto-char (match-end index))
1616 (funcall action (match-beginning index) (match-end index))))
1619 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1620 ;;;; User command - report
1623 (defun whitespace-regexp (regexp &optional kind)
1624 "Return REGEXP depending on `whitespace-indent-tabs-mode'."
1625 (cond
1626 ((or (eq kind 'tab)
1627 whitespace-indent-tabs-mode)
1628 (format (car regexp) whitespace-tab-width))
1629 ((or (eq kind 'space)
1630 (not whitespace-indent-tabs-mode))
1631 (cdr regexp))))
1634 (defun whitespace-indentation-regexp (&optional kind)
1635 "Return the indentation regexp depending on `whitespace-indent-tabs-mode'."
1636 (whitespace-regexp whitespace-indentation-regexp kind))
1639 (defun whitespace-space-after-tab-regexp (&optional kind)
1640 "Return the space-after-tab regexp depending on `whitespace-indent-tabs-mode'."
1641 (whitespace-regexp whitespace-space-after-tab-regexp kind))
1644 (defconst whitespace-report-list
1645 (list
1646 (cons 'empty whitespace-empty-at-bob-regexp)
1647 (cons 'empty whitespace-empty-at-eob-regexp)
1648 (cons 'trailing whitespace-trailing-regexp)
1649 (cons 'indentation nil)
1650 (cons 'indentation::tab nil)
1651 (cons 'indentation::space nil)
1652 (cons 'space-before-tab whitespace-space-before-tab-regexp)
1653 (cons 'space-before-tab::tab whitespace-space-before-tab-regexp)
1654 (cons 'space-before-tab::space whitespace-space-before-tab-regexp)
1655 (cons 'space-after-tab nil)
1656 (cons 'space-after-tab::tab nil)
1657 (cons 'space-after-tab::space nil)
1659 "List of whitespace bogus symbol and corresponding regexp.")
1662 (defconst whitespace-report-text
1663 '( ;; `indent-tabs-mode' has non-nil value
1665 Whitespace Report
1667 Current Setting Whitespace Problem
1669 empty [] [] empty lines at beginning of buffer
1670 empty [] [] empty lines at end of buffer
1671 trailing [] [] SPACEs or TABs at end of line
1672 indentation [] [] 8 or more SPACEs at beginning of line
1673 indentation::tab [] [] 8 or more SPACEs at beginning of line
1674 indentation::space [] [] TABs at beginning of line
1675 space-before-tab [] [] SPACEs before TAB
1676 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1677 space-before-tab::space [] [] SPACEs before TAB: TABs
1678 space-after-tab [] [] 8 or more SPACEs after TAB
1679 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1680 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1682 indent-tabs-mode =
1683 tab-width = \n\n"
1684 . ;; `indent-tabs-mode' has nil value
1686 Whitespace Report
1688 Current Setting Whitespace Problem
1690 empty [] [] empty lines at beginning of buffer
1691 empty [] [] empty lines at end of buffer
1692 trailing [] [] SPACEs or TABs at end of line
1693 indentation [] [] TABs at beginning of line
1694 indentation::tab [] [] 8 or more SPACEs at beginning of line
1695 indentation::space [] [] TABs at beginning of line
1696 space-before-tab [] [] SPACEs before TAB
1697 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1698 space-before-tab::space [] [] SPACEs before TAB: TABs
1699 space-after-tab [] [] 8 or more SPACEs after TAB
1700 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1701 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1703 indent-tabs-mode =
1704 tab-width = \n\n")
1705 "Text for whitespace bogus report.
1707 It is a cons of strings, where the car part is used when
1708 `indent-tabs-mode' is non-nil, and the cdr part is used when
1709 `indent-tabs-mode' is nil.")
1712 (defconst whitespace-report-buffer-name "*Whitespace Report*"
1713 "The buffer name for whitespace bogus report.")
1716 ;;;###autoload
1717 (defun whitespace-report (&optional force report-if-bogus)
1718 "Report some whitespace problems in buffer.
1720 Return nil if there is no whitespace problem; otherwise, return
1721 non-nil.
1723 If FORCE is non-nil or \\[universal-argument] was pressed just
1724 before calling `whitespace-report' interactively, it forces
1725 `whitespace-style' to have:
1727 empty
1728 trailing
1729 indentation
1730 space-before-tab
1731 space-after-tab
1733 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1734 whitespace problems in buffer.
1736 Report if some of the following whitespace problems exist:
1738 * If `indent-tabs-mode' is non-nil:
1739 empty 1. empty lines at beginning of buffer.
1740 empty 2. empty lines at end of buffer.
1741 trailing 3. SPACEs or TABs at end of line.
1742 indentation 4. 8 or more SPACEs at beginning of line.
1743 space-before-tab 5. SPACEs before TAB.
1744 space-after-tab 6. 8 or more SPACEs after TAB.
1746 * If `indent-tabs-mode' is nil:
1747 empty 1. empty lines at beginning of buffer.
1748 empty 2. empty lines at end of buffer.
1749 trailing 3. SPACEs or TABs at end of line.
1750 indentation 4. TABS at beginning of line.
1751 space-before-tab 5. SPACEs before TAB.
1752 space-after-tab 6. 8 or more SPACEs after TAB.
1754 See `whitespace-style' for documentation.
1755 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1756 cleaning up these problems."
1757 (interactive (list current-prefix-arg))
1758 (whitespace-report-region (point-min) (point-max)
1759 force report-if-bogus))
1762 ;;;###autoload
1763 (defun whitespace-report-region (start end &optional force report-if-bogus)
1764 "Report some whitespace problems in a region.
1766 Return nil if there is no whitespace problem; otherwise, return
1767 non-nil.
1769 If FORCE is non-nil or \\[universal-argument] was pressed just
1770 before calling `whitespace-report-region' interactively, it
1771 forces `whitespace-style' to have:
1773 empty
1774 indentation
1775 space-before-tab
1776 trailing
1777 space-after-tab
1779 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1780 whitespace problems in buffer.
1782 Report if some of the following whitespace problems exist:
1784 * If `indent-tabs-mode' is non-nil:
1785 empty 1. empty lines at beginning of buffer.
1786 empty 2. empty lines at end of buffer.
1787 trailing 3. SPACEs or TABs at end of line.
1788 indentation 4. 8 or more SPACEs at beginning of line.
1789 space-before-tab 5. SPACEs before TAB.
1790 space-after-tab 6. 8 or more SPACEs after TAB.
1792 * If `indent-tabs-mode' is nil:
1793 empty 1. empty lines at beginning of buffer.
1794 empty 2. empty lines at end of buffer.
1795 trailing 3. SPACEs or TABs at end of line.
1796 indentation 4. TABS at beginning of line.
1797 space-before-tab 5. SPACEs before TAB.
1798 space-after-tab 6. 8 or more SPACEs after TAB.
1800 See `whitespace-style' for documentation.
1801 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1802 cleaning up these problems."
1803 (interactive "r")
1804 (setq force (or current-prefix-arg force))
1805 (save-excursion
1806 (save-match-data
1807 (let* ((has-bogus nil)
1808 (rstart (min start end))
1809 (rend (max start end))
1810 (bogus-list
1811 (mapcar
1812 #'(lambda (option)
1813 (when force
1814 (add-to-list 'whitespace-style (car option)))
1815 (goto-char rstart)
1816 (let ((regexp
1817 (cond
1818 ((eq (car option) 'indentation)
1819 (whitespace-indentation-regexp))
1820 ((eq (car option) 'indentation::tab)
1821 (whitespace-indentation-regexp 'tab))
1822 ((eq (car option) 'indentation::space)
1823 (whitespace-indentation-regexp 'space))
1824 ((eq (car option) 'space-after-tab)
1825 (whitespace-space-after-tab-regexp))
1826 ((eq (car option) 'space-after-tab::tab)
1827 (whitespace-space-after-tab-regexp 'tab))
1828 ((eq (car option) 'space-after-tab::space)
1829 (whitespace-space-after-tab-regexp 'space))
1831 (cdr option)))))
1832 (and (re-search-forward regexp rend t)
1833 (setq has-bogus t))))
1834 whitespace-report-list)))
1835 (when (if report-if-bogus has-bogus t)
1836 (whitespace-kill-buffer whitespace-report-buffer-name)
1837 ;; `whitespace-indent-tabs-mode' is local to current buffer
1838 ;; `whitespace-tab-width' is local to current buffer
1839 (let ((ws-indent-tabs-mode whitespace-indent-tabs-mode)
1840 (ws-tab-width whitespace-tab-width))
1841 (with-current-buffer (get-buffer-create
1842 whitespace-report-buffer-name)
1843 (erase-buffer)
1844 (insert (if ws-indent-tabs-mode
1845 (car whitespace-report-text)
1846 (cdr whitespace-report-text)))
1847 (goto-char (point-min))
1848 (forward-line 3)
1849 (dolist (option whitespace-report-list)
1850 (forward-line 1)
1851 (whitespace-mark-x
1852 27 (memq (car option) whitespace-style))
1853 (whitespace-mark-x 7 (car bogus-list))
1854 (setq bogus-list (cdr bogus-list)))
1855 (forward-line 1)
1856 (whitespace-insert-value ws-indent-tabs-mode)
1857 (whitespace-insert-value ws-tab-width)
1858 (when has-bogus
1859 (goto-char (point-max))
1860 (insert " Type `M-x whitespace-cleanup'"
1861 " to cleanup the buffer.\n\n"
1862 " Type `M-x whitespace-cleanup-region'"
1863 " to cleanup a region.\n\n"))
1864 (whitespace-display-window (current-buffer)))))
1865 has-bogus))))
1868 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1869 ;;;; Internal functions
1872 (defvar whitespace-font-lock-mode nil
1873 "Used to remember whether a buffer had font lock mode on or not.")
1875 (defvar whitespace-font-lock nil
1876 "Used to remember whether a buffer initially had font lock on or not.")
1878 (defvar whitespace-font-lock-keywords nil
1879 "Used to save locally `font-lock-keywords' value.")
1882 (defconst whitespace-help-text
1884 Whitespace Toggle Options
1886 FACES
1887 [] t - toggle TAB visualization
1888 [] s - toggle SPACE and HARD SPACE visualization
1889 [] r - toggle trailing blanks visualization
1890 [] l - toggle \"long lines\" visualization
1891 [] L - toggle \"long lines\" tail visualization
1892 [] n - toggle NEWLINE visualization
1893 [] e - toggle empty line at bob and/or eob visualization
1894 [] C-i - toggle indentation SPACEs visualization (via `indent-tabs-mode')
1895 [] I - toggle indentation SPACEs visualization
1896 [] i - toggle indentation TABs visualization
1897 [] C-a - toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1898 [] A - toggle SPACEs after TAB: SPACEs visualization
1899 [] a - toggle SPACEs after TAB: TABs visualization
1900 [] C-b - toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1901 [] B - toggle SPACEs before TAB: SPACEs visualization
1902 [] b - toggle SPACEs before TAB: TABs visualization
1904 DISPLAY TABLE
1905 [] T - toggle TAB visualization
1906 [] S - toggle SPACE and HARD SPACE visualization
1907 [] N - toggle NEWLINE visualization
1909 x - restore `whitespace-style' value
1911 ? - display this text\n\n"
1912 "Text for whitespace toggle options.")
1915 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1916 "The buffer name for whitespace toggle options.")
1919 (defun whitespace-insert-value (value)
1920 "Insert VALUE at column 20 of next line."
1921 (forward-line 1)
1922 (move-to-column 20 t)
1923 (insert (format "%s" value)))
1926 (defun whitespace-mark-x (nchars condition)
1927 "Insert the mark ('X' or ' ') after NCHARS depending on CONDITION."
1928 (forward-char nchars)
1929 (insert (if condition "X" " ")))
1932 (defun whitespace-insert-option-mark (the-list the-value)
1933 "Insert the option mark ('X' or ' ') in toggle options buffer."
1934 (goto-char (point-min))
1935 (forward-line 2)
1936 (dolist (sym the-list)
1937 (if (eq sym 'help-newline)
1938 (forward-line 2)
1939 (forward-line 1)
1940 (whitespace-mark-x 2 (memq sym the-value)))))
1943 (defun whitespace-help-on (style)
1944 "Display the whitespace toggle options."
1945 (unless (get-buffer whitespace-help-buffer-name)
1946 (delete-other-windows)
1947 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
1948 (save-excursion
1949 (set-buffer buffer)
1950 (erase-buffer)
1951 (insert whitespace-help-text)
1952 (whitespace-insert-option-mark
1953 whitespace-style-value-list style)
1954 (whitespace-display-window buffer)))))
1957 (defun whitespace-display-window (buffer)
1958 "Display BUFFER in a new window."
1959 (goto-char (point-min))
1960 (set-buffer-modified-p nil)
1961 (let ((size (- (window-height)
1962 (max window-min-height
1963 (1+ (count-lines (point-min)
1964 (point-max)))))))
1965 (when (<= size 0)
1966 (kill-buffer buffer)
1967 (error "Frame height is too small; \
1968 can't split window to display whitespace toggle options"))
1969 (set-window-buffer (split-window nil size) buffer)))
1972 (defun whitespace-kill-buffer (buffer-name)
1973 "Kill buffer BUFFER-NAME and windows related with it."
1974 (let ((buffer (get-buffer buffer-name)))
1975 (when buffer
1976 (delete-windows-on buffer)
1977 (kill-buffer buffer))))
1980 (defun whitespace-help-off ()
1981 "Remove the buffer and window of the whitespace toggle options."
1982 (whitespace-kill-buffer whitespace-help-buffer-name))
1985 (defun whitespace-interactive-char (local-p)
1986 "Interactive function to read a char and return a symbol.
1988 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1989 uses a global context.
1991 It accepts one of the following chars:
1993 CHAR MEANING
1994 (VIA FACES)
1995 t toggle TAB visualization
1996 s toggle SPACE and HARD SPACE visualization
1997 r toggle trailing blanks visualization
1998 l toggle \"long lines\" visualization
1999 L toggle \"long lines\" tail visualization
2000 n toggle NEWLINE visualization
2001 e toggle empty line at bob and/or eob visualization
2002 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
2003 I toggle indentation SPACEs visualization
2004 i toggle indentation TABs visualization
2005 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
2006 A toggle SPACEs after TAB: SPACEs visualization
2007 a toggle SPACEs after TAB: TABs visualization
2008 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
2009 B toggle SPACEs before TAB: SPACEs visualization
2010 b toggle SPACEs before TAB: TABs visualization
2012 (VIA DISPLAY TABLE)
2013 T toggle TAB visualization
2014 S toggle SPACE and HARD SPACE visualization
2015 N toggle NEWLINE visualization
2017 x restore `whitespace-style' value
2018 ? display brief help
2020 See also `whitespace-toggle-option-alist'."
2021 (let* ((is-off (not (if local-p
2022 whitespace-mode
2023 global-whitespace-mode)))
2024 (style (cond (is-off whitespace-style) ; use default value
2025 (local-p whitespace-active-style)
2026 (t whitespace-toggle-style)))
2027 (prompt
2028 (format "Whitespace Toggle %s (type ? for further options)-"
2029 (if local-p "Local" "Global")))
2030 ch sym)
2031 ;; read a valid option and get the corresponding symbol
2032 (save-window-excursion
2033 (condition-case data
2034 (progn
2035 (while
2036 ;; while condition
2037 (progn
2038 (setq ch (read-char prompt))
2039 (not
2040 (setq sym
2041 (cdr
2042 (assq ch whitespace-toggle-option-alist)))))
2043 ;; while body
2044 (if (eq ch ?\?)
2045 (whitespace-help-on style)
2046 (ding)))
2047 (whitespace-help-off)
2048 (message " ")) ; clean echo area
2049 ;; handler
2050 ((quit error)
2051 (whitespace-help-off)
2052 (error (error-message-string data)))))
2053 (list sym))) ; return the apropriate symbol
2056 (defun whitespace-toggle-list (local-p arg the-list)
2057 "Toggle options in THE-LIST based on list ARG.
2059 If LOCAL-P is non-nil, it uses a local context; otherwise, it
2060 uses a global context.
2062 ARG is a list of options to be toggled.
2064 THE-LIST is a list of options. This list will be toggled and the
2065 resultant list will be returned."
2066 (unless (if local-p whitespace-mode global-whitespace-mode)
2067 (setq the-list whitespace-style))
2068 (setq the-list (copy-sequence the-list)) ; keep original list
2069 (dolist (sym (if (listp arg) arg (list arg)))
2070 (cond
2071 ;; ignore help value
2072 ((eq sym 'help-newline))
2073 ;; restore default values
2074 ((eq sym 'whitespace-style)
2075 (setq the-list whitespace-style))
2076 ;; toggle valid values
2077 ((memq sym whitespace-style-value-list)
2078 (setq the-list (if (memq sym the-list)
2079 (delq sym the-list)
2080 (cons sym the-list))))))
2081 the-list)
2084 (defvar whitespace-display-table nil
2085 "Used to save a local display table.")
2087 (defvar whitespace-display-table-was-local nil
2088 "Used to remember whether a buffer initially had a local display table.")
2091 (defun whitespace-turn-on ()
2092 "Turn on whitespace visualization."
2093 ;; prepare local hooks
2094 (add-hook 'write-file-functions 'whitespace-write-file-hook nil t)
2095 ;; create whitespace local buffer environment
2096 (set (make-local-variable 'whitespace-font-lock-mode) nil)
2097 (set (make-local-variable 'whitespace-font-lock) nil)
2098 (set (make-local-variable 'whitespace-font-lock-keywords) nil)
2099 (set (make-local-variable 'whitespace-display-table) nil)
2100 (set (make-local-variable 'whitespace-display-table-was-local) nil)
2101 (set (make-local-variable 'whitespace-active-style)
2102 (if (listp whitespace-style)
2103 whitespace-style
2104 (list whitespace-style)))
2105 (set (make-local-variable 'whitespace-indent-tabs-mode)
2106 indent-tabs-mode)
2107 (set (make-local-variable 'whitespace-tab-width)
2108 tab-width)
2109 ;; turn on whitespace
2110 (when whitespace-active-style
2111 (whitespace-color-on)
2112 (whitespace-display-char-on)))
2115 (defun whitespace-turn-off ()
2116 "Turn off whitespace visualization."
2117 (remove-hook 'write-file-functions 'whitespace-write-file-hook t)
2118 (when whitespace-active-style
2119 (whitespace-color-off)
2120 (whitespace-display-char-off)))
2123 (defun whitespace-style-face-p ()
2124 "Return t if there is some visualization via face."
2125 (or (memq 'tabs whitespace-active-style)
2126 (memq 'spaces whitespace-active-style)
2127 (memq 'trailing whitespace-active-style)
2128 (memq 'lines whitespace-active-style)
2129 (memq 'lines-tail whitespace-active-style)
2130 (memq 'newline whitespace-active-style)
2131 (memq 'empty whitespace-active-style)
2132 (memq 'indentation whitespace-active-style)
2133 (memq 'indentation::tab whitespace-active-style)
2134 (memq 'indentation::space whitespace-active-style)
2135 (memq 'space-after-tab whitespace-active-style)
2136 (memq 'space-after-tab::tab whitespace-active-style)
2137 (memq 'space-after-tab::space whitespace-active-style)
2138 (memq 'space-before-tab whitespace-active-style)
2139 (memq 'space-before-tab::tab whitespace-active-style)
2140 (memq 'space-before-tab::space whitespace-active-style)))
2143 (defun whitespace-color-on ()
2144 "Turn on color visualization."
2145 (when (whitespace-style-face-p)
2146 (unless whitespace-font-lock
2147 (setq whitespace-font-lock t
2148 whitespace-font-lock-keywords
2149 (copy-sequence font-lock-keywords)))
2150 ;; save current point and refontify when necessary
2151 (set (make-local-variable 'whitespace-point)
2152 (point))
2153 (set (make-local-variable 'whitespace-font-lock-refontify)
2154 nil)
2155 (add-hook 'post-command-hook #'whitespace-post-command-hook nil t)
2156 ;; turn off font lock
2157 (set (make-local-variable 'whitespace-font-lock-mode)
2158 font-lock-mode)
2159 (font-lock-mode 0)
2160 ;; add whitespace-mode color into font lock
2161 (when (memq 'spaces whitespace-active-style)
2162 (font-lock-add-keywords
2164 (list
2165 ;; Show SPACEs
2166 (list #'whitespace-space-regexp 1 whitespace-space t)
2167 ;; Show HARD SPACEs
2168 (list whitespace-hspace-regexp 1 whitespace-hspace t))
2170 (when (memq 'tabs whitespace-active-style)
2171 (font-lock-add-keywords
2173 (list
2174 ;; Show TABs
2175 (list #'whitespace-tab-regexp 1 whitespace-tab t))
2177 (when (memq 'trailing whitespace-active-style)
2178 (font-lock-add-keywords
2180 (list
2181 ;; Show trailing blanks
2182 (list #'whitespace-trailing-regexp 1 whitespace-trailing t))
2184 (when (or (memq 'lines whitespace-active-style)
2185 (memq 'lines-tail whitespace-active-style))
2186 (font-lock-add-keywords
2188 (list
2189 ;; Show "long" lines
2190 (list
2191 (format
2192 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
2193 whitespace-tab-width (1- whitespace-tab-width)
2194 (/ whitespace-line-column whitespace-tab-width)
2195 (let ((rem (% whitespace-line-column whitespace-tab-width)))
2196 (if (zerop rem)
2198 (format ".\\{%d\\}" rem))))
2199 (if (memq 'lines whitespace-active-style)
2200 0 ; whole line
2201 2) ; line tail
2202 whitespace-line t))
2204 (cond
2205 ((memq 'space-before-tab whitespace-active-style)
2206 (font-lock-add-keywords
2208 (list
2209 ;; Show SPACEs before TAB (indent-tabs-mode)
2210 (list whitespace-space-before-tab-regexp
2211 (if whitespace-indent-tabs-mode 1 2)
2212 whitespace-space-before-tab t))
2214 ((memq 'space-before-tab::tab whitespace-active-style)
2215 (font-lock-add-keywords
2217 (list
2218 ;; Show SPACEs before TAB (SPACEs)
2219 (list whitespace-space-before-tab-regexp
2220 1 whitespace-space-before-tab t))
2222 ((memq 'space-before-tab::space whitespace-active-style)
2223 (font-lock-add-keywords
2225 (list
2226 ;; Show SPACEs before TAB (TABs)
2227 (list whitespace-space-before-tab-regexp
2228 2 whitespace-space-before-tab t))
2229 t)))
2230 (cond
2231 ((memq 'indentation whitespace-active-style)
2232 (font-lock-add-keywords
2234 (list
2235 ;; Show indentation SPACEs (indent-tabs-mode)
2236 (list (whitespace-indentation-regexp)
2237 1 whitespace-indentation t))
2239 ((memq 'indentation::tab whitespace-active-style)
2240 (font-lock-add-keywords
2242 (list
2243 ;; Show indentation SPACEs (SPACEs)
2244 (list (whitespace-indentation-regexp 'tab)
2245 1 whitespace-indentation t))
2247 ((memq 'indentation::space whitespace-active-style)
2248 (font-lock-add-keywords
2250 (list
2251 ;; Show indentation SPACEs (TABs)
2252 (list (whitespace-indentation-regexp 'space)
2253 1 whitespace-indentation t))
2254 t)))
2255 (when (memq 'empty whitespace-active-style)
2256 (font-lock-add-keywords
2258 (list
2259 ;; Show empty lines at beginning of buffer
2260 (list #'whitespace-empty-at-bob-regexp
2261 1 whitespace-empty t))
2263 (font-lock-add-keywords
2265 (list
2266 ;; Show empty lines at end of buffer
2267 (list #'whitespace-empty-at-eob-regexp
2268 1 whitespace-empty t))
2270 (cond
2271 ((memq 'space-after-tab whitespace-active-style)
2272 (font-lock-add-keywords
2274 (list
2275 ;; Show SPACEs after TAB (indent-tabs-mode)
2276 (list (whitespace-space-after-tab-regexp)
2277 1 whitespace-space-after-tab t))
2279 ((memq 'space-after-tab::tab whitespace-active-style)
2280 (font-lock-add-keywords
2282 (list
2283 ;; Show SPACEs after TAB (SPACEs)
2284 (list (whitespace-space-after-tab-regexp 'tab)
2285 1 whitespace-space-after-tab t))
2287 ((memq 'space-after-tab::space whitespace-active-style)
2288 (font-lock-add-keywords
2290 (list
2291 ;; Show SPACEs after TAB (TABs)
2292 (list (whitespace-space-after-tab-regexp 'space)
2293 1 whitespace-space-after-tab t))
2294 t)))
2295 ;; now turn on font lock and highlight blanks
2296 (font-lock-mode 1)))
2299 (defun whitespace-color-off ()
2300 "Turn off color visualization."
2301 ;; turn off font lock
2302 (when (whitespace-style-face-p)
2303 (font-lock-mode 0)
2304 (remove-hook 'post-command-hook #'whitespace-post-command-hook)
2305 (when whitespace-font-lock
2306 (setq whitespace-font-lock nil
2307 font-lock-keywords whitespace-font-lock-keywords))
2308 ;; restore original font lock state
2309 (font-lock-mode whitespace-font-lock-mode)))
2312 (defun whitespace-trailing-regexp (limit)
2313 "Match trailing spaces which do not contain the point at end of line."
2314 (let ((status t))
2315 (while (if (re-search-forward whitespace-trailing-regexp limit t)
2316 (save-match-data
2317 (= whitespace-point (match-end 1))) ;; loop if point at eol
2318 (setq status nil))) ;; end of buffer
2319 status))
2322 (defun whitespace-empty-at-bob-regexp (limit)
2323 "Match spaces at beginning of buffer which do not contain the point at \
2324 beginning of buffer."
2325 (and (/= whitespace-point 1)
2326 (re-search-forward whitespace-empty-at-bob-regexp limit t)))
2329 (defun whitespace-empty-at-eob-regexp (limit)
2330 "Match spaces at end of buffer which do not contain the point at end of \
2331 buffer."
2332 (and (/= whitespace-point (1+ (buffer-size)))
2333 (re-search-forward whitespace-empty-at-eob-regexp limit t)))
2336 (defun whitespace-space-regexp (limit)
2337 "Match spaces."
2338 (setq whitespace-font-lock-refontify t)
2339 (re-search-forward whitespace-space-regexp limit t))
2342 (defun whitespace-tab-regexp (limit)
2343 "Match tabs."
2344 (setq whitespace-font-lock-refontify t)
2345 (re-search-forward whitespace-tab-regexp limit t))
2348 (defun whitespace-post-command-hook ()
2349 "Save current point into `whitespace-point' variable.
2350 Also refontify when necessary."
2351 (setq whitespace-point (point))
2352 (let ((refontify (or (eolp) ; end of line
2353 (= whitespace-point 1)))) ; beginning of buffer
2354 (when (or whitespace-font-lock-refontify refontify)
2355 (setq whitespace-font-lock-refontify refontify)
2356 (jit-lock-refontify))))
2359 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2360 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
2363 (defun whitespace-style-mark-p ()
2364 "Return t if there is some visualization via display table."
2365 (or (memq 'tab-mark whitespace-active-style)
2366 (memq 'space-mark whitespace-active-style)
2367 (memq 'newline-mark whitespace-active-style)))
2370 (defsubst whitespace-char-valid-p (char)
2371 ;; This check should be improved!!!
2372 (or (< char 256)
2373 (characterp char)))
2376 (defun whitespace-display-vector-p (vec)
2377 "Return true if every character in vector VEC can be displayed."
2378 (let ((i (length vec)))
2379 (when (> i 0)
2380 (while (and (>= (setq i (1- i)) 0)
2381 (whitespace-char-valid-p (aref vec i))))
2382 (< i 0))))
2385 (defun whitespace-display-char-on ()
2386 "Turn on character display mapping."
2387 (when (and whitespace-display-mappings
2388 (whitespace-style-mark-p))
2389 (let (vecs vec)
2390 ;; Remember whether a buffer has a local display table.
2391 (unless whitespace-display-table-was-local
2392 (setq whitespace-display-table-was-local t
2393 whitespace-display-table
2394 (copy-sequence buffer-display-table)))
2395 (unless buffer-display-table
2396 (setq buffer-display-table (make-display-table)))
2397 (dolist (entry whitespace-display-mappings)
2398 ;; check if it is to display this mark
2399 (when (memq (car entry) whitespace-style)
2400 ;; Get a displayable mapping.
2401 (setq vecs (cddr entry))
2402 (while (and vecs
2403 (not (whitespace-display-vector-p (car vecs))))
2404 (setq vecs (cdr vecs)))
2405 ;; Display a valid mapping.
2406 (when vecs
2407 (setq vec (copy-sequence (car vecs)))
2408 ;; NEWLINE char
2409 (when (and (eq (cadr entry) ?\n)
2410 (memq 'newline whitespace-active-style))
2411 ;; Only insert face bits on NEWLINE char mapping to avoid
2412 ;; obstruction of other faces like TABs and (HARD) SPACEs
2413 ;; faces, font-lock faces, etc.
2414 (dotimes (i (length vec))
2415 (or (eq (aref vec i) ?\n)
2416 (aset vec i
2417 (make-glyph-code (aref vec i)
2418 whitespace-newline)))))
2419 ;; Display mapping
2420 (aset buffer-display-table (cadr entry) vec)))))))
2423 (defun whitespace-display-char-off ()
2424 "Turn off character display mapping."
2425 (and whitespace-display-mappings
2426 (whitespace-style-mark-p)
2427 whitespace-display-table-was-local
2428 (setq whitespace-display-table-was-local nil
2429 buffer-display-table whitespace-display-table)))
2432 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2433 ;;;; Hook
2436 (defun whitespace-action-when-on ()
2437 "Action to be taken always when local whitespace is turned on."
2438 (cond ((memq 'cleanup whitespace-action)
2439 (whitespace-cleanup))
2440 ((memq 'report-on-bogus whitespace-action)
2441 (whitespace-report nil t))))
2444 (defun whitespace-write-file-hook ()
2445 "Action to be taken when buffer is written.
2446 It should be added buffer-locally to `write-file-functions'."
2447 (cond ((memq 'auto-cleanup whitespace-action)
2448 (whitespace-cleanup))
2449 ((memq 'abort-on-bogus whitespace-action)
2450 (when (whitespace-report nil t)
2451 (error "Abort write due to whitespace problems in %s"
2452 (buffer-name)))))
2453 nil) ; continue hook processing
2456 (defun whitespace-warn-read-only (msg)
2457 "Warn if buffer is read-only."
2458 (when (memq 'warn-if-read-only whitespace-action)
2459 (message "Can't %s: %s is read-only" msg (buffer-name))))
2462 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2465 (defun whitespace-unload-function ()
2466 "Unload the whitespace library."
2467 (global-whitespace-mode -1)
2468 ;; be sure all local whitespace mode is turned off
2469 (save-current-buffer
2470 (dolist (buf (buffer-list))
2471 (set-buffer buf)
2472 (whitespace-mode -1)))
2473 nil) ; continue standard unloading
2476 (provide 'whitespace)
2479 (run-hooks 'whitespace-load-hook)
2482 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
2483 ;;; whitespace.el ends here