summaryrefslogtreecommitdiff
path: root/lisp/shell.el
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2012-05-15 12:58:35 -0400
committerStefan Monnier <monnier@iro.umontreal.ca>2012-05-15 12:58:35 -0400
commit2473256d7b660edc5c1525163b2e9917d6ebf18d (patch)
treebb21474889ee68bee3259e7711f40320fbbcb369 /lisp/shell.el
parentfdb058c22800a2cce782c74ee3e3918b432b271c (diff)
downloademacs-2473256d7b660edc5c1525163b2e9917d6ebf18d.tar.gz
Only handle ".." and '..' quoting in shell-mode.
* lisp/shell.el (shell--unquote&requote-argument, shell--unquote-argument) (shell--requote-argument): New functions. (shell-completion-vars): Use them. (shell--parse-pcomplete-arguments): Rename from shell-parse-pcomplete-arguments. * lisp/comint.el (comint-word): Obey comint-file-name-quote-list. Simplify. (comint--unquote&requote-argument): Don't handle ".." and '..' quoting. Obey comint-file-name-quote-list. Fixes: debbugs:11466
Diffstat (limited to 'lisp/shell.el')
-rw-r--r--lisp/shell.el61
1 files changed, 55 insertions, 6 deletions
diff --git a/lisp/shell.el b/lisp/shell.el
index 1784188f6ad..ca238a443f3 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -372,8 +372,57 @@ Thus, this does not include the shell's current directory.")
;;; Basic Procedures
-(defun shell-parse-pcomplete-arguments ()
+(defun shell--unquote&requote-argument (qstr &optional upos)
+ (unless upos (setq upos 0))
+ (let* ((qpos 0)
+ (dquotes nil)
+ (ustrs '())
+ (re (concat
+ "[\"']"
+ "\\|\\$\\(?:\\([[:alpha:]][[:alnum:]]*\\)"
+ "\\|{\\(?1:[^{}]+\\)}\\)"
+ (when (memq system-type '(ms-dos windows-nt))
+ "\\|%\\(?1:[^\\\\/]*\\)%")
+ (when comint-file-name-quote-list
+ "\\|\\\\\\(.\\)")))
+ (qupos nil)
+ (push (lambda (str end)
+ (push str ustrs)
+ (setq upos (- upos (length str)))
+ (unless (or qupos (> upos 0))
+ (setq qupos (if (< end 0) (- end) (+ upos end))))))
+ match)
+ (while (setq match (string-match re qstr qpos))
+ (funcall push (substring qstr qpos match) match)
+ (cond
+ ((match-beginning 2) (funcall push (match-string 2 qstr) (match-end 0)))
+ ((match-beginning 1) (funcall push (getenv (match-string 1 qstr))
+ (- (match-end 0))))
+ ((eq (aref qstr match) ?\") (setq dquotes (not dquotes)))
+ ((eq (aref qstr match) ?\')
+ (cond
+ (dquotes (funcall push "'" (match-end 0)))
+ ((< match (1+ (length qstr)))
+ (let ((end (string-match "'" qstr (1+ match))))
+ (funcall push (substring qstr (1+ match) end)
+ (or end (length qstr)))))
+ (t nil)))
+ (t (error "Unexpected case in shell--unquote&requote-argument!")))
+ (setq qpos (match-end 0)))
+ (funcall push (substring qstr qpos) (length qstr))
+ (list (mapconcat #'identity (nreverse ustrs) "")
+ qupos #'comint-quote-filename)))
+
+(defun shell--unquote-argument (str)
+ (car (shell--unquote&requote-argument str)))
+(defun shell--requote-argument (upos qstr)
+ ;; See `completion-table-with-quoting'.
+ (let ((res (shell--unquote&requote-argument qstr upos)))
+ (cons (nth 1 res) (nth 2 res))))
+
+(defun shell--parse-pcomplete-arguments ()
"Parse whitespace separated arguments in the current region."
+ ;; FIXME: share code with shell--unquote&requote-argument.
(let ((begin (save-excursion (shell-backward-command 1) (point)))
(end (point))
begins args)
@@ -394,13 +443,13 @@ Thus, this does not include the shell's current directory.")
(cond
((match-beginning 3) ;Backslash escape.
(push (cond
- ((null pcomplete-arg-quote-list)
+ ((null comint-file-name-quote-list)
(goto-char (match-beginning 3)) "\\")
((= (match-beginning 3) (match-end 3)) "\\")
(t (match-string 3)))
arg))
((match-beginning 2) ;Double quote.
- (push (if (null pcomplete-arg-quote-list) (match-string 2)
+ (push (if (null comint-file-name-quote-list) (match-string 2)
(replace-regexp-in-string
"\\\\\\(.\\)" "\\1" (match-string 2)))
arg))
@@ -430,10 +479,10 @@ Shell buffers. It implements `shell-completion-execonly' for
shell-file-name-quote-list)
(set (make-local-variable 'comint-dynamic-complete-functions)
shell-dynamic-complete-functions)
+ (setq-local comint-unquote-function #'shell--unquote-argument)
+ (setq-local comint-requote-function #'shell--requote-argument)
(set (make-local-variable 'pcomplete-parse-arguments-function)
- #'shell-parse-pcomplete-arguments)
- (set (make-local-variable 'pcomplete-arg-quote-list)
- comint-file-name-quote-list)
+ #'shell--parse-pcomplete-arguments)
(set (make-local-variable 'pcomplete-termination-string)
(cond ((not comint-completion-addsuffix) "")
((stringp comint-completion-addsuffix)