]> code.delx.au - gnu-emacs/blob - lisp/whitespace.el
(proced-mode): Redefine as just the major-mode.
[gnu-emacs] / lisp / whitespace.el
1 ;;; whitespace.el --- minor mode to visualize TAB, (HARD) SPACE, NEWLINE
2
3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5
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
11
12 ;; This file is part of GNU Emacs.
13
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.
18
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.
23
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.
28
29 ;;; Commentary:
30
31 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32 ;;
33 ;; Introduction
34 ;; ------------
35 ;;
36 ;; This package is a minor mode to visualize blanks (TAB, (HARD) SPACE
37 ;; and NEWLINE).
38 ;;
39 ;; whitespace uses two ways to visualize blanks: faces and display
40 ;; table.
41 ;;
42 ;; * Faces are used to highlight the background with a color.
43 ;; whitespace uses font-lock to highlight blank characters.
44 ;;
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).
48 ;;
49 ;; The `whitespace-style' and `whitespace-chars' variables are used to
50 ;; select which way should be used to visualize blanks.
51 ;;
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.
60 ;;
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).
64 ;;
65 ;; There are two ways of using whitespace: local and global.
66 ;;
67 ;; * Local whitespace affects only the current buffer.
68 ;;
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.
74 ;;
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.
79 ;;
80 ;; When global and local whitespace are on:
81 ;;
82 ;; * if local whitespace is turned off, whitespace is turned off for
83 ;; the current buffer only.
84 ;;
85 ;; * if global whitespace is turned off, whitespace continues on only
86 ;; in the buffers in which local whitespace is on.
87 ;;
88 ;; To use whitespace, insert in your ~/.emacs:
89 ;;
90 ;; (require 'whitespace-mode)
91 ;;
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:
95 ;;
96 ;; (autoload 'whitespace-mode "whitespace"
97 ;; "Toggle whitespace visualization." t)
98 ;; (autoload 'whitespace-toggle-options "whitespace"
99 ;; "Toggle local `whitespace-mode' options." t)
100 ;;
101 ;; whitespace was inspired by:
102 ;;
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'.
109 ;;
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)
113 ;;
114 ;; whitespace-mode.el Lawrence Mitchell <wence@gmx.li>
115 ;; Major mode for editing Whitespace
116 ;; (inspired the idea to use display table)
117 ;;
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)
122 ;;
123 ;;
124 ;; Using whitespace
125 ;; ----------------
126 ;;
127 ;; There is no problem if you mix local and global minor mode usage.
128 ;;
129 ;; * LOCAL whitespace:
130 ;; + To toggle whitespace options locally, type:
131 ;;
132 ;; M-x whitespace-toggle-options RET
133 ;;
134 ;; + To activate whitespace locally, type:
135 ;;
136 ;; C-u 1 M-x whitespace-mode RET
137 ;;
138 ;; + To deactivate whitespace locally, type:
139 ;;
140 ;; C-u 0 M-x whitespace-mode RET
141 ;;
142 ;; + To toggle whitespace locally, type:
143 ;;
144 ;; M-x whitespace-mode RET
145 ;;
146 ;; * GLOBAL whitespace:
147 ;; + To toggle whitespace options globally, type:
148 ;;
149 ;; M-x global-whitespace-toggle-options RET
150 ;;
151 ;; + To activate whitespace globally, type:
152 ;;
153 ;; C-u 1 M-x global-whitespace-mode RET
154 ;;
155 ;; + To deactivate whitespace globally, type:
156 ;;
157 ;; C-u 0 M-x global-whitespace-mode RET
158 ;;
159 ;; + To toggle whitespace globally, type:
160 ;;
161 ;; M-x global-whitespace-mode RET
162 ;;
163 ;; There are also the following useful commands:
164 ;;
165 ;; `whitespace-report'
166 ;; Report some blank problems in buffer.
167 ;;
168 ;; `whitespace-report-region'
169 ;; Report some blank problems in a region.
170 ;;
171 ;; `whitespace-cleanup'
172 ;; Cleanup some blank problems in all buffer or at region.
173 ;;
174 ;; `whitespace-cleanup-region'
175 ;; Cleanup some blank problems at region.
176 ;;
177 ;; The problems, which are cleaned up, are:
178 ;;
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.
183 ;;
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.
187 ;;
188 ;; 4. SPACEs before TAB.
189 ;; If `whitespace-chars' includes the value `space-before-tab',
190 ;; replace SPACEs by TABs.
191 ;;
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.
195 ;;
196 ;; 6. 8 or more SPACEs after TAB.
197 ;; If `whitespace-chars' includes the value `space-after-tab',
198 ;; replace SPACEs by TABs.
199 ;;
200 ;;
201 ;; Hooks
202 ;; -----
203 ;;
204 ;; whitespace has the following hook variables:
205 ;;
206 ;; `whitespace-mode-hook'
207 ;; It is evaluated always when whitespace is turned on locally.
208 ;;
209 ;; `global-whitespace-mode-hook'
210 ;; It is evaluated always when whitespace is turned on globally.
211 ;;
212 ;; `whitespace-load-hook'
213 ;; It is evaluated after whitespace package is loaded.
214 ;;
215 ;;
216 ;; Options
217 ;; -------
218 ;;
219 ;; Below it's shown a brief description of whitespace options, please,
220 ;; see the options declaration in the code for a long documentation.
221 ;;
222 ;; `whitespace-style' Specify the visualization style.
223 ;;
224 ;; `whitespace-chars' Specify which kind of blank is
225 ;; visualized.
226 ;;
227 ;; `whitespace-space' Face used to visualize SPACE.
228 ;;
229 ;; `whitespace-hspace' Face used to visualize HARD SPACE.
230 ;;
231 ;; `whitespace-tab' Face used to visualize TAB.
232 ;;
233 ;; `whitespace-newline' Face used to visualize NEWLINE char
234 ;; mapping.
235 ;;
236 ;; `whitespace-trailing' Face used to visualize trailing
237 ;; blanks.
238 ;;
239 ;; `whitespace-line' Face used to visualize "long" lines.
240 ;;
241 ;; `whitespace-space-before-tab' Face used to visualize SPACEs
242 ;; before TAB.
243 ;;
244 ;; `whitespace-indentation' Face used to visualize 8 or more
245 ;; SPACEs at beginning of line.
246 ;;
247 ;; `whitespace-empty' Face used to visualize empty lines at
248 ;; beginning and/or end of buffer.
249 ;;
250 ;; `whitespace-space-after-tab' Face used to visualize 8 or more
251 ;; SPACEs after TAB.
252 ;;
253 ;; `whitespace-space-regexp' Specify SPACE characters regexp.
254 ;;
255 ;; `whitespace-hspace-regexp' Specify HARD SPACE characters regexp.
256 ;;
257 ;; `whitespace-tab-regexp' Specify TAB characters regexp.
258 ;;
259 ;; `whitespace-trailing-regexp' Specify trailing characters regexp.
260 ;;
261 ;; `whitespace-space-before-tab-regexp' Specify SPACEs before TAB
262 ;; regexp.
263 ;;
264 ;; `whitespace-indentation-regexp' Specify regexp for 8 or more
265 ;; SPACEs at beginning of line.
266 ;;
267 ;; `whitespace-empty-at-bob-regexp' Specify regexp for empty lines
268 ;; at beginning of buffer.
269 ;;
270 ;; `whitespace-empty-at-eob-regexp' Specify regexp for empty lines
271 ;; at end of buffer.
272 ;;
273 ;; `whitespace-space-after-tab-regexp' Specify regexp for 8 or more
274 ;; SPACEs after TAB.
275 ;;
276 ;; `whitespace-line-column' Specify column beyond which the line
277 ;; is highlighted.
278 ;;
279 ;; `whitespace-display-mappings' Specify an alist of mappings
280 ;; for displaying characters.
281 ;;
282 ;; `whitespace-global-modes' Modes for which global
283 ;; `whitespace-mode' is automagically
284 ;; turned on.
285 ;;
286 ;; `whitespace-action' Specify which action is taken when a
287 ;; buffer is visited, killed or written.
288 ;;
289 ;;
290 ;; Acknowledgements
291 ;; ----------------
292 ;;
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.
295 ;;
296 ;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
297 ;; lines tail. See EightyColumnRule (EmacsWiki).
298 ;;
299 ;; Thanks to Juri Linkov <juri@jurta.org> for suggesting:
300 ;; * `define-minor-mode'.
301 ;; * `global-whitespace-*' name for global commands.
302 ;;
303 ;; Thanks to Robert J. Chassell <bob@gnu.org> for doc fix and testing.
304 ;;
305 ;; Thanks to Drew Adams <drew.adams@oracle.com> for toggle commands
306 ;; suggestion.
307 ;;
308 ;; Thanks to Antti Kaihola <antti.kaihola@linux-aktivaattori.org> for
309 ;; helping to fix `find-file-hooks' reference.
310 ;;
311 ;; Thanks to Andreas Roehler <andreas.roehler@easy-emacs.de> for
312 ;; indicating defface byte-compilation warnings.
313 ;;
314 ;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight
315 ;; "long" lines. See EightyColumnRule (EmacsWiki).
316 ;;
317 ;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
318 ;; newline character mapping.
319 ;;
320 ;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
321 ;; whitespace-mode.el on XEmacs.
322 ;;
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).
325 ;;
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.
332 ;;
333 ;;
334 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
335
336 ;;; code:
337
338 \f
339 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
340 ;;;; User Variables:
341
342
343 ;;; Interface to the command system
344
345
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)
352
353
354 (defcustom whitespace-style '(mark color)
355 "*Specify the visualization style.
356
357 It's a list containing some or all of the following values:
358
359 mark display mappings are visualized.
360
361 color faces are visualized.
362
363 Any other value is ignored.
364
365 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
366
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)
373
374
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.
379
380 It's a list containing some or all of the following values:
381
382 trailing trailing blanks are visualized.
383
384 tabs TABs are visualized.
385
386 spaces SPACEs and HARD SPACEs are visualized.
387
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).
393
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'.
400
401 space-before-tab SPACEs before TAB are visualized.
402
403 newline NEWLINEs are visualized.
404
405 indentation 8 or more SPACEs at beginning of line are
406 visualized.
407
408 empty empty lines at beginning and/or end of buffer
409 are visualized.
410
411 space-after-tab 8 or more SPACEs after a TAB are visualized.
412
413 Any other value is ignored.
414
415 If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
416
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)
436
437
438 (defcustom whitespace-space 'whitespace-space
439 "*Symbol face used to visualize SPACE.
440
441 Used when `whitespace-style' includes the value `color'."
442 :type 'face
443 :group 'whitespace)
444
445
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)
454
455
456 (defcustom whitespace-hspace 'whitespace-hspace
457 "*Symbol face used to visualize HARD SPACE.
458
459 Used when `whitespace-style' includes the value `color'."
460 :type 'face
461 :group 'whitespace)
462
463
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)
472
473
474 (defcustom whitespace-tab 'whitespace-tab
475 "*Symbol face used to visualize TAB.
476
477 Used when `whitespace-style' includes the value `color'."
478 :type 'face
479 :group 'whitespace)
480
481
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)
490
491
492 (defcustom whitespace-newline 'whitespace-newline
493 "*Symbol face used to visualize NEWLINE char mapping.
494
495 See `whitespace-display-mappings'.
496
497 Used when `whitespace-style' includes the values `mark'
498 and `color', and `whitespace-chars' includes `newline'."
499 :type 'face
500 :group 'whitespace)
501
502
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.
510
511 See `whitespace-display-mappings'."
512 :group 'whitespace)
513
514
515 (defcustom whitespace-trailing 'whitespace-trailing
516 "*Symbol face used to visualize traling blanks.
517
518 Used when `whitespace-style' includes the value `color'."
519 :type 'face
520 :group 'whitespace)
521
522
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)
528
529
530 (defcustom whitespace-line 'whitespace-line
531 "*Symbol face used to visualize \"long\" lines.
532
533 See `whitespace-line-column'.
534
535 Used when `whitespace-style' includes the value `color'."
536 :type 'face
537 :group 'whitespace)
538
539
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.
544
545 See `whitespace-line-column'."
546 :group 'whitespace)
547
548
549 (defcustom whitespace-space-before-tab 'whitespace-space-before-tab
550 "*Symbol face used to visualize SPACEs before TAB.
551
552 Used when `whitespace-style' includes the value `color'."
553 :type 'face
554 :group 'whitespace)
555
556
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)
562
563
564 (defcustom whitespace-indentation 'whitespace-indentation
565 "*Symbol face used to visualize 8 or more SPACEs at beginning of line.
566
567 Used when `whitespace-style' includes the value `color'."
568 :type 'face
569 :group 'whitespace)
570
571
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)
577
578
579 (defcustom whitespace-empty 'whitespace-empty
580 "*Symbol face used to visualize empty lines at beginning and/or end of buffer.
581
582 Used when `whitespace-style' includes the value `color'."
583 :type 'face
584 :group 'whitespace)
585
586
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)
592
593
594 (defcustom whitespace-space-after-tab 'whitespace-space-after-tab
595 "*Symbol face used to visualize 8 or more SPACEs after TAB.
596
597 Used when `whitespace-style' includes the value `color'."
598 :type 'face
599 :group 'whitespace)
600
601
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)
607
608
609 (defcustom whitespace-hspace-regexp
610 "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
611 "*Specify HARD SPACE characters regexp.
612
613 If you're using `mule' package, there may be other characters besides:
614
615 \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
616
617 that should be considered HARD SPACE.
618
619 Here are some examples:
620
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.
629
630 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
631 Use exactly one pair of enclosing \\\\( and \\\\).
632
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)
637
638
639 (defcustom whitespace-space-regexp "\\( +\\)"
640 "*Specify SPACE characters regexp.
641
642 If you're using `mule' package, there may be other characters
643 besides \" \" that should be considered SPACE.
644
645 Here are some examples:
646
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.
652
653 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
654 Use exactly one pair of enclosing \\\\( and \\\\).
655
656 Used when `whitespace-style' includes the value `color',
657 and `whitespace-chars' includes `spaces'."
658 :type '(regexp :tag "SPACE Chars")
659 :group 'whitespace)
660
661
662 (defcustom whitespace-tab-regexp "\\(\t+\\)"
663 "*Specify TAB characters regexp.
664
665 If you're using `mule' package, there may be other characters
666 besides \"\\t\" that should be considered TAB.
667
668 Here are some examples:
669
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.
675
676 NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
677 Use exactly one pair of enclosing \\\\( and \\\\).
678
679 Used when `whitespace-style' includes the value `color',
680 and `whitespace-chars' includes `tabs'."
681 :type '(regexp :tag "TAB Chars")
682 :group 'whitespace)
683
684
685 (defcustom whitespace-trailing-regexp
686 "\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20"
687 "*Specify trailing characters regexp.
688
689 If you're using `mule' package, there may be other characters besides:
690
691 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
692 \"\\xF20\"
693
694 that should be considered blank.
695
696 NOTE: DO NOT enclose by \\\\( and \\\\) the elements to highlight.
697 `whitespace-mode' surrounds this regexp by \"\\\\(\\\\(\" and
698 \"\\\\)+\\\\)$\".
699
700 Used when `whitespace-style' includes the value `color',
701 and `whitespace-chars' includes `trailing'."
702 :type '(regexp :tag "Trailing Chars")
703 :group 'whitespace)
704
705
706 (defcustom whitespace-space-before-tab-regexp "\\( +\\)\t"
707 "*Specify SPACEs before TAB regexp.
708
709 If you're using `mule' package, there may be other characters besides:
710
711 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
712 \"\\xF20\"
713
714 that should be considered blank.
715
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)
720
721
722 (defcustom whitespace-indentation-regexp
723 "^\t*\\(\\( \\{8\\}\\)+\\)[^\n\t]"
724 "*Specify regexp for 8 or more SPACEs at beginning of line.
725
726 If you're using `mule' package, there may be other characters besides:
727
728 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
729 \"\\xF20\"
730
731 that should be considered blank.
732
733 Used when `whitespace-style' includes the value `color',
734 and `whitespace-chars' includes `indentation'."
735 :type '(regexp :tag "Indentation SPACEs")
736 :group 'whitespace)
737
738
739 (defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
740 "*Specify regexp for empty lines at beginning of buffer.
741
742 If you're using `mule' package, there may be other characters besides:
743
744 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
745 \"\\xF20\"
746
747 that should be considered blank.
748
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)
753
754
755 (defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
756 "*Specify regexp for empty lines at end of buffer.
757
758 If you're using `mule' package, there may be other characters besides:
759
760 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
761 \"\\xF20\"
762
763 that should be considered blank.
764
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)
769
770
771 (defcustom whitespace-space-after-tab-regexp "\t\\(\\( \\{8\\}\\)+\\)"
772 "*Specify regexp for 8 or more SPACEs after TAB.
773
774 If you're using `mule' package, there may be other characters besides:
775
776 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
777 \"\\xF20\"
778
779 that should be considered blank.
780
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)
785
786
787 (defcustom whitespace-line-column 80
788 "*Specify column beyond which the line is highlighted.
789
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)
794
795
796 ;; Hacked from `visible-whitespace-mappings' in visws.el
797 (defcustom whitespace-display-mappings
798 '(
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
812 ;;
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
819 )
820 "*Specify an alist of mappings for displaying characters.
821
822 Each element has the following form:
823
824 (CHAR VECTOR...)
825
826 Where:
827
828 CHAR is the character to be mapped.
829
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.
834
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.
839
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)
850
851
852 (defcustom whitespace-global-modes t
853 "*Modes for which global `whitespace-mode' is automagically turned on.
854
855 Global `whitespace-mode' is controlled by the command
856 `global-whitespace-mode'.
857
858 If nil, means no modes have `whitespace-mode' automatically
859 turned on.
860
861 If t, all modes that support `whitespace-mode' have it
862 automatically turned on.
863
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:
867
868 (c-mode c++-mode)
869
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)
881
882
883 (defcustom whitespace-action nil
884 "*Specify which action is taken when a buffer is visited, killed or written.
885
886 It's a list containing some or all of the following values:
887
888 nil no action is taken.
889
890 cleanup cleanup any bogus whitespace always when local
891 whitespace is turned on.
892 See `whitespace-cleanup' and
893 `whitespace-cleanup-region'.
894
895 report-on-bogus report if there is any bogus whitespace always
896 when local whitespace is turned on.
897
898 auto-cleanup cleanup any bogus whitespace when buffer is
899 written or killed.
900 See `whitespace-cleanup' and
901 `whitespace-cleanup-region'.
902
903 abort-on-bogus abort if there is any bogus whitespace and the
904 buffer is written or killed.
905
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)
916
917 \f
918 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
919 ;;;; User commands - Local mode
920
921
922 ;;;###autoload
923 (define-minor-mode whitespace-mode
924 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
925
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))))
942
943 \f
944 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
945 ;;;; User commands - Global mode
946
947
948 (define-minor-mode global-whitespace-mode
949 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
950
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)))))))
976
977
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...
988 (or
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)))))
999
1000 \f
1001 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1002 ;;;; User commands - Toggle
1003
1004
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
1016 )
1017 "List of valid `whitespace-chars' values.")
1018
1019
1020 (defconst whitespace-style-value-list
1021 '(color
1022 mark
1023 )
1024 "List of valid `whitespace-style' values.")
1025
1026
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)
1042 )
1043 "Alist of toggle options.
1044
1045 Each element has the form:
1046
1047 (CHAR . SYMBOL)
1048
1049 Where:
1050
1051 CHAR is a char which the user will have to type.
1052
1053 SYMBOL is a valid symbol associated with CHAR.
1054 See `whitespace-chars-value-list' and
1055 `whitespace-style-value-list'.")
1056
1057
1058 (defvar whitespace-active-chars nil
1059 "Used to save locally `whitespace-chars' value.")
1060 (make-variable-buffer-local 'whitespace-active-chars)
1061
1062 (defvar whitespace-active-style nil
1063 "Used to save locally `whitespace-style' value.")
1064 (make-variable-buffer-local 'whitespace-active-style)
1065
1066
1067 ;;;###autoload
1068 (defun whitespace-toggle-options (arg)
1069 "Toggle local `whitespace-mode' options.
1070
1071 If local whitespace-mode is off, toggle the option given by ARG
1072 and turn on local whitespace-mode.
1073
1074 If local whitespace-mode is on, toggle the option given by ARG
1075 and restart local whitespace-mode.
1076
1077 Interactively, it reads one of the following chars:
1078
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
1095
1096 Non-interactively, ARG should be a symbol or a list of symbols.
1097 The valid symbols are:
1098
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
1113
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)))
1126
1127
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.")
1132
1133
1134 ;;;###autoload
1135 (defun global-whitespace-toggle-options (arg)
1136 "Toggle global `whitespace-mode' options.
1137
1138 If global whitespace-mode is off, toggle the option given by ARG
1139 and turn on global whitespace-mode.
1140
1141 If global whitespace-mode is on, toggle the option given by ARG
1142 and restart global whitespace-mode.
1143
1144 Interactively, it accepts one of the following chars:
1145
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
1162
1163 Non-interactively, ARG should be a symbol or a list of symbols.
1164 The valid symbols are:
1165
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
1180
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)))
1195
1196 \f
1197 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1198 ;;;; User commands - Cleanup
1199
1200
1201 ;;;###autoload
1202 (defun whitespace-cleanup ()
1203 "Cleanup some blank problems in all buffer or at region.
1204
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.
1210
1211 See also `whitespace-cleanup-region'.
1212
1213 The problems cleaned up are:
1214
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.
1219
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.
1223
1224 4. SPACEs before TAB.
1225 If `whitespace-chars' includes the value `space-before-tab',
1226 replace SPACEs by TABs.
1227
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.
1231
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))))
1266
1267
1268 ;;;###autoload
1269 (defun whitespace-cleanup-region (start end)
1270 "Cleanup some blank problems at region.
1271
1272 The problems cleaned up are:
1273
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.
1277
1278 2. SPACEs before TAB.
1279 If `whitespace-chars' includes the value `space-before-tab',
1280 replace SPACEs by TABs.
1281
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.
1285
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
1327
1328
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)))))
1343
1344 \f
1345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1346 ;;;; User command - report
1347
1348
1349 (defun whitespace-trailing-regexp ()
1350 "Make the `whitespace-trailing-regexp' regexp."
1351 (concat "\\(\\(" whitespace-trailing-regexp "\\)+\\)$"))
1352
1353
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)
1362 )
1363 "List of whitespace bogus symbol and corresponding regexp.")
1364
1365
1366 (defconst whitespace-report-text
1367 "\
1368 Whitespace Report
1369
1370 Current Setting Whitespace Problem
1371
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.")
1379
1380
1381 (defconst whitespace-report-buffer-name "*Whitespace Report*"
1382 "The buffer name for whitespace bogus report.")
1383
1384
1385 ;;;###autoload
1386 (defun whitespace-report (&optional force report-if-bogus)
1387 "Report some whitespace problems in buffer.
1388
1389 Return nil if there is no whitespace problem; otherwise, return
1390 non-nil.
1391
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:
1395
1396 empty
1397 indentation
1398 space-before-tab
1399 trailing
1400 space-after-tab
1401
1402 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1403 whitespace problems in buffer.
1404
1405 Report if some of the following whitespace problems exist:
1406
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.
1413
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))
1420
1421
1422 ;;;###autoload
1423 (defun whitespace-report-region (start end &optional force report-if-bogus)
1424 "Report some whitespace problems in a region.
1425
1426 Return nil if there is no whitespace problem; otherwise, return
1427 non-nil.
1428
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:
1432
1433 empty
1434 indentation
1435 space-before-tab
1436 trailing
1437 space-after-tab
1438
1439 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1440 whitespace problems in buffer.
1441
1442 Report if some of the following whitespace problems exist:
1443
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.
1450
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))))
1489
1490 \f
1491 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1492 ;;;; Internal functions
1493
1494
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)
1498
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)
1502
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)
1506
1507
1508 (defconst whitespace-help-text
1509 "\
1510 whitespace-mode toggle options:
1511
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
1522
1523 [] c - toggle color faces
1524 [] m - toggle visual mark
1525
1526 x - restore `whitespace-chars' value
1527 z - restore `whitespace-style' value
1528
1529 ? - display this text\n\n"
1530 "Text for whitespace toggle options.")
1531
1532
1533 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1534 "The buffer name for whitespace toggle options.")
1535
1536
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" " ")))
1541
1542
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))))
1549
1550
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)))))
1566
1567
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)))
1581
1582
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))))
1589
1590
1591 (defun whitespace-interactive-char (local-p)
1592 "Interactive function to read a char and return a symbol.
1593
1594 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1595 uses a global context.
1596
1597 It accepts one of the following chars:
1598
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
1615
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
1653
1654
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.
1658
1659 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1660 uses a global context.
1661
1662 ARG is a list of options to be toggled.
1663
1664 THE-LIST is a list of options. This list will be toggled and the
1665 resultant list will be returned.
1666
1667 DEFAULT-LIST is the default list of options. It is used to
1668 restore the options in THE-LIST.
1669
1670 SYM-RESTORE is the symbol which indicates to restore the options
1671 in THE-LIST.
1672
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)
1689
1690
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)))
1704
1705
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)))
1713
1714
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
1728 nil
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))
1734 t))
1735 (when (memq 'tabs whitespace-active-chars)
1736 (font-lock-add-keywords
1737 nil
1738 (list
1739 ;; Show TABs
1740 (list whitespace-tab-regexp 1 whitespace-tab t))
1741 t))
1742 (when (memq 'trailing whitespace-active-chars)
1743 (font-lock-add-keywords
1744 nil
1745 (list
1746 ;; Show trailing blanks
1747 (list (whitespace-trailing-regexp) 1 whitespace-trailing t))
1748 t))
1749 (when (or (memq 'lines whitespace-active-chars)
1750 (memq 'lines-tail whitespace-active-chars))
1751 (font-lock-add-keywords
1752 nil
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)
1762 ""
1763 (format ".\\{%d\\}" rem))))
1764 (if (memq 'lines whitespace-active-chars)
1765 0 ; whole line
1766 2) ; line tail
1767 whitespace-line t))
1768 t))
1769 (when (memq 'space-before-tab whitespace-active-chars)
1770 (font-lock-add-keywords
1771 nil
1772 (list
1773 ;; Show SPACEs before TAB
1774 (list whitespace-space-before-tab-regexp
1775 1 whitespace-space-before-tab t))
1776 t))
1777 (when (memq 'indentation whitespace-active-chars)
1778 (font-lock-add-keywords
1779 nil
1780 (list
1781 ;; Show indentation SPACEs
1782 (list whitespace-indentation-regexp
1783 1 whitespace-indentation t))
1784 t))
1785 (when (memq 'empty whitespace-active-chars)
1786 (font-lock-add-keywords
1787 nil
1788 (list
1789 ;; Show empty lines at beginning of buffer
1790 (list whitespace-empty-at-bob-regexp
1791 1 whitespace-empty t))
1792 t)
1793 (font-lock-add-keywords
1794 nil
1795 (list
1796 ;; Show empty lines at end of buffer
1797 (list whitespace-empty-at-eob-regexp
1798 1 whitespace-empty t))
1799 t))
1800 (when (memq 'space-after-tab whitespace-active-chars)
1801 (font-lock-add-keywords
1802 nil
1803 (list
1804 ;; Show SPACEs after TAB
1805 (list whitespace-space-after-tab-regexp
1806 1 whitespace-space-after-tab t))
1807 t))
1808 ;; now turn on font lock and highlight blanks
1809 (font-lock-mode 1)))
1810
1811
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)))
1822
1823 \f
1824 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1825 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
1826
1827
1828 (defvar whitespace-display-table nil
1829 "Used to save a local display table.")
1830 (make-variable-buffer-local 'whitespace-display-table)
1831
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)
1835
1836
1837 (defsubst whitespace-char-valid-p (char)
1838 ;; This check should be improved!!!
1839 (or (< char 256)
1840 (characterp char)))
1841
1842
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))))
1850
1851
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
1890 (t
1891 ;; Do nothing
1892 )))))))
1893
1894
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)))
1901
1902 \f
1903 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1904 ;;;; Hook
1905
1906
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))))
1913
1914
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))
1919
1920
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))
1925
1926
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
1934
1935
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
1941
1942
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))
1951 (t
1952 nil)))
1953
1954 \f
1955 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1956
1957
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
1967
1968
1969 (provide 'whitespace)
1970
1971
1972 (run-hooks 'whitespace-load-hook)
1973
1974
1975 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
1976 ;;; whitespace.el ends here