;;; whitespace.el --- minor mode to visualize TAB, (HARD) SPACE, NEWLINE
-;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-;; Free Software Foundation, Inc.
+;; Copyright (C) 2000-2013 Free Software Foundation, Inc.
;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br>
;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br>
;; Keywords: data, wp
-;; Version: 13.1
+;; Version: 13.2.2
;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
;; This file is part of GNU Emacs.
;; There are also the following useful commands:
;;
;; `whitespace-newline-mode'
-;; Toggle NEWLINE minor mode visualization ("nl" on modeline).
+;; Toggle NEWLINE minor mode visualization ("nl" on mode line).
;;
;; `global-whitespace-newline-mode'
-;; Toggle NEWLINE global minor mode visualization ("NL" on modeline).
+;; Toggle NEWLINE global minor mode visualization ("NL" on mode line).
;;
;; `whitespace-report'
;; Report some blank problems in buffer.
;; buffer is visited or written.
;;
;;
-;; Acknowledgements
-;; ----------------
+;; Acknowledgments
+;; ---------------
+;;
+;; Thanks to felix (EmacsWiki) for keeping highlight when switching between
+;; major modes on a file.
;;
;; Thanks to David Reitter <david.reitter@gmail.com> for suggesting a
;; `whitespace-newline' initialization with low contrast relative to
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
+cleaning up a buffer. See `whitespace-cleanup' and
`whitespace-cleanup-region' for documentation.
See also `whitespace-display-mappings' for documentation."
(const :tag "(Mark) NEWLINEs" newline-mark)))
:group 'whitespace)
-
-(defcustom whitespace-space 'whitespace-space
+(defvar whitespace-space 'whitespace-space
"Symbol face used to visualize SPACE.
-
-Used when `whitespace-style' includes the value `spaces'."
- :type 'face
- :group 'whitespace)
+Used when `whitespace-style' includes the value `spaces'.")
+(make-obsolete-variable 'whitespace-space "use the face instead" "24.4")
(defface whitespace-space
'((((class color) (background dark))
- (:background "grey20" :foreground "darkgray"))
+ :background "grey20" :foreground "darkgray")
(((class color) (background light))
- (:background "LightYellow" :foreground "lightgray"))
- (t (:inverse-video t)))
+ :background "LightYellow" :foreground "lightgray")
+ (t :inverse-video t))
"Face used to visualize SPACE."
:group 'whitespace)
-(defcustom whitespace-hspace 'whitespace-hspace
+(defvar whitespace-hspace 'whitespace-hspace
"Symbol face used to visualize HARD SPACE.
-
-Used when `whitespace-style' includes the value `spaces'."
- :type 'face
- :group 'whitespace)
-
+Used when `whitespace-style' includes the value `spaces'.")
+(make-obsolete-variable 'whitespace-hspace "use the face instead" "24.4")
(defface whitespace-hspace ; 'nobreak-space
'((((class color) (background dark))
- (:background "grey24" :foreground "darkgray"))
+ :background "grey24" :foreground "darkgray")
(((class color) (background light))
- (:background "LemonChiffon3" :foreground "lightgray"))
- (t (:inverse-video t)))
+ :background "LemonChiffon3" :foreground "lightgray")
+ (t :inverse-video t))
"Face used to visualize HARD SPACE."
:group 'whitespace)
-(defcustom whitespace-tab 'whitespace-tab
+(defvar whitespace-tab 'whitespace-tab
"Symbol face used to visualize TAB.
-
-Used when `whitespace-style' includes the value `tabs'."
- :type 'face
- :group 'whitespace)
-
+Used when `whitespace-style' includes the value `tabs'.")
+(make-obsolete-variable 'whitespace-tab "use the face instead" "24.4")
(defface whitespace-tab
'((((class color) (background dark))
- (:background "grey22" :foreground "darkgray"))
+ :background "grey22" :foreground "darkgray")
(((class color) (background light))
- (:background "beige" :foreground "lightgray"))
- (t (:inverse-video t)))
+ :background "beige" :foreground "lightgray")
+ (t :inverse-video t))
"Face used to visualize TAB."
:group 'whitespace)
-(defcustom whitespace-newline 'whitespace-newline
+(defvar whitespace-newline 'whitespace-newline
"Symbol face used to visualize NEWLINE char mapping.
-
See `whitespace-display-mappings'.
-
Used when `whitespace-style' includes the values `newline-mark'
-and `newline'."
- :type 'face
- :group 'whitespace)
-
+and `newline'.")
+(make-obsolete-variable 'whitespace-newline "use the face instead" "24.4")
(defface whitespace-newline
- '((((class color) (background dark))
- (:foreground "darkgray" :bold nil))
- (((class color) (background light))
- (:foreground "lightgray" :bold nil))
- (t (:underline t :bold nil)))
+ '((default :weight normal)
+ (((class color) (background dark)) :foreground "darkgray")
+ (((class color) (min-colors 88) (background light)) :foreground "lightgray")
+ ;; Displays with 16 colors use lightgray as background, so using a
+ ;; lightgray foreground makes the newline mark invisible.
+ (((class color) (background light)) :foreground "brown")
+ (t :underline t))
"Face used to visualize NEWLINE char mapping.
See `whitespace-display-mappings'."
:group 'whitespace)
-(defcustom whitespace-trailing 'whitespace-trailing
+(defvar whitespace-trailing 'whitespace-trailing
"Symbol face used to visualize trailing blanks.
-
-Used when `whitespace-style' includes the value `trailing'."
- :type 'face
- :group 'whitespace)
-
+Used when `whitespace-style' includes the value `trailing'.")
+(make-obsolete-variable 'whitespace-trailing "use the face instead" "24.4")
(defface whitespace-trailing ; 'trailing-whitespace
- '((((class mono)) (:inverse-video t :bold t :underline t))
- (t (:background "red1" :foreground "yellow" :bold t)))
+ '((default :weight bold)
+ (((class mono)) :inverse-video t :underline t)
+ (t :background "red1" :foreground "yellow"))
"Face used to visualize trailing blanks."
:group 'whitespace)
-(defcustom whitespace-line 'whitespace-line
+(defvar whitespace-line 'whitespace-line
"Symbol face used to visualize \"long\" lines.
-
See `whitespace-line-column'.
-
-Used when `whitespace-style' includes the value `line'."
- :type 'face
- :group 'whitespace)
-
+Used when `whitespace-style' includes the value `line'.")
+(make-obsolete-variable 'whitespace-line "use the face instead" "24.4")
(defface whitespace-line
- '((((class mono)) (:inverse-video t :bold t :underline t))
- (t (:background "gray20" :foreground "violet")))
+ '((((class mono)) :inverse-video t :weight bold :underline t)
+ (t :background "gray20" :foreground "violet"))
"Face used to visualize \"long\" lines.
See `whitespace-line-column'."
:group 'whitespace)
-(defcustom whitespace-space-before-tab 'whitespace-space-before-tab
+(defvar whitespace-space-before-tab 'whitespace-space-before-tab
"Symbol face used to visualize SPACEs before TAB.
-
-Used when `whitespace-style' includes the value `space-before-tab'."
- :type 'face
- :group 'whitespace)
-
+Used when `whitespace-style' includes the value `space-before-tab'.")
+(make-obsolete-variable 'whitespace-space-before-tab
+ "use the face instead" "24.4")
(defface whitespace-space-before-tab
- '((((class mono)) (:inverse-video t :bold t :underline t))
- (t (:background "DarkOrange" :foreground "firebrick")))
+ '((((class mono)) :inverse-video t :weight bold :underline t)
+ (t :background "DarkOrange" :foreground "firebrick"))
"Face used to visualize SPACEs before TAB."
:group 'whitespace)
-(defcustom whitespace-indentation 'whitespace-indentation
+(defvar whitespace-indentation 'whitespace-indentation
"Symbol face used to visualize 8 or more SPACEs at beginning of line.
-
-Used when `whitespace-style' includes the value `indentation'."
- :type 'face
- :group 'whitespace)
-
+Used when `whitespace-style' includes the value `indentation'.")
+(make-obsolete-variable 'whitespace-indentation "use the face instead" "24.4")
(defface whitespace-indentation
- '((((class mono)) (:inverse-video t :bold t :underline t))
- (t (:background "yellow" :foreground "firebrick")))
+ '((((class mono)) :inverse-video t :weight bold :underline t)
+ (t :background "yellow" :foreground "firebrick"))
"Face used to visualize 8 or more SPACEs at beginning of line."
:group 'whitespace)
-(defcustom whitespace-empty 'whitespace-empty
+(defvar whitespace-empty 'whitespace-empty
"Symbol face used to visualize empty lines at beginning and/or end of buffer.
-
-Used when `whitespace-style' includes the value `empty'."
- :type 'face
- :group 'whitespace)
-
+Used when `whitespace-style' includes the value `empty'.")
+(make-obsolete-variable 'whitespace-empty "use the face instead" "24.4")
(defface whitespace-empty
- '((((class mono)) (:inverse-video t :bold t :underline t))
- (t (:background "yellow" :foreground "firebrick")))
+ '((((class mono)) :inverse-video t :weight bold :underline t)
+ (t :background "yellow" :foreground "firebrick"))
"Face used to visualize empty lines at beginning and/or end of buffer."
:group 'whitespace)
-(defcustom whitespace-space-after-tab 'whitespace-space-after-tab
+(defvar whitespace-space-after-tab 'whitespace-space-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
- :group 'whitespace)
-
+Used when `whitespace-style' includes the value `space-after-tab'.")
+(make-obsolete-variable 'whitespace-space-after-tab
+ "use the face instead" "24.4")
(defface whitespace-space-after-tab
- '((((class mono)) (:inverse-video t :bold t :underline t))
- (t (:background "yellow" :foreground "firebrick")))
+ '((((class mono)) :inverse-video t :weight bold :underline t)
+ (t :background "yellow" :foreground "firebrick"))
"Face used to visualize 8 or more SPACEs after TAB."
:group 'whitespace)
(defcustom whitespace-hspace-regexp
- "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)"
+ "\\(\u00A0+\\)"
"Specify HARD SPACE characters regexp.
-If you're using `mule' package, there may be other characters besides:
-
- \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \"\\xF20\"
-
-that should be considered HARD SPACE.
-
Here are some examples:
\"\\\\(^\\xA0+\\\\)\" \
(defcustom whitespace-trailing-regexp
- "\\(\\(\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)$"
+ "\\([\t \u00A0]+\\)$"
"Specify trailing characters regexp.
-If you're using `mule' package, there may be other characters besides:
+There may be other characters besides:
- \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
-\"\\xF20\"
+ \" \" \"\\t\" \"\\u00A0\"
that should be considered blank.
(defcustom whitespace-space-before-tab-regexp "\\( +\\)\\(\t+\\)"
"Specify SPACEs before TAB regexp.
-If you're using `mule' package, there may be other characters besides:
-
- \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
-\"\\xF20\"
-
-that should be considered blank.
-
Used when `whitespace-style' includes `space-before-tab',
`space-before-tab::tab' or `space-before-tab::space'."
:type '(regexp :tag "SPACEs Before TAB")
It is a cons where the cons car is used for SPACEs visualization
and the cons cdr is used for TABs visualization.
-If you're using `mule' package, there may be other characters besides:
-
- \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
-\"\\xF20\"
-
-that should be considered blank.
-
Used when `whitespace-style' includes `indentation',
`indentation::tab' or `indentation::space'."
- :type '(cons (regexp :tag "Indentation SPACEs")
- (regexp :tag "Indentation TABs"))
+ :type '(cons (string :tag "Indentation SPACEs")
+ (string :tag "Indentation TABs"))
:group 'whitespace)
(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:
-
- \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
-\"\\xF20\"
-
-that should be considered blank.
-
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.
-If you're using `mule' package, there may be other characters besides:
-
- \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
-\"\\xF20\"
-
-that should be considered blank.
-
Used when `whitespace-style' includes `empty'."
:type '(regexp :tag "Empty Lines At End Of Buffer")
:group 'whitespace)
It is a cons where the cons car is used for SPACEs visualization
and the cons cdr is used for TABs visualization.
-If you're using `mule' package, there may be other characters besides:
-
- \" \" \"\\t\" \"\\xA0\" \"\\x8A0\" \"\\x920\" \"\\xE20\" \
-\"\\xF20\"
-
-that should be considered blank.
-
Used when `whitespace-style' includes `space-after-tab',
`space-after-tab::tab' or `space-after-tab::space'."
- :type '(regexp :tag "SPACEs After TAB")
+ :type '(cons (string :tag "SPACEs After TAB")
+ string)
:group 'whitespace)
'(
(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
- (space-mark ?\xF20 [?\xF24] [?_]) ; 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 [?\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
+ ;; (newline-mark ?\n [?\u00AF ?\n] [?$ ?\n]) ; eol - overscore
+ ;; (newline-mark ?\n [?\u00AC ?\n] [?$ ?\n]) ; eol - negation
+ ;; (newline-mark ?\n [?\u00B0 ?\n] [?$ ?\n]) ; eol - degrees
;;
;; WARNING: the mapping below has a problem.
;; When a TAB occupies exactly one column, it will display the
;;;###autoload
(define-minor-mode whitespace-mode
- "Toggle whitespace minor mode visualization (\"ws\" on modeline).
-
-If ARG is null, toggle whitespace visualization.
-If ARG is a number greater than zero, turn on visualization;
-otherwise, turn off visualization.
+ "Toggle whitespace visualization (Whitespace mode).
+With a prefix argument ARG, enable Whitespace mode if ARG is
+positive, and disable it otherwise. If called from Lisp, enable
+the mode if ARG is omitted or nil.
See also `whitespace-style', `whitespace-newline' and
`whitespace-display-mappings'."
;;;###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.
+ "Toggle newline visualization (Whitespace Newline mode).
+With a prefix argument ARG, enable Whitespace Newline mode if ARG
+is positive, and disable it otherwise. If called from Lisp,
+enable the mode if ARG is omitted or nil.
Use `whitespace-newline-mode' only for NEWLINE visualization
exclusively. For other visualizations, including NEWLINE
: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)))
+ (let ((whitespace-style '(face newline-mark newline)))
+ (whitespace-mode (if whitespace-newline-mode
+ 1 -1)))
+ ;; sync states (running a batch job)
+ (setq whitespace-newline-mode whitespace-mode))
\f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;###autoload
(define-minor-mode global-whitespace-mode
- "Toggle whitespace global minor mode visualization (\"WS\" on modeline).
-
-If ARG is null, toggle whitespace visualization.
-If ARG is a number greater than zero, turn on visualization;
-otherwise, turn off visualization.
+ "Toggle whitespace visualization globally (Global Whitespace mode).
+With a prefix argument ARG, enable Global Whitespace mode if ARG
+is positive, and disable it otherwise. If called from Lisp,
+enable it if ARG is omitted or nil.
See also `whitespace-style', `whitespace-newline' and
`whitespace-display-mappings'."
(noninteractive ; running a batch job
(setq global-whitespace-mode nil))
(global-whitespace-mode ; global-whitespace-mode on
- (save-excursion
+ (save-current-buffer
(add-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
+ (add-hook 'after-change-major-mode-hook 'whitespace-turn-on-if-enabled)
(dolist (buffer (buffer-list)) ; adjust all local mode
(set-buffer buffer)
(unless whitespace-mode
(whitespace-turn-on-if-enabled)))))
(t ; global-whitespace-mode off
- (save-excursion
+ (save-current-buffer
(remove-hook 'find-file-hook 'whitespace-turn-on-if-enabled)
+ (remove-hook 'after-change-major-mode-hook 'whitespace-turn-on-if-enabled)
(dolist (buffer (buffer-list)) ; adjust all local mode
(set-buffer buffer)
(unless whitespace-mode
(whitespace-turn-off)))))))
+(defvar whitespace-enable-predicate
+ (lambda ()
+ (and (cond
+ ((eq whitespace-global-modes t))
+ ((listp whitespace-global-modes)
+ (if (eq (car-safe whitespace-global-modes) 'not)
+ (not (memq major-mode (cdr whitespace-global-modes)))
+ (memq major-mode whitespace-global-modes)))
+ (t nil))
+ ;; ...we have a display (we're running a batch job)
+ (not noninteractive)
+ ;; ...the buffer is not internal (name starts with a space)
+ (not (eq (aref (buffer-name) 0) ?\ ))
+ ;; ...the buffer is not special (name starts with *)
+ (or (not (eq (aref (buffer-name) 0) ?*))
+ ;; except the scratch buffer.
+ (string= (buffer-name) "*scratch*"))))
+ "Predicate to decide which buffers obey `global-whitespace-mode'.
+This function is called with no argument and should return non-nil
+if the current buffer should obey `global-whitespace-mode'.
+This variable is normally modified via `add-function'.")
(defun whitespace-turn-on-if-enabled ()
- (when (cond
- ((eq whitespace-global-modes t))
- ((listp whitespace-global-modes)
- (if (eq (car-safe whitespace-global-modes) 'not)
- (not (memq major-mode (cdr whitespace-global-modes)))
- (memq major-mode whitespace-global-modes)))
- (t nil))
- (let (inhibit-quit)
- ;; Don't turn on whitespace mode if...
- (or
- ;; ...we don't have a display (we're running a batch job)
- noninteractive
- ;; ...or if the buffer is invisible (name starts with a space)
- (eq (aref (buffer-name) 0) ?\ )
- ;; ...or if the buffer is temporary (name starts with *)
- (and (eq (aref (buffer-name) 0) ?*)
- ;; except the scratch buffer.
- (not (string= (buffer-name) "*scratch*")))
- ;; Otherwise, turn on whitespace mode.
- (whitespace-turn-on)))))
-
+ (when (funcall whitespace-enable-predicate)
+ (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.
+ "Toggle global newline visualization (Global Whitespace Newline mode).
+With a prefix argument ARG, enable Global Whitespace Newline mode
+if ARG is positive, and disable it otherwise. If called from
+Lisp, enable it if ARG is omitted or nil.
Use `global-whitespace-newline-mode' only for NEWLINE
visualization exclusively. For other visualizations, including
(defvar whitespace-point (point)
"Used to save locally current point value.
-Used by `whitespace-trailing-regexp' function (which see).")
+Used by function `whitespace-trailing-regexp' (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).")
+Used by function `whitespace-post-command-hook' (which see).")
(defvar whitespace-bob-marker nil
"Used to save locally the bob marker value.
-Used by `whitespace-post-command-hook' function (which see).")
+Used by function `whitespace-post-command-hook' (which see).")
(defvar whitespace-eob-marker nil
"Used to save locally the eob marker value.
-Used by `whitespace-post-command-hook' function (which see).")
+Used by function `whitespace-post-command-hook' (which see).")
(defvar whitespace-buffer-changed nil
"Used to indicate locally if buffer changed.
;; whole buffer
(t
(save-excursion
- (save-match-data
+ (save-match-data ;FIXME: Why?
;; 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)
(let (overwrite-mode) ; enforce no overwrite
(goto-char (point-min))
- (when (re-search-forward
- (concat "\\`" whitespace-empty-at-bob-regexp) nil t)
+ (when (looking-at whitespace-empty-at-bob-regexp)
(delete-region (match-beginning 1) (match-end 1)))
(when (re-search-forward
(concat whitespace-empty-at-eob-regexp "\\'") nil t)
;; PROBLEM 6: 8 or more SPACEs after TAB
(whitespace-cleanup-region (point-min) (point-max)))))
+(defun whitespace-ensure-local-variables ()
+ "Set `whitespace-indent-tabs-mode' and `whitespace-tab-width' locally."
+ (set (make-local-variable 'whitespace-indent-tabs-mode)
+ indent-tabs-mode)
+ (set (make-local-variable 'whitespace-tab-width)
+ tab-width))
;;;###autoload
(defun whitespace-cleanup-region (start end)
;; read-only buffer
(whitespace-warn-read-only "cleanup region")
;; non-read-only buffer
+ (whitespace-ensure-local-variables)
(let ((rstart (min start end))
(rend (copy-marker (max start end)))
(indent-tabs-mode whitespace-indent-tabs-mode)
overwrite-mode ; enforce no overwrite
tmp)
(save-excursion
- (save-match-data
+ (save-match-data ;FIXME: Why?
;; PROBLEM 1: 8 or more SPACEs at bol
(cond
;; ACTION: replace 8 or more SPACEs at bol by TABs, if
(whitespace-replace-action
(if whitespace-indent-tabs-mode 'tabify 'untabify)
rstart rend whitespace-space-before-tab-regexp
- (if whitespace-indent-tabs-mode 1 2)))
+ (if whitespace-indent-tabs-mode 0 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))
+ whitespace-space-before-tab-regexp 0))
;; ACTION: replace TABs by SPACEs.
((memq 'space-before-tab::space whitespace-style)
(whitespace-replace-action
(interactive "r")
(setq force (or current-prefix-arg force))
(save-excursion
- (save-match-data
+ (save-match-data ;FIXME: Why?
(let* ((has-bogus nil)
(rstart (min start end))
(rend (max start end))
;;;; Internal functions
-(defvar whitespace-font-lock-mode nil
- "Used to remember whether a buffer had font lock mode on or not.")
-
-(defvar whitespace-font-lock nil
- "Used to remember whether a buffer initially had font lock on or not.")
-
(defvar whitespace-font-lock-keywords nil
- "Used to save locally `font-lock-keywords' value.")
+ "Used to save the value `whitespace-color-on' adds to `font-lock-keywords'.")
(defconst whitespace-help-text
"Scroll help window, if it exists.
If UP is non-nil, scroll up; otherwise, scroll down."
- (condition-case data-help
+ (condition-case nil
(let ((buffer (get-buffer whitespace-help-buffer-name)))
(if buffer
(with-selected-window (get-buffer-window buffer)
(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
(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)
(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)
+ (whitespace-ensure-local-variables)
;; turn on whitespace
(when whitespace-active-style
(whitespace-color-on)
(defun whitespace-color-on ()
"Turn on color visualization."
(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))
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-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show SPACEs
- (list whitespace-space-regexp 1 whitespace-space t)
- ;; Show HARD SPACEs
- (list whitespace-hspace-regexp 1 whitespace-hspace t))
- t))
- (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-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show trailing blanks
- (list #'whitespace-trailing-regexp 1 whitespace-trailing t))
- t))
- (when (or (memq 'lines whitespace-active-style)
- (memq 'lines-tail whitespace-active-style))
- (font-lock-add-keywords
- nil
- (list
- ;; Show "long" lines
- (list
- (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-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show SPACEs before TAB (indent-tabs-mode)
- (list whitespace-space-before-tab-regexp
- (if whitespace-indent-tabs-mode 1 2)
- whitespace-space-before-tab t))
- t))
- ((memq 'space-before-tab::tab whitespace-active-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show SPACEs before TAB (SPACEs)
- (list whitespace-space-before-tab-regexp
- 1 whitespace-space-before-tab t))
- t))
- ((memq 'space-before-tab::space whitespace-active-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show SPACEs before TAB (TABs)
- (list whitespace-space-before-tab-regexp
- 2 whitespace-space-before-tab t))
- t)))
- (cond
- ((memq 'indentation whitespace-active-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show indentation SPACEs (indent-tabs-mode)
- (list (whitespace-indentation-regexp)
- 1 whitespace-indentation t))
- t))
- ((memq 'indentation::tab whitespace-active-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show indentation SPACEs (SPACEs)
- (list (whitespace-indentation-regexp 'tab)
- 1 whitespace-indentation t))
- t))
- ((memq 'indentation::space whitespace-active-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show indentation SPACEs (TABs)
- (list (whitespace-indentation-regexp 'space)
- 1 whitespace-indentation t))
- t)))
- (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
- 1 whitespace-empty t))
- t)
- (font-lock-add-keywords
- nil
- (list
- ;; Show empty lines at end of buffer
- (list #'whitespace-empty-at-eob-regexp
- 1 whitespace-empty t))
- t))
- (cond
- ((memq 'space-after-tab whitespace-active-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show SPACEs after TAB (indent-tabs-mode)
- (list (whitespace-space-after-tab-regexp)
- 1 whitespace-space-after-tab t))
- t))
- ((memq 'space-after-tab::tab whitespace-active-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show SPACEs after TAB (SPACEs)
- (list (whitespace-space-after-tab-regexp 'tab)
- 1 whitespace-space-after-tab t))
- t))
- ((memq 'space-after-tab::space whitespace-active-style)
- (font-lock-add-keywords
- nil
- (list
- ;; Show SPACEs after TAB (TABs)
- (list (whitespace-space-after-tab-regexp 'space)
- 1 whitespace-space-after-tab t))
- t)))
- ;; now turn on font lock and highlight blanks
- (font-lock-mode 1)))
+ ;; Add whitespace-mode color into font lock.
+ (setq
+ whitespace-font-lock-keywords
+ `(
+ ,@(when (memq 'spaces whitespace-active-style)
+ ;; Show SPACEs.
+ `((,whitespace-space-regexp 1 whitespace-space t)
+ ;; Show HARD SPACEs.
+ (,whitespace-hspace-regexp 1 whitespace-hspace t)))
+ ,@(when (memq 'tabs whitespace-active-style)
+ ;; Show TABs.
+ `((,whitespace-tab-regexp 1 whitespace-tab t)))
+ ,@(when (memq 'trailing whitespace-active-style)
+ ;; Show trailing blanks.
+ `((,#'whitespace-trailing-regexp 1 whitespace-trailing t)))
+ ,@(when (or (memq 'lines whitespace-active-style)
+ (memq 'lines-tail whitespace-active-style))
+ ;; Show "long" lines.
+ `((,(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 prepend)))
+ ,@(when (or (memq 'space-before-tab whitespace-active-style)
+ (memq 'space-before-tab::tab whitespace-active-style)
+ (memq 'space-before-tab::space whitespace-active-style))
+ `((,whitespace-space-before-tab-regexp
+ ,(cond
+ ((memq 'space-before-tab whitespace-active-style)
+ ;; Show SPACEs before TAB (indent-tabs-mode).
+ (if whitespace-indent-tabs-mode 1 2))
+ ((memq 'space-before-tab::tab whitespace-active-style)
+ 1)
+ ((memq 'space-before-tab::space whitespace-active-style)
+ 2))
+ whitespace-space-before-tab t)))
+ ,@(when (or (memq 'indentation whitespace-active-style)
+ (memq 'indentation::tab whitespace-active-style)
+ (memq 'indentation::space whitespace-active-style))
+ `((,(cond
+ ((memq 'indentation whitespace-active-style)
+ ;; Show indentation SPACEs (indent-tabs-mode).
+ (whitespace-indentation-regexp))
+ ((memq 'indentation::tab whitespace-active-style)
+ ;; Show indentation SPACEs (SPACEs).
+ (whitespace-indentation-regexp 'tab))
+ ((memq 'indentation::space whitespace-active-style)
+ ;; Show indentation SPACEs (TABs).
+ (whitespace-indentation-regexp 'space)))
+ 1 whitespace-indentation t)))
+ ,@(when (memq 'empty whitespace-active-style)
+ ;; Show empty lines at beginning of buffer.
+ `((,#'whitespace-empty-at-bob-regexp
+ 1 whitespace-empty t)
+ ;; Show empty lines at end of buffer.
+ (,#'whitespace-empty-at-eob-regexp
+ 1 whitespace-empty t)))
+ ,@(when (or (memq 'space-after-tab whitespace-active-style)
+ (memq 'space-after-tab::tab whitespace-active-style)
+ (memq 'space-after-tab::space whitespace-active-style))
+ `((,(cond
+ ((memq 'space-after-tab whitespace-active-style)
+ ;; Show SPACEs after TAB (indent-tabs-mode).
+ (whitespace-space-after-tab-regexp))
+ ((memq 'space-after-tab::tab whitespace-active-style)
+ ;; Show SPACEs after TAB (SPACEs).
+ (whitespace-space-after-tab-regexp 'tab))
+ ((memq 'space-after-tab::space whitespace-active-style)
+ ;; Show SPACEs after TAB (TABs).
+ (whitespace-space-after-tab-regexp 'space)))
+ 1 whitespace-space-after-tab t)))))
+ (font-lock-add-keywords nil whitespace-font-lock-keywords t)
+ (when font-lock-mode
+ (font-lock-fontify-buffer))))
(defun whitespace-color-off ()
"Turn off color visualization."
;; 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)))
+ (font-lock-remove-keywords nil whitespace-font-lock-keywords)
+ (when font-lock-mode
+ (font-lock-fontify-buffer))))
(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
+ (= whitespace-point (match-end 1)) ;; loop if point at eol
+ (setq status nil))) ;; end of buffer
status))
((= 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)))
+ (set-marker whitespace-bob-marker (if r (match-end 1) b)))
;; inside bob empty region
((<= limit whitespace-bob-marker)
(setq r (looking-at whitespace-empty-at-bob-regexp))
;; 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)))
+ (set-marker whitespace-bob-marker (if r (match-end 1) b)))
;; it is not inside bob empty region
(t
(setq r nil)))
r))
-(defun whitespace-buffer-changed (beg end)
+(defun whitespace-buffer-changed (_beg _end)
"Set `whitespace-buffer-changed' variable to t."
(setq whitespace-buffer-changed t))
(setq whitespace-display-table-was-local t
whitespace-display-table
(copy-sequence buffer-display-table))
- ;; asure `buffer-display-table' is unique
+ ;; Assure `buffer-display-table' is unique
;; when two or more windows are visible.
(setq buffer-display-table
(copy-sequence buffer-display-table)))
(run-hooks 'whitespace-load-hook)
-;; arch-tag: 1b1e2500-dbd4-4a26-8f7a-5a5edfd3c97e
;;; whitespace.el ends here