]> code.delx.au - gnu-emacs/blobdiff - lisp/shell.el
Merge from trunk.
[gnu-emacs] / lisp / shell.el
index d6bc685618cb299c17f85fe069cd12ba5214b7c5..de811543ba089f3fcaf02eb587607c177e1aaf2c 100644 (file)
@@ -98,6 +98,7 @@
 
 (eval-when-compile (require 'cl))
 (require 'comint)
+(require 'pcomplete)
 
 ;;; Customization and Buffer Variables
 
@@ -186,7 +187,9 @@ This is a fine thing to set in your `.emacs' file.")
     shell-environment-variable-completion
     shell-command-completion
     shell-c-a-p-replace-by-expanded-directory
+    pcomplete-completions-at-point
     shell-filename-completion
+    ;; Not sure when this one would still be useful.  --Stef
     comint-filename-completion)
   "List of functions called to perform completion.
 This variable is used to initialize `comint-dynamic-complete-functions' in the
@@ -380,6 +383,35 @@ to `dirtrack-mode'."
   :group 'shell
   :type '(choice (const nil) regexp))
 
+
+(defun shell-completion-vars ()
+  "Setup completion vars for `shell-mode' and `read-shell-command'."
+  (set (make-local-variable 'comint-completion-fignore)
+       shell-completion-fignore)
+  (set (make-local-variable 'comint-delimiter-argument-list)
+       shell-delimiter-argument-list)
+  (set (make-local-variable 'comint-file-name-chars) shell-file-name-chars)
+  (set (make-local-variable 'comint-file-name-quote-list)
+       shell-file-name-quote-list)
+  (set (make-local-variable 'comint-dynamic-complete-functions)
+       shell-dynamic-complete-functions)
+  (set (make-local-variable 'pcomplete-parse-arguments-function)
+       ;; FIXME: This function should be moved to shell.el.
+       #'pcomplete-parse-comint-arguments)
+  (set (make-local-variable 'pcomplete-termination-string)
+       (cond ((not comint-completion-addsuffix) "")
+             ((stringp comint-completion-addsuffix)
+              comint-completion-addsuffix)
+             ((not (consp comint-completion-addsuffix)) " ")
+             (t (cdr comint-completion-addsuffix))))
+  ;; Don't use pcomplete's defaulting mechanism, rely on
+  ;; shell-dynamic-complete-functions instead.
+  (set (make-local-variable 'pcomplete-default-completion-function) #'ignore)
+  (setq comint-input-autoexpand shell-input-autoexpand)
+  ;; Not needed in shell-mode because it's inherited from comint-mode, but
+  ;; placed here for read-shell-command.
+  (add-hook 'completion-at-point-functions 'comint-completion-at-point nil t))
+
 (put 'shell-mode 'mode-class 'special)
 
 (define-derived-mode shell-mode comint-mode "Shell"
@@ -437,22 +469,12 @@ Variables `comint-output-filter-functions', a hook, and
 control whether input and output cause the window to scroll to the end of the
 buffer."
   (setq comint-prompt-regexp shell-prompt-pattern)
-  (setq comint-completion-fignore shell-completion-fignore)
-  (setq comint-delimiter-argument-list shell-delimiter-argument-list)
-  (setq comint-file-name-chars shell-file-name-chars)
-  (setq comint-file-name-quote-list shell-file-name-quote-list)
-  (set (make-local-variable 'comint-dynamic-complete-functions)
-       shell-dynamic-complete-functions)
+  (shell-completion-vars)
   (set (make-local-variable 'paragraph-separate) "\\'")
-  (make-local-variable 'paragraph-start)
-  (setq paragraph-start comint-prompt-regexp)
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults '(shell-font-lock-keywords t))
-  (make-local-variable 'shell-dirstack)
-  (setq shell-dirstack nil)
-  (make-local-variable 'shell-last-dir)
-  (setq shell-last-dir nil)
-  (setq comint-input-autoexpand shell-input-autoexpand)
+  (set (make-local-variable 'paragraph-start) comint-prompt-regexp)
+  (set (make-local-variable 'font-lock-defaults) '(shell-font-lock-keywords t))
+  (set (make-local-variable 'shell-dirstack) nil)
+  (set (make-local-variable 'shell-last-dir) nil)
   (shell-dirtrack-mode 1)
   ;; This is not really correct, since the shell buffer does not really
   ;; edit this directory.  But it is useful in the buffer list and menus.
@@ -693,6 +715,7 @@ Environment variables are expanded, see function `substitute-in-file-name'."
                               (concat "^" shell-command-separator-regexp)
                               str) ; skip whitespace
                              (match-end 0)))
+               (case-fold-search)
                end cmd arg1)
            (while (string-match shell-command-regexp str start)
              (setq end (match-end 0)
@@ -1063,12 +1086,15 @@ Returns t if successful."
     (list
      start end
      (lambda (string pred action)
-       (completion-table-with-terminator
-        " " (lambda (string pred action)
-              (if (string-match "/" string)
-                  (completion-file-name-table string pred action)
-                (complete-with-action action completions string pred)))
-        string pred action)))))
+       (if (string-match "/" string)
+           (completion-file-name-table string pred action)
+         (complete-with-action action completions string pred)))
+     :exit-function
+     (lambda (_string finished)
+       (when (memq finished '(sole finished))
+         (if (looking-at " ")
+             (goto-char (match-end 0))
+           (insert " ")))))))
 
 ;; (defun shell-dynamic-complete-as-command ()
 ;;    "Dynamically complete at point as a command.
@@ -1139,18 +1165,17 @@ Returns non-nil if successful."
                                   (substring x 0 (string-match "=" x)))
                                 process-environment))
              (suffix (case (char-before start) (?\{ "}") (?\( ")") (t ""))))
-        (list
-         start end
-         (apply-partially
-          #'completion-table-with-terminator
-          (cons (lambda (comp)
-                  (concat comp
-                          suffix
-                          (if (file-directory-p
-                               (comint-directory (getenv comp)))
-                              "/")))
-                "\\`a\\`")
-          variables))))))
+        (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 ()