;;; 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: 11.2.2
+;; Version: 12.1
;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
;; This file is part of GNU Emacs.
;; 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
'(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.
+ "Specify which kind of blank is visualized.
It's a list containing some or all of the following values:
spaces SPACEs and HARD SPACEs are visualized via
faces.
- lines lines whose have columns beyond
+ lines lines which have columns beyond
`whitespace-line-column' are highlighted via
- faces .
+ faces.
Whole line is highlighted.
It has precedence over `lines-tail' (see
below).
- lines-tail lines whose have columns beyond
+ lines-tail lines which have columns beyond
`whitespace-line-column' are highlighted via
faces.
But only the part of line which goes
space-after-tab::tab 8 or more SPACEs after a TAB are
visualized via faces.
- space-after-tab::space TABs are visualized when occurs 8 or
- more SPACEs after a TAB via faces.
+ space-after-tab::space TABs are visualized when 8 or more
+ SPACEs occur after a TAB, via faces.
space-after-tab 8 or more SPACEs after a TAB are
visualized, if `indent-tabs-mode'
space-before-tab::tab SPACEs before TAB are visualized via
faces.
- space-before-tab::space TABs are visualized when occurs SPACEs
- before TAB via faces.
+ space-before-tab::space TABs are visualized when SPACEs occur
+ before TAB, via faces.
space-before-tab SPACEs before TAB are visualized, if
`indent-tabs-mode' (which see) is
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
+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' list. The evaluation order for
(defcustom whitespace-space 'whitespace-space
- "*Symbol face used to visualize SPACE.
+ "Symbol face used to visualize SPACE.
Used when `whitespace-style' includes the value `spaces'."
:type 'face
(defcustom whitespace-hspace 'whitespace-hspace
- "*Symbol face used to visualize HARD SPACE.
+ "Symbol face used to visualize HARD SPACE.
Used when `whitespace-style' includes the value `spaces'."
:type 'face
(defcustom whitespace-tab 'whitespace-tab
- "*Symbol face used to visualize TAB.
+ "Symbol face used to visualize TAB.
Used when `whitespace-style' includes the value `tabs'."
:type 'face
(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'.
(defcustom whitespace-trailing 'whitespace-trailing
- "*Symbol face used to visualize trailing blanks.
+ "Symbol face used to visualize trailing blanks.
Used when `whitespace-style' includes the value `trailing'."
:type 'face
(defcustom whitespace-line 'whitespace-line
- "*Symbol face used to visualize \"long\" lines.
+ "Symbol face used to visualize \"long\" lines.
See `whitespace-line-column'.
(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' includes the value `space-before-tab'."
:type 'face
(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' includes the value `indentation'."
:type 'face
(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' includes the value `empty'."
:type 'face
(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' includes the value `space-after-tab'."
:type 'face
(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:
(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.
(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.
(defcustom whitespace-trailing-regexp
"\\(\\(\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)$"
- "*Specify trailing characters regexp.
+ "Specify trailing characters regexp.
If you're using `mule' package, there may be other characters besides:
(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:
(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.
(defcustom whitespace-empty-at-bob-regexp "\\`\\(\\([ \t]*\n\\)+\\)"
- "*Specify regexp for empty lines at beginning of buffer.
+ "Specify regexp for empty lines at beginning of buffer.
If you're using `mule' package, there may be other characters besides:
(defcustom whitespace-empty-at-eob-regexp "^\\([ \t\n]+\\)\\'"
- "*Specify regexp for empty lines at end of buffer.
+ "Specify regexp for empty lines at end of buffer.
If you're using `mule' package, there may be other characters besides:
(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.
(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' includes `lines' or `lines-tail'."
:type '(integer :tag "Line Length")
;; 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:
(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 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:
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'."
If ARG is null, toggle NEWLINE visualization.
If ARG is a number greater than zero, turn on visualization;
otherwise, turn off visualization.
-Only useful with a windowing system.
Use `whitespace-newline-mode' only for NEWLINE visualization
exclusively. For other visualizations, including NEWLINE
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'."
If ARG is null, toggle NEWLINE visualization.
If ARG is a number greater than zero, turn on visualization;
otherwise, turn off visualization.
-Only useful with a windowing system.
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'.
+please use `global-whitespace-mode'.
See also `whitespace-newline' and `whitespace-display-mappings'."
:lighter " NL"
(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).")
+
;;;###autoload
(defun whitespace-toggle-options (arg)
whitespace-style restore `whitespace-style' value
-Only useful with a windowing system.
-
See `whitespace-style' and `indent-tabs-mode' for documentation."
(interactive (whitespace-interactive-char t))
(let ((whitespace-style
whitespace-style restore `whitespace-style' value
-Only useful with a windowing system.
-
See `whitespace-style' and `indent-tabs-mode' for documentation."
(interactive (whitespace-interactive-char nil))
(let ((whitespace-style
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.
(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)
(whitespace-insert-option-mark
((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)
(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)
+ nil)
+ (add-hook 'post-command-hook #'whitespace-post-command-hook nil t)
;; turn off font lock
(set (make-local-variable 'whitespace-font-lock-mode)
font-lock-mode)
nil
(list
;; Show SPACEs
- (list whitespace-space-regexp 1 whitespace-space t)
+ (list #'whitespace-space-regexp 1 whitespace-space t)
;; Show HARD SPACEs
(list whitespace-hspace-regexp 1 whitespace-hspace t))
t))
nil
(list
;; Show TABs
- (list whitespace-tab-regexp 1 whitespace-tab t))
+ (list #'whitespace-tab-regexp 1 whitespace-tab t))
t))
(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-style)
(memq 'lines-tail whitespace-active-style))
(format
"^\\([^\t\n]\\{%s\\}\\|[^\t\n]\\{0,%s\\}\t\\)\\{%d\\}%s\\(.+\\)$"
whitespace-tab-width (1- whitespace-tab-width)
- (/ whitespace-line-column tab-width)
+ (/ whitespace-line-column whitespace-tab-width)
(let ((rem (% whitespace-line-column whitespace-tab-width)))
(if (zerop rem)
""
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
;; turn off font lock
(when (whitespace-style-face-p)
(font-lock-mode 0)
+ (remove-hook 'post-command-hook #'whitespace-post-command-hook)
(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."
+ (and (/= whitespace-point 1)
+ (re-search-forward whitespace-empty-at-bob-regexp limit t)))
+
+
+(defun whitespace-empty-at-eob-regexp (limit)
+ "Match spaces at end of buffer which do not contain the point at end of \
+buffer."
+ (and (/= whitespace-point (1+ (buffer-size)))
+ (re-search-forward whitespace-empty-at-eob-regexp limit t)))
+
+
+(defun whitespace-space-regexp (limit)
+ "Match spaces."
+ (setq whitespace-font-lock-refontify t)
+ (re-search-forward whitespace-space-regexp limit t))
+
+
+(defun whitespace-tab-regexp (limit)
+ "Match tabs."
+ (setq whitespace-font-lock-refontify t)
+ (re-search-forward whitespace-tab-regexp limit t))
+
+
+(defun whitespace-post-command-hook ()
+ "Save current point into `whitespace-point' variable.
+Also refontify when necessary."
+ (setq whitespace-point (point))
+ (let ((refontify (or (eolp) ; end of line
+ (= whitespace-point 1)))) ; beginning of buffer
+ (when (or whitespace-font-lock-refontify refontify)
+ (setq whitespace-font-lock-refontify refontify)
+ (jit-lock-refontify))))
+
\f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Hacked from visws.el (Miles Bader <miles@gnu.org>)
(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.
+ (set (make-local-variable 'buffer-display-table)
+ (copy-sequence buffer-display-table))
(unless buffer-display-table
(setq buffer-display-table (make-display-table)))
(dolist (entry whitespace-display-mappings)