diff options
| author | Stefan Monnier | 2012-05-15 12:58:35 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-05-15 12:58:35 -0400 |
| commit | 2473256d7b660edc5c1525163b2e9917d6ebf18d (patch) | |
| tree | bb21474889ee68bee3259e7711f40320fbbcb369 /lisp | |
| parent | fdb058c22800a2cce782c74ee3e3918b432b271c (diff) | |
| download | emacs-2473256d7b660edc5c1525163b2e9917d6ebf18d.tar.gz emacs-2473256d7b660edc5c1525163b2e9917d6ebf18d.zip | |
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')
| -rw-r--r-- | lisp/ChangeLog | 10 | ||||
| -rw-r--r-- | lisp/comint.el | 38 | ||||
| -rw-r--r-- | lisp/shell.el | 61 |
3 files changed, 80 insertions, 29 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 865bdd7c6a3..de2cfc6f0ac 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,15 @@ | |||
| 1 | 2012-05-15 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2012-05-15 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | Only handle ".." and '..' quoting in shell-mode (bug#11466). | ||
| 4 | * shell.el (shell--unquote&requote-argument, shell--unquote-argument) | ||
| 5 | (shell--requote-argument): New functions. | ||
| 6 | (shell-completion-vars): Use them. | ||
| 7 | (shell--parse-pcomplete-arguments): Rename from | ||
| 8 | shell-parse-pcomplete-arguments. | ||
| 9 | * comint.el (comint-word): Obey comint-file-name-quote-list. Simplify. | ||
| 10 | (comint--unquote&requote-argument): Don't handle ".." and '..' quoting. | ||
| 11 | Obey comint-file-name-quote-list. | ||
| 12 | |||
| 3 | * emacs-lisp/smie.el (smie-indent--bolp-1): New function. | 13 | * emacs-lisp/smie.el (smie-indent--bolp-1): New function. |
| 4 | (smie-indent-keyword): Use it. | 14 | (smie-indent-keyword): Use it. |
| 5 | 15 | ||
diff --git a/lisp/comint.el b/lisp/comint.el index 43e42c87be7..db0f5b8b460 100644 --- a/lisp/comint.el +++ b/lisp/comint.el | |||
| @@ -2968,19 +2968,20 @@ This is a good thing to set in mode hooks.") | |||
| 2968 | "Return the word of WORD-CHARS at point, or nil if none is found. | 2968 | "Return the word of WORD-CHARS at point, or nil if none is found. |
| 2969 | Word constituents are considered to be those in WORD-CHARS, which is like the | 2969 | Word constituents are considered to be those in WORD-CHARS, which is like the |
| 2970 | inside of a \"[...]\" (see `skip-chars-forward'), plus all non-ASCII characters." | 2970 | inside of a \"[...]\" (see `skip-chars-forward'), plus all non-ASCII characters." |
| 2971 | ;; FIXME: Need to handle "..." and '...' quoting in shell.el! | ||
| 2972 | ;; This should be combined with pomplete-parsing somehow. | ||
| 2971 | (save-excursion | 2973 | (save-excursion |
| 2972 | (let ((here (point)) | 2974 | (let ((here (point)) |
| 2973 | giveup) | 2975 | giveup) |
| 2974 | (while (not giveup) | 2976 | (while (not giveup) |
| 2975 | (let ((startpoint (point))) | 2977 | (let ((startpoint (point))) |
| 2976 | (skip-chars-backward (concat "\\\\" word-chars)) | 2978 | (skip-chars-backward (concat "\\\\" word-chars)) |
| 2977 | ;; Fixme: This isn't consistent with Bash, at least -- not | 2979 | (if (and comint-file-name-quote-list |
| 2978 | ;; all non-ASCII chars should be word constituents. | 2980 | (eq (char-before (1- (point))) ?\\)) |
| 2979 | (if (and (> (- (point) 2) (point-min)) | ||
| 2980 | (= (char-after (- (point) 2)) ?\\)) | ||
| 2981 | (forward-char -2)) | 2981 | (forward-char -2)) |
| 2982 | (if (and (> (- (point) 1) (point-min)) | 2982 | ;; FIXME: This isn't consistent with Bash, at least -- not |
| 2983 | (>= (char-after (- (point) 1)) 128)) | 2983 | ;; all non-ASCII chars should be word constituents. |
| 2984 | (if (and (not (bobp)) (>= (char-before) 128)) | ||
| 2984 | (forward-char -1)) | 2985 | (forward-char -1)) |
| 2985 | (if (= (point) startpoint) | 2986 | (if (= (point) startpoint) |
| 2986 | (setq giveup t)))) | 2987 | (setq giveup t)))) |
| @@ -3012,14 +3013,14 @@ See `comint-word'." | |||
| 3012 | (defun comint--unquote&requote-argument (qstr &optional upos) | 3013 | (defun comint--unquote&requote-argument (qstr &optional upos) |
| 3013 | (unless upos (setq upos 0)) | 3014 | (unless upos (setq upos 0)) |
| 3014 | (let* ((qpos 0) | 3015 | (let* ((qpos 0) |
| 3015 | (dquotes nil) | ||
| 3016 | (ustrs '()) | 3016 | (ustrs '()) |
| 3017 | (re (concat | 3017 | (re (concat |
| 3018 | "[\"']\\|\\\\\\(.\\)" | 3018 | "\\$\\(?:\\([[:alpha:]][[:alnum:]]*\\)" |
| 3019 | "\\|\\$\\(?:\\([[:alpha:]][[:alnum:]]*\\)" | 3019 | "\\|{\\(?1:[^{}]+\\)}\\)" |
| 3020 | "\\|{\\(?2:[^{}]+\\)}\\)" | ||
| 3021 | (when (memq system-type '(ms-dos windows-nt)) | 3020 | (when (memq system-type '(ms-dos windows-nt)) |
| 3022 | "\\|%\\(?2:[^\\\\/]*\\)%"))) | 3021 | "\\|%\\(?1:[^\\\\/]*\\)%") |
| 3022 | (when comint-file-name-quote-list | ||
| 3023 | "\\|\\\\\\(.\\)"))) | ||
| 3023 | (qupos nil) | 3024 | (qupos nil) |
| 3024 | (push (lambda (str end) | 3025 | (push (lambda (str end) |
| 3025 | (push str ustrs) | 3026 | (push str ustrs) |
| @@ -3030,18 +3031,9 @@ See `comint-word'." | |||
| 3030 | (while (setq match (string-match re qstr qpos)) | 3031 | (while (setq match (string-match re qstr qpos)) |
| 3031 | (funcall push (substring qstr qpos match) match) | 3032 | (funcall push (substring qstr qpos match) match) |
| 3032 | (cond | 3033 | (cond |
| 3033 | ((match-beginning 1) (funcall push (match-string 1 qstr) (match-end 0))) | 3034 | ((match-beginning 2) (funcall push (match-string 2 qstr) (match-end 0))) |
| 3034 | ((match-beginning 2) (funcall push (getenv (match-string 2 qstr)) | 3035 | ((match-beginning 1) (funcall push (getenv (match-string 1 qstr)) |
| 3035 | (- (match-end 0)))) | 3036 | (- (match-end 0)))) |
| 3036 | ((eq (aref qstr match) ?\") (setq dquotes (not dquotes))) | ||
| 3037 | ((eq (aref qstr match) ?\') | ||
| 3038 | (cond | ||
| 3039 | (dquotes (funcall push "'" (match-end 0))) | ||
| 3040 | ((< match (1+ (length qstr))) | ||
| 3041 | (let ((end (string-match "'" qstr (1+ match)))) | ||
| 3042 | (funcall push (substring qstr (1+ match) end) | ||
| 3043 | (or end (length qstr))))) | ||
| 3044 | (t nil))) | ||
| 3045 | (t (error "Unexpected case in comint--unquote&requote-argument!"))) | 3037 | (t (error "Unexpected case in comint--unquote&requote-argument!"))) |
| 3046 | (setq qpos (match-end 0))) | 3038 | (setq qpos (match-end 0))) |
| 3047 | (funcall push (substring qstr qpos) (length qstr)) | 3039 | (funcall push (substring qstr qpos) (length qstr)) |
| @@ -3140,7 +3132,7 @@ Returns t if successful." | |||
| 3140 | See `completion-table-with-quoting' and `comint-requote-function'.") | 3132 | See `completion-table-with-quoting' and `comint-requote-function'.") |
| 3141 | (defvar comint-requote-function #'comint--requote-argument | 3133 | (defvar comint-requote-function #'comint--requote-argument |
| 3142 | "Function to use for completion of quoted data. | 3134 | "Function to use for completion of quoted data. |
| 3143 | See `completion-table-with-quoting' and `comint-requote-function'.") | 3135 | See `completion-table-with-quoting' and `comint-unquote-function'.") |
| 3144 | 3136 | ||
| 3145 | (defun comint--complete-file-name-data () | 3137 | (defun comint--complete-file-name-data () |
| 3146 | "Return the completion data for file name at point." | 3138 | "Return the completion data for file name at point." |
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.") | |||
| 372 | 372 | ||
| 373 | ;;; Basic Procedures | 373 | ;;; Basic Procedures |
| 374 | 374 | ||
| 375 | (defun shell-parse-pcomplete-arguments () | 375 | (defun shell--unquote&requote-argument (qstr &optional upos) |
| 376 | (unless upos (setq upos 0)) | ||
| 377 | (let* ((qpos 0) | ||
| 378 | (dquotes nil) | ||
| 379 | (ustrs '()) | ||
| 380 | (re (concat | ||
| 381 | "[\"']" | ||
| 382 | "\\|\\$\\(?:\\([[:alpha:]][[:alnum:]]*\\)" | ||
| 383 | "\\|{\\(?1:[^{}]+\\)}\\)" | ||
| 384 | (when (memq system-type '(ms-dos windows-nt)) | ||
| 385 | "\\|%\\(?1:[^\\\\/]*\\)%") | ||
| 386 | (when comint-file-name-quote-list | ||
| 387 | "\\|\\\\\\(.\\)"))) | ||
| 388 | (qupos nil) | ||
| 389 | (push (lambda (str end) | ||
| 390 | (push str ustrs) | ||
| 391 | (setq upos (- upos (length str))) | ||
| 392 | (unless (or qupos (> upos 0)) | ||
| 393 | (setq qupos (if (< end 0) (- end) (+ upos end)))))) | ||
| 394 | match) | ||
| 395 | (while (setq match (string-match re qstr qpos)) | ||
| 396 | (funcall push (substring qstr qpos match) match) | ||
| 397 | (cond | ||
| 398 | ((match-beginning 2) (funcall push (match-string 2 qstr) (match-end 0))) | ||
| 399 | ((match-beginning 1) (funcall push (getenv (match-string 1 qstr)) | ||
| 400 | (- (match-end 0)))) | ||
| 401 | ((eq (aref qstr match) ?\") (setq dquotes (not dquotes))) | ||
| 402 | ((eq (aref qstr match) ?\') | ||
| 403 | (cond | ||
| 404 | (dquotes (funcall push "'" (match-end 0))) | ||
| 405 | ((< match (1+ (length qstr))) | ||
| 406 | (let ((end (string-match "'" qstr (1+ match)))) | ||
| 407 | (funcall push (substring qstr (1+ match) end) | ||
| 408 | (or end (length qstr))))) | ||
| 409 | (t nil))) | ||
| 410 | (t (error "Unexpected case in shell--unquote&requote-argument!"))) | ||
| 411 | (setq qpos (match-end 0))) | ||
| 412 | (funcall push (substring qstr qpos) (length qstr)) | ||
| 413 | (list (mapconcat #'identity (nreverse ustrs) "") | ||
| 414 | qupos #'comint-quote-filename))) | ||
| 415 | |||
| 416 | (defun shell--unquote-argument (str) | ||
| 417 | (car (shell--unquote&requote-argument str))) | ||
| 418 | (defun shell--requote-argument (upos qstr) | ||
| 419 | ;; See `completion-table-with-quoting'. | ||
| 420 | (let ((res (shell--unquote&requote-argument qstr upos))) | ||
| 421 | (cons (nth 1 res) (nth 2 res)))) | ||
| 422 | |||
| 423 | (defun shell--parse-pcomplete-arguments () | ||
| 376 | "Parse whitespace separated arguments in the current region." | 424 | "Parse whitespace separated arguments in the current region." |
| 425 | ;; FIXME: share code with shell--unquote&requote-argument. | ||
| 377 | (let ((begin (save-excursion (shell-backward-command 1) (point))) | 426 | (let ((begin (save-excursion (shell-backward-command 1) (point))) |
| 378 | (end (point)) | 427 | (end (point)) |
| 379 | begins args) | 428 | begins args) |
| @@ -394,13 +443,13 @@ Thus, this does not include the shell's current directory.") | |||
| 394 | (cond | 443 | (cond |
| 395 | ((match-beginning 3) ;Backslash escape. | 444 | ((match-beginning 3) ;Backslash escape. |
| 396 | (push (cond | 445 | (push (cond |
| 397 | ((null pcomplete-arg-quote-list) | 446 | ((null comint-file-name-quote-list) |
| 398 | (goto-char (match-beginning 3)) "\\") | 447 | (goto-char (match-beginning 3)) "\\") |
| 399 | ((= (match-beginning 3) (match-end 3)) "\\") | 448 | ((= (match-beginning 3) (match-end 3)) "\\") |
| 400 | (t (match-string 3))) | 449 | (t (match-string 3))) |
| 401 | arg)) | 450 | arg)) |
| 402 | ((match-beginning 2) ;Double quote. | 451 | ((match-beginning 2) ;Double quote. |
| 403 | (push (if (null pcomplete-arg-quote-list) (match-string 2) | 452 | (push (if (null comint-file-name-quote-list) (match-string 2) |
| 404 | (replace-regexp-in-string | 453 | (replace-regexp-in-string |
| 405 | "\\\\\\(.\\)" "\\1" (match-string 2))) | 454 | "\\\\\\(.\\)" "\\1" (match-string 2))) |
| 406 | arg)) | 455 | arg)) |
| @@ -430,10 +479,10 @@ Shell buffers. It implements `shell-completion-execonly' for | |||
| 430 | shell-file-name-quote-list) | 479 | shell-file-name-quote-list) |
| 431 | (set (make-local-variable 'comint-dynamic-complete-functions) | 480 | (set (make-local-variable 'comint-dynamic-complete-functions) |
| 432 | shell-dynamic-complete-functions) | 481 | shell-dynamic-complete-functions) |
| 482 | (setq-local comint-unquote-function #'shell--unquote-argument) | ||
| 483 | (setq-local comint-requote-function #'shell--requote-argument) | ||
| 433 | (set (make-local-variable 'pcomplete-parse-arguments-function) | 484 | (set (make-local-variable 'pcomplete-parse-arguments-function) |
| 434 | #'shell-parse-pcomplete-arguments) | 485 | #'shell--parse-pcomplete-arguments) |
| 435 | (set (make-local-variable 'pcomplete-arg-quote-list) | ||
| 436 | comint-file-name-quote-list) | ||
| 437 | (set (make-local-variable 'pcomplete-termination-string) | 486 | (set (make-local-variable 'pcomplete-termination-string) |
| 438 | (cond ((not comint-completion-addsuffix) "") | 487 | (cond ((not comint-completion-addsuffix) "") |
| 439 | ((stringp comint-completion-addsuffix) | 488 | ((stringp comint-completion-addsuffix) |