Use find-file-hook instead of find-file-hooks.
[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
596c0ee1 9;; Version: 9.2
30d0ade9
VJL
10;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
11
12;; This file is part of GNU Emacs.
13
14;; GNU Emacs is free software; you can redistribute it and/or modify
15;; it under the terms of the GNU General Public License as published
16;; by the Free Software Foundation; either version 3, or (at your
17;; option) any later version.
18
19;; GNU Emacs is distributed in the hope that it will be useful, but
20;; WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22;; General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
25;; along with GNU Emacs; see the file COPYING. If not, write to the
26;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27;; Boston, MA 02110-1301, USA.
28
29;;; Commentary:
30
31;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32;;
33;; Introduction
34;; ------------
35;;
040f578c 36;; This package is a minor mode to visualize blanks (TAB, (HARD) SPACE
30d0ade9
VJL
37;; and NEWLINE).
38;;
c9dff4e3 39;; whitespace uses two ways to visualize blanks: faces and display
30d0ade9
VJL
40;; table.
41;;
42;; * Faces are used to highlight the background with a color.
c9dff4e3 43;; whitespace uses font-lock to highlight blank characters.
30d0ade9
VJL
44;;
45;; * Display table changes the way a character is displayed, that is,
46;; it provides a visual mark for characters, for example, at the end
47;; of line (?\xB6), at SPACEs (?\xB7) and at TABs (?\xBB).
48;;
c9dff4e3
VJL
49;; The `whitespace-style' and `whitespace-chars' variables are used to
50;; select which way should be used to visualize blanks.
30d0ade9 51;;
c9dff4e3 52;; Note that when whitespace is turned on, whitespace saves the
30d0ade9 53;; font-lock state, that is, if font-lock is on or off. And
c9dff4e3
VJL
54;; whitespace restores the font-lock state when it is turned off. So,
55;; if whitespace is turned on and font-lock is off, whitespace also
30d0ade9 56;; turns on the font-lock to highlight blanks, but the font-lock will
c9dff4e3
VJL
57;; be turned off when whitespace is turned off. Thus, turn on
58;; font-lock before whitespace is on, if you want that font-lock
59;; continues on after whitespace is turned off.
30d0ade9 60;;
c9dff4e3 61;; When whitespace is on, it takes care of highlighting some special
30d0ade9
VJL
62;; characters over the default mechanism of `nobreak-char-display'
63;; (which see) and `show-trailing-whitespace' (which see).
64;;
c9dff4e3 65;; There are two ways of using whitespace: local and global.
30d0ade9 66;;
c9dff4e3 67;; * Local whitespace affects only the current buffer.
30d0ade9 68;;
c9dff4e3
VJL
69;; * Global whitespace affects all current and future buffers. That
70;; is, if you turn on global whitespace and then create a new
71;; buffer, the new buffer will also have whitespace on. The
72;; `whitespace-global-modes' variable controls which major-mode will
73;; be automagically turned on.
30d0ade9
VJL
74;;
75;; You can mix the local and global usage without any conflict. But
c9dff4e3
VJL
76;; local whitespace has priority over global whitespace. Whitespace
77;; mode is active in a buffer if you have enabled it in that buffer or
78;; if you have enabled it globally.
30d0ade9 79;;
c9dff4e3 80;; When global and local whitespace are on:
30d0ade9 81;;
c9dff4e3 82;; * if local whitespace is turned off, whitespace is turned off for
30d0ade9
VJL
83;; the current buffer only.
84;;
c9dff4e3
VJL
85;; * if global whitespace is turned off, whitespace continues on only
86;; in the buffers in which local whitespace is on.
30d0ade9 87;;
c9dff4e3 88;; To use whitespace, insert in your ~/.emacs:
30d0ade9 89;;
c9dff4e3 90;; (require 'whitespace-mode)
30d0ade9 91;;
c9dff4e3
VJL
92;; Or autoload at least one of the commands`whitespace-mode',
93;; `whitespace-toggle-options', `global-whitespace-mode' or
94;; `global-whitespace-toggle-options'. For example:
30d0ade9 95;;
c9dff4e3
VJL
96;; (autoload 'whitespace-mode "whitespace"
97;; "Toggle whitespace visualization." t)
98;; (autoload 'whitespace-toggle-options "whitespace"
99;; "Toggle local `whitespace-mode' options." t)
30d0ade9 100;;
c9dff4e3 101;; whitespace was inspired by:
30d0ade9 102;;
97a739d5
VJL
103;; whitespace.el Rajesh Vaidheeswarran <rv@gnu.org>
104;; Warn about and clean bogus whitespaces in the file
105;; (inspired the idea to warn and clean some blanks)
c9dff4e3
VJL
106;; This was the original `whitespace.el' which was replaced by
107;; `blank-mode.el'. And later `blank-mode.el' was renamed to
108;; `whitespace.el'.
97a739d5 109;;
30d0ade9
VJL
110;; show-whitespace-mode.el Aurelien Tisne <aurelien.tisne@free.fr>
111;; Simple mode to highlight whitespaces
112;; (inspired the idea to use font-lock)
113;;
114;; whitespace-mode.el Lawrence Mitchell <wence@gmx.li>
115;; Major mode for editing Whitespace
116;; (inspired the idea to use display table)
117;;
118;; visws.el Miles Bader <miles@gnu.org>
119;; Make whitespace visible
120;; (handle display table, his code was modified, but the main
121;; idea was kept)
122;;
123;;
c9dff4e3 124;; Using whitespace
30d0ade9
VJL
125;; ----------------
126;;
127;; There is no problem if you mix local and global minor mode usage.
128;;
c9dff4e3
VJL
129;; * LOCAL whitespace:
130;; + To toggle whitespace options locally, type:
30d0ade9 131;;
c9dff4e3 132;; M-x whitespace-toggle-options RET
30d0ade9 133;;
c9dff4e3 134;; + To activate whitespace locally, type:
30d0ade9 135;;
c9dff4e3 136;; C-u 1 M-x whitespace-mode RET
30d0ade9 137;;
c9dff4e3 138;; + To deactivate whitespace locally, type:
30d0ade9 139;;
c9dff4e3 140;; C-u 0 M-x whitespace-mode RET
30d0ade9 141;;
c9dff4e3 142;; + To toggle whitespace locally, type:
30d0ade9 143;;
c9dff4e3 144;; M-x whitespace-mode RET
30d0ade9 145;;
c9dff4e3
VJL
146;; * GLOBAL whitespace:
147;; + To toggle whitespace options globally, type:
30d0ade9 148;;
c9dff4e3 149;; M-x global-whitespace-toggle-options RET
30d0ade9 150;;
c9dff4e3 151;; + To activate whitespace globally, type:
30d0ade9 152;;
c9dff4e3 153;; C-u 1 M-x global-whitespace-mode RET
30d0ade9 154;;
c9dff4e3 155;; + To deactivate whitespace globally, type:
30d0ade9 156;;
c9dff4e3 157;; C-u 0 M-x global-whitespace-mode RET
30d0ade9 158;;
c9dff4e3 159;; + To toggle whitespace globally, type:
30d0ade9 160;;
c9dff4e3 161;; M-x global-whitespace-mode RET
30d0ade9 162;;
97a739d5
VJL
163;; There are also the following useful commands:
164;;
c9dff4e3 165;; `whitespace-cleanup'
97a739d5
VJL
166;; Cleanup some blank problems in all buffer or at region.
167;;
c9dff4e3 168;; `whitespace-cleanup-region'
97a739d5
VJL
169;; Cleanup some blank problems at region.
170;;
c9dff4e3
VJL
171;; `whitespace-buffer'
172;; Turn on `whitespace-mode' forcing some settings.
173;;
97a739d5
VJL
174;; The problems, which are cleaned up, are:
175;;
176;; 1. empty lines at beginning of buffer.
177;; 2. empty lines at end of buffer.
b502217b 178;; If `whitespace-chars' includes the value `empty', remove all
c9dff4e3 179;; empty lines at beginning and/or end of buffer.
97a739d5
VJL
180;;
181;; 3. 8 or more SPACEs at beginning of line.
4a4b61e2
VJL
182;; If `whitespace-chars' includes the value `indentation', replace
183;; 8 or more SPACEs at beginning of line by TABs.
97a739d5
VJL
184;;
185;; 4. SPACEs before TAB.
b502217b 186;; If `whitespace-chars' includes the value `space-before-tab',
c9dff4e3 187;; replace SPACEs by TABs.
97a739d5
VJL
188;;
189;; 5. SPACEs or TABs at end of line.
b502217b 190;; If `whitespace-chars' includes the value `trailing', remove all
97a739d5
VJL
191;; SPACEs or TABs at end of line."
192;;
193;; 6. 8 or more SPACEs after TAB.
b502217b 194;; If `whitespace-chars' includes the value `space-after-tab',
c9dff4e3 195;; replace SPACEs by TABs.
97a739d5 196;;
30d0ade9
VJL
197;;
198;; Hooks
199;; -----
200;;
c9dff4e3 201;; whitespace has the following hook variables:
30d0ade9 202;;
c9dff4e3
VJL
203;; `whitespace-mode-hook'
204;; It is evaluated always when whitespace is turned on locally.
30d0ade9 205;;
c9dff4e3
VJL
206;; `global-whitespace-mode-hook'
207;; It is evaluated always when whitespace is turned on globally.
30d0ade9 208;;
c9dff4e3
VJL
209;; `whitespace-load-hook'
210;; It is evaluated after whitespace package is loaded.
30d0ade9
VJL
211;;
212;;
213;; Options
214;; -------
215;;
c9dff4e3 216;; Below it's shown a brief description of whitespace options, please,
30d0ade9
VJL
217;; see the options declaration in the code for a long documentation.
218;;
c9dff4e3 219;; `whitespace-style' Specify the visualization style.
30d0ade9 220;;
c9dff4e3 221;; `whitespace-chars' Specify which kind of blank is
040f578c 222;; visualized.
30d0ade9 223;;
c9dff4e3 224;; `whitespace-space' Face used to visualize SPACE.
30d0ade9 225;;
c9dff4e3 226;; `whitespace-hspace' Face used to visualize HARD SPACE.
30d0ade9 227;;
c9dff4e3 228;; `whitespace-tab' Face used to visualize TAB.
30d0ade9 229;;
c9dff4e3 230;; `whitespace-newline' Face used to visualize NEWLINE char
30d0ade9
VJL
231;; mapping.
232;;
c9dff4e3 233;; `whitespace-trailing' Face used to visualize trailing
30d0ade9
VJL
234;; blanks.
235;;
c9dff4e3 236;; `whitespace-line' Face used to visualize "long" lines.
30d0ade9 237;;
c9dff4e3
VJL
238;; `whitespace-space-before-tab' Face used to visualize SPACEs
239;; before TAB.
30d0ade9 240;;
c9dff4e3 241;; `whitespace-indentation' Face used to visualize 8 or more
97a739d5
VJL
242;; SPACEs at beginning of line.
243;;
c9dff4e3 244;; `whitespace-empty' Face used to visualize empty lines at
97a739d5
VJL
245;; beginning and/or end of buffer.
246;;
c9dff4e3 247;; `whitespace-space-after-tab' Face used to visualize 8 or more
97a739d5
VJL
248;; SPACEs after TAB.
249;;
c9dff4e3 250;; `whitespace-space-regexp' Specify SPACE characters regexp.
30d0ade9 251;;
c9dff4e3 252;; `whitespace-hspace-regexp' Specify HARD SPACE characters regexp.
30d0ade9 253;;
c9dff4e3 254;; `whitespace-tab-regexp' Specify TAB characters regexp.
30d0ade9 255;;
c9dff4e3 256;; `whitespace-trailing-regexp' Specify trailing characters regexp.
30d0ade9 257;;
c9dff4e3 258;; `whitespace-space-before-tab-regexp' Specify SPACEs before TAB
30d0ade9
VJL
259;; regexp.
260;;
c9dff4e3
VJL
261;; `whitespace-indentation-regexp' Specify regexp for 8 or more
262;; SPACEs at beginning of line.
97a739d5 263;;
c9dff4e3
VJL
264;; `whitespace-empty-at-bob-regexp' Specify regexp for empty lines
265;; at beginning of buffer.
97a739d5 266;;
c9dff4e3
VJL
267;; `whitespace-empty-at-eob-regexp' Specify regexp for empty lines
268;; at end of buffer.
97a739d5 269;;
c9dff4e3 270;; `whitespace-space-after-tab-regexp' Specify regexp for 8 or more
97a739d5
VJL
271;; SPACEs after TAB.
272;;
c9dff4e3 273;; `whitespace-line-column' Specify column beyond which the line
30d0ade9
VJL
274;; is highlighted.
275;;
c9dff4e3
VJL
276;; `whitespace-display-mappings' Specify an alist of mappings
277;; for displaying characters.
30d0ade9 278;;
4a4b61e2
VJL
279;; `whitespace-global-modes' Modes for which global
280;; `whitespace-mode' is automagically
281;; turned on.
30d0ade9
VJL
282;;
283;;
284;; Acknowledgements
285;; ----------------
286;;
9f3b76d5
VJL
287;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
288;; lines tail. See EightyColumnRule (EmacsWiki).
289;;
30d0ade9
VJL
290;; Thanks to Juri Linkov <juri@jurta.org> for suggesting:
291;; * `define-minor-mode'.
c9dff4e3 292;; * `global-whitespace-*' name for global commands.
30d0ade9
VJL
293;;
294;; Thanks to Robert J. Chassell <bob@gnu.org> for doc fix and testing.
295;;
296;; Thanks to Drew Adams <drew.adams@oracle.com> for toggle commands
297;; suggestion.
298;;
299;; Thanks to Antti Kaihola <antti.kaihola@linux-aktivaattori.org> for
300;; helping to fix `find-file-hooks' reference.
301;;
302;; Thanks to Andreas Roehler <andreas.roehler@easy-emacs.de> for
303;; indicating defface byte-compilation warnings.
304;;
305;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight
9f3b76d5 306;; "long" lines. See EightyColumnRule (EmacsWiki).
30d0ade9
VJL
307;;
308;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
309;; newline character mapping.
310;;
311;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
c9dff4e3 312;; whitespace-mode.el on XEmacs.
30d0ade9
VJL
313;;
314;; Thanks to Miles Bader <miles@gnu.org> for handling display table via
315;; visws.el (his code was modified, but the main idea was kept).
316;;
317;; Thanks to:
c9dff4e3 318;; Rajesh Vaidheeswarran <rv@gnu.org> (original) whitespace.el
30d0ade9
VJL
319;; Aurelien Tisne <aurelien.tisne@free.fr> show-whitespace-mode.el
320;; Lawrence Mitchell <wence@gmx.li> whitespace-mode.el
321;; Miles Bader <miles@gnu.org> visws.el
322;; And to all people who contributed with them.
323;;
324;;
325;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
326
327;;; code:
328
329\f
330;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
331;;;; User Variables:
332
333
334;;; Interface to the command system
335
336
c9dff4e3 337(defgroup whitespace nil
040f578c 338 "Visualize blanks (TAB, (HARD) SPACE and NEWLINE)."
c9dff4e3 339 :link '(emacs-library-link :tag "Source Lisp File" "whitespace.el")
b502217b 340 :version "23.1"
30d0ade9
VJL
341 :group 'wp
342 :group 'data)
343
344
c9dff4e3 345(defcustom whitespace-style '(mark color)
040f578c 346 "*Specify the visualization style.
30d0ade9 347
b502217b 348It's a list containing some or all of the following values:
30d0ade9 349
040f578c 350 mark display mappings are visualized.
30d0ade9 351
040f578c 352 color faces are visualized.
30d0ade9
VJL
353
354Any other value is ignored.
355
040f578c 356If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
30d0ade9 357
c9dff4e3 358See also `whitespace-display-mappings' for documentation."
30d0ade9
VJL
359 :type '(repeat :tag "Style of Blank"
360 (choice :tag "Style of Blank"
361 (const :tag "Display Table" mark)
362 (const :tag "Faces" color)))
c9dff4e3 363 :group 'whitespace)
30d0ade9
VJL
364
365
c9dff4e3 366(defcustom whitespace-chars
97a739d5
VJL
367 '(tabs spaces trailing lines space-before-tab newline
368 indentation empty space-after-tab)
040f578c 369 "*Specify which kind of blank is visualized.
30d0ade9 370
b502217b 371It's a list containing some or all of the following values:
30d0ade9 372
040f578c 373 trailing trailing blanks are visualized.
30d0ade9 374
040f578c 375 tabs TABs are visualized.
30d0ade9 376
040f578c 377 spaces SPACEs and HARD SPACEs are visualized.
30d0ade9 378
9f3b76d5 379 lines lines whose have columns beyond
c9dff4e3 380 `whitespace-line-column' are highlighted.
9f3b76d5
VJL
381 Whole line is highlighted.
382 It has precedence over
383 `lines-tail' (see below).
384
385 lines-tail lines whose have columns beyond
c9dff4e3 386 `whitespace-line-column' are highlighted.
9f3b76d5 387 But only the part of line which goes
c9dff4e3 388 beyond `whitespace-line-column' column.
9f3b76d5 389 It has effect only if `lines' (see above)
c9dff4e3 390 is not present in `whitespace-chars'.
30d0ade9 391
040f578c 392 space-before-tab SPACEs before TAB are visualized.
30d0ade9 393
040f578c 394 newline NEWLINEs are visualized.
30d0ade9 395
97a739d5
VJL
396 indentation 8 or more SPACEs at beginning of line are
397 visualized.
398
399 empty empty lines at beginning and/or end of buffer
400 are visualized.
401
402 space-after-tab 8 or more SPACEs after a TAB are visualized.
403
040f578c 404Any other value is ignored.
30d0ade9 405
040f578c 406If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs.
30d0ade9 407
b502217b
JB
408Used when `whitespace-style' includes the value `color'.
409Used also when `whitespace-chars' includes `newline',
410and `whitespace-style' includes `mark'."
30d0ade9
VJL
411 :type '(repeat :tag "Kind of Blank"
412 (choice :tag "Kind of Blank"
413 (const :tag "Trailing TABs, SPACEs and HARD SPACEs"
414 trailing)
415 (const :tag "SPACEs and HARD SPACEs" spaces)
416 (const :tag "TABs" tabs)
417 (const :tag "Lines" lines)
418 (const :tag "SPACEs before TAB"
419 space-before-tab)
97a739d5
VJL
420 (const :tag "NEWLINEs" newline)
421 (const :tag "Indentation SPACEs" indentation)
422 (const :tag "Empty Lines At BOB And/Or EOB"
423 empty)
424 (const :tag "SPACEs after TAB"
425 space-after-tab)))
c9dff4e3 426 :group 'whitespace)
30d0ade9
VJL
427
428
c9dff4e3 429(defcustom whitespace-space 'whitespace-space
040f578c 430 "*Symbol face used to visualize SPACE.
30d0ade9 431
b502217b 432Used when `whitespace-style' includes the value `color'."
30d0ade9 433 :type 'face
c9dff4e3 434 :group 'whitespace)
30d0ade9
VJL
435
436
c9dff4e3 437(defface whitespace-space
30d0ade9
VJL
438 '((((class color) (background dark))
439 (:background "grey20" :foreground "aquamarine3"))
440 (((class color) (background light))
441 (:background "LightYellow" :foreground "aquamarine3"))
442 (t (:inverse-video t)))
040f578c 443 "Face used to visualize SPACE."
c9dff4e3 444 :group 'whitespace)
30d0ade9
VJL
445
446
c9dff4e3 447(defcustom whitespace-hspace 'whitespace-hspace
040f578c 448 "*Symbol face used to visualize HARD SPACE.
30d0ade9 449
b502217b 450Used when `whitespace-style' includes the value `color'."
30d0ade9 451 :type 'face
c9dff4e3 452 :group 'whitespace)
30d0ade9
VJL
453
454
c9dff4e3 455(defface whitespace-hspace ; 'nobreak-space
30d0ade9
VJL
456 '((((class color) (background dark))
457 (:background "grey24" :foreground "aquamarine3"))
458 (((class color) (background light))
459 (:background "LemonChiffon3" :foreground "aquamarine3"))
460 (t (:inverse-video t)))
040f578c 461 "Face used to visualize HARD SPACE."
c9dff4e3 462 :group 'whitespace)
30d0ade9
VJL
463
464
c9dff4e3 465(defcustom whitespace-tab 'whitespace-tab
040f578c 466 "*Symbol face used to visualize TAB.
30d0ade9 467
b502217b 468Used when `whitespace-style' includes the value `color'."
30d0ade9 469 :type 'face
c9dff4e3 470 :group 'whitespace)
30d0ade9
VJL
471
472
c9dff4e3 473(defface whitespace-tab
30d0ade9
VJL
474 '((((class color) (background dark))
475 (:background "grey22" :foreground "aquamarine3"))
476 (((class color) (background light))
477 (:background "beige" :foreground "aquamarine3"))
478 (t (:inverse-video t)))
040f578c 479 "Face used to visualize TAB."
c9dff4e3 480 :group 'whitespace)
30d0ade9
VJL
481
482
c9dff4e3 483(defcustom whitespace-newline 'whitespace-newline
040f578c 484 "*Symbol face used to visualize NEWLINE char mapping.
30d0ade9 485
c9dff4e3 486See `whitespace-display-mappings'.
30d0ade9 487
b502217b
JB
488Used when `whitespace-style' includes the values `mark'
489and `color', and `whitespace-chars' includes `newline'."
30d0ade9 490 :type 'face
c9dff4e3 491 :group 'whitespace)
30d0ade9
VJL
492
493
c9dff4e3 494(defface whitespace-newline
30d0ade9
VJL
495 '((((class color) (background dark))
496 (:background "grey26" :foreground "aquamarine3" :bold t))
497 (((class color) (background light))
498 (:background "linen" :foreground "aquamarine3" :bold t))
499 (t (:bold t :underline t)))
040f578c 500 "Face used to visualize NEWLINE char mapping.
30d0ade9 501
c9dff4e3
VJL
502See `whitespace-display-mappings'."
503 :group 'whitespace)
30d0ade9
VJL
504
505
c9dff4e3 506(defcustom whitespace-trailing 'whitespace-trailing
040f578c 507 "*Symbol face used to visualize traling blanks.
30d0ade9 508
b502217b 509Used when `whitespace-style' includes the value `color'."
30d0ade9 510 :type 'face
c9dff4e3 511 :group 'whitespace)
30d0ade9
VJL
512
513
c9dff4e3 514(defface whitespace-trailing ; 'trailing-whitespace
30d0ade9
VJL
515 '((((class mono)) (:inverse-video t :bold t :underline t))
516 (t (:background "red1" :foreground "yellow" :bold t)))
040f578c 517 "Face used to visualize trailing blanks."
c9dff4e3 518 :group 'whitespace)
30d0ade9
VJL
519
520
c9dff4e3 521(defcustom whitespace-line 'whitespace-line
040f578c 522 "*Symbol face used to visualize \"long\" lines.
30d0ade9 523
c9dff4e3 524See `whitespace-line-column'.
30d0ade9 525
b502217b 526Used when `whitespace-style' includes the value `color'."
30d0ade9 527 :type 'face
c9dff4e3 528 :group 'whitespace)
30d0ade9
VJL
529
530
c9dff4e3 531(defface whitespace-line
30d0ade9
VJL
532 '((((class mono)) (:inverse-video t :bold t :underline t))
533 (t (:background "gray20" :foreground "violet")))
040f578c 534 "Face used to visualize \"long\" lines.
30d0ade9 535
c9dff4e3
VJL
536See `whitespace-line-column'."
537 :group 'whitespace)
30d0ade9
VJL
538
539
c9dff4e3 540(defcustom whitespace-space-before-tab 'whitespace-space-before-tab
040f578c 541 "*Symbol face used to visualize SPACEs before TAB.
30d0ade9 542
b502217b 543Used when `whitespace-style' includes the value `color'."
30d0ade9 544 :type 'face
c9dff4e3 545 :group 'whitespace)
30d0ade9
VJL
546
547
c9dff4e3 548(defface whitespace-space-before-tab
30d0ade9
VJL
549 '((((class mono)) (:inverse-video t :bold t :underline t))
550 (t (:background "DarkOrange" :foreground "firebrick")))
040f578c 551 "Face used to visualize SPACEs before TAB."
c9dff4e3 552 :group 'whitespace)
30d0ade9
VJL
553
554
c9dff4e3 555(defcustom whitespace-indentation 'whitespace-indentation
97a739d5
VJL
556 "*Symbol face used to visualize 8 or more SPACEs at beginning of line.
557
b502217b 558Used when `whitespace-style' includes the value `color'."
97a739d5 559 :type 'face
c9dff4e3 560 :group 'whitespace)
97a739d5
VJL
561
562
c9dff4e3 563(defface whitespace-indentation
97a739d5
VJL
564 '((((class mono)) (:inverse-video t :bold t :underline t))
565 (t (:background "yellow" :foreground "firebrick")))
566 "Face used to visualize 8 or more SPACEs at beginning of line."
c9dff4e3 567 :group 'whitespace)
97a739d5
VJL
568
569
c9dff4e3 570(defcustom whitespace-empty 'whitespace-empty
97a739d5
VJL
571 "*Symbol face used to visualize empty lines at beginning and/or end of buffer.
572
b502217b 573Used when `whitespace-style' includes the value `color'."
97a739d5 574 :type 'face
c9dff4e3 575 :group 'whitespace)
97a739d5
VJL
576
577
c9dff4e3 578(defface whitespace-empty
97a739d5
VJL
579 '((((class mono)) (:inverse-video t :bold t :underline t))
580 (t (:background "yellow" :foreground "firebrick")))
581 "Face used to visualize empty lines at beginning and/or end of buffer."
c9dff4e3 582 :group 'whitespace)
97a739d5
VJL
583
584
c9dff4e3 585(defcustom whitespace-space-after-tab 'whitespace-space-after-tab
97a739d5
VJL
586 "*Symbol face used to visualize 8 or more SPACEs after TAB.
587
b502217b 588Used when `whitespace-style' includes the value `color'."
97a739d5 589 :type 'face
c9dff4e3 590 :group 'whitespace)
97a739d5
VJL
591
592
c9dff4e3 593(defface whitespace-space-after-tab
97a739d5
VJL
594 '((((class mono)) (:inverse-video t :bold t :underline t))
595 (t (:background "yellow" :foreground "firebrick")))
596 "Face used to visualize 8 or more SPACEs after TAB."
c9dff4e3 597 :group 'whitespace)
97a739d5
VJL
598
599
c9dff4e3 600(defcustom whitespace-hspace-regexp
30d0ade9
VJL
601 "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
602 "*Specify HARD SPACE characters regexp.
603
b502217b 604If you're using `mule' package, there may be other characters besides:
30d0ade9
VJL
605
606 \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
607
040f578c 608that should be considered HARD SPACE.
30d0ade9
VJL
609
610Here are some examples:
611
612 \"\\\\(^\\xA0+\\\\)\" \
040f578c 613visualize only leading HARD SPACEs.
30d0ade9 614 \"\\\\(\\xA0+$\\\\)\" \
040f578c 615visualize only trailing HARD SPACEs.
30d0ade9 616 \"\\\\(^\\xA0+\\\\|\\xA0+$\\\\)\" \
040f578c 617visualize leading and/or trailing HARD SPACEs.
30d0ade9 618 \"\\t\\\\(\\xA0+\\\\)\\t\" \
040f578c 619visualize only HARD SPACEs between TABs.
30d0ade9
VJL
620
621NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
622 Use exactly one pair of enclosing \\\\( and \\\\).
623
b502217b
JB
624Used when `whitespace-style' includes the value `color',
625and `whitespace-chars' includes `spaces'."
30d0ade9 626 :type '(regexp :tag "HARD SPACE Chars")
c9dff4e3 627 :group 'whitespace)
30d0ade9
VJL
628
629
c9dff4e3 630(defcustom whitespace-space-regexp "\\( +\\)"
30d0ade9
VJL
631 "*Specify SPACE characters regexp.
632
b502217b 633If you're using `mule' package, there may be other characters
040f578c 634besides \" \" that should be considered SPACE.
30d0ade9
VJL
635
636Here are some examples:
637
040f578c
VJL
638 \"\\\\(^ +\\\\)\" visualize only leading SPACEs.
639 \"\\\\( +$\\\\)\" visualize only trailing SPACEs.
30d0ade9 640 \"\\\\(^ +\\\\| +$\\\\)\" \
040f578c
VJL
641visualize leading and/or trailing SPACEs.
642 \"\\t\\\\( +\\\\)\\t\" visualize only SPACEs between TABs.
30d0ade9
VJL
643
644NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
645 Use exactly one pair of enclosing \\\\( and \\\\).
646
b502217b
JB
647Used when `whitespace-style' includes the value `color',
648and `whitespace-chars' includes `spaces'."
30d0ade9 649 :type '(regexp :tag "SPACE Chars")
c9dff4e3 650 :group 'whitespace)
30d0ade9
VJL
651
652
c9dff4e3 653(defcustom whitespace-tab-regexp "\\(\t+\\)"
30d0ade9
VJL
654 "*Specify TAB characters regexp.
655
b502217b 656If you're using `mule' package, there may be other characters
040f578c 657besides \"\\t\" that should be considered TAB.
30d0ade9
VJL
658
659Here are some examples:
660
040f578c
VJL
661 \"\\\\(^\\t+\\\\)\" visualize only leading TABs.
662 \"\\\\(\\t+$\\\\)\" visualize only trailing TABs.
30d0ade9 663 \"\\\\(^\\t+\\\\|\\t+$\\\\)\" \
040f578c
VJL
664visualize leading and/or trailing TABs.
665 \" \\\\(\\t+\\\\) \" visualize only TABs between SPACEs.
30d0ade9
VJL
666
667NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
668 Use exactly one pair of enclosing \\\\( and \\\\).
669
b502217b
JB
670Used when `whitespace-style' includes the value `color',
671and `whitespace-chars' includes `tabs'."
30d0ade9 672 :type '(regexp :tag "TAB Chars")
c9dff4e3 673 :group 'whitespace)
30d0ade9
VJL
674
675
c9dff4e3 676(defcustom whitespace-trailing-regexp
30d0ade9
VJL
677 "\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20"
678 "*Specify trailing characters regexp.
679
b502217b 680If you're using `mule' package, there may be other characters besides:
30d0ade9
VJL
681
682 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
683\"\\xF20\"
684
040f578c 685that should be considered blank.
30d0ade9 686
040f578c 687NOTE: DO NOT enclose by \\\\( and \\\\) the elements to highlight.
c9dff4e3 688 `whitespace-mode' surrounds this regexp by \"\\\\(\\\\(\" and
30d0ade9
VJL
689 \"\\\\)+\\\\)$\".
690
b502217b
JB
691Used when `whitespace-style' includes the value `color',
692and `whitespace-chars' includes `trailing'."
30d0ade9 693 :type '(regexp :tag "Trailing Chars")
c9dff4e3 694 :group 'whitespace)
30d0ade9
VJL
695
696
c9dff4e3 697(defcustom whitespace-space-before-tab-regexp "\\( +\\)\t"
30d0ade9
VJL
698 "*Specify SPACEs before TAB regexp.
699
b502217b 700If you're using `mule' package, there may be other characters besides:
30d0ade9
VJL
701
702 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
703\"\\xF20\"
704
040f578c 705that should be considered blank.
30d0ade9 706
b502217b
JB
707Used when `whitespace-style' includes the value `color',
708and `whitespace-chars' includes `space-before-tab'."
30d0ade9 709 :type '(regexp :tag "SPACEs Before TAB")
c9dff4e3 710 :group 'whitespace)
30d0ade9
VJL
711
712
c9dff4e3
VJL
713(defcustom whitespace-indentation-regexp
714 "^\t*\\(\\( \\{8\\}\\)+\\)[^\n\t]"
97a739d5
VJL
715 "*Specify regexp for 8 or more SPACEs at beginning of line.
716
b502217b 717If you're using `mule' package, there may be other characters besides:
97a739d5
VJL
718
719 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
720\"\\xF20\"
721
722that should be considered blank.
723
b502217b
JB
724Used when `whitespace-style' includes the value `color',
725and `whitespace-chars' includes `indentation'."
97a739d5 726 :type '(regexp :tag "Indentation SPACEs")
c9dff4e3 727 :group 'whitespace)
97a739d5
VJL
728
729
c9dff4e3 730(defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
97a739d5
VJL
731 "*Specify regexp for empty lines at beginning of buffer.
732
b502217b 733If you're using `mule' package, there may be other characters besides:
97a739d5
VJL
734
735 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
736\"\\xF20\"
737
738that should be considered blank.
739
b502217b
JB
740Used when `whitespace-style' includes the value `color',
741and `whitespace-chars' includes `empty'."
97a739d5 742 :type '(regexp :tag "Empty Lines At Beginning Of Buffer")
c9dff4e3 743 :group 'whitespace)
97a739d5
VJL
744
745
c9dff4e3 746(defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
97a739d5
VJL
747 "*Specify regexp for empty lines at end of buffer.
748
b502217b 749If you're using `mule' package, there may be other characters besides:
97a739d5
VJL
750
751 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
752\"\\xF20\"
753
754that should be considered blank.
755
b502217b
JB
756Used when `whitespace-style' includes the value `color',
757and `whitespace-chars' includes `empty'."
97a739d5 758 :type '(regexp :tag "Empty Lines At End Of Buffer")
c9dff4e3 759 :group 'whitespace)
97a739d5
VJL
760
761
c9dff4e3 762(defcustom whitespace-space-after-tab-regexp "\t\\(\\( \\{8\\}\\)+\\)"
97a739d5
VJL
763 "*Specify regexp for 8 or more SPACEs after TAB.
764
b502217b 765If you're using `mule' package, there may be other characters besides:
97a739d5
VJL
766
767 \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
768\"\\xF20\"
769
770that should be considered blank.
771
b502217b
JB
772Used when `whitespace-style' includes the value `color',
773and `whitespace-chars' includes `space-after-tab'."
97a739d5 774 :type '(regexp :tag "SPACEs After TAB")
c9dff4e3 775 :group 'whitespace)
97a739d5
VJL
776
777
c9dff4e3 778(defcustom whitespace-line-column 80
9f3b76d5 779 "*Specify column beyond which the line is highlighted.
30d0ade9 780
b502217b
JB
781Used when `whitespace-style' includes the value `color',
782and `whitespace-chars' includes `lines' or `lines-tail'."
30d0ade9 783 :type '(integer :tag "Line Length")
c9dff4e3 784 :group 'whitespace)
30d0ade9
VJL
785
786
787;; Hacked from `visible-whitespace-mappings' in visws.el
c9dff4e3 788(defcustom whitespace-display-mappings
30d0ade9
VJL
789 ;; Due to limitations of glyph representation, the char code can not
790 ;; be above ?\x1FFFF. Probably, this will be fixed after Emacs
791 ;; unicode merging.
792 '(
793 (?\ [?\xB7] [?.]) ; space - centered dot
794 (?\xA0 [?\xA4] [?_]) ; hard space - currency
795 (?\x8A0 [?\x8A4] [?_]) ; hard space - currency
796 (?\x920 [?\x924] [?_]) ; hard space - currency
797 (?\xE20 [?\xE24] [?_]) ; hard space - currency
798 (?\xF20 [?\xF24] [?_]) ; hard space - currency
c9dff4e3 799 ;; NEWLINE is displayed using the face `whitespace-newline'
30d0ade9
VJL
800 (?\n [?$ ?\n]) ; end-of-line - dollar sign
801 ;; (?\n [?\u21B5 ?\n] [?$ ?\n]) ; end-of-line - downwards arrow
802 ;; (?\n [?\xB6 ?\n] [?$ ?\n]) ; end-of-line - pilcrow
803 ;; (?\n [?\x8AF ?\n] [?$ ?\n]) ; end-of-line - overscore
804 ;; (?\n [?\x8AC ?\n] [?$ ?\n]) ; end-of-line - negation
805 ;; (?\n [?\x8B0 ?\n] [?$ ?\n]) ; end-of-line - grade
806 ;;
807 ;; WARNING: the mapping below has a problem.
808 ;; When a TAB occupies exactly one column, it will display the
809 ;; character ?\xBB at that column followed by a TAB which goes to
810 ;; the next TAB column.
811 ;; If this is a problem for you, please, comment the line below.
812 (?\t [?\xBB ?\t] [?\\ ?\t]) ; tab - left quote mark
813 )
814 "*Specify an alist of mappings for displaying characters.
815
816Each element has the following form:
817
818 (CHAR VECTOR...)
819
820Where:
821
822CHAR is the character to be mapped.
823
824VECTOR is a vector of characters to be displayed in place of CHAR.
825 The first display vector that can be displayed is used;
826 if no display vector for a mapping can be displayed, then
827 that character is displayed unmodified.
828
829The NEWLINE character is displayed using the face given by
c9dff4e3
VJL
830`whitespace-newline' variable. The characters in the vector to
831be displayed will not have this face applied if the character
832code is above #x1FFFF.
30d0ade9 833
b502217b 834Used when `whitespace-style' includes the value `mark'."
30d0ade9
VJL
835 :type '(repeat
836 (list :tag "Character Mapping"
837 (character :tag "Char")
838 (repeat :inline t :tag "Vector List"
839 (vector :tag ""
840 (repeat :inline t
841 :tag "Vector Characters"
842 (character :tag "Char"))))))
c9dff4e3 843 :group 'whitespace)
30d0ade9
VJL
844
845
c9dff4e3
VJL
846(defcustom whitespace-global-modes t
847 "*Modes for which global `whitespace-mode' is automagically turned on.
30d0ade9 848
c9dff4e3
VJL
849Global `whitespace-mode' is controlled by the command
850`global-whitespace-mode'.
30d0ade9 851
c9dff4e3 852If nil, means no modes have `whitespace-mode' automatically
30d0ade9 853turned on.
c9dff4e3
VJL
854
855If t, all modes that support `whitespace-mode' have it
856automatically turned on.
857
858Else it should be a list of `major-mode' symbol names for which
859`whitespace-mode' should be automatically turned on. The sense
30d0ade9
VJL
860of the list is negated if it begins with `not'. For example:
861
862 (c-mode c++-mode)
863
c9dff4e3
VJL
864means that `whitespace-mode' is turned on for buffers in C and
865C++ modes only."
97a739d5
VJL
866 :type '(choice (const :tag "None" nil)
867 (const :tag "All" t)
868 (set :menu-tag "Mode Specific" :tag "Modes"
30d0ade9
VJL
869 :value (not)
870 (const :tag "Except" not)
871 (repeat :inline t
97a739d5 872 (symbol :tag "Mode"))))
c9dff4e3 873 :group 'whitespace)
30d0ade9
VJL
874
875\f
876;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
877;;;; User commands - Local mode
878
879
880;;;###autoload
c9dff4e3
VJL
881(define-minor-mode whitespace-mode
882 "Toggle whitespace minor mode visualization (\"ws\" on modeline).
30d0ade9 883
c9dff4e3 884If ARG is null, toggle whitespace visualization.
040f578c
VJL
885If ARG is a number greater than zero, turn on visualization;
886otherwise, turn off visualization.
30d0ade9 887Only useful with a windowing system."
c9dff4e3 888 :lighter " ws"
30d0ade9
VJL
889 :init-value nil
890 :global nil
c9dff4e3 891 :group 'whitespace
30d0ade9
VJL
892 (cond
893 (noninteractive ; running a batch job
c9dff4e3
VJL
894 (setq whitespace-mode nil))
895 (whitespace-mode ; whitespace-mode on
896 (whitespace-turn-on))
897 (t ; whitespace-mode off
898 (whitespace-turn-off))))
30d0ade9
VJL
899
900\f
901;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
902;;;; User commands - Global mode
903
904
c9dff4e3
VJL
905(define-minor-mode global-whitespace-mode
906 "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
30d0ade9 907
c9dff4e3 908If ARG is null, toggle whitespace visualization.
040f578c
VJL
909If ARG is a number greater than zero, turn on visualization;
910otherwise, turn off visualization.
30d0ade9 911Only useful with a windowing system."
acaf02dd 912 :lighter " WS"
30d0ade9
VJL
913 :init-value nil
914 :global t
c9dff4e3 915 :group 'whitespace
30d0ade9
VJL
916 (cond
917 (noninteractive ; running a batch job
c9dff4e3
VJL
918 (setq global-whitespace-mode nil))
919 (global-whitespace-mode ; global-whitespace-mode on
30d0ade9 920 (save-excursion
4a4b61e2 921 (add-hook 'find-file-hook 'whitespace-turn-on-if-enabled t)
30d0ade9
VJL
922 (dolist (buffer (buffer-list)) ; adjust all local mode
923 (set-buffer buffer)
c9dff4e3
VJL
924 (unless whitespace-mode
925 (whitespace-turn-on-if-enabled)))))
926 (t ; global-whitespace-mode off
30d0ade9 927 (save-excursion
4a4b61e2 928 (remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
30d0ade9
VJL
929 (dolist (buffer (buffer-list)) ; adjust all local mode
930 (set-buffer buffer)
1e2b96c2
JB
931 (when (or (not whitespace-mode)
932 ;; whitespace is being unloaded
933 (bound-and-true-p unload-function-defs-list))
c9dff4e3 934 (whitespace-turn-off)))))))
30d0ade9
VJL
935
936
c9dff4e3 937(defun whitespace-turn-on-if-enabled ()
30d0ade9 938 (when (cond
c9dff4e3
VJL
939 ((eq whitespace-global-modes t))
940 ((listp whitespace-global-modes)
941 (if (eq (car-safe whitespace-global-modes) 'not)
942 (not (memq major-mode (cdr whitespace-global-modes)))
943 (memq major-mode whitespace-global-modes)))
30d0ade9
VJL
944 (t nil))
945 (let (inhibit-quit)
c9dff4e3 946 ;; Don't turn on whitespace mode if...
30d0ade9
VJL
947 (or
948 ;; ...we don't have a display (we're running a batch job)
949 noninteractive
950 ;; ...or if the buffer is invisible (name starts with a space)
951 (eq (aref (buffer-name) 0) ?\ )
952 ;; ...or if the buffer is temporary (name starts with *)
953 (and (eq (aref (buffer-name) 0) ?*)
954 ;; except the scratch buffer.
955 (not (string= (buffer-name) "*scratch*")))
c9dff4e3
VJL
956 ;; Otherwise, turn on whitespace mode.
957 (whitespace-turn-on)))))
30d0ade9
VJL
958
959\f
960;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
961;;;; User commands - Toggle
962
963
c9dff4e3 964(defconst whitespace-chars-value-list
30d0ade9
VJL
965 '(tabs
966 spaces
967 trailing
968 space-before-tab
969 lines
9f3b76d5 970 lines-tail
30d0ade9 971 newline
97a739d5
VJL
972 indentation
973 empty
974 space-after-tab
30d0ade9 975 )
c9dff4e3 976 "List of valid `whitespace-chars' values.")
30d0ade9
VJL
977
978
c9dff4e3 979(defconst whitespace-style-value-list
30d0ade9
VJL
980 '(color
981 mark
982 )
c9dff4e3 983 "List of valid `whitespace-style' values.")
30d0ade9
VJL
984
985
c9dff4e3 986(defconst whitespace-toggle-option-alist
30d0ade9
VJL
987 '((?t . tabs)
988 (?s . spaces)
989 (?r . trailing)
990 (?b . space-before-tab)
991 (?l . lines)
9f3b76d5 992 (?L . lines-tail)
30d0ade9 993 (?n . newline)
97a739d5
VJL
994 (?i . indentation)
995 (?e . empty)
996 (?a . space-after-tab)
30d0ade9
VJL
997 (?c . color)
998 (?m . mark)
c9dff4e3
VJL
999 (?x . whitespace-chars)
1000 (?z . whitespace-style)
30d0ade9
VJL
1001 )
1002 "Alist of toggle options.
1003
1004Each element has the form:
1005
1006 (CHAR . SYMBOL)
1007
1008Where:
1009
1010CHAR is a char which the user will have to type.
1011
1012SYMBOL is a valid symbol associated with CHAR.
c9dff4e3
VJL
1013 See `whitespace-chars-value-list' and
1014 `whitespace-style-value-list'.")
30d0ade9
VJL
1015
1016
c9dff4e3
VJL
1017(defvar whitespace-active-chars nil
1018 "Used to save locally `whitespace-chars' value.")
1019(make-variable-buffer-local 'whitespace-active-chars)
30d0ade9 1020
c9dff4e3
VJL
1021(defvar whitespace-active-style nil
1022 "Used to save locally `whitespace-style' value.")
1023(make-variable-buffer-local 'whitespace-active-style)
30d0ade9
VJL
1024
1025
1026;;;###autoload
c9dff4e3
VJL
1027(defun whitespace-toggle-options (arg)
1028 "Toggle local `whitespace-mode' options.
30d0ade9 1029
c9dff4e3
VJL
1030If local whitespace-mode is off, toggle the option given by ARG
1031and turn on local whitespace-mode.
30d0ade9 1032
c9dff4e3
VJL
1033If local whitespace-mode is on, toggle the option given by ARG
1034and restart local whitespace-mode.
30d0ade9
VJL
1035
1036Interactively, it reads one of the following chars:
1037
1038 CHAR MEANING
040f578c
VJL
1039 t toggle TAB visualization
1040 s toggle SPACE and HARD SPACE visualization
1041 r toggle trailing blanks visualization
1042 b toggle SPACEs before TAB visualization
1043 l toggle \"long lines\" visualization
9f3b76d5 1044 L toggle \"long lines\" tail visualization
040f578c 1045 n toggle NEWLINE visualization
97a739d5
VJL
1046 i toggle indentation SPACEs visualization
1047 e toggle empty line at bob and/or eob visualization
1048 a toggle SPACEs after TAB visualization
30d0ade9
VJL
1049 c toggle color faces
1050 m toggle visual mark
c9dff4e3
VJL
1051 x restore `whitespace-chars' value
1052 z restore `whitespace-style' value
30d0ade9
VJL
1053 ? display brief help
1054
040f578c 1055Non-interactively, ARG should be a symbol or a list of symbols.
30d0ade9
VJL
1056The valid symbols are:
1057
040f578c
VJL
1058 tabs toggle TAB visualization
1059 spaces toggle SPACE and HARD SPACE visualization
1060 trailing toggle trailing blanks visualization
1061 space-before-tab toggle SPACEs before TAB visualization
1062 lines toggle \"long lines\" visualization
9f3b76d5 1063 lines-tail toggle \"long lines\" tail visualization
040f578c 1064 newline toggle NEWLINE visualization
97a739d5
VJL
1065 indentation toggle indentation SPACEs visualization
1066 empty toggle empty line at bob and/or eob visualization
1067 space-after-tab toggle SPACEs after TAB visualization
30d0ade9
VJL
1068 color toggle color faces
1069 mark toggle visual mark
b502217b
JB
1070 whitespace-chars restore `whitespace-chars' value
1071 whitespace-style restore `whitespace-style' value
30d0ade9
VJL
1072
1073Only useful with a windowing system."
c9dff4e3
VJL
1074 (interactive (whitespace-interactive-char t))
1075 (let ((whitespace-chars
1076 (whitespace-toggle-list
1077 t arg whitespace-active-chars whitespace-chars
1078 'whitespace-chars whitespace-chars-value-list))
1079 (whitespace-style
1080 (whitespace-toggle-list
1081 t arg whitespace-active-style whitespace-style
1082 'whitespace-style whitespace-style-value-list)))
1083 (whitespace-mode 0)
1084 (whitespace-mode 1)))
30d0ade9
VJL
1085
1086
c9dff4e3
VJL
1087(defvar whitespace-toggle-chars nil
1088 "Used to toggle the global `whitespace-chars' value.")
1089(defvar whitespace-toggle-style nil
1090 "Used to toggle the global `whitespace-style' value.")
30d0ade9
VJL
1091
1092
1093;;;###autoload
c9dff4e3
VJL
1094(defun global-whitespace-toggle-options (arg)
1095 "Toggle global `whitespace-mode' options.
30d0ade9 1096
c9dff4e3
VJL
1097If global whitespace-mode is off, toggle the option given by ARG
1098and turn on global whitespace-mode.
30d0ade9 1099
c9dff4e3
VJL
1100If global whitespace-mode is on, toggle the option given by ARG
1101and restart global whitespace-mode.
30d0ade9 1102
b502217b 1103Interactively, it accepts one of the following chars:
30d0ade9
VJL
1104
1105 CHAR MEANING
040f578c
VJL
1106 t toggle TAB visualization
1107 s toggle SPACE and HARD SPACE visualization
1108 r toggle trailing blanks visualization
1109 b toggle SPACEs before TAB visualization
1110 l toggle \"long lines\" visualization
9f3b76d5 1111 L toggle \"long lines\" tail visualization
040f578c 1112 n toggle NEWLINE visualization
97a739d5
VJL
1113 i toggle indentation SPACEs visualization
1114 e toggle empty line at bob and/or eob visualization
1115 a toggle SPACEs after TAB visualization
30d0ade9
VJL
1116 c toggle color faces
1117 m toggle visual mark
c9dff4e3
VJL
1118 x restore `whitespace-chars' value
1119 z restore `whitespace-style' value
30d0ade9
VJL
1120 ? display brief help
1121
040f578c 1122Non-interactively, ARG should be a symbol or a list of symbols.
30d0ade9
VJL
1123The valid symbols are:
1124
040f578c
VJL
1125 tabs toggle TAB visualization
1126 spaces toggle SPACE and HARD SPACE visualization
1127 trailing toggle trailing blanks visualization
1128 space-before-tab toggle SPACEs before TAB visualization
1129 lines toggle \"long lines\" visualization
9f3b76d5 1130 lines-tail toggle \"long lines\" tail visualization
040f578c 1131 newline toggle NEWLINE visualization
97a739d5
VJL
1132 indentation toggle indentation SPACEs visualization
1133 empty toggle empty line at bob and/or eob visualization
1134 space-after-tab toggle SPACEs after TAB visualization
30d0ade9
VJL
1135 color toggle color faces
1136 mark toggle visual mark
4a4b61e2
VJL
1137 whitespace-chars restore `whitespace-chars' value
1138 whitespace-style restore `whitespace-style' value
30d0ade9
VJL
1139
1140Only useful with a windowing system."
c9dff4e3
VJL
1141 (interactive (whitespace-interactive-char nil))
1142 (let ((whitespace-chars
1143 (whitespace-toggle-list
1144 nil arg whitespace-toggle-chars whitespace-chars
1145 'whitespace-chars whitespace-chars-value-list))
1146 (whitespace-style
1147 (whitespace-toggle-list
1148 nil arg whitespace-toggle-style whitespace-style
1149 'whitespace-style whitespace-style-value-list)))
1150 (setq whitespace-toggle-chars whitespace-chars
1151 whitespace-toggle-style whitespace-style)
1152 (global-whitespace-mode 0)
1153 (global-whitespace-mode 1)))
30d0ade9
VJL
1154
1155\f
97a739d5
VJL
1156;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1157;;;; User commands - Cleanup
1158
1159
1160;;;###autoload
c9dff4e3 1161(defun whitespace-cleanup ()
97a739d5
VJL
1162 "Cleanup some blank problems in all buffer or at region.
1163
1164It usually applies to the whole buffer, but in transient mark
1165mode when the mark is active, it applies to the region. It also
1166applies to the region when it is not in transiente mark mode, the
b502217b 1167mark is active and \\[universal-argument] was pressed just before calling
c9dff4e3 1168`whitespace-cleanup' interactively.
97a739d5 1169
c9dff4e3 1170See also `whitespace-cleanup-region'.
97a739d5 1171
b502217b 1172The problems cleaned up are:
97a739d5
VJL
1173
11741. empty lines at beginning of buffer.
11752. empty lines at end of buffer.
b502217b 1176 If `whitespace-chars' includes the value `empty', remove all
c9dff4e3 1177 empty lines at beginning and/or end of buffer.
97a739d5
VJL
1178
11793. 8 or more SPACEs at beginning of line.
b502217b 1180 If `whitespace-chars' includes the value `indentation', replace
c9dff4e3 1181 8 or more SPACEs at beginning of line by TABs.
97a739d5
VJL
1182
11834. SPACEs before TAB.
b502217b 1184 If `whitespace-chars' includes the value `space-before-tab',
c9dff4e3 1185 replace SPACEs by TABs.
97a739d5
VJL
1186
11875. SPACEs or TABs at end of line.
b502217b 1188 If `whitespace-chars' includes the value `trailing', remove all
97a739d5
VJL
1189 SPACEs or TABs at end of line.
1190
11916. 8 or more SPACEs after TAB.
b502217b 1192 If `whitespace-chars' includes the value `space-after-tab',
c9dff4e3 1193 replace SPACEs by TABs."
97a739d5
VJL
1194 (interactive "@*")
1195 (if (and (or transient-mark-mode
1196 current-prefix-arg)
1197 mark-active)
1198 ;; region active
1199 ;; problems 1 and 2 are not handled in region
1200 ;; problem 3: 8 or more SPACEs at bol
1201 ;; problem 4: SPACEs before TAB
1202 ;; problem 5: SPACEs or TABs at eol
1203 ;; problem 6: 8 or more SPACEs after TAB
c9dff4e3 1204 (whitespace-cleanup-region (region-beginning) (region-end))
97a739d5
VJL
1205 ;; whole buffer
1206 (save-excursion
9f3b76d5
VJL
1207 (save-match-data
1208 ;; problem 1: empty lines at bob
1209 ;; problem 2: empty lines at eob
1210 ;; action: remove all empty lines at bob and/or eob
c9dff4e3 1211 (when (memq 'empty whitespace-chars)
9f3b76d5
VJL
1212 (let (overwrite-mode) ; enforce no overwrite
1213 (goto-char (point-min))
c9dff4e3
VJL
1214 (when (re-search-forward
1215 whitespace-empty-at-bob-regexp nil t)
9f3b76d5 1216 (delete-region (match-beginning 1) (match-end 1)))
c9dff4e3
VJL
1217 (when (re-search-forward
1218 whitespace-empty-at-eob-regexp nil t)
9f3b76d5
VJL
1219 (delete-region (match-beginning 1) (match-end 1)))))))
1220 ;; problem 3: 8 or more SPACEs at bol
1221 ;; problem 4: SPACEs before TAB
1222 ;; problem 5: SPACEs or TABs at eol
1223 ;; problem 6: 8 or more SPACEs after TAB
c9dff4e3 1224 (whitespace-cleanup-region (point-min) (point-max))))
97a739d5
VJL
1225
1226
1227;;;###autoload
c9dff4e3 1228(defun whitespace-cleanup-region (start end)
97a739d5
VJL
1229 "Cleanup some blank problems at region.
1230
b502217b 1231The problems cleaned up are:
97a739d5
VJL
1232
12331. 8 or more SPACEs at beginning of line.
b502217b 1234 If `whitespace-chars' includes the value `indentation', replace
c9dff4e3 1235 8 or more SPACEs at beginning of line by TABs.
97a739d5
VJL
1236
12372. SPACEs before TAB.
b502217b 1238 If `whitespace-chars' includes the value `space-before-tab',
c9dff4e3 1239 replace SPACEs by TABs.
97a739d5
VJL
1240
12413. SPACEs or TABs at end of line.
b502217b 1242 If `whitespace-chars' includes the value `trailing', remove all
97a739d5
VJL
1243 SPACEs or TABs at end of line.
1244
12454. 8 or more SPACEs after TAB.
b502217b 1246 If `whitespace-chars' includes the value `space-after-tab',
c9dff4e3 1247 replace SPACEs by TABs."
97a739d5
VJL
1248 (interactive "@*r")
1249 (let ((rstart (min start end))
1250 (rend (copy-marker (max start end)))
1251 (tab-width 8) ; assure TAB width
1252 (indent-tabs-mode t) ; always insert TABs
1253 overwrite-mode ; enforce no overwrite
1254 tmp)
1255 (save-excursion
9f3b76d5
VJL
1256 (save-match-data
1257 ;; problem 1: 8 or more SPACEs at bol
1258 ;; action: replace 8 or more SPACEs at bol by TABs
c9dff4e3 1259 (when (memq 'indentation whitespace-chars)
97a739d5 1260 (goto-char rstart)
c9dff4e3
VJL
1261 (while (re-search-forward
1262 whitespace-indentation-regexp rend t)
9f3b76d5
VJL
1263 (setq tmp (current-indentation))
1264 (delete-horizontal-space)
1265 (unless (eolp)
1266 (indent-to tmp))))
1267 ;; problem 3: SPACEs or TABs at eol
1268 ;; action: remove all SPACEs or TABs at eol
c9dff4e3
VJL
1269 (when (memq 'trailing whitespace-chars)
1270 (let ((regexp (concat "\\(\\(" whitespace-trailing-regexp
9f3b76d5
VJL
1271 "\\)+\\)$")))
1272 (goto-char rstart)
1273 (while (re-search-forward regexp rend t)
1274 (delete-region (match-beginning 1) (match-end 1)))))
1275 ;; problem 4: 8 or more SPACEs after TAB
1276 ;; action: replace 8 or more SPACEs by TABs
c9dff4e3
VJL
1277 (when (memq 'space-after-tab whitespace-chars)
1278 (whitespace-replace-spaces-by-tabs
1279 rstart rend whitespace-space-after-tab-regexp))
9f3b76d5
VJL
1280 ;; problem 2: SPACEs before TAB
1281 ;; action: replace SPACEs before TAB by TABs
c9dff4e3
VJL
1282 (when (memq 'space-before-tab whitespace-chars)
1283 (whitespace-replace-spaces-by-tabs
1284 rstart rend whitespace-space-before-tab-regexp))))
97a739d5
VJL
1285 (set-marker rend nil))) ; point marker to nowhere
1286
9f3b76d5 1287
c9dff4e3 1288(defun whitespace-replace-spaces-by-tabs (rstart rend regexp)
9f3b76d5
VJL
1289 "Replace all SPACEs by TABs matched by REGEXP between RSTART and REND."
1290 (goto-char rstart)
1291 (while (re-search-forward regexp rend t)
1292 (goto-char (match-beginning 1))
1293 (let* ((scol (current-column))
1294 (ecol (save-excursion
1295 (goto-char (match-end 1))
1296 (current-column))))
1297 (delete-region (match-beginning 1) (match-end 1))
1298 (insert-char ?\t
c9dff4e3
VJL
1299 (/ (- (- ecol (% ecol 8)) ; prev end col
1300 (- scol (% scol 8))) ; prev start col
9f3b76d5
VJL
1301 8)))))
1302
97a739d5 1303\f
c9dff4e3
VJL
1304;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1305;;;; User command - old whitespace compatibility
1306
1307
1308;;;###autoload
1309(defun whitespace-buffer ()
1310 "Turn on `whitespace-mode' forcing some settings.
1311
1312It forces `whitespace-style' to have `color'.
1313
1314It also forces `whitespace-chars' to have:
1315
1316 trailing
1317 indentation
1318 space-before-tab
1319 empty
1320 space-after-tab
1321
1322So, it is possible to visualize the following problems:
1323
1324 empty 1. empty lines at beginning of buffer.
1325 empty 2. empty lines at end of buffer.
1326 indentation 3. 8 or more SPACEs at beginning of line.
1327 space-before-tab 4. SPACEs before TAB.
1328 trailing 5. SPACEs or TABs at end of line.
1329 space-after-tab 6. 8 or more SPACEs after TAB.
1330
1331See `whitespace-chars' and `whitespace-style' for documentation.
1332See also `whitespace-cleanup' and `whitespace-cleanup-region' for
1333cleaning up these problems."
1334 (interactive)
1335 (whitespace-mode 0) ; assure is off
1336 ;; keep original values
1337 (let ((whitespace-style (copy-sequence whitespace-style))
1338 (whitespace-chars (copy-sequence whitespace-chars)))
1339 ;; adjust options for whitespace bogus blanks
1340 (add-to-list 'whitespace-style 'color)
1341 (mapc #'(lambda (option)
1342 (add-to-list 'whitespace-chars option))
1343 '(trailing
1344 indentation
1345 space-before-tab
1346 empty
1347 space-after-tab))
1348 (whitespace-mode 1))) ; turn on
1349
1350\f
30d0ade9
VJL
1351;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1352;;;; Internal functions
1353
1354
c9dff4e3 1355(defvar whitespace-font-lock-mode nil
30d0ade9 1356 "Used to remember whether a buffer had font lock mode on or not.")
c9dff4e3 1357(make-variable-buffer-local 'whitespace-font-lock-mode)
30d0ade9 1358
c9dff4e3 1359(defvar whitespace-font-lock nil
30d0ade9 1360 "Used to remember whether a buffer initially had font lock on or not.")
c9dff4e3 1361(make-variable-buffer-local 'whitespace-font-lock)
30d0ade9 1362
c9dff4e3 1363(defvar whitespace-font-lock-keywords nil
30d0ade9 1364 "Used to save locally `font-lock-keywords' value.")
c9dff4e3 1365(make-variable-buffer-local 'whitespace-font-lock-keywords)
30d0ade9
VJL
1366
1367
c9dff4e3 1368(defconst whitespace-help-text
30d0ade9 1369 "\
c9dff4e3 1370 whitespace-mode toggle options:
30d0ade9 1371
040f578c
VJL
1372 [] t - toggle TAB visualization
1373 [] s - toggle SPACE and HARD SPACE visualization
1374 [] r - toggle trailing blanks visualization
1375 [] b - toggle SPACEs before TAB visualization
1376 [] l - toggle \"long lines\" visualization
9f3b76d5 1377 [] L - toggle \"long lines\" tail visualization
040f578c 1378 [] n - toggle NEWLINE visualization
97a739d5
VJL
1379 [] i - toggle indentation SPACEs visualization
1380 [] e - toggle empty line at bob and/or eob visualization
1381 [] a - toggle SPACEs after TAB visualization
30d0ade9
VJL
1382
1383 [] c - toggle color faces
1384 [] m - toggle visual mark
1385
c9dff4e3
VJL
1386 x - restore `whitespace-chars' value
1387 z - restore `whitespace-style' value
30d0ade9
VJL
1388
1389 ? - display this text\n\n"
c9dff4e3 1390 "Text for whitespace toggle options.")
30d0ade9
VJL
1391
1392
c9dff4e3
VJL
1393(defconst whitespace-help-buffer-name "*Whitespace Toggle Options*"
1394 "The buffer name for whitespace toggle options.")
30d0ade9
VJL
1395
1396
c9dff4e3 1397(defun whitespace-insert-option-mark (the-list the-value)
30d0ade9
VJL
1398 "Insert the option mark ('X' or ' ') in toggle options buffer."
1399 (forward-line 1)
1400 (dolist (sym the-list)
1401 (forward-line 1)
1402 (forward-char 2)
1403 (insert (if (memq sym the-value) "X" " "))))
1404
1405
c9dff4e3
VJL
1406(defun whitespace-help-on (chars style)
1407 "Display the whitespace toggle options."
1408 (unless (get-buffer whitespace-help-buffer-name)
30d0ade9 1409 (delete-other-windows)
c9dff4e3 1410 (let ((buffer (get-buffer-create whitespace-help-buffer-name)))
30d0ade9
VJL
1411 (save-excursion
1412 (set-buffer buffer)
1413 (erase-buffer)
c9dff4e3 1414 (insert whitespace-help-text)
30d0ade9 1415 (goto-char (point-min))
c9dff4e3
VJL
1416 (whitespace-insert-option-mark
1417 whitespace-chars-value-list chars)
1418 (whitespace-insert-option-mark
1419 whitespace-style-value-list style)
30d0ade9
VJL
1420 (goto-char (point-min))
1421 (set-buffer-modified-p nil)
1422 (let ((size (- (window-height)
1423 (max window-min-height
c9dff4e3
VJL
1424 (1+ (count-lines (point-min)
1425 (point-max)))))))
30d0ade9
VJL
1426 (when (<= size 0)
1427 (kill-buffer buffer)
1428 (error "Frame height is too small; \
c9dff4e3 1429can't split window to display whitespace toggle options"))
30d0ade9
VJL
1430 (set-window-buffer (split-window nil size) buffer))))))
1431
1432
c9dff4e3
VJL
1433(defun whitespace-help-off ()
1434 "Remove the buffer and window of the whitespace toggle options."
1435 (let ((buffer (get-buffer whitespace-help-buffer-name)))
30d0ade9
VJL
1436 (when buffer
1437 (delete-windows-on buffer)
1438 (kill-buffer buffer))))
1439
1440
c9dff4e3 1441(defun whitespace-interactive-char (local-p)
30d0ade9
VJL
1442 "Interactive function to read a char and return a symbol.
1443
1444If LOCAL-P is non-nil, it uses a local context; otherwise, it
1445uses a global context.
1446
b502217b 1447It accepts one of the following chars:
30d0ade9
VJL
1448
1449 CHAR MEANING
040f578c
VJL
1450 t toggle TAB visualization
1451 s toggle SPACE and HARD SPACE visualization
1452 r toggle trailing blanks visualization
1453 b toggle SPACEs before TAB visualization
1454 l toggle \"long lines\" visualization
9f3b76d5 1455 L toggle \"long lines\" tail visualization
040f578c 1456 n toggle NEWLINE visualization
97a739d5
VJL
1457 i toggle indentation SPACEs visualization
1458 e toggle empty line at bob and/or eob visualization
1459 a toggle SPACEs after TAB visualization
30d0ade9
VJL
1460 c toggle color faces
1461 m toggle visual mark
c9dff4e3
VJL
1462 x restore `whitespace-chars' value
1463 z restore `whitespace-style' value
30d0ade9
VJL
1464 ? display brief help
1465
c9dff4e3
VJL
1466See also `whitespace-toggle-option-alist'."
1467 (let* ((is-off (not (if local-p
1468 whitespace-mode
1469 global-whitespace-mode)))
1470 (chars (cond (is-off whitespace-chars) ; use default value
1471 (local-p whitespace-active-chars)
1472 (t whitespace-toggle-chars)))
1473 (style (cond (is-off whitespace-style) ; use default value
1474 (local-p whitespace-active-style)
1475 (t whitespace-toggle-style)))
30d0ade9 1476 (prompt
c9dff4e3 1477 (format "Whitespace Toggle %s (type ? for further options)-"
30d0ade9
VJL
1478 (if local-p "Local" "Global")))
1479 ch sym)
1480 ;; read a valid option and get the corresponding symbol
1481 (save-window-excursion
1482 (condition-case data
1483 (progn
1484 (while
1485 ;; while condition
1486 (progn
1487 (setq ch (read-char prompt))
1488 (not
1489 (setq sym
c9dff4e3
VJL
1490 (cdr
1491 (assq ch whitespace-toggle-option-alist)))))
30d0ade9
VJL
1492 ;; while body
1493 (if (eq ch ?\?)
c9dff4e3 1494 (whitespace-help-on chars style)
30d0ade9 1495 (ding)))
c9dff4e3 1496 (whitespace-help-off)
30d0ade9
VJL
1497 (message " ")) ; clean echo area
1498 ;; handler
1499 ((quit error)
c9dff4e3 1500 (whitespace-help-off)
30d0ade9
VJL
1501 (error (error-message-string data)))))
1502 (list sym))) ; return the apropriate symbol
1503
1504
c9dff4e3
VJL
1505(defun whitespace-toggle-list (local-p arg the-list default-list
1506 sym-restore sym-list)
30d0ade9
VJL
1507 "Toggle options in THE-LIST based on list ARG.
1508
1509If LOCAL-P is non-nil, it uses a local context; otherwise, it
1510uses a global context.
1511
1512ARG is a list of options to be toggled.
1513
1514THE-LIST is a list of options. This list will be toggled and the
1515resultant list will be returned.
1516
1517DEFAULT-LIST is the default list of options. It is used to
1518restore the options in THE-LIST.
1519
1520SYM-RESTORE is the symbol which indicates to restore the options
1521in THE-LIST.
1522
1523SYM-LIST is a list of valid options, used to check if the ARG's
1524options are valid."
c9dff4e3 1525 (unless (if local-p whitespace-mode global-whitespace-mode)
30d0ade9
VJL
1526 (setq the-list default-list))
1527 (setq the-list (copy-sequence the-list)) ; keep original list
1528 (dolist (sym (if (listp arg) arg (list arg)))
1529 (cond
1530 ;; restore default values
1531 ((eq sym sym-restore)
1532 (setq the-list default-list))
1533 ;; toggle valid values
1534 ((memq sym sym-list)
1535 (setq the-list (if (memq sym the-list)
1536 (delq sym the-list)
1537 (cons sym the-list))))))
1538 the-list)
1539
1540
c9dff4e3
VJL
1541(defun whitespace-turn-on ()
1542 "Turn on whitespace visualization."
1543 (setq whitespace-active-style (if (listp whitespace-style)
1544 whitespace-style
1545 (list whitespace-style)))
1546 (setq whitespace-active-chars (if (listp whitespace-chars)
1547 whitespace-chars
1548 (list whitespace-chars)))
1549 (when (memq 'color whitespace-active-style)
1550 (whitespace-color-on))
1551 (when (memq 'mark whitespace-active-style)
1552 (whitespace-display-char-on)))
30d0ade9
VJL
1553
1554
c9dff4e3 1555(defun whitespace-turn-off ()
b502217b 1556 "Turn off whitespace visualization."
c9dff4e3
VJL
1557 (when (memq 'color whitespace-active-style)
1558 (whitespace-color-off))
1559 (when (memq 'mark whitespace-active-style)
1560 (whitespace-display-char-off)))
30d0ade9
VJL
1561
1562
c9dff4e3 1563(defun whitespace-color-on ()
040f578c 1564 "Turn on color visualization."
c9dff4e3
VJL
1565 (when whitespace-active-chars
1566 (unless whitespace-font-lock
1567 (setq whitespace-font-lock t
1568 whitespace-font-lock-keywords
30d0ade9
VJL
1569 (copy-sequence font-lock-keywords)))
1570 ;; turn off font lock
c9dff4e3 1571 (setq whitespace-font-lock-mode font-lock-mode)
30d0ade9 1572 (font-lock-mode 0)
c9dff4e3
VJL
1573 ;; add whitespace-mode color into font lock
1574 (when (memq 'spaces whitespace-active-chars)
30d0ade9
VJL
1575 (font-lock-add-keywords
1576 nil
1577 (list
1578 ;; Show SPACEs
c9dff4e3 1579 (list whitespace-space-regexp 1 whitespace-space t)
30d0ade9 1580 ;; Show HARD SPACEs
c9dff4e3 1581 (list whitespace-hspace-regexp 1 whitespace-hspace t))
30d0ade9 1582 t))
c9dff4e3 1583 (when (memq 'tabs whitespace-active-chars)
30d0ade9
VJL
1584 (font-lock-add-keywords
1585 nil
1586 (list
1587 ;; Show TABs
c9dff4e3 1588 (list whitespace-tab-regexp 1 whitespace-tab t))
30d0ade9 1589 t))
c9dff4e3 1590 (when (memq 'trailing whitespace-active-chars)
30d0ade9
VJL
1591 (font-lock-add-keywords
1592 nil
1593 (list
1594 ;; Show trailing blanks
c9dff4e3
VJL
1595 (list (concat "\\(\\(" whitespace-trailing-regexp "\\)+\\)$")
1596 1 whitespace-trailing t))
30d0ade9 1597 t))
c9dff4e3
VJL
1598 (when (or (memq 'lines whitespace-active-chars)
1599 (memq 'lines-tail whitespace-active-chars))
30d0ade9
VJL
1600 (font-lock-add-keywords
1601 nil
1602 (list
1603 ;; Show "long" lines
9f3b76d5
VJL
1604 (list
1605 (format
1606 "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
1607 tab-width (1- tab-width)
c9dff4e3
VJL
1608 (/ whitespace-line-column tab-width)
1609 (let ((rem (% whitespace-line-column tab-width)))
9f3b76d5
VJL
1610 (if (zerop rem)
1611 ""
1612 (format ".\\{%d\\}" rem))))
c9dff4e3 1613 (if (memq 'lines whitespace-active-chars)
9f3b76d5
VJL
1614 0 ; whole line
1615 2) ; line tail
c9dff4e3 1616 whitespace-line t))
30d0ade9 1617 t))
c9dff4e3 1618 (when (memq 'space-before-tab whitespace-active-chars)
30d0ade9
VJL
1619 (font-lock-add-keywords
1620 nil
1621 (list
1622 ;; Show SPACEs before TAB
c9dff4e3
VJL
1623 (list whitespace-space-before-tab-regexp
1624 1 whitespace-space-before-tab t))
30d0ade9 1625 t))
c9dff4e3 1626 (when (memq 'indentation whitespace-active-chars)
97a739d5
VJL
1627 (font-lock-add-keywords
1628 nil
1629 (list
1630 ;; Show indentation SPACEs
c9dff4e3
VJL
1631 (list whitespace-indentation-regexp
1632 1 whitespace-indentation t))
97a739d5 1633 t))
c9dff4e3 1634 (when (memq 'empty whitespace-active-chars)
97a739d5
VJL
1635 (font-lock-add-keywords
1636 nil
1637 (list
1638 ;; Show empty lines at beginning of buffer
c9dff4e3
VJL
1639 (list whitespace-empty-at-bob-regexp
1640 1 whitespace-empty t))
97a739d5
VJL
1641 t)
1642 (font-lock-add-keywords
1643 nil
1644 (list
1645 ;; Show empty lines at end of buffer
c9dff4e3
VJL
1646 (list whitespace-empty-at-eob-regexp
1647 1 whitespace-empty t))
97a739d5 1648 t))
c9dff4e3 1649 (when (memq 'space-after-tab whitespace-active-chars)
97a739d5
VJL
1650 (font-lock-add-keywords
1651 nil
1652 (list
1653 ;; Show SPACEs after TAB
c9dff4e3
VJL
1654 (list whitespace-space-after-tab-regexp
1655 1 whitespace-space-after-tab t))
97a739d5 1656 t))
30d0ade9
VJL
1657 ;; now turn on font lock and highlight blanks
1658 (font-lock-mode 1)))
1659
1660
c9dff4e3 1661(defun whitespace-color-off ()
040f578c 1662 "Turn off color visualization."
c9dff4e3 1663 (when whitespace-active-chars
040f578c
VJL
1664 ;; turn off font lock
1665 (font-lock-mode 0)
c9dff4e3
VJL
1666 (when whitespace-font-lock
1667 (setq whitespace-font-lock nil
1668 font-lock-keywords whitespace-font-lock-keywords))
30d0ade9 1669 ;; restore original font lock state
c9dff4e3 1670 (font-lock-mode whitespace-font-lock-mode)))
30d0ade9
VJL
1671
1672\f
1673;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1674;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
1675
1676
c9dff4e3 1677(defvar whitespace-display-table nil
30d0ade9 1678 "Used to save a local display table.")
c9dff4e3 1679(make-variable-buffer-local 'whitespace-display-table)
30d0ade9 1680
c9dff4e3
VJL
1681(defvar whitespace-display-table-was-local nil
1682 "Used to remember whether a buffer initially had a local display table.")
1683(make-variable-buffer-local 'whitespace-display-table-was-local)
30d0ade9
VJL
1684
1685
c9dff4e3 1686(defsubst whitespace-char-valid-p (char)
30d0ade9
VJL
1687 ;; This check should be improved!!!
1688 (or (< char 256)
1689 (char-valid-p char)))
1690
1691
c9dff4e3 1692(defun whitespace-display-vector-p (vec)
30d0ade9
VJL
1693 "Return true if every character in vector VEC can be displayed."
1694 (let ((i (length vec)))
1695 (when (> i 0)
1696 (while (and (>= (setq i (1- i)) 0)
c9dff4e3 1697 (whitespace-char-valid-p (aref vec i))))
30d0ade9
VJL
1698 (< i 0))))
1699
1700
c9dff4e3 1701(defun whitespace-display-char-on ()
30d0ade9 1702 "Turn on character display mapping."
c9dff4e3 1703 (when whitespace-display-mappings
30d0ade9
VJL
1704 (let (vecs vec)
1705 ;; Remember whether a buffer has a local display table.
c9dff4e3
VJL
1706 (unless whitespace-display-table-was-local
1707 (setq whitespace-display-table-was-local t
1708 whitespace-display-table
30d0ade9
VJL
1709 (copy-sequence buffer-display-table)))
1710 (unless buffer-display-table
1711 (setq buffer-display-table (make-display-table)))
c9dff4e3 1712 (dolist (entry whitespace-display-mappings)
30d0ade9
VJL
1713 (setq vecs (cdr entry))
1714 ;; Get a displayable mapping.
1715 (while (and vecs
c9dff4e3 1716 (not (whitespace-display-vector-p (car vecs))))
30d0ade9
VJL
1717 (setq vecs (cdr vecs)))
1718 ;; Display a valid mapping.
1719 (when vecs
1720 (setq vec (copy-sequence (car vecs)))
1721 (cond
1722 ;; Any char except newline
1723 ((not (eq (car entry) ?\n))
1724 (aset buffer-display-table (car entry) vec))
1725 ;; Newline char - display it
c9dff4e3 1726 ((memq 'newline whitespace-active-chars)
30d0ade9
VJL
1727 ;; Only insert face bits on NEWLINE char mapping to avoid
1728 ;; obstruction of other faces like TABs and (HARD) SPACEs
1729 ;; faces, font-lock faces, etc.
c9dff4e3 1730 (when (memq 'color whitespace-active-style)
30d0ade9
VJL
1731 (dotimes (i (length vec))
1732 ;; Due to limitations of glyph representation, the char
1733 ;; code can not be above ?\x1FFFF. Probably, this will
1734 ;; be fixed after Emacs unicode merging.
1735 (or (eq (aref vec i) ?\n)
1736 (> (aref vec i) #x1FFFF)
c9dff4e3
VJL
1737 (aset vec i
1738 (make-glyph-code (aref vec i)
1739 whitespace-newline)))))
30d0ade9
VJL
1740 ;; Display mapping
1741 (aset buffer-display-table (car entry) vec))
1742 ;; Newline char - don't display it
1743 (t
1744 ;; Do nothing
1745 )))))))
1746
1747
c9dff4e3 1748(defun whitespace-display-char-off ()
30d0ade9 1749 "Turn off character display mapping."
c9dff4e3
VJL
1750 (and whitespace-display-mappings
1751 whitespace-display-table-was-local
1752 (setq whitespace-display-table-was-local nil
1753 buffer-display-table whitespace-display-table)))
596c0ee1
VJL
1754
1755\f
30d0ade9
VJL
1756;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1757
1758
1e2b96c2
JB
1759(defun whitespace-unload-function ()
1760 "Unload the Whitespace library."
1761 (global-whitespace-mode -1)
1762 ;; continue standard unloading
1763 nil)
1764
c9dff4e3 1765(provide 'whitespace)
30d0ade9
VJL
1766
1767
c9dff4e3 1768(run-hooks 'whitespace-load-hook)
30d0ade9
VJL
1769
1770
17f6865b 1771;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
c9dff4e3 1772;;; whitespace.el ends here