133 lines
5.4 KiB
EmacsLisp
133 lines
5.4 KiB
EmacsLisp
(defun dabbrev-expand (arg)
|
|
"Expand previous word \"dynamically\".
|
|
|
|
Expands to the most recent, preceding word for which this is a prefix.
|
|
If no suitable preceding word is found, words following point are
|
|
considered. If still no suitable word is found, then look in the
|
|
buffers accepted by the function pointed out by variable
|
|
`dabbrev-friend-buffer-function', if `dabbrev-check-other-buffers'
|
|
says so. Then, if `dabbrev-check-all-buffers' is non-nil, look in
|
|
all the other buffers, subject to constraints specified
|
|
by `dabbrev-ignored-buffer-names' and `dabbrev-ignored-buffer-regexps'.
|
|
|
|
A positive prefix argument, N, says to take the Nth backward *distinct*
|
|
possibility. A negative argument says search forward.
|
|
|
|
If the cursor has not moved from the end of the previous expansion and
|
|
no argument is given, replace the previously-made expansion
|
|
with the next possible expansion not yet tried.
|
|
|
|
The variable `dabbrev-backward-only' may be used to limit the
|
|
direction of search to backward if set non-nil.
|
|
|
|
See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
|
|
(interactive "*P")
|
|
(let (abbrev record-case-pattern
|
|
expansion old direction (orig-point (point)))
|
|
;; abbrev -- the abbrev to expand
|
|
;; expansion -- the expansion found (eventually) or nil until then
|
|
;; old -- the text currently in the buffer
|
|
;; (the abbrev, or the previously-made expansion)
|
|
(save-excursion
|
|
(if (and (null arg)
|
|
(markerp dabbrev--last-abbrev-location)
|
|
(marker-position dabbrev--last-abbrev-location)
|
|
(or (eq last-command this-command)
|
|
(and (window-minibuffer-p)
|
|
(= dabbrev--last-abbrev-location
|
|
(point)))))
|
|
;; Find a different expansion for the same abbrev as last time.
|
|
(progn
|
|
(setq abbrev dabbrev--last-abbreviation)
|
|
(setq old dabbrev--last-expansion)
|
|
(setq direction dabbrev--last-direction))
|
|
;; If the user inserts a space after expanding
|
|
;; and then asks to expand again, always fetch the next word.
|
|
(if (and (eq (preceding-char) ?\s)
|
|
(markerp dabbrev--last-abbrev-location)
|
|
(marker-position dabbrev--last-abbrev-location)
|
|
(= (point) (1+ dabbrev--last-abbrev-location)))
|
|
(progn
|
|
;; The "abbrev" to expand is just the space.
|
|
(setq abbrev " ")
|
|
(save-excursion
|
|
(save-restriction
|
|
(widen)
|
|
(if (buffer-live-p dabbrev--last-buffer)
|
|
(set-buffer dabbrev--last-buffer))
|
|
;; Find the end of the last "expansion" word.
|
|
(if (or (eq dabbrev--last-direction 1)
|
|
(and (eq dabbrev--last-direction 0)
|
|
(< dabbrev--last-expansion-location (point))))
|
|
(setq dabbrev--last-expansion-location
|
|
(+ dabbrev--last-expansion-location
|
|
(length dabbrev--last-expansion))))
|
|
(goto-char dabbrev--last-expansion-location)
|
|
;; Take the following word, with intermediate separators,
|
|
;; as our expansion this time.
|
|
(re-search-forward
|
|
(concat "\\(?:" dabbrev--abbrev-char-regexp "\\)+"))
|
|
(setq expansion (buffer-substring-no-properties
|
|
dabbrev--last-expansion-location (point)))
|
|
|
|
;; Record the end of this expansion, in case we repeat this.
|
|
(setq dabbrev--last-expansion-location (point))))
|
|
;; Indicate that dabbrev--last-expansion-location is
|
|
;; at the end of the expansion.
|
|
(setq dabbrev--last-direction -1))
|
|
|
|
;; We have a different abbrev to expand.
|
|
(dabbrev--reset-global-variables)
|
|
(setq direction (if (null arg)
|
|
(if dabbrev-backward-only 1 0)
|
|
(prefix-numeric-value arg)))
|
|
(setq abbrev (dabbrev--abbrev-at-point))
|
|
(setq record-case-pattern t)
|
|
(setq old nil)))
|
|
|
|
;;--------------------------------
|
|
;; Find the expansion
|
|
;;--------------------------------
|
|
(or expansion
|
|
(setq expansion
|
|
(dabbrev--find-expansion
|
|
abbrev direction
|
|
(dabbrev--ignore-case-p abbrev)))))
|
|
(cond
|
|
((not expansion)
|
|
(dabbrev--reset-global-variables)
|
|
(if old
|
|
(save-excursion
|
|
(setq buffer-undo-list (cons orig-point buffer-undo-list))
|
|
;; Put back the original abbrev with its original case pattern.
|
|
(search-backward old)
|
|
(insert abbrev)
|
|
(delete-region (point) (+ (point) (length old)))))
|
|
(user-error "No%s dynamic expansion for `%s' found"
|
|
(if old " further" "") abbrev))
|
|
(t
|
|
(if (not (or (eq dabbrev--last-buffer dabbrev--last-buffer-found)
|
|
(minibuffer-window-active-p (selected-window))))
|
|
(progn
|
|
(when (buffer-name dabbrev--last-buffer)
|
|
(message "Expansion found in `%s'"
|
|
(buffer-name dabbrev--last-buffer)))
|
|
(setq dabbrev--last-buffer-found dabbrev--last-buffer))
|
|
(message nil))
|
|
(if (and (or (eq (current-buffer) dabbrev--last-buffer)
|
|
(null dabbrev--last-buffer)
|
|
(buffer-live-p dabbrev--last-buffer))
|
|
(numberp dabbrev--last-expansion-location)
|
|
(and (> dabbrev--last-expansion-location (point))))
|
|
(setq dabbrev--last-expansion-location
|
|
(copy-marker dabbrev--last-expansion-location)))
|
|
;; Success: stick it in and return.
|
|
(setq buffer-undo-list (cons orig-point buffer-undo-list))
|
|
(setq expansion (dabbrev--substitute-expansion old abbrev expansion
|
|
record-case-pattern))
|
|
|
|
;; Save state for re-expand.
|
|
(setq dabbrev--last-expansion expansion)
|
|
(setq dabbrev--last-abbreviation abbrev)
|
|
(setq dabbrev--last-abbrev-location (point-marker))))))
|