Function: comint-replace-by-expanded-history-before-point

comint-replace-by-expanded-history-before-point is a byte-compiled function defined in comint.el.gz.

Signature

(comint-replace-by-expanded-history-before-point SILENT &optional START DRY-RUN)

Documentation

Expand directory stack reference before point.

See comint-replace-by-expanded-history. Returns t if successful.

If the optional argument START is non-nil, that specifies the start of the text to scan for history references, rather than the logical beginning of line.

If DRY-RUN is non-nil, throw to DRY-RUN before performing any actual side-effect.

Source Code

;; Defined in /usr/src/emacs/lisp/comint.el.gz
(defun comint-replace-by-expanded-history-before-point
  (silent &optional start dry-run)
  "Expand directory stack reference before point.
See `comint-replace-by-expanded-history'.  Returns t if successful.

If the optional argument START is non-nil, that specifies the
start of the text to scan for history references, rather
than the logical beginning of line.

If DRY-RUN is non-nil, throw to DRY-RUN before performing any
actual side-effect."
  (save-excursion
    (let ((toend (- (line-end-position) (point)))
	  (start (or start (comint-line-beginning-position))))
      (goto-char start)
      (while (progn
	       (skip-chars-forward "^!^" (- (line-end-position) toend))
	       (< (point) (- (line-end-position) toend)))
	;; This seems a bit complex.  We look for references such as !!, !-num,
	;; !foo, !?foo, !{bar}, !?{bar}, ^oh, ^my^, ^god^it, ^never^ends^.
	;; If that wasn't enough, the plings can be suffixed with argument
	;; range specifiers.
	;; Argument ranges are complex too, so we hive off the input line,
	;; referenced with plings, with the range string to `comint-args'.
	(setq comint-input-ring-index nil)
	(cond ((or (= (preceding-char) ?\\)
		   (comint-within-quotes start (point)))
	       ;; The history is quoted, or we're in quotes.
	       (goto-char (1+ (point))))
	      ((looking-at "![0-9]+\\($\\|[^-]\\)")
	       ;; We cannot know the interpreter's idea of input line numbers.
               (if dry-run (throw dry-run 'message))
	       (goto-char (match-end 0))
	       (message "Absolute reference cannot be expanded"))
	      ((looking-at "!-\\([0-9]+\\)\\(:?[0-9^$*-]+\\)?")
	       ;; Just a number of args from `number' lines backward.
               (if dry-run (throw dry-run 'history))
	       (let ((number (1- (string-to-number
				  (buffer-substring (match-beginning 1)
						    (match-end 1))))))
		 (if (<= number (ring-length comint-input-ring))
		     (progn
		       (replace-match
			(comint-args (comint-previous-input-string number)
				     (match-beginning 2) (match-end 2))
			t t)
		       (setq comint-input-ring-index number)
		       (message "History item: %d" (1+ number)))
		   (goto-char (match-end 0))
		   (message "Relative reference exceeds input history size"))))
	      ((or (looking-at "!!?:?\\([0-9^$*-]+\\)") (looking-at "!!"))
	       ;; Just a number of args from the previous input line.
               (if dry-run (throw dry-run 'expand))
	       (replace-match (comint-args (comint-previous-input-string 0)
					   (match-beginning 1) (match-end 1))
			      t t)
	       (message "History item: previous"))
	      ((looking-at
		"!\\??\\({\\(.+\\)}\\|\\(\\sw+\\)\\)\\(:?[0-9^$*-]+\\)?")
	       ;; Most recent input starting with or containing (possibly
	       ;; protected) string, maybe just a number of args.  Phew.
               (if dry-run (throw dry-run 'expand))
	       (let* ((mb1 (match-beginning 1)) (me1 (match-end 1))
		      (mb2 (match-beginning 2)) (me2 (match-end 2))
		      (exp (buffer-substring (or mb2 mb1) (or me2 me1)))
		      (pref (if (save-match-data (looking-at "!\\?")) "" "^"))
		      (pos (save-match-data
			     (comint-previous-matching-input-string-position
			      (concat pref (regexp-quote exp)) 1))))
		 (if (null pos)
		     (progn
		       (goto-char (match-end 0))
		       (or silent
			   (progn (message "Not found")
				  (ding))))
		   (setq comint-input-ring-index pos)
		   (replace-match
		    (comint-args (ring-ref comint-input-ring pos)
				 (match-beginning 4) (match-end 4))
		    t t)
		   (message "History item: %d" (1+ pos)))))
	      ((looking-at "\\^\\([^^]+\\)\\^?\\([^^]*\\)\\^?")
	       ;; Quick substitution on the previous input line.
               (if dry-run (throw dry-run 'expand))
	       (let ((old (buffer-substring (match-beginning 1) (match-end 1)))
		     (new (buffer-substring (match-beginning 2) (match-end 2)))
		     (pos nil))
		 (replace-match (comint-previous-input-string 0) t t)
		 (setq pos (point))
		 (goto-char (match-beginning 0))
		 (if (not (search-forward old pos t))
		     (or silent
			 (user-error "Not found"))
		   (replace-match new t t)
		   (message "History item: substituted"))))
	      (t
	       (forward-char 1)))))
    nil))