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