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