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