comparison lisp/rfn-eshadow.el @ 90261:7beb78bc1f8e

Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-97 Merge from emacs--cvs-trunk--0 Patches applied: * emacs--cvs-trunk--0 (patch 616-696) - Add lisp/mh-e/.arch-inventory - Update from CVS - Merge from gnus--rel--5.10 - Update from CVS: lisp/smerge-mode.el: Add 'tools' to file keywords. - lisp/gnus/ChangeLog: Remove duplicate entry * gnus--rel--5.10 (patch 147-181) - Update from CVS - Merge from emacs--cvs-trunk--0 - Update from CVS: lisp/mml.el (mml-preview): Doc fix. - Update from CVS: texi/message.texi: Fix default values. - Update from CVS: texi/gnus.texi (RSS): Addition.
author Miles Bader <miles@gnu.org>
date Mon, 16 Jan 2006 08:37:27 +0000
parents 2d92f5c9d6ae 4571a040cf5b
children c5406394f567
comparison
equal deleted inserted replaced
90260:0ca0d9181b5e 90261:7beb78bc1f8e
91 (list :inline t 91 (list :inline t
92 :format "%v" 92 :format "%v"
93 (symbol :tag "Property") 93 (symbol :tag "Property")
94 (sexp :tag "Value"))))) 94 (sexp :tag "Value")))))
95 95
96 ;;;###autoload
97 (defcustom file-name-shadow-properties 96 (defcustom file-name-shadow-properties
98 '(face file-name-shadow field shadow) 97 '(face file-name-shadow field shadow)
99 "Properties given to the `shadowed' part of a filename in the minibuffer. 98 "Properties given to the `shadowed' part of a filename in the minibuffer.
100 Only used when `file-name-shadow-mode' is active. 99 Only used when `file-name-shadow-mode' is active.
101 If emacs is not running under a window system, 100 If Emacs is not running under a window system,
102 `file-name-shadow-tty-properties' is used instead." 101 `file-name-shadow-tty-properties' is used instead."
103 :type file-name-shadow-properties-custom-type 102 :type file-name-shadow-properties-custom-type
104 :group 'minibuffer) 103 :group 'minibuffer
105 104 :version "22.1")
106 ;;;###autoload 105
107 (defcustom file-name-shadow-tty-properties 106 (defcustom file-name-shadow-tty-properties
108 '(before-string "{" after-string "} " field shadow) 107 '(before-string "{" after-string "} " field shadow)
109 "Properties given to the `shadowed' part of a filename in the minibuffer. 108 "Properties given to the `shadowed' part of a filename in the minibuffer.
110 Only used when `file-name-shadow-mode' is active and emacs 109 Only used when `file-name-shadow-mode' is active and emacs
111 is not running under a window-system; if emacs is running under a window 110 is not running under a window-system; if emacs is running under a window
112 system, `file-name-shadow-properties' is used instead." 111 system, `file-name-shadow-properties' is used instead."
113 :type file-name-shadow-properties-custom-type 112 :type file-name-shadow-properties-custom-type
114 :group 'minibuffer) 113 :group 'minibuffer
114 :version "22.1")
115 115
116 (defface file-name-shadow 116 (defface file-name-shadow
117 '((t :inherit shadow)) 117 '((t :inherit shadow))
118 "Face used by `file-name-shadow-mode' for the shadow." 118 "Face used by `file-name-shadow-mode' for the shadow."
119 :group 'minibuffer) 119 :group 'minibuffer
120 :version "22.1")
120 121
121 122
122 ;;; Internal variables 123 ;;; Internal variables
123
124 ;; Regexp to locate dividing point between shadow and real pathname
125 (defconst rfn-eshadow-regexp
126 (cond ((memq system-type '(ms-dos windows-nt))
127 ;; This horrible regexp considers the following patterns as
128 ;; starting an absolute pathname, when following a `/' or an `\':
129 ;; L: / // ~ $ \\ \\\\
130 "\\(.*[^/]+/+?\\|/*?\\|\\)\\(~\\|$[^$]\\|$\\'\\|[][\\^a-z]:\\|//?\\([^][\\^a-z/$~]\\|[^/$~][^:]\\|[^/$~]?\\'\\)\\)")
131 (t
132 ;; default is for unix-style filenames
133 "\\(.*/\\)\\([/~]\\|$[^$]\\|$\\'\\)"))
134 "Regular expression used to match shadowed filenames.
135 There should be at least one regexp group; the end of the first one
136 is used as the end of the shadowed portion of the filename.")
137 124
138 ;; A list of minibuffers to which we've added a post-command-hook. 125 ;; A list of minibuffers to which we've added a post-command-hook.
139 (defvar rfn-eshadow-frobbed-minibufs nil) 126 (defvar rfn-eshadow-frobbed-minibufs nil)
140 127
141 ;; An overlay covering the shadowed part of the filename (local to the 128 ;; An overlay covering the shadowed part of the filename (local to the
166 (overlay-put rfn-eshadow-overlay 'evaporate t) 153 (overlay-put rfn-eshadow-overlay 'evaporate t)
167 ;; Add our post-command hook, and make sure can remove it later. 154 ;; Add our post-command hook, and make sure can remove it later.
168 (add-to-list 'rfn-eshadow-frobbed-minibufs (current-buffer)) 155 (add-to-list 'rfn-eshadow-frobbed-minibufs (current-buffer))
169 (add-hook 'post-command-hook #'rfn-eshadow-update-overlay nil t))) 156 (add-hook 'post-command-hook #'rfn-eshadow-update-overlay nil t)))
170 157
158 (defsubst rfn-eshadow-sifn-equal (goal pos)
159 (equal goal (condition-case nil
160 (substitute-in-file-name
161 (buffer-substring-no-properties pos (point-max)))
162 ;; `substitute-in-file-name' can fail on partial input.
163 (error nil))))
164
171 ;; post-command-hook to update overlay 165 ;; post-command-hook to update overlay
172 (defun rfn-eshadow-update-overlay () 166 (defun rfn-eshadow-update-overlay ()
173 "Update `rfn-eshadow-overlay' to cover shadowed part of minibuffer input. 167 "Update `rfn-eshadow-overlay' to cover shadowed part of minibuffer input.
174 This is intended to be used as a minibuffer post-command-hook for 168 This is intended to be used as a minibuffer `post-command-hook' for
175 `file-name-shadow-mode'; the minibuffer should have already 169 `file-name-shadow-mode'; the minibuffer should have already
176 been set up by `rfn-eshadow-setup-minibuffer'." 170 been set up by `rfn-eshadow-setup-minibuffer'."
177 ;; This is not really a correct implementation; it won't always do the 171 (condition-case nil
178 ;; right thing in the presence of environment variables that 172 (let ((goal (substitute-in-file-name (minibuffer-contents)))
179 ;; substitute-in-file-name would expand; currently it just assumes any 173 (mid (overlay-end rfn-eshadow-overlay))
180 ;; environment variable contains an absolute filename. 174 (start (minibuffer-prompt-end))
181 (save-excursion 175 (end (point-max)))
182 (let ((inhibit-point-motion-hooks t)) 176 (unless
183 (goto-char (minibuffer-prompt-end)) 177 ;; Catch the common case where the shadow does not need to move.
184 ;; Update the overlay (which will evaporate if it's empty). 178 (and mid
185 (move-overlay rfn-eshadow-overlay 179 (or (eq mid end)
186 (point) 180 (not (rfn-eshadow-sifn-equal goal (1+ mid))))
187 (if (looking-at rfn-eshadow-regexp) 181 (or (eq mid start)
188 (match-end 1) 182 (rfn-eshadow-sifn-equal goal mid)))
189 (point)))))) 183 ;; Binary search for the greatest position still equivalent to
190 184 ;; the whole.
191 185 (while (or (< (1+ start) end)
192 ;;; Note this definition must be at the end of the file, because 186 (if (and (< (1+ end) (point-max))
193 ;;; `define-minor-mode' actually calls the mode-function if the 187 (rfn-eshadow-sifn-equal goal (1+ end)))
194 ;;; associated variable is non-nil, which requires that all needed 188 ;; (SIFN end) != goal, but (SIFN (1+end)) == goal,
195 ;;; functions be already defined. [This is arguably a bug in d-m-m] 189 ;; We've reached a discontinuity: this can happen
196 ;;;###autoload 190 ;; e.g. if `end' point to "/:...".
191 (setq start (1+ end) end (point-max))))
192 (setq mid (/ (+ start end) 2))
193 (if (rfn-eshadow-sifn-equal goal mid)
194 (setq start mid)
195 (setq end mid)))
196 (move-overlay rfn-eshadow-overlay (minibuffer-prompt-end) start)))
197 ;; `substitute-in-file-name' can fail on partial input.
198 (error nil)))
199
197 (define-minor-mode file-name-shadow-mode 200 (define-minor-mode file-name-shadow-mode
198 "Toggle File-Name Shadow mode. 201 "Toggle File-Name Shadow mode.
199 When active, any part of a filename being read in the minibuffer 202 When active, any part of a filename being read in the minibuffer
200 that would be ignored (because the result is passed through 203 that would be ignored (because the result is passed through
201 `substitute-in-file-name') is given the properties in 204 `substitute-in-file-name') is given the properties in
203 that portion dim, invisible, or otherwise less visually noticeable. 206 that portion dim, invisible, or otherwise less visually noticeable.
204 207
205 With prefix argument ARG, turn on if positive, otherwise off. 208 With prefix argument ARG, turn on if positive, otherwise off.
206 Returns non-nil if the new state is enabled." 209 Returns non-nil if the new state is enabled."
207 :global t 210 :global t
208 :group 'minibuffer 211 :init-value t
212 :group 'minibuffer
213 :version "22.1"
209 (if file-name-shadow-mode 214 (if file-name-shadow-mode
210 ;; Enable the mode 215 ;; Enable the mode
211 (add-hook 'minibuffer-setup-hook 'rfn-eshadow-setup-minibuffer) 216 (add-hook 'minibuffer-setup-hook 'rfn-eshadow-setup-minibuffer)
212 ;; Disable the mode 217 ;; Disable the mode
213 (remove-hook 'minibuffer-setup-hook 'rfn-eshadow-setup-minibuffer) 218 (remove-hook 'minibuffer-setup-hook 'rfn-eshadow-setup-minibuffer)
218 (setq rfn-eshadow-frobbed-minibufs nil))) 223 (setq rfn-eshadow-frobbed-minibufs nil)))
219 224
220 225
221 (provide 'rfn-eshadow) 226 (provide 'rfn-eshadow)
222 227
223 ;;; arch-tag: dcf70a52-0115-4ec2-b1e3-4f8d3541a888 228 ;; arch-tag: dcf70a52-0115-4ec2-b1e3-4f8d3541a888
224 ;;; rfn-eshadow.el ends here 229 ;;; rfn-eshadow.el ends here