;;; whitespace.el --- minor mode to visualize TAB, (HARD) SPACE, NEWLINE
-;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
;; Free Software Foundation, Inc.
;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br>
;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br>
;; Keywords: data, wp
-;; Version: 10.0
+;; Version: 13.1
;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published
-;; by the Free Software Foundation; either version 3, or (at your
-;; option) any later version.
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
-;; GNU Emacs is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-;; General Public License for more details.
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; it provides a visual mark for characters, for example, at the end
;; of line (?\xB6), at SPACEs (?\xB7) and at TABs (?\xBB).
;;
-;; The `whitespace-style-mark' and `whitespace-style-color' variables
-;; are used to select which way should be used to visualize blanks.
+;; The `whitespace-style' variable selects which way blanks are
+;; visualized.
;;
;; Note that when whitespace is turned on, whitespace saves the
;; font-lock state, that is, if font-lock is on or off. And
;; characters over the default mechanism of `nobreak-char-display'
;; (which see) and `show-trailing-whitespace' (which see).
;;
+;; The trailing spaces are not highlighted while point is at end of line.
+;; Also the spaces at beginning of buffer are not highlighted while point is at
+;; beginning of buffer; and the spaces at end of buffer are not highlighted
+;; while point is at end of buffer.
+;;
;; There are two ways of using whitespace: local and global.
;;
;; * Local whitespace affects only the current buffer.
;;
;; To use whitespace, insert in your ~/.emacs:
;;
-;; (require 'whitespace-mode)
+;; (require 'whitespace)
;;
;; Or autoload at least one of the commands`whitespace-mode',
;; `whitespace-toggle-options', `global-whitespace-mode' or
;;
;; There are also the following useful commands:
;;
+;; `whitespace-newline-mode'
+;; Toggle NEWLINE minor mode visualization ("nl" on modeline).
+;;
+;; `global-whitespace-newline-mode'
+;; Toggle NEWLINE global minor mode visualization ("NL" on modeline).
+;;
;; `whitespace-report'
;; Report some blank problems in buffer.
;;
;;
;; 1. empty lines at beginning of buffer.
;; 2. empty lines at end of buffer.
-;; If `whitespace-style-color' includes the value `empty', remove
-;; all empty lines at beginning and/or end of buffer.
+;; If `whitespace-style' includes the value `empty', remove all
+;; empty lines at beginning and/or end of buffer.
;;
;; 3. 8 or more SPACEs at beginning of line.
-;; If `whitespace-style-color' includes the value `indentation':
+;; If `whitespace-style' includes the value `indentation':
;; replace 8 or more SPACEs at beginning of line by TABs, if
;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
;; SPACEs.
-;; If `whitespace-style-color' includes the value
-;; `indentation::tab', replace 8 or more SPACEs at beginning of line
-;; by TABs.
-;; If `whitespace-style-color' includes the value
-;; `indentation::space', replace TABs by SPACEs.
+;; If `whitespace-style' includes the value `indentation::tab',
+;; replace 8 or more SPACEs at beginning of line by TABs.
+;; If `whitespace-style' includes the value `indentation::space',
+;; replace TABs by SPACEs.
;;
;; 4. SPACEs before TAB.
-;; If `whitespace-style-color' includes the value
-;; `space-before-tab': replace SPACEs by TABs, if
-;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
-;; SPACEs.
-;; If `whitespace-style-color' includes the value
+;; If `whitespace-style' includes the value `space-before-tab':
+;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
+;; otherwise, replace TABs by SPACEs.
+;; If `whitespace-style' includes the value
;; `space-before-tab::tab', replace SPACEs by TABs.
-;; If `whitespace-style-color' includes the value
+;; If `whitespace-style' includes the value
;; `space-before-tab::space', replace TABs by SPACEs.
;;
;; 5. SPACEs or TABs at end of line.
-;; If `whitespace-style-color' includes the value `trailing',
-;; remove all SPACEs or TABs at end of line.
+;; If `whitespace-style' includes the value `trailing', remove all
+;; SPACEs or TABs at end of line.
;;
;; 6. 8 or more SPACEs after TAB.
-;; If `whitespace-style-color' includes the value
-;; `space-after-tab': replace SPACEs by TABs, if `indent-tabs-mode'
-;; is non-nil; otherwise, replace TABs by SPACEs.
-;; If `whitespace-style-color' includes the value
-;; `space-after-tab::tab', replace SPACEs by TABs.
-;; If `whitespace-style-color' includes the value
+;; If `whitespace-style' includes the value `space-after-tab':
+;; replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
+;; otherwise, replace TABs by SPACEs.
+;; If `whitespace-style' includes the value `space-after-tab::tab',
+;; replace SPACEs by TABs.
+;; If `whitespace-style' includes the value
;; `space-after-tab::space', replace TABs by SPACEs.
;;
;;
;; Below it's shown a brief description of whitespace options, please,
;; see the options declaration in the code for a long documentation.
;;
-;; `whitespace-style-mark' Specify which kind of blank is
-;; visualized via display table.
-;;
-;; `whitespace-style-color' Specify which kind of blank is
-;; visualized via faces.
+;; `whitespace-style' Specify which kind of blank is
+;; visualized.
;;
;; `whitespace-space' Face used to visualize SPACE.
;;
;; turned on.
;;
;; `whitespace-action' Specify which action is taken when a
-;; buffer is visited, killed or written.
+;; buffer is visited or written.
;;
;;
;; Acknowledgements
;; ----------------
;;
+;; Thanks to David Reitter <david.reitter@gmail.com> for suggesting a
+;; `whitespace-newline' initialization with low contrast relative to
+;; the background color.
+;;
;; Thanks to Stephen Deasey <sdeasey@gmail.com> for the
;; `indent-tabs-mode' usage suggestion.
;;
;; Thanks to Eric Cooper <ecc@cmu.edu> for the suggestion to have hook
-;; actions when buffer is written or killed as the original whitespace
-;; package had.
+;; actions when buffer is written as the original whitespace package
+;; had.
;;
;; Thanks to nschum (EmacsWiki) for the idea about highlight "long"
;; lines tail. See EightyColumnRule (EmacsWiki).
;; "long" lines. See EightyColumnRule (EmacsWiki).
;;
;; Thanks to Yanghui Bian <yanghuibian@gmail.com> for indicating a new
-;; newline character mapping.
+;; NEWLINE character mapping.
;;
;; Thanks to Pete Forman <pete.forman@westgeo.com> for indicating
;; whitespace-mode.el on XEmacs.
"Visualize blanks (TAB, (HARD) SPACE and NEWLINE)."
:link '(emacs-library-link :tag "Source Lisp File" "whitespace.el")
:version "23.1"
- :group 'wp
- :group 'data)
+ :group 'convenience)
-(defcustom whitespace-style-mark '(space-mark tab-mark newline-mark)
- "*Specify which kind of blank is visualized via display table.
+(defcustom whitespace-style
+ '(face
+ tabs spaces trailing lines space-before-tab newline
+ indentation empty space-after-tab
+ space-mark tab-mark newline-mark)
+ "Specify which kind of blank is visualized.
It's a list containing some or all of the following values:
- space-mark SPACEs and HARD SPACEs are visualized.
-
- tab-mark TABs are visualized.
-
- newline-mark NEWLINEs are visualized.
-
-Any other value is ignored.
-
-If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs via display
-table.
-
-See also `whitespace-display-mappings' for documentation."
- :type '(repeat :tag "Kind of Blank Mark"
- (choice :tag "Kind of Blank Mark"
- (const :tag "SPACEs and HARD SPACEs"
- space-mark)
- (const :tag "TABs" tab-mark)
- (const :tag "NEWLINEs" newline-mark)))
- :group 'whitespace)
-
-
-(defcustom whitespace-style-color
- '(tabs spaces trailing lines space-before-tab newline
- indentation empty space-after-tab)
- "*Specify which kind of blank is visualized via faces.
-
-It's a list containing some or all of the following values:
+ face enable all visualization via faces (see below).
- trailing trailing blanks are visualized.
+ trailing trailing blanks are visualized via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
- tabs TABs are visualized.
+ tabs TABs are visualized via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
- spaces SPACEs and HARD SPACEs are visualized.
+ spaces SPACEs and HARD SPACEs are visualized via
+ faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
- lines lines whose have columns beyond
- `whitespace-line-column' are highlighted.
+ lines lines which have columns beyond
+ `whitespace-line-column' are highlighted via
+ faces.
Whole line is highlighted.
- It has precedence over
- `lines-tail' (see below).
-
- lines-tail lines whose have columns beyond
- `whitespace-line-column' are highlighted.
+ It has precedence over `lines-tail' (see
+ below).
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
+
+ lines-tail lines which have columns beyond
+ `whitespace-line-column' are highlighted via
+ faces.
But only the part of line which goes
beyond `whitespace-line-column' column.
It has effect only if `lines' (see above)
- is not present in `whitespace-style-color'.
+ is not present in `whitespace-style'
+ and if `face' (see above) is present in
+ `whitespace-style'.
- newline NEWLINEs are visualized.
+ newline NEWLINEs are visualized via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
empty empty lines at beginning and/or end of buffer
- are visualized.
+ are visualized via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
indentation::tab 8 or more SPACEs at beginning of line are
- visualized.
+ visualized via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
- indentation::space TABs at beginning of line are visualized.
+ indentation::space TABs at beginning of line are visualized via
+ faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
indentation 8 or more SPACEs at beginning of line are
visualized, if `indent-tabs-mode' (which see)
is non-nil; otherwise, TABs at beginning of
- line are visualized.
+ line are visualized via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
space-after-tab::tab 8 or more SPACEs after a TAB are
- visualized.
+ visualized via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
- space-after-tab::space TABs are visualized when occurs 8 or
- more SPACEs after a TAB.
+ space-after-tab::space TABs are visualized when 8 or more
+ SPACEs occur after a TAB, via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
space-after-tab 8 or more SPACEs after a TAB are
visualized, if `indent-tabs-mode'
(which see) is non-nil; otherwise,
- the TABs are visualized.
+ the TABs are visualized via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
- space-before-tab::tab SPACEs before TAB are visualized.
+ space-before-tab::tab SPACEs before TAB are visualized via
+ faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
- space-before-tab::space TABs are visualized when occurs SPACEs
- before TAB.
+ space-before-tab::space TABs are visualized when SPACEs occur
+ before TAB, via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
space-before-tab SPACEs before TAB are visualized, if
`indent-tabs-mode' (which see) is
non-nil; otherwise, the TABs are
- visualized.
+ visualized via faces.
+ It has effect only if `face' (see above)
+ is present in `whitespace-style'.
+
+ space-mark SPACEs and HARD SPACEs are visualized via
+ display table.
+
+ tab-mark TABs are visualized via display table.
+
+ newline-mark NEWLINEs are visualized via display table.
Any other value is ignored.
-If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs via faces.
+If nil, don't visualize TABs, (HARD) SPACEs and NEWLINEs via faces and
+via display table.
-There is an evaluation order for some values, if some values are
-included in `whitespace-style-color' list. For example, if
+There is an evaluation order for some values, if they are
+included in `whitespace-style' list. For example, if
indentation, indentation::tab and/or indentation::space are
-included in `whitespace-style-color' list. The evaluation order
-for these values is:
+included in `whitespace-style' list. The evaluation order for
+these values is:
* For indentation:
1. indentation
3. space-before-tab::space
So, for example, if indentation and indentation::space are
-included in `whitespace-style-color' list, the indentation value
-is evaluated instead of indentation::space value."
- :type '(repeat :tag "Kind of Blank Face"
+included in `whitespace-style' list, the indentation value is
+evaluated instead of indentation::space value.
+
+One reason for not visualize spaces via faces (if `face' is not
+included in `whitespace-style') is to use exclusively for
+cleanning up a buffer. See `whitespace-cleanup' and
+`whitespace-cleanup-region' for documentation.
+
+See also `whitespace-display-mappings' for documentation."
+ :type '(repeat :tag "Kind of Blank"
(choice :tag "Kind of Blank Face"
- (const :tag "Trailing TABs, SPACEs and HARD SPACEs"
+ (const :tag "(Face) Face visualization"
+ face)
+ (const :tag "(Face) Trailing TABs, SPACEs and HARD SPACEs"
trailing)
- (const :tag "SPACEs and HARD SPACEs" spaces)
- (const :tag "TABs" tabs)
- (const :tag "Lines" lines)
- (const :tag "SPACEs before TAB"
+ (const :tag "(Face) SPACEs and HARD SPACEs"
+ spaces)
+ (const :tag "(Face) TABs" tabs)
+ (const :tag "(Face) Lines" lines)
+ (const :tag "(Face) SPACEs before TAB"
space-before-tab)
- (const :tag "NEWLINEs" newline)
- (const :tag "Indentation SPACEs" indentation)
- (const :tag "Empty Lines At BOB And/Or EOB"
+ (const :tag "(Face) NEWLINEs" newline)
+ (const :tag "(Face) Indentation SPACEs"
+ indentation)
+ (const :tag "(Face) Empty Lines At BOB And/Or EOB"
empty)
- (const :tag "SPACEs after TAB"
- space-after-tab)))
+ (const :tag "(Face) SPACEs after TAB"
+ space-after-tab)
+ (const :tag "(Mark) SPACEs and HARD SPACEs"
+ space-mark)
+ (const :tag "(Mark) TABs" tab-mark)
+ (const :tag "(Mark) NEWLINEs" newline-mark)))
:group 'whitespace)
(defcustom whitespace-space 'whitespace-space
- "*Symbol face used to visualize SPACE.
+ "Symbol face used to visualize SPACE.
-Used when `whitespace-style-color' includes the value `spaces'."
+Used when `whitespace-style' includes the value `spaces'."
:type 'face
:group 'whitespace)
(defface whitespace-space
'((((class color) (background dark))
- (:background "grey20" :foreground "aquamarine3"))
+ (:background "grey20" :foreground "darkgray"))
(((class color) (background light))
- (:background "LightYellow" :foreground "aquamarine3"))
+ (:background "LightYellow" :foreground "lightgray"))
(t (:inverse-video t)))
"Face used to visualize SPACE."
:group 'whitespace)
(defcustom whitespace-hspace 'whitespace-hspace
- "*Symbol face used to visualize HARD SPACE.
+ "Symbol face used to visualize HARD SPACE.
-Used when `whitespace-style-color' includes the value `spaces'."
+Used when `whitespace-style' includes the value `spaces'."
:type 'face
:group 'whitespace)
(defface whitespace-hspace ; 'nobreak-space
'((((class color) (background dark))
- (:background "grey24" :foreground "aquamarine3"))
+ (:background "grey24" :foreground "darkgray"))
(((class color) (background light))
- (:background "LemonChiffon3" :foreground "aquamarine3"))
+ (:background "LemonChiffon3" :foreground "lightgray"))
(t (:inverse-video t)))
"Face used to visualize HARD SPACE."
:group 'whitespace)
(defcustom whitespace-tab 'whitespace-tab
- "*Symbol face used to visualize TAB.
+ "Symbol face used to visualize TAB.
-Used when `whitespace-style-color' includes the value `tabs'."
+Used when `whitespace-style' includes the value `tabs'."
:type 'face
:group 'whitespace)
(defface whitespace-tab
'((((class color) (background dark))
- (:background "grey22" :foreground "aquamarine3"))
+ (:background "grey22" :foreground "darkgray"))
(((class color) (background light))
- (:background "beige" :foreground "aquamarine3"))
+ (:background "beige" :foreground "lightgray"))
(t (:inverse-video t)))
"Face used to visualize TAB."
:group 'whitespace)
(defcustom whitespace-newline 'whitespace-newline
- "*Symbol face used to visualize NEWLINE char mapping.
+ "Symbol face used to visualize NEWLINE char mapping.
See `whitespace-display-mappings'.
-Used when `whitespace-style-mark' includes the values `newline-mark'
-and `whitespace-style-color' includes `newline'."
+Used when `whitespace-style' includes the values `newline-mark'
+and `newline'."
:type 'face
:group 'whitespace)
(defface whitespace-newline
'((((class color) (background dark))
- (:background "grey26" :foreground "aquamarine3" :bold t))
+ (:foreground "darkgray" :bold nil))
(((class color) (background light))
- (:background "linen" :foreground "aquamarine3" :bold t))
- (t (:bold t :underline t)))
+ (:foreground "lightgray" :bold nil))
+ (t (:underline t :bold nil)))
"Face used to visualize NEWLINE char mapping.
See `whitespace-display-mappings'."
(defcustom whitespace-trailing 'whitespace-trailing
- "*Symbol face used to visualize traling blanks.
+ "Symbol face used to visualize trailing blanks.
-Used when `whitespace-style-color' includes the value `trailing'."
+Used when `whitespace-style' includes the value `trailing'."
:type 'face
:group 'whitespace)
(defcustom whitespace-line 'whitespace-line
- "*Symbol face used to visualize \"long\" lines.
+ "Symbol face used to visualize \"long\" lines.
See `whitespace-line-column'.
-Used when `whitespace-style-color' includes the value `line'."
+Used when `whitespace-style' includes the value `line'."
:type 'face
:group 'whitespace)
(defcustom whitespace-space-before-tab 'whitespace-space-before-tab
- "*Symbol face used to visualize SPACEs before TAB.
+ "Symbol face used to visualize SPACEs before TAB.
-Used when `whitespace-style-color' includes the value `space-before-tab'."
+Used when `whitespace-style' includes the value `space-before-tab'."
:type 'face
:group 'whitespace)
(defcustom whitespace-indentation 'whitespace-indentation
- "*Symbol face used to visualize 8 or more SPACEs at beginning of line.
+ "Symbol face used to visualize 8 or more SPACEs at beginning of line.
-Used when `whitespace-style-color' includes the value `indentation'."
+Used when `whitespace-style' includes the value `indentation'."
:type 'face
:group 'whitespace)
(defcustom whitespace-empty 'whitespace-empty
- "*Symbol face used to visualize empty lines at beginning and/or end of buffer.
+ "Symbol face used to visualize empty lines at beginning and/or end of buffer.
-Used when `whitespace-style-color' includes the value `empty'."
+Used when `whitespace-style' includes the value `empty'."
:type 'face
:group 'whitespace)
(defcustom whitespace-space-after-tab 'whitespace-space-after-tab
- "*Symbol face used to visualize 8 or more SPACEs after TAB.
+ "Symbol face used to visualize 8 or more SPACEs after TAB.
-Used when `whitespace-style-color' includes the value `space-after-tab'."
+Used when `whitespace-style' includes the value `space-after-tab'."
:type 'face
:group 'whitespace)
(defcustom whitespace-hspace-regexp
"\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
- "*Specify HARD SPACE characters regexp.
+ "Specify HARD SPACE characters regexp.
If you're using `mule' package, there may be other characters besides:
NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
Use exactly one pair of enclosing \\\\( and \\\\).
-Used when `whitespace-style-color' includes `spaces'."
+Used when `whitespace-style' includes `spaces'."
:type '(regexp :tag "HARD SPACE Chars")
:group 'whitespace)
(defcustom whitespace-space-regexp "\\( +\\)"
- "*Specify SPACE characters regexp.
+ "Specify SPACE characters regexp.
If you're using `mule' package, there may be other characters
besides \" \" that should be considered SPACE.
NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
Use exactly one pair of enclosing \\\\( and \\\\).
-Used when `whitespace-style-color' includes `spaces'."
+Used when `whitespace-style' includes `spaces'."
:type '(regexp :tag "SPACE Chars")
:group 'whitespace)
(defcustom whitespace-tab-regexp "\\(\t+\\)"
- "*Specify TAB characters regexp.
+ "Specify TAB characters regexp.
If you're using `mule' package, there may be other characters
besides \"\\t\" that should be considered TAB.
NOTE: Enclose always by \\\\( and \\\\) the elements to highlight.
Use exactly one pair of enclosing \\\\( and \\\\).
-Used when `whitespace-style-color' includes `tabs'."
+Used when `whitespace-style' includes `tabs'."
:type '(regexp :tag "TAB Chars")
:group 'whitespace)
(defcustom whitespace-trailing-regexp
- "\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20"
- "*Specify trailing characters regexp.
+ "\\(\\(\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)$"
+ "Specify trailing characters regexp.
If you're using `mule' package, there may be other characters besides:
that should be considered blank.
-NOTE: DO NOT enclose by \\\\( and \\\\) the elements to highlight.
- `whitespace-mode' surrounds this regexp by \"\\\\(\\\\(\" and
- \"\\\\)+\\\\)$\".
+NOTE: Enclose always by \"\\\\(\" and \"\\\\)$\" the elements to highlight.
+ Use exactly one pair of enclosing elements above.
-Used when `whitespace-style-color' includes `trailing'."
+Used when `whitespace-style' includes `trailing'."
:type '(regexp :tag "Trailing Chars")
:group 'whitespace)
(defcustom whitespace-space-before-tab-regexp "\\( +\\)\\(\t+\\)"
- "*Specify SPACEs before TAB regexp.
+ "Specify SPACEs before TAB regexp.
If you're using `mule' package, there may be other characters besides:
that should be considered blank.
-Used when `whitespace-style-color' includes `space-before-tab',
+Used when `whitespace-style' includes `space-before-tab',
`space-before-tab::tab' or `space-before-tab::space'."
:type '(regexp :tag "SPACEs Before TAB")
:group 'whitespace)
(defcustom whitespace-indentation-regexp
'("^\t*\\(\\( \\{%d\\}\\)+\\)[^\n\t]"
. "^ *\\(\t+\\)[^\n]")
- "*Specify regexp for 8 or more SPACEs at beginning of line.
+ "Specify regexp for 8 or more SPACEs at beginning of line.
It is a cons where the cons car is used for SPACEs visualization
and the cons cdr is used for TABs visualization.
that should be considered blank.
-Used when `whitespace-style-color' includes `indentation',
+Used when `whitespace-style' includes `indentation',
`indentation::tab' or `indentation::space'."
:type '(cons (regexp :tag "Indentation SPACEs")
(regexp :tag "Indentation TABs"))
:group 'whitespace)
-(defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
- "*Specify regexp for empty lines at beginning of buffer.
+(defcustom whitespace-empty-at-bob-regexp "^\\(\\([ \t]*\n\\)+\\)"
+ "Specify regexp for empty lines at beginning of buffer.
If you're using `mule' package, there may be other characters besides:
that should be considered blank.
-Used when `whitespace-style-color' includes `empty'."
+Used when `whitespace-style' includes `empty'."
:type '(regexp :tag "Empty Lines At Beginning Of Buffer")
:group 'whitespace)
-(defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
- "*Specify regexp for empty lines at end of buffer.
+(defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)"
+ "Specify regexp for empty lines at end of buffer.
If you're using `mule' package, there may be other characters besides:
that should be considered blank.
-Used when `whitespace-style-color' includes `empty'."
+Used when `whitespace-style' includes `empty'."
:type '(regexp :tag "Empty Lines At End Of Buffer")
:group 'whitespace)
(defcustom whitespace-space-after-tab-regexp
'("\t+\\(\\( \\{%d\\}\\)+\\)"
. "\\(\t+\\) +")
- "*Specify regexp for 8 or more SPACEs after TAB.
+ "Specify regexp for 8 or more SPACEs after TAB.
It is a cons where the cons car is used for SPACEs visualization
and the cons cdr is used for TABs visualization.
that should be considered blank.
-Used when `whitespace-style-color' includes `space-after-tab',
+Used when `whitespace-style' includes `space-after-tab',
`space-after-tab::tab' or `space-after-tab::space'."
:type '(regexp :tag "SPACEs After TAB")
:group 'whitespace)
(defcustom whitespace-line-column 80
- "*Specify column beyond which the line is highlighted.
+ "Specify column beyond which the line is highlighted.
-Used when `whitespace-style-color' includes `lines' or `lines-tail'."
- :type '(integer :tag "Line Length")
+It must be an integer or nil. If nil, the `fill-column' variable value is
+used.
+
+Used when `whitespace-style' includes `lines' or `lines-tail'."
+ :type '(choice :tag "Line Length Limit"
+ (integer :tag "Line Length")
+ (const :tag "Use fill-column" nil))
:group 'whitespace)
;; Hacked from `visible-whitespace-mappings' in visws.el
(defcustom whitespace-display-mappings
'(
- (space-mark ?\ [?\xB7] [?.]) ; space - centered dot
- (space-mark ?\xA0 [?\xA4] [?_]) ; hard space - currency
+ (space-mark ?\ [?\u00B7] [?.]) ; space - centered dot
+ (space-mark ?\xA0 [?\u00A4] [?_]) ; hard space - currency
(space-mark ?\x8A0 [?\x8A4] [?_]) ; hard space - currency
(space-mark ?\x920 [?\x924] [?_]) ; hard space - currency
(space-mark ?\xE20 [?\xE24] [?_]) ; hard space - currency
;; NEWLINE is displayed using the face `whitespace-newline'
(newline-mark ?\n [?$ ?\n]) ; eol - dollar sign
;; (newline-mark ?\n [?\u21B5 ?\n] [?$ ?\n]) ; eol - downwards arrow
- ;; (newline-mark ?\n [?\xB6 ?\n] [?$ ?\n]) ; eol - pilcrow
+ ;; (newline-mark ?\n [?\u00B6 ?\n] [?$ ?\n]) ; eol - pilcrow
;; (newline-mark ?\n [?\x8AF ?\n] [?$ ?\n]) ; eol - overscore
;; (newline-mark ?\n [?\x8AC ?\n] [?$ ?\n]) ; eol - negation
;; (newline-mark ?\n [?\x8B0 ?\n] [?$ ?\n]) ; eol - grade
;; character ?\xBB at that column followed by a TAB which goes to
;; the next TAB column.
;; If this is a problem for you, please, comment the line below.
- (tab-mark ?\t [?\xBB ?\t] [?\\ ?\t]) ; tab - left quote mark
+ (tab-mark ?\t [?\u00BB ?\t] [?\\ ?\t]) ; tab - left quote mark
)
- "*Specify an alist of mappings for displaying characters.
+ "Specify an alist of mappings for displaying characters.
Each element has the following form:
The NEWLINE character is displayed using the face given by
`whitespace-newline' variable.
-Used when `whitespace-style-mark' is non-nil."
+Used when `whitespace-style' includes `tab-mark', `space-mark' or
+`newline-mark'."
:type '(repeat
(list :tag "Character Mapping"
(choice :tag "Char Kind"
(defcustom whitespace-global-modes t
- "*Modes for which global `whitespace-mode' is automagically turned on.
+ "Modes for which global `whitespace-mode' is automagically turned on.
Global `whitespace-mode' is controlled by the command
`global-whitespace-mode'.
(defcustom whitespace-action nil
- "*Specify which action is taken when a buffer is visited, killed or written.
+ "Specify which action is taken when a buffer is visited or written.
It's a list containing some or all of the following values:
when local whitespace is turned on.
auto-cleanup cleanup any bogus whitespace when buffer is
- written or killed.
+ written.
See `whitespace-cleanup' and
`whitespace-cleanup-region'.
abort-on-bogus abort if there is any bogus whitespace and the
- buffer is written or killed.
+ buffer is written.
+
+ warn-if-read-only give a warning if `cleanup' or `auto-cleanup'
+ is included in `whitespace-action' and the
+ buffer is read-only.
Any other value is treated as nil."
:type '(choice :tag "Actions"
(const :tag "Cleanup When On" cleanup)
(const :tag "Report On Bogus" report-on-bogus)
(const :tag "Auto Cleanup" auto-cleanup)
- (const :tag "Abort On Bogus" abort-on-bogus))))
+ (const :tag "Abort On Bogus" abort-on-bogus)
+ (const :tag "Warn If Read-Only" warn-if-read-only))))
:group 'whitespace)
\f
If ARG is null, toggle whitespace visualization.
If ARG is a number greater than zero, turn on visualization;
otherwise, turn off visualization.
-Only useful with a windowing system."
+
+See also `whitespace-style', `whitespace-newline' and
+`whitespace-display-mappings'."
:lighter " ws"
:init-value nil
:global nil
(t ; whitespace-mode off
(whitespace-turn-off))))
+
+;;;###autoload
+(define-minor-mode whitespace-newline-mode
+ "Toggle NEWLINE minor mode visualization (\"nl\" on modeline).
+
+If ARG is null, toggle NEWLINE visualization.
+If ARG is a number greater than zero, turn on visualization;
+otherwise, turn off visualization.
+
+Use `whitespace-newline-mode' only for NEWLINE visualization
+exclusively. For other visualizations, including NEWLINE
+visualization together with (HARD) SPACEs and/or TABs, please,
+use `whitespace-mode'.
+
+See also `whitespace-newline' and `whitespace-display-mappings'."
+ :lighter " nl"
+ :init-value nil
+ :global nil
+ :group 'whitespace
+ (let ((whitespace-style '(newline-mark newline)))
+ (whitespace-mode whitespace-newline-mode)
+ ;; sync states (running a batch job)
+ (setq whitespace-newline-mode whitespace-mode)))
+
\f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; User commands - Global mode
If ARG is null, toggle whitespace visualization.
If ARG is a number greater than zero, turn on visualization;
otherwise, turn off visualization.
-Only useful with a windowing system."
+
+See also `whitespace-style', `whitespace-newline' and
+`whitespace-display-mappings'."
:lighter " WS"
:init-value nil
:global t
;; Otherwise, turn on whitespace mode.
(whitespace-turn-on)))))
+
+;;;###autoload
+(define-minor-mode global-whitespace-newline-mode
+ "Toggle NEWLINE global minor mode visualization (\"NL\" on modeline).
+
+If ARG is null, toggle NEWLINE visualization.
+If ARG is a number greater than zero, turn on visualization;
+otherwise, turn off visualization.
+
+Use `global-whitespace-newline-mode' only for NEWLINE
+visualization exclusively. For other visualizations, including
+NEWLINE visualization together with (HARD) SPACEs and/or TABs,
+please use `global-whitespace-mode'.
+
+See also `whitespace-newline' and `whitespace-display-mappings'."
+ :lighter " NL"
+ :init-value nil
+ :global t
+ :group 'whitespace
+ (let ((whitespace-style '(newline-mark newline)))
+ (global-whitespace-mode global-whitespace-newline-mode)
+ ;; sync states (running a batch job)
+ (setq global-whitespace-newline-mode global-whitespace-mode)))
+
\f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; User commands - Toggle
-(defconst whitespace-color-value-list
- '(tabs
+(defconst whitespace-style-value-list
+ '(face
+ tabs
spaces
trailing
lines
space-before-tab
space-before-tab::tab
space-before-tab::space
- )
- "List of valid `whitespace-style-color' values.")
-
-
-(defconst whitespace-mark-value-list
- '(tab-mark
+ help-newline ; value used by `whitespace-insert-option-mark'
+ tab-mark
space-mark
newline-mark
)
- "List of valid `whitespace-style-mark' values.")
+ "List of valid `whitespace-style' values.")
(defconst whitespace-toggle-option-alist
- '( ;; `whitespace-color-value-list' values
+ '((?f . face)
(?t . tabs)
(?s . spaces)
(?r . trailing)
(?\C-b . space-before-tab)
(?B . space-before-tab::tab)
(?b . space-before-tab::space)
- ;; `whitespace-mark-value-list' values
(?T . tab-mark)
(?S . space-mark)
(?N . newline-mark)
- ;; restore values
- (?x . whitespace-style-color)
- (?z . whitespace-style-mark)
+ (?x . whitespace-style)
)
"Alist of toggle options.
CHAR is a char which the user will have to type.
SYMBOL is a valid symbol associated with CHAR.
- See `whitespace-color-value-list' and
- `whitespace-mark-value-list'.")
-
+ See `whitespace-style-value-list'.")
-(defvar whitespace-active-color nil
- "Used to save locally `whitespace-style-color' value.")
-(defvar whitespace-active-mark nil
- "Used to save locally `whitespace-style-mark' value.")
+(defvar whitespace-active-style nil
+ "Used to save locally `whitespace-style' value.")
(defvar whitespace-indent-tabs-mode indent-tabs-mode
"Used to save locally `indent-tabs-mode' value.")
(defvar whitespace-tab-width tab-width
"Used to save locally `tab-width' value.")
+(defvar whitespace-point (point)
+ "Used to save locally current point value.
+Used by `whitespace-trailing-regexp' function (which see).")
+
+(defvar whitespace-font-lock-refontify nil
+ "Used to save locally the font-lock refontify state.
+Used by `whitespace-post-command-hook' function (which see).")
+
+(defvar whitespace-bob-marker nil
+ "Used to save locally the bob marker value.
+Used by `whitespace-post-command-hook' function (which see).")
+
+(defvar whitespace-eob-marker nil
+ "Used to save locally the eob marker value.
+Used by `whitespace-post-command-hook' function (which see).")
+
+(defvar whitespace-buffer-changed nil
+ "Used to indicate locally if buffer changed.
+Used by `whitespace-post-command-hook' and `whitespace-buffer-changed'
+functions (which see).")
+
;;;###autoload
(defun whitespace-toggle-options (arg)
CHAR MEANING
(VIA FACES)
+ f toggle face visualization
t toggle TAB visualization
s toggle SPACE and HARD SPACE visualization
r toggle trailing blanks visualization
S toggle SPACEs before TAB visualization
N toggle NEWLINE visualization
- x restore `whitespace-style-color' value
- z restore `whitespace-style-mark' value
+ x restore `whitespace-style' value
? display brief help
Non-interactively, ARG should be a symbol or a list of symbols.
The valid symbols are:
+ face toggle face visualization
tabs toggle TAB visualization
spaces toggle SPACE and HARD SPACE visualization
trailing toggle trailing blanks visualization
space-mark toggle SPACEs before TAB visualization
newline-mark toggle NEWLINE visualization
- whitespace-style-color restore `whitespace-style-color' value
- whitespace-style-mark restore `whitespace-style-mark' value
+ whitespace-style restore `whitespace-style' value
-Only useful with a windowing system.
-
-See `whitespace-style-color', `whitespace-style-mark' and
-`indent-tabs-mode' for documentation."
+See `whitespace-style' and `indent-tabs-mode' for documentation."
(interactive (whitespace-interactive-char t))
- (let ((whitespace-style-color
- (whitespace-toggle-list
- t arg whitespace-active-color whitespace-style-color
- 'whitespace-style-color whitespace-color-value-list))
- (whitespace-style-mark
- (whitespace-toggle-list
- t arg whitespace-active-mark whitespace-style-mark
- 'whitespace-style-mark whitespace-mark-value-list)))
+ (let ((whitespace-style
+ (whitespace-toggle-list t arg whitespace-active-style)))
(whitespace-mode 0)
(whitespace-mode 1)))
-(defvar whitespace-toggle-color nil
- "Used to toggle the global `whitespace-style-color' value.")
-(defvar whitespace-toggle-mark nil
- "Used to toggle the global `whitespace-style-mark' value.")
+(defvar whitespace-toggle-style nil
+ "Used to toggle the global `whitespace-style' value.")
;;;###autoload
CHAR MEANING
(VIA FACES)
+ f toggle face visualization
t toggle TAB visualization
s toggle SPACE and HARD SPACE visualization
r toggle trailing blanks visualization
S toggle SPACEs before TAB visualization
N toggle NEWLINE visualization
- x restore `whitespace-style-color' value
- z restore `whitespace-style-mark' value
+ x restore `whitespace-style' value
? display brief help
Non-interactively, ARG should be a symbol or a list of symbols.
The valid symbols are:
+ face toggle face visualization
tabs toggle TAB visualization
spaces toggle SPACE and HARD SPACE visualization
trailing toggle trailing blanks visualization
space-mark toggle SPACEs before TAB visualization
newline-mark toggle NEWLINE visualization
- whitespace-style-color restore `whitespace-style-color' value
- whitespace-style-mark restore `whitespace-style-mark' value
-
-Only useful with a windowing system.
+ whitespace-style restore `whitespace-style' value
-See `whitespace-style-color', `whitespace-style-mark' and
-`indent-tabs-mode' for documentation."
+See `whitespace-style' and `indent-tabs-mode' for documentation."
(interactive (whitespace-interactive-char nil))
- (let ((whitespace-style-color
- (whitespace-toggle-list
- nil arg whitespace-toggle-color whitespace-style-color
- 'whitespace-style-color whitespace-color-value-list))
- (whitespace-style-mark
- (whitespace-toggle-list
- nil arg whitespace-toggle-mark whitespace-style-mark
- 'whitespace-style-mark whitespace-mark-value-list)))
- (setq whitespace-toggle-color whitespace-style-color
- whitespace-toggle-mark whitespace-style-mark)
+ (let ((whitespace-style
+ (whitespace-toggle-list nil arg whitespace-toggle-style)))
+ (setq whitespace-toggle-style whitespace-style)
(global-whitespace-mode 0)
(global-whitespace-mode 1)))
It usually applies to the whole buffer, but in transient mark
mode when the mark is active, it applies to the region. It also
-applies to the region when it is not in transiente mark mode, the
+applies to the region when it is not in transient mark mode, the
mark is active and \\[universal-argument] was pressed just before
calling `whitespace-cleanup' interactively.
1. empty lines at beginning of buffer.
2. empty lines at end of buffer.
- If `whitespace-style-color' includes the value `empty', remove all
+ If `whitespace-style' includes the value `empty', remove all
empty lines at beginning and/or end of buffer.
3. 8 or more SPACEs at beginning of line.
- If `whitespace-style-color' includes the value `indentation':
+ If `whitespace-style' includes the value `indentation':
replace 8 or more SPACEs at beginning of line by TABs, if
`indent-tabs-mode' is non-nil; otherwise, replace TABs by
SPACEs.
- If `whitespace-style-color' includes the value
- `indentation::tab', replace 8 or more SPACEs at beginning of
- line by TABs.
- If `whitespace-style-color' includes the value
- `indentation::space', replace TABs by SPACEs.
+ If `whitespace-style' includes the value `indentation::tab',
+ replace 8 or more SPACEs at beginning of line by TABs.
+ If `whitespace-style' includes the value `indentation::space',
+ replace TABs by SPACEs.
4. SPACEs before TAB.
- If `whitespace-style-color' includes the value `space-before-tab':
+ If `whitespace-style' includes the value `space-before-tab':
replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
otherwise, replace TABs by SPACEs.
- If `whitespace-style-color' includes the value
+ If `whitespace-style' includes the value
`space-before-tab::tab', replace SPACEs by TABs.
- If `whitespace-style-color' includes the value
+ If `whitespace-style' includes the value
`space-before-tab::space', replace TABs by SPACEs.
5. SPACEs or TABs at end of line.
- If `whitespace-style-color' includes the value `trailing', remove
+ If `whitespace-style' includes the value `trailing', remove
all SPACEs or TABs at end of line.
6. 8 or more SPACEs after TAB.
- If `whitespace-style-color' includes the value `space-after-tab':
+ If `whitespace-style' includes the value `space-after-tab':
replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
otherwise, replace TABs by SPACEs.
- If `whitespace-style-color' includes the value
+ If `whitespace-style' includes the value
`space-after-tab::tab', replace SPACEs by TABs.
- If `whitespace-style-color' includes the value
+ If `whitespace-style' includes the value
`space-after-tab::space', replace TABs by SPACEs.
-See `whitespace-style-color', `indent-tabs-mode' and `tab-width'
-for documentation."
- (interactive "@*")
- (if (and (or transient-mark-mode
- current-prefix-arg)
- mark-active)
- ;; region active
- ;; PROBLEMs 1 and 2 are not handled in region
- ;; PROBLEM 3: 8 or more SPACEs at bol
- ;; PROBLEM 4: SPACEs before TAB
- ;; PROBLEM 5: SPACEs or TABs at eol
- ;; PROBLEM 6: 8 or more SPACEs after TAB
- (whitespace-cleanup-region (region-beginning) (region-end))
- ;; whole buffer
+See `whitespace-style', `indent-tabs-mode' and `tab-width' for
+documentation."
+ (interactive "@")
+ (cond
+ ;; read-only buffer
+ (buffer-read-only
+ (whitespace-warn-read-only "cleanup"))
+ ;; region active
+ ((and (or transient-mark-mode
+ current-prefix-arg)
+ mark-active)
+ ;; PROBLEMs 1 and 2 are not handled in region
+ ;; PROBLEM 3: 8 or more SPACEs at bol
+ ;; PROBLEM 4: SPACEs before TAB
+ ;; PROBLEM 5: SPACEs or TABs at eol
+ ;; PROBLEM 6: 8 or more SPACEs after TAB
+ (whitespace-cleanup-region (region-beginning) (region-end)))
+ ;; whole buffer
+ (t
(save-excursion
(save-match-data
;; PROBLEM 1: empty lines at bob
;; PROBLEM 2: empty lines at eob
;; ACTION: remove all empty lines at bob and/or eob
- (when (memq 'empty whitespace-style-color)
+ (when (memq 'empty whitespace-style)
(let (overwrite-mode) ; enforce no overwrite
(goto-char (point-min))
(when (re-search-forward
- whitespace-empty-at-bob-regexp nil t)
+ (concat "\\`" whitespace-empty-at-bob-regexp) nil t)
(delete-region (match-beginning 1) (match-end 1)))
(when (re-search-forward
- whitespace-empty-at-eob-regexp nil t)
+ (concat whitespace-empty-at-eob-regexp "\\'") nil t)
(delete-region (match-beginning 1) (match-end 1)))))))
;; PROBLEM 3: 8 or more SPACEs at bol
;; PROBLEM 4: SPACEs before TAB
;; PROBLEM 5: SPACEs or TABs at eol
;; PROBLEM 6: 8 or more SPACEs after TAB
- (whitespace-cleanup-region (point-min) (point-max))))
+ (whitespace-cleanup-region (point-min) (point-max)))))
;;;###autoload
The problems cleaned up are:
1. 8 or more SPACEs at beginning of line.
- If `whitespace-style-color' includes the value `indentation':
+ If `whitespace-style' includes the value `indentation':
replace 8 or more SPACEs at beginning of line by TABs, if
`indent-tabs-mode' is non-nil; otherwise, replace TABs by
SPACEs.
- If `whitespace-style-color' includes the value
- `indentation::tab', replace 8 or more SPACEs at beginning of
- line by TABs.
- If `whitespace-style-color' includes the value
- `indentation::space', replace TABs by SPACEs.
+ If `whitespace-style' includes the value `indentation::tab',
+ replace 8 or more SPACEs at beginning of line by TABs.
+ If `whitespace-style' includes the value `indentation::space',
+ replace TABs by SPACEs.
2. SPACEs before TAB.
- If `whitespace-style-color' includes the value `space-before-tab':
+ If `whitespace-style' includes the value `space-before-tab':
replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
otherwise, replace TABs by SPACEs.
- If `whitespace-style-color' includes the value
+ If `whitespace-style' includes the value
`space-before-tab::tab', replace SPACEs by TABs.
- If `whitespace-style-color' includes the value
+ If `whitespace-style' includes the value
`space-before-tab::space', replace TABs by SPACEs.
3. SPACEs or TABs at end of line.
- If `whitespace-style-color' includes the value `trailing', remove
+ If `whitespace-style' includes the value `trailing', remove
all SPACEs or TABs at end of line.
4. 8 or more SPACEs after TAB.
- If `whitespace-style-color' includes the value `space-after-tab':
+ If `whitespace-style' includes the value `space-after-tab':
replace SPACEs by TABs, if `indent-tabs-mode' is non-nil;
otherwise, replace TABs by SPACEs.
- If `whitespace-style-color' includes the value
+ If `whitespace-style' includes the value
`space-after-tab::tab', replace SPACEs by TABs.
- If `whitespace-style-color' includes the value
+ If `whitespace-style' includes the value
`space-after-tab::space', replace TABs by SPACEs.
-See `whitespace-style-color', `indent-tabs-mode' and `tab-width'
-for documentation."
- (interactive "@*r")
- (let ((rstart (min start end))
- (rend (copy-marker (max start end)))
- (indent-tabs-mode whitespace-indent-tabs-mode)
- (tab-width whitespace-tab-width)
- overwrite-mode ; enforce no overwrite
- tmp)
- (save-excursion
- (save-match-data
- ;; PROBLEM 1: 8 or more SPACEs at bol
- (cond
- ;; ACTION: replace 8 or more SPACEs at bol by TABs, if
- ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
- ;; SPACEs.
- ((memq 'indentation whitespace-style-color)
- (let ((regexp (whitespace-indentation-regexp)))
- (goto-char rstart)
- (while (re-search-forward regexp rend t)
- (setq tmp (current-indentation))
- (goto-char (match-beginning 0))
- (delete-horizontal-space)
- (unless (eolp)
- (indent-to tmp)))))
- ;; ACTION: replace 8 or more SPACEs at bol by TABs.
- ((memq 'indentation::tab whitespace-style-color)
- (whitespace-replace-action
- 'tabify rstart rend
- (whitespace-indentation-regexp 'tab) 0))
- ;; ACTION: replace TABs by SPACEs.
- ((memq 'indentation::space whitespace-style-color)
- (whitespace-replace-action
- 'untabify rstart rend
- (whitespace-indentation-regexp 'space) 0)))
- ;; PROBLEM 3: SPACEs or TABs at eol
- ;; ACTION: remove all SPACEs or TABs at eol
- (when (memq 'trailing whitespace-style-color)
- (whitespace-replace-action
- 'delete-region rstart rend
- (whitespace-trailing-regexp) 1))
- ;; PROBLEM 4: 8 or more SPACEs after TAB
- (cond
- ;; ACTION: replace 8 or more SPACEs by TABs, if
- ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
- ;; SPACEs.
- ((memq 'space-after-tab whitespace-style-color)
- (whitespace-replace-action
- (if whitespace-indent-tabs-mode 'tabify 'untabify)
- rstart rend (whitespace-space-after-tab-regexp) 1))
- ;; ACTION: replace 8 or more SPACEs by TABs.
- ((memq 'space-after-tab::tab whitespace-style-color)
- (whitespace-replace-action
- 'tabify rstart rend
- (whitespace-space-after-tab-regexp 'tab) 1))
- ;; ACTION: replace TABs by SPACEs.
- ((memq 'space-after-tab::space whitespace-style-color)
- (whitespace-replace-action
- 'untabify rstart rend
- (whitespace-space-after-tab-regexp 'space) 1)))
- ;; PROBLEM 2: SPACEs before TAB
- (cond
- ;; ACTION: replace SPACEs before TAB by TABs, if
- ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs by
- ;; SPACEs.
- ((memq 'space-before-tab whitespace-style-color)
- (whitespace-replace-action
- (if whitespace-indent-tabs-mode 'tabify 'untabify)
- rstart rend whitespace-space-before-tab-regexp
- (if whitespace-indent-tabs-mode 1 2)))
- ;; ACTION: replace SPACEs before TAB by TABs.
- ((memq 'space-before-tab::tab whitespace-style-color)
- (whitespace-replace-action
- 'tabify rstart rend
- whitespace-space-before-tab-regexp 1))
- ;; ACTION: replace TABs by SPACEs.
- ((memq 'space-before-tab::space whitespace-style-color)
- (whitespace-replace-action
- 'untabify rstart rend
- whitespace-space-before-tab-regexp 2)))))
- (set-marker rend nil))) ; point marker to nowhere
+See `whitespace-style', `indent-tabs-mode' and `tab-width' for
+documentation."
+ (interactive "@r")
+ (if buffer-read-only
+ ;; read-only buffer
+ (whitespace-warn-read-only "cleanup region")
+ ;; non-read-only buffer
+ (let ((rstart (min start end))
+ (rend (copy-marker (max start end)))
+ (indent-tabs-mode whitespace-indent-tabs-mode)
+ (tab-width whitespace-tab-width)
+ overwrite-mode ; enforce no overwrite
+ tmp)
+ (save-excursion
+ (save-match-data
+ ;; PROBLEM 1: 8 or more SPACEs at bol
+ (cond
+ ;; ACTION: replace 8 or more SPACEs at bol by TABs, if
+ ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
+ ;; by SPACEs.
+ ((memq 'indentation whitespace-style)
+ (let ((regexp (whitespace-indentation-regexp)))
+ (goto-char rstart)
+ (while (re-search-forward regexp rend t)
+ (setq tmp (current-indentation))
+ (goto-char (match-beginning 0))
+ (delete-horizontal-space)
+ (unless (eolp)
+ (indent-to tmp)))))
+ ;; ACTION: replace 8 or more SPACEs at bol by TABs.
+ ((memq 'indentation::tab whitespace-style)
+ (whitespace-replace-action
+ 'tabify rstart rend
+ (whitespace-indentation-regexp 'tab) 0))
+ ;; ACTION: replace TABs by SPACEs.
+ ((memq 'indentation::space whitespace-style)
+ (whitespace-replace-action
+ 'untabify rstart rend
+ (whitespace-indentation-regexp 'space) 0)))
+ ;; PROBLEM 3: SPACEs or TABs at eol
+ ;; ACTION: remove all SPACEs or TABs at eol
+ (when (memq 'trailing whitespace-style)
+ (whitespace-replace-action
+ 'delete-region rstart rend
+ whitespace-trailing-regexp 1))
+ ;; PROBLEM 4: 8 or more SPACEs after TAB
+ (cond
+ ;; ACTION: replace 8 or more SPACEs by TABs, if
+ ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
+ ;; by SPACEs.
+ ((memq 'space-after-tab whitespace-style)
+ (whitespace-replace-action
+ (if whitespace-indent-tabs-mode 'tabify 'untabify)
+ rstart rend (whitespace-space-after-tab-regexp) 1))
+ ;; ACTION: replace 8 or more SPACEs by TABs.
+ ((memq 'space-after-tab::tab whitespace-style)
+ (whitespace-replace-action
+ 'tabify rstart rend
+ (whitespace-space-after-tab-regexp 'tab) 1))
+ ;; ACTION: replace TABs by SPACEs.
+ ((memq 'space-after-tab::space whitespace-style)
+ (whitespace-replace-action
+ 'untabify rstart rend
+ (whitespace-space-after-tab-regexp 'space) 1)))
+ ;; PROBLEM 2: SPACEs before TAB
+ (cond
+ ;; ACTION: replace SPACEs before TAB by TABs, if
+ ;; `indent-tabs-mode' is non-nil; otherwise, replace TABs
+ ;; by SPACEs.
+ ((memq 'space-before-tab whitespace-style)
+ (whitespace-replace-action
+ (if whitespace-indent-tabs-mode 'tabify 'untabify)
+ rstart rend whitespace-space-before-tab-regexp
+ (if whitespace-indent-tabs-mode 1 2)))
+ ;; ACTION: replace SPACEs before TAB by TABs.
+ ((memq 'space-before-tab::tab whitespace-style)
+ (whitespace-replace-action
+ 'tabify rstart rend
+ whitespace-space-before-tab-regexp 1))
+ ;; ACTION: replace TABs by SPACEs.
+ ((memq 'space-before-tab::space whitespace-style)
+ (whitespace-replace-action
+ 'untabify rstart rend
+ whitespace-space-before-tab-regexp 2)))))
+ (set-marker rend nil)))) ; point marker to nowhere
(defun whitespace-replace-action (action rstart rend regexp index)
;;;; User command - report
-(defun whitespace-trailing-regexp ()
- "Make the `whitespace-trailing-regexp' regexp."
- (concat "\\(\\(" whitespace-trailing-regexp "\\)+\\)$"))
-
-
(defun whitespace-regexp (regexp &optional kind)
"Return REGEXP depending on `whitespace-indent-tabs-mode'."
(cond
(list
(cons 'empty whitespace-empty-at-bob-regexp)
(cons 'empty whitespace-empty-at-eob-regexp)
- (cons 'trailing (whitespace-trailing-regexp))
+ (cons 'trailing whitespace-trailing-regexp)
(cons 'indentation nil)
(cons 'indentation::tab nil)
(cons 'indentation::space nil)
If FORCE is non-nil or \\[universal-argument] was pressed just
before calling `whitespace-report' interactively, it forces
-`whitespace-style-color' to have:
+`whitespace-style' to have:
empty
trailing
space-before-tab 5. SPACEs before TAB.
space-after-tab 6. 8 or more SPACEs after TAB.
-See `whitespace-style-color' and `whitespace-style-mark' for
-documentation.
+See `whitespace-style' for documentation.
See also `whitespace-cleanup' and `whitespace-cleanup-region' for
cleaning up these problems."
(interactive (list current-prefix-arg))
If FORCE is non-nil or \\[universal-argument] was pressed just
before calling `whitespace-report-region' interactively, it
-forces `whitespace-style-color' to have:
+forces `whitespace-style' to have:
empty
indentation
space-before-tab 5. SPACEs before TAB.
space-after-tab 6. 8 or more SPACEs after TAB.
-See `whitespace-style-color' and `whitespace-style-mark' for
-documentation.
+See `whitespace-style' for documentation.
See also `whitespace-cleanup' and `whitespace-cleanup-region' for
cleaning up these problems."
(interactive "r")
(mapcar
#'(lambda (option)
(when force
- (add-to-list 'whitespace-style-color
- (car option)))
+ (add-to-list 'whitespace-style (car option)))
(goto-char rstart)
(let ((regexp
(cond
(dolist (option whitespace-report-list)
(forward-line 1)
(whitespace-mark-x
- 27 (memq (car option) whitespace-style-color))
+ 27 (memq (car option) whitespace-style))
(whitespace-mark-x 7 (car bogus-list))
(setq bogus-list (cdr bogus-list)))
(forward-line 1)
(defconst whitespace-help-text
"\
- Whitespace Toggle Options
-
- FACES
+ Whitespace Toggle Options | scroll up : SPC or > |
+ | scroll down: M-SPC or < |
+ FACES \\__________________________/
+ [] f - toggle face visualization
[] t - toggle TAB visualization
[] s - toggle SPACE and HARD SPACE visualization
[] r - toggle trailing blanks visualization
[] S - toggle SPACE and HARD SPACE visualization
[] N - toggle NEWLINE visualization
- x - restore `whitespace-style-color' value
- z - restore `whitespace-style-mark' value
+ x - restore `whitespace-style' value
? - display this text\n\n"
"Text for whitespace toggle options.")
(defun whitespace-insert-option-mark (the-list the-value)
"Insert the option mark ('X' or ' ') in toggle options buffer."
+ (goto-char (point-min))
(forward-line 2)
(dolist (sym the-list)
- (forward-line 1)
- (whitespace-mark-x 2 (memq sym the-value))))
+ (if (eq sym 'help-newline)
+ (forward-line 2)
+ (forward-line 1)
+ (whitespace-mark-x 2 (memq sym the-value)))))
-(defun whitespace-help-on (chars style)
+(defun whitespace-help-on (style)
"Display the whitespace toggle options."
(unless (get-buffer whitespace-help-buffer-name)
(delete-other-windows)
(let ((buffer (get-buffer-create whitespace-help-buffer-name)))
- (save-excursion
- (set-buffer buffer)
+ (with-current-buffer buffer
(erase-buffer)
(insert whitespace-help-text)
- (goto-char (point-min))
(whitespace-insert-option-mark
- whitespace-color-value-list chars)
- (whitespace-insert-option-mark
- whitespace-mark-value-list style)
+ whitespace-style-value-list style)
(whitespace-display-window buffer)))))
"Display BUFFER in a new window."
(goto-char (point-min))
(set-buffer-modified-p nil)
- (let ((size (- (window-height)
- (max window-min-height
- (1+ (count-lines (point-min)
- (point-max)))))))
- (when (<= size 0)
- (kill-buffer buffer)
- (error "Frame height is too small; \
+ (when (< (window-height) (* 2 window-min-height))
+ (kill-buffer buffer)
+ (error "Window height is too small; \
can't split window to display whitespace toggle options"))
- (set-window-buffer (split-window nil size) buffer)))
+ (let ((win (split-window)))
+ (set-window-buffer win buffer)
+ (shrink-window-if-larger-than-buffer win)))
(defun whitespace-kill-buffer (buffer-name)
(whitespace-kill-buffer whitespace-help-buffer-name))
+(defun whitespace-help-scroll (&optional up)
+ "Scroll help window, if it exists.
+
+If UP is non-nil, scroll up; otherwise, scroll down."
+ (condition-case data-help
+ (let ((buffer (get-buffer whitespace-help-buffer-name)))
+ (if buffer
+ (with-selected-window (get-buffer-window buffer)
+ (if up
+ (scroll-up 3)
+ (scroll-down 3)))
+ (ding)))
+ ;; handler
+ ((error)
+ ;; just ignore error
+ )))
+
+
(defun whitespace-interactive-char (local-p)
"Interactive function to read a char and return a symbol.
CHAR MEANING
(VIA FACES)
+ f toggle face visualization
t toggle TAB visualization
s toggle SPACE and HARD SPACE visualization
r toggle trailing blanks visualization
S toggle SPACE and HARD SPACE visualization
N toggle NEWLINE visualization
- x restore `whitespace-style-color' value
- z restore `whitespace-style-mark' value
+ x restore `whitespace-style' value
? display brief help
See also `whitespace-toggle-option-alist'."
(let* ((is-off (not (if local-p
whitespace-mode
global-whitespace-mode)))
- (chars (cond (is-off whitespace-style-color) ; use default value
- (local-p whitespace-active-color)
- (t whitespace-toggle-color)))
- (style (cond (is-off whitespace-style-mark) ; use default value
- (local-p whitespace-active-mark)
- (t whitespace-toggle-mark)))
+ (style (cond (is-off whitespace-style) ; use default value
+ (local-p whitespace-active-style)
+ (t whitespace-toggle-style)))
(prompt
(format "Whitespace Toggle %s (type ? for further options)-"
(if local-p "Local" "Global")))
(cdr
(assq ch whitespace-toggle-option-alist)))))
;; while body
- (if (eq ch ?\?)
- (whitespace-help-on chars style)
- (ding)))
+ (cond
+ ((eq ch ?\?) (whitespace-help-on style))
+ ((eq ch ?\ ) (whitespace-help-scroll t))
+ ((eq ch ?\M- ) (whitespace-help-scroll))
+ ((eq ch ?>) (whitespace-help-scroll t))
+ ((eq ch ?<) (whitespace-help-scroll))
+ (t (ding))))
(whitespace-help-off)
(message " ")) ; clean echo area
;; handler
((quit error)
(whitespace-help-off)
(error (error-message-string data)))))
- (list sym))) ; return the apropriate symbol
+ (list sym))) ; return the appropriate symbol
-(defun whitespace-toggle-list (local-p arg the-list default-list
- sym-restore sym-list)
+(defun whitespace-toggle-list (local-p arg the-list)
"Toggle options in THE-LIST based on list ARG.
If LOCAL-P is non-nil, it uses a local context; otherwise, it
ARG is a list of options to be toggled.
THE-LIST is a list of options. This list will be toggled and the
-resultant list will be returned.
-
-DEFAULT-LIST is the default list of options. It is used to
-restore the options in THE-LIST.
-
-SYM-RESTORE is the symbol which indicates to restore the options
-in THE-LIST.
-
-SYM-LIST is a list of valid options, used to check if the ARG's
-options are valid."
+resultant list will be returned."
(unless (if local-p whitespace-mode global-whitespace-mode)
- (setq the-list default-list))
+ (setq the-list whitespace-style))
(setq the-list (copy-sequence the-list)) ; keep original list
(dolist (sym (if (listp arg) arg (list arg)))
(cond
+ ;; ignore help value
+ ((eq sym 'help-newline))
;; restore default values
- ((eq sym sym-restore)
- (setq the-list default-list))
+ ((eq sym 'whitespace-style)
+ (setq the-list whitespace-style))
;; toggle valid values
- ((memq sym sym-list)
+ ((memq sym whitespace-style-value-list)
(setq the-list (if (memq sym the-list)
(delq sym the-list)
(cons sym the-list))))))
the-list)
+(defvar whitespace-display-table nil
+ "Used to save a local display table.")
+
+(defvar whitespace-display-table-was-local nil
+ "Used to remember whether a buffer initially had a local display table.")
+
+
(defun whitespace-turn-on ()
"Turn on whitespace visualization."
;; prepare local hooks
- (whitespace-add-local-hook)
+ (add-hook 'write-file-functions 'whitespace-write-file-hook nil t)
;; create whitespace local buffer environment
(set (make-local-variable 'whitespace-font-lock-mode) nil)
(set (make-local-variable 'whitespace-font-lock) nil)
(set (make-local-variable 'whitespace-font-lock-keywords) nil)
(set (make-local-variable 'whitespace-display-table) nil)
(set (make-local-variable 'whitespace-display-table-was-local) nil)
- (set (make-local-variable 'whitespace-active-mark)
- (if (listp whitespace-style-mark)
- whitespace-style-mark
- (list whitespace-style-mark)))
- (set (make-local-variable 'whitespace-active-color)
- (if (listp whitespace-style-color)
- whitespace-style-color
- (list whitespace-style-color)))
+ (set (make-local-variable 'whitespace-active-style)
+ (if (listp whitespace-style)
+ whitespace-style
+ (list whitespace-style)))
(set (make-local-variable 'whitespace-indent-tabs-mode)
indent-tabs-mode)
(set (make-local-variable 'whitespace-tab-width)
tab-width)
;; turn on whitespace
- (when whitespace-active-color
- (whitespace-color-on))
- (when whitespace-active-mark
+ (when whitespace-active-style
+ (whitespace-color-on)
(whitespace-display-char-on)))
(defun whitespace-turn-off ()
"Turn off whitespace visualization."
- (whitespace-remove-local-hook)
- (when whitespace-active-color
- (whitespace-color-off))
- (when whitespace-active-mark
+ (remove-hook 'write-file-functions 'whitespace-write-file-hook t)
+ (when whitespace-active-style
+ (whitespace-color-off)
(whitespace-display-char-off)))
+(defun whitespace-style-face-p ()
+ "Return t if there is some visualization via face."
+ (and (memq 'face whitespace-active-style)
+ (or (memq 'tabs whitespace-active-style)
+ (memq 'spaces whitespace-active-style)
+ (memq 'trailing whitespace-active-style)
+ (memq 'lines whitespace-active-style)
+ (memq 'lines-tail whitespace-active-style)
+ (memq 'newline whitespace-active-style)
+ (memq 'empty whitespace-active-style)
+ (memq 'indentation whitespace-active-style)
+ (memq 'indentation::tab whitespace-active-style)
+ (memq 'indentation::space whitespace-active-style)
+ (memq 'space-after-tab whitespace-active-style)
+ (memq 'space-after-tab::tab whitespace-active-style)
+ (memq 'space-after-tab::space whitespace-active-style)
+ (memq 'space-before-tab whitespace-active-style)
+ (memq 'space-before-tab::tab whitespace-active-style)
+ (memq 'space-before-tab::space whitespace-active-style))))
+
+
(defun whitespace-color-on ()
"Turn on color visualization."
- (when whitespace-active-color
+ (when (whitespace-style-face-p)
(unless whitespace-font-lock
(setq whitespace-font-lock t
whitespace-font-lock-keywords
(copy-sequence font-lock-keywords)))
+ ;; save current point and refontify when necessary
+ (set (make-local-variable 'whitespace-point)
+ (point))
+ (set (make-local-variable 'whitespace-font-lock-refontify)
+ 0)
+ (set (make-local-variable 'whitespace-bob-marker)
+ (point-min-marker))
+ (set (make-local-variable 'whitespace-eob-marker)
+ (point-max-marker))
+ (set (make-local-variable 'whitespace-buffer-changed)
+ nil)
+ (add-hook 'post-command-hook #'whitespace-post-command-hook nil t)
+ (add-hook 'before-change-functions #'whitespace-buffer-changed nil t)
;; turn off font lock
(set (make-local-variable 'whitespace-font-lock-mode)
font-lock-mode)
(font-lock-mode 0)
;; add whitespace-mode color into font lock
- (when (memq 'spaces whitespace-active-color)
+ (when (memq 'spaces whitespace-active-style)
(font-lock-add-keywords
nil
(list
;; Show HARD SPACEs
(list whitespace-hspace-regexp 1 whitespace-hspace t))
t))
- (when (memq 'tabs whitespace-active-color)
+ (when (memq 'tabs whitespace-active-style)
(font-lock-add-keywords
nil
(list
;; Show TABs
(list whitespace-tab-regexp 1 whitespace-tab t))
t))
- (when (memq 'trailing whitespace-active-color)
+ (when (memq 'trailing whitespace-active-style)
(font-lock-add-keywords
nil
(list
;; Show trailing blanks
- (list (whitespace-trailing-regexp) 1 whitespace-trailing t))
+ (list #'whitespace-trailing-regexp 1 whitespace-trailing t))
t))
- (when (or (memq 'lines whitespace-active-color)
- (memq 'lines-tail whitespace-active-color))
+ (when (or (memq 'lines whitespace-active-style)
+ (memq 'lines-tail whitespace-active-style))
(font-lock-add-keywords
nil
(list
;; Show "long" lines
(list
- (format
- "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
- whitespace-tab-width (1- whitespace-tab-width)
- (/ whitespace-line-column tab-width)
- (let ((rem (% whitespace-line-column whitespace-tab-width)))
- (if (zerop rem)
- ""
- (format ".\\{%d\\}" rem))))
- (if (memq 'lines whitespace-active-color)
+ (let ((line-column (or whitespace-line-column fill-column)))
+ (format
+ "^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
+ whitespace-tab-width
+ (1- whitespace-tab-width)
+ (/ line-column whitespace-tab-width)
+ (let ((rem (% line-column whitespace-tab-width)))
+ (if (zerop rem)
+ ""
+ (format ".\\{%d\\}" rem)))))
+ (if (memq 'lines whitespace-active-style)
0 ; whole line
2) ; line tail
whitespace-line t))
t))
(cond
- ((memq 'space-before-tab whitespace-active-color)
+ ((memq 'space-before-tab whitespace-active-style)
(font-lock-add-keywords
nil
(list
(if whitespace-indent-tabs-mode 1 2)
whitespace-space-before-tab t))
t))
- ((memq 'space-before-tab::tab whitespace-active-color)
+ ((memq 'space-before-tab::tab whitespace-active-style)
(font-lock-add-keywords
nil
(list
(list whitespace-space-before-tab-regexp
1 whitespace-space-before-tab t))
t))
- ((memq 'space-before-tab::space whitespace-active-color)
+ ((memq 'space-before-tab::space whitespace-active-style)
(font-lock-add-keywords
nil
(list
2 whitespace-space-before-tab t))
t)))
(cond
- ((memq 'indentation whitespace-active-color)
+ ((memq 'indentation whitespace-active-style)
(font-lock-add-keywords
nil
(list
(list (whitespace-indentation-regexp)
1 whitespace-indentation t))
t))
- ((memq 'indentation::tab whitespace-active-color)
+ ((memq 'indentation::tab whitespace-active-style)
(font-lock-add-keywords
nil
(list
(list (whitespace-indentation-regexp 'tab)
1 whitespace-indentation t))
t))
- ((memq 'indentation::space whitespace-active-color)
+ ((memq 'indentation::space whitespace-active-style)
(font-lock-add-keywords
nil
(list
(list (whitespace-indentation-regexp 'space)
1 whitespace-indentation t))
t)))
- (when (memq 'empty whitespace-active-color)
+ (when (memq 'empty whitespace-active-style)
(font-lock-add-keywords
nil
(list
;; Show empty lines at beginning of buffer
- (list whitespace-empty-at-bob-regexp
+ (list #'whitespace-empty-at-bob-regexp
1 whitespace-empty t))
t)
(font-lock-add-keywords
nil
(list
;; Show empty lines at end of buffer
- (list whitespace-empty-at-eob-regexp
+ (list #'whitespace-empty-at-eob-regexp
1 whitespace-empty t))
t))
(cond
- ((memq 'space-after-tab whitespace-active-color)
+ ((memq 'space-after-tab whitespace-active-style)
(font-lock-add-keywords
nil
(list
(list (whitespace-space-after-tab-regexp)
1 whitespace-space-after-tab t))
t))
- ((memq 'space-after-tab::tab whitespace-active-color)
+ ((memq 'space-after-tab::tab whitespace-active-style)
(font-lock-add-keywords
nil
(list
(list (whitespace-space-after-tab-regexp 'tab)
1 whitespace-space-after-tab t))
t))
- ((memq 'space-after-tab::space whitespace-active-color)
+ ((memq 'space-after-tab::space whitespace-active-style)
(font-lock-add-keywords
nil
(list
(defun whitespace-color-off ()
"Turn off color visualization."
- (when whitespace-active-color
- ;; turn off font lock
+ ;; turn off font lock
+ (when (whitespace-style-face-p)
(font-lock-mode 0)
+ (remove-hook 'post-command-hook #'whitespace-post-command-hook t)
+ (remove-hook 'before-change-functions #'whitespace-buffer-changed t)
(when whitespace-font-lock
(setq whitespace-font-lock nil
font-lock-keywords whitespace-font-lock-keywords))
;; restore original font lock state
(font-lock-mode whitespace-font-lock-mode)))
+
+(defun whitespace-trailing-regexp (limit)
+ "Match trailing spaces which do not contain the point at end of line."
+ (let ((status t))
+ (while (if (re-search-forward whitespace-trailing-regexp limit t)
+ (save-match-data
+ (= whitespace-point (match-end 1))) ;; loop if point at eol
+ (setq status nil))) ;; end of buffer
+ status))
+
+
+(defun whitespace-empty-at-bob-regexp (limit)
+ "Match spaces at beginning of buffer which do not contain the point at \
+beginning of buffer."
+ (let ((b (point))
+ r)
+ (cond
+ ;; at bob
+ ((= b 1)
+ (setq r (and (/= whitespace-point 1)
+ (looking-at whitespace-empty-at-bob-regexp)))
+ (if r
+ (set-marker whitespace-bob-marker (match-end 1))
+ (set-marker whitespace-bob-marker b)))
+ ;; inside bob empty region
+ ((<= limit whitespace-bob-marker)
+ (setq r (looking-at whitespace-empty-at-bob-regexp))
+ (if r
+ (when (< (match-end 1) limit)
+ (set-marker whitespace-bob-marker (match-end 1)))
+ (set-marker whitespace-bob-marker b)))
+ ;; intersection with end of bob empty region
+ ((<= b whitespace-bob-marker)
+ (setq r (looking-at whitespace-empty-at-bob-regexp))
+ (if r
+ (set-marker whitespace-bob-marker (match-end 1))
+ (set-marker whitespace-bob-marker b)))
+ ;; it is not inside bob empty region
+ (t
+ (setq r nil)))
+ ;; move to end of matching
+ (and r (goto-char (match-end 1)))
+ r))
+
+
+(defsubst whitespace-looking-back (regexp limit)
+ (save-excursion
+ (when (/= 0 (skip-chars-backward " \t\n" limit))
+ (unless (bolp)
+ (forward-line 1))
+ (looking-at regexp))))
+
+
+(defun whitespace-empty-at-eob-regexp (limit)
+ "Match spaces at end of buffer which do not contain the point at end of \
+buffer."
+ (let ((b (point))
+ (e (1+ (buffer-size)))
+ r)
+ (cond
+ ;; at eob
+ ((= limit e)
+ (when (/= whitespace-point e)
+ (goto-char limit)
+ (setq r (whitespace-looking-back whitespace-empty-at-eob-regexp b)))
+ (if r
+ (set-marker whitespace-eob-marker (match-beginning 1))
+ (set-marker whitespace-eob-marker limit)
+ (goto-char b))) ; return back to initial position
+ ;; inside eob empty region
+ ((>= b whitespace-eob-marker)
+ (goto-char limit)
+ (setq r (whitespace-looking-back whitespace-empty-at-eob-regexp b))
+ (if r
+ (when (> (match-beginning 1) b)
+ (set-marker whitespace-eob-marker (match-beginning 1)))
+ (set-marker whitespace-eob-marker limit)
+ (goto-char b))) ; return back to initial position
+ ;; intersection with beginning of eob empty region
+ ((>= limit whitespace-eob-marker)
+ (goto-char limit)
+ (setq r (whitespace-looking-back whitespace-empty-at-eob-regexp b))
+ (if r
+ (set-marker whitespace-eob-marker (match-beginning 1))
+ (set-marker whitespace-eob-marker limit)
+ (goto-char b))) ; return back to initial position
+ ;; it is not inside eob empty region
+ (t
+ (setq r nil)))
+ r))
+
+
+(defun whitespace-buffer-changed (beg end)
+ "Set `whitespace-buffer-changed' variable to t."
+ (setq whitespace-buffer-changed t))
+
+
+(defun whitespace-post-command-hook ()
+ "Save current point into `whitespace-point' variable.
+Also refontify when necessary."
+ (setq whitespace-point (point)) ; current point position
+ (let ((refontify
+ (or
+ ;; it is at end of line ...
+ (and (eolp)
+ ;; ... with trailing SPACE or TAB
+ (or (= (preceding-char) ?\ )
+ (= (preceding-char) ?\t)))
+ ;; it is at beginning of buffer (bob)
+ (= whitespace-point 1)
+ ;; the buffer was modified and ...
+ (and whitespace-buffer-changed
+ (or
+ ;; ... or inside bob whitespace region
+ (<= whitespace-point whitespace-bob-marker)
+ ;; ... or at bob whitespace region border
+ (and (= whitespace-point (1+ whitespace-bob-marker))
+ (= (preceding-char) ?\n))))
+ ;; it is at end of buffer (eob)
+ (= whitespace-point (1+ (buffer-size)))
+ ;; the buffer was modified and ...
+ (and whitespace-buffer-changed
+ (or
+ ;; ... or inside eob whitespace region
+ (>= whitespace-point whitespace-eob-marker)
+ ;; ... or at eob whitespace region border
+ (and (= whitespace-point (1- whitespace-eob-marker))
+ (= (following-char) ?\n)))))))
+ (when (or refontify (> whitespace-font-lock-refontify 0))
+ (setq whitespace-buffer-changed nil)
+ ;; adjust refontify counter
+ (setq whitespace-font-lock-refontify
+ (if refontify
+ 1
+ (1- whitespace-font-lock-refontify)))
+ ;; refontify
+ (jit-lock-refontify))))
+
\f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
-(defvar whitespace-display-table nil
- "Used to save a local display table.")
-
-(defvar whitespace-display-table-was-local nil
- "Used to remember whether a buffer initially had a local display table.")
+(defun whitespace-style-mark-p ()
+ "Return t if there is some visualization via display table."
+ (or (memq 'tab-mark whitespace-active-style)
+ (memq 'space-mark whitespace-active-style)
+ (memq 'newline-mark whitespace-active-style)))
(defsubst whitespace-char-valid-p (char)
(defun whitespace-display-char-on ()
"Turn on character display mapping."
- (when whitespace-display-mappings
+ (when (and whitespace-display-mappings
+ (whitespace-style-mark-p))
(let (vecs vec)
;; Remember whether a buffer has a local display table.
(unless whitespace-display-table-was-local
(setq whitespace-display-table-was-local t
whitespace-display-table
+ (copy-sequence buffer-display-table))
+ ;; asure `buffer-display-table' is unique
+ ;; when two or more windows are visible.
+ (setq buffer-display-table
(copy-sequence buffer-display-table)))
(unless buffer-display-table
(setq buffer-display-table (make-display-table)))
(dolist (entry whitespace-display-mappings)
;; check if it is to display this mark
- (when (memq (car entry) whitespace-style-mark)
+ (when (memq (car entry) whitespace-style)
;; Get a displayable mapping.
(setq vecs (cddr entry))
(while (and vecs
(setq vec (copy-sequence (car vecs)))
;; NEWLINE char
(when (and (eq (cadr entry) ?\n)
- (memq 'newline whitespace-active-color))
+ (memq 'newline whitespace-active-style))
;; Only insert face bits on NEWLINE char mapping to avoid
;; obstruction of other faces like TABs and (HARD) SPACEs
;; faces, font-lock faces, etc.
(defun whitespace-display-char-off ()
"Turn off character display mapping."
(and whitespace-display-mappings
+ (whitespace-style-mark-p)
whitespace-display-table-was-local
(setq whitespace-display-table-was-local nil
buffer-display-table whitespace-display-table)))
(whitespace-report nil t))))
-(defun whitespace-add-local-hook ()
- "Add some whitespace hooks locally."
- (add-hook 'write-file-functions 'whitespace-write-file-hook nil t)
- (add-hook 'kill-buffer-hook 'whitespace-kill-buffer-hook nil t))
-
-
-(defun whitespace-remove-local-hook ()
- "Remove some whitespace hooks locally."
- (remove-hook 'write-file-functions 'whitespace-write-file-hook t)
- (remove-hook 'kill-buffer-hook 'whitespace-kill-buffer-hook t))
-
-
(defun whitespace-write-file-hook ()
"Action to be taken when buffer is written.
It should be added buffer-locally to `write-file-functions'."
- (when (whitespace-action)
- (error "Abort write due to whitespace problems in %s"
- (buffer-name)))
- nil) ; continue hook processing
-
-
-(defun whitespace-kill-buffer-hook ()
- "Action to be taken when buffer is killed.
-It should be added buffer-locally to `kill-buffer-hook'."
- (whitespace-action)
+ (cond ((memq 'auto-cleanup whitespace-action)
+ (whitespace-cleanup))
+ ((memq 'abort-on-bogus whitespace-action)
+ (when (whitespace-report nil t)
+ (error "Abort write due to whitespace problems in %s"
+ (buffer-name)))))
nil) ; continue hook processing
-(defun whitespace-action ()
- "Action to be taken when buffer is killed or written.
-Return t when the action should be aborted."
- (cond ((memq 'auto-cleanup whitespace-action)
- (whitespace-cleanup)
- nil)
- ((memq 'abort-on-bogus whitespace-action)
- (whitespace-report nil t))
- (t
- nil)))
+(defun whitespace-warn-read-only (msg)
+ "Warn if buffer is read-only."
+ (when (memq 'warn-if-read-only whitespace-action)
+ (message "Can't %s: %s is read-only" msg (buffer-name))))
\f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;