(diary-face-attrs): Revert previous change to `weight' type. Fix
[emacs.git] / lisp / whitespace.el
blobd156d47f12c0d8bf030e8be55850982ef941ac94
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.3
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-report'
166 ;; Report some blank problems in buffer.
168 ;; `whitespace-report-region'
169 ;; Report some blank problems in a region.
171 ;; `whitespace-cleanup'
172 ;; Cleanup some blank problems in all buffer or at region.
174 ;; `whitespace-cleanup-region'
175 ;; Cleanup some blank problems at region.
177 ;; The problems, which are cleaned up, are:
179 ;; 1. empty lines at beginning of buffer.
180 ;; 2. empty lines at end of buffer.
181 ;; If `whitespace-chars' includes the value `empty', remove all
182 ;; empty lines at beginning and/or end of buffer.
184 ;; 3. 8 or more SPACEs at beginning of line.
185 ;; If `whitespace-chars' includes the value `indentation', replace
186 ;; 8 or more SPACEs at beginning of line by TABs.
188 ;; 4. SPACEs before TAB.
189 ;; If `whitespace-chars' includes the value `space-before-tab',
190 ;; replace SPACEs by TABs.
192 ;; 5. SPACEs or TABs at end of line.
193 ;; If `whitespace-chars' includes the value `trailing', remove all
194 ;; SPACEs or TABs at end of line.
196 ;; 6. 8 or more SPACEs after TAB.
197 ;; If `whitespace-chars' includes the value `space-after-tab',
198 ;; replace SPACEs by TABs.
201 ;; Hooks
202 ;; -----
204 ;; whitespace has the following hook variables:
206 ;; `whitespace-mode-hook'
207 ;; It is evaluated always when whitespace is turned on locally.
209 ;; `global-whitespace-mode-hook'
210 ;; It is evaluated always when whitespace is turned on globally.
212 ;; `whitespace-load-hook'
213 ;; It is evaluated after whitespace package is loaded.
216 ;; Options
217 ;; -------
219 ;; Below it's shown a brief description of whitespace options, please,
220 ;; see the options declaration in the code for a long documentation.
222 ;; `whitespace-style' Specify the visualization style.
224 ;; `whitespace-chars' Specify which kind of blank is
225 ;; visualized.
227 ;; `whitespace-space' Face used to visualize SPACE.
229 ;; `whitespace-hspace' Face used to visualize HARD SPACE.
231 ;; `whitespace-tab' Face used to visualize TAB.
233 ;; `whitespace-newline' Face used to visualize NEWLINE char
234 ;; mapping.
236 ;; `whitespace-trailing' Face used to visualize trailing
237 ;; blanks.
239 ;; `whitespace-line' Face used to visualize "long" lines.
241 ;; `whitespace-space-before-tab' Face used to visualize SPACEs
242 ;; before TAB.
244 ;; `whitespace-indentation' Face used to visualize 8 or more
245 ;; SPACEs at beginning of line.
247 ;; `whitespace-empty' Face used to visualize empty lines at
248 ;; beginning and/or end of buffer.
250 ;; `whitespace-space-after-tab' Face used to visualize 8 or more
251 ;; SPACEs after TAB.
253 ;; `whitespace-space-regexp' Specify SPACE characters regexp.
255 ;; `whitespace-hspace-regexp' Specify HARD SPACE characters regexp.
257 ;; `whitespace-tab-regexp' Specify TAB characters regexp.
259 ;; `whitespace-trailing-regexp' Specify trailing characters regexp.
261 ;; `whitespace-space-before-tab-regexp' Specify SPACEs before TAB
262 ;; regexp.
264 ;; `whitespace-indentation-regexp' Specify regexp for 8 or more
265 ;; SPACEs at beginning of line.
267 ;; `whitespace-empty-at-bob-regexp' Specify regexp for empty lines
268 ;; at beginning of buffer.
270 ;; `whitespace-empty-at-eob-regexp' Specify regexp for empty lines
271 ;; at end of buffer.
273 ;; `whitespace-space-after-tab-regexp' Specify regexp for 8 or more
274 ;; SPACEs after TAB.
276 ;; `whitespace-line-column' Specify column beyond which the line
277 ;; is highlighted.
279 ;; `whitespace-display-mappings' Specify an alist of mappings
280 ;; for displaying characters.
282 ;; `whitespace-global-modes' Modes for which global
283 ;; `whitespace-mode' is automagically
284 ;; turned on.
286 ;; `whitespace-action' Specify which action is taken when a
287 ;; buffer is visited, killed or written.
290 ;; Acknowledgements
291 ;; ----------------
293 ;; Thanks to Eric Cooper <ecc@cmu.edu> for the suggestion to have hook actions
294 ;; when buffer is written or killed as the original whitespace package had.
296 ;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
297 ;; lines tail. See EightyColumnRule (EmacsWiki).
299 ;; Thanks to Juri Linkov <juri@jurta.org> for suggesting:
300 ;; * `define-minor-mode'.
301 ;; * `global-whitespace-*' name for global commands.
303 ;; Thanks to Robert J. Chassell <bob@gnu.org> for doc fix and testing.
305 ;; Thanks to Drew Adams <drew.adams@oracle.com> for toggle commands
306 ;; suggestion.
308 ;; Thanks to Antti Kaihola <antti.kaihola@linux-aktivaattori.org> for
309 ;; helping to fix `find-file-hooks' reference.
311 ;; Thanks to Andreas Roehler <andreas.roehler@easy-emacs.de> for
312 ;; indicating defface byte-compilation warnings.
314 ;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight
315 ;; "long" lines. See EightyColumnRule (EmacsWiki).
317 ;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
318 ;; newline character mapping.
320 ;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
321 ;; whitespace-mode.el on XEmacs.
323 ;; Thanks to Miles Bader <miles@gnu.org> for handling display table via
324 ;; visws.el (his code was modified, but the main idea was kept).
326 ;; Thanks to:
327 ;; Rajesh Vaidheeswarran <rv@gnu.org> (original) whitespace.el
328 ;; Aurelien Tisne <aurelien.tisne@free.fr> show-whitespace-mode.el
329 ;; Lawrence Mitchell <wence@gmx.li> whitespace-mode.el
330 ;; Miles Bader <miles@gnu.org> visws.el
331 ;; And to all people who contributed with them.
334 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
336 ;;; code:
339 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
340 ;;;; User Variables:
343 ;;; Interface to the command system
346 (defgroup whitespace nil
347 "Visualize blanks (TAB, (HARD) SPACE and NEWLINE)."
348 :link '(emacs-library-link :tag "Source Lisp File" "whitespace.el")
349 :version "23.1"
350 :group 'wp
351 :group 'data)
354 (defcustom whitespace-style '(mark color)
355 "*Specify the visualization style.
357 It's a list containing some or all of the following values:
359 mark display mappings are visualized.
361 color faces are visualized.
363 Any other value is ignored.
365 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
367 See also `whitespace-display-mappings' for documentation."
368 :type '(repeat :tag "Style of Blank"
369 (choice :tag "Style of Blank"
370 (const :tag "Display Table" mark)
371 (const :tag "Faces" color)))
372 :group 'whitespace)
375 (defcustom whitespace-chars
376 '(tabs spaces trailing lines space-before-tab newline
377 indentation empty space-after-tab)
378 "*Specify which kind of blank is visualized.
380 It's a list containing some or all of the following values:
382 trailing trailing blanks are visualized.
384 tabs TABs are visualized.
386 spaces SPACEs and HARD SPACEs are visualized.
388 lines lines whose have columns beyond
389 `whitespace-line-column' are highlighted.
390 Whole line is highlighted.
391 It has precedence over
392 `lines-tail' (see below).
394 lines-tail lines whose have columns beyond
395 `whitespace-line-column' are highlighted.
396 But only the part of line which goes
397 beyond `whitespace-line-column' column.
398 It has effect only if `lines' (see above)
399 is not present in `whitespace-chars'.
401 space-before-tab SPACEs before TAB are visualized.
403 newline NEWLINEs are visualized.
405 indentation 8 or more SPACEs at beginning of line are
406 visualized.
408 empty empty lines at beginning and/or end of buffer
409 are visualized.
411 space-after-tab 8 or more SPACEs after a TAB are visualized.
413 Any other value is ignored.
415 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
417 Used when `whitespace-style' includes the value `color'.
418 Used also when `whitespace-chars' includes `newline',
419 and `whitespace-style' includes `mark'."
420 :type '(repeat :tag "Kind of Blank"
421 (choice :tag "Kind of Blank"
422 (const :tag "Trailing TABs, SPACEs and HARD SPACEs"
423 trailing)
424 (const :tag "SPACEs and HARD SPACEs" spaces)
425 (const :tag "TABs" tabs)
426 (const :tag "Lines" lines)
427 (const :tag "SPACEs before TAB"
428 space-before-tab)
429 (const :tag "NEWLINEs" newline)
430 (const :tag "Indentation SPACEs" indentation)
431 (const :tag "Empty Lines At BOB And/Or EOB"
432 empty)
433 (const :tag "SPACEs after TAB"
434 space-after-tab)))
435 :group 'whitespace)
438 (defcustom whitespace-space 'whitespace-space
439 "*Symbol face used to visualize SPACE.
441 Used when `whitespace-style' includes the value `color'."
442 :type 'face
443 :group 'whitespace)
446 (defface whitespace-space
447 '((((class color) (background dark))
448 (:background "grey20" :foreground "aquamarine3"))
449 (((class color) (background light))
450 (:background "LightYellow" :foreground "aquamarine3"))
451 (t (:inverse-video t)))
452 "Face used to visualize SPACE."
453 :group 'whitespace)
456 (defcustom whitespace-hspace 'whitespace-hspace
457 "*Symbol face used to visualize HARD SPACE.
459 Used when `whitespace-style' includes the value `color'."
460 :type 'face
461 :group 'whitespace)
464 (defface whitespace-hspace ; 'nobreak-space
465 '((((class color) (background dark))
466 (:background "grey24" :foreground "aquamarine3"))
467 (((class color) (background light))
468 (:background "LemonChiffon3" :foreground "aquamarine3"))
469 (t (:inverse-video t)))
470 "Face used to visualize HARD SPACE."
471 :group 'whitespace)
474 (defcustom whitespace-tab 'whitespace-tab
475 "*Symbol face used to visualize TAB.
477 Used when `whitespace-style' includes the value `color'."
478 :type 'face
479 :group 'whitespace)
482 (defface whitespace-tab
483 '((((class color) (background dark))
484 (:background "grey22" :foreground "aquamarine3"))
485 (((class color) (background light))
486 (:background "beige" :foreground "aquamarine3"))
487 (t (:inverse-video t)))
488 "Face used to visualize TAB."
489 :group 'whitespace)
492 (defcustom whitespace-newline 'whitespace-newline
493 "*Symbol face used to visualize NEWLINE char mapping.
495 See `whitespace-display-mappings'.
497 Used when `whitespace-style' includes the values `mark'
498 and `color', and `whitespace-chars' includes `newline'."
499 :type 'face
500 :group 'whitespace)
503 (defface whitespace-newline
504 '((((class color) (background dark))
505 (:background "grey26" :foreground "aquamarine3" :bold t))
506 (((class color) (background light))
507 (:background "linen" :foreground "aquamarine3" :bold t))
508 (t (:bold t :underline t)))
509 "Face used to visualize NEWLINE char mapping.
511 See `whitespace-display-mappings'."
512 :group 'whitespace)
515 (defcustom whitespace-trailing 'whitespace-trailing
516 "*Symbol face used to visualize traling blanks.
518 Used when `whitespace-style' includes the value `color'."
519 :type 'face
520 :group 'whitespace)
523 (defface whitespace-trailing ; 'trailing-whitespace
524 '((((class mono)) (:inverse-video t :bold t :underline t))
525 (t (:background "red1" :foreground "yellow" :bold t)))
526 "Face used to visualize trailing blanks."
527 :group 'whitespace)
530 (defcustom whitespace-line 'whitespace-line
531 "*Symbol face used to visualize \"long\" lines.
533 See `whitespace-line-column'.
535 Used when `whitespace-style' includes the value `color'."
536 :type 'face
537 :group 'whitespace)
540 (defface whitespace-line
541 '((((class mono)) (:inverse-video t :bold t :underline t))
542 (t (:background "gray20" :foreground "violet")))
543 "Face used to visualize \"long\" lines.
545 See `whitespace-line-column'."
546 :group 'whitespace)
549 (defcustom whitespace-space-before-tab 'whitespace-space-before-tab
550 "*Symbol face used to visualize SPACEs before TAB.
552 Used when `whitespace-style' includes the value `color'."
553 :type 'face
554 :group 'whitespace)
557 (defface whitespace-space-before-tab
558 '((((class mono)) (:inverse-video t :bold t :underline t))
559 (t (:background "DarkOrange" :foreground "firebrick")))
560 "Face used to visualize SPACEs before TAB."
561 :group 'whitespace)
564 (defcustom whitespace-indentation 'whitespace-indentation
565 "*Symbol face used to visualize 8 or more SPACEs at beginning of line.
567 Used when `whitespace-style' includes the value `color'."
568 :type 'face
569 :group 'whitespace)
572 (defface whitespace-indentation
573 '((((class mono)) (:inverse-video t :bold t :underline t))
574 (t (:background "yellow" :foreground "firebrick")))
575 "Face used to visualize 8 or more SPACEs at beginning of line."
576 :group 'whitespace)
579 (defcustom whitespace-empty 'whitespace-empty
580 "*Symbol face used to visualize empty lines at beginning and/or end of buffer.
582 Used when `whitespace-style' includes the value `color'."
583 :type 'face
584 :group 'whitespace)
587 (defface whitespace-empty
588 '((((class mono)) (:inverse-video t :bold t :underline t))
589 (t (:background "yellow" :foreground "firebrick")))
590 "Face used to visualize empty lines at beginning and/or end of buffer."
591 :group 'whitespace)
594 (defcustom whitespace-space-after-tab 'whitespace-space-after-tab
595 "*Symbol face used to visualize 8 or more SPACEs after TAB.
597 Used when `whitespace-style' includes the value `color'."
598 :type 'face
599 :group 'whitespace)
602 (defface whitespace-space-after-tab
603 '((((class mono)) (:inverse-video t :bold t :underline t))
604 (t (:background "yellow" :foreground "firebrick")))
605 "Face used to visualize 8 or more SPACEs after TAB."
606 :group 'whitespace)
609 (defcustom whitespace-hspace-regexp
610 "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
611 "*Specify HARD SPACE characters regexp.
613 If you're using `mule' package, there may be other characters besides:
615 \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
617 that should be considered HARD SPACE.
619 Here are some examples:
621 \"\\\\(^\\xA0+\\\\)\" \
622 visualize only leading HARD SPACEs.
623 \"\\\\(\\xA0+$\\\\)\" \
624 visualize only trailing HARD SPACEs.
625 \"\\\\(^\\xA0+\\\\|\\xA0+$\\\\)\" \
626 visualize leading and/or trailing HARD SPACEs.
627 \"\\t\\\\(\\xA0+\\\\)\\t\" \
628 visualize only HARD SPACEs between TABs.
630 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
631 Use exactly one pair of enclosing \\\\( and \\\\).
633 Used when `whitespace-style' includes the value `color',
634 and `whitespace-chars' includes `spaces'."
635 :type '(regexp :tag "HARD SPACE Chars")
636 :group 'whitespace)
639 (defcustom whitespace-space-regexp "\\( +\\)"
640 "*Specify SPACE characters regexp.
642 If you're using `mule' package, there may be other characters
643 besides \" \" that should be considered SPACE.
645 Here are some examples:
647 \"\\\\(^ +\\\\)\" visualize only leading SPACEs.
648 \"\\\\( +$\\\\)\" visualize only trailing SPACEs.
649 \"\\\\(^ +\\\\| +$\\\\)\" \
650 visualize leading and/or trailing SPACEs.
651 \"\\t\\\\( +\\\\)\\t\" visualize only SPACEs between TABs.
653 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
654 Use exactly one pair of enclosing \\\\( and \\\\).
656 Used when `whitespace-style' includes the value `color',
657 and `whitespace-chars' includes `spaces'."
658 :type '(regexp :tag "SPACE Chars")
659 :group 'whitespace)
662 (defcustom whitespace-tab-regexp "\\(\t+\\)"
663 "*Specify TAB characters regexp.
665 If you're using `mule' package, there may be other characters
666 besides \"\\t\" that should be considered TAB.
668 Here are some examples:
670 \"\\\\(^\\t+\\\\)\" visualize only leading TABs.
671 \"\\\\(\\t+$\\\\)\" visualize only trailing TABs.
672 \"\\\\(^\\t+\\\\|\\t+$\\\\)\" \
673 visualize leading and/or trailing TABs.
674 \" \\\\(\\t+\\\\) \" visualize only TABs between SPACEs.
676 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
677 Use exactly one pair of enclosing \\\\( and \\\\).
679 Used when `whitespace-style' includes the value `color',
680 and `whitespace-chars' includes `tabs'."
681 :type '(regexp :tag "TAB Chars")
682 :group 'whitespace)
685 (defcustom whitespace-trailing-regexp
686 "\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20"
687 "*Specify trailing characters regexp.
689 If you're using `mule' package, there may be other characters besides:
691 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
692 \"\\xF20\"
694 that should be considered blank.
696 NOTE: DO NOT enclose by \\\\( and \\\\) the elements to highlight.
697 `whitespace-mode' surrounds this regexp by \"\\\\(\\\\(\" and
698 \"\\\\)+\\\\)$\".
700 Used when `whitespace-style' includes the value `color',
701 and `whitespace-chars' includes `trailing'."
702 :type '(regexp :tag "Trailing Chars")
703 :group 'whitespace)
706 (defcustom whitespace-space-before-tab-regexp "\\( +\\)\t"
707 "*Specify SPACEs before TAB regexp.
709 If you're using `mule' package, there may be other characters besides:
711 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
712 \"\\xF20\"
714 that should be considered blank.
716 Used when `whitespace-style' includes the value `color',
717 and `whitespace-chars' includes `space-before-tab'."
718 :type '(regexp :tag "SPACEs Before TAB")
719 :group 'whitespace)
722 (defcustom whitespace-indentation-regexp
723 "^\t*\\(\\( \\{8\\}\\)+\\)[^\n\t]"
724 "*Specify regexp for 8 or more SPACEs at beginning of line.
726 If you're using `mule' package, there may be other characters besides:
728 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
729 \"\\xF20\"
731 that should be considered blank.
733 Used when `whitespace-style' includes the value `color',
734 and `whitespace-chars' includes `indentation'."
735 :type '(regexp :tag "Indentation SPACEs")
736 :group 'whitespace)
739 (defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
740 "*Specify regexp for empty lines at beginning of buffer.
742 If you're using `mule' package, there may be other characters besides:
744 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
745 \"\\xF20\"
747 that should be considered blank.
749 Used when `whitespace-style' includes the value `color',
750 and `whitespace-chars' includes `empty'."
751 :type '(regexp :tag "Empty Lines At Beginning Of Buffer")
752 :group 'whitespace)
755 (defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
756 "*Specify regexp for empty lines at end of buffer.
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 Used when `whitespace-style' includes the value `color',
766 and `whitespace-chars' includes `empty'."
767 :type '(regexp :tag "Empty Lines At End Of Buffer")
768 :group 'whitespace)
771 (defcustom whitespace-space-after-tab-regexp "\t\\(\\( \\{8\\}\\)+\\)"
772 "*Specify regexp for 8 or more SPACEs after TAB.
774 If you're using `mule' package, there may be other characters besides:
776 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
777 \"\\xF20\"
779 that should be considered blank.
781 Used when `whitespace-style' includes the value `color',
782 and `whitespace-chars' includes `space-after-tab'."
783 :type '(regexp :tag "SPACEs After TAB")
784 :group 'whitespace)
787 (defcustom whitespace-line-column 80
788 "*Specify column beyond which the line is highlighted.
790 Used when `whitespace-style' includes the value `color',
791 and `whitespace-chars' includes `lines' or `lines-tail'."
792 :type '(integer :tag "Line Length")
793 :group 'whitespace)
796 ;; Hacked from `visible-whitespace-mappings' in visws.el
797 (defcustom whitespace-display-mappings
799 (?\ [?\xB7] [?.]) ; space - centered dot
800 (?\xA0 [?\xA4] [?_]) ; hard space - currency
801 (?\x8A0 [?\x8A4] [?_]) ; hard space - currency
802 (?\x920 [?\x924] [?_]) ; hard space - currency
803 (?\xE20 [?\xE24] [?_]) ; hard space - currency
804 (?\xF20 [?\xF24] [?_]) ; hard space - currency
805 ;; NEWLINE is displayed using the face `whitespace-newline'
806 (?\n [?\u21B5 ?\n] [?$ ?\n]) ; end-of-line - downwards arrow
807 ;; (?\n [?$ ?\n]) ; end-of-line - dollar sign
808 ;; (?\n [?\xB6 ?\n] [?$ ?\n]) ; end-of-line - pilcrow
809 ;; (?\n [?\x8AF ?\n] [?$ ?\n]) ; end-of-line - overscore
810 ;; (?\n [?\x8AC ?\n] [?$ ?\n]) ; end-of-line - negation
811 ;; (?\n [?\x8B0 ?\n] [?$ ?\n]) ; end-of-line - grade
813 ;; WARNING: the mapping below has a problem.
814 ;; When a TAB occupies exactly one column, it will display the
815 ;; character ?\xBB at that column followed by a TAB which goes to
816 ;; the next TAB column.
817 ;; If this is a problem for you, please, comment the line below.
818 (?\t [?\xBB ?\t] [?\\ ?\t]) ; tab - left quote mark
820 "*Specify an alist of mappings for displaying characters.
822 Each element has the following form:
824 (CHAR VECTOR...)
826 Where:
828 CHAR is the character to be mapped.
830 VECTOR is a vector of characters to be displayed in place of CHAR.
831 The first display vector that can be displayed is used;
832 if no display vector for a mapping can be displayed, then
833 that character is displayed unmodified.
835 The NEWLINE character is displayed using the face given by
836 `whitespace-newline' variable. The characters in the vector to
837 be displayed will not have this face applied if the character
838 code is above #x1FFFF.
840 Used when `whitespace-style' includes the value `mark'."
841 :type '(repeat
842 (list :tag "Character Mapping"
843 (character :tag "Char")
844 (repeat :inline t :tag "Vector List"
845 (vector :tag ""
846 (repeat :inline t
847 :tag "Vector Characters"
848 (character :tag "Char"))))))
849 :group 'whitespace)
852 (defcustom whitespace-global-modes t
853 "*Modes for which global `whitespace-mode' is automagically turned on.
855 Global `whitespace-mode' is controlled by the command
856 `global-whitespace-mode'.
858 If nil, means no modes have `whitespace-mode' automatically
859 turned on.
861 If t, all modes that support `whitespace-mode' have it
862 automatically turned on.
864 Else it should be a list of `major-mode' symbol names for which
865 `whitespace-mode' should be automatically turned on. The sense
866 of the list is negated if it begins with `not'. For example:
868 (c-mode c++-mode)
870 means that `whitespace-mode' is turned on for buffers in C and
871 C++ modes only."
872 :type '(choice :tag "Global Modes"
873 (const :tag "None" nil)
874 (const :tag "All" t)
875 (set :menu-tag "Mode Specific" :tag "Modes"
876 :value (not)
877 (const :tag "Except" not)
878 (repeat :inline t
879 (symbol :tag "Mode"))))
880 :group 'whitespace)
883 (defcustom whitespace-action nil
884 "*Specify which action is taken when a buffer is visited, killed or written.
886 It's a list containing some or all of the following values:
888 nil no action is taken.
890 cleanup cleanup any bogus whitespace always when local
891 whitespace is turned on.
892 See `whitespace-cleanup' and
893 `whitespace-cleanup-region'.
895 report-on-bogus report if there is any bogus whitespace always
896 when local whitespace is turned on.
898 auto-cleanup cleanup any bogus whitespace when buffer is
899 written or killed.
900 See `whitespace-cleanup' and
901 `whitespace-cleanup-region'.
903 abort-on-bogus abort if there is any bogus whitespace and the
904 buffer is written or killed.
906 Any other value is treated as nil."
907 :type '(choice :tag "Actions"
908 (const :tag "None" nil)
909 (repeat :tag "Action List"
910 (choice :tag "Action"
911 (const :tag "Cleanup When On" cleanup)
912 (const :tag "Report On Bogus" report-on-bogus)
913 (const :tag "Auto Cleanup" auto-cleanup)
914 (const :tag "Abort On Bogus" abort-on-bogus))))
915 :group 'whitespace)
918 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
919 ;;;; User commands - Local mode
922 ;;;###autoload
923 (define-minor-mode whitespace-mode
924 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
926 If ARG is null, toggle whitespace visualization.
927 If ARG is a number greater than zero, turn on visualization;
928 otherwise, turn off visualization.
929 Only useful with a windowing system."
930 :lighter " ws"
931 :init-value nil
932 :global nil
933 :group 'whitespace
934 (cond
935 (noninteractive ; running a batch job
936 (setq whitespace-mode nil))
937 (whitespace-mode ; whitespace-mode on
938 (whitespace-turn-on)
939 (whitespace-action-when-on))
940 (t ; whitespace-mode off
941 (whitespace-turn-off))))
944 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
945 ;;;; User commands - Global mode
948 (define-minor-mode global-whitespace-mode
949 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
951 If ARG is null, toggle whitespace visualization.
952 If ARG is a number greater than zero, turn on visualization;
953 otherwise, turn off visualization.
954 Only useful with a windowing system."
955 :lighter " WS"
956 :init-value nil
957 :global t
958 :group 'whitespace
959 (cond
960 (noninteractive ; running a batch job
961 (setq global-whitespace-mode nil))
962 (global-whitespace-mode ; global-whitespace-mode on
963 (save-excursion
964 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
965 (dolist (buffer (buffer-list)) ; adjust all local mode
966 (set-buffer buffer)
967 (unless whitespace-mode
968 (whitespace-turn-on-if-enabled)))))
969 (t ; global-whitespace-mode off
970 (save-excursion
971 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
972 (dolist (buffer (buffer-list)) ; adjust all local mode
973 (set-buffer buffer)
974 (unless whitespace-mode
975 (whitespace-turn-off)))))))
978 (defun whitespace-turn-on-if-enabled ()
979 (when (cond
980 ((eq whitespace-global-modes t))
981 ((listp whitespace-global-modes)
982 (if (eq (car-safe whitespace-global-modes) 'not)
983 (not (memq major-mode (cdr whitespace-global-modes)))
984 (memq major-mode whitespace-global-modes)))
985 (t nil))
986 (let (inhibit-quit)
987 ;; Don't turn on whitespace mode if...
989 ;; ...we don't have a display (we're running a batch job)
990 noninteractive
991 ;; ...or if the buffer is invisible (name starts with a space)
992 (eq (aref (buffer-name) 0) ?\ )
993 ;; ...or if the buffer is temporary (name starts with *)
994 (and (eq (aref (buffer-name) 0) ?*)
995 ;; except the scratch buffer.
996 (not (string= (buffer-name) "*scratch*")))
997 ;; Otherwise, turn on whitespace mode.
998 (whitespace-turn-on)))))
1001 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1002 ;;;; User commands - Toggle
1005 (defconst whitespace-chars-value-list
1006 '(tabs
1007 spaces
1008 trailing
1009 space-before-tab
1010 lines
1011 lines-tail
1012 newline
1013 indentation
1014 empty
1015 space-after-tab
1017 "List of valid `whitespace-chars' values.")
1020 (defconst whitespace-style-value-list
1021 '(color
1022 mark
1024 "List of valid `whitespace-style' values.")
1027 (defconst whitespace-toggle-option-alist
1028 '((?t . tabs)
1029 (?s . spaces)
1030 (?r . trailing)
1031 (?b . space-before-tab)
1032 (?l . lines)
1033 (?L . lines-tail)
1034 (?n . newline)
1035 (?i . indentation)
1036 (?e . empty)
1037 (?a . space-after-tab)
1038 (?c . color)
1039 (?m . mark)
1040 (?x . whitespace-chars)
1041 (?z . whitespace-style)
1043 "Alist of toggle options.
1045 Each element has the form:
1047 (CHAR . SYMBOL)
1049 Where:
1051 CHAR is a char which the user will have to type.
1053 SYMBOL is a valid symbol associated with CHAR.
1054 See `whitespace-chars-value-list' and
1055 `whitespace-style-value-list'.")
1058 (defvar whitespace-active-chars nil
1059 "Used to save locally `whitespace-chars' value.")
1060 (make-variable-buffer-local 'whitespace-active-chars)
1062 (defvar whitespace-active-style nil
1063 "Used to save locally `whitespace-style' value.")
1064 (make-variable-buffer-local 'whitespace-active-style)
1067 ;;;###autoload
1068 (defun whitespace-toggle-options (arg)
1069 "Toggle local `whitespace-mode' options.
1071 If local whitespace-mode is off, toggle the option given by ARG
1072 and turn on local whitespace-mode.
1074 If local whitespace-mode is on, toggle the option given by ARG
1075 and restart local whitespace-mode.
1077 Interactively, it reads one of the following chars:
1079 CHAR MEANING
1080 t toggle TAB visualization
1081 s toggle SPACE and HARD SPACE visualization
1082 r toggle trailing blanks visualization
1083 b toggle SPACEs before TAB visualization
1084 l toggle \"long lines\" visualization
1085 L toggle \"long lines\" tail visualization
1086 n toggle NEWLINE visualization
1087 i toggle indentation SPACEs visualization
1088 e toggle empty line at bob and/or eob visualization
1089 a toggle SPACEs after TAB visualization
1090 c toggle color faces
1091 m toggle visual mark
1092 x restore `whitespace-chars' value
1093 z restore `whitespace-style' value
1094 ? display brief help
1096 Non-interactively, ARG should be a symbol or a list of symbols.
1097 The valid symbols are:
1099 tabs toggle TAB visualization
1100 spaces toggle SPACE and HARD SPACE visualization
1101 trailing toggle trailing blanks visualization
1102 space-before-tab toggle SPACEs before TAB visualization
1103 lines toggle \"long lines\" visualization
1104 lines-tail toggle \"long lines\" tail visualization
1105 newline toggle NEWLINE visualization
1106 indentation toggle indentation SPACEs visualization
1107 empty toggle empty line at bob and/or eob visualization
1108 space-after-tab toggle SPACEs after TAB visualization
1109 color toggle color faces
1110 mark toggle visual mark
1111 whitespace-chars restore `whitespace-chars' value
1112 whitespace-style restore `whitespace-style' value
1114 Only useful with a windowing system."
1115 (interactive (whitespace-interactive-char t))
1116 (let ((whitespace-chars
1117 (whitespace-toggle-list
1118 t arg whitespace-active-chars whitespace-chars
1119 'whitespace-chars whitespace-chars-value-list))
1120 (whitespace-style
1121 (whitespace-toggle-list
1122 t arg whitespace-active-style whitespace-style
1123 'whitespace-style whitespace-style-value-list)))
1124 (whitespace-mode 0)
1125 (whitespace-mode 1)))
1128 (defvar whitespace-toggle-chars nil
1129 "Used to toggle the global `whitespace-chars' value.")
1130 (defvar whitespace-toggle-style nil
1131 "Used to toggle the global `whitespace-style' value.")
1134 ;;;###autoload
1135 (defun global-whitespace-toggle-options (arg)
1136 "Toggle global `whitespace-mode' options.
1138 If global whitespace-mode is off, toggle the option given by ARG
1139 and turn on global whitespace-mode.
1141 If global whitespace-mode is on, toggle the option given by ARG
1142 and restart global whitespace-mode.
1144 Interactively, it accepts one of the following chars:
1146 CHAR MEANING
1147 t toggle TAB visualization
1148 s toggle SPACE and HARD SPACE visualization
1149 r toggle trailing blanks visualization
1150 b toggle SPACEs before TAB visualization
1151 l toggle \"long lines\" visualization
1152 L toggle \"long lines\" tail visualization
1153 n toggle NEWLINE visualization
1154 i toggle indentation SPACEs visualization
1155 e toggle empty line at bob and/or eob visualization
1156 a toggle SPACEs after TAB visualization
1157 c toggle color faces
1158 m toggle visual mark
1159 x restore `whitespace-chars' value
1160 z restore `whitespace-style' value
1161 ? display brief help
1163 Non-interactively, ARG should be a symbol or a list of symbols.
1164 The valid symbols are:
1166 tabs toggle TAB visualization
1167 spaces toggle SPACE and HARD SPACE visualization
1168 trailing toggle trailing blanks visualization
1169 space-before-tab toggle SPACEs before TAB visualization
1170 lines toggle \"long lines\" visualization
1171 lines-tail toggle \"long lines\" tail visualization
1172 newline toggle NEWLINE visualization
1173 indentation toggle indentation SPACEs visualization
1174 empty toggle empty line at bob and/or eob visualization
1175 space-after-tab toggle SPACEs after TAB visualization
1176 color toggle color faces
1177 mark toggle visual mark
1178 whitespace-chars restore `whitespace-chars' value
1179 whitespace-style restore `whitespace-style' value
1181 Only useful with a windowing system."
1182 (interactive (whitespace-interactive-char nil))
1183 (let ((whitespace-chars
1184 (whitespace-toggle-list
1185 nil arg whitespace-toggle-chars whitespace-chars
1186 'whitespace-chars whitespace-chars-value-list))
1187 (whitespace-style
1188 (whitespace-toggle-list
1189 nil arg whitespace-toggle-style whitespace-style
1190 'whitespace-style whitespace-style-value-list)))
1191 (setq whitespace-toggle-chars whitespace-chars
1192 whitespace-toggle-style whitespace-style)
1193 (global-whitespace-mode 0)
1194 (global-whitespace-mode 1)))
1197 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1198 ;;;; User commands - Cleanup
1201 ;;;###autoload
1202 (defun whitespace-cleanup ()
1203 "Cleanup some blank problems in all buffer or at region.
1205 It usually applies to the whole buffer, but in transient mark
1206 mode when the mark is active, it applies to the region. It also
1207 applies to the region when it is not in transiente mark mode, the
1208 mark is active and \\[universal-argument] was pressed just before calling
1209 `whitespace-cleanup' interactively.
1211 See also `whitespace-cleanup-region'.
1213 The problems cleaned up are:
1215 1. empty lines at beginning of buffer.
1216 2. empty lines at end of buffer.
1217 If `whitespace-chars' includes the value `empty', remove all
1218 empty lines at beginning and/or end of buffer.
1220 3. 8 or more SPACEs at beginning of line.
1221 If `whitespace-chars' includes the value `indentation', replace
1222 8 or more SPACEs at beginning of line by TABs.
1224 4. SPACEs before TAB.
1225 If `whitespace-chars' includes the value `space-before-tab',
1226 replace SPACEs by TABs.
1228 5. SPACEs or TABs at end of line.
1229 If `whitespace-chars' includes the value `trailing', remove all
1230 SPACEs or TABs at end of line.
1232 6. 8 or more SPACEs after TAB.
1233 If `whitespace-chars' includes the value `space-after-tab',
1234 replace SPACEs by TABs."
1235 (interactive "@*")
1236 (if (and (or transient-mark-mode
1237 current-prefix-arg)
1238 mark-active)
1239 ;; region active
1240 ;; problems 1 and 2 are not handled in region
1241 ;; problem 3: 8 or more SPACEs at bol
1242 ;; problem 4: SPACEs before TAB
1243 ;; problem 5: SPACEs or TABs at eol
1244 ;; problem 6: 8 or more SPACEs after TAB
1245 (whitespace-cleanup-region (region-beginning) (region-end))
1246 ;; whole buffer
1247 (save-excursion
1248 (save-match-data
1249 ;; problem 1: empty lines at bob
1250 ;; problem 2: empty lines at eob
1251 ;; action: remove all empty lines at bob and/or eob
1252 (when (memq 'empty whitespace-chars)
1253 (let (overwrite-mode) ; enforce no overwrite
1254 (goto-char (point-min))
1255 (when (re-search-forward
1256 whitespace-empty-at-bob-regexp nil t)
1257 (delete-region (match-beginning 1) (match-end 1)))
1258 (when (re-search-forward
1259 whitespace-empty-at-eob-regexp nil t)
1260 (delete-region (match-beginning 1) (match-end 1)))))))
1261 ;; problem 3: 8 or more SPACEs at bol
1262 ;; problem 4: SPACEs before TAB
1263 ;; problem 5: SPACEs or TABs at eol
1264 ;; problem 6: 8 or more SPACEs after TAB
1265 (whitespace-cleanup-region (point-min) (point-max))))
1268 ;;;###autoload
1269 (defun whitespace-cleanup-region (start end)
1270 "Cleanup some blank problems at region.
1272 The problems cleaned up are:
1274 1. 8 or more SPACEs at beginning of line.
1275 If `whitespace-chars' includes the value `indentation', replace
1276 8 or more SPACEs at beginning of line by TABs.
1278 2. SPACEs before TAB.
1279 If `whitespace-chars' includes the value `space-before-tab',
1280 replace SPACEs by TABs.
1282 3. SPACEs or TABs at end of line.
1283 If `whitespace-chars' includes the value `trailing', remove all
1284 SPACEs or TABs at end of line.
1286 4. 8 or more SPACEs after TAB.
1287 If `whitespace-chars' includes the value `space-after-tab',
1288 replace SPACEs by TABs."
1289 (interactive "@*r")
1290 (let ((rstart (min start end))
1291 (rend (copy-marker (max start end)))
1292 (tab-width 8) ; assure TAB width
1293 (indent-tabs-mode t) ; always insert TABs
1294 overwrite-mode ; enforce no overwrite
1295 tmp)
1296 (save-excursion
1297 (save-match-data
1298 ;; problem 1: 8 or more SPACEs at bol
1299 ;; action: replace 8 or more SPACEs at bol by TABs
1300 (when (memq 'indentation whitespace-chars)
1301 (goto-char rstart)
1302 (while (re-search-forward
1303 whitespace-indentation-regexp rend t)
1304 (setq tmp (current-indentation))
1305 (goto-char (match-beginning 0))
1306 (delete-horizontal-space)
1307 (unless (eolp)
1308 (indent-to tmp))))
1309 ;; problem 3: SPACEs or TABs at eol
1310 ;; action: remove all SPACEs or TABs at eol
1311 (when (memq 'trailing whitespace-chars)
1312 (let ((regexp (whitespace-trailing-regexp)))
1313 (goto-char rstart)
1314 (while (re-search-forward regexp rend t)
1315 (delete-region (match-beginning 1) (match-end 1)))))
1316 ;; problem 4: 8 or more SPACEs after TAB
1317 ;; action: replace 8 or more SPACEs by TABs
1318 (when (memq 'space-after-tab whitespace-chars)
1319 (whitespace-replace-spaces-by-tabs
1320 rstart rend whitespace-space-after-tab-regexp))
1321 ;; problem 2: SPACEs before TAB
1322 ;; action: replace SPACEs before TAB by TABs
1323 (when (memq 'space-before-tab whitespace-chars)
1324 (whitespace-replace-spaces-by-tabs
1325 rstart rend whitespace-space-before-tab-regexp))))
1326 (set-marker rend nil))) ; point marker to nowhere
1329 (defun whitespace-replace-spaces-by-tabs (rstart rend regexp)
1330 "Replace all SPACEs by TABs matched by REGEXP between RSTART and REND."
1331 (goto-char rstart)
1332 (while (re-search-forward regexp rend t)
1333 (goto-char (match-beginning 1))
1334 (let* ((scol (current-column))
1335 (ecol (save-excursion
1336 (goto-char (match-end 1))
1337 (current-column))))
1338 (delete-region (match-beginning 1) (match-end 1))
1339 (insert-char ?\t
1340 (/ (- (- ecol (% ecol 8)) ; prev end col
1341 (- scol (% scol 8))) ; prev start col
1342 8)))))
1345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1346 ;;;; User command - report
1349 (defun whitespace-trailing-regexp ()
1350 "Make the `whitespace-trailing-regexp' regexp."
1351 (concat "\\(\\(" whitespace-trailing-regexp "\\)+\\)$"))
1354 (defconst whitespace-report-list
1355 (list
1356 (cons 'empty whitespace-empty-at-bob-regexp)
1357 (cons 'empty whitespace-empty-at-eob-regexp)
1358 (cons 'indentation whitespace-indentation-regexp)
1359 (cons 'space-before-tab whitespace-space-before-tab-regexp)
1360 (cons 'trailing (whitespace-trailing-regexp))
1361 (cons 'space-after-tab whitespace-space-after-tab-regexp)
1363 "List of whitespace bogus symbol and corresponding regexp.")
1366 (defconst whitespace-report-text
1368 Whitespace Report
1370 Current Setting Whitespace Problem
1372 empty [] [] empty lines at beginning of buffer.
1373 empty [] [] empty lines at end of buffer.
1374 indentation [] [] 8 or more SPACEs at beginning of line.
1375 space-before-tab [] [] SPACEs before TAB.
1376 trailing [] [] SPACEs or TABs at end of line.
1377 space-after-tab [] [] 8 or more SPACEs after TAB.\n\n"
1378 "Text for whitespace bogus report.")
1381 (defconst whitespace-report-buffer-name "*Whitespace Report*"
1382 "The buffer name for whitespace bogus report.")
1385 ;;;###autoload
1386 (defun whitespace-report (&optional force report-if-bogus)
1387 "Report some whitespace problems in buffer.
1389 Return nil if there is no whitespace problem; otherwise, return
1390 non-nil.
1392 If FORCE is non-nil or \\[universal-argument] was pressed just before calling
1393 `whitespace-report' interactively, it forces `whitespace-chars' to
1394 have:
1396 empty
1397 indentation
1398 space-before-tab
1399 trailing
1400 space-after-tab
1402 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1403 whitespace problems in buffer.
1405 Report if some of the following whitespace problems exist:
1407 empty 1. empty lines at beginning of buffer.
1408 empty 2. empty lines at end of buffer.
1409 indentation 3. 8 or more SPACEs at beginning of line.
1410 space-before-tab 4. SPACEs before TAB.
1411 trailing 5. SPACEs or TABs at end of line.
1412 space-after-tab 6. 8 or more SPACEs after TAB.
1414 See `whitespace-chars' and `whitespace-style' for documentation.
1415 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1416 cleaning up these problems."
1417 (interactive (list current-prefix-arg))
1418 (whitespace-report-region (point-min) (point-max)
1419 force report-if-bogus))
1422 ;;;###autoload
1423 (defun whitespace-report-region (start end &optional force report-if-bogus)
1424 "Report some whitespace problems in a region.
1426 Return nil if there is no whitespace problem; otherwise, return
1427 non-nil.
1429 If FORCE is non-nil or \\[universal-argument] was pressed just before calling
1430 `whitespace-report-region' interactively, it forces `whitespace-chars'
1431 to have:
1433 empty
1434 indentation
1435 space-before-tab
1436 trailing
1437 space-after-tab
1439 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1440 whitespace problems in buffer.
1442 Report if some of the following whitespace problems exist:
1444 empty 1. empty lines at beginning of buffer.
1445 empty 2. empty lines at end of buffer.
1446 indentation 3. 8 or more SPACEs at beginning of line.
1447 space-before-tab 4. SPACEs before TAB.
1448 trailing 5. SPACEs or TABs at end of line.
1449 space-after-tab 6. 8 or more SPACEs after TAB.
1451 See `whitespace-chars' and `whitespace-style' for documentation.
1452 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1453 cleaning up these problems."
1454 (interactive "r")
1455 (setq force (or current-prefix-arg force))
1456 (save-excursion
1457 (save-match-data
1458 (let* (has-bogus
1459 (rstart (min start end))
1460 (rend (max start end))
1461 (bogus-list (mapcar
1462 #'(lambda (option)
1463 (when force
1464 (add-to-list 'whitespace-chars (car option)))
1465 (goto-char rstart)
1466 (and (re-search-forward (cdr option) rend t)
1467 (setq has-bogus t)))
1468 whitespace-report-list)))
1469 (when (if report-if-bogus has-bogus t)
1470 (with-current-buffer (get-buffer-create
1471 whitespace-report-buffer-name)
1472 (erase-buffer)
1473 (insert whitespace-report-text)
1474 (goto-char (point-min))
1475 (forward-line 3)
1476 (dolist (option whitespace-report-list)
1477 (forward-line 1)
1478 (whitespace-mark-x 22 (memq (car option) whitespace-chars))
1479 (whitespace-mark-x 7 (car bogus-list))
1480 (setq bogus-list (cdr bogus-list)))
1481 (when has-bogus
1482 (goto-char (point-max))
1483 (insert " Type `M-x whitespace-cleanup'"
1484 " to cleanup the buffer.\n\n")
1485 (insert " Type `M-x whitespace-cleanup-region'"
1486 " to cleanup a region.\n\n"))
1487 (whitespace-display-window (current-buffer))))
1488 has-bogus))))
1491 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1492 ;;;; Internal functions
1495 (defvar whitespace-font-lock-mode nil
1496 "Used to remember whether a buffer had font lock mode on or not.")
1497 (make-variable-buffer-local 'whitespace-font-lock-mode)
1499 (defvar whitespace-font-lock nil
1500 "Used to remember whether a buffer initially had font lock on or not.")
1501 (make-variable-buffer-local 'whitespace-font-lock)
1503 (defvar whitespace-font-lock-keywords nil
1504 "Used to save locally `font-lock-keywords' value.")
1505 (make-variable-buffer-local 'whitespace-font-lock-keywords)
1508 (defconst whitespace-help-text
1510 whitespace-mode toggle options:
1512 [] t - toggle TAB visualization
1513 [] s - toggle SPACE and HARD SPACE visualization
1514 [] r - toggle trailing blanks visualization
1515 [] b - toggle SPACEs before TAB visualization
1516 [] l - toggle \"long lines\" visualization
1517 [] L - toggle \"long lines\" tail visualization
1518 [] n - toggle NEWLINE visualization
1519 [] i - toggle indentation SPACEs visualization
1520 [] e - toggle empty line at bob and/or eob visualization
1521 [] a - toggle SPACEs after TAB visualization
1523 [] c - toggle color faces
1524 [] m - toggle visual mark
1526 x - restore `whitespace-chars' value
1527 z - restore `whitespace-style' value
1529 ? - display this text\n\n"
1530 "Text for whitespace toggle options.")
1533 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1534 "The buffer name for whitespace toggle options.")
1537 (defun whitespace-mark-x (nchars condition)
1538 "Insert the mark ('X' or ' ') after NCHARS depending on CONDITION."
1539 (forward-char nchars)
1540 (insert (if condition "X" " ")))
1543 (defun whitespace-insert-option-mark (the-list the-value)
1544 "Insert the option mark ('X' or ' ') in toggle options buffer."
1545 (forward-line 1)
1546 (dolist (sym the-list)
1547 (forward-line 1)
1548 (whitespace-mark-x 2 (memq sym the-value))))
1551 (defun whitespace-help-on (chars style)
1552 "Display the whitespace toggle options."
1553 (unless (get-buffer whitespace-help-buffer-name)
1554 (delete-other-windows)
1555 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
1556 (save-excursion
1557 (set-buffer buffer)
1558 (erase-buffer)
1559 (insert whitespace-help-text)
1560 (goto-char (point-min))
1561 (whitespace-insert-option-mark
1562 whitespace-chars-value-list chars)
1563 (whitespace-insert-option-mark
1564 whitespace-style-value-list style)
1565 (whitespace-display-window buffer)))))
1568 (defun whitespace-display-window (buffer)
1569 "Display BUFFER in a new window."
1570 (goto-char (point-min))
1571 (set-buffer-modified-p nil)
1572 (let ((size (- (window-height)
1573 (max window-min-height
1574 (1+ (count-lines (point-min)
1575 (point-max)))))))
1576 (when (<= size 0)
1577 (kill-buffer buffer)
1578 (error "Frame height is too small; \
1579 can't split window to display whitespace toggle options"))
1580 (set-window-buffer (split-window nil size) buffer)))
1583 (defun whitespace-help-off ()
1584 "Remove the buffer and window of the whitespace toggle options."
1585 (let ((buffer (get-buffer whitespace-help-buffer-name)))
1586 (when buffer
1587 (delete-windows-on buffer)
1588 (kill-buffer buffer))))
1591 (defun whitespace-interactive-char (local-p)
1592 "Interactive function to read a char and return a symbol.
1594 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1595 uses a global context.
1597 It accepts one of the following chars:
1599 CHAR MEANING
1600 t toggle TAB visualization
1601 s toggle SPACE and HARD SPACE visualization
1602 r toggle trailing blanks visualization
1603 b toggle SPACEs before TAB visualization
1604 l toggle \"long lines\" visualization
1605 L toggle \"long lines\" tail visualization
1606 n toggle NEWLINE visualization
1607 i toggle indentation SPACEs visualization
1608 e toggle empty line at bob and/or eob visualization
1609 a toggle SPACEs after TAB visualization
1610 c toggle color faces
1611 m toggle visual mark
1612 x restore `whitespace-chars' value
1613 z restore `whitespace-style' value
1614 ? display brief help
1616 See also `whitespace-toggle-option-alist'."
1617 (let* ((is-off (not (if local-p
1618 whitespace-mode
1619 global-whitespace-mode)))
1620 (chars (cond (is-off whitespace-chars) ; use default value
1621 (local-p whitespace-active-chars)
1622 (t whitespace-toggle-chars)))
1623 (style (cond (is-off whitespace-style) ; use default value
1624 (local-p whitespace-active-style)
1625 (t whitespace-toggle-style)))
1626 (prompt
1627 (format "Whitespace Toggle %s (type ? for further options)-"
1628 (if local-p "Local" "Global")))
1629 ch sym)
1630 ;; read a valid option and get the corresponding symbol
1631 (save-window-excursion
1632 (condition-case data
1633 (progn
1634 (while
1635 ;; while condition
1636 (progn
1637 (setq ch (read-char prompt))
1638 (not
1639 (setq sym
1640 (cdr
1641 (assq ch whitespace-toggle-option-alist)))))
1642 ;; while body
1643 (if (eq ch ?\?)
1644 (whitespace-help-on chars style)
1645 (ding)))
1646 (whitespace-help-off)
1647 (message " ")) ; clean echo area
1648 ;; handler
1649 ((quit error)
1650 (whitespace-help-off)
1651 (error (error-message-string data)))))
1652 (list sym))) ; return the apropriate symbol
1655 (defun whitespace-toggle-list (local-p arg the-list default-list
1656 sym-restore sym-list)
1657 "Toggle options in THE-LIST based on list ARG.
1659 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1660 uses a global context.
1662 ARG is a list of options to be toggled.
1664 THE-LIST is a list of options. This list will be toggled and the
1665 resultant list will be returned.
1667 DEFAULT-LIST is the default list of options. It is used to
1668 restore the options in THE-LIST.
1670 SYM-RESTORE is the symbol which indicates to restore the options
1671 in THE-LIST.
1673 SYM-LIST is a list of valid options, used to check if the ARG's
1674 options are valid."
1675 (unless (if local-p whitespace-mode global-whitespace-mode)
1676 (setq the-list default-list))
1677 (setq the-list (copy-sequence the-list)) ; keep original list
1678 (dolist (sym (if (listp arg) arg (list arg)))
1679 (cond
1680 ;; restore default values
1681 ((eq sym sym-restore)
1682 (setq the-list default-list))
1683 ;; toggle valid values
1684 ((memq sym sym-list)
1685 (setq the-list (if (memq sym the-list)
1686 (delq sym the-list)
1687 (cons sym the-list))))))
1688 the-list)
1691 (defun whitespace-turn-on ()
1692 "Turn on whitespace visualization."
1693 (whitespace-add-local-hook)
1694 (setq whitespace-active-style (if (listp whitespace-style)
1695 whitespace-style
1696 (list whitespace-style)))
1697 (setq whitespace-active-chars (if (listp whitespace-chars)
1698 whitespace-chars
1699 (list whitespace-chars)))
1700 (when (memq 'color whitespace-active-style)
1701 (whitespace-color-on))
1702 (when (memq 'mark whitespace-active-style)
1703 (whitespace-display-char-on)))
1706 (defun whitespace-turn-off ()
1707 "Turn off whitespace visualization."
1708 (whitespace-remove-local-hook)
1709 (when (memq 'color whitespace-active-style)
1710 (whitespace-color-off))
1711 (when (memq 'mark whitespace-active-style)
1712 (whitespace-display-char-off)))
1715 (defun whitespace-color-on ()
1716 "Turn on color visualization."
1717 (when whitespace-active-chars
1718 (unless whitespace-font-lock
1719 (setq whitespace-font-lock t
1720 whitespace-font-lock-keywords
1721 (copy-sequence font-lock-keywords)))
1722 ;; turn off font lock
1723 (setq whitespace-font-lock-mode font-lock-mode)
1724 (font-lock-mode 0)
1725 ;; add whitespace-mode color into font lock
1726 (when (memq 'spaces whitespace-active-chars)
1727 (font-lock-add-keywords
1729 (list
1730 ;; Show SPACEs
1731 (list whitespace-space-regexp 1 whitespace-space t)
1732 ;; Show HARD SPACEs
1733 (list whitespace-hspace-regexp 1 whitespace-hspace t))
1735 (when (memq 'tabs whitespace-active-chars)
1736 (font-lock-add-keywords
1738 (list
1739 ;; Show TABs
1740 (list whitespace-tab-regexp 1 whitespace-tab t))
1742 (when (memq 'trailing whitespace-active-chars)
1743 (font-lock-add-keywords
1745 (list
1746 ;; Show trailing blanks
1747 (list (whitespace-trailing-regexp) 1 whitespace-trailing t))
1749 (when (or (memq 'lines whitespace-active-chars)
1750 (memq 'lines-tail whitespace-active-chars))
1751 (font-lock-add-keywords
1753 (list
1754 ;; Show "long" lines
1755 (list
1756 (format
1757 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
1758 tab-width (1- tab-width)
1759 (/ whitespace-line-column tab-width)
1760 (let ((rem (% whitespace-line-column tab-width)))
1761 (if (zerop rem)
1763 (format ".\\{%d\\}" rem))))
1764 (if (memq 'lines whitespace-active-chars)
1765 0 ; whole line
1766 2) ; line tail
1767 whitespace-line t))
1769 (when (memq 'space-before-tab whitespace-active-chars)
1770 (font-lock-add-keywords
1772 (list
1773 ;; Show SPACEs before TAB
1774 (list whitespace-space-before-tab-regexp
1775 1 whitespace-space-before-tab t))
1777 (when (memq 'indentation whitespace-active-chars)
1778 (font-lock-add-keywords
1780 (list
1781 ;; Show indentation SPACEs
1782 (list whitespace-indentation-regexp
1783 1 whitespace-indentation t))
1785 (when (memq 'empty whitespace-active-chars)
1786 (font-lock-add-keywords
1788 (list
1789 ;; Show empty lines at beginning of buffer
1790 (list whitespace-empty-at-bob-regexp
1791 1 whitespace-empty t))
1793 (font-lock-add-keywords
1795 (list
1796 ;; Show empty lines at end of buffer
1797 (list whitespace-empty-at-eob-regexp
1798 1 whitespace-empty t))
1800 (when (memq 'space-after-tab whitespace-active-chars)
1801 (font-lock-add-keywords
1803 (list
1804 ;; Show SPACEs after TAB
1805 (list whitespace-space-after-tab-regexp
1806 1 whitespace-space-after-tab t))
1808 ;; now turn on font lock and highlight blanks
1809 (font-lock-mode 1)))
1812 (defun whitespace-color-off ()
1813 "Turn off color visualization."
1814 (when whitespace-active-chars
1815 ;; turn off font lock
1816 (font-lock-mode 0)
1817 (when whitespace-font-lock
1818 (setq whitespace-font-lock nil
1819 font-lock-keywords whitespace-font-lock-keywords))
1820 ;; restore original font lock state
1821 (font-lock-mode whitespace-font-lock-mode)))
1824 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1825 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
1828 (defvar whitespace-display-table nil
1829 "Used to save a local display table.")
1830 (make-variable-buffer-local 'whitespace-display-table)
1832 (defvar whitespace-display-table-was-local nil
1833 "Used to remember whether a buffer initially had a local display table.")
1834 (make-variable-buffer-local 'whitespace-display-table-was-local)
1837 (defsubst whitespace-char-valid-p (char)
1838 ;; This check should be improved!!!
1839 (or (< char 256)
1840 (characterp char)))
1843 (defun whitespace-display-vector-p (vec)
1844 "Return true if every character in vector VEC can be displayed."
1845 (let ((i (length vec)))
1846 (when (> i 0)
1847 (while (and (>= (setq i (1- i)) 0)
1848 (whitespace-char-valid-p (aref vec i))))
1849 (< i 0))))
1852 (defun whitespace-display-char-on ()
1853 "Turn on character display mapping."
1854 (when whitespace-display-mappings
1855 (let (vecs vec)
1856 ;; Remember whether a buffer has a local display table.
1857 (unless whitespace-display-table-was-local
1858 (setq whitespace-display-table-was-local t
1859 whitespace-display-table
1860 (copy-sequence buffer-display-table)))
1861 (unless buffer-display-table
1862 (setq buffer-display-table (make-display-table)))
1863 (dolist (entry whitespace-display-mappings)
1864 (setq vecs (cdr entry))
1865 ;; Get a displayable mapping.
1866 (while (and vecs
1867 (not (whitespace-display-vector-p (car vecs))))
1868 (setq vecs (cdr vecs)))
1869 ;; Display a valid mapping.
1870 (when vecs
1871 (setq vec (copy-sequence (car vecs)))
1872 (cond
1873 ;; Any char except newline
1874 ((not (eq (car entry) ?\n))
1875 (aset buffer-display-table (car entry) vec))
1876 ;; Newline char - display it
1877 ((memq 'newline whitespace-active-chars)
1878 ;; Only insert face bits on NEWLINE char mapping to avoid
1879 ;; obstruction of other faces like TABs and (HARD) SPACEs
1880 ;; faces, font-lock faces, etc.
1881 (when (memq 'color whitespace-active-style)
1882 (dotimes (i (length vec))
1883 (or (eq (aref vec i) ?\n)
1884 (aset vec i
1885 (make-glyph-code (aref vec i)
1886 whitespace-newline)))))
1887 ;; Display mapping
1888 (aset buffer-display-table (car entry) vec))
1889 ;; Newline char - don't display it
1891 ;; Do nothing
1892 )))))))
1895 (defun whitespace-display-char-off ()
1896 "Turn off character display mapping."
1897 (and whitespace-display-mappings
1898 whitespace-display-table-was-local
1899 (setq whitespace-display-table-was-local nil
1900 buffer-display-table whitespace-display-table)))
1903 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1904 ;;;; Hook
1907 (defun whitespace-action-when-on ()
1908 "Action to be taken always when local whitespace is turned on."
1909 (cond ((memq 'cleanup whitespace-action)
1910 (whitespace-cleanup))
1911 ((memq 'report-on-bogus whitespace-action)
1912 (whitespace-report nil t))))
1915 (defun whitespace-add-local-hook ()
1916 "Add some whitespace hooks locally."
1917 (add-hook 'write-file-functions 'whitespace-write-file-hook nil t)
1918 (add-hook 'kill-buffer-hook 'whitespace-kill-buffer-hook nil t))
1921 (defun whitespace-remove-local-hook ()
1922 "Remove some whitespace hooks locally."
1923 (remove-hook 'write-file-functions 'whitespace-write-file-hook t)
1924 (remove-hook 'kill-buffer-hook 'whitespace-kill-buffer-hook t))
1927 (defun whitespace-write-file-hook ()
1928 "Action to be taken when buffer is written.
1929 It should be added buffer-locally to `write-file-functions'."
1930 (when (whitespace-action)
1931 (error "Abort write due to whitespace problems in %s"
1932 (buffer-name)))
1933 nil) ; continue hook processing
1936 (defun whitespace-kill-buffer-hook ()
1937 "Action to be taken when buffer is killed.
1938 It should be added buffer-locally to `kill-buffer-hook'."
1939 (whitespace-action)
1940 nil) ; continue hook processing
1943 (defun whitespace-action ()
1944 "Action to be taken when buffer is killed or written.
1945 Return t when the action should be aborted."
1946 (cond ((memq 'auto-cleanup whitespace-action)
1947 (whitespace-cleanup)
1948 nil)
1949 ((memq 'abort-on-bogus whitespace-action)
1950 (whitespace-report nil t))
1952 nil)))
1955 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1958 (defun whitespace-unload-function ()
1959 "Unload the whitespace library."
1960 (global-whitespace-mode -1)
1961 ;; be sure all local whitespace mode is turned off
1962 (save-current-buffer
1963 (dolist (buf (buffer-list))
1964 (set-buffer buf)
1965 (whitespace-mode -1)))
1966 nil) ; continue standard unloading
1969 (provide 'whitespace)
1972 (run-hooks 'whitespace-load-hook)
1975 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
1976 ;;; whitespace.el ends here