aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorStefan Monnier2012-05-15 12:58:35 -0400
committerStefan Monnier2012-05-15 12:58:35 -0400
commit2473256d7b660edc5c1525163b2e9917d6ebf18d (patch)
treebb21474889ee68bee3259e7711f40320fbbcb369 /lisp
parentfdb058c22800a2cce782c74ee3e3918b432b271c (diff)
downloademacs-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/ChangeLog10
-rw-r--r--lisp/comint.el38
-rw-r--r--lisp/shell.el61
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 @@
12012-05-15 Stefan Monnier <monnier@iro.umontreal.ca> 12012-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.
2969Word constituents are considered to be those in WORD-CHARS, which is like the 2969Word constituents are considered to be those in WORD-CHARS, which is like the
2970inside of a \"[...]\" (see `skip-chars-forward'), plus all non-ASCII characters." 2970inside 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."
3140See `completion-table-with-quoting' and `comint-requote-function'.") 3132See `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.
3143See `completion-table-with-quoting' and `comint-requote-function'.") 3135See `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)