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