diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2012-05-15 12:58:35 -0400 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2012-05-15 12:58:35 -0400 |
commit | 2473256d7b660edc5c1525163b2e9917d6ebf18d (patch) | |
tree | bb21474889ee68bee3259e7711f40320fbbcb369 /lisp/shell.el | |
parent | fdb058c22800a2cce782c74ee3e3918b432b271c (diff) | |
download | emacs-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.el | 61 |
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) |