aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Marshall1995-04-03 13:06:25 +0000
committerSimon Marshall1995-04-03 13:06:25 +0000
commit59f36b08082a7ef690cdcfe16fd9d5315ea4ad00 (patch)
treeee363616e4b8c0d08f9eb893334f2ca4ab814e4f
parent7b4c65034c0081cd144a77b22f8a0214b51e4f86 (diff)
downloademacs-59f36b08082a7ef690cdcfe16fd9d5315ea4ad00.tar.gz
emacs-59f36b08082a7ef690cdcfe16fd9d5315ea4ad00.zip
Added support for special (quoted) characters in file names:
new functions comint-quote-filename and comint-unquote-filename, using new variable comint-file-name-quote-list. Changed comint-word, comint-match-partial-filename and comint-dynamic-list-filename-completions to support character quoting. Made comint-dynamic-complete-as-filename and comint-dynamic-simple-complete use strings of comint-completion-addsuffix for completion, if a cons pair.
-rw-r--r--lisp/comint.el119
1 files changed, 79 insertions, 40 deletions
diff --git a/lisp/comint.el b/lisp/comint.el
index a904779543f..ac73762903a 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -118,6 +118,7 @@
118;;; comint-last-input-match - string ... 118;;; comint-last-input-match - string ...
119;;; comint-dynamic-complete-functions - hook For the completion mechanism 119;;; comint-dynamic-complete-functions - hook For the completion mechanism
120;;; comint-completion-fignore - list ... 120;;; comint-completion-fignore - list ...
121;;; comint-file-name-quote-list - list ...
121;;; comint-get-old-input - function Hooks for specific 122;;; comint-get-old-input - function Hooks for specific
122;;; comint-input-filter-functions - hook process-in-a-buffer 123;;; comint-input-filter-functions - hook process-in-a-buffer
123;;; comint-output-filter-functions - hook function modes. 124;;; comint-output-filter-functions - hook function modes.
@@ -130,7 +131,7 @@
130;;; comint-scroll-show-maximum-output - boolean... 131;;; comint-scroll-show-maximum-output - boolean...
131;;; 132;;;
132;;; Comint mode non-buffer local variables: 133;;; Comint mode non-buffer local variables:
133;;; comint-completion-addsuffix - boolean For file name completion 134;;; comint-completion-addsuffix - boolean/cons For file name completion
134;;; comint-completion-autolist - boolean behavior 135;;; comint-completion-autolist - boolean behavior
135;;; comint-completion-recexact - boolean ... 136;;; comint-completion-recexact - boolean ...
136 137
@@ -391,6 +392,7 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
391 (make-local-variable 'comint-ptyp) 392 (make-local-variable 'comint-ptyp)
392 (make-local-variable 'comint-exec-hook) 393 (make-local-variable 'comint-exec-hook)
393 (make-local-variable 'comint-process-echoes) 394 (make-local-variable 'comint-process-echoes)
395 (make-local-variable 'comint-file-name-quote-list)
394 (run-hooks 'comint-mode-hook)) 396 (run-hooks 'comint-mode-hook))
395 397
396(if comint-mode-map 398(if comint-mode-map
@@ -1406,23 +1408,23 @@ applications."
1406 ;; Use this instead of `read-char' to avoid "Non-character input-event". 1408 ;; Use this instead of `read-char' to avoid "Non-character input-event".
1407 (setq c (read-char-exclusive)) 1409 (setq c (read-char-exclusive))
1408 (cond ((= c ?\C-g) 1410 (cond ((= c ?\C-g)
1409 ;; This function may get called from a process filter, where 1411 ;; This function may get called from a process filter, where
1410 ;; inhibit-quit is set. In later versions of emacs read-char 1412 ;; inhibit-quit is set. In later versions of emacs read-char
1411 ;; may clear quit-flag itself and return C-g. That would make 1413 ;; may clear quit-flag itself and return C-g. That would make
1412 ;; it impossible to quit this loop in a simple way, so 1414 ;; it impossible to quit this loop in a simple way, so
1413 ;; re-enable it here (for backward-compatibility the check for 1415 ;; re-enable it here (for backward-compatibility the check for
1414 ;; quit-flag below would still be necessary, so this seems 1416 ;; quit-flag below would still be necessary, so this seems
1415 ;; like the simplest way to do things). 1417 ;; like the simplest way to do things).
1416 (setq quit-flag t 1418 (setq quit-flag t
1417 done t)) 1419 done t))
1418 ((or (= c ?\r) (= c ?\n) (= c ?\e)) 1420 ((or (= c ?\r) (= c ?\n) (= c ?\e))
1419 (setq done t)) 1421 (setq done t))
1420 ((= c ?\C-u) 1422 ((= c ?\C-u)
1421 (setq ans "")) 1423 (setq ans ""))
1422 ((and (/= c ?\b) (/= c ?\177)) 1424 ((and (/= c ?\b) (/= c ?\177))
1423 (setq ans (concat ans (char-to-string c)))) 1425 (setq ans (concat ans (char-to-string c))))
1424 ((> (length ans) 0) 1426 ((> (length ans) 0)
1425 (setq ans (substring ans 0 -1))))) 1427 (setq ans (substring ans 0 -1)))))
1426 (if quit-flag 1428 (if quit-flag
1427 ;; Emulate a true quit, except that we have to return a value. 1429 ;; Emulate a true quit, except that we have to return a value.
1428 (prog1 1430 (prog1
@@ -1802,6 +1804,8 @@ This mirrors the optional behavior of tcsh.")
1802 1804
1803(defvar comint-completion-addsuffix t 1805(defvar comint-completion-addsuffix t
1804 "*If non-nil, add a `/' to completed directories, ` ' to file names. 1806 "*If non-nil, add a `/' to completed directories, ` ' to file names.
1807If a cons pair, it should be of the form (DIRSUFFIX . FILESUFFIX) where
1808DIRSUFFIX and FILESUFFIX are strings added on unambiguous or exact completion.
1805This mirrors the optional behavior of tcsh.") 1809This mirrors the optional behavior of tcsh.")
1806 1810
1807(defvar comint-completion-recexact nil 1811(defvar comint-completion-recexact nil
@@ -1821,6 +1825,11 @@ Note that this applies to `comint-dynamic-complete-filename' only.")
1821This is used by comint's and shell's completion functions, and by shell's 1825This is used by comint's and shell's completion functions, and by shell's
1822directory tracking functions.") 1826directory tracking functions.")
1823 1827
1828(defvar comint-file-name-quote-list nil
1829 "List of characters to quote with `\' when in a file name.
1830
1831This is a good thing to set in mode hooks.")
1832
1824 1833
1825(defun comint-directory (directory) 1834(defun comint-directory (directory)
1826 ;; Return expanded DIRECTORY, with `comint-file-name-prefix' if absolute. 1835 ;; Return expanded DIRECTORY, with `comint-file-name-prefix' if absolute.
@@ -1834,23 +1843,43 @@ directory tracking functions.")
1834Word constituents are considered to be those in WORD-CHARS, which is like the 1843Word constituents are considered to be those in WORD-CHARS, which is like the
1835inside of a \"[...]\" (see `skip-chars-forward')." 1844inside of a \"[...]\" (see `skip-chars-forward')."
1836 (save-excursion 1845 (save-excursion
1837 (let ((limit (point)) 1846 (let ((non-word-chars (concat "[^\\\\" word-chars "]")) (here (point)))
1838 (word (concat "[" word-chars "]")) 1847 (while (and (re-search-backward non-word-chars nil 'move)
1839 (non-word (concat "[^" word-chars "]"))) 1848 ;(memq (char-after (point)) shell-file-name-quote-list)
1840 (if (re-search-backward non-word nil 'move) 1849 (not (bolp)) (eq (char-after (1- (point))) ?\\))
1841 (forward-char 1)) 1850 (backward-char 1))
1842 ;; Anchor the search forwards. 1851 (forward-char 1)
1843 (if (or (eolp) (looking-at non-word)) 1852 (and (< (point) here) (buffer-substring (point) here)))))
1844 nil
1845 (re-search-forward (concat word "+") limit)
1846 (buffer-substring (match-beginning 0) (match-end 0))))))
1847 1853
1848 1854
1849(defun comint-match-partial-filename () 1855(defun comint-match-partial-filename ()
1850 "Return the filename at point, or nil if non is found. 1856 "Return the filename at point, or nil if non is found.
1851Environment variables are substituted. See `comint-word'." 1857Environment variables are substituted. See `comint-word'."
1852 (let ((filename (comint-word "~/A-Za-z0-9+@:_.$#%,={}-"))) 1858 (let ((filename (comint-word "~/A-Za-z0-9+@:_.$#%,={}-")))
1853 (and filename (substitute-in-file-name filename)))) 1859 (and filename (substitute-in-file-name (comint-unquote-filename filename)))))
1860
1861
1862(defun comint-quote-filename (filename)
1863 "Return FILENAME with magic characters quoted.
1864Magic characters are those in `comint-file-name-quote-list'."
1865 (if (null comint-file-name-quote-list)
1866 filename
1867 (let ((regexp
1868 (format "\\(^\\|[^\\]\\)\\([%s]\\)"
1869 (mapconcat 'char-to-string comint-file-name-quote-list ""))))
1870 (save-match-data
1871 (while (string-match regexp filename)
1872 (setq filename (replace-match "\\1\\\\\\2" nil nil filename)))
1873 filename))))
1874
1875(defun comint-unquote-filename (filename)
1876 "Return FILENAME with quoted characters unquoted."
1877 (if (null comint-file-name-quote-list)
1878 filename
1879 (save-match-data
1880 (while (string-match "\\\\\\(.\\)" filename)
1881 (setq filename (replace-match "\\1" nil nil filename)))
1882 filename)))
1854 1883
1855 1884
1856(defun comint-dynamic-complete () 1885(defun comint-dynamic-complete ()
@@ -1893,6 +1922,12 @@ See `comint-dynamic-complete-filename'. Returns t if successful."
1893 (file-name-handler-alist nil) 1922 (file-name-handler-alist nil)
1894 (minibuffer-p (window-minibuffer-p (selected-window))) 1923 (minibuffer-p (window-minibuffer-p (selected-window)))
1895 (success t) 1924 (success t)
1925 (dirsuffix (cond ((not comint-completion-addsuffix) "")
1926 ((not (consp comint-completion-addsuffix)) "/")
1927 (t (car comint-completion-addsuffix))))
1928 (filesuffix (cond ((not comint-completion-addsuffix) "")
1929 ((not (consp comint-completion-addsuffix)) " ")
1930 (t (cdr comint-completion-addsuffix))))
1896 (filename (or (comint-match-partial-filename) "")) 1931 (filename (or (comint-match-partial-filename) ""))
1897 (pathdir (file-name-directory filename)) 1932 (pathdir (file-name-directory filename))
1898 (pathnondir (file-name-nondirectory filename)) 1933 (pathnondir (file-name-nondirectory filename))
@@ -1902,24 +1937,24 @@ See `comint-dynamic-complete-filename'. Returns t if successful."
1902 (message "No completions of %s" filename) 1937 (message "No completions of %s" filename)
1903 (setq success nil)) 1938 (setq success nil))
1904 ((eq completion t) ; Means already completed "file". 1939 ((eq completion t) ; Means already completed "file".
1905 (if comint-completion-addsuffix (insert " ")) 1940 (insert filesuffix)
1906 (or minibuffer-p (message "Sole completion"))) 1941 (or minibuffer-p (message "Sole completion")))
1907 ((string-equal completion "") ; Means completion on "directory/". 1942 ((string-equal completion "") ; Means completion on "directory/".
1908 (comint-dynamic-list-filename-completions)) 1943 (comint-dynamic-list-filename-completions))
1909 (t ; Completion string returned. 1944 (t ; Completion string returned.
1910 (let ((file (concat (file-name-as-directory directory) completion))) 1945 (let ((file (concat (file-name-as-directory directory) completion)))
1911 (insert (substring (directory-file-name completion) 1946 (insert (comint-quote-filename
1912 (length pathnondir))) 1947 (substring (directory-file-name completion)
1948 (length pathnondir))))
1913 (cond ((symbolp (file-name-completion completion directory)) 1949 (cond ((symbolp (file-name-completion completion directory))
1914 ;; We inserted a unique completion. 1950 ;; We inserted a unique completion.
1915 (if comint-completion-addsuffix 1951 (insert (if (file-directory-p file) dirsuffix filesuffix))
1916 (insert (if (file-directory-p file) "/" " ")))
1917 (or minibuffer-p (message "Completed"))) 1952 (or minibuffer-p (message "Completed")))
1918 ((and comint-completion-recexact comint-completion-addsuffix 1953 ((and comint-completion-recexact comint-completion-addsuffix
1919 (string-equal pathnondir completion) 1954 (string-equal pathnondir completion)
1920 (file-exists-p file)) 1955 (file-exists-p file))
1921 ;; It's not unique, but user wants shortest match. 1956 ;; It's not unique, but user wants shortest match.
1922 (insert (if (file-directory-p file) "/" " ")) 1957 (insert (if (file-directory-p file) dirsuffix filesuffix))
1923 (or minibuffer-p (message "Completed shortest"))) 1958 (or minibuffer-p (message "Completed shortest")))
1924 ((or comint-completion-autolist 1959 ((or comint-completion-autolist
1925 (string-equal pathnondir completion)) 1960 (string-equal pathnondir completion))
@@ -1957,6 +1992,9 @@ Returns `listed' if a completion listing was shown.
1957 1992
1958See also `comint-dynamic-complete-filename'." 1993See also `comint-dynamic-complete-filename'."
1959 (let* ((completion-ignore-case nil) 1994 (let* ((completion-ignore-case nil)
1995 (suffix (cond ((not comint-completion-addsuffix) "")
1996 ((not (consp comint-completion-addsuffix)) " ")
1997 (t (cdr comint-completion-addsuffix))))
1960 (candidates (mapcar (function (lambda (x) (list x))) candidates)) 1998 (candidates (mapcar (function (lambda (x) (list x))) candidates))
1961 (completions (all-completions stub candidates))) 1999 (completions (all-completions stub candidates)))
1962 (cond ((null completions) 2000 (cond ((null completions)
@@ -1968,7 +2006,7 @@ See also `comint-dynamic-complete-filename'."
1968 (message "Sole completion") 2006 (message "Sole completion")
1969 (insert (substring completion (length stub))) 2007 (insert (substring completion (length stub)))
1970 (message "Completed")) 2008 (message "Completed"))
1971 (if comint-completion-addsuffix (insert " ")) 2009 (insert suffix)
1972 'sole)) 2010 'sole))
1973 (t ; There's no unique completion. 2011 (t ; There's no unique completion.
1974 (let ((completion (try-completion stub candidates))) 2012 (let ((completion (try-completion stub candidates)))
@@ -1978,7 +2016,7 @@ See also `comint-dynamic-complete-filename'."
1978 (string-equal stub completion) 2016 (string-equal stub completion)
1979 (member completion completions)) 2017 (member completion completions))
1980 ;; It's not unique, but user wants shortest match. 2018 ;; It's not unique, but user wants shortest match.
1981 (insert " ") 2019 (insert suffix)
1982 (message "Completed shortest") 2020 (message "Completed shortest")
1983 'shortest) 2021 'shortest)
1984 ((or comint-completion-autolist 2022 ((or comint-completion-autolist
@@ -2001,9 +2039,10 @@ See also `comint-dynamic-complete-filename'."
2001 (pathnondir (file-name-nondirectory filename)) 2039 (pathnondir (file-name-nondirectory filename))
2002 (directory (if pathdir (comint-directory pathdir) default-directory)) 2040 (directory (if pathdir (comint-directory pathdir) default-directory))
2003 (completions (file-name-all-completions pathnondir directory))) 2041 (completions (file-name-all-completions pathnondir directory)))
2004 (if completions 2042 (if (not completions)
2005 (comint-dynamic-list-completions completions) 2043 (message "No completions of %s" filename)
2006 (message "No completions of %s" filename)))) 2044 (comint-dynamic-list-completions
2045 (mapcar 'comint-quote-filename completions)))))
2007 2046
2008 2047
2009(defun comint-dynamic-list-completions (completions) 2048(defun comint-dynamic-list-completions (completions)