No need to autoload vc-rcs, vc-sccs defcustoms.
[bpt/emacs.git] / lisp / hippie-exp.el
CommitLineData
e8af40ee 1;;; hippie-exp.el --- expand text trying various ways to find its expansion
3b1e4dd1 2
acaf905b 3;; Copyright (C) 1992, 2001-2012 Free Software Foundation, Inc.
b578f267 4
3b1e4dd1 5;; Author: Anders Holst <aho@sans.kth.se>
41b8e71c
RS
6;; Last change: 3 March 1998
7;; Version: 1.6
f5f727f8 8;; Keywords: abbrev convenience
3b1e4dd1 9
652304c9
RS
10;; This file is part of GNU Emacs.
11
eb3fa2cf 12;; GNU Emacs is free software: you can redistribute it and/or modify
652304c9 13;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
652304c9
RS
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
eb3fa2cf 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
652304c9 24
76550a57 25;;; Commentary:
b578f267 26
652304c9
RS
27;; `hippie-expand' is a single function for a lot of different kinds
28;; of completions and expansions. Called repeatedly it tries all
c60ee5e7 29;; possible completions in succession.
652304c9
RS
30;; Which kinds of completions to try, and in which order, is
31;; determined by the contents of `hippie-expand-try-functions-list'.
32;; Much customization of `hippie-expand' can be made by changing the
33;; order of, removing, or inserting new functions in this list.
34;; Given a positive numeric argument, `hippie-expand' jumps directly
35;; ARG functions forward in this list. Given some other argument
36;; (a negative argument or just Ctrl-U) it undoes the tried
37;; completion.
d1d1ddbd 38;;
652304c9
RS
39;; If the variable `hippie-expand-verbose' is non-nil, `hippie-expand'
40;; outputs in a message which try-function in the list that is used
41;; currently (ie. was used currently and will be tried first the next
42;; time).
8c6677ed
JB
43;; The variable `hippie-expand-max-buffers' determines in how many
44;; buffers, apart from the current, to search for expansions in. It
45;; is used by the try-functions named "-all-buffers".
d1d1ddbd
RS
46;; The variable `hippie-expand-ignore-buffers' is a list of regexps
47;; matching buffer names (as strings) or major modes (as atoms) of
48;; buffers that should not be searched by the try-functions named
49;; "-all-buffers".
41b8e71c
RS
50;; If set, the variable `hippie-expand-only-buffers' does the opposite
51;; of `hippie-expand-ignore-buffers', in that the search is restricted
52;; to only the kind of buffers listed.
53;; If the variable `hippie-expand-no-restriction' is non-nil, narrowed
54;; buffers are widened before they are searched.
55;; The variable `hippie-expand-dabbrev-skip-space' controls whether
56;; trailing spaces will be included in the abbreviation to search for,
57;; which then gives the same behavior as the original `dabbrev-expand'.
58;; The variable `hippie-expand-dabbrev-as-symbol' controls whether
59;; characters of syntax '_' is considered part of the words to expand
60;; dynamically.
652304c9 61;; See also the macro `make-hippie-expand-function' below.
c60ee5e7 62;;
652304c9
RS
63;; A short description of the current try-functions in this file:
64;; `try-complete-file-name' : very convenient to have in any buffer,
65;; and not just in the minibuffer or (some) shell-mode. It goes
66;; through all possible completions instead of just completing as
67;; much as is unique.
68;; `try-complete-file-name-partially' : To insert in the list just
69;; before `try-complete-file-name' for those who want first to get
70;; a file name completed only as many characters as is unique.
652304c9
RS
71;; `try-expand-all-abbrevs' : can be removed if you don't use abbrevs.
72;; Otherwise it looks through all abbrev-tables, starting with
c60ee5e7
JB
73;; the local followed by the global.
74;; `try-expand-line' : Searches the buffer for an entire line that
75;; begins exactly as the current line. Convenient sometimes, for
652304c9 76;; example as a substitute for (or complement to) the history
8c6677ed 77;; list in shell-like buffers. At other times, only confusing.
652304c9
RS
78;; `try-expand-line-all-buffers' : Like `try-expand-line' but searches
79;; in all buffers (except the current). (This may be a little
8c6677ed
JB
80;; slow, don't use it unless you are really fond of `hippie-expand'.)
81;; `try-expand-list' : Tries to expand the text back to the nearest
f72f0c23
SM
82;; open delimiter, to a whole list from the buffer. Convenient for
83;; example when writing Lisp or TeX.
c60ee5e7
JB
84;; `try-expand-list-all-buffers' : Like `try-expand-list' but searches
85;; in all buffers (except the current).
652304c9
RS
86;; `try-expand-dabbrev' : works exactly as dabbrev-expand (but of
87;; course in a way compatible with the other try-functions).
88;; `try-expand-dabbrev-all-buffers' : perhaps the most useful of them,
89;; like `dabbrev-expand' but searches all Emacs buffers (except the
90;; current) for matching words. (No, I don't find this one
c60ee5e7 91;; particularly slow.)
510cbc92
RS
92;; `try-expand-dabbrev-visible': Searches the currently visible parts of
93;; all windows. Can be put before `try-expand-dabbrev-all-buffers' to
94;; first try the expansions you can see.
95;; `try-expand-dabbrev-from-kill': Searches the kill ring for a suitable
96;; completion of the word. Good to have, just in case the word was not
97;; found elsewhere.
98;; `try-expand-whole-kill' : Tries to complete text with a whole entry
99;; from the kill ring. May be good if you don't know how far up in
100;; the kill-ring the required entry is, and don't want to mess with
101;; "Choose Next Paste".
652304c9
RS
102;; `try-complete-lisp-symbol' : like `lisp-complete-symbol', but goes
103;; through all possibilities instead of completing what is unique.
104;; Might be tedious (usually a lot of possible completions) and
105;; since its function is much like `lisp-complete-symbol', which
106;; already has a key of its own, you might want to remove this.
107;; `try-complete-lisp-symbol-partially' : To insert in the list just
108;; before `try-complete-lisp-symbol' for those who first want to get
c60ee5e7 109;; completion of what is unique in the name.
8c6677ed
JB
110;;
111;; Not all of the above functions are by default in
112;; `hippie-expand-try-functions-list'. This variable is better set
113;; in ".emacs" to make `hippie-expand' behave maximally convenient
114;; according to personal taste. Also, instead of loading the
115;; variable with all kinds of try-functions above, it might be an
116;; idea to use `make-hippie-expand-function' to construct different
117;; `hippie-expand'-like functions, with different try-lists and bound
f72f0c23 118;; to different keys. It is also possible to make
8c6677ed
JB
119;; `hippie-expand-try-functions-list' a buffer local variable, and
120;; let it depend on the mode (by setting it in the mode-hooks).
652304c9
RS
121;;
122;; To write new try-functions, consider the following:
123;; Each try-function takes one argument OLD which is nil the first
124;; time the function is called and true in succeeding calls for the
125;; same string to complete. The first time the function has to
126;; extract the string before point to complete, and substitute the
127;; first completion alternative for it. On following calls it has to
128;; substitute the next possible completion for the last tried string.
129;; The try-function is to return t as long as it finds new
130;; possible completions. When there are no more alternatives it has
131;; to restore the text before point to its original contents, and
132;; return nil (don't beep or message or anything).
133;; The try-function can (should) use the following functions:
134;; `he-init-string' : Initializes the text to substitute to the
135;; contents of the region BEGIN to END. Also sets the variable
136;; `he-search-string' to the text to expand.
137;; `he-substitute-string' : substitutes STR into the region
138;; initialized with `he-init-string'. (An optional second argument
139;; TRANS-CASE non-nil, means transfer of case from the abbreviation
140;; to the expansion is ok if that is enabled in the buffer.)
141;; `he-reset-string' : Resets the initialized region to its original
142;; contents.
143;; There is also a variable: `he-tried-table' which is meant to contain
c60ee5e7 144;; all tried expansions so far. The try-function can check this
652304c9 145;; variable to see whether an expansion has already been tried
510cbc92 146;; (hint: `he-string-member').
652304c9 147;;
8c6677ed 148;; Known bugs
652304c9
RS
149;;
150;; It may happen that some completion suggestion occurs twice, in
c60ee5e7 151;; spite of the use of `he-tried-table' to prevent that. This is
652304c9
RS
152;; because different try-functions may try to complete different
153;; lengths of text, and thus put different amounts of the
510cbc92
RS
154;; text in `he-tried-table'. Anyway this seems to occur seldom enough
155;; not to be too disturbing. Also it should NOT be possible for the
652304c9
RS
156;; opposite situation to occur, that `hippie-expand' misses some
157;; suggestion because it thinks it has already tried it.
158;;
09ae5da1 159;; Acknowledgment
652304c9
RS
160;;
161;; I want to thank Mikael Djurfeldt in discussions with whom the idea
162;; of this function took form.
163;; I am also grateful to all those who have given me suggestions on
510cbc92 164;; how to improve it, and all those who helped to find and remove bugs.
652304c9
RS
165;;
166
76550a57 167;;; Code:
652304c9 168
6df53d08 169(require 'comint)
ddb6e2e2 170
94114394
RS
171(defgroup hippie-expand nil
172 "Expand text trying various ways to find its expansion."
ddb6e2e2
DL
173 :link '(custom-manual "(autotype)Hippie Expand")
174 :link '(emacs-commentary-link "hippie-exp")
f5f727f8
DN
175 :group 'abbrev
176 :group 'convenience)
94114394 177
652304c9
RS
178(defvar he-num -1)
179
8c6677ed 180(defvar he-string-beg (make-marker))
652304c9 181
8c6677ed 182(defvar he-string-end (make-marker))
652304c9
RS
183
184(defvar he-search-string ())
185
186(defvar he-expand-list ())
187
188(defvar he-tried-table ())
189
8c6677ed 190(defvar he-search-loc (make-marker))
652304c9 191
510cbc92
RS
192(defvar he-search-loc2 ())
193
652304c9
RS
194(defvar he-search-bw ())
195
196(defvar he-search-bufs ())
197
8c6677ed
JB
198(defvar he-searched-n-bufs ())
199
510cbc92
RS
200(defvar he-search-window ())
201
ddb6e2e2
DL
202(defcustom hippie-expand-try-functions-list
203 '(try-complete-file-name-partially
204 try-complete-file-name
205 try-expand-all-abbrevs
206 try-expand-list
207 try-expand-line
208 try-expand-dabbrev
209 try-expand-dabbrev-all-buffers
210 try-expand-dabbrev-from-kill
211 try-complete-lisp-symbol-partially
212 try-complete-lisp-symbol)
652304c9
RS
213 "The list of expansion functions tried in order by `hippie-expand'.
214To change the behavior of `hippie-expand', remove, change the order of,
ddb6e2e2
DL
215or insert functions in this list."
216 :type '(repeat function)
217 :group 'hippie-expand)
652304c9 218
94114394 219(defcustom hippie-expand-verbose t
9201cc28 220 "Non-nil makes `hippie-expand' output which function it is trying."
94114394
RS
221 :type 'boolean
222 :group 'hippie-expand)
652304c9 223
41b8e71c 224(defcustom hippie-expand-dabbrev-skip-space nil
9201cc28 225 "Non-nil means tolerate trailing spaces in the abbreviation to expand."
41b8e71c
RS
226 :group 'hippie-expand
227 :type 'boolean)
228
41b8e71c 229(defcustom hippie-expand-dabbrev-as-symbol t
9201cc28 230 "Non-nil means expand as symbols, i.e. syntax `_' is considered a letter."
41b8e71c
RS
231 :group 'hippie-expand
232 :type 'boolean)
233
41b8e71c 234(defcustom hippie-expand-no-restriction t
9201cc28 235 "Non-nil means that narrowed buffers are widened during search."
41b8e71c
RS
236 :group 'hippie-expand
237 :type 'boolean)
238
94114394 239(defcustom hippie-expand-max-buffers ()
9201cc28 240 "The maximum number of buffers (apart from the current) searched.
94114394
RS
241If nil, all buffers are searched."
242 :type '(choice (const :tag "All" nil)
243 integer)
244 :group 'hippie-expand)
8c6677ed 245
6bdad9ae 246(defcustom hippie-expand-ignore-buffers (list (purecopy "^ \\*.*\\*$") 'dired-mode)
9201cc28 247 "A list specifying which buffers not to search (if not current).
d1d1ddbd 248Can contain both regexps matching buffer names (as strings) and major modes
94114394
RS
249\(as atoms)"
250 :type '(repeat (choice regexp (symbol :tag "Major Mode")))
251 :group 'hippie-expand)
d1d1ddbd 252
41b8e71c 253(defcustom hippie-expand-only-buffers ()
9201cc28 254 "A list specifying the only buffers to search (in addition to current).
41b8e71c 255Can contain both regexps matching buffer names (as strings) and major modes
0ff9b955 256\(as atoms). If non-nil, this variable overrides the variable
41b8e71c
RS
257`hippie-expand-ignore-buffers'."
258 :type '(repeat (choice regexp (symbol :tag "Major Mode")))
259 :group 'hippie-expand)
260
8c6677ed 261;;;###autoload
652304c9
RS
262(defun hippie-expand (arg)
263 "Try to expand text before point, using multiple methods.
264The expansion functions in `hippie-expand-try-functions-list' are
265tried in order, until a possible expansion is found. Repeated
266application of `hippie-expand' inserts successively possible
c60ee5e7 267expansions.
652304c9 268With a positive numeric argument, jumps directly to the ARG next
c60ee5e7
JB
269function in this list. With a negative argument or just \\[universal-argument],
270undoes the expansion."
652304c9 271 (interactive "P")
c60ee5e7 272 (if (or (not arg)
652304c9
RS
273 (and (integerp arg) (> arg 0)))
274 (let ((first (or (= he-num -1)
275 (not (equal this-command last-command)))))
276 (if first
277 (progn
278 (setq he-num -1)
279 (setq he-tried-table nil)))
280 (if arg
281 (if (not first) (he-reset-string))
282 (setq arg 0))
283 (let ((i (max (+ he-num arg) 0)))
284 (while (not (or (>= i (length hippie-expand-try-functions-list))
c60ee5e7 285 (apply (nth i hippie-expand-try-functions-list)
652304c9
RS
286 (list (= he-num i)))))
287 (setq i (1+ i)))
288 (setq he-num i))
289 (if (>= he-num (length hippie-expand-try-functions-list))
290 (progn
291 (setq he-num -1)
292 (if first
293 (message "No expansion found")
294 (message "No further expansions found"))
295 (ding))
8c6677ed 296 (if (and hippie-expand-verbose
510cbc92 297 (not (window-minibuffer-p (selected-window))))
32561aba 298 (message "Using %s"
41b8e71c 299 (nth he-num hippie-expand-try-functions-list)))))
510cbc92
RS
300 (if (and (>= he-num 0)
301 (eq (marker-buffer he-string-beg) (current-buffer)))
652304c9
RS
302 (progn
303 (setq he-num -1)
304 (he-reset-string)
8c6677ed 305 (if (and hippie-expand-verbose
510cbc92 306 (not (window-minibuffer-p (selected-window))))
652304c9 307 (message "Undoing expansions"))))))
8c6677ed 308
652304c9
RS
309;; Initializes the region to expand (to between BEG and END).
310(defun he-init-string (beg end)
8c6677ed
JB
311 (set-marker he-string-beg beg)
312 (set-marker he-string-end end)
41b8e71c 313 (setq he-search-string (buffer-substring-no-properties beg end)))
652304c9
RS
314
315;; Resets the expanded region to its original contents.
316(defun he-reset-string ()
8c6677ed 317 (let ((newpos (point-marker)))
8c6677ed
JB
318 (goto-char he-string-beg)
319 (insert he-search-string)
510cbc92
RS
320 (delete-region (point) he-string-end)
321 (goto-char newpos)))
652304c9
RS
322
323;; Substitutes an expansion STR into the correct region (the region
c60ee5e7 324;; initialized with `he-init-string').
652304c9
RS
325;; An optional argument TRANS-CASE means that it is ok to transfer case
326;; from the abbreviation to the expansion if that is possible, and is
327;; enabled in the buffer.
328(defun he-substitute-string (str &optional trans-case)
329 (let ((trans-case (and trans-case
330 case-replace
510cbc92
RS
331 case-fold-search))
332 (newpos (point-marker))
333 (subst ()))
652304c9 334 (goto-char he-string-beg)
510cbc92
RS
335 (setq subst (if trans-case (he-transfer-case he-search-string str) str))
336 (setq he-tried-table (cons subst he-tried-table))
337 (insert subst)
338 (delete-region (point) he-string-end)
339 (goto-char newpos)))
340
341(defun he-capitalize-first (str)
342 (save-match-data
343 (if (string-match "\\Sw*\\(\\sw\\).*" str)
344 (let ((res (downcase str))
345 (no (match-beginning 1)))
346 (aset res no (upcase (aref str no)))
347 res)
348 str)))
652304c9
RS
349
350(defun he-ordinary-case-p (str)
351 (or (string= str (downcase str))
352 (string= str (upcase str))
510cbc92
RS
353 (string= str (capitalize str))
354 (string= str (he-capitalize-first str))))
355
356(defun he-transfer-case (from-str to-str)
357 (cond ((string= from-str (substring to-str 0 (min (length from-str)
358 (length to-str))))
359 to-str)
360 ((not (he-ordinary-case-p to-str))
8d392c8e 361 to-str)
510cbc92
RS
362 ((string= from-str (downcase from-str))
363 (downcase to-str))
364 ((string= from-str (upcase from-str))
365 (upcase to-str))
366 ((string= from-str (he-capitalize-first from-str))
367 (he-capitalize-first to-str))
368 ((string= from-str (capitalize from-str))
369 (capitalize to-str))
370 (t
371 to-str)))
372
652304c9
RS
373
374;; Check if STR is a member of LST.
0ff9b955 375;; Transform to the final case if optional TRANS-CASE is non-nil.
510cbc92
RS
376(defun he-string-member (str lst &optional trans-case)
377 (if str
378 (member (if (and trans-case
379 case-replace
380 case-fold-search)
381 (he-transfer-case he-search-string str)
382 str)
383 lst)))
652304c9 384
41b8e71c 385;; Check if current buffer matches any atom or regexp in LST.
53964682 386;; Atoms are interpreted as major modes, strings as regexps matching the name.
41b8e71c
RS
387(defun he-buffer-member (lst)
388 (or (memq major-mode lst)
389 (progn
390 (while (and lst
391 (or (not (stringp (car lst)))
392 (not (string-match (car lst) (buffer-name)))))
393 (setq lst (cdr lst)))
394 lst)))
d1d1ddbd 395
652304c9
RS
396;; For the real hippie-expand enthusiast: A macro that makes it
397;; possible to use many functions like hippie-expand, but with
398;; different try-functions-lists.
399;; Usage is for example:
400;; (fset 'my-complete-file (make-hippie-expand-function
401;; '(try-complete-file-name-partially
402;; try-complete-file-name)))
403;; (fset 'my-complete-line (make-hippie-expand-function
404;; '(try-expand-line
405;; try-expand-line-all-buffers)))
c60ee5e7 406;;
8c6677ed 407;;;###autoload
652304c9
RS
408(defmacro make-hippie-expand-function (try-list &optional verbose)
409 "Construct a function similar to `hippie-expand'.
410Make it use the expansion functions in TRY-LIST. An optional second
411argument VERBOSE non-nil makes the function verbose."
d7d20e6a 412 `(function (lambda (arg)
c60ee5e7 413 ,(concat
d7d20e6a
GM
414 "Try to expand text before point, using the following functions: \n"
415 (mapconcat 'prin1-to-string (eval try-list) ", "))
416 (interactive "P")
417 (let ((hippie-expand-try-functions-list ,try-list)
418 (hippie-expand-verbose ,verbose))
419 (hippie-expand arg)))))
652304c9
RS
420
421
422;;; Here follows the try-functions and their requisites:
423
510cbc92 424
652304c9
RS
425(defun try-complete-file-name (old)
426 "Try to complete text as a file name.
427The argument OLD has to be nil the first call of this function, and t
428for subsequent calls (for further possible completions of the same
429string). It returns t if a new completion is found, nil otherwise."
430 (if (not old)
c60ee5e7 431 (progn
652304c9 432 (he-init-string (he-file-name-beg) (point))
7c2fb837
DN
433 (let ((name-part (file-name-nondirectory he-search-string))
434 (dir-part (expand-file-name (or (file-name-directory
652304c9
RS
435 he-search-string) ""))))
436 (if (not (he-string-member name-part he-tried-table))
437 (setq he-tried-table (cons name-part he-tried-table)))
438 (if (and (not (equal he-search-string ""))
7c2fb837 439 (file-directory-p dir-part))
c60ee5e7 440 (setq he-expand-list (sort (file-name-all-completions
652304c9
RS
441 name-part
442 dir-part)
443 'string-lessp))
444 (setq he-expand-list ())))))
445
446 (while (and he-expand-list
447 (he-string-member (car he-expand-list) he-tried-table))
448 (setq he-expand-list (cdr he-expand-list)))
449 (if (null he-expand-list)
450 (progn
510cbc92 451 (if old (he-reset-string))
652304c9 452 ())
510cbc92 453 (let ((filename (he-concat-directory-file-name
7c2fb837 454 (file-name-directory he-search-string)
510cbc92 455 (car he-expand-list))))
652304c9 456 (he-substitute-string filename)
510cbc92 457 (setq he-tried-table (cons (car he-expand-list) (cdr he-tried-table)))
652304c9
RS
458 (setq he-expand-list (cdr he-expand-list))
459 t)))
460
461(defun try-complete-file-name-partially (old)
462 "Try to complete text as a file name, as many characters as unique.
463The argument OLD has to be nil the first call of this function. It
c60ee5e7 464returns t if a unique, possibly partial, completion is found, nil
652304c9
RS
465otherwise."
466 (let ((expansion ()))
467 (if (not old)
c60ee5e7 468 (progn
652304c9 469 (he-init-string (he-file-name-beg) (point))
7c2fb837
DN
470 (let ((name-part (file-name-nondirectory he-search-string))
471 (dir-part (expand-file-name (or (file-name-directory
652304c9
RS
472 he-search-string) ""))))
473 (if (and (not (equal he-search-string ""))
7c2fb837 474 (file-directory-p dir-part))
652304c9
RS
475 (setq expansion (file-name-completion name-part
476 dir-part)))
477 (if (or (eq expansion t)
510cbc92
RS
478 (string= expansion name-part)
479 (he-string-member expansion he-tried-table))
652304c9
RS
480 (setq expansion ())))))
481
482 (if (not expansion)
483 (progn
510cbc92 484 (if old (he-reset-string))
652304c9 485 ())
510cbc92 486 (let ((filename (he-concat-directory-file-name
7c2fb837 487 (file-name-directory he-search-string)
510cbc92 488 expansion)))
652304c9 489 (he-substitute-string filename)
510cbc92 490 (setq he-tried-table (cons expansion (cdr he-tried-table)))
652304c9
RS
491 t))))
492
510cbc92 493(defvar he-file-name-chars
7c2fb837 494 (cond ((memq system-type '(ms-dos windows-nt cygwin))
510cbc92
RS
495 "-a-zA-Z0-9_/.,~^#$+=:\\\\")
496 (t ;; More strange file formats ?
497 "-a-zA-Z0-9_/.,~^#$+="))
498 "Characters that are considered part of the file name to expand.")
499
652304c9 500(defun he-file-name-beg ()
de073e06
KH
501 (let ((op (point)))
502 (save-excursion
503 (skip-chars-backward he-file-name-chars)
504 (if (> (skip-syntax-backward "w") 0) ;; No words with non-file chars
41b8e71c
RS
505 op
506 (point)))))
652304c9 507
7c2fb837 508;; Thanks go to David Hughes <ukchugd@ukpmr.cs.philips.nl> who
510cbc92 509;; helped to make it work on PC.
510cbc92
RS
510(defun he-concat-directory-file-name (dir-part name-part)
511 "Try to slam together two parts of a file specification, system dependently."
a0341d13 512 (cond ((null dir-part) name-part)
a3374680 513 ((eq system-type 'ms-dos)
510cbc92
RS
514 (if (and (string-match "\\\\" dir-part)
515 (not (string-match "/" dir-part))
516 (= (aref name-part (1- (length name-part))) ?/))
517 (aset name-part (1- (length name-part)) ?\\))
518 (concat dir-part name-part))
c60ee5e7 519 (t
510cbc92 520 (concat dir-part name-part))))
c60ee5e7 521
652304c9
RS
522(defun try-complete-lisp-symbol (old)
523 "Try to complete word as an Emacs Lisp symbol.
524The argument OLD has to be nil the first call of this function, and t
525for subsequent calls (for further possible completions of the same
526string). It returns t if a new completion is found, nil otherwise."
527 (if (not old)
c60ee5e7 528 (progn
652304c9
RS
529 (he-init-string (he-lisp-symbol-beg) (point))
530 (if (not (he-string-member he-search-string he-tried-table))
531 (setq he-tried-table (cons he-search-string he-tried-table)))
c60ee5e7 532 (setq he-expand-list
652304c9
RS
533 (and (not (equal he-search-string ""))
534 (sort (all-completions he-search-string obarray
535 (function (lambda (sym)
536 (or (boundp sym)
537 (fboundp sym)
538 (symbol-plist sym)))))
539 'string-lessp)))))
540 (while (and he-expand-list
541 (he-string-member (car he-expand-list) he-tried-table))
542 (setq he-expand-list (cdr he-expand-list)))
543 (if (null he-expand-list)
544 (progn
510cbc92 545 (if old (he-reset-string))
652304c9
RS
546 ())
547 (progn
548 (he-substitute-string (car he-expand-list))
652304c9
RS
549 (setq he-expand-list (cdr he-expand-list))
550 t)))
551
552(defun try-complete-lisp-symbol-partially (old)
553 "Try to complete as an Emacs Lisp symbol, as many characters as unique.
554The argument OLD has to be nil the first call of this function. It
c60ee5e7 555returns t if a unique, possibly partial, completion is found, nil
652304c9
RS
556otherwise."
557 (let ((expansion ()))
558 (if (not old)
c60ee5e7 559 (progn
652304c9
RS
560 (he-init-string (he-lisp-symbol-beg) (point))
561 (if (not (string= he-search-string ""))
c60ee5e7 562 (setq expansion
652304c9
RS
563 (try-completion he-search-string obarray
564 (function (lambda (sym)
565 (or (boundp sym)
566 (fboundp sym)
567 (symbol-plist sym)))))))
568 (if (or (eq expansion t)
510cbc92
RS
569 (string= expansion he-search-string)
570 (he-string-member expansion he-tried-table))
652304c9
RS
571 (setq expansion ()))))
572
573 (if (not expansion)
574 (progn
510cbc92 575 (if old (he-reset-string))
652304c9
RS
576 ())
577 (progn
578 (he-substitute-string expansion)
652304c9
RS
579 t))))
580
581(defun he-lisp-symbol-beg ()
de073e06
KH
582 (save-excursion
583 (skip-syntax-backward "w_")
584 (point)))
652304c9
RS
585
586(defun try-expand-line (old)
587 "Try to complete the current line to an entire line in the buffer.
588The argument OLD has to be nil the first call of this function, and t
589for subsequent calls (for further possible completions of the same
590string). It returns t if a new completion is found, nil otherwise."
591 (let ((expansion ())
592 (strip-prompt (and (get-buffer-process (current-buffer))
d7210472 593 comint-use-prompt-regexp
8c6677ed 594 comint-prompt-regexp)))
652304c9
RS
595 (if (not old)
596 (progn
597 (he-init-string (he-line-beg strip-prompt) (point))
8c6677ed 598 (set-marker he-search-loc he-string-beg)
652304c9
RS
599 (setq he-search-bw t)))
600
601 (if (not (equal he-search-string ""))
602 (save-excursion
41b8e71c
RS
603 (save-restriction
604 (if hippie-expand-no-restriction
605 (widen))
606 ;; Try looking backward unless inhibited.
607 (if he-search-bw
c60ee5e7 608 (progn
41b8e71c
RS
609 (goto-char he-search-loc)
610 (setq expansion (he-line-search he-search-string
611 strip-prompt t))
612 (set-marker he-search-loc (point))
613 (if (not expansion)
614 (progn
615 (set-marker he-search-loc he-string-end)
616 (setq he-search-bw ())))))
617
618 (if (not expansion) ; Then look forward.
c60ee5e7 619 (progn
41b8e71c 620 (goto-char he-search-loc)
c60ee5e7 621 (setq expansion (he-line-search he-search-string
41b8e71c
RS
622 strip-prompt nil))
623 (set-marker he-search-loc (point)))))))
652304c9
RS
624
625 (if (not expansion)
626 (progn
510cbc92 627 (if old (he-reset-string))
652304c9
RS
628 ())
629 (progn
630 (he-substitute-string expansion t)
652304c9
RS
631 t))))
632
633(defun try-expand-line-all-buffers (old)
634 "Try to complete the current line, searching all other buffers.
635The argument OLD has to be nil the first call of this function, and t
636for subsequent calls (for further possible completions of the same
637string). It returns t if a new completion is found, nil otherwise."
638 (let ((expansion ())
639 (strip-prompt (and (get-buffer-process (current-buffer))
d7210472 640 comint-use-prompt-regexp
8c6677ed 641 comint-prompt-regexp))
510cbc92
RS
642 (buf (current-buffer))
643 (orig-case-fold-search case-fold-search))
652304c9
RS
644 (if (not old)
645 (progn
646 (he-init-string (he-line-beg strip-prompt) (point))
8c6677ed 647 (setq he-search-bufs (buffer-list))
510cbc92 648 (setq he-searched-n-bufs 0)
8c6677ed 649 (set-marker he-search-loc 1 (car he-search-bufs))))
652304c9
RS
650
651 (if (not (equal he-search-string ""))
c60ee5e7 652 (while (and he-search-bufs
510cbc92
RS
653 (not expansion)
654 (or (not hippie-expand-max-buffers)
655 (< he-searched-n-bufs hippie-expand-max-buffers)))
652304c9
RS
656 (set-buffer (car he-search-bufs))
657 (if (and (not (eq (current-buffer) buf))
41b8e71c
RS
658 (if hippie-expand-only-buffers
659 (he-buffer-member hippie-expand-only-buffers)
660 (not (he-buffer-member hippie-expand-ignore-buffers))))
652304c9 661 (save-excursion
41b8e71c
RS
662 (save-restriction
663 (if hippie-expand-no-restriction
664 (widen))
665 (goto-char he-search-loc)
666 (setq strip-prompt (and (get-buffer-process (current-buffer))
d7210472 667 comint-use-prompt-regexp
41b8e71c 668 comint-prompt-regexp))
c60ee5e7 669 (setq expansion
41b8e71c
RS
670 (let ((case-fold-search orig-case-fold-search))
671 (he-line-search he-search-string
672 strip-prompt nil)))
673 (set-marker he-search-loc (point))
674 (if (not expansion)
675 (progn
676 (setq he-search-bufs (cdr he-search-bufs))
677 (setq he-searched-n-bufs (1+ he-searched-n-bufs))
678 (set-marker he-search-loc 1 (car he-search-bufs))))))
510cbc92
RS
679 (setq he-search-bufs (cdr he-search-bufs))
680 (set-marker he-search-loc 1 (car he-search-bufs)))))
652304c9
RS
681
682 (set-buffer buf)
683 (if (not expansion)
684 (progn
510cbc92 685 (if old (he-reset-string))
652304c9
RS
686 ())
687 (progn
688 (he-substitute-string expansion t)
689 t))))
690
c60ee5e7 691(defun he-line-search (str strip-prompt reverse)
652304c9
RS
692 (let ((result ()))
693 (while (and (not result)
694 (if reverse
c60ee5e7 695 (re-search-backward
652304c9
RS
696 (he-line-search-regexp str strip-prompt)
697 nil t)
698 (re-search-forward
699 (he-line-search-regexp str strip-prompt)
700 nil t)))
d7d20e6a
GM
701 (setq result (buffer-substring-no-properties (match-end 1)
702 (match-end 0)))
510cbc92
RS
703 (if (he-string-member result he-tried-table t)
704 (setq result nil))) ; if already in table, ignore
652304c9
RS
705 result))
706
707(defun he-line-beg (strip-prompt)
708 (save-excursion
c60ee5e7 709 (if (re-search-backward (he-line-search-regexp "" strip-prompt)
9b026d9f 710 (line-beginning-position) t)
652304c9 711 (match-beginning 2)
652304c9
RS
712 (point))))
713
714(defun he-line-search-regexp (pat strip-prompt)
715 (if strip-prompt
8c6677ed 716 (concat "\\(" comint-prompt-regexp "\\|^\\s-*\\)\\("
652304c9
RS
717 (regexp-quote pat)
718 "[^\n]*[^ \t\n]\\)")
c60ee5e7 719 (concat "^\\(\\s-*\\)\\("
652304c9
RS
720 (regexp-quote pat)
721 "[^\n]*[^ \t\n]\\)")))
722
8c6677ed
JB
723(defun try-expand-list (old)
724 "Try to complete the current beginning of a list.
725The argument OLD has to be nil the first call of this function, and t
726for subsequent calls (for further possible completions of the same
727string). It returns t if a new completion is found, nil otherwise."
728 (let ((expansion ()))
729 (if (not old)
730 (progn
731 (he-init-string (he-list-beg) (point))
732 (set-marker he-search-loc he-string-beg)
733 (setq he-search-bw t)))
734
735 (if (not (equal he-search-string ""))
736 (save-excursion
41b8e71c
RS
737 (save-restriction
738 (if hippie-expand-no-restriction
739 (widen))
740 ;; Try looking backward unless inhibited.
741 (if he-search-bw
c60ee5e7 742 (progn
41b8e71c
RS
743 (goto-char he-search-loc)
744 (setq expansion (he-list-search he-search-string t))
745 (set-marker he-search-loc (point))
746 (if (not expansion)
747 (progn
748 (set-marker he-search-loc he-string-end)
749 (setq he-search-bw ())))))
750
751 (if (not expansion) ; Then look forward.
c60ee5e7 752 (progn
41b8e71c
RS
753 (goto-char he-search-loc)
754 (setq expansion (he-list-search he-search-string nil))
755 (set-marker he-search-loc (point)))))))
8c6677ed
JB
756
757 (if (not expansion)
758 (progn
759 (if old (he-reset-string))
760 ())
761 (progn
762 (he-substitute-string expansion t)
8c6677ed
JB
763 t))))
764
765(defun try-expand-list-all-buffers (old)
766 "Try to complete the current list, searching all other buffers.
767The argument OLD has to be nil the first call of this function, and t
768for subsequent calls (for further possible completions of the same
769string). It returns t if a new completion is found, nil otherwise."
770 (let ((expansion ())
510cbc92
RS
771 (buf (current-buffer))
772 (orig-case-fold-search case-fold-search))
8c6677ed
JB
773 (if (not old)
774 (progn
775 (he-init-string (he-list-beg) (point))
776 (setq he-search-bufs (buffer-list))
510cbc92 777 (setq he-searched-n-bufs 0)
8c6677ed
JB
778 (set-marker he-search-loc 1 (car he-search-bufs))))
779
780 (if (not (equal he-search-string ""))
c60ee5e7 781 (while (and he-search-bufs
510cbc92
RS
782 (not expansion)
783 (or (not hippie-expand-max-buffers)
784 (< he-searched-n-bufs hippie-expand-max-buffers)))
8c6677ed
JB
785 (set-buffer (car he-search-bufs))
786 (if (and (not (eq (current-buffer) buf))
41b8e71c
RS
787 (if hippie-expand-only-buffers
788 (he-buffer-member hippie-expand-only-buffers)
789 (not (he-buffer-member hippie-expand-ignore-buffers))))
8c6677ed 790 (save-excursion
41b8e71c
RS
791 (save-restriction
792 (if hippie-expand-no-restriction
793 (widen))
794 (goto-char he-search-loc)
c60ee5e7 795 (setq expansion
41b8e71c
RS
796 (let ((case-fold-search orig-case-fold-search))
797 (he-list-search he-search-string nil)))
798 (set-marker he-search-loc (point))
799 (if (not expansion)
800 (progn
801 (setq he-search-bufs (cdr he-search-bufs))
802 (setq he-searched-n-bufs (1+ he-searched-n-bufs))
803 (set-marker he-search-loc 1 (car he-search-bufs))))))
510cbc92
RS
804 (setq he-search-bufs (cdr he-search-bufs))
805 (set-marker he-search-loc 1 (car he-search-bufs)))))
8c6677ed
JB
806
807 (set-buffer buf)
808 (if (not expansion)
809 (progn
510cbc92 810 (if old (he-reset-string))
8c6677ed
JB
811 ())
812 (progn
813 (he-substitute-string expansion t)
814 t))))
815
c60ee5e7 816(defun he-list-search (str reverse)
8c6677ed 817 (let ((result ())
510cbc92 818 beg pos err)
8c6677ed
JB
819 (while (and (not result)
820 (if reverse
821 (search-backward str nil t)
822 (search-forward str nil t)))
823 (setq pos (point))
824 (setq beg (match-beginning 0))
825 (goto-char beg)
826 (setq err ())
827 (condition-case ()
510cbc92
RS
828 (forward-list 1)
829 (error (setq err t)))
c60ee5e7 830 (if (and reverse
510cbc92
RS
831 (> (point) he-string-beg))
832 (setq err t))
8c6677ed 833 (if (not err)
510cbc92 834 (progn
41b8e71c 835 (setq result (buffer-substring-no-properties beg (point)))
510cbc92
RS
836 (if (he-string-member result he-tried-table t)
837 (setq result nil)))) ; if already in table, ignore
8c6677ed
JB
838 (goto-char pos))
839 result))
840
841(defun he-list-beg ()
842 (save-excursion
843 (condition-case ()
510cbc92 844 (backward-up-list 1)
8c6677ed
JB
845 (error ()))
846 (point)))
847
652304c9
RS
848(defun try-expand-all-abbrevs (old)
849 "Try to expand word before point according to all abbrev tables.
850The argument OLD has to be nil the first call of this function, and t
851for subsequent calls (for further possible expansions of the same
852string). It returns t if a new expansion is found, nil otherwise."
853 (if (not old)
854 (progn
855 (he-init-string (he-dabbrev-beg) (point))
c60ee5e7 856 (setq he-expand-list
652304c9
RS
857 (and (not (equal he-search-string ""))
858 (mapcar (function (lambda (sym)
510cbc92
RS
859 (if (and (boundp sym) (vectorp (eval sym)))
860 (abbrev-expansion (downcase he-search-string)
861 (eval sym)))))
c60ee5e7 862 (append '(local-abbrev-table
652304c9
RS
863 global-abbrev-table)
864 abbrev-table-name-list))))))
865 (while (and he-expand-list
866 (or (not (car he-expand-list))
510cbc92 867 (he-string-member (car he-expand-list) he-tried-table t)))
652304c9
RS
868 (setq he-expand-list (cdr he-expand-list)))
869 (if (null he-expand-list)
870 (progn
510cbc92 871 (if old (he-reset-string))
652304c9
RS
872 ())
873 (progn
8c6677ed 874 (he-substitute-string (car he-expand-list) t)
652304c9
RS
875 (setq he-expand-list (cdr he-expand-list))
876 t)))
877
878(defun try-expand-dabbrev (old)
879 "Try to expand word \"dynamically\", searching the current buffer.
880The argument OLD has to be nil the first call of this function, and t
881for subsequent calls (for further possible expansions of the same
882string). It returns t if a new expansion is found, nil otherwise."
883 (let ((expansion ()))
884 (if (not old)
885 (progn
886 (he-init-string (he-dabbrev-beg) (point))
8c6677ed 887 (set-marker he-search-loc he-string-beg)
652304c9
RS
888 (setq he-search-bw t)))
889
890 (if (not (equal he-search-string ""))
891 (save-excursion
41b8e71c
RS
892 (save-restriction
893 (if hippie-expand-no-restriction
894 (widen))
895 ;; Try looking backward unless inhibited.
896 (if he-search-bw
c60ee5e7 897 (progn
41b8e71c
RS
898 (goto-char he-search-loc)
899 (setq expansion (he-dabbrev-search he-search-string t))
900 (set-marker he-search-loc (point))
901 (if (not expansion)
902 (progn
903 (set-marker he-search-loc he-string-end)
904 (setq he-search-bw ())))))
905
906 (if (not expansion) ; Then look forward.
c60ee5e7 907 (progn
41b8e71c
RS
908 (goto-char he-search-loc)
909 (setq expansion (he-dabbrev-search he-search-string nil))
910 (set-marker he-search-loc (point)))))))
c60ee5e7 911
652304c9
RS
912 (if (not expansion)
913 (progn
510cbc92 914 (if old (he-reset-string))
652304c9
RS
915 ())
916 (progn
917 (he-substitute-string expansion t)
652304c9
RS
918 t))))
919
920(defun try-expand-dabbrev-all-buffers (old)
f72f0c23 921 "Try to expand word \"dynamically\", searching all other buffers.
652304c9
RS
922The argument OLD has to be nil the first call of this function, and t
923for subsequent calls (for further possible expansions of the same
924string). It returns t if a new expansion is found, nil otherwise."
925 (let ((expansion ())
510cbc92
RS
926 (buf (current-buffer))
927 (orig-case-fold-search case-fold-search))
652304c9
RS
928 (if (not old)
929 (progn
930 (he-init-string (he-dabbrev-beg) (point))
8c6677ed 931 (setq he-search-bufs (buffer-list))
510cbc92 932 (setq he-searched-n-bufs 0)
8c6677ed 933 (set-marker he-search-loc 1 (car he-search-bufs))))
652304c9
RS
934
935 (if (not (equal he-search-string ""))
c60ee5e7 936 (while (and he-search-bufs
510cbc92
RS
937 (not expansion)
938 (or (not hippie-expand-max-buffers)
939 (< he-searched-n-bufs hippie-expand-max-buffers)))
652304c9
RS
940 (set-buffer (car he-search-bufs))
941 (if (and (not (eq (current-buffer) buf))
41b8e71c
RS
942 (if hippie-expand-only-buffers
943 (he-buffer-member hippie-expand-only-buffers)
944 (not (he-buffer-member hippie-expand-ignore-buffers))))
652304c9 945 (save-excursion
41b8e71c
RS
946 (save-restriction
947 (if hippie-expand-no-restriction
948 (widen))
949 (goto-char he-search-loc)
950 (setq expansion
951 (let ((case-fold-search orig-case-fold-search))
952 (he-dabbrev-search he-search-string nil)))
953 (set-marker he-search-loc (point))
954 (if (not expansion)
955 (progn
956 (setq he-search-bufs (cdr he-search-bufs))
957 (setq he-searched-n-bufs (1+ he-searched-n-bufs))
958 (set-marker he-search-loc 1 (car he-search-bufs))))))
510cbc92
RS
959 (setq he-search-bufs (cdr he-search-bufs))
960 (set-marker he-search-loc 1 (car he-search-bufs)))))
652304c9
RS
961
962 (set-buffer buf)
963 (if (not expansion)
964 (progn
510cbc92 965 (if old (he-reset-string))
652304c9
RS
966 ())
967 (progn
968 (he-substitute-string expansion t)
969 t))))
970
510cbc92
RS
971;; Thanks go to Jeff Dairiki <dairiki@faraday.apl.washington.edu> who
972;; suggested this one.
973(defun try-expand-dabbrev-visible (old)
974 "Try to expand word \"dynamically\", searching visible window parts.
975The argument OLD has to be nil the first call of this function, and t
976for subsequent calls (for further possible expansions of the same
977string). It returns t if a new expansion is found, nil otherwise."
978 (let ((expansion ())
510cbc92
RS
979 (flag (if (frame-visible-p (window-frame (selected-window)))
980 'visible t)))
f72f0c23
SM
981 (unless old
982 (he-init-string (he-dabbrev-beg) (point))
983 (setq he-search-window (selected-window))
984 (set-marker he-search-loc
985 (window-start he-search-window)
986 (window-buffer he-search-window)))
510cbc92
RS
987
988 (while (and (not (equal he-search-string ""))
f72f0c23
SM
989 (marker-position he-search-loc)
990 (not expansion))
7fdbcd83 991 (with-current-buffer (marker-buffer he-search-loc)
f72f0c23
SM
992 (save-excursion
993 (goto-char he-search-loc)
994 (setq expansion (he-dabbrev-search he-search-string ()
995 (window-end he-search-window)))
996 (if (and expansion
997 (eq (marker-buffer he-string-beg) (current-buffer))
998 (eq (marker-position he-string-beg) (match-beginning 0)))
999 (setq expansion
1000 (he-dabbrev-search he-search-string ()
1001 (window-end he-search-window))))
1002 (set-marker he-search-loc (point) (current-buffer))))
1003 (unless expansion
1004 (setq he-search-window (next-window he-search-window nil flag))
1005 (if (eq he-search-window (selected-window))
1006 (set-marker he-search-loc nil)
1007 (set-marker he-search-loc (window-start he-search-window)
1008 (window-buffer he-search-window)))))
c60ee5e7 1009
510cbc92
RS
1010 (if (not expansion)
1011 (progn
1012 (if old (he-reset-string))
1013 ())
1014 (progn
1015 (he-substitute-string expansion t)
1016 t))))
652304c9 1017
510cbc92
RS
1018(defun he-dabbrev-search (pattern &optional reverse limit)
1019 (let ((result ())
41b8e71c
RS
1020 (regpat (cond ((not hippie-expand-dabbrev-as-symbol)
1021 (concat "\\<" (regexp-quote pattern) "\\sw+"))
1022 ((eq (char-syntax (aref pattern 0)) ?_)
1023 (concat (regexp-quote pattern) "\\(\\sw\\|\\s_\\)+"))
1024 (t
1025 (concat "\\<" (regexp-quote pattern)
1026 "\\(\\sw\\|\\s_\\)+")))))
c60ee5e7 1027 (while (and (not result)
652304c9 1028 (if reverse
510cbc92
RS
1029 (re-search-backward regpat limit t)
1030 (re-search-forward regpat limit t)))
41b8e71c
RS
1031 (setq result (buffer-substring-no-properties (match-beginning 0)
1032 (match-end 0)))
1033 (if (or (and hippie-expand-dabbrev-as-symbol
1034 (> (match-beginning 0) (point-min))
510cbc92
RS
1035 (memq (char-syntax (char-after (1- (match-beginning 0))))
1036 '(?_ ?w)))
1037 (he-string-member result he-tried-table t))
1038 (setq result nil))) ; ignore if bad prefix or already in table
652304c9
RS
1039 result))
1040
1041(defun he-dabbrev-beg ()
510cbc92
RS
1042 (let ((op (point)))
1043 (save-excursion
41b8e71c 1044 (if hippie-expand-dabbrev-skip-space
510cbc92 1045 (skip-syntax-backward ". "))
41b8e71c
RS
1046 (if (= (skip-syntax-backward (if hippie-expand-dabbrev-as-symbol
1047 "w_" "w"))
1048 0)
510cbc92
RS
1049 op
1050 (point)))))
1051
1052(defun try-expand-dabbrev-from-kill (old)
1053 "Try to expand word \"dynamically\", searching the kill ring.
1054The argument OLD has to be nil the first call of this function, and t
1055for subsequent calls (for further possible completions of the same
1056string). It returns t if a new completion is found, nil otherwise."
1057 (let ((expansion ()))
1058 (if (not old)
c60ee5e7 1059 (progn
510cbc92
RS
1060 (he-init-string (he-dabbrev-beg) (point))
1061 (setq he-expand-list
1062 (if (not (equal he-search-string ""))
1063 kill-ring))
1064 (setq he-search-loc2 0)))
1065 (if (not (equal he-search-string ""))
1066 (setq expansion (he-dabbrev-kill-search he-search-string)))
1067 (if (not expansion)
1068 (progn
1069 (if old (he-reset-string))
1070 ())
1071 (progn
1072 (he-substitute-string expansion t)
1073 t))))
1074
1075(defun he-dabbrev-kill-search (pattern)
1076 (let ((result ())
41b8e71c
RS
1077 (regpat (cond ((not hippie-expand-dabbrev-as-symbol)
1078 (concat "\\<" (regexp-quote pattern) "\\sw+"))
1079 ((eq (char-syntax (aref pattern 0)) ?_)
1080 (concat (regexp-quote pattern) "\\(\\sw\\|\\s_\\)+"))
1081 (t
1082 (concat "\\<" (regexp-quote pattern)
1083 "\\(\\sw\\|\\s_\\)+"))))
510cbc92 1084 (killstr (car he-expand-list)))
c60ee5e7 1085 (while (and (not result)
510cbc92
RS
1086 he-expand-list)
1087 (while (and (not result)
1088 (string-match regpat killstr he-search-loc2))
1089 (setq result (substring killstr (match-beginning 0) (match-end 0)))
41b8e71c 1090 (set-text-properties 0 (length result) () result)
510cbc92 1091 (setq he-search-loc2 (1+ (match-beginning 0)))
41b8e71c
RS
1092 (if (or (and hippie-expand-dabbrev-as-symbol
1093 (> (match-beginning 0) 0)
510cbc92
RS
1094 (memq (char-syntax (aref killstr (1- (match-beginning 0))))
1095 '(?_ ?w)))
1096 (he-string-member result he-tried-table t))
1097 (setq result nil))) ; ignore if bad prefix or already in table
c60ee5e7 1098 (if (and (not result)
510cbc92
RS
1099 he-expand-list)
1100 (progn
c60ee5e7 1101 (setq he-expand-list (cdr he-expand-list))
510cbc92
RS
1102 (setq killstr (car he-expand-list))
1103 (setq he-search-loc2 0))))
1104 result))
1105
1106(defun try-expand-whole-kill (old)
1107 "Try to complete text with something from the kill ring.
1108The argument OLD has to be nil the first call of this function, and t
1109for subsequent calls (for further possible completions of the same
1110string). It returns t if a new completion is found, nil otherwise."
1111 (let ((expansion ()))
1112 (if (not old)
c60ee5e7 1113 (progn
510cbc92
RS
1114 (he-init-string (he-kill-beg) (point))
1115 (if (not (he-string-member he-search-string he-tried-table))
1116 (setq he-tried-table (cons he-search-string he-tried-table)))
c60ee5e7 1117 (setq he-expand-list
510cbc92
RS
1118 (if (not (equal he-search-string ""))
1119 kill-ring))
1120 (setq he-search-loc2 ())))
1121 (if (not (equal he-search-string ""))
1122 (setq expansion (he-whole-kill-search he-search-string)))
1123 (if (not expansion)
1124 (progn
1125 (if old (he-reset-string))
1126 ())
1127 (progn
1128 (he-substitute-string expansion)
1129 t))))
1130
1131(defun he-whole-kill-search (str)
1132 (let ((case-fold-search ())
1133 (result ())
1134 (str (regexp-quote str))
1135 (killstr (car he-expand-list))
1136 (pos -1))
1137 (while (and (not result)
1138 he-expand-list)
1139 (if (not he-search-loc2)
1140 (while (setq pos (string-match str killstr (1+ pos)))
1141 (setq he-search-loc2 (cons pos he-search-loc2))))
1142 (while (and (not result)
1143 he-search-loc2)
1144 (setq pos (car he-search-loc2))
1145 (setq he-search-loc2 (cdr he-search-loc2))
1146 (save-excursion
1147 (goto-char he-string-beg)
1148 (if (and (>= (- (point) pos) (point-min)) ; avoid some string GC
1149 (eq (char-after (- (point) pos)) (aref killstr 0))
1150 (search-backward (substring killstr 0 pos)
1151 (- (point) pos) t))
41b8e71c
RS
1152 (progn
1153 (setq result (substring killstr pos))
1154 (set-text-properties 0 (length result) () result))))
510cbc92
RS
1155 (if (and result
1156 (he-string-member result he-tried-table))
1157 (setq result nil))) ; ignore if already in table
1158 (if (and (not result)
1159 he-expand-list)
1160 (progn
c60ee5e7 1161 (setq he-expand-list (cdr he-expand-list))
510cbc92
RS
1162 (setq killstr (car he-expand-list))
1163 (setq pos -1))))
1164 result))
1165
1166(defun he-kill-beg ()
1167 (let ((op (point)))
1168 (save-excursion
1169 (skip-syntax-backward "^w_")
1170 (if (= (skip-syntax-backward "w_") 0)
1171 op
1172 (point)))))
1173
8c6677ed
JB
1174
1175(provide 'hippie-exp)
652304c9 1176
8c6677ed 1177;;; hippie-exp.el ends here