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