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