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