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