Mercurial > emacs
comparison lisp/dabbrev.el @ 10230:7396503653cf
Complete rewrite by Lars.Lindberg@sypro.cap.se.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 24 Dec 1994 01:26:51 +0000 |
parents | 069c54e77fd1 |
children | e88ff4b30786 |
comparison
equal
deleted
inserted
replaced
10229:634f36d4b2ae | 10230:7396503653cf |
---|---|
1 ;;; dabbrev.el --- dynamic abbreviation package for GNU Emacs. | 1 ;;; new-dabbrev.el --- dynamic abbreviation package |
2 | |
3 ;; Copyright (C) 1985, 1986 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1985, 1986 Free Software Foundation, Inc. |
4 | 3 |
5 ;; Last-Modified: 16 Mar 1992 | 4 ;; Author: Don Morrison |
6 ;; Copyright (C) 1985, 1986 Free Software Foundation, Inc. | 5 ;; Maintainer: Lars Lindberg <Lars.Lindberg@sypro.cap.se> |
7 | 6 ;; Created: 16 Mars 1992 |
8 ;; Maintainer: FSF | 7 ;; Version: 4.4.2 beta |
9 ;; Keywords: abbrev | 8 (defun dabbrev--version () "4.4.2 beta") |
10 | 9 ;; Keywords: abbrev expand completion |
11 ;; This file is part of GNU Emacs. | 10 |
12 | 11 ;; This program is free software; you can redistribute it and/or modify |
13 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
14 ;; it under the terms of the GNU General Public License as published by | 12 ;; it under the terms of the GNU General Public License as published by |
15 ;; the Free Software Foundation; either version 2, or (at your option) | 13 ;; the Free Software Foundation; either version 2 of the License, or |
16 ;; any later version. | 14 ;; (at your option) any later version. |
17 | 15 ;; |
18 ;; GNU Emacs is distributed in the hope that it will be useful, | 16 ;; This program is distributed in the hope that it will be useful, |
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 ;; GNU General Public License for more details. | 19 ;; GNU General Public License for more details. |
22 | 20 ;; |
23 ;; You should have received a copy of the GNU General Public License | 21 ;; You should have received a copy of the GNU General Public License |
24 ;; along with GNU Emacs; see the file COPYING. If not, write to | 22 ;; along with this program; if not, write to the Free Software |
25 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 23 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | 24 |
27 ;;; Commentary: | 25 ;;; Commentary: |
28 | 26 |
29 ; DABBREVS - "Dynamic abbreviations" hack, originally written by Don Morrison | 27 ;; The purpose with this package is to let you write just a few |
30 ; for Twenex Emacs. Converted to mlisp by Russ Fish. Supports the table | 28 ;; characters of words you've written earlier to be able to expand |
31 ; feature to avoid hitting the same expansion on re-expand, and the search | 29 ;; them. |
32 ; size limit variable. Bugs fixed from the Twenex version are flagged by | 30 ;; |
33 ; comments starting with ;;; . | 31 ;; To expand a word, just put the point right after the word and press |
34 ; | 32 ;; M-/ (dabbrev-expand) or M-C-/ (dabbrev-completion). |
35 ; converted to Emacs Lisp by Spencer Thomas. | 33 ;; |
36 ; Thoroughly cleaned up by Richard Stallman. | 34 ;; There are powerful things in this package that aren't turned on by |
37 ; | 35 ;; default. I recommend you to do the following. |
38 ; If anyone feels like hacking at it, Bob Keller (Keller@Utah-20) first | 36 ;; |
39 ; suggested the beast, and has some good ideas for its improvement, but | 37 ;; Put the following 2 lines in your .emacs file: |
40 ; doesn't know TECO (the lucky devil...). One thing that should definitely | 38 ;; (setq dabbrev-always-check-other-buffers t) |
41 ; be done is adding the ability to search some other buffer(s) if you can?t | 39 ;; (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_") |
42 ; find the expansion you want in the current one. | 40 ;; |
41 ;; Dabbrev will now search in all buffers with the same major mode for | |
42 ;; your expansions. It will also search for complete symbols, the old | |
43 ;; dabbrev package only looked half-heartedly for symbols. | |
44 ;; | |
45 ;; Check out the customizable variables below to learn about all the | |
46 ;; features of this package. | |
47 | |
48 ;;; Hints and tips for major modes writers: | |
49 | |
50 ;; Recommended values C/Lisp etc text | |
51 ;; dabbrev-case-fold-search nil t | |
52 ;; dabbrev-case-replace nil t | |
53 ;; | |
54 ;; Set the variables you want special for your mode like this: | |
55 ;; (set (make-local-variable 'dabbrev-case-replace) nil) | |
56 ;; Then you don't interfer with other modes. | |
57 ;; | |
58 ;; If your mode handles buffers that refers to other buffers | |
59 ;; (i.e. compilation-mode, gud-mode), then try to set | |
60 ;; `dabbrev-select-buffers-function' or `dabbrev-friend-buffer-function' | |
61 ;; to a function that point out those buffers. | |
62 | |
63 ;; Same goes for major-modes that are connected to other modes. There | |
64 ;; are for instance a number of mail-modes. One for reading, one for | |
65 ;; creating a new mail etc. Maybe those should be connected. | |
66 | |
67 ;; Example for GNUS (when we write a reply, we want dabbrev to look in | |
68 ;; the article for expansion): | |
69 ;; (set (make-local-variable 'dabbrev-friend-buffer-function) | |
70 ;; (lambda (buffer) | |
71 ;; (save-excursion | |
72 ;; (set-buffer buffer) | |
73 ;; (memq major-mode '(news-reply-mode gnus-article-mode))))) | |
74 | |
75 ;;; Change Log | |
76 ;; 4.4.2 1994-11-25 | |
77 ;; Added new variable; `dabbrev-check-rest-of-buffers'. | |
78 ;; 4.4.1 1994-11-24 | |
79 ;; Now has correct creation date. | |
80 ;; Added kill-ring idea to "Future enhancements". | |
81 ;; 4.4 1994-11-22 | |
82 ;; Changed the copyright text. Thanks [hymie]. | |
83 ;; new-dabbrev now handles abbrevs that starts with symbol | |
84 ;; syntax. Thanks [burgett] for kicking me to do it. | |
85 ;; Now also handles `dabbrev-abbrev-skip-leading-regexp' better. | |
86 ;; 4.3 1994-11-14 | |
87 ;; Now only displays "Expansion found in <buffer>" when the | |
88 ;; expansion has been found in buffers that hasn't been examined | |
89 ;; yet. Thanks [kifer]. | |
90 ;; Added a new variable; `dabbrev-search-these-buffers-only'. | |
91 ;; Fixed bug in mini-buffer completion. Thanks [kifer]. | |
92 ;; Found a real time-waster when using `dabbrev-completion'. | |
93 ;; Thanks for the elp.el package Barry Warsaw! | |
94 ;; Found bug that made point move in other buffers. | |
95 ;; Now handles Lucid emacs define-key style. | |
96 ;; Thanks [jules]. | |
97 ;; Now uses the `<symbol>' syntax in doc strings. | |
98 ;; Cosmetic bugs and syntactical bugs in documentation strings. | |
99 ;; Thanks [hawley]. | |
100 ;; 4.2 1994-03-04 | |
101 ;; Now searches other buffers again. Thanks [ake]. | |
102 ;; 4.1 1994-02-22 | |
103 ;; Introduced the new variables `dabbrev-case-fold-search' and | |
104 ;; `dabbrev-case-replace'. | |
105 ;; Introduced the new variable `dabbrev-select-buffers-function'. | |
106 ;; Introduced the new variable `dabbrev-abbrev-skip-leading-regexp'. | |
107 ;; Changed `dabbrev-always-check-other-buffers' to not buffer local. | |
108 ;; Thanks [kifer]. | |
109 ;; Bug in `dabbrev-completion', x expanded to xxy instead of xy. | |
110 ;; Thanks [kifer]. | |
111 ;; Added `dabbrev-submit-feedback' for better error-reporting. | |
112 ;; The hooks (`dabbrev-select-buffers-function' and | |
113 ;; `dabbrev-friend-buffer-function') are now not automatically | |
114 ;; buffer local. | |
115 ;; Now provides dabbrev too. | |
116 ;; 3.2 1993-12-14 | |
117 ;; Message for expansion found in buffer other than current. | |
118 ;; Minor bugs. | |
119 ;; 3.1 1993-12-13 | |
120 ;; Better comment for `dabbrev-abbrev-char-regexp'. | |
121 ;; 3.0 1993-12-09 | |
122 ;; Freshed things up for the release. | |
123 ;; `dabbrev-completion' now doesn't have to use the minibuffer. | |
124 ;; Thanks [alon]. | |
125 ;; 2.0 1993-12-02 Lars Lindberg <lli@sypro.cap.se> | |
126 ;; Searches in other buffers for the expansion. | |
127 ;; Works also for the minibuffer. | |
128 ;; Added `dabbrev-completion'. | |
129 ;; More efficient code. | |
130 ;; Found minor bugs. | |
131 ;; 1.0 converted to Emacs Lisp by Spencer Thomas. | |
132 ;; Thoroughly cleaned up by Richard Stallman. | |
133 ;; 0.0 | |
134 ;; DABBREVS - "Dynamic abbreviations" hack, originally written by | |
135 ;; Don Morrison for Twenex Emacs. Converted to mlisp by Russ Fish. | |
136 ;; Supports the table feature to avoid hitting the same expansion on | |
137 ;; re-expand, and the search size limit variable. | |
138 | |
139 ;; Known bugs and limitations. | |
140 ;; - Possible to do several levels of `dabbrev-completion' in the | |
141 ;; minibuffer. | |
142 ;; - dabbrev-completion doesn't handle resetting the globals variables | |
143 ;; right. It resets them after finding the abbrev. | |
144 | |
145 ;; Future enhancements | |
146 ;; - Check the tags-files? Like tags-complete? | |
147 ;; - Add the possibility of searching both forward and backward to | |
148 ;; the nearest expansion. | |
149 ;; - Check the kill-ring when everything else fails. (Maybe something | |
150 ;; for hippie-expand?). [Bng] <boris@cs.rochester.edu> | |
151 | |
152 ;;; Thanks goes to | |
153 ;; [hymie] Hyman Rosen <marks!hymie@jyacc.jyacc.com> | |
154 ;; [burgett] Steve Burgett <burgett@bizet.eecs.berkeley.edu> | |
155 ;; [jules] Julian Gosnell <jules@x.co.uk> | |
156 ;; [kifer] Michael Kifer <kifer@sbcs.sunysb.edu> | |
157 ;; [ake] Ake Stenhoff <extaksf@aom.ericsson.se> | |
158 ;; [alon] Alon Albert <al%imercury@uunet.uu.net> | |
159 ;; [tromey] Tom Tromey <tromey@busco.lanl.gov> | |
160 ;; [Rolf] Rolf Schreiber <rolf@mathematik.uni-stuttgart.de> | |
161 ;; [Petri] Petri Raitio <per@tekla.fi> | |
162 ;; [ejb] Jay Berkenbilt <ejb@ERA.COM> | |
163 ;; [hawley] Bob Hawley <rth1@quartet.mt.att.com> | |
164 ;; ... and to all the people who have participated in the beta tests. | |
43 | 165 |
44 ;;; Code: | 166 ;;; Code: |
45 | 167 (require 'cl) |
46 ;; (defun dabbrevs-help () | 168 |
47 ;; "Give help about dabbrevs." | 169 ;;;---------------------------------------------------------------- |
48 ;; (interactive) | 170 ;;;---------------------------------------------------------------- |
49 ;; (&info "emacs" "dabbrevs") ; Select the specific info node. | 171 ;;; Customization variables |
50 ;; ) | 172 ;;;---------------------------------------------------------------- |
51 (defvar dabbrevs-limit nil | 173 ;;;---------------------------------------------------------------- |
52 "*Limits region searched by `dabbrevs-expand' to this many chars away.") | 174 (defvar dabbrev-backward-only nil |
53 (make-variable-buffer-local 'dabbrevs-limit) | 175 "*If non-NIL, `dabbrev-expand' only looks backwards.") |
54 | 176 |
55 (defvar dabbrevs-backward-only nil | 177 (defvar dabbrev-limit nil |
56 "*If non-NIL, `dabbrevs-expand' only looks backwards.") | 178 "*Limits region searched by `dabbrev-expand' to this many chars away.") |
57 | 179 |
58 ; State vars for dabbrevs-re-expand. | 180 (defvar dabbrev-abbrev-skip-leading-regexp nil |
59 (defvar last-dabbrevs-table nil | 181 "*Regexp for skipping leading characters of an abbreviation. |
60 "Table of expansions seen so far (local)") | 182 |
61 (make-variable-buffer-local 'last-dabbrevs-table) | 183 Example: Set this to \"\\\\$\" for programming languages that sometimes |
62 | 184 has and sometimes has not a leading $ for variable names. |
63 (defvar last-dabbrevs-abbreviation "" | 185 |
64 "Last string we tried to expand (local).") | 186 Set this to nil if no characters should be skipped.") |
65 (make-variable-buffer-local 'last-dabbrevs-abbreviation) | 187 |
66 | 188 ;; I recommend that you set this to nil. |
67 (defvar last-dabbrevs-direction 0 | 189 (defvar dabbrev-case-fold-search 'case-fold-search |
68 "Direction of last dabbrevs search (local)") | 190 "*T if dabbrev searches should ignore case. |
69 (make-variable-buffer-local 'last-dabbrevs-direction) | 191 nil if case is significant. |
70 | 192 Non-nil and not t means evaluate for value. |
71 (defvar last-dabbrevs-abbrev-location nil | 193 |
72 "Location last abbreviation began (local).") | 194 Example:Setting this to 'case-fold-search means evaluate that variable |
73 (make-variable-buffer-local 'last-dabbrevs-abbrev-location) | 195 to see if it is t or non-nil.") |
74 | 196 |
75 (defvar last-dabbrevs-expansion nil | 197 (defvar dabbrev-upcase-means-case-search nil |
76 "Last expansion of an abbreviation. (local)") | 198 "*The significance of an uppercase character in an abbreviation. |
77 (make-variable-buffer-local 'last-dabbrevs-expansion) | 199 |
78 | 200 This variable only makes sense when the value of |
79 (defvar last-dabbrevs-expansion-location nil | 201 `dabbrev-case-fold-search' evaluates to t. |
80 "Location the last expansion was found. (local)") | 202 |
81 (make-variable-buffer-local 'last-dabbrevs-expansion-location) | 203 nil = case fold search |
204 t = case sensitive search") | |
205 | |
206 ;; I recommend that you set this to nil. | |
207 (defvar dabbrev-case-replace 'case-replace | |
208 "*T if dabbrev should preserve case when expanding the abbreviation. | |
209 nil if it should not. | |
210 Non-nil and not t means evaluate for value. | |
211 | |
212 This variable only makes sense when the value of | |
213 `dabbrev-case-fold-search' evaluates to t. | |
214 | |
215 Example: Setting this to 'case-replace means evaluate that variable to | |
216 see if it is t or non-nil.") | |
217 | |
218 ;; I recommend that you set this to "\\sw\\|\\s_" | |
219 (defvar dabbrev-abbrev-char-regexp nil | |
220 "*A regexp that recognizes a character in an abbreviation or an | |
221 expansion. Will be surrounded with \\\\( ... \\\\) when used. | |
222 | |
223 Set this to \"\\\\sw\" if you want ordinary words or | |
224 \"\\\\sw\\\\|\\\\s_\" if you want symbols. | |
225 | |
226 You can also set it to nil if you want old-style dabbrev searching | |
227 (the abbreviation is from point to previous word-start, the | |
228 search is for symbols). | |
229 | |
230 For instance, if you are programming in Lisp, yes-or-no-p is a symbol, | |
231 while 'yes', 'or', 'no' and 'p' are considered words. If you set this | |
232 variable to nil, then expanding yes-or-no- will look for a symbol | |
233 starting with or containing 'no-'. If you set this variable to | |
234 \"\\\\sw\\\\|\\\\s_\" dabbrev will look for a symbol starting with | |
235 \"yes-or-no-\". Finally, if you set this variable to \"\\\\sw\", then an | |
236 error will be signalled, because \"-\" is not part of a word but if you | |
237 try to expand \"yes-or-no\", dabbrev will look for a word starting with | |
238 \"no\". | |
239 | |
240 The recommended value is \"\\\\sw\\\\|\\\\s_\".") | |
241 | |
242 ;; I recommend that you set this to t. | |
243 (defvar dabbrev-check-rest-of-buffers nil | |
244 "*Should dabbrev package search in all buffers?. | |
245 | |
246 Non-nil means first look in buffers pointed out by | |
247 `dabbrev-select-buffers-function' and then look in the rest of the | |
248 buffers.") | |
249 | |
250 | |
251 ;; I recommend that you set this to t. | |
252 (defvar dabbrev-always-check-other-buffers nil | |
253 "*Should \\[dabbrev-expand] look in other buffers?\ | |
254 nil = Don't look in other buffers.\n\ | |
255 t = Look in other buffers.\n\ | |
256 Value other than nil and t = ask the user if he want's to look in | |
257 other buffers. | |
258 | |
259 The recommended value is t.") | |
260 | |
261 ;; I guess setting this to a function that selects all C- or C++- | |
262 ;; mode buffers would be a good choice for a debugging buffer, | |
263 ;; when debugging C- or C++-code. | |
264 (defvar dabbrev-select-buffers-function 'dabbrev--select-buffers | |
265 "A function that selects buffers that should be searched by dabbrev. | |
266 | |
267 The function should take no arguments and return a list of buffers to | |
268 search for expansions. Have a look at `dabbrev--select-buffers' for | |
269 an example. | |
270 | |
271 A mode setting this variable should make it buffer local.") | |
272 | |
273 (defvar dabbrev-friend-buffer-function 'dabbrev--same-major-mode-p | |
274 "*A function to check if OTHER-BUFFER should be searched by dabbrev. | |
275 | |
276 The function should take one argument, OTHER-BUFFER, and return | |
277 non-nil if that buffer should be searched. Have a look at | |
278 `dabbrev--same-major-mode-p' for an example. | |
279 | |
280 Setting this makes sense only if the function pointed out by | |
281 `dabbrev-select-buffers-function' uses it. The package function | |
282 `dabbrev--select-buffers' is such a function. | |
283 | |
284 A mode setting this variable should make it buffer local.") | |
285 | |
286 (defvar dabbrev-search-these-buffers-only nil | |
287 "Should be a list of buffers if non-nil. | |
288 | |
289 Dabbrev search will only look in these buffers. It will not even look | |
290 in the current buffer if it is not a member of this list.") | |
291 | |
292 ;;;---------------------------------------------------------------- | |
293 ;;;---------------------------------------------------------------- | |
294 ;;; Internal variables | |
295 ;;;---------------------------------------------------------------- | |
296 ;;;---------------------------------------------------------------- | |
297 | |
298 ;; Last obarray of completions in `dabbrev-completion' | |
299 (defvar dabbrev--last-obarray nil) | |
300 | |
301 ;; Table of expansions seen so far | |
302 (defvar dabbrev--last-table nil) | |
303 | |
304 ;; Last string we tried to expand. | |
305 (defvar dabbrev--last-abbreviation nil) | |
306 | |
307 ;; Location last abbreviation began | |
308 (defvar dabbrev--last-abbrev-location nil) | |
309 | |
310 ;; Direction of last dabbrevs search | |
311 (defvar dabbrev--last-direction 0) | |
312 | |
313 ;; Last expansion of an abbreviation. | |
314 (defvar dabbrev--last-expansion nil) | |
315 | |
316 ;; Location the last expansion was found. | |
317 (defvar dabbrev--last-expansion-location nil) | |
318 | |
319 ;; The list of remaining buffers with the same mode as current buffer. | |
320 (defvar dabbrev--friend-buffer-list nil) | |
321 | |
322 ;; The buffer we looked in last. | |
323 (defvar dabbrev--last-buffer nil) | |
324 | |
325 ;; The buffer we found the expansion last time. | |
326 (defvar dabbrev--last-buffer-found nil) | |
327 | |
328 ;; The buffer we last did a completion in. | |
329 (defvar dabbrev--last-completion-buffer nil) | |
330 | |
331 ;; Same as dabbrev-always-check-other-buffers, but is set for every expand. | |
332 (defvar dabbrev--check-other-buffers dabbrev-always-check-other-buffers) | |
333 | |
334 ;; The regexp for recognizing a character in an abbreviation. | |
335 (defvar dabbrev--abbrev-char-regexp nil) | |
336 | |
337 ;;;---------------------------------------------------------------- | |
338 ;;;---------------------------------------------------------------- | |
339 ;;; Macros | |
340 ;;;---------------------------------------------------------------- | |
341 ;;;---------------------------------------------------------------- | |
342 | |
343 ;;; Get the buffer that mini-buffer was activated from | |
344 (defsubst dabbrev--minibuffer-origin () | |
345 (car (cdr (buffer-list)))) | |
346 | |
347 ;;;---------------------------------------------------------------- | |
348 ;;;---------------------------------------------------------------- | |
349 ;;; Exported functions | |
350 ;;;---------------------------------------------------------------- | |
351 ;;;---------------------------------------------------------------- | |
352 | |
353 ;;;###autoload | |
354 (define-key esc-map "/" 'dabbrev-expand) | |
355 ;;;###autoload | |
356 (if (string-match "Lucid$" emacs-version) | |
357 (define-key esc-map [(control /)] 'dabbrev-completion) | |
358 (define-key esc-map [?\C-/] 'dabbrev-completion)) | |
359 | |
360 ;;;###autoload | |
361 (defun dabbrev-completion (&optional arg) | |
362 "Completion on current word. | |
363 | |
364 Like \\[dabbrev-expand] but finds all expansions in the current buffer | |
365 and presents suggestions for completion. | |
366 | |
367 If you call this function with prefix ARG, then it searches all | |
368 buffers accepted by the function pointed out by | |
369 `dabbrev-friend-buffer-function' to find the completions. | |
370 | |
371 With no prefix ARG it tries to reuse the old completion list | |
372 before making a new one." | |
373 | |
374 (interactive "*P") | |
375 (let* ((dabbrev-always-check-other-buffers (and arg t)) | |
376 (abbrev (dabbrev--abbrev-at-point)) | |
377 (ignore-case-p (and (eval dabbrev-case-fold-search) | |
378 (or (not dabbrev-upcase-means-case-search) | |
379 (string= abbrev (downcase abbrev))))) | |
380 (my-obarray dabbrev--last-obarray) | |
381 init) | |
382 (save-excursion | |
383 (if (and (null arg) | |
384 my-obarray | |
385 (or (eq dabbrev--last-completion-buffer (current-buffer)) | |
386 (and (window-minibuffer-p (selected-window)) | |
387 (eq dabbrev--last-completion-buffer | |
388 (dabbrev--minibuffer-origin)))) | |
389 dabbrev--last-abbreviation | |
390 (>= (length abbrev) (length dabbrev--last-abbreviation)) | |
391 (string= dabbrev--last-abbreviation | |
392 (substring abbrev 0 | |
393 (length dabbrev--last-abbreviation))) | |
394 (setq init (try-completion abbrev my-obarray))) | |
395 ;;-------------------------------- | |
396 ;; This is a continue. | |
397 ;;-------------------------------- | |
398 (progn) | |
399 ;;-------------------------------- | |
400 ;; New abbreviation to expand. | |
401 ;;-------------------------------- | |
402 (dabbrev--reset-global-variables) | |
403 (setq dabbrev--last-abbreviation abbrev) | |
404 ;; Find all expansion | |
405 (let ((completion-list | |
406 (dabbrev--find-all-expansions abbrev ignore-case-p))) | |
407 ;; Make an obarray with all expansions | |
408 (setq my-obarray (make-vector (length completion-list) 0)) | |
409 (or (> (length my-obarray) 0) | |
410 (error "No dynamic expansion for \"%s\" found%s." | |
411 abbrev | |
412 (if dabbrev--check-other-buffers "" " in this-buffer"))) | |
413 (cond | |
414 ((or (not ignore-case-p) | |
415 (not dabbrev-case-replace)) | |
416 (mapc (function (lambda (string) | |
417 (intern string my-obarray))) | |
418 completion-list)) | |
419 ((string= abbrev (upcase abbrev)) | |
420 (mapc (function (lambda (string) | |
421 (intern (upcase string) my-obarray))) | |
422 completion-list)) | |
423 ((string= (substring abbrev 0 1) | |
424 (upcase (substring abbrev 0 1))) | |
425 (mapc (function (lambda (string) | |
426 (intern (dabbrev--capitalize string) my-obarray))) | |
427 completion-list)) | |
428 (t | |
429 (mapc (function (lambda (string) | |
430 (intern (downcase string) my-obarray))) | |
431 completion-list))) | |
432 (setq dabbrev--last-obarray my-obarray) | |
433 (setq dabbrev--last-completion-buffer (current-buffer)) | |
434 ;; Find the longest common string. | |
435 (setq init (try-completion abbrev my-obarray))))) | |
436 ;;-------------------------------- | |
437 ;; Let the user choose between the expansions | |
438 ;;-------------------------------- | |
439 (or (stringp init) | |
440 (setq init abbrev)) | |
441 (cond | |
442 ;; * Replace string fragment with matched common substring completion. | |
443 ((and (not (string-equal init "")) | |
444 (not (string-equal (downcase init) (downcase abbrev)))) | |
445 (if (> (length (all-completions init my-obarray)) 1) | |
446 (message "Repeat '%s' to see all completions" this-command) | |
447 (message "The only possible completion")) | |
448 (dabbrev--substitute-expansion nil abbrev init)) | |
449 (t | |
450 ;; * String is a common substring completion already. Make list. | |
451 (message "Making completion list...") | |
452 (with-output-to-temp-buffer " *Completions*" | |
453 (display-completion-list (all-completions init my-obarray))) | |
454 (message "Making completion list... Done."))) | |
455 (and (window-minibuffer-p (selected-window)) | |
456 (message nil)))) | |
82 | 457 |
83 ;;;###autoload | 458 ;;;###autoload |
84 (defun dabbrev-expand (arg) | 459 (defun dabbrev-expand (arg) |
85 "Expand previous word \"dynamically\". | 460 "Expand previous word \"dynamically\". |
461 | |
86 Expands to the most recent, preceding word for which this is a prefix. | 462 Expands to the most recent, preceding word for which this is a prefix. |
87 If no suitable preceding word is found, words following point are considered. | 463 If no suitable preceding word is found, words following point are |
88 | 464 considered. If still no suitable word is found, then look in the |
89 If `case-fold-search' and `case-replace' are non-nil (usually true) | 465 buffers accepted by the function pointed out by variable |
90 then the substituted word may be case-adjusted to match the abbreviation | 466 `dabbrev-friend-buffer-function'. |
91 that you had typed. This takes place if the substituted word, as found, | 467 |
92 is all lower case, or if it is at the beginning of a sentence and only | 468 A positive prefix argument, N, says to take the Nth backward _distinct_ |
93 its first letter was upper case. | 469 possibility. A negative argument says search forward. |
94 | |
95 A positive prefix arg N says to take the Nth backward DISTINCT | |
96 possibility. A negative argument says search forward. The variable | |
97 `dabbrev-backward-only' may be used to limit the direction of search to | |
98 backward if set non-nil. | |
99 | 470 |
100 If the cursor has not moved from the end of the previous expansion and | 471 If the cursor has not moved from the end of the previous expansion and |
101 no argument is given, replace the previously-made expansion | 472 no argument is given, replace the previously-made expansion |
102 with the next possible expansion not yet tried." | 473 with the next possible expansion not yet tried. |
474 | |
475 The variable `dabbrev-backward-only' may be used to limit the | |
476 direction of search to backward if set non-nil. | |
477 | |
478 To make it more powerful, make sure that | |
479 `dabbrev-always-check-other-buffers' is set to t. | |
480 | |
481 Also check out `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]." | |
103 (interactive "*P") | 482 (interactive "*P") |
104 (let (abbrev expansion old which loc n pattern | 483 (let (abbrev expansion old direction) |
105 (do-case (and case-fold-search case-replace))) | |
106 ;; abbrev -- the abbrev to expand | 484 ;; abbrev -- the abbrev to expand |
107 ;; expansion -- the expansion found (eventually) or nil until then | 485 ;; expansion -- the expansion found (eventually) or nil until then |
108 ;; old -- the text currently in the buffer | 486 ;; old -- the text currently in the buffer |
109 ;; (the abbrev, or the previously-made expansion) | 487 ;; (the abbrev, or the previously-made expansion) |
110 ;; loc -- place where expansion is found | |
111 ;; (to start search there for next expansion if requested later) | |
112 ;; do-case -- non-nil if should transform case when substituting. | |
113 (save-excursion | 488 (save-excursion |
114 (if (and (null arg) | 489 (if (and (null arg) |
115 (eq last-command this-command) | 490 dabbrev--last-abbrev-location |
116 last-dabbrevs-abbrev-location) | 491 (or (eq last-command this-command) |
492 (and (window-minibuffer-p (selected-window)) | |
493 (= dabbrev--last-abbrev-location | |
494 (point))))) | |
495 ;;-------------------------------- | |
496 ;; This is a redo. | |
497 ;;-------------------------------- | |
117 (progn | 498 (progn |
118 (setq abbrev last-dabbrevs-abbreviation) | 499 (setq abbrev dabbrev--last-abbreviation) |
119 (setq old last-dabbrevs-expansion) | 500 (setq old dabbrev--last-expansion) |
120 (setq which last-dabbrevs-direction)) | 501 (setq direction dabbrev--last-direction)) |
121 (setq which (if (null arg) | 502 ;;-------------------------------- |
122 (if dabbrevs-backward-only 1 0) | 503 ;; New abbreviation to expand. |
123 (prefix-numeric-value arg))) | 504 ;;-------------------------------- |
124 (setq loc (point)) | 505 (dabbrev--reset-global-variables) |
125 (forward-word -1) | 506 (setq direction (if (null arg) |
126 (setq last-dabbrevs-abbrev-location (point)) ; Original location. | 507 (if dabbrev-backward-only 1 0) |
127 (setq abbrev (buffer-substring (point) loc)) | 508 (prefix-numeric-value arg))) |
128 (setq old abbrev) | 509 (setq abbrev (dabbrev--abbrev-at-point)) |
129 (setq last-dabbrevs-expansion-location nil) | 510 (setq old nil)) |
130 (setq last-dabbrev-table nil)) ; Clear table of things seen. | 511 |
131 | 512 ;;-------------------------------- |
132 (setq pattern (concat "\\b" (regexp-quote abbrev) "\\(\\sw\\|\\s_\\)+")) | 513 ;; Find the expansion |
133 ;; Try looking backward unless inhibited. | 514 ;;-------------------------------- |
134 (if (>= which 0) | 515 (setq expansion |
135 (progn | 516 (dabbrev--find-expansion abbrev direction |
136 (setq n (max 1 which)) | 517 (and (eval dabbrev-case-fold-search) |
137 (if last-dabbrevs-expansion-location | 518 (or (not dabbrev-upcase-means-case-search) |
138 (goto-char last-dabbrevs-expansion-location)) | 519 (string= abbrev (downcase abbrev))))))) |
139 (while (and (> n 0) | 520 (cond |
140 (setq expansion (dabbrevs-search pattern t do-case))) | 521 ((not expansion) |
141 (setq loc (point-marker)) | 522 (dabbrev--reset-global-variables) |
142 (setq last-dabbrev-table (cons expansion last-dabbrev-table)) | 523 (if old |
143 (setq n (1- n))) | 524 (save-excursion |
144 (or expansion | 525 (search-backward (substring old (length abbrev))) |
145 (setq last-dabbrevs-expansion-location nil)) | 526 (delete-region (match-beginning 0) (match-end 0)))) |
146 (setq last-dabbrevs-direction (min 1 which)))) | 527 (error "No%s dynamic expansion for \"%s\" found." |
147 | 528 (if old " further" "") abbrev)) |
148 (if (and (<= which 0) (not expansion)) ; Then look forward. | 529 (t |
149 (progn | 530 (if (not (eq dabbrev--last-buffer dabbrev--last-buffer-found)) |
150 (setq n (max 1 (- which))) | 531 (progn |
151 (if last-dabbrevs-expansion-location | 532 (message "Expansion found in '%s'" |
152 (goto-char last-dabbrevs-expansion-location)) | 533 (buffer-name dabbrev--last-buffer)) |
153 (while (and (> n 0) | 534 (setq dabbrev--last-buffer-found dabbrev--last-buffer)) |
154 (setq expansion (dabbrevs-search pattern nil do-case))) | 535 (message nil)) |
155 (setq loc (point-marker)) | |
156 (setq last-dabbrev-table (cons expansion last-dabbrev-table)) | |
157 (setq n (1- n))) | |
158 (setq last-dabbrevs-direction -1)))) | |
159 | |
160 (if (not expansion) | |
161 (let ((first (string= abbrev old))) | |
162 (setq last-dabbrevs-abbrev-location nil) | |
163 (if (not first) | |
164 (progn (undo-boundary) | |
165 (search-backward old) | |
166 (if (eq major-mode 'picture-mode) | |
167 (picture-replace-match abbrev t 'literal) | |
168 (replace-match abbrev t 'literal)))) | |
169 (error (if first | |
170 "No dynamic expansion for \"%s\" found." | |
171 "No further dynamic expansions for \"%s\" found.") | |
172 abbrev)) | |
173 ;; Success: stick it in and return. | 536 ;; Success: stick it in and return. |
174 (undo-boundary) | 537 (dabbrev--substitute-expansion old abbrev expansion) |
175 (search-backward old) | 538 ;; Save state for re-expand. |
176 ;; Make case of replacement conform to case of abbreviation | 539 (setq dabbrev--last-expansion expansion) |
177 ;; provided (1) that kind of thing is enabled in this buffer | 540 (setq dabbrev--last-abbreviation abbrev) |
178 ;; and (2) the replacement itself is all lower case. | 541 (setq dabbrev--last-abbrev-location (point-marker)))))) |
179 ;; First put back the original abbreviation with its original | 542 |
180 ;; case pattern. | 543 (eval-when-compile (require 'reporter)) |
181 (save-excursion | 544 (defun dabbrev-submit-feedback () |
182 (if (eq major-mode 'picture-mode) | 545 "Submit via mail a bug report on the dabbrev package." |
183 (picture-replace-match abbrev t 'literal) | 546 (interactive) |
184 (replace-match abbrev t 'literal))) | 547 (require 'reporter) |
185 (search-forward abbrev) | 548 (and (y-or-n-p "Do you really want to submit a report on the dabbrev package? ") |
186 (let ((do-case (and do-case | 549 (reporter-submit-bug-report |
187 (string= (substring expansion 1) | 550 "Lars Lindberg <lli@sypro.cap.se>" |
188 (downcase (substring expansion 1)))))) | 551 (format "new-dabbrev.el (Release %s)" (dabbrev--version)) |
189 ;; First put back the original abbreviation with its original | 552 '(dabbrev-backward-only |
190 ;; case pattern. | 553 dabbrev-limit |
554 dabbrev-case-fold-search | |
555 dabbrev-case-replace | |
556 dabbrev-upcase-means-case-search | |
557 dabbrev-abbrev-char-regexp | |
558 dabbrev-always-check-other-buffers | |
559 dabbrev-select-buffers-function | |
560 dabbrev-friend-buffer-function) | |
561 nil nil nil))) | |
562 | |
563 ;;;---------------------------------------------------------------- | |
564 ;;;---------------------------------------------------------------- | |
565 ;;; Local functions | |
566 ;;;---------------------------------------------------------------- | |
567 ;;;---------------------------------------------------------------- | |
568 | |
569 (defun dabbrev--capitalize (string) | |
570 ;; Capitalize STRING (See capitalize-word) | |
571 (let ((new-string "")) | |
572 (save-match-data | |
573 (while (string-match "\\w+" string) | |
574 (let* ((mb (match-beginning 0)) | |
575 (me (match-end 0)) | |
576 (ms (substring string mb me))) | |
577 (setq new-string | |
578 (concat new-string | |
579 (substring string 0 mb) | |
580 (upcase (substring ms 0 1)) | |
581 (downcase (substring ms 1)))) | |
582 (setq string (substring string me))))) | |
583 new-string)) | |
584 | |
585 ;;; Checks if OTHER-BUFFER has the same major mode as current buffer. | |
586 (defun dabbrev--same-major-mode-p (other-buffer) | |
587 (let ((orig-mode major-mode)) | |
588 (save-excursion | |
589 (set-buffer other-buffer) | |
590 (eq orig-mode major-mode)))) | |
591 | |
592 ;;; Back over all abbrev type characters and then moves forward over | |
593 ;;; all skip characters. | |
594 (defun dabbrev--goto-start-of-abbrev () | |
595 ;; Move backwards over abbrev chars | |
596 (save-match-data | |
597 (when (not (bobp)) | |
598 (forward-char -1) | |
599 (while (and (looking-at dabbrev--abbrev-char-regexp) | |
600 (not (bobp))) | |
601 (forward-char -1)) | |
602 (or (looking-at dabbrev--abbrev-char-regexp) | |
603 (forward-char 1))) | |
604 (and dabbrev-abbrev-skip-leading-regexp | |
605 (while (looking-at dabbrev-abbrev-skip-leading-regexp) | |
606 (forward-char 1))))) | |
607 | |
608 ;;; Extract the symbol at point to serve as abbrevitation. | |
609 (defun dabbrev--abbrev-at-point () | |
610 ;; Check for error | |
611 (save-excursion | |
612 (save-match-data | |
613 (if (or (bobp) | |
614 (progn | |
615 (forward-char -1) | |
616 (not (looking-at (concat "\\(" | |
617 (or dabbrev-abbrev-char-regexp | |
618 "\\sw\\|\\s_") | |
619 "\\)+"))))) | |
620 (error "Not positioned immediately after an abbreviation.")))) | |
621 ;; Return abbrev at point | |
622 (save-excursion | |
623 (setq dabbrev--last-abbrev-location (point)) | |
624 (buffer-substring (point) | |
625 (progn (dabbrev--goto-start-of-abbrev) | |
626 (point))))) | |
627 | |
628 ;;; Initializes all global variables | |
629 (defun dabbrev--reset-global-variables () | |
630 ;; dabbrev--last-obarray and dabbrev--last-completion-buffer | |
631 ;; must not be reset here. | |
632 (setq dabbrev--last-table nil | |
633 dabbrev--last-abbreviation nil | |
634 dabbrev--last-abbrev-location nil | |
635 dabbrev--last-direction nil | |
636 dabbrev--last-expansion nil | |
637 dabbrev--last-expansion-location nil | |
638 dabbrev--friend-buffer-list nil | |
639 dabbrev--last-buffer nil | |
640 dabbrev--last-buffer-found nil | |
641 dabbrev--abbrev-char-regexp (or dabbrev-abbrev-char-regexp | |
642 "\\sw\\|\\s_") | |
643 dabbrev--check-other-buffers dabbrev-always-check-other-buffers)) | |
644 | |
645 ;;; Find all buffers that are considered "friends" according to the | |
646 ;;; function pointed out by dabbrev-friend-buffer-function. | |
647 (defun dabbrev--select-buffers () | |
648 (save-excursion | |
649 (and (window-minibuffer-p (selected-window)) | |
650 (set-buffer (dabbrev--minibuffer-origin))) | |
651 (let ((orig-buffer (current-buffer))) | |
652 (loop for buffer | |
653 in (buffer-list) | |
654 if (and (not (eq orig-buffer buffer)) | |
655 (boundp 'dabbrev-friend-buffer-function) | |
656 (funcall dabbrev-friend-buffer-function buffer)) | |
657 collect buffer)))) | |
658 | |
659 ;;; Try to find ABBREV in REVERSE direction N times. | |
660 (defun dabbrev--try-find (abbrev reverse n ignore-case) | |
661 (save-excursion | |
662 (let ((case-fold-search-is-local (memq 'case-fold-search | |
663 (buffer-local-variables))) | |
664 (expansion nil)) | |
665 (and dabbrev--last-expansion-location | |
666 (goto-char dabbrev--last-expansion-location)) | |
667 (unwind-protect | |
668 (progn | |
669 (or case-fold-search-is-local | |
670 (make-local-variable 'case-fold-search)) | |
671 ;; Tricky! If `case-fold-search' isn't buffer-local, then | |
672 ;; this innocent let creates a buffer-local variable and | |
673 ;; when the let returns, it is still there! The | |
674 ;; unwind-protect stuff around this makes sure that there | |
675 ;; exists one before the let, and removes it afterwards. | |
676 (let ((case-fold-search ignore-case)) | |
677 (loop repeat n | |
678 while (setq expansion (dabbrev--search abbrev | |
679 reverse | |
680 ignore-case))))) | |
681 (or case-fold-search-is-local | |
682 (kill-local-variable 'case-fold-search))) | |
683 (and expansion | |
684 (setq dabbrev--last-expansion-location (point))) | |
685 expansion))) | |
686 | |
687 ;;; Find all expansions of ABBREV | |
688 (defun dabbrev--find-all-expansions (abbrev ignore-case) | |
689 (let ((all-expansions nil) | |
690 expansion) | |
691 (save-excursion | |
692 (goto-char (point-min)) | |
693 (while (setq expansion (dabbrev--find-expansion abbrev -1 ignore-case)) | |
694 (push expansion all-expansions))) | |
695 all-expansions)) | |
696 | |
697 (defun dabbrev--scanning-message () | |
698 (message "Scanning '%s'" (buffer-name (current-buffer)))) | |
699 | |
700 ;;; Find one occasion of ABBREV. | |
701 ;;; DIRECTION > 0 means look that many times backwards. | |
702 ;;; DIRECTION < 0 means look that many times forward. | |
703 ;;; DIRECTION = 0 means try both backward and forward. | |
704 ;;; IGNORE-CASE non-nil means ignore case when searching. | |
705 (defun dabbrev--find-expansion (abbrev direction ignore-case) | |
706 (let (expansion) | |
707 (save-excursion | |
708 (cond | |
709 (dabbrev--last-buffer | |
710 (set-buffer dabbrev--last-buffer) | |
711 (dabbrev--scanning-message)) | |
712 ((and (not dabbrev-search-these-buffers-only) | |
713 (window-minibuffer-p (selected-window))) | |
714 (set-buffer (dabbrev--minibuffer-origin)) | |
715 ;; In the minibuffer-origin buffer we will only search from | |
716 ;; the top and down. | |
717 (goto-char (point-min)) | |
718 (setq direction -1) | |
719 (dabbrev--scanning-message))) | |
720 (cond | |
721 ;; ------------------------------------------ | |
722 ;; Look backwards | |
723 ;; ------------------------------------------ | |
724 ((and (not dabbrev-search-these-buffers-only) | |
725 (>= direction 0) | |
726 (setq dabbrev--last-direction (min 1 direction)) | |
727 (setq expansion (dabbrev--try-find abbrev t | |
728 (max 1 direction) | |
729 ignore-case))) | |
730 expansion) | |
731 ;; ------------------------------------------ | |
732 ;; Look forward | |
733 ;; ------------------------------------------ | |
734 ((and (or (not dabbrev-search-these-buffers-only) | |
735 dabbrev--last-buffer) | |
736 (<= direction 0) | |
737 (setq dabbrev--last-direction -1) | |
738 (setq expansion (dabbrev--try-find abbrev nil | |
739 (max 1 (- direction)) | |
740 ignore-case))) | |
741 expansion) | |
742 ;; ------------------------------------------ | |
743 ;; Look in other buffers. | |
744 ;; Start at (point-min) and look forward. | |
745 ;; ------------------------------------------ | |
746 (t | |
747 (setq dabbrev--last-direction -1) | |
748 ;; Make sure that we should check other buffers | |
749 (or dabbrev--friend-buffer-list | |
750 dabbrev--last-buffer | |
751 (setq dabbrev--friend-buffer-list | |
752 (mapcar (function get-buffer) | |
753 dabbrev-search-these-buffers-only)) | |
754 (not dabbrev--check-other-buffers) | |
755 (not (or (eq dabbrev--check-other-buffers t) | |
756 (progn | |
757 (setq dabbrev--check-other-buffers | |
758 (y-or-n-p "Check in other buffers this time? "))))) | |
759 (let* (friend-buffer-list non-friend-buffer-list) | |
760 (setq dabbrev--friend-buffer-list | |
761 (funcall dabbrev-select-buffers-function)) | |
762 (when dabbrev-check-rest-of-buffers | |
763 (setq non-friend-buffer-list | |
764 (nreverse | |
765 (loop for buffer | |
766 in (buffer-list) | |
767 if (not (memq buffer dabbrev--friend-buffer-list)) | |
768 collect buffer))) | |
769 (setq dabbrev--friend-buffer-list | |
770 (append dabbrev--friend-buffer-list | |
771 non-friend-buffer-list))))) | |
772 ;; Walk through the buffers | |
773 (while (and (not expansion) dabbrev--friend-buffer-list) | |
774 (setq dabbrev--last-buffer | |
775 (car dabbrev--friend-buffer-list)) | |
776 (setq dabbrev--friend-buffer-list | |
777 (cdr dabbrev--friend-buffer-list)) | |
778 (set-buffer dabbrev--last-buffer) | |
779 (dabbrev--scanning-message) | |
780 (setq dabbrev--last-expansion-location (point-min)) | |
781 (setq expansion (dabbrev--try-find abbrev nil 1 ignore-case))) | |
782 expansion))))) | |
783 | |
784 (eval-when-compile (require 'picture)) | |
785 | |
786 (defun dabbrev--safe-replace-match (string &optional fixedcase literal) | |
787 (if (eq major-mode 'picture-mode) | |
788 (picture-replace-match string fixedcase literal) | |
789 (replace-match string fixedcase literal))) | |
790 | |
791 ;;;---------------------------------------------------------------- | |
792 ;;; Substitute the current string in buffer with the expansion | |
793 ;;; OLD is nil or the last expansion substring. | |
794 ;;; ABBREV is the abbreviation we are working with. | |
795 ;;; EXPANSION is the expansion substring. | |
796 (defun dabbrev--substitute-expansion (old abbrev expansion) | |
797 ;;(undo-boundary) | |
798 (let ((use-case-replace (and (eval dabbrev-case-fold-search) | |
799 (or (not dabbrev-upcase-means-case-search) | |
800 (string= abbrev (downcase abbrev))) | |
801 (eval dabbrev-case-replace)))) | |
802 (and nil use-case-replace | |
803 (setq old (concat abbrev (or old ""))) | |
804 (setq expansion (concat abbrev expansion))) | |
805 (if old | |
191 (save-excursion | 806 (save-excursion |
192 (replace-match abbrev t 'literal)) | 807 (search-backward old)) |
193 ;;; This used to be necessary, but no longer, | 808 ;;(store-match-data (list (point-marker) (point-marker))) |
194 ;;; because now point is preserved correctly above. | 809 (search-backward abbrev)) |
195 ;;; (search-forward abbrev) | 810 ;; Make case of replacement conform to case of abbreviation |
196 (if (eq major-mode 'picture-mode) | 811 ;; provided (1) that kind of thing is enabled in this buffer |
197 (picture-replace-match (if do-case (downcase expansion) expansion) | 812 ;; and (2) the replacement itself is all lower case. |
198 (not do-case) | 813 (dabbrev--safe-replace-match expansion |
199 'literal) | 814 (not use-case-replace) |
200 (replace-match (if do-case (downcase expansion) expansion) | 815 t))) |
201 (not do-case) | 816 |
202 'literal))) | 817 |
203 ;; Save state for re-expand. | 818 ;;;---------------------------------------------------------------- |
204 (setq last-dabbrevs-abbreviation abbrev) | 819 ;;; Search function used by dabbrevs library. |
205 (setq last-dabbrevs-expansion expansion) | 820 |
206 (setq last-dabbrevs-expansion-location loc)))) | 821 ;;; ABBREV is string to find as prefix of word. Second arg, REVERSE, |
207 | 822 ;;; is t for reverse search, nil for forward. Variable dabbrev-limit |
208 ;;;###autoload (define-key esc-map "/" 'dabbrev-expand) | 823 ;;; controls the maximum search region size. Third argment IGNORE-CASE |
209 | 824 ;;; non-nil means treat case as insignificant while looking for a match |
210 | 825 ;;; and when comparing with previous matches. Also if that's non-nil |
211 ;; Search function used by dabbrevs library. | 826 ;;; and the match is found at the beginning of a sentence and is in |
212 ;; First arg is string to find as prefix of word. Second arg is | 827 ;;; lower case except for the initial then it is converted to all lower |
213 ;; t for reverse search, nil for forward. Variable dabbrevs-limit | 828 ;;; case for return. |
214 ;; controls the maximum search region size. | 829 |
215 | 830 ;;; Table of expansions already seen is examined in buffer |
216 ;; Table of expansions already seen is examined in buffer last-dabbrev-table, | 831 ;;; `dabbrev--last-table' so that only distinct possibilities are found |
217 ;; so that only distinct possibilities are found by dabbrevs-re-expand. | 832 ;;; by dabbrev-re-expand. |
218 ;; Note that to prevent finding the abbrev itself it must have been | 833 |
219 ;; entered in the table. | 834 ;;; Value is the expansion, or nil if not found. |
220 | 835 |
221 ;; IGNORE-CASE non-nil means treat case as insignificant while | 836 (defun dabbrev--search (abbrev reverse ignore-case) |
222 ;; looking for a match and when comparing with previous matches. | 837 (save-match-data |
223 ;; Also if that's non-nil and the match is found at the beginning of a sentence | 838 (let ((pattern1 (concat (regexp-quote abbrev) |
224 ;; and is in lower case except for the initial | 839 "\\(" dabbrev--abbrev-char-regexp "\\)")) |
225 ;; then it is converted to all lower case for return. | 840 (pattern2 (concat (regexp-quote abbrev) |
226 | 841 "\\(\\(" dabbrev--abbrev-char-regexp "\\)+\\)")) |
227 ;; Value is the expansion, or nil if not found. After a successful | 842 (found-string nil)) |
228 ;; search, point is left right after the expansion found. | 843 ;; Limited search. |
229 | 844 (save-restriction |
230 (defun dabbrevs-search (pattern reverse ignore-case) | 845 (and dabbrev-limit |
231 (let (missing result (case-fold-search ignore-case)) | 846 (narrow-to-region dabbrev--last-expansion-location |
232 (save-restriction ; Uses restriction for limited searches. | 847 (+ (point) |
233 (if dabbrevs-limit | 848 (if reverse (- dabbrev-limit) dabbrev-limit)))) |
234 (narrow-to-region last-dabbrevs-abbrev-location | 849 ;;-------------------------------- |
235 (+ (point) | 850 ;; Look for a distinct expansion, using dabbrev--last-table. |
236 (* dabbrevs-limit (if reverse -1 1))))) | 851 ;;-------------------------------- |
237 ;; Keep looking for a distinct expansion. | 852 (while (and (not found-string) |
238 (setq result nil) | 853 (if reverse |
239 (setq missing nil) | 854 (re-search-backward pattern1 nil t) |
240 (while (and (not result) (not missing)) | 855 (re-search-forward pattern1 nil t))) |
241 ; Look for it, leave loop if search fails. | 856 (cond |
242 (setq missing | 857 ((progn |
243 (not (if reverse | 858 (goto-char (match-beginning 0)) |
244 (re-search-backward pattern nil t) | 859 (dabbrev--goto-start-of-abbrev) |
245 (re-search-forward pattern nil t)))) | 860 (/= (point) (match-beginning 0))) |
246 | 861 ;; Prefix of found abbreviation not OK |
247 (if (not missing) | 862 nil) |
248 (progn | 863 (t |
249 (setq result (buffer-substring (match-beginning 0) | 864 (goto-char (match-beginning 0)) |
250 (match-end 0))) | 865 (re-search-forward pattern2) |
251 (let* ((test last-dabbrev-table)) | 866 (setq found-string |
252 (while (and test | 867 (buffer-substring (match-beginning 1) (match-end 1))) |
253 (not | 868 (and ignore-case (setq found-string (downcase found-string))) |
254 (if ignore-case | 869 ;; Throw away if found in table |
255 (string= (downcase (car test)) | 870 (when (some |
256 (downcase result)) | 871 (function |
257 (string= (car test) result)))) | 872 (lambda (table-string) (string= found-string table-string))) |
258 (setq test (cdr test))) | 873 dabbrev--last-table) |
259 (if test (setq result nil)))))) ; if already in table, ignore | 874 (setq found-string nil)))) |
260 (if result | 875 (if reverse |
261 (save-excursion | 876 (goto-char (match-beginning 0)) |
262 (let ((beg (match-beginning 0))) | 877 (goto-char (match-end 0)))) |
263 (goto-char beg) | 878 (cond |
264 (and ignore-case | 879 (found-string |
265 (string= (substring result 1) | 880 ;;-------------------------------- |
266 (downcase (substring result 1))) | 881 ;; Put in `dabbrev--last-table' and decide if we should return |
267 (if (string= paragraph-start | 882 ;; result or (downcase result) |
268 (concat "^$\\|" page-delimiter)) | 883 ;;-------------------------------- |
269 (and (re-search-backward sentence-end nil t) | 884 (push found-string dabbrev--last-table) |
270 (= (match-end 0) beg)) | 885 (let ((result (buffer-substring (match-beginning 0) (match-end 0)))) |
271 (forward-char 1) | 886 (if (and ignore-case (eval dabbrev-case-replace)) |
272 (backward-sentence) | 887 (downcase result) |
273 (= (point) beg)) | 888 result)))))))) |
274 (setq result (downcase result)))))) | 889 |
275 result))) | 890 (provide 'new-dabbrev) |
276 | |
277 (provide 'dabbrev) | 891 (provide 'dabbrev) |
278 | 892 ;; new-dabbrev.el ends here |
279 ;;; dabbrev.el ends here | 893 |
894 |