(Fprimitive_undo): Use base buffer's modtime field.
[bpt/emacs.git] / lisp / hippie-exp.el
index 1d2f647..9e7334a 100644 (file)
@@ -1,5 +1,11 @@
-;; Expand a word trying various ways to find its expansion.
-;; Copyright (C) 1992 Free Software Foundation, Inc.
+;;; hippie-exp.el --- expand text trying various ways to find its expansion.
+
+;; Author: Anders Holst <aho@sans.kth.se>
+;; Last change: 2 September 1993
+;; Version: 1.3
+;; Keywords: abbrev
+
+;; Copyright (C) 1992, 1993 Free Software Foundation, Inc.
 ;;
 ;; This file is part of GNU Emacs.
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to
 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-;; 
-;;  Author: Anders Holst (aho@sans.kth.se)
-;;
-;;  Last change: 4 January 1993
 
-;;  
-;;  DESCRIPTION
+;;; Commentary:
 ;;  
 ;;  `hippie-expand' is a single function for a lot of different kinds
 ;;  of completions and expansions.  Called repeatedly it tries all
 ;;  ARG functions forward in this list.  Given some other argument
 ;;  (a negative argument or just Ctrl-U) it undoes the tried
 ;;  completion.
+;;
 ;;  If the variable `hippie-expand-verbose' is non-nil, `hippie-expand'
 ;;  outputs in a message which try-function in the list that is used
 ;;  currently (ie. was used currently and will be tried first the next
 ;;  time).
+;;  The variable `hippie-expand-max-buffers' determines in how many
+;;  buffers, apart from the current, to search for expansions in.  It
+;;  is used by the try-functions named "-all-buffers".
+;;  The variable `hippie-expand-ignore-buffers' is a list of regexps
+;;  matching buffer names (as strings) or major modes (as atoms) of
+;;  buffers that should not be searched by the try-functions named
+;;  "-all-buffers".
 ;;  See also the macro `make-hippie-expand-function' below.
 ;;  
 ;;  A short description of the current try-functions in this file:
 ;;    `try-complete-file-name-partially' : To insert in the list just
 ;;      before `try-complete-file-name' for those who want first to get
 ;;      a file name completed only as many characters as is unique.
-;;      (NOTE: Not by default in `hippie-expand-try-functions-list'.)
 ;;    `try-expand-all-abbrevs' : can be removed if you don't use abbrevs.
 ;;      Otherwise it looks through all abbrev-tables, starting with
 ;;      the local followed by the global. 
 ;;    `try-expand-line' : Searches the buffer for an entire line that 
 ;;      begins exactly as the current line.  Convenient sometimes, for 
 ;;      example as a substitute for (or complement to) the history
-;;      list in shell-like buffers.  Remove it if you find it confusing.
+;;      list in shell-like buffers.  At other times, only confusing.
 ;;    `try-expand-line-all-buffers' : Like `try-expand-line' but searches
 ;;      in all buffers (except the current).  (This may be a little
-;;      slow, don't use it unless you are really fond of `hippie-expand'.
-;;      NOTE: Not by default in hippie-expand-try-functions-list.)
+;;      slow, don't use it unless you are really fond of `hippie-expand'.)
+;;    `try-expand-list' : Tries to expand the text back to the nearest
+;;      open delimiter, to a whole list from the buffer. Convenient for
+;;      example when writing lisp or TeX.
+;;    `try-expand-list-all-buffers' : Like `try-expand-list' but searches 
+;;      in all buffers (except the current).  
 ;;    `try-expand-dabbrev' : works exactly as dabbrev-expand (but of
 ;;      course in a way compatible with the other try-functions).
 ;;    `try-expand-dabbrev-all-buffers' : perhaps the most useful of them,
 ;;      already has a key of its own, you might want to remove this.
 ;;    `try-complete-lisp-symbol-partially' : To insert in the list just
 ;;      before `try-complete-lisp-symbol' for those who first want to get
-;;      completion of what is unique in the name.  (NOTE: Not by
-;;      default in hippie-expand-try-functions-list.)
+;;      completion of what is unique in the name.  
+;;
+;;  Not all of the above functions are by default in
+;;  `hippie-expand-try-functions-list'.  This variable is better set
+;;  in ".emacs" to make `hippie-expand' behave maximally convenient
+;;  according to personal taste.  Also, instead of loading the
+;;  variable with all kinds of try-functions above, it might be an
+;;  idea to use `make-hippie-expand-function' to construct different
+;;  `hippie-expand'-like functions, with different try-lists and bound
+;;  to different keys. It is also possible to make
+;;  `hippie-expand-try-functions-list' a buffer local variable, and
+;;  let it depend on the mode (by setting it in the mode-hooks).
 ;;
 ;;  To write new try-functions, consider the following:
 ;;  Each try-function takes one argument OLD which is nil the first
 ;;  variable to see whether an expansion has already been tried
 ;;  (hint: `he-string-member'), and add its own tried expansions to it.
 ;;
-;;
-;;  KNOWN BUGS
+;;  Known bugs
 ;;
 ;;  It may happen that some completion suggestion occurs twice, in
 ;;  spite of the use of `he-tried-table' to prevent that.  This is 
 ;;  because different try-functions may try to complete different
 ;;  lengths of text, and thus put different amounts of the
 ;;  text in `he-try-table'.  Anyway this seems to occur seldom enough not
-;;  to be too disturbing.  Also it should NOT bee possible for the
+;;  to be too disturbing.  Also it should NOT be possible for the
 ;;  opposite situation to occur, that `hippie-expand' misses some
 ;;  suggestion because it thinks it has already tried it.
 ;;
-;;  
-;;  ACKNOWLEDGEMENT
+;;  Acknowledgement
 ;;
 ;;  I want to thank Mikael Djurfeldt in discussions with whom the idea
 ;;  of this function took form.
 ;;  how to improve it.
 ;;
 
+;;; Code:
 
 (defvar he-num -1)
 
-(defvar he-string-beg ())
+(defvar he-string-beg (make-marker))
 
-(defvar he-string-end ())
+(defvar he-string-end (make-marker))
 
 (defvar he-search-string ())
 
 
 (defvar he-tried-table ())
 
-(defvar he-search-loc ())
+(defvar he-search-loc (make-marker))
 
 (defvar he-search-bw ())
 
 (defvar he-search-bufs ())
 
+(defvar he-searched-n-bufs ())
+
+;;;###autoload
 (defvar hippie-expand-try-functions-list '(try-complete-file-name
                                           try-expand-all-abbrevs
+                                           try-expand-list
                                           try-expand-line
                                           try-expand-dabbrev
                                           try-expand-dabbrev-all-buffers
 To change the behavior of `hippie-expand', remove, change the order of,
 or insert functions in this list.")
 
+;;;###autoload
 (defvar hippie-expand-verbose t
   "*Non-nil makes `hippie-expand' output which function it is trying.")
 
+;;;###autoload
+(defvar hippie-expand-max-buffers ()
+  "*The maximum number of buffers (apart from the current) searched.
+If nil, all buffers are searched.")
+
+;;;###autoload
+(defvar hippie-expand-ignore-buffers '("^ \\*.*\\*$" dired-mode)
+  "*A list specifying which buffers not to search (if not current).
+Can contain both regexps matching buffer names (as strings) and major modes
+\(as atoms)")
+
+;;;###autoload
 (defun hippie-expand (arg)
   "Try to expand text before point, using multiple methods.
 The expansion functions in `hippie-expand-try-functions-list' are
@@ -190,7 +228,8 @@ undoes the expansion."
                  (message "No expansion found")
                  (message "No further expansions found"))
              (ding))
-           (if hippie-expand-verbose
+           (if (and hippie-expand-verbose
+                     (not (window-minibuffer-p (selected-window))))
                (message (concat "Using "
                                 (prin1-to-string (nth he-num 
                                   hippie-expand-try-functions-list)))))))
@@ -198,20 +237,26 @@ undoes the expansion."
          (progn
            (setq he-num -1)
            (he-reset-string)
-           (if hippie-expand-verbose
+           (if (and hippie-expand-verbose
+                     (not (window-minibuffer-p (selected-window))))
                (message "Undoing expansions"))))))
-      
+
 ;; Initializes the region to expand (to between BEG and END).
 (defun he-init-string (beg end)
-  (setq he-string-beg beg)
-  (setq he-string-end end)
+  (set-marker he-string-beg beg)
+  (set-marker he-string-end end)
   (setq he-search-string (buffer-substring beg end)))
 
 ;; Resets the expanded region to its original contents.
 (defun he-reset-string ()
-  (delete-region he-string-beg he-string-end)
-  (insert he-search-string)
-  (setq he-string-end (point)))
+  (let ((newpos (point-marker)))
+    (delete-region he-string-beg he-string-end)
+    (goto-char he-string-beg)
+    (insert he-search-string)
+    (set-marker he-string-end (point))
+    (if (= newpos he-string-beg)
+       (goto-char he-string-end)
+       (goto-char newpos))))
 
 ;; Substitutes an expansion STR into the correct region (the region
 ;; initialized with `he-init-string'). 
@@ -222,14 +267,18 @@ undoes the expansion."
   (let ((trans-case (and trans-case
                         case-replace
                         case-fold-search
-                        (he-transfer-case-ok str he-search-string))))
+                        (he-transfer-case-ok str he-search-string)))
+       (newpos (point-marker)))
     (he-reset-string)
     (goto-char he-string-beg)
     (search-forward he-search-string)
     (replace-match (if trans-case (downcase str) str)
                   (not trans-case)
                   'literal)
-    (setq he-string-end (point))))
+    (set-marker he-string-end (point))
+    (if (= newpos he-string-beg)
+       (goto-char he-string-end)
+       (goto-char newpos))))
 
 (defun he-ordinary-case-p (str)
   (or (string= str (downcase str))
@@ -237,7 +286,8 @@ undoes the expansion."
       (string= str (capitalize str))))
 
 (defun he-transfer-case-ok (to-str from-str)
-  (and (not (string= from-str (substring to-str 0 (length from-str))))
+  (and (not (string= from-str (substring to-str 0 (min (length from-str)
+                                                       (length to-str)))))
          ;; otherwise transfer is not needed (and this also solves
         ;; some obscure situations)
        (he-ordinary-case-p to-str)
@@ -257,6 +307,15 @@ undoes the expansion."
     (setq lst (cdr lst)))
   lst)
 
+;; Check if STR matches any regexp in LST.
+;; Ignore possible non-strings in LST.
+(defun he-regexp-member (str lst)
+  (while (and lst
+             (or (not (stringp (car lst)))
+                  (not (string-match (car lst) str))))
+    (setq lst (cdr lst)))
+  lst)
+
 ;;  For the real hippie-expand enthusiast: A macro that makes it
 ;;  possible to use many functions like hippie-expand, but with
 ;;  different try-functions-lists.
@@ -268,18 +327,19 @@ undoes the expansion."
 ;;                             '(try-expand-line
 ;;                               try-expand-line-all-buffers)))
 ;;  
+;;;###autoload
 (defmacro make-hippie-expand-function (try-list &optional verbose)
   "Construct a function similar to `hippie-expand'.
 Make it use the expansion functions in TRY-LIST.  An optional second
 argument VERBOSE non-nil makes the function verbose."
-  (` '(lambda (arg)
+  (` (function (lambda (arg)
        (, (concat 
            "Try to expand text before point, using the following functions: \n"
           (mapconcat 'prin1-to-string (eval try-list) ", ")))
        (interactive "P")
        (let ((hippie-expand-try-functions-list (, try-list))
             (hippie-expand-verbose (, verbose)))
-        (hippie-expand arg)))))
+        (hippie-expand arg))))))
 
 
 ;;;  Here follows the try-functions and their requisites:
@@ -310,7 +370,7 @@ string).  It returns t if a new completion is found, nil otherwise."
     (setq he-expand-list (cdr he-expand-list)))
   (if (null he-expand-list)
       (progn
-       (he-reset-string)
+        (if old (he-reset-string))
        ())
       (let ((filename (concat (file-name-directory he-search-string)
                              (car he-expand-list))))
@@ -341,7 +401,7 @@ otherwise."
 
     (if (not expansion)
        (progn
-         (he-reset-string)
+          (if old (he-reset-string))
          ())
        (let ((filename (concat (file-name-directory he-search-string)
                                expansion)))
@@ -378,7 +438,7 @@ string).  It returns t if a new completion is found, nil otherwise."
     (setq he-expand-list (cdr he-expand-list)))
   (if (null he-expand-list)
       (progn
-       (he-reset-string)
+        (if old (he-reset-string))
        ())
       (progn
        (he-substitute-string (car he-expand-list))
@@ -408,7 +468,7 @@ otherwise."
 
   (if (not expansion)
       (progn
-       (he-reset-string)
+        (if old (he-reset-string))
        ())
       (progn
        (he-substitute-string expansion)
@@ -428,11 +488,11 @@ for subsequent calls (for further possible completions of the same
 string).  It returns t if a new completion is found, nil otherwise."
   (let ((expansion ())
        (strip-prompt (and (get-buffer-process (current-buffer))
-                          shell-prompt-pattern)))
+                          comint-prompt-regexp)))
     (if (not old)
        (progn
          (he-init-string (he-line-beg strip-prompt) (point))
-         (setq he-search-loc he-string-beg)
+         (set-marker he-search-loc he-string-beg)
          (setq he-search-bw t)))
 
     (if (not (equal he-search-string ""))
@@ -443,10 +503,10 @@ string).  It returns t if a new completion is found, nil otherwise."
                (goto-char he-search-loc)
                (setq expansion (he-line-search he-search-string
                                                strip-prompt t))
-               (setq he-search-loc (point-marker))
+               (set-marker he-search-loc (point))
                (if (not expansion)
                    (progn
-                     (setq he-search-loc he-string-end)
+                     (set-marker he-search-loc he-string-end)
                      (setq he-search-bw ())))))
          
          (if (not expansion) ; Then look forward.
@@ -454,11 +514,11 @@ string).  It returns t if a new completion is found, nil otherwise."
                (goto-char he-search-loc)
                (setq expansion (he-line-search he-search-string 
                                                strip-prompt nil))
-               (setq he-search-loc (point-marker))))))
+               (set-marker he-search-loc (point))))))
 
     (if (not expansion)
        (progn
-         (he-reset-string)
+          (if old (he-reset-string))
          ())
        (progn
          (he-substitute-string expansion t)
@@ -472,35 +532,44 @@ for subsequent calls (for further possible completions of the same
 string).  It returns t if a new completion is found, nil otherwise."
   (let ((expansion ())
        (strip-prompt (and (get-buffer-process (current-buffer))
-                          shell-prompt-pattern))
+                          comint-prompt-regexp))
        (buf (current-buffer)))
     (if (not old)
        (progn
          (he-init-string (he-line-beg strip-prompt) (point))
-         (setq he-search-loc 0)
-         (setq he-search-bufs (buffer-list))))
+         (setq he-search-bufs (buffer-list))
+          (setq he-searched-n-bufs 0)
+         (set-marker he-search-loc 1 (car he-search-bufs))))
 
     (if (not (equal he-search-string ""))
-       (while (and he-search-bufs (not expansion))
+       (while (and he-search-bufs 
+                    (not expansion)
+                    (or (not hippie-expand-max-buffers)
+                        (< he-searched-n-bufs hippie-expand-max-buffers)))
          (set-buffer (car he-search-bufs))
          (if (and (not (eq (current-buffer) buf))
-                  (not (eq major-mode 'dired-mode)))
-                  ;; dont search dired buffers
+                  (not (memq major-mode hippie-expand-ignore-buffers))
+                   (not (he-regexp-member (buffer-name)
+                                          hippie-expand-ignore-buffers)))
              (save-excursion
                (goto-char he-search-loc)
+                (setq strip-prompt (and (get-buffer-process (current-buffer))
+                                        comint-prompt-regexp))
                (setq expansion (he-line-search he-search-string
                                                strip-prompt nil))
-               (setq he-search-loc (point-marker))))
-         (if expansion
-             (setq he-tried-table (cons expansion he-tried-table))
-             (progn
-               (setq he-search-loc 0)
-               (setq he-search-bufs (cdr he-search-bufs))))))
+               (set-marker he-search-loc (point))
+                (if expansion
+                    (setq he-tried-table (cons expansion he-tried-table))
+                  (setq he-search-bufs (cdr he-search-bufs))
+                  (setq he-searched-n-bufs (1+ he-searched-n-bufs))
+                  (set-marker he-search-loc 1 (car he-search-bufs))))
+            (setq he-search-bufs (cdr he-search-bufs))
+            (set-marker he-search-loc 1 (car he-search-bufs)))))
 
     (set-buffer buf)
     (if (not expansion)
        (progn
-         (he-reset-string)
+          (if old (he-reset-string))
          ())
        (progn
          (he-substitute-string expansion t)
@@ -533,13 +602,130 @@ string).  It returns t if a new completion is found, nil otherwise."
 
 (defun he-line-search-regexp (pat strip-prompt)
   (if strip-prompt
-      (concat "\\(" shell-prompt-pattern "\\|^\\s-*\\)\\("
+      (concat "\\(" comint-prompt-regexp "\\|^\\s-*\\)\\("
              (regexp-quote pat)
              "[^\n]*[^ \t\n]\\)")
       (concat "^\\(\\s-*\\)\\(" 
              (regexp-quote pat)
              "[^\n]*[^ \t\n]\\)")))
 
+(defun try-expand-list (old)
+  "Try to complete the current beginning of a list.
+The argument OLD has to be nil the first call of this function, and t
+for subsequent calls (for further possible completions of the same
+string).  It returns t if a new completion is found, nil otherwise."
+  (let ((expansion ()))
+    (if (not old)
+       (progn
+         (he-init-string (he-list-beg) (point))
+         (set-marker he-search-loc he-string-beg)
+         (setq he-search-bw t)))
+
+    (if (not (equal he-search-string ""))
+       (save-excursion
+         ;; Try looking backward unless inhibited.
+         (if he-search-bw
+             (progn 
+               (goto-char he-search-loc)
+               (setq expansion (he-list-search he-search-string t))
+               (set-marker he-search-loc (point))
+               (if (not expansion)
+                   (progn
+                     (set-marker he-search-loc he-string-end)
+                     (setq he-search-bw ())))))
+         
+         (if (not expansion) ; Then look forward.
+             (progn 
+               (goto-char he-search-loc)
+               (setq expansion (he-list-search he-search-string nil))
+               (set-marker he-search-loc (point))))))
+
+    (if (not expansion)
+       (progn
+         (if old (he-reset-string))
+         ())
+       (progn
+         (he-substitute-string expansion t)
+         (setq he-tried-table (cons expansion he-tried-table))
+         t))))
+
+(defun try-expand-list-all-buffers (old)
+  "Try to complete the current list, searching all other buffers.
+The argument OLD has to be nil the first call of this function, and t
+for subsequent calls (for further possible completions of the same
+string).  It returns t if a new completion is found, nil otherwise."
+  (let ((expansion ())
+       (buf (current-buffer)))
+    (if (not old)
+       (progn
+         (he-init-string (he-list-beg) (point))
+         (setq he-search-bufs (buffer-list))
+          (setq he-searched-n-bufs 0)
+         (set-marker he-search-loc 1 (car he-search-bufs))))
+
+    (if (not (equal he-search-string ""))
+       (while (and he-search-bufs 
+                    (not expansion)
+                    (or (not hippie-expand-max-buffers)
+                        (< he-searched-n-bufs hippie-expand-max-buffers)))
+         (set-buffer (car he-search-bufs))
+         (if (and (not (eq (current-buffer) buf))
+                  (not (memq major-mode hippie-expand-ignore-buffers))
+                   (not (he-regexp-member (buffer-name)
+                                          hippie-expand-ignore-buffers)))
+             (save-excursion
+               (goto-char he-search-loc)
+               (setq expansion (he-list-search he-search-string nil))
+               (set-marker he-search-loc (point))
+                (if expansion
+                    (setq he-tried-table (cons expansion he-tried-table))
+                  (setq he-search-bufs (cdr he-search-bufs))
+                  (setq he-searched-n-bufs (1+ he-searched-n-bufs))
+                  (set-marker he-search-loc 1 (car he-search-bufs))))
+            (setq he-search-bufs (cdr he-search-bufs))
+            (set-marker he-search-loc 1 (car he-search-bufs)))))
+
+    (set-buffer buf)
+    (if (not expansion)
+       (progn
+          (if old (he-reset-string))
+         ())
+       (progn
+         (he-substitute-string expansion t)
+         t))))
+
+(defun he-list-search (str reverse) 
+  (let ((result ())
+        beg pos err)
+    (while (and (not result)
+               (if reverse
+                   (search-backward str nil t)
+                   (search-forward str nil t)))
+      (setq pos (point))
+      (setq beg (match-beginning 0))
+      (goto-char beg)
+      (setq err ())
+      (condition-case ()
+          (forward-list 1)
+        (error (setq err t)))
+      (if (and reverse 
+               (> (point) he-string-beg))
+          (setq err t))
+      (if (not err)
+          (progn
+            (setq result (buffer-substring beg (point)))
+            (if (he-string-member result he-tried-table)
+                (setq result nil))))          ; if already in table, ignore
+      (goto-char pos))
+    result))
+
+(defun he-list-beg ()
+  (save-excursion
+    (condition-case ()
+        (backward-up-list 1)
+      (error ()))
+    (point)))
+
 (defun try-expand-all-abbrevs (old)
   "Try to expand word before point according to all abbrev tables.
 The argument OLD has to be nil the first call of this function, and t
@@ -551,7 +737,7 @@ string).  It returns t if a new expansion is found, nil otherwise."
        (setq he-expand-list 
              (and (not (equal he-search-string ""))
                   (mapcar (function (lambda (sym)
-                            (abbrev-expansion he-search-string 
+                            (abbrev-expansion (downcase he-search-string)
                                               (eval sym))))
                           (append '(local-abbrev-table 
                                     global-abbrev-table)
@@ -562,10 +748,10 @@ string).  It returns t if a new expansion is found, nil otherwise."
     (setq he-expand-list (cdr he-expand-list)))
   (if (null he-expand-list)
       (progn
-       (he-reset-string)
+        (if old (he-reset-string))
        ())
       (progn
-       (he-substitute-string (car he-expand-list))
+       (he-substitute-string (car he-expand-list) t)
        (setq he-tried-table (cons (car he-expand-list) he-tried-table))
        (setq he-expand-list (cdr he-expand-list))
        t)))
@@ -579,7 +765,7 @@ string).  It returns t if a new expansion is found, nil otherwise."
     (if (not old)
        (progn
          (he-init-string (he-dabbrev-beg) (point))
-         (setq he-search-loc he-string-beg)
+         (set-marker he-search-loc he-string-beg)
          (setq he-search-bw t)))
 
     (if (not (equal he-search-string ""))
@@ -589,21 +775,21 @@ string).  It returns t if a new expansion is found, nil otherwise."
              (progn 
                (goto-char he-search-loc)
                (setq expansion (he-dab-search he-search-string t))
-               (setq he-search-loc (point-marker))
+               (set-marker he-search-loc (point))
                (if (not expansion)
                    (progn
-                     (setq he-search-loc he-string-end)
+                     (set-marker he-search-loc he-string-end)
                      (setq he-search-bw ())))))
          
          (if (not expansion) ; Then look forward.
              (progn 
                (goto-char he-search-loc)
                (setq expansion (he-dab-search he-search-string nil))
-               (setq he-search-loc (point-marker))))))
+               (set-marker he-search-loc (point))))))
        
     (if (not expansion)
        (progn
-         (he-reset-string)
+          (if old (he-reset-string))
          ())
        (progn
          (he-substitute-string expansion t)
@@ -620,36 +806,43 @@ string).  It returns t if a new expansion is found, nil otherwise."
     (if (not old)
        (progn
          (he-init-string (he-dabbrev-beg) (point))
-         (setq he-search-loc 0)
-         (setq he-search-bufs (buffer-list))))
+         (setq he-search-bufs (buffer-list))
+          (setq he-searched-n-bufs 0)
+         (set-marker he-search-loc 1 (car he-search-bufs))))
 
     (if (not (equal he-search-string ""))
-       (while (and he-search-bufs (not expansion))
+       (while (and he-search-bufs 
+                    (not expansion)
+                    (or (not hippie-expand-max-buffers)
+                        (< he-searched-n-bufs hippie-expand-max-buffers)))
          (set-buffer (car he-search-bufs))
          (if (and (not (eq (current-buffer) buf))
-                  (not (eq major-mode 'dired-mode))) 
-                  ;; dont search dired buffers
+                  (not (memq major-mode hippie-expand-ignore-buffers))
+                   (not (he-regexp-member (buffer-name)
+                                          hippie-expand-ignore-buffers)))
              (save-excursion
                (goto-char he-search-loc)
                (setq expansion (he-dab-search he-search-string nil))
-               (setq he-search-loc (point-marker))))
-         (if expansion
-             (setq he-tried-table (cons expansion he-tried-table))
-             (progn
-               (setq he-search-loc 0)
-               (setq he-search-bufs (cdr he-search-bufs))))))
+               (set-marker he-search-loc (point))
+                (if expansion
+                    (setq he-tried-table (cons expansion he-tried-table))
+                  (setq he-search-bufs (cdr he-search-bufs))
+                  (setq he-searched-n-bufs (1+ he-searched-n-bufs))
+                  (set-marker he-search-loc 1 (car he-search-bufs))))
+            (setq he-search-bufs (cdr he-search-bufs))
+            (set-marker he-search-loc 1 (car he-search-bufs)))))
 
     (set-buffer buf)
     (if (not expansion)
        (progn
-         (he-reset-string)
+          (if old (he-reset-string))
          ())
        (progn
          (he-substitute-string expansion t)
          t))))
 
 (defun he-dab-search-regexp (pat)
-  (concat "\\b" (regexp-quote pat) 
+  (concat "\\<" (regexp-quote pat) 
          "\\(\\sw\\|\\s_\\)+"))
 
 (defun he-dab-search (pattern reverse)
@@ -666,9 +859,12 @@ string).  It returns t if a new expansion is found, nil otherwise."
     result))
 
 (defun he-dabbrev-beg ()
-  (let ((skips "-a-zA-Z0-9_."))
-    (save-excursion
-      (skip-chars-backward skips)
-      (skip-chars-forward "-_.")
-      (point))))
+  (min (point)
+       (save-excursion
+         (skip-syntax-backward "w_")
+         (skip-syntax-forward "_")
+         (point))))
+
+(provide 'hippie-exp)
 
+;;; hippie-exp.el ends here