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