|
|
1.1 root 1: ;; $Header: filec.el,v 1.10 88/11/03 17:09:21 layer Exp $
2:
3: ;; Command and file name completion
4:
5: (defvar fi:shell-token-pattern "[ \t\n()<>&|;=]"
6: "*The regular expression used by file name completion to mark path name
7: boundaries.")
8:
9: (defvar fi::shell-completions-window nil
10: "If non-nil, completion window requires cleaning up.")
11:
12: (defun fi:shell-do-completion ()
13: "Do either command or file name completion in a subprocess buffer
14: containing a shell (or other subprocess for which it would be useful, such
15: as Common Lisp or rlogin buffers)."
16: ;; First, find out whether or not we are completing a command or file
17: ;; name. Then, if a command, determine if it can be reduced to file name
18: ;; completion because it contains a slash (either absolute or relative,
19: ;; it doesn't matter).
20: (interactive)
21: (let* ((completion-ignore-case nil)
22: (completion-ignored-extensions nil)
23: (opoint (point))
24: (input-start
25: (save-excursion
26: (goto-char
27: (if (marker-buffer fi::last-input-end)
28: fi::last-input-end
29: 0))
30: (if (re-search-forward subprocess-prompt-pattern opoint t)
31: (point)))))
32: (if input-start
33: (if (save-excursion
34: (or (re-search-backward "[ \t]" input-start t)
35: (search-backward "/" input-start t)))
36: (call-interactively 'fi:shell-file-name-completion)
37: (call-interactively 'fi:shell-command-completion)))))
38:
39: (defun fi:shell-file-name-completion ()
40: "Perform file name completion in subprocess modes."
41: (interactive)
42: (let ((shell-expand-string
43: (substitute-in-file-name
44: (fi::shell-completion-default-prefix)))
45: (shell-expand-dir nil)
46: (shell-expand-file nil)
47: (shell-expand-completion nil))
48: ;; directory part of name
49: (setq shell-expand-dir
50: (or (file-name-directory shell-expand-string) default-directory))
51: ;; file part of name
52: (setq shell-expand-file
53: (file-name-nondirectory shell-expand-string))
54:
55: ;; do the expansion
56: (setq shell-expand-completion
57: (file-name-completion shell-expand-file shell-expand-dir))
58: ;; display the results
59: (if (eq shell-expand-completion t) (message "Sole completion")
60: (if (eq shell-expand-completion nil) (message "No match")
61: (if (equal shell-expand-completion shell-expand-file)
62: (progn
63: (if fi::shell-completions-window nil
64: (setq fi::shell-completions-window
65: (current-window-configuration)))
66: (message "Making completion list...")
67: (with-output-to-temp-buffer " *Completions*"
68: (display-completion-list
69: (sort (file-name-all-completions
70: shell-expand-completion shell-expand-dir)
71: 'string-lessp)))
72: (message ""))
73: ;; put in the expansion
74: (search-backward shell-expand-file)
75: (replace-match shell-expand-completion t t))))))
76:
77: (defun fi:shell-command-completion (shell-expand-string)
78: "Perform file name completion in subprocess modes."
79: (interactive (list (fi::shell-completion-default-prefix)))
80: (let ((completions nil)
81: (complete-alist nil)
82: (dirs exec-path))
83: ;;
84: ;; Find all possible completions of `shell-expand-string' in the
85: ;; exec-path (ie, PATH environment variable), comprised of only
86: ;; executable file names.
87: ;;
88: (while dirs
89: (let* ((dir (expand-file-name (car dirs)))
90: (res
91: (fi::executable-files
92: (file-name-all-completions shell-expand-string dir)
93: dir)))
94: (if res
95: (setq completions (append res completions))))
96: (setq dirs (cdr dirs)))
97:
98: ;; `completions' is now a list of all possible completions
99:
100: ;; build `complete-alist' for `try-completions'
101: (let ((names completions))
102: (while names
103: (setq complete-alist (cons (cons (car names) (car names))
104: complete-alist))
105: (setq names (cdr names))))
106:
107: (cond
108: ((null completions)
109: (message "No match"))
110: ((= 1 (length completions))
111: (cond ((string= shell-expand-string (car completions))
112: (fi::shell-completion-cleanup)
113: (message "Sole completion"))
114: (t (search-backward shell-expand-string)
115: (replace-match (car completions) t t))))
116: (t ;; display the completions
117: (let ((new-command (try-completion shell-expand-string complete-alist)))
118: (cond
119: ((and new-command (not (string= new-command shell-expand-string)))
120: (search-backward shell-expand-string)
121: (replace-match new-command t t)))
122: (if (not fi::shell-completions-window)
123: (setq fi::shell-completions-window
124: (current-window-configuration)))
125: (with-output-to-temp-buffer " *Completions*"
126: (display-completion-list
127: (sort completions 'string-lessp))))))))
128:
129: (defun fi::executable-files (files dir)
130: (cond
131: (files
132: (let (res file)
133: (while files
134: (setq file (concat dir "/" (car files)))
135: (if (and (not (file-directory-p file))
136: (not (zerop (logand 73 (file-modes file)))))
137: (setq res (cons (car files) res)))
138: (setq files (cdr files)))
139: res))))
140:
141: (defun fi::shell-completion-default-prefix ()
142: (re-search-backward fi:shell-token-pattern nil t)
143: (forward-char)
144: (buffer-substring
145: (point)
146: (progn
147: (if (re-search-forward fi:shell-token-pattern nil 0) (backward-char))
148: (point))))
149:
150: (defun fi::shell-completion-cleanup ()
151: "Clean up windows after shell file name completion."
152: (interactive)
153: (if fi::shell-completions-window
154: (save-excursion
155: (set-window-configuration fi::shell-completions-window)
156: (setq fi::shell-completions-window nil))))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.