- (shell-dynamic-complete-as-environment-variable)))))
-
-
-(defun shell-dynamic-complete-as-environment-variable ()
- "Dynamically complete at point as an environment variable.
-Used by `shell-dynamic-complete-environment-variable'.
-Uses `comint-dynamic-simple-complete'."
- (let* ((var (or (shell-match-partial-variable) ""))
- (variable (substring var (or (string-match "[^$({]\\|$" var) 0)))
- (variables (mapcar (function (lambda (x)
- (substring x 0 (string-match "=" x))))
- process-environment))
- (addsuffix comint-completion-addsuffix)
- (comint-completion-addsuffix nil)
- (success (comint-dynamic-simple-complete variable variables)))
- (if (memq success '(sole shortest))
- (let* ((var (shell-match-partial-variable))
- (variable (substring var (string-match "[^$({]" var)))
- (protection (cond ((string-match "{" var) "}")
- ((string-match "(" var) ")")
- (t "")))
- (suffix (cond ((null addsuffix) "")
- ((file-directory-p
- (comint-directory (getenv variable))) "/")
- (t " "))))
- (insert protection suffix)))
- success))
-
+ (apply #'completion-in-region data)))))
+
+
+(defun shell-environment-variable-completion ()
+ "Completion data for an environment variable at point, if any."
+ (let* ((var (shell-match-partial-variable))
+ (end (match-end 0)))
+ (when (and (not (zerop (length var))) (eq (aref var 0) ?$))
+ (let* ((start
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (looking-at "\\$?[({]*")
+ (match-end 0)))
+ (variables (mapcar (lambda (x)
+ (substring x 0 (string-match "=" x)))
+ process-environment))
+ (suffix (case (char-before start) (?\{ "}") (?\( ")") (t ""))))
+ (list start end variables
+ :exit-function
+ (lambda (s finished)
+ (when (memq finished '(sole finished))
+ (let ((suf (concat suffix
+ (if (file-directory-p
+ (comint-directory (getenv s)))
+ "/"))))
+ (if (looking-at (regexp-quote suf))
+ (goto-char (match-end 0))
+ (insert suf))))))))))
+
+
+(defun shell-c-a-p-replace-by-expanded-directory ()
+ "Expand directory stack reference before point.
+For use on `completion-at-point-functions'."
+ (when (comint-match-partial-filename)
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (let ((stack (cons default-directory shell-dirstack))
+ (index (cond ((looking-at "=-/?")
+ (length shell-dirstack))
+ ((looking-at "=\\([0-9]+\\)/?")
+ (string-to-number
+ (buffer-substring
+ (match-beginning 1) (match-end 1)))))))
+ (when index
+ (let ((start (match-beginning 0))
+ (end (match-end 0))
+ (replacement (file-name-as-directory (nth index stack))))
+ (lambda ()
+ (cond
+ ((>= index (length stack))
+ (error "Directory stack not that deep"))
+ (t
+ (save-excursion
+ (goto-char start)
+ (insert replacement)
+ (delete-char (- end start)))
+ (message "Directory item: %d" index)
+ t)))))))))