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