Function: dabbrev--substitute-expansion

dabbrev--substitute-expansion is a byte-compiled function defined in dabbrev.el.gz.

Signature

(dabbrev--substitute-expansion OLD ABBREV EXPANSION RECORD-CASE-PATTERN)

Documentation

Replace OLD with EXPANSION in the buffer.

OLD is text currently in the buffer, perhaps the abbreviation or perhaps another expansion that was tried previously. ABBREV is the abbreviation we are expanding. It is " " if we are copying subsequent words. EXPANSION is the expansion substring to be used this time. RECORD-CASE-PATTERN, if non-nil, means set dabbrev--last-case-pattern to record whether we upcased the expansion, downcased it, or did neither.

Source Code

;; Defined in /usr/src/emacs/lisp/dabbrev.el.gz
;;;----------------------------------------------------------------
(defun dabbrev--substitute-expansion (old abbrev expansion record-case-pattern)
  "Replace OLD with EXPANSION in the buffer.
OLD is text currently in the buffer, perhaps the abbreviation
or perhaps another expansion that was tried previously.
ABBREV is the abbreviation we are expanding.
It is \" \" if we are copying subsequent words.
EXPANSION is the expansion substring to be used this time.
RECORD-CASE-PATTERN, if non-nil, means set `dabbrev--last-case-pattern'
to record whether we upcased the expansion, downcased it, or did neither."
  ;;(undo-boundary)
  (let ((use-case-replace
         (and (dabbrev--ignore-case-p abbrev)
              (if (eq dabbrev-case-replace 'case-replace)
                  case-replace
                dabbrev-case-replace))))

    ;; If we upcased or downcased the original expansion,
    ;; do likewise for the subsequent words when we copy them.
    ;; Don't do any of the usual case processing, though.
    (when (equal abbrev " ")
      (if dabbrev--last-case-pattern
	  (setq expansion
		(funcall dabbrev--last-case-pattern expansion)))
      (setq use-case-replace nil))

    ;; 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.
    ;;
    ;; Treat a one-capital-letter (possibly with preceding non-letter
    ;; characters) abbrev as "not all upper case", so as to force
    ;; preservation of the expansion's pattern if the expansion starts
    ;; with a capital letter.
    (let ((expansion-rest (substring expansion 1))
	  (first-letter-position (string-match "[[:alpha:]]" abbrev)))
      (if (or (null first-letter-position)
	      (and (not
                    (and (or (string= expansion-rest (downcase expansion-rest))
                             (string= expansion-rest (upcase expansion-rest)))
                         (or (string= abbrev (downcase abbrev))
                             (and (string= abbrev (upcase abbrev))
                                  (> (- (length abbrev) first-letter-position)
                                     1)))))
		   (string= abbrev
			    (substring expansion 0 (length abbrev)))))
	  (setq use-case-replace nil)))

    ;; If the abbrev and the expansion are both all-lower-case
    ;; then don't do any conversion.  The conversion would be a no-op
    ;; for this replacement, but it would carry forward to subsequent words.
    ;; The goal of this is to prevent that carrying forward.
    (if (and (string= expansion (downcase expansion))
	     (string= abbrev (downcase abbrev)))
	(setq use-case-replace nil))

    (if use-case-replace
	(setq expansion (downcase expansion)))

    ;; In case we insert subsequent words,
    ;; record if we upcased or downcased the first word,
    ;; in order to do likewise for subsequent words.
    (and record-case-pattern
	 (setq dabbrev--last-case-pattern
	       (and use-case-replace
		    (cond ((equal abbrev (upcase abbrev)) 'upcase)
			  ((equal abbrev (downcase abbrev)) 'downcase)))))

    ;; Convert whitespace to single spaces.
    (if dabbrev-eliminate-newlines
	(let ((pos
	       (if (equal abbrev " ") 0 (length abbrev))))
	  ;; If ABBREV is real, search after the end of it.
	  ;; If ABBREV is space and we are copying successive words,
	  ;; search starting at the front.
	  (while (string-match "[\n \t]+" expansion pos)
	    (setq pos (1+ (match-beginning 0)))
	    (setq expansion (replace-match " " nil nil expansion)))))

    (if old
	(save-excursion
	  (search-backward old))
      ;;(set-match-data (list (point-marker) (point-marker)))
      (search-backward abbrev)
      (search-forward abbrev))

    ;; Make case of replacement conform to case of abbreviation
    ;; provided (1) that kind of thing is enabled in this buffer
    ;; and (2) the replacement itself is all lower case.
    (dabbrev--safe-replace-match expansion
				 (not use-case-replace)
				 t))
  ;; Return the expansion actually used.
  expansion)