+ (set-buffer other-buffer)
+ major-mode)))
+
+;;; Back over all abbrev type characters and then moves forward over
+;;; all skip characters.
+(defun dabbrev--goto-start-of-abbrev ()
+ ;; Move backwards over abbrev chars
+ (save-match-data
+ (if (not (bobp))
+ (progn
+ (forward-char -1)
+ (while (and (looking-at dabbrev--abbrev-char-regexp)
+ (not (bobp)))
+ (forward-char -1))
+ (or (looking-at dabbrev--abbrev-char-regexp)
+ (forward-char 1))))
+ (and dabbrev-abbrev-skip-leading-regexp
+ (while (looking-at dabbrev-abbrev-skip-leading-regexp)
+ (forward-char 1)))))
+
+;;; Extract the symbol at point to serve as abbreviation.
+(defun dabbrev--abbrev-at-point ()
+ ;; Check for error
+ (if (bobp)
+ (error "No possible abbreviation preceding point"))
+ ;; Return abbrev at point
+ (save-excursion
+ ;; Record the end of the abbreviation.
+ (setq dabbrev--last-abbrev-location (point))
+ ;; If we aren't right after an abbreviation,
+ ;; move point back to just after one.
+ ;; This is so the user can get successive words
+ ;; by typing the punctuation followed by M-/.
+ (save-match-data
+ (if (save-excursion
+ (forward-char -1)
+ (not (looking-at (concat "\\("
+ (or dabbrev-abbrev-char-regexp
+ "\\sw\\|\\s_")
+ "\\)+"))))
+ (if (re-search-backward (or dabbrev-abbrev-char-regexp
+ "\\sw\\|\\s_")
+ nil t)
+ (forward-char 1)
+ (error "No possible abbreviation preceding point"))))
+ ;; Now find the beginning of that one.
+ (dabbrev--goto-start-of-abbrev)
+ (buffer-substring-no-properties
+ dabbrev--last-abbrev-location (point))))
+
+;;; Initializes all global variables
+(defun dabbrev--reset-global-variables ()
+ ;; dabbrev--last-obarray and dabbrev--last-completion-buffer
+ ;; must not be reset here.
+ (setq dabbrev--last-table nil
+ dabbrev--last-abbreviation nil
+ dabbrev--last-abbrev-location nil
+ dabbrev--last-direction nil
+ dabbrev--last-expansion nil
+ dabbrev--last-expansion-location nil
+ dabbrev--friend-buffer-list nil
+ dabbrev--last-buffer nil
+ dabbrev--last-buffer-found nil
+ dabbrev--abbrev-char-regexp (or dabbrev-abbrev-char-regexp
+ "\\sw\\|\\s_")
+ dabbrev--check-other-buffers dabbrev-check-other-buffers))
+
+;;; Find all buffers that are considered "friends" according to the
+;;; function pointed out by dabbrev-friend-buffer-function.
+(defun dabbrev--select-buffers ()
+ (save-excursion
+ (and (window-minibuffer-p (selected-window))
+ (set-buffer (dabbrev--minibuffer-origin)))
+ (let ((orig-buffer (current-buffer)))
+ (dabbrev-filter-elements
+ buffer (buffer-list)
+ (and (not (eq orig-buffer buffer))
+ (boundp 'dabbrev-friend-buffer-function)
+ (funcall dabbrev-friend-buffer-function buffer))))))
+
+;;; Search for ABBREV, N times, normally looking forward,
+;;; but looking in reverse instead if REVERSE is non-nil.
+(defun dabbrev--try-find (abbrev reverse n ignore-case)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (let ((expansion nil))
+ (and dabbrev--last-expansion-location
+ (goto-char dabbrev--last-expansion-location))
+ (let ((case-fold-search ignore-case)
+ (count n))
+ (while (and (> count 0)
+ (setq expansion (dabbrev--search abbrev
+ reverse
+ ignore-case)))
+ (setq count (1- count))))
+ (and expansion
+ (setq dabbrev--last-expansion-location (point)))
+ expansion))))
+
+;;; Find all expansions of ABBREV
+(defun dabbrev--find-all-expansions (abbrev ignore-case)
+ (let ((all-expansions nil)
+ expansion)
+ (save-excursion
+ (goto-char (point-min))
+ (while (setq expansion (dabbrev--find-expansion abbrev -1 ignore-case))
+ (setq all-expansions (cons expansion all-expansions))))
+ all-expansions))
+
+(defun dabbrev--scanning-message ()
+ (message "Scanning `%s'" (buffer-name (current-buffer))))
+
+;;; Find one occasion of ABBREV.
+;;; DIRECTION > 0 means look that many times backwards.
+;;; DIRECTION < 0 means look that many times forward.
+;;; DIRECTION = 0 means try both backward and forward.
+;;; IGNORE-CASE non-nil means ignore case when searching.
+(defun dabbrev--find-expansion (abbrev direction ignore-case)
+ (let (expansion)
+ (save-excursion
+ (cond
+ (dabbrev--last-buffer
+ (set-buffer dabbrev--last-buffer)
+ (dabbrev--scanning-message))
+ ((and (not dabbrev-search-these-buffers-only)
+ (window-minibuffer-p (selected-window)))
+ (set-buffer (dabbrev--minibuffer-origin))
+ ;; In the minibuffer-origin buffer we will only search from
+ ;; the top and down.
+ (goto-char (point-min))
+ (setq direction -1)
+ (dabbrev--scanning-message)))
+ (cond
+ ;; ------------------------------------------
+ ;; Look backwards
+ ;; ------------------------------------------
+ ((and (not dabbrev-search-these-buffers-only)
+ (>= direction 0)
+ (setq dabbrev--last-direction (min 1 direction))
+ (setq expansion (dabbrev--try-find abbrev t
+ (max 1 direction)
+ ignore-case)))
+ expansion)
+ ;; ------------------------------------------
+ ;; Look forward
+ ;; ------------------------------------------
+ ((and (or (not dabbrev-search-these-buffers-only)
+ dabbrev--last-buffer)
+ (<= direction 0)
+ (setq dabbrev--last-direction -1)
+ (setq expansion (dabbrev--try-find abbrev nil
+ (max 1 (- direction))
+ ignore-case)))
+ expansion)
+ ;; ------------------------------------------
+ ;; Look in other buffers.
+ ;; Start at (point-min) and look forward.
+ ;; ------------------------------------------
+ (t
+ (setq dabbrev--last-direction -1)
+ ;; Make sure that we should check other buffers
+ (or dabbrev--friend-buffer-list
+ dabbrev--last-buffer
+ (setq dabbrev--friend-buffer-list
+ (mapcar (function get-buffer)
+ dabbrev-search-these-buffers-only))
+ (not dabbrev--check-other-buffers)
+ (not (or (eq dabbrev--check-other-buffers t)
+ (progn
+ (setq dabbrev--check-other-buffers
+ (y-or-n-p "Scan other buffers also? ")))))
+ (let* (friend-buffer-list non-friend-buffer-list)
+ (setq dabbrev--friend-buffer-list
+ (funcall dabbrev-select-buffers-function))
+ (if dabbrev-check-all-buffers
+ (setq non-friend-buffer-list
+ (nreverse
+ (dabbrev-filter-elements
+ buffer (buffer-list)
+ (let ((bn (buffer-name buffer)))
+ (and (not (member bn dabbrev-ignored-buffer-names))
+ (not (memq buffer dabbrev--friend-buffer-list))
+ (not
+ (let ((tail dabbrev-ignored-regexps)
+ (match nil))
+ (while (and tail (not match))
+ (setq match (string-match (car tail) bn)
+ tail (cdr tail)))
+ match))))))
+ dabbrev--friend-buffer-list
+ (append dabbrev--friend-buffer-list
+ non-friend-buffer-list)))))
+ ;; Move buffers that are visible on the screen
+ ;; to the front of the list. Remove the current buffer.
+ (when dabbrev--friend-buffer-list
+ (let ((w (next-window (selected-window))))
+ (while (not (eq w (selected-window)))
+ (setq dabbrev--friend-buffer-list
+ (cons (window-buffer w)
+ (delq (window-buffer w) dabbrev--friend-buffer-list)))
+ (setq w (next-window w))))
+ (setq dabbrev--friend-buffer-list
+ (delq (current-buffer) dabbrev--friend-buffer-list)))
+ ;; Walk through the buffers
+ (while (and (not expansion) dabbrev--friend-buffer-list)
+ (setq dabbrev--last-buffer
+ (car dabbrev--friend-buffer-list))
+ (setq dabbrev--friend-buffer-list
+ (cdr dabbrev--friend-buffer-list))
+ (set-buffer dabbrev--last-buffer)
+ (dabbrev--scanning-message)
+ (setq dabbrev--last-expansion-location (point-min))
+ (setq expansion (dabbrev--try-find abbrev nil 1 ignore-case)))
+ expansion)))))
+
+(defun dabbrev--safe-replace-match (string &optional fixedcase literal)
+ (if (eq major-mode 'picture-mode)
+ (picture-replace-match string fixedcase literal)
+ (replace-match string fixedcase literal)))
+
+;;;----------------------------------------------------------------
+;;; Substitute the current string in buffer with the expansion
+;;; OLD is nil or the last expansion substring.
+;;; ABBREV is the abbreviation we are working with.
+;;; EXPANSION is the expansion substring.
+(defun dabbrev--substitute-expansion (old abbrev expansion)
+ ;;(undo-boundary)
+ (let ((use-case-replace (and (if (eq dabbrev-case-fold-search 'case-fold-search)
+ case-fold-search
+ dabbrev-case-fold-search)
+ (or (not dabbrev-upcase-means-case-search)
+ (string= abbrev (downcase abbrev)))
+ (if (eq dabbrev-case-replace 'case-replace)
+ case-replace
+ dabbrev-case-replace))))
+ (and nil use-case-replace
+ (setq old (concat abbrev (or old "")))
+ (setq expansion (concat abbrev expansion)))
+ ;; If the expansion has mixed case
+ ;; and it is not simply a capitalized word,
+ ;; or if the abbrev has mixed case,
+ ;; and if the given abbrev's case pattern
+ ;; matches the start of the expansion,
+ ;; copy the expansion's case
+ ;; instead of downcasing all the rest.
+ (let ((expansion-rest (substring expansion 1)))
+ (if (and (not (and (or (string= expansion-rest (downcase expansion-rest))
+ (string= expansion-rest (upcase expansion-rest)))
+ (or (string= abbrev (downcase abbrev))
+ (string= abbrev (upcase abbrev)))))
+ (string= abbrev
+ (substring expansion 0 (length abbrev))))
+ (setq use-case-replace nil)))
+ (if (equal abbrev " ")
+ (setq use-case-replace nil))
+ (if use-case-replace
+ (setq expansion (downcase expansion)))
+ (if old