* align.el:
[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.2.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 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 as the original whitespace package
320 ;; 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 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.
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.
991
992 warn-if-read-only give a warning if `cleanup' or `auto-cleanup'
993 is included in `whitespace-action' and the
994 buffer is read-only.
995
996 Any other value is treated as nil."
997 :type '(choice :tag "Actions"
998 (const :tag "None" nil)
999 (repeat :tag "Action List"
1000 (choice :tag "Action"
1001 (const :tag "Cleanup When On" cleanup)
1002 (const :tag "Report On Bogus" report-on-bogus)
1003 (const :tag "Auto Cleanup" auto-cleanup)
1004 (const :tag "Abort On Bogus" abort-on-bogus)
1005 (const :tag "Warn If Read-Only" warn-if-read-only))))
1006 :group 'whitespace)
1007
1008 \f
1009 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1010 ;;;; User commands - Local mode
1011
1012
1013 ;;;###autoload
1014 (define-minor-mode whitespace-mode
1015 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
1016
1017 If ARG is null, toggle whitespace visualization.
1018 If ARG is a number greater than zero, turn on visualization;
1019 otherwise, turn off visualization.
1020 Only useful with a windowing system.
1021
1022 See also `whitespace-style', `whitespace-newline' and
1023 `whitespace-display-mappings'."
1024 :lighter " ws"
1025 :init-value nil
1026 :global nil
1027 :group 'whitespace
1028 (cond
1029 (noninteractive ; running a batch job
1030 (setq whitespace-mode nil))
1031 (whitespace-mode ; whitespace-mode on
1032 (whitespace-turn-on)
1033 (whitespace-action-when-on))
1034 (t ; whitespace-mode off
1035 (whitespace-turn-off))))
1036
1037
1038 ;;;###autoload
1039 (define-minor-mode whitespace-newline-mode
1040 "Toggle NEWLINE minor mode visualization (\"nl\" on modeline).
1041
1042 If ARG is null, toggle NEWLINE visualization.
1043 If ARG is a number greater than zero, turn on visualization;
1044 otherwise, turn off visualization.
1045 Only useful with a windowing system.
1046
1047 Use `whitespace-newline-mode' only for NEWLINE visualization
1048 exclusively. For other visualizations, including NEWLINE
1049 visualization together with (HARD) SPACEs and/or TABs, please,
1050 use `whitespace-mode'.
1051
1052 See also `whitespace-newline' and `whitespace-display-mappings'."
1053 :lighter " nl"
1054 :init-value nil
1055 :global nil
1056 :group 'whitespace
1057 (let ((whitespace-style '(newline-mark newline)))
1058 (whitespace-mode whitespace-newline-mode)
1059 ;; sync states (running a batch job)
1060 (setq whitespace-newline-mode whitespace-mode)))
1061
1062 \f
1063 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1064 ;;;; User commands - Global mode
1065
1066
1067 ;;;###autoload
1068 (define-minor-mode global-whitespace-mode
1069 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
1070
1071 If ARG is null, toggle whitespace visualization.
1072 If ARG is a number greater than zero, turn on visualization;
1073 otherwise, turn off visualization.
1074 Only useful with a windowing system.
1075
1076 See also `whitespace-style', `whitespace-newline' and
1077 `whitespace-display-mappings'."
1078 :lighter " WS"
1079 :init-value nil
1080 :global t
1081 :group 'whitespace
1082 (cond
1083 (noninteractive ; running a batch job
1084 (setq global-whitespace-mode nil))
1085 (global-whitespace-mode ; global-whitespace-mode on
1086 (save-excursion
1087 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1088 (dolist (buffer (buffer-list)) ; adjust all local mode
1089 (set-buffer buffer)
1090 (unless whitespace-mode
1091 (whitespace-turn-on-if-enabled)))))
1092 (t ; global-whitespace-mode off
1093 (save-excursion
1094 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
1095 (dolist (buffer (buffer-list)) ; adjust all local mode
1096 (set-buffer buffer)
1097 (unless whitespace-mode
1098 (whitespace-turn-off)))))))
1099
1100
1101 (defun whitespace-turn-on-if-enabled ()
1102 (when (cond
1103 ((eq whitespace-global-modes t))
1104 ((listp whitespace-global-modes)
1105 (if (eq (car-safe whitespace-global-modes) 'not)
1106 (not (memq major-mode (cdr whitespace-global-modes)))
1107 (memq major-mode whitespace-global-modes)))
1108 (t nil))
1109 (let (inhibit-quit)
1110 ;; Don't turn on whitespace mode if...
1111 (or
1112 ;; ...we don't have a display (we're running a batch job)
1113 noninteractive
1114 ;; ...or if the buffer is invisible (name starts with a space)
1115 (eq (aref (buffer-name) 0) ?\ )
1116 ;; ...or if the buffer is temporary (name starts with *)
1117 (and (eq (aref (buffer-name) 0) ?*)
1118 ;; except the scratch buffer.
1119 (not (string= (buffer-name) "*scratch*")))
1120 ;; Otherwise, turn on whitespace mode.
1121 (whitespace-turn-on)))))
1122
1123
1124 ;;;###autoload
1125 (define-minor-mode global-whitespace-newline-mode
1126 "Toggle NEWLINE global minor mode visualization (\"NL\" on modeline).
1127
1128 If ARG is null, toggle NEWLINE visualization.
1129 If ARG is a number greater than zero, turn on visualization;
1130 otherwise, turn off visualization.
1131 Only useful with a windowing system.
1132
1133 Use `global-whitespace-newline-mode' only for NEWLINE
1134 visualization exclusively. For other visualizations, including
1135 NEWLINE visualization together with (HARD) SPACEs and/or TABs,
1136 please, use `global-whitespace-mode'.
1137
1138 See also `whitespace-newline' and `whitespace-display-mappings'."
1139 :lighter " NL"
1140 :init-value nil
1141 :global t
1142 :group 'whitespace
1143 (let ((whitespace-style '(newline-mark newline)))
1144 (global-whitespace-mode global-whitespace-newline-mode)
1145 ;; sync states (running a batch job)
1146 (setq global-whitespace-newline-mode global-whitespace-mode)))
1147
1148 \f
1149 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1150 ;;;; User commands - Toggle
1151
1152
1153 (defconst whitespace-style-value-list
1154 '(tabs
1155 spaces
1156 trailing
1157 lines
1158 lines-tail
1159 newline
1160 empty
1161 indentation
1162 indentation::tab
1163 indentation::space
1164 space-after-tab
1165 space-after-tab::tab
1166 space-after-tab::space
1167 space-before-tab
1168 space-before-tab::tab
1169 space-before-tab::space
1170 help-newline ; value used by `whitespace-insert-option-mark'
1171 tab-mark
1172 space-mark
1173 newline-mark
1174 )
1175 "List of valid `whitespace-style' values.")
1176
1177
1178 (defconst whitespace-toggle-option-alist
1179 '((?t . tabs)
1180 (?s . spaces)
1181 (?r . trailing)
1182 (?l . lines)
1183 (?L . lines-tail)
1184 (?n . newline)
1185 (?e . empty)
1186 (?\C-i . indentation)
1187 (?I . indentation::tab)
1188 (?i . indentation::space)
1189 (?\C-a . space-after-tab)
1190 (?A . space-after-tab::tab)
1191 (?a . space-after-tab::space)
1192 (?\C-b . space-before-tab)
1193 (?B . space-before-tab::tab)
1194 (?b . space-before-tab::space)
1195 (?T . tab-mark)
1196 (?S . space-mark)
1197 (?N . newline-mark)
1198 (?x . whitespace-style)
1199 )
1200 "Alist of toggle options.
1201
1202 Each element has the form:
1203
1204 (CHAR . SYMBOL)
1205
1206 Where:
1207
1208 CHAR is a char which the user will have to type.
1209
1210 SYMBOL is a valid symbol associated with CHAR.
1211 See `whitespace-style-value-list'.")
1212
1213
1214 (defvar whitespace-active-style nil
1215 "Used to save locally `whitespace-style' value.")
1216
1217 (defvar whitespace-indent-tabs-mode indent-tabs-mode
1218 "Used to save locally `indent-tabs-mode' value.")
1219
1220 (defvar whitespace-tab-width tab-width
1221 "Used to save locally `tab-width' value.")
1222
1223
1224 ;;;###autoload
1225 (defun whitespace-toggle-options (arg)
1226 "Toggle local `whitespace-mode' options.
1227
1228 If local whitespace-mode is off, toggle the option given by ARG
1229 and turn on local whitespace-mode.
1230
1231 If local whitespace-mode is on, toggle the option given by ARG
1232 and restart local whitespace-mode.
1233
1234 Interactively, it reads one of the following chars:
1235
1236 CHAR MEANING
1237 (VIA FACES)
1238 t toggle TAB visualization
1239 s toggle SPACE and HARD SPACE visualization
1240 r toggle trailing blanks visualization
1241 l toggle \"long lines\" visualization
1242 L toggle \"long lines\" tail visualization
1243 n toggle NEWLINE visualization
1244 e toggle empty line at bob and/or eob visualization
1245 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1246 I toggle indentation SPACEs visualization
1247 i toggle indentation TABs visualization
1248 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1249 A toggle SPACEs after TAB: SPACEs visualization
1250 a toggle SPACEs after TAB: TABs visualization
1251 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1252 B toggle SPACEs before TAB: SPACEs visualization
1253 b toggle SPACEs before TAB: TABs visualization
1254
1255 (VIA DISPLAY TABLE)
1256 T toggle TAB visualization
1257 S toggle SPACEs before TAB visualization
1258 N toggle NEWLINE visualization
1259
1260 x restore `whitespace-style' value
1261 ? display brief help
1262
1263 Non-interactively, ARG should be a symbol or a list of symbols.
1264 The valid symbols are:
1265
1266 tabs toggle TAB visualization
1267 spaces toggle SPACE and HARD SPACE visualization
1268 trailing toggle trailing blanks visualization
1269 lines toggle \"long lines\" visualization
1270 lines-tail toggle \"long lines\" tail visualization
1271 newline toggle NEWLINE visualization
1272 empty toggle empty line at bob and/or eob visualization
1273 indentation toggle indentation SPACEs visualization
1274 indentation::tab toggle indentation SPACEs visualization
1275 indentation::space toggle indentation TABs visualization
1276 space-after-tab toggle SPACEs after TAB visualization
1277 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1278 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1279 space-before-tab toggle SPACEs before TAB visualization
1280 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1281 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1282
1283 tab-mark toggle TAB visualization
1284 space-mark toggle SPACEs before TAB visualization
1285 newline-mark toggle NEWLINE visualization
1286
1287 whitespace-style restore `whitespace-style' value
1288
1289 Only useful with a windowing system.
1290
1291 See `whitespace-style' and `indent-tabs-mode' for documentation."
1292 (interactive (whitespace-interactive-char t))
1293 (let ((whitespace-style
1294 (whitespace-toggle-list t arg whitespace-active-style)))
1295 (whitespace-mode 0)
1296 (whitespace-mode 1)))
1297
1298
1299 (defvar whitespace-toggle-style nil
1300 "Used to toggle the global `whitespace-style' value.")
1301
1302
1303 ;;;###autoload
1304 (defun global-whitespace-toggle-options (arg)
1305 "Toggle global `whitespace-mode' options.
1306
1307 If global whitespace-mode is off, toggle the option given by ARG
1308 and turn on global whitespace-mode.
1309
1310 If global whitespace-mode is on, toggle the option given by ARG
1311 and restart global whitespace-mode.
1312
1313 Interactively, it accepts one of the following chars:
1314
1315 CHAR MEANING
1316 (VIA FACES)
1317 t toggle TAB visualization
1318 s toggle SPACE and HARD SPACE visualization
1319 r toggle trailing blanks visualization
1320 l toggle \"long lines\" visualization
1321 L toggle \"long lines\" tail visualization
1322 n toggle NEWLINE visualization
1323 e toggle empty line at bob and/or eob visualization
1324 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1325 I toggle indentation SPACEs visualization
1326 i toggle indentation TABs visualization
1327 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1328 A toggle SPACEs after TAB: SPACEs visualization
1329 a toggle SPACEs after TAB: TABs visualization
1330 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1331 B toggle SPACEs before TAB: SPACEs visualization
1332 b toggle SPACEs before TAB: TABs visualization
1333
1334 (VIA DISPLAY TABLE)
1335 T toggle TAB visualization
1336 S toggle SPACEs before TAB visualization
1337 N toggle NEWLINE visualization
1338
1339 x restore `whitespace-style' value
1340 ? display brief help
1341
1342 Non-interactively, ARG should be a symbol or a list of symbols.
1343 The valid symbols are:
1344
1345 tabs toggle TAB visualization
1346 spaces toggle SPACE and HARD SPACE visualization
1347 trailing toggle trailing blanks visualization
1348 lines toggle \"long lines\" visualization
1349 lines-tail toggle \"long lines\" tail visualization
1350 newline toggle NEWLINE visualization
1351 empty toggle empty line at bob and/or eob visualization
1352 indentation toggle indentation SPACEs visualization
1353 indentation::tab toggle indentation SPACEs visualization
1354 indentation::space toggle indentation TABs visualization
1355 space-after-tab toggle SPACEs after TAB visualization
1356 space-after-tab::tab toggle SPACEs after TAB: SPACEs visualization
1357 space-after-tab::space toggle SPACEs after TAB: TABs visualization
1358 space-before-tab toggle SPACEs before TAB visualization
1359 space-before-tab::tab toggle SPACEs before TAB: SPACEs visualization
1360 space-before-tab::space toggle SPACEs before TAB: TABs visualization
1361
1362 tab-mark toggle TAB visualization
1363 space-mark toggle SPACEs before TAB visualization
1364 newline-mark toggle NEWLINE visualization
1365
1366 whitespace-style restore `whitespace-style' value
1367
1368 Only useful with a windowing system.
1369
1370 See `whitespace-style' and `indent-tabs-mode' for documentation."
1371 (interactive (whitespace-interactive-char nil))
1372 (let ((whitespace-style
1373 (whitespace-toggle-list nil arg whitespace-toggle-style)))
1374 (setq whitespace-toggle-style whitespace-style)
1375 (global-whitespace-mode 0)
1376 (global-whitespace-mode 1)))
1377
1378 \f
1379 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1380 ;;;; User commands - Cleanup
1381
1382
1383 ;;;###autoload
1384 (defun whitespace-cleanup ()
1385 "Cleanup some blank problems in all buffer or at region.
1386
1387 It usually applies to the whole buffer, but in transient mark
1388 mode when the mark is active, it applies to the region. It also
1389 applies to the region when it is not in transient mark mode, the
1390 mark is active and \\[universal-argument] was pressed just before
1391 calling `whitespace-cleanup' interactively.
1392
1393 See also `whitespace-cleanup-region'.
1394
1395 The problems cleaned up are:
1396
1397 1. empty lines at beginning of buffer.
1398 2. empty lines at end of buffer.
1399 If `whitespace-style' includes the value `empty', remove all
1400 empty lines at beginning and/or end of buffer.
1401
1402 3. 8 or more SPACEs at beginning of line.
1403 If `whitespace-style' includes the value `indentation':
1404 replace 8 or more SPACEs at beginning of line by TABs, if
1405 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1406 SPACEs.
1407 If `whitespace-style' includes the value `indentation::tab',
1408 replace 8 or more SPACEs at beginning of line by TABs.
1409 If `whitespace-style' includes the value `indentation::space',
1410 replace TABs by SPACEs.
1411
1412 4. SPACEs before TAB.
1413 If `whitespace-style' includes the value `space-before-tab':
1414 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1415 otherwise, replace TABs by SPACEs.
1416 If `whitespace-style' includes the value
1417 `space-before-tab::tab', replace SPACEs by TABs.
1418 If `whitespace-style' includes the value
1419 `space-before-tab::space', replace TABs by SPACEs.
1420
1421 5. SPACEs or TABs at end of line.
1422 If `whitespace-style' includes the value `trailing', remove
1423 all SPACEs or TABs at end of line.
1424
1425 6. 8 or more SPACEs after TAB.
1426 If `whitespace-style' includes the value `space-after-tab':
1427 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1428 otherwise, replace TABs by SPACEs.
1429 If `whitespace-style' includes the value
1430 `space-after-tab::tab', replace SPACEs by TABs.
1431 If `whitespace-style' includes the value
1432 `space-after-tab::space', replace TABs by SPACEs.
1433
1434 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1435 documentation."
1436 (interactive "@")
1437 (cond
1438 ;; read-only buffer
1439 (buffer-read-only
1440 (whitespace-warn-read-only "cleanup"))
1441 ;; region active
1442 ((and (or transient-mark-mode
1443 current-prefix-arg)
1444 mark-active)
1445 ;; PROBLEMs 1 and 2 are not handled in region
1446 ;; PROBLEM 3: 8 or more SPACEs at bol
1447 ;; PROBLEM 4: SPACEs before TAB
1448 ;; PROBLEM 5: SPACEs or TABs at eol
1449 ;; PROBLEM 6: 8 or more SPACEs after TAB
1450 (whitespace-cleanup-region (region-beginning) (region-end)))
1451 ;; whole buffer
1452 (t
1453 (save-excursion
1454 (save-match-data
1455 ;; PROBLEM 1: empty lines at bob
1456 ;; PROBLEM 2: empty lines at eob
1457 ;; ACTION: remove all empty lines at bob and/or eob
1458 (when (memq 'empty whitespace-style)
1459 (let (overwrite-mode) ; enforce no overwrite
1460 (goto-char (point-min))
1461 (when (re-search-forward
1462 whitespace-empty-at-bob-regexp nil t)
1463 (delete-region (match-beginning 1) (match-end 1)))
1464 (when (re-search-forward
1465 whitespace-empty-at-eob-regexp nil t)
1466 (delete-region (match-beginning 1) (match-end 1)))))))
1467 ;; PROBLEM 3: 8 or more SPACEs at bol
1468 ;; PROBLEM 4: SPACEs before TAB
1469 ;; PROBLEM 5: SPACEs or TABs at eol
1470 ;; PROBLEM 6: 8 or more SPACEs after TAB
1471 (whitespace-cleanup-region (point-min) (point-max)))))
1472
1473
1474 ;;;###autoload
1475 (defun whitespace-cleanup-region (start end)
1476 "Cleanup some blank problems at region.
1477
1478 The problems cleaned up are:
1479
1480 1. 8 or more SPACEs at beginning of line.
1481 If `whitespace-style' includes the value `indentation':
1482 replace 8 or more SPACEs at beginning of line by TABs, if
1483 `indent-tabs-mode' is non-nil; otherwise, replace TABs by
1484 SPACEs.
1485 If `whitespace-style' includes the value `indentation::tab',
1486 replace 8 or more SPACEs at beginning of line by TABs.
1487 If `whitespace-style' includes the value `indentation::space',
1488 replace TABs by SPACEs.
1489
1490 2. SPACEs before TAB.
1491 If `whitespace-style' includes the value `space-before-tab':
1492 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1493 otherwise, replace TABs by SPACEs.
1494 If `whitespace-style' includes the value
1495 `space-before-tab::tab', replace SPACEs by TABs.
1496 If `whitespace-style' includes the value
1497 `space-before-tab::space', replace TABs by SPACEs.
1498
1499 3. SPACEs or TABs at end of line.
1500 If `whitespace-style' includes the value `trailing', remove
1501 all SPACEs or TABs at end of line.
1502
1503 4. 8 or more SPACEs after TAB.
1504 If `whitespace-style' includes the value `space-after-tab':
1505 replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
1506 otherwise, replace TABs by SPACEs.
1507 If `whitespace-style' includes the value
1508 `space-after-tab::tab', replace SPACEs by TABs.
1509 If `whitespace-style' includes the value
1510 `space-after-tab::space', replace TABs by SPACEs.
1511
1512 See `whitespace-style', `indent-tabs-mode' and `tab-width' for
1513 documentation."
1514 (interactive "@r")
1515 (if buffer-read-only
1516 ;; read-only buffer
1517 (whitespace-warn-read-only "cleanup region")
1518 ;; non-read-only buffer
1519 (let ((rstart (min start end))
1520 (rend (copy-marker (max start end)))
1521 (indent-tabs-mode whitespace-indent-tabs-mode)
1522 (tab-width whitespace-tab-width)
1523 overwrite-mode ; enforce no overwrite
1524 tmp)
1525 (save-excursion
1526 (save-match-data
1527 ;; PROBLEM 1: 8 or more SPACEs at bol
1528 (cond
1529 ;; ACTION: replace 8 or more SPACEs at bol by TABs, if
1530 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1531 ;; by SPACEs.
1532 ((memq 'indentation whitespace-style)
1533 (let ((regexp (whitespace-indentation-regexp)))
1534 (goto-char rstart)
1535 (while (re-search-forward regexp rend t)
1536 (setq tmp (current-indentation))
1537 (goto-char (match-beginning 0))
1538 (delete-horizontal-space)
1539 (unless (eolp)
1540 (indent-to tmp)))))
1541 ;; ACTION: replace 8 or more SPACEs at bol by TABs.
1542 ((memq 'indentation::tab whitespace-style)
1543 (whitespace-replace-action
1544 'tabify rstart rend
1545 (whitespace-indentation-regexp 'tab) 0))
1546 ;; ACTION: replace TABs by SPACEs.
1547 ((memq 'indentation::space whitespace-style)
1548 (whitespace-replace-action
1549 'untabify rstart rend
1550 (whitespace-indentation-regexp 'space) 0)))
1551 ;; PROBLEM 3: SPACEs or TABs at eol
1552 ;; ACTION: remove all SPACEs or TABs at eol
1553 (when (memq 'trailing whitespace-style)
1554 (whitespace-replace-action
1555 'delete-region rstart rend
1556 whitespace-trailing-regexp 1))
1557 ;; PROBLEM 4: 8 or more SPACEs after TAB
1558 (cond
1559 ;; ACTION: replace 8 or more SPACEs by TABs, if
1560 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1561 ;; by SPACEs.
1562 ((memq 'space-after-tab whitespace-style)
1563 (whitespace-replace-action
1564 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1565 rstart rend (whitespace-space-after-tab-regexp) 1))
1566 ;; ACTION: replace 8 or more SPACEs by TABs.
1567 ((memq 'space-after-tab::tab whitespace-style)
1568 (whitespace-replace-action
1569 'tabify rstart rend
1570 (whitespace-space-after-tab-regexp 'tab) 1))
1571 ;; ACTION: replace TABs by SPACEs.
1572 ((memq 'space-after-tab::space whitespace-style)
1573 (whitespace-replace-action
1574 'untabify rstart rend
1575 (whitespace-space-after-tab-regexp 'space) 1)))
1576 ;; PROBLEM 2: SPACEs before TAB
1577 (cond
1578 ;; ACTION: replace SPACEs before TAB by TABs, if
1579 ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
1580 ;; by SPACEs.
1581 ((memq 'space-before-tab whitespace-style)
1582 (whitespace-replace-action
1583 (if whitespace-indent-tabs-mode 'tabify 'untabify)
1584 rstart rend whitespace-space-before-tab-regexp
1585 (if whitespace-indent-tabs-mode 1 2)))
1586 ;; ACTION: replace SPACEs before TAB by TABs.
1587 ((memq 'space-before-tab::tab whitespace-style)
1588 (whitespace-replace-action
1589 'tabify rstart rend
1590 whitespace-space-before-tab-regexp 1))
1591 ;; ACTION: replace TABs by SPACEs.
1592 ((memq 'space-before-tab::space whitespace-style)
1593 (whitespace-replace-action
1594 'untabify rstart rend
1595 whitespace-space-before-tab-regexp 2)))))
1596 (set-marker rend nil)))) ; point marker to nowhere
1597
1598
1599 (defun whitespace-replace-action (action rstart rend regexp index)
1600 "Do ACTION in the string matched by REGEXP between RSTART and REND.
1601
1602 INDEX is the level group matched by REGEXP and used by ACTION.
1603
1604 See also `tab-width'."
1605 (goto-char rstart)
1606 (while (re-search-forward regexp rend t)
1607 (goto-char (match-end index))
1608 (funcall action (match-beginning index) (match-end index))))
1609
1610 \f
1611 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1612 ;;;; User command - report
1613
1614
1615 (defun whitespace-regexp (regexp &optional kind)
1616 "Return REGEXP depending on `whitespace-indent-tabs-mode'."
1617 (cond
1618 ((or (eq kind 'tab)
1619 whitespace-indent-tabs-mode)
1620 (format (car regexp) whitespace-tab-width))
1621 ((or (eq kind 'space)
1622 (not whitespace-indent-tabs-mode))
1623 (cdr regexp))))
1624
1625
1626 (defun whitespace-indentation-regexp (&optional kind)
1627 "Return the indentation regexp depending on `whitespace-indent-tabs-mode'."
1628 (whitespace-regexp whitespace-indentation-regexp kind))
1629
1630
1631 (defun whitespace-space-after-tab-regexp (&optional kind)
1632 "Return the space-after-tab regexp depending on `whitespace-indent-tabs-mode'."
1633 (whitespace-regexp whitespace-space-after-tab-regexp kind))
1634
1635
1636 (defconst whitespace-report-list
1637 (list
1638 (cons 'empty whitespace-empty-at-bob-regexp)
1639 (cons 'empty whitespace-empty-at-eob-regexp)
1640 (cons 'trailing whitespace-trailing-regexp)
1641 (cons 'indentation nil)
1642 (cons 'indentation::tab nil)
1643 (cons 'indentation::space nil)
1644 (cons 'space-before-tab whitespace-space-before-tab-regexp)
1645 (cons 'space-before-tab::tab whitespace-space-before-tab-regexp)
1646 (cons 'space-before-tab::space whitespace-space-before-tab-regexp)
1647 (cons 'space-after-tab nil)
1648 (cons 'space-after-tab::tab nil)
1649 (cons 'space-after-tab::space nil)
1650 )
1651 "List of whitespace bogus symbol and corresponding regexp.")
1652
1653
1654 (defconst whitespace-report-text
1655 '( ;; `indent-tabs-mode' has non-nil value
1656 "\
1657 Whitespace Report
1658
1659 Current Setting Whitespace Problem
1660
1661 empty [] [] empty lines at beginning of buffer
1662 empty [] [] empty lines at end of buffer
1663 trailing [] [] SPACEs or TABs at end of line
1664 indentation [] [] 8 or more SPACEs at beginning of line
1665 indentation::tab [] [] 8 or more SPACEs at beginning of line
1666 indentation::space [] [] TABs at beginning of line
1667 space-before-tab [] [] SPACEs before TAB
1668 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1669 space-before-tab::space [] [] SPACEs before TAB: TABs
1670 space-after-tab [] [] 8 or more SPACEs after TAB
1671 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1672 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1673
1674 indent-tabs-mode =
1675 tab-width = \n\n"
1676 . ;; `indent-tabs-mode' has nil value
1677 "\
1678 Whitespace Report
1679
1680 Current Setting Whitespace Problem
1681
1682 empty [] [] empty lines at beginning of buffer
1683 empty [] [] empty lines at end of buffer
1684 trailing [] [] SPACEs or TABs at end of line
1685 indentation [] [] TABs at beginning of line
1686 indentation::tab [] [] 8 or more SPACEs at beginning of line
1687 indentation::space [] [] TABs at beginning of line
1688 space-before-tab [] [] SPACEs before TAB
1689 space-before-tab::tab [] [] SPACEs before TAB: SPACEs
1690 space-before-tab::space [] [] SPACEs before TAB: TABs
1691 space-after-tab [] [] 8 or more SPACEs after TAB
1692 space-after-tab::tab [] [] 8 or more SPACEs after TAB: SPACEs
1693 space-after-tab::space [] [] 8 or more SPACEs after TAB: TABs
1694
1695 indent-tabs-mode =
1696 tab-width = \n\n")
1697 "Text for whitespace bogus report.
1698
1699 It is a cons of strings, where the car part is used when
1700 `indent-tabs-mode' is non-nil, and the cdr part is used when
1701 `indent-tabs-mode' is nil.")
1702
1703
1704 (defconst whitespace-report-buffer-name "*Whitespace Report*"
1705 "The buffer name for whitespace bogus report.")
1706
1707
1708 ;;;###autoload
1709 (defun whitespace-report (&optional force report-if-bogus)
1710 "Report some whitespace problems in buffer.
1711
1712 Return nil if there is no whitespace problem; otherwise, return
1713 non-nil.
1714
1715 If FORCE is non-nil or \\[universal-argument] was pressed just
1716 before calling `whitespace-report' interactively, it forces
1717 `whitespace-style' to have:
1718
1719 empty
1720 trailing
1721 indentation
1722 space-before-tab
1723 space-after-tab
1724
1725 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1726 whitespace problems in buffer.
1727
1728 Report if some of the following whitespace problems exist:
1729
1730 * If `indent-tabs-mode' is non-nil:
1731 empty 1. empty lines at beginning of buffer.
1732 empty 2. empty lines at end of buffer.
1733 trailing 3. SPACEs or TABs at end of line.
1734 indentation 4. 8 or more SPACEs at beginning of line.
1735 space-before-tab 5. SPACEs before TAB.
1736 space-after-tab 6. 8 or more SPACEs after TAB.
1737
1738 * If `indent-tabs-mode' is nil:
1739 empty 1. empty lines at beginning of buffer.
1740 empty 2. empty lines at end of buffer.
1741 trailing 3. SPACEs or TABs at end of line.
1742 indentation 4. TABS at beginning of line.
1743 space-before-tab 5. SPACEs before TAB.
1744 space-after-tab 6. 8 or more SPACEs after TAB.
1745
1746 See `whitespace-style' for documentation.
1747 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1748 cleaning up these problems."
1749 (interactive (list current-prefix-arg))
1750 (whitespace-report-region (point-min) (point-max)
1751 force report-if-bogus))
1752
1753
1754 ;;;###autoload
1755 (defun whitespace-report-region (start end &optional force report-if-bogus)
1756 "Report some whitespace problems in a region.
1757
1758 Return nil if there is no whitespace problem; otherwise, return
1759 non-nil.
1760
1761 If FORCE is non-nil or \\[universal-argument] was pressed just
1762 before calling `whitespace-report-region' interactively, it
1763 forces `whitespace-style' to have:
1764
1765 empty
1766 indentation
1767 space-before-tab
1768 trailing
1769 space-after-tab
1770
1771 If REPORT-IF-BOGUS is non-nil, it reports only when there are any
1772 whitespace problems in buffer.
1773
1774 Report if some of the following whitespace problems exist:
1775
1776 * If `indent-tabs-mode' is non-nil:
1777 empty 1. empty lines at beginning of buffer.
1778 empty 2. empty lines at end of buffer.
1779 trailing 3. SPACEs or TABs at end of line.
1780 indentation 4. 8 or more SPACEs at beginning of line.
1781 space-before-tab 5. SPACEs before TAB.
1782 space-after-tab 6. 8 or more SPACEs after TAB.
1783
1784 * If `indent-tabs-mode' is nil:
1785 empty 1. empty lines at beginning of buffer.
1786 empty 2. empty lines at end of buffer.
1787 trailing 3. SPACEs or TABs at end of line.
1788 indentation 4. TABS at beginning of line.
1789 space-before-tab 5. SPACEs before TAB.
1790 space-after-tab 6. 8 or more SPACEs after TAB.
1791
1792 See `whitespace-style' for documentation.
1793 See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1794 cleaning up these problems."
1795 (interactive "r")
1796 (setq force (or current-prefix-arg force))
1797 (save-excursion
1798 (save-match-data
1799 (let* ((has-bogus nil)
1800 (rstart (min start end))
1801 (rend (max start end))
1802 (bogus-list
1803 (mapcar
1804 #'(lambda (option)
1805 (when force
1806 (add-to-list 'whitespace-style (car option)))
1807 (goto-char rstart)
1808 (let ((regexp
1809 (cond
1810 ((eq (car option) 'indentation)
1811 (whitespace-indentation-regexp))
1812 ((eq (car option) 'indentation::tab)
1813 (whitespace-indentation-regexp 'tab))
1814 ((eq (car option) 'indentation::space)
1815 (whitespace-indentation-regexp 'space))
1816 ((eq (car option) 'space-after-tab)
1817 (whitespace-space-after-tab-regexp))
1818 ((eq (car option) 'space-after-tab::tab)
1819 (whitespace-space-after-tab-regexp 'tab))
1820 ((eq (car option) 'space-after-tab::space)
1821 (whitespace-space-after-tab-regexp 'space))
1822 (t
1823 (cdr option)))))
1824 (and (re-search-forward regexp rend t)
1825 (setq has-bogus t))))
1826 whitespace-report-list)))
1827 (when (if report-if-bogus has-bogus t)
1828 (whitespace-kill-buffer whitespace-report-buffer-name)
1829 ;; `whitespace-indent-tabs-mode' is local to current buffer
1830 ;; `whitespace-tab-width' is local to current buffer
1831 (let ((ws-indent-tabs-mode whitespace-indent-tabs-mode)
1832 (ws-tab-width whitespace-tab-width))
1833 (with-current-buffer (get-buffer-create
1834 whitespace-report-buffer-name)
1835 (erase-buffer)
1836 (insert (if ws-indent-tabs-mode
1837 (car whitespace-report-text)
1838 (cdr whitespace-report-text)))
1839 (goto-char (point-min))
1840 (forward-line 3)
1841 (dolist (option whitespace-report-list)
1842 (forward-line 1)
1843 (whitespace-mark-x
1844 27 (memq (car option) whitespace-style))
1845 (whitespace-mark-x 7 (car bogus-list))
1846 (setq bogus-list (cdr bogus-list)))
1847 (forward-line 1)
1848 (whitespace-insert-value ws-indent-tabs-mode)
1849 (whitespace-insert-value ws-tab-width)
1850 (when has-bogus
1851 (goto-char (point-max))
1852 (insert " Type `M-x whitespace-cleanup'"
1853 " to cleanup the buffer.\n\n"
1854 " Type `M-x whitespace-cleanup-region'"
1855 " to cleanup a region.\n\n"))
1856 (whitespace-display-window (current-buffer)))))
1857 has-bogus))))
1858
1859 \f
1860 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1861 ;;;; Internal functions
1862
1863
1864 (defvar whitespace-font-lock-mode nil
1865 "Used to remember whether a buffer had font lock mode on or not.")
1866
1867 (defvar whitespace-font-lock nil
1868 "Used to remember whether a buffer initially had font lock on or not.")
1869
1870 (defvar whitespace-font-lock-keywords nil
1871 "Used to save locally `font-lock-keywords' value.")
1872
1873
1874 (defconst whitespace-help-text
1875 "\
1876 Whitespace Toggle Options
1877
1878 FACES
1879 [] t - toggle TAB visualization
1880 [] s - toggle SPACE and HARD SPACE visualization
1881 [] r - toggle trailing blanks visualization
1882 [] l - toggle \"long lines\" visualization
1883 [] L - toggle \"long lines\" tail visualization
1884 [] n - toggle NEWLINE visualization
1885 [] e - toggle empty line at bob and/or eob visualization
1886 [] C-i - toggle indentation SPACEs visualization (via `indent-tabs-mode')
1887 [] I - toggle indentation SPACEs visualization
1888 [] i - toggle indentation TABs visualization
1889 [] C-a - toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1890 [] A - toggle SPACEs after TAB: SPACEs visualization
1891 [] a - toggle SPACEs after TAB: TABs visualization
1892 [] C-b - toggle SPACEs before TAB visualization (via `indent-tabs-mode')
1893 [] B - toggle SPACEs before TAB: SPACEs visualization
1894 [] b - toggle SPACEs before TAB: TABs visualization
1895
1896 DISPLAY TABLE
1897 [] T - toggle TAB visualization
1898 [] S - toggle SPACE and HARD SPACE visualization
1899 [] N - toggle NEWLINE visualization
1900
1901 x - restore `whitespace-style' value
1902
1903 ? - display this text\n\n"
1904 "Text for whitespace toggle options.")
1905
1906
1907 (defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1908 "The buffer name for whitespace toggle options.")
1909
1910
1911 (defun whitespace-insert-value (value)
1912 "Insert VALUE at column 20 of next line."
1913 (forward-line 1)
1914 (move-to-column 20 t)
1915 (insert (format "%s" value)))
1916
1917
1918 (defun whitespace-mark-x (nchars condition)
1919 "Insert the mark ('X' or ' ') after NCHARS depending on CONDITION."
1920 (forward-char nchars)
1921 (insert (if condition "X" " ")))
1922
1923
1924 (defun whitespace-insert-option-mark (the-list the-value)
1925 "Insert the option mark ('X' or ' ') in toggle options buffer."
1926 (goto-char (point-min))
1927 (forward-line 2)
1928 (dolist (sym the-list)
1929 (if (eq sym 'help-newline)
1930 (forward-line 2)
1931 (forward-line 1)
1932 (whitespace-mark-x 2 (memq sym the-value)))))
1933
1934
1935 (defun whitespace-help-on (style)
1936 "Display the whitespace toggle options."
1937 (unless (get-buffer whitespace-help-buffer-name)
1938 (delete-other-windows)
1939 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
1940 (save-excursion
1941 (set-buffer buffer)
1942 (erase-buffer)
1943 (insert whitespace-help-text)
1944 (whitespace-insert-option-mark
1945 whitespace-style-value-list style)
1946 (whitespace-display-window buffer)))))
1947
1948
1949 (defun whitespace-display-window (buffer)
1950 "Display BUFFER in a new window."
1951 (goto-char (point-min))
1952 (set-buffer-modified-p nil)
1953 (let ((size (- (window-height)
1954 (max window-min-height
1955 (1+ (count-lines (point-min)
1956 (point-max)))))))
1957 (when (<= size 0)
1958 (kill-buffer buffer)
1959 (error "Frame height is too small; \
1960 can't split window to display whitespace toggle options"))
1961 (set-window-buffer (split-window nil size) buffer)))
1962
1963
1964 (defun whitespace-kill-buffer (buffer-name)
1965 "Kill buffer BUFFER-NAME and windows related with it."
1966 (let ((buffer (get-buffer buffer-name)))
1967 (when buffer
1968 (delete-windows-on buffer)
1969 (kill-buffer buffer))))
1970
1971
1972 (defun whitespace-help-off ()
1973 "Remove the buffer and window of the whitespace toggle options."
1974 (whitespace-kill-buffer whitespace-help-buffer-name))
1975
1976
1977 (defun whitespace-interactive-char (local-p)
1978 "Interactive function to read a char and return a symbol.
1979
1980 If LOCAL-P is non-nil, it uses a local context; otherwise, it
1981 uses a global context.
1982
1983 It accepts one of the following chars:
1984
1985 CHAR MEANING
1986 (VIA FACES)
1987 t toggle TAB visualization
1988 s toggle SPACE and HARD SPACE visualization
1989 r toggle trailing blanks visualization
1990 l toggle \"long lines\" visualization
1991 L toggle \"long lines\" tail visualization
1992 n toggle NEWLINE visualization
1993 e toggle empty line at bob and/or eob visualization
1994 C-i toggle indentation SPACEs visualization (via `indent-tabs-mode')
1995 I toggle indentation SPACEs visualization
1996 i toggle indentation TABs visualization
1997 C-a toggle SPACEs after TAB visualization (via `indent-tabs-mode')
1998 A toggle SPACEs after TAB: SPACEs visualization
1999 a toggle SPACEs after TAB: TABs visualization
2000 C-b toggle SPACEs before TAB visualization (via `indent-tabs-mode')
2001 B toggle SPACEs before TAB: SPACEs visualization
2002 b toggle SPACEs before TAB: TABs visualization
2003
2004 (VIA DISPLAY TABLE)
2005 T toggle TAB visualization
2006 S toggle SPACE and HARD SPACE visualization
2007 N toggle NEWLINE visualization
2008
2009 x restore `whitespace-style' value
2010 ? display brief help
2011
2012 See also `whitespace-toggle-option-alist'."
2013 (let* ((is-off (not (if local-p
2014 whitespace-mode
2015 global-whitespace-mode)))
2016 (style (cond (is-off whitespace-style) ; use default value
2017 (local-p whitespace-active-style)
2018 (t whitespace-toggle-style)))
2019 (prompt
2020 (format "Whitespace Toggle %s (type ? for further options)-"
2021 (if local-p "Local" "Global")))
2022 ch sym)
2023 ;; read a valid option and get the corresponding symbol
2024 (save-window-excursion
2025 (condition-case data
2026 (progn
2027 (while
2028 ;; while condition
2029 (progn
2030 (setq ch (read-char prompt))
2031 (not
2032 (setq sym
2033 (cdr
2034 (assq ch whitespace-toggle-option-alist)))))
2035 ;; while body
2036 (if (eq ch ?\?)
2037 (whitespace-help-on style)
2038 (ding)))
2039 (whitespace-help-off)
2040 (message " ")) ; clean echo area
2041 ;; handler
2042 ((quit error)
2043 (whitespace-help-off)
2044 (error (error-message-string data)))))
2045 (list sym))) ; return the apropriate symbol
2046
2047
2048 (defun whitespace-toggle-list (local-p arg the-list)
2049 "Toggle options in THE-LIST based on list ARG.
2050
2051 If LOCAL-P is non-nil, it uses a local context; otherwise, it
2052 uses a global context.
2053
2054 ARG is a list of options to be toggled.
2055
2056 THE-LIST is a list of options. This list will be toggled and the
2057 resultant list will be returned."
2058 (unless (if local-p whitespace-mode global-whitespace-mode)
2059 (setq the-list whitespace-style))
2060 (setq the-list (copy-sequence the-list)) ; keep original list
2061 (dolist (sym (if (listp arg) arg (list arg)))
2062 (cond
2063 ;; ignore help value
2064 ((eq sym 'help-newline))
2065 ;; restore default values
2066 ((eq sym 'whitespace-style)
2067 (setq the-list whitespace-style))
2068 ;; toggle valid values
2069 ((memq sym whitespace-style-value-list)
2070 (setq the-list (if (memq sym the-list)
2071 (delq sym the-list)
2072 (cons sym the-list))))))
2073 the-list)
2074
2075
2076 (defvar whitespace-display-table nil
2077 "Used to save a local display table.")
2078
2079 (defvar whitespace-display-table-was-local nil
2080 "Used to remember whether a buffer initially had a local display table.")
2081
2082
2083 (defun whitespace-turn-on ()
2084 "Turn on whitespace visualization."
2085 ;; prepare local hooks
2086 (add-hook 'write-file-functions 'whitespace-write-file-hook nil t)
2087 ;; create whitespace local buffer environment
2088 (set (make-local-variable 'whitespace-font-lock-mode) nil)
2089 (set (make-local-variable 'whitespace-font-lock) nil)
2090 (set (make-local-variable 'whitespace-font-lock-keywords) nil)
2091 (set (make-local-variable 'whitespace-display-table) nil)
2092 (set (make-local-variable 'whitespace-display-table-was-local) nil)
2093 (set (make-local-variable 'whitespace-active-style)
2094 (if (listp whitespace-style)
2095 whitespace-style
2096 (list whitespace-style)))
2097 (set (make-local-variable 'whitespace-indent-tabs-mode)
2098 indent-tabs-mode)
2099 (set (make-local-variable 'whitespace-tab-width)
2100 tab-width)
2101 ;; turn on whitespace
2102 (when whitespace-active-style
2103 (whitespace-color-on)
2104 (whitespace-display-char-on)))
2105
2106
2107 (defun whitespace-turn-off ()
2108 "Turn off whitespace visualization."
2109 (remove-hook 'write-file-functions 'whitespace-write-file-hook t)
2110 (when whitespace-active-style
2111 (whitespace-color-off)
2112 (whitespace-display-char-off)))
2113
2114
2115 (defun whitespace-style-face-p ()
2116 "Return t if there is some visualization via face."
2117 (or (memq 'tabs whitespace-active-style)
2118 (memq 'spaces whitespace-active-style)
2119 (memq 'trailing whitespace-active-style)
2120 (memq 'lines whitespace-active-style)
2121 (memq 'lines-tail whitespace-active-style)
2122 (memq 'newline whitespace-active-style)
2123 (memq 'empty whitespace-active-style)
2124 (memq 'indentation whitespace-active-style)
2125 (memq 'indentation::tab whitespace-active-style)
2126 (memq 'indentation::space whitespace-active-style)
2127 (memq 'space-after-tab whitespace-active-style)
2128 (memq 'space-after-tab::tab whitespace-active-style)
2129 (memq 'space-after-tab::space whitespace-active-style)
2130 (memq 'space-before-tab whitespace-active-style)
2131 (memq 'space-before-tab::tab whitespace-active-style)
2132 (memq 'space-before-tab::space whitespace-active-style)))
2133
2134
2135 (defun whitespace-color-on ()
2136 "Turn on color visualization."
2137 (when (whitespace-style-face-p)
2138 (unless whitespace-font-lock
2139 (setq whitespace-font-lock t
2140 whitespace-font-lock-keywords
2141 (copy-sequence font-lock-keywords)))
2142 ;; turn off font lock
2143 (set (make-local-variable 'whitespace-font-lock-mode)
2144 font-lock-mode)
2145 (font-lock-mode 0)
2146 ;; add whitespace-mode color into font lock
2147 (when (memq 'spaces whitespace-active-style)
2148 (font-lock-add-keywords
2149 nil
2150 (list
2151 ;; Show SPACEs
2152 (list whitespace-space-regexp 1 whitespace-space t)
2153 ;; Show HARD SPACEs
2154 (list whitespace-hspace-regexp 1 whitespace-hspace t))
2155 t))
2156 (when (memq 'tabs whitespace-active-style)
2157 (font-lock-add-keywords
2158 nil
2159 (list
2160 ;; Show TABs
2161 (list whitespace-tab-regexp 1 whitespace-tab t))
2162 t))
2163 (when (memq 'trailing whitespace-active-style)
2164 (font-lock-add-keywords
2165 nil
2166 (list
2167 ;; Show trailing blanks
2168 (list whitespace-trailing-regexp 1 whitespace-trailing t))
2169 t))
2170 (when (or (memq 'lines whitespace-active-style)
2171 (memq 'lines-tail whitespace-active-style))
2172 (font-lock-add-keywords
2173 nil
2174 (list
2175 ;; Show "long" lines
2176 (list
2177 (format
2178 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
2179 whitespace-tab-width (1- whitespace-tab-width)
2180 (/ whitespace-line-column tab-width)
2181 (let ((rem (% whitespace-line-column whitespace-tab-width)))
2182 (if (zerop rem)
2183 ""
2184 (format ".\\{%d\\}" rem))))
2185 (if (memq 'lines whitespace-active-style)
2186 0 ; whole line
2187 2) ; line tail
2188 whitespace-line t))
2189 t))
2190 (cond
2191 ((memq 'space-before-tab whitespace-active-style)
2192 (font-lock-add-keywords
2193 nil
2194 (list
2195 ;; Show SPACEs before TAB (indent-tabs-mode)
2196 (list whitespace-space-before-tab-regexp
2197 (if whitespace-indent-tabs-mode 1 2)
2198 whitespace-space-before-tab t))
2199 t))
2200 ((memq 'space-before-tab::tab whitespace-active-style)
2201 (font-lock-add-keywords
2202 nil
2203 (list
2204 ;; Show SPACEs before TAB (SPACEs)
2205 (list whitespace-space-before-tab-regexp
2206 1 whitespace-space-before-tab t))
2207 t))
2208 ((memq 'space-before-tab::space whitespace-active-style)
2209 (font-lock-add-keywords
2210 nil
2211 (list
2212 ;; Show SPACEs before TAB (TABs)
2213 (list whitespace-space-before-tab-regexp
2214 2 whitespace-space-before-tab t))
2215 t)))
2216 (cond
2217 ((memq 'indentation whitespace-active-style)
2218 (font-lock-add-keywords
2219 nil
2220 (list
2221 ;; Show indentation SPACEs (indent-tabs-mode)
2222 (list (whitespace-indentation-regexp)
2223 1 whitespace-indentation t))
2224 t))
2225 ((memq 'indentation::tab whitespace-active-style)
2226 (font-lock-add-keywords
2227 nil
2228 (list
2229 ;; Show indentation SPACEs (SPACEs)
2230 (list (whitespace-indentation-regexp 'tab)
2231 1 whitespace-indentation t))
2232 t))
2233 ((memq 'indentation::space whitespace-active-style)
2234 (font-lock-add-keywords
2235 nil
2236 (list
2237 ;; Show indentation SPACEs (TABs)
2238 (list (whitespace-indentation-regexp 'space)
2239 1 whitespace-indentation t))
2240 t)))
2241 (when (memq 'empty whitespace-active-style)
2242 (font-lock-add-keywords
2243 nil
2244 (list
2245 ;; Show empty lines at beginning of buffer
2246 (list whitespace-empty-at-bob-regexp
2247 1 whitespace-empty t))
2248 t)
2249 (font-lock-add-keywords
2250 nil
2251 (list
2252 ;; Show empty lines at end of buffer
2253 (list whitespace-empty-at-eob-regexp
2254 1 whitespace-empty t))
2255 t))
2256 (cond
2257 ((memq 'space-after-tab whitespace-active-style)
2258 (font-lock-add-keywords
2259 nil
2260 (list
2261 ;; Show SPACEs after TAB (indent-tabs-mode)
2262 (list (whitespace-space-after-tab-regexp)
2263 1 whitespace-space-after-tab t))
2264 t))
2265 ((memq 'space-after-tab::tab whitespace-active-style)
2266 (font-lock-add-keywords
2267 nil
2268 (list
2269 ;; Show SPACEs after TAB (SPACEs)
2270 (list (whitespace-space-after-tab-regexp 'tab)
2271 1 whitespace-space-after-tab t))
2272 t))
2273 ((memq 'space-after-tab::space whitespace-active-style)
2274 (font-lock-add-keywords
2275 nil
2276 (list
2277 ;; Show SPACEs after TAB (TABs)
2278 (list (whitespace-space-after-tab-regexp 'space)
2279 1 whitespace-space-after-tab t))
2280 t)))
2281 ;; now turn on font lock and highlight blanks
2282 (font-lock-mode 1)))
2283
2284
2285 (defun whitespace-color-off ()
2286 "Turn off color visualization."
2287 ;; turn off font lock
2288 (when (whitespace-style-face-p)
2289 (font-lock-mode 0)
2290 (when whitespace-font-lock
2291 (setq whitespace-font-lock nil
2292 font-lock-keywords whitespace-font-lock-keywords))
2293 ;; restore original font lock state
2294 (font-lock-mode whitespace-font-lock-mode)))
2295
2296 \f
2297 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2298 ;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
2299
2300
2301 (defun whitespace-style-mark-p ()
2302 "Return t if there is some visualization via display table."
2303 (or (memq 'tab-mark whitespace-active-style)
2304 (memq 'space-mark whitespace-active-style)
2305 (memq 'newline-mark whitespace-active-style)))
2306
2307
2308 (defsubst whitespace-char-valid-p (char)
2309 ;; This check should be improved!!!
2310 (or (< char 256)
2311 (characterp char)))
2312
2313
2314 (defun whitespace-display-vector-p (vec)
2315 "Return true if every character in vector VEC can be displayed."
2316 (let ((i (length vec)))
2317 (when (> i 0)
2318 (while (and (>= (setq i (1- i)) 0)
2319 (whitespace-char-valid-p (aref vec i))))
2320 (< i 0))))
2321
2322
2323 (defun whitespace-display-char-on ()
2324 "Turn on character display mapping."
2325 (when (and whitespace-display-mappings
2326 (whitespace-style-mark-p))
2327 (let (vecs vec)
2328 ;; Remember whether a buffer has a local display table.
2329 (unless whitespace-display-table-was-local
2330 (setq whitespace-display-table-was-local t
2331 whitespace-display-table
2332 (copy-sequence buffer-display-table)))
2333 (unless buffer-display-table
2334 (setq buffer-display-table (make-display-table)))
2335 (dolist (entry whitespace-display-mappings)
2336 ;; check if it is to display this mark
2337 (when (memq (car entry) whitespace-style)
2338 ;; Get a displayable mapping.
2339 (setq vecs (cddr entry))
2340 (while (and vecs
2341 (not (whitespace-display-vector-p (car vecs))))
2342 (setq vecs (cdr vecs)))
2343 ;; Display a valid mapping.
2344 (when vecs
2345 (setq vec (copy-sequence (car vecs)))
2346 ;; NEWLINE char
2347 (when (and (eq (cadr entry) ?\n)
2348 (memq 'newline whitespace-active-style))
2349 ;; Only insert face bits on NEWLINE char mapping to avoid
2350 ;; obstruction of other faces like TABs and (HARD) SPACEs
2351 ;; faces, font-lock faces, etc.
2352 (dotimes (i (length vec))
2353 (or (eq (aref vec i) ?\n)
2354 (aset vec i
2355 (make-glyph-code (aref vec i)
2356 whitespace-newline)))))
2357 ;; Display mapping
2358 (aset buffer-display-table (cadr entry) vec)))))))
2359
2360
2361 (defun whitespace-display-char-off ()
2362 "Turn off character display mapping."
2363 (and whitespace-display-mappings
2364 (whitespace-style-mark-p)
2365 whitespace-display-table-was-local
2366 (setq whitespace-display-table-was-local nil
2367 buffer-display-table whitespace-display-table)))
2368
2369 \f
2370 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2371 ;;;; Hook
2372
2373
2374 (defun whitespace-action-when-on ()
2375 "Action to be taken always when local whitespace is turned on."
2376 (cond ((memq 'cleanup whitespace-action)
2377 (whitespace-cleanup))
2378 ((memq 'report-on-bogus whitespace-action)
2379 (whitespace-report nil t))))
2380
2381
2382 (defun whitespace-write-file-hook ()
2383 "Action to be taken when buffer is written.
2384 It should be added buffer-locally to `write-file-functions'."
2385 (cond ((memq 'auto-cleanup whitespace-action)
2386 (whitespace-cleanup))
2387 ((memq 'abort-on-bogus whitespace-action)
2388 (when (whitespace-report nil t)
2389 (error "Abort write due to whitespace problems in %s"
2390 (buffer-name)))))
2391 nil) ; continue hook processing
2392
2393
2394 (defun whitespace-warn-read-only (msg)
2395 "Warn if buffer is read-only."
2396 (when (memq 'warn-if-read-only whitespace-action)
2397 (message "Can't %s: %s is read-only" msg (buffer-name))))
2398
2399 \f
2400 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2401
2402
2403 (defun whitespace-unload-function ()
2404 "Unload the whitespace library."
2405 (global-whitespace-mode -1)
2406 ;; be sure all local whitespace mode is turned off
2407 (save-current-buffer
2408 (dolist (buf (buffer-list))
2409 (set-buffer buf)
2410 (whitespace-mode -1)))
2411 nil) ; continue standard unloading
2412
2413
2414 (provide 'whitespace)
2415
2416
2417 (run-hooks 'whitespace-load-hook)
2418
2419
2420 ;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
2421 ;;; whitespace.el ends here