From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Vinicius Jose Latorre Newsgroups: gmane.emacs.devel Subject: Re: blank-mode.el Date: Wed, 31 Oct 2007 01:16:29 -0300 Message-ID: <4728019D.6040903@ig.com.br> References: <47251573.90509@ig.com.br> <87k5p6me9s.fsf@kfs-lx.testafd.dk> <4725FE3F.9020000@ig.com.br> <87ejfczrru.fsf@jurta.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------040705080204020302080801" X-Trace: ger.gmane.org 1193800326 5236 80.91.229.12 (31 Oct 2007 03:12:06 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 31 Oct 2007 03:12:06 +0000 (UTC) Cc: emacs-devel@gnu.org To: Juri Linkov Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Oct 31 04:12:06 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1In3zu-00009j-O6 for ged-emacs-devel@m.gmane.org; Wed, 31 Oct 2007 04:12:04 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1In3zk-0000nN-L6 for ged-emacs-devel@m.gmane.org; Tue, 30 Oct 2007 23:11:52 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1In3zg-0000hz-2z for emacs-devel@gnu.org; Tue, 30 Oct 2007 23:11:48 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1In3zd-0000cA-LU for emacs-devel@gnu.org; Tue, 30 Oct 2007 23:11:47 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1In3zd-0000bs-IE for emacs-devel@gnu.org; Tue, 30 Oct 2007 23:11:45 -0400 Original-Received: from an-out-0708.google.com ([209.85.132.246]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1In3zc-0005IO-WD for emacs-devel@gnu.org; Tue, 30 Oct 2007 23:11:45 -0400 Original-Received: by an-out-0708.google.com with SMTP id c38so608ana for ; Tue, 30 Oct 2007 20:11:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:user-agent:mime-version:to:cc:subject:references:in-reply-to:content-type:sender; bh=xpWOS6dNioC6nx/gdKNpbabEY1uc4K4M0oSsQioENpA=; b=VdbAf0GFdR1g8a5u2Fduy0Xv6iXcGt1NkW6dm934TGALnyofG99Vrc3E7E5n/SrUTeKd5iHZabmhQUGUwiR9P+gtU2aXG2SobZ5qfBXioQJ/WuBz13kX9PFIZGl2jv9fYTNRff4vChPexvXq6z0QaCD4GV3bxpEBUDGXyb6iI+A= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:user-agent:mime-version:to:cc:subject:references:in-reply-to:content-type:sender; b=NlVUHvjOCzb/Q8cCG/AHafIW278aD7UHE7utJGx+TgeFPcquxCX6vi4VGpCOUbsDOTNABZZrzG840olJ4R6N91i3qkVWQsv3IOJTtXxxkWkKU2nWxhbo0Dbja0rrfjyyqKvInoqE2wIKfXJzUEhuc5FbpSZJgXAZtbLskoVfqXY= Original-Received: by 10.100.207.5 with SMTP id e5mr1190657ang.1193800304191; Tue, 30 Oct 2007 20:11:44 -0700 (PDT) Original-Received: from ?192.168.0.100? ( [201.82.131.44]) by mx.google.com with ESMTPS id c20sm18826ana.2007.10.30.20.11.37 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 30 Oct 2007 20:11:40 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.8) Gecko/20071009 SeaMonkey/1.1.5 In-Reply-To: <87ejfczrru.fsf@jurta.org> X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 2) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:82185 Archived-At: This is a multi-part message in MIME format. --------------040705080204020302080801 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit The blank-mode.el (attached in this email) now has the toggle funs: blank-toggle blank-toggle-global If it's called interactively, it reads a char. If it's called non-interactively, it should be passed a symbol or a list of symbols. Please, read the fun docstring. Juri Linkov wrote: >>>> So, if blank-toggle is binded to a key, for example, C-c b, then the >>>> user could >>>> type: >>>> >>>> C-c b t toggle tabs >>>> C-c b s toggle spaces and hard spaces >>>> C-c b r toggle trailing blanks >>>> C-c b b toggle spaces before tab >>>> C-c b l toggle lines >>> I like the idea (and blank-mode in general), > > I like this package too, and I have some suggestions: since it implements > a minor mode I suggest defining it with `define-minor-mode', and name the > global mode `global-blank-mode'. Well, I'll try to use define-minor-mode in the next blank-mode version. Is there some convention (or consensus) about global mode name? > Also I have a question how it interacts with nobreak-char-display. > Does your package overwrite highlighting of nobreak space displayed > by nobreak-char-display feature, or ignores it? I've made some tests and both blank-mode faces and display table are displayed when blank-mode is on and nobreak-char-display is t. When blank-mode is turned off and nobreak-char-display is t, the nobreak-char-display faces and display table are displayed. That is, blank-mode have precedence over nobreak-char-display but only over hard spaces (or nobreak spaces), the soft hyphens is handled only by nobreak-char-display. The same occurs with show-trailing-whitespace feature. >>> but according to the >>> Emacs Lisp reference, C-c b is reserved for major modes: >>> >>> The key sequences bound in a minor mode should consist of `C-c' >>> followed by one of `.,/?`'"[]\|~!#$%^&*()-_+='. (The other punctuation >>> characters are reserved for major modes.) >> No problem, the key binding above was only an example, it could be any >> other key binding. > > I think a key prefix with good mnemonics for blank-minor-mode is `C-c _'. Cool! At moment blank-mode doesn't have any key binding, this is left to the user do. But I'll put a tip in blank-mode documentation suggesting the key prefix `C-c _'. --------------040705080204020302080801 Content-Type: text/plain; name="blank-mode.el" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="blank-mode.el" ;;; blank-mode.el --- Minor mode to visualise blanks (SPACE, HARD SPACE and TAB). ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 ;; Vinicius Jose Latorre ;; Time-stamp: <2007/10/31 00:49:12 vinicius> ;; Author: Vinicius Jose Latorre ;; Maintainer: Vinicius Jose Latorre ;; Keywords: data, wp ;; Version: 7.0 ;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre ;; This file is *NOT* (yet?) part of GNU Emacs. ;; This program is free software; you can redistribute it and/or modify it ;; under the terms of the GNU General Public License as published by the Free ;; Software Foundation; either version 2, or (at your option) any later ;; version. ;; This program is distributed in the hope that it will be useful, but WITHOUT ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ;; more details. ;; You should have received a copy of the GNU General Public License along with ;; GNU Emacs; see the file COPYING. If not, write to the Free Software ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ;;; Commentary: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Introduction ;; ------------ ;; ;; This package is a minor mode to visualise blanks (SPACE, HARD SPACE and ;; TAB). ;; ;; blank-mode uses two ways to visualise blanks: faces and display table. ;; ;; * Faces are used to highlight the background with a color. blank-mode uses ;; font-lock to highlight blank characters. ;; ;; * Display table changes the way a character is displayed, that is, it ;; provides a visual mark for characters, for example, at the end of line ;; (?\xB6), at spaces (?\xB7) and at tabs (?\xBB). ;; ;; The `blank-style' and `blank-chars' variables are used to select which way ;; should be used to visualise blanks. ;; ;; Note that when blank-mode is turned on, blank-mode saves the font-lock ;; state, that is, if font-lock is on or off. And blank-mode restores the ;; font-lock state when it is turned off. So, if blank-mode is turned on and ;; font-lock is off, blank-mode also turns on the font-lock to highlight ;; blanks, but the font-lock will be turned off when blank-mode is turned off. ;; Thus, turn on font-lock before blank-mode is on, if you want that font-lock ;; continues on after blank-mode is turned off. ;; ;; To use blank-mode, insert in your ~/.emacs: ;; ;; (require 'blank-mode) ;; ;; Or: ;; ;; (autoload 'blank-mode-on "blank-mode" ;; "Turn on blank visualisation." t) ;; (autoload 'blank-mode-off "blank-mode" ;; "Turn off blank visualisation." t) ;; (autoload 'blank-mode "blank-mode" ;; "Toggle blank visualisation." t) ;; (autoload 'blank-global-mode-on "blank-mode" ;; "Turn on blank mode in every buffer." t) ;; (autoload 'blank-global-mode-off "blank-mode" ;; "Turn off blank mode in every buffer." t) ;; (autoload 'blank-global-mode "blank-mode" ;; "Toggle blank mode in every buffer." t) ;; (autoload 'blank-mode-customize "blank-mode" ;; "Customize blank visualisation." t) ;; ;; For good performance, be sure to byte-compile blank-mode.el, e.g. ;; ;; M-x byte-compile-file ;; ;; This will generate blank-mode.elc, which will be loaded instead of ;; blank-mode.el. ;; ;; blank-mode was tested with GNU Emacs 20.6.1, 21 and 22. ;; ;; ;; Using blank-mode ;; ---------------- ;; ;; There is no problem if you mix local and global minor mode usage. ;; ;; * To customize blank-mode, type: ;; ;; M-x blank-mode-customize RET ;; ;; * LOCAL blank-mode: ;; + To activate blank-mode locally, type: ;; ;; M-x blank-mode-on RET ;; ;; Or: ;; ;; C-u 1 M-x blank-mode RET ;; ;; + To deactivate blank-mode locally, type: ;; ;; M-x blank-mode-off RET ;; ;; Or: ;; ;; C-u 0 M-x blank-mode RET ;; ;; + To toggle blank-mode locally, type: ;; ;; M-x blank-mode RET ;; ;; + To toggle blank-mode options locally, type: ;; ;; M-x blank-toggle RET ;; ;; * GLOBAL blank-mode: ;; + To activate blank-mode globally, type: ;; ;; M-x blank-global-mode-on RET ;; ;; Or: ;; ;; C-u 1 M-x blank-global-mode RET ;; ;; + To deactivate blank-mode globally, type: ;; ;; M-x blank-global-mode-off RET ;; ;; Or: ;; ;; C-u 0 M-x blank-global-mode RET ;; ;; + To toggle blank-mode globally, type: ;; ;; M-x blank-global-mode RET ;; ;; + To toggle blank-mode options globally, type: ;; ;; M-x blank-toggle-global RET ;; ;; You can also bind `blank-mode', `blank-mode-on', `blank-mode-off', ;; `blank-global-mode', `blank-global-mode-on', `blank-global-mode-off', ;; `blank-mode-customize', `blank-toggle' and `blank-toggle-global' to some ;; key, like: ;; ;; (global-set-key "\C-c\C-a" 'blank-mode-on) ;; (global-set-key "\C-c\C-b" 'blank-mode-off) ;; (global-set-key "\C-c\C-l" 'blank-mode) ;; (global-set-key "\C-c\C-d" 'blank-global-mode-on) ;; (global-set-key "\C-c\C-e" 'blank-global-mode-off) ;; (global-set-key "\C-c\C-g" 'blank-global-mode) ;; (global-set-key "\C-c\C-c" 'blank-mode-customize) ;; (global-set-key "\C-c_" 'blank-toggle) ;; (global-set-key "\C-c=" 'blank-toggle-global) ;; ;; ;; Hooks ;; ----- ;; ;; blank-mode has the following hook variables: ;; ;; `blank-mode-hook' ;; It is evaluated always when blank-mode is turned on locally. ;; ;; `blank-global-mode-hook' ;; It is evaluated always when blank-mode is turned on globally. ;; ;; `blank-load-hook' ;; It is evaluated after blank-mode package is loaded. ;; ;; ;; Options ;; ------- ;; ;; Below it's shown a brief description of blank-mode options, please, see the ;; options declaration in the code for a long documentation. ;; ;; `blank-verbose' Non-nil means generate messages. ;; ;; `blank-style' Specify the visualisation style. ;; ;; `blank-chars' Specify which kind of blank is visualised. ;; ;; `blank-space-face' Face used to visualise SPACE. ;; ;; `blank-hspace-face' Face used to visualise HARD SPACE. ;; ;; `blank-tab-face' Face used to visualise TAB. ;; ;; `blank-map-face' Face used to visualise NEWLINE char mapping. ;; ;; `blank-trailing-face' Face used to visualise trailing blanks. ;; ;; `blank-line-face' Face used to visualise "long" lines. ;; ;; `blank-space-before-tab-face' Face used to visualise space before tab. ;; ;; `blank-space-regexp' Specify space characters regexp. ;; ;; `blank-hspace-regexp' Specify hard space characters regexp. ;; ;; `blank-tab-regexp' Specify tab characters regexp. ;; ;; `blank-trailing-regexp' Specify trailing characters regexp. ;; ;; `blank-space-before-tab-regexp' Specify space before tab regexp. ;; ;; `blank-line-length' Specify length beyond which the line is ;; highlighted. ;; ;; `blank-display-mappings' Specify an alist of mappings for displaying ;; characters. ;; ;; `blank-global-modes' Modes for which global `blank-mode' is ;; automagically turned on. ;; ;; To set the above options you may: ;; ;; a) insert the code in your ~/.emacs, like: ;; ;; (setq blank-space-face 'underline) ;; ;; This way always keep your default settings when you enter a new Emacs ;; session. ;; ;; b) or use `set-variable' in your Emacs session, like: ;; ;; M-x set-variable RET blank-space-face RET underline RET ;; ;; This way keep your settings only during the current Emacs session. ;; ;; c) or use customization, for example: ;; click on menu-bar *Help* option, ;; then click on *Customize*, ;; then click on *Browse Customization Groups*, ;; expand *Data* group, ;; expand *Blank* group ;; and then customize blank-mode options. ;; Through this way, you may choose if the settings are kept or not when ;; you leave out the current Emacs session. ;; ;; d) or see the option value: ;; ;; C-h v blank-space-face RET ;; ;; and click the *customize* hypertext button. ;; Through this way, you may choose if the settings are kept or not when ;; you leave out the current Emacs session. ;; ;; e) or invoke: ;; ;; M-x blank-mode-customize RET ;; ;; and then customize blank-mode options. ;; Through this way, you may choose if the settings are kept or not when ;; you leave out the current Emacs session. ;; ;; ;; Acknowledgements ;; ---------------- ;; ;; Thanks to Drew Adams for toggle commands suggestion. ;; ;; Thanks to Antti Kaihola for helping ;; to fix `find-file-hooks' reference. ;; ;; Thanks to Andreas Roehler for indicating ;; defface byte-compilation warnings. ;; ;; Thanks to TimOCallaghan (EmacsWiki) for the idea about highlight "long" ;; lines. See EightyColumnRule (EmacsWiki). ;; ;; Thanks to Yanghui Bian for indicating a new ;; newline character mapping. ;; ;; Thanks to Pete Forman for indicating ;; whitespace-mode on XEmacs. ;; ;; Thanks to: ;; Aurelien Tisne show-whitespace-mode.el ;; Lawrence Mitchell whitespace-mode.el ;; Miles Bader visws.el ;; And to all people who contributed with them. ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User Variables: ;;; Interface to the command system (defgroup blank nil "Visualise blanks (SPACE, HARD SPACE and TAB)." :link '(emacs-library-link :tag "Source Lisp File" "blank-mode.el") :version "20.6" :group 'wp :group 'data) (defcustom blank-verbose t "*Non-nil means generate messages." :type 'boolean :version "20.6" :group 'blank) (defcustom blank-style '(mark color) "*Specify the visualisation style. It's a list which element value can be: 'mark display mappings are visualised. 'color faces are visualised. Any other value is ignored. If it's nil, don't visualise TABs, SPACEs and HARD SPACEs. See also `blank-display-mappings' for documentation." :type '(repeat :tag "Style of Blank" (choice :tag "Style of Blank" (const :tag "Display Table" mark) (const :tag "Faces" color))) :version "20.6" :group 'blank) (defcustom blank-chars '(tabs spaces trailing lines space-before-tab) "*Specify which kind of blank is visualised. It's a list which element value can be: 'trailing trailing blanks are visualised. 'tabs TABs are visualised. 'spaces SPACEs and HARD SPACEs are visualised. 'lines lines whose length is greater than `blank-line-length' are highlighted. 'space-before-tab spaces before tabs are visualised. Any other element value is ignored. If it's nil, don't visualise TABs, SPACEs and HARD SPACEs. Used when `blank-style' has 'color as an element." :type '(repeat :tag "Kind of Blank" (choice :tag "Kind of Blank" (const :tag "Trailing TABs, SPACEs and HARD SPACEs" trailing) (const :tag "SPACEs and HARD SPACEs" spaces) (const :tag "TABs" tabs) (const :tag "Lines" lines) (const :tag "SPACEs before TABs" space-before-tab))) :version "20.6" :group 'blank) (defcustom blank-space-face 'blank-space-face "*Symbol face used to visualise SPACE. Used when `blank-style' has 'color as an element." :type 'face :version "20.6" :group 'blank) (defface blank-space-face '((((class color) (background dark)) :background "SteelBlue4" :foreground "aquamarine3") (((class color) (background light)) :background "LightYellow" :foreground "aquamarine3") (t (:inverse-video t))) "Face used to visualise SPACE." :version "20.6" :group 'blank) (defcustom blank-hspace-face 'blank-hspace-face ; 'nobreak-space "*Symbol face used to visualise HARD SPACE. Used when `blank-style' has 'color as an element." :type 'face :version "20.6" :group 'blank) (defface blank-hspace-face '((((class color) (background dark)) :background "CadetBlue4" :foreground "aquamarine3") (((class color) (background light)) :background "LemonChiffon3" :foreground "aquamarine3") (t (:inverse-video t))) "Face used to visualise HARD SPACE." :version "20.6" :group 'blank) (defcustom blank-tab-face 'blank-tab-face "*Symbol face used to visualise TAB. Used when `blank-style' has 'color as an element." :type 'face :version "20.6" :group 'blank) (defface blank-tab-face '((((class color) (background dark)) :background "SkyBlue4" :foreground "aquamarine3") (((class color) (background light)) :background "beige" :foreground "aquamarine3") (t (:inverse-video t))) "Face used to visualise TAB." :version "20.6" :group 'blank) (defcustom blank-map-face 'blank-map-face "*Symbol face used to visualise NEWLINE char mapping. See `blank-display-mappings'. Used when `blank-style' has 'mark as an element." :type 'face :version "20.6" :group 'blank) (defface blank-map-face '((((class color) (background dark)) :background "CadetBlue5" :foreground "aquamarine3" :bold t) (((class color) (background light)) :background "linen" :foreground "aquamarine3" :bold t) (t (:bold t :underline t))) "Face used to visualise NEWLINE char mapping. See `blank-display-mappings'." :version "20.6" :group 'blank) (defcustom blank-trailing-face 'blank-trailing-face ; 'trailing-whitespace "*Symbol face used to visualise traling blanks. Used when `blank-style' has 'color as an element." :type 'face :version "20.6" :group 'blank) (defface blank-trailing-face '((((class mono)) (:inverse-video t :bold t :underline t)) (t (:background "red1" :foreground "yellow" :bold t))) "Face used to visualise trailing blanks." :version "20.6" :group 'blank) (defcustom blank-line-face 'blank-line-face "*Symbol face used to visualise \"long\" lines. See `blank-line-legnth'. Used when `blank-style' has 'color as an element." :type 'face :version "20.6" :group 'blank) (defface blank-line-face '((((class mono)) (:inverse-video t :bold t :underline t)) (t (:background "gray20" :foreground "violet"))) "Face used to visualise \"long\" lines. See `blank-line-length'." :version "20.6" :group 'blank) (defcustom blank-space-before-tab-face 'blank-space-before-tab-face "*Symbol face used to visualise space before tab. Used when `blank-style' has 'color as an element." :type 'face :version "22" :group 'blank) (defface blank-space-before-tab-face '((((class mono)) (:inverse-video t :bold t :underline t)) (t (:background "DarkOrange" :foreground "firebrick"))) "Face used to visualise space before tab." :version "22" :group 'blank) (defcustom blank-hspace-regexp "\\(\\(\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20\\)+\\)" "*Specify hard space characters regexp. If you're using `mule' package, it may exist other characters besides \"\\xA0\" that it should be considered hard space. Here are some examples: \"\\\\(^\\xA0+\\\\)\" visualise only leading hard spaces. \"\\\\(\\xA0+$\\\\)\" visualise only trailing hard spaces. \"\\\\(^\\xA0+\\\\|\\xA0+$\\\\)\" visualise leading and/or trailing hard spaces. \"\\t\\\\(\\xA0+\\\\)\\t\" visualise only hard spaces between tabs. NOTE: Enclose always by \\\\( and \\\\) the elements to highlight. Use exactly one pair of enclosing \\\\( and \\\\). Used when `blank-style' has 'color as an element, and `blank-chars' has 'spaces as an element." :type '(regexp :tag "Hard Space Chars") :version "20.6" :group 'blank) (defcustom blank-space-regexp "\\( +\\)" "*Specify space characters regexp. If you're using `mule' package, it may exist other characters besides \" \" that it should be considered space. Here are some examples: \"\\\\(^ +\\\\)\" visualise only leading spaces. \"\\\\( +$\\\\)\" visualise only trailing spaces. \"\\\\(^ +\\\\| +$\\\\)\" visualise leading and/or trailing spaces. \"\\t\\\\( +\\\\)\\t\" visualise only spaces between tabs. NOTE: Enclose always by \\\\( and \\\\) the elements to highlight. Use exactly one pair of enclosing \\\\( and \\\\). Used when `blank-style' has 'color as an element, and `blank-chars' has 'spaces as an element." :type '(regexp :tag "Space Chars") :version "20.6" :group 'blank) (defcustom blank-tab-regexp "\\(\t+\\)" "*Specify tab characters regexp. If you're using `mule' package, it may exist other characters besides \"\\t\" that it should be considered tab. Here are some examples: \"\\\\(^\\t+\\\\)\" visualise only leading tabs. \"\\\\(\\t+$\\\\)\" visualise only trailing tabs. \"\\\\(^\\t+\\\\|\\t+$\\\\)\" visualise leading and/or trailing tabs. \" \\\\(\\t+\\\\) \" visualise only tabs between spaces. NOTE: Enclose always by \\\\( and \\\\) the elements to highlight. Use exactly one pair of enclosing \\\\( and \\\\). Used when `blank-style' has 'color as an element, and `blank-chars' has 'tabs as an element." :type '(regexp :tag "Tab Chars") :version "20.6" :group 'blank) (defcustom blank-trailing-regexp "\t\\| \\|\xA0\\|\x8A0\\|\x920\\|\xE20\\|\xF20" "*Specify trailing characters regexp. If you're using `mule' package, it may exist other characters besides \" \", \"\\t\" or \"\\xA0\" that it should be considered blank. NOTE: DOES NOT enclose by \\\\( and \\\\) the elements to highlight. `blank-mode' surrounds this regexp by \"\\\\(\\\\(\" and \"\\\\)+\\\\)$\". Used when `blank-style' has 'color as an element, and `blank-chars' has 'trailing as an element." :type '(regexp :tag "Trailing Chars") :version "20.6" :group 'blank) (defcustom blank-space-before-tab-regexp "\\( +\\)\t" "*Specify spaces before tabs regexp. If you're using `mule' package, it may exist other characters besides \" \", \"\\t\" or \"\\xA0\" that it should be considered blank. Used when `blank-style' has 'color as an element, and `blank-chars' has 'space-before-tab as an element." :type '(regexp :tag "Space Before Tab") :version "22" :group 'blank) (defcustom blank-line-length 80 "*Specify length beyond which the line is highlighted. Used when `blank-style' has 'color as an element, and `blank-chars' has 'lines as an element." :type '(integer :tag "Line Length") :version "20.6" :group 'blank) ;; Hacked from `visible-whitespace-mappings' in visws.el (defcustom blank-display-mappings '((?\xA0 [?\xA4] [?_]) ; hard space (?\x8A0 [?\x8A4] [?_]) ; hard space (?\x920 [?\x924] [?_]) ; hard space (?\xe20 [?\xe24] [?_]) ; hard space (?\xf20 [?\xf24] [?_]) ; hard space (?\ [?\xB7] [?.]) ; space (?\n [?\xB6 ?\n] [?$ ?\n]) ; end-of-line ;; WARNING: the mapping below has a problem. ;; When a tab occupies exactly one column, it will display the character ;; ?\xBB at that column followed by a tab which goes to the next tab ;; column. ;; If this is a problem for you, please, comment the line below. (?\t [?\xBB ?\t] [?\\ ?\t]) ; tab ) "*Specify an alist of mappings for displaying characters. Each element has the following form: (CHAR VECTOR...) Where: CHAR is the character to be mapped. VECTOR is a vector of characters to be displayed in place of CHAR. The first display vector that can be displayed is used; if no display vector for a mapping can be displayed, then that character is displayed unmodified. The NEWLINE character is displayed using the face given by `blank-map-face' variable. Used when `blank-style' has 'mark as an element." :type '(repeat (list :tag "Character Mapping" (character :tag "Char") (repeat :inline t :tag "Vector List" (vector :tag "" (repeat :inline t :tag "Vector Characters" (character :tag "Char")))))) :version "20.6" :group 'blank) (defcustom blank-global-modes t "*Modes for which global `blank-mode' is automagically turned on. Global `blank-mode' is controlled by the command `blank-global-mode'. If nil, means no modes have `blank-mode' automatically turned on. If t, all modes that support `blank-mode' have it automatically turned on. If a list, it should be a list of `major-mode' symbol names for which `blank-mode' should be automatically turned on. The sense of the list is negated if it begins with `not'. For example: (c-mode c++-mode) means that `blank-mode' is turned on for buffers in C and C++ modes only." :type '(choice (const :tag "none" nil) (const :tag "all" t) (set :menu-tag "mode specific" :tag "modes" :value (not) (const :tag "Except" not) (repeat :inline t (symbol :tag "mode")))) :version "20.6" :group 'blank) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Macros (defmacro blank-message (&rest body) `(and blank-verbose (interactive-p) (message ,@body))) (defmacro blank-minor-mode (arg mode on off) `(progn (if (if arg (> (prefix-numeric-value arg) 0) (not ,mode)) (,on) (,off)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User commands - Customization ;;;###autoload (defun blank-mode-customize () "Customize blank-mode options." (interactive) (customize-group 'blank)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User commands - Local mode (defvar blank-mode nil "Non-nil means blank-mode local minor mode is enabled (bl on modeline).") (make-variable-buffer-local 'blank-mode) ;;;###autoload (defun blank-mode (&optional arg) "Toggle blank minor mode visualisation (bl on modeline). If ARG is null, toggle blank visualisation. If ARG is a number and is greater than zero, turn on visualisation; otherwise, turn off visualisation. Only useful with a windowing system." (interactive "P") (blank-minor-mode arg blank-mode blank-mode-on blank-mode-off) (blank-message "Blank Mode is now %s." (if blank-mode "on" "off"))) ;;;###autoload (defun blank-mode-on () "Turn on blank minor mode visualisation (bl on modeline)." (interactive) (or noninteractive blank-mode (when blank-style (setq blank-mode t) (blank-turn-on) (run-hooks 'blank-mode-hook) (blank-message "Blank Mode is now on.")))) ;;;###autoload (defun blank-mode-off () "Turn off blank minor mode visualisation (bl on modeline)." (interactive) (and blank-mode (progn (setq blank-mode nil) (blank-turn-off) (blank-message "Blank Mode is now off.")))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User commands - Global mode (defvar blank-global-mode nil "Non-nil means blank-mode global minor mode is enabled (BL on modeline).") ;;;###autoload (defun blank-global-mode (&optional arg) "Toggle blank global minor mode visualisation (BL on modeline). If ARG is null, toggle blank visualisation. If ARG is a number and is greater than zero, turn on visualisation; otherwise, turn off visualisation. Only useful with a windowing system." (interactive "P") (blank-minor-mode arg blank-global-mode blank-global-mode-on blank-global-mode-off) (blank-message "Blank Global Mode is %s" (if blank-global-mode "on" "off"))) ;;;###autoload (defun blank-global-mode-on () "Turn on blank global minor mode visualisation (BL on modeline)." (interactive) (or noninteractive blank-global-mode (progn (save-excursion (let ((buffers (buffer-list))) (setq blank-global-mode t) (if (boundp 'find-file-hook) (add-hook 'find-file-hook 'blank-turn-on-if-enabled t) (add-hook 'find-file-hooks 'blank-turn-on-if-enabled t)) (while buffers ; adjust all local mode (set-buffer (car buffers)) (unless blank-mode (blank-turn-on-if-enabled)) (setq buffers (cdr buffers))))) (run-hooks 'blank-global-mode-hook) (blank-message "Blank Global Mode is on")))) ;;;###autoload (defun blank-global-mode-off () "Turn off blank global minor mode visualisation (BL on modeline)." (interactive) (and blank-global-mode (progn (save-excursion (let ((buffers (buffer-list))) (setq blank-global-mode nil) (if (boundp 'find-file-hook) (remove-hook 'find-file-hook 'blank-turn-on-if-enabled) (remove-hook 'find-file-hooks 'blank-turn-on-if-enabled)) (while buffers ; adjust all local mode (set-buffer (car buffers)) (unless blank-mode (blank-turn-off)) (setq buffers (cdr buffers))))) (blank-message "Blank Global Mode is off")))) (defun blank-turn-on-if-enabled () (when (cond ((eq blank-global-modes t)) ((listp blank-global-modes) (if (eq (car-safe blank-global-modes) 'not) (not (memq major-mode (cdr blank-global-modes))) (memq major-mode blank-global-modes))) (t nil)) (let (inhibit-quit) ;; Don't turn on blank mode if... (or ;; ...we don't have a display (we're running a batch job) noninteractive ;; ...or if the buffer is invisible (the name starts with a space) (eq (aref (buffer-name) 0) ?\ ) ;; ...or if the buffer is temporary (the name starts with *) (and (eq (aref (buffer-name) 0) ?*) ;; except the scratch buffer. (not (string= (buffer-name) "*scratch*"))) ;; Otherwise, turn on blank mode. (blank-turn-on))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User commands - Toggle (defconst blank-chars-value-list '(tabs spaces trailing space-before-tab lines ) "List of valid `blank-chars' value.") (defconst blank-style-value-list '(color mark ) "List of valid `blank-style' value.") (defconst blank-toggle-option-alist '((?t . tabs) (?s . spaces) (?r . trailing) (?b . space-before-tab) (?l . lines) (?c . color) (?m . mark) (?x . blank-chars) (?z . blank-style) ) "Alist of toggle options. Each element has the form: (CHAR . SYMBOL) Where: CHAR is a char which the user will have to type. SYMBOL is a valid symbol associated with CHAR. See `blank-chars-value-list' and `blank-style-value-list'.") (defconst blank-help-text "\ blank-mode toggle options: [] t - toggle TAB visualisation [] s - toggle SPACE and HARD SPACE visualisation [] r - toggle trailing blanks visualisation [] b - toggle spaces before tab visualisation [] l - toggle \"long lines\" visualisation [] c - toggle color faces [] m - toggle visual mark x - restore `blank-chars' value z - restore `blank-style' value ? - display this text\n\n" "Text for blank toggle options.") (defconst blank-help-buffer-name "*Blank Toggle Options*" "The buffer name for blank toggle options.") (defun blank-help-on (chars style) "Display the blank toggle options." (unless (get-buffer blank-help-buffer-name) (save-excursion (let ((buffer (get-buffer-create blank-help-buffer-name))) (delete-windows-on buffer) (set-buffer buffer) (erase-buffer) (insert blank-help-text) (goto-char (point-min)) (forward-line 1) (dolist (sym blank-chars-value-list) (forward-line 1) (forward-char 2) (insert (if (memq sym chars) "*" " "))) (forward-line 1) (dolist (sym blank-style-value-list) (forward-line 1) (forward-char 2) (insert (if (memq sym style) "*" " "))) (goto-char (point-min)) (set-buffer-modified-p nil) (let* ((lines (count-lines (point-min) (point-max))) (size (- (window-height) (max window-min-height (1+ lines))))) (set-window-buffer (split-window nil size) buffer))))) t) (defun blank-help-off () "Remove the buffer and window of the blank toggle options." (let ((buffer (get-buffer blank-help-buffer-name))) (when buffer (delete-windows-on buffer) (kill-buffer buffer)))) (defun blank-interactive-char (local-p) "Interactive function to read a char and return the corresponding symbol. If LOCAL-P is non-nil, it uses a local context; otherwise, it uses a global context. It reads one of the following chars: CHAR MEANING t toggle TAB visualisation s toggle SPACE and HARD SPACE visualisation r toggle trailing blanks visualisation b toggle spaces before tab visualisation l toggle \"long lines\" visualisation c toggle color faces m toggle visual mark x restore `blank-chars' value z restore `blank-style' value ? display brief help See also `blank-toggle-option-alist'." (let ((prompt (format "Blank Toggle %s (type ? for further options)-" (if local-p "Local" "Global"))) (chars (if local-p blank-active-chars blank-toggle-chars)) (style (if local-p blank-active-style blank-toggle-style)) c s emsg) ;; if blank-mode is off, use default value (unless (if local-p blank-mode blank-global-mode) (unless chars (setq chars blank-chars)) (unless style (setq style blank-style))) ;; read a valid option and get the corresponding symbol (condition-case data (progn (while (progn (setq c (read-char prompt)) (not (setq s (cdr (assq c blank-toggle-option-alist))))) (if (eq c ?\?) (blank-help-on chars style) (ding)))) ;; handler ((quit error) (setq emsg (error-message-string data)))) (blank-help-off) (when emsg (error emsg)) (message " ") ; clean echo area (list s))) (defun blank-toggle-list (local-p arg the-list default-list sym-restore sym-list) "Toggle options in THE-LIST based on list ARG. If LOCAL-P is non-nil, it uses a local context; otherwise, it uses a global context. ARG is a list of options to be toggled. THE-LIST is a list of options. This list will be toggled and the resultant list will be returned. DEFAULT-LIST is the default list of options. It is used to restore the options in THE-LIST. SYM-RESTORE is the symbol which indicates to restore the options in THE-LIST. SYM-LIST is a list of valid options, used to check if the ARG's options are valid." (unless (if local-p (and blank-mode blank-active-style) blank-global-mode) (setq the-list default-list)) (dolist (sym (if (listp arg) arg (list arg))) (cond ;; restore default values ((eq sym sym-restore) (setq the-list default-list)) ;; toggle valid values ((memq sym sym-list) (setq the-list (if (memq sym the-list) (delq sym the-list) (cons sym the-list)))) )) the-list) ;;;###autoload (defun blank-toggle (arg) "Toggle local `blank-mode' options. Interactively, it reads one of the following chars: CHAR MEANING t toggle TAB visualisation s toggle SPACE and HARD SPACE visualisation r toggle trailing blanks visualisation b toggle spaces before tab visualisation l toggle \"long lines\" visualisation c toggle color faces m toggle visual mark x restore `blank-chars' value z restore `blank-style' value ? display brief help Non-interactively, ARG should be a symbol or a list of symbol. The valid symbols are: tabs toggle TAB visualisation spaces toggle SPACE and HARD SPACE visualisation trailing toggle trailing blanks visualisation space-before-tab toggle spaces before tab visualisation lines toggle \"long lines\" visualisation color toggle color faces mark toggle visual mark blank-chars restore `blank-chars' value blank-style restore `blank-style' value Only useful with a windowing system." (interactive (blank-interactive-char t)) (let ((blank-chars (blank-toggle-list t arg blank-active-chars blank-chars 'blank-chars blank-chars-value-list)) (blank-style (blank-toggle-list t arg blank-active-style blank-style 'blank-style blank-style-value-list))) (blank-mode 0) (blank-mode 1))) (defvar blank-toggle-chars nil "Used to toggle the global `blank-chars' value.") (defvar blank-toggle-style nil "Used to toggle the global `blank-style' value.") ;;;###autoload (defun blank-toggle-global (arg) "Toggle global `blank-mode' options. Interactively, it reads one of the following chars: CHAR MEANING t toggle TAB visualisation s toggle SPACE and HARD SPACE visualisation r toggle trailing blanks visualisation b toggle spaces before tab visualisation l toggle \"long lines\" visualisation c toggle color faces m toggle visual mark x restore `blank-chars' value z restore `blank-style' value ? display brief help Non-interactively, ARG should be a symbol or a list of symbol. The valid symbols are: tabs toggle TAB visualisation spaces toggle SPACE and HARD SPACE visualisation trailing toggle trailing blanks visualisation space-before-tab toggle spaces before tab visualisation lines toggle \"long lines\" visualisation color toggle color faces mark toggle visual mark blank-chars restore `blank-chars' value blank-style restore `blank-style' value Only useful with a windowing system." (interactive (blank-interactive-char nil)) (let ((blank-chars (blank-toggle-list nil arg blank-toggle-chars blank-chars 'blank-chars blank-chars-value-list)) (blank-style (blank-toggle-list nil arg blank-toggle-style blank-style 'blank-style blank-style-value-list))) (setq blank-toggle-chars blank-chars blank-toggle-style blank-style) (blank-global-mode 0) (blank-global-mode 1))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Internal functions (defvar blank-font-lock-mode nil "Used to remember whether a buffer had font lock mode on or not.") (make-variable-buffer-local 'blank-font-lock-mode) (defvar blank-font-lock nil "Used to remember whether a buffer initially had font lock on or not.") (make-variable-buffer-local 'blank-font-lock) (defvar blank-font-lock-keywords nil "Used to save locally `font-lock-keywords' value.") (make-variable-buffer-local 'blank-font-lock-keywords) (defvar blank-active-chars nil "Used to save locally `blank-chars' value.") (make-variable-buffer-local 'blank-active-chars) (defvar blank-active-style nil "Used to save locally `blank-style' value.") (make-variable-buffer-local 'blank-active-style) (defun blank-turn-on () "Turn on blank visualisation." (setq blank-active-style (if (listp blank-style) blank-style (list blank-style))) (and (memq 'color blank-active-style) (blank-color-on)) (and (memq 'mark blank-active-style) (blank-display-char-on))) (defun blank-turn-off () "Turn off blank visualisation." (and (memq 'color blank-active-style) (blank-color-off)) (and (memq 'mark blank-active-style) (blank-display-char-off))) (defun blank-color-on () "Turn on color visualisation." (setq blank-active-chars (if (listp blank-chars) blank-chars (list blank-chars))) (when blank-active-chars (unless blank-font-lock (setq blank-font-lock t blank-font-lock-keywords (copy-sequence font-lock-keywords))) (and (memq 'spaces blank-active-chars) (font-lock-add-keywords nil (list ;; Show spaces (list blank-space-regexp 1 blank-space-face t) ;; Show hard spaces (list blank-hspace-regexp 1 blank-hspace-face t)) t)) (and (memq 'tabs blank-active-chars) (font-lock-add-keywords nil (list ;; Show tabs (list blank-tab-regexp 1 blank-tab-face t)) t)) (and (memq 'trailing blank-active-chars) (font-lock-add-keywords nil (list ;; Show trailing blanks (list (concat "\\(\\(" blank-trailing-regexp "\\)+\\)$") 1 blank-trailing-face t)) t)) (and (memq 'lines blank-active-chars) (font-lock-add-keywords nil (list ;; Show "long" lines (list (concat "^\\(.\\{" (int-to-string blank-line-length) ",\\}\\)$") 1 blank-line-face t)) t)) (and (memq 'space-before-tab blank-active-chars) (font-lock-add-keywords nil (list ;; Show spaces before tabs (list blank-space-before-tab-regexp 1 blank-space-before-tab-face t)) t)) ;; turn off font lock (setq blank-font-lock-mode font-lock-mode) (font-lock-mode 0) ;; now turn on font lock and highlight blanks (font-lock-mode 1))) (defun blank-color-off () "Turn off color visualisation." (when blank-active-chars (when blank-font-lock (setq blank-font-lock nil font-lock-keywords blank-font-lock-keywords)) ;; turn off font lock (font-lock-mode 0) ;; restore original font lock state (font-lock-mode blank-font-lock-mode))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Hacked from visws.el (defvar blank-display-table nil "Used to save a local display table.") (make-variable-buffer-local 'blank-display-table) (defvar blank-display-table-was-local nil "Used to remember whether a buffer initially had a local display table or not.") (make-variable-buffer-local 'blank-display-table-was-local) (defun blank-legal-display-vector-p (vec) "Return true if every character in the display vector VEC can be displayed." (let ((i (length vec))) (when (> i 0) ;; This check should be improved!!! (while (and (>= (setq i (1- i)) 0) (or (< (aref vec i) 256) (char-valid-p (aref vec i))))) (< i 0)))) (defun blank-display-char-on () "Turn on character display mapping." (and blank-display-mappings (let ((face-bits (ash (face-id blank-map-face) 19)) (map-list blank-display-mappings) entry vecs len vec i) ;; Remember whether a buffer has a local display table. (unless blank-display-table-was-local (setq blank-display-table-was-local t blank-display-table (copy-sequence buffer-display-table))) (or buffer-display-table (setq buffer-display-table (make-display-table))) (while map-list (setq entry (car map-list) vecs (cdr entry) map-list (cdr map-list)) ;; Get a displayable mapping. (while (and vecs (not (blank-legal-display-vector-p (car vecs)))) (setq vecs (cdr vecs))) ;; Display a valid mapping. (when vecs (setq vec (copy-sequence (car vecs))) ;; Only insert face bits on NEWLINE char mapping to avoid ;; obstruction of other faces like TABs and (HARD) SPACEs faces, ;; font-lock faces, etc. (when (eq (car entry) ?\n) (setq len (length (car vecs)) i -1) (while (< (setq i (1+ i)) len) (or (eq (aref vec i) ?\n) (aset vec i (logior (aref vec i) face-bits))))) (aset buffer-display-table (car entry) vec)))))) (defun blank-display-char-off () "Turn off character display mapping." (and blank-display-mappings blank-display-table-was-local (setq blank-display-table-was-local nil buffer-display-table blank-display-table))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (add-to-list 'minor-mode-alist '(blank-mode " bl")) (add-to-list 'minor-mode-alist '(blank-global-mode " BL")) (provide 'blank-mode) (run-hooks 'blank-load-hook) ;;; blank-mode.el ends here --------------040705080204020302080801 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel --------------040705080204020302080801--