|
|
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.