Commit | Line | Data |
---|---|---|
60370d40 | 1 | ;;; pcmpl-unix.el --- standard UNIX completions |
4fa9f636 | 2 | |
acaf905b | 3 | ;; Copyright (C) 1999-2012 Free Software Foundation, Inc. |
4fa9f636 | 4 | |
bd78fa1d CY |
5 | ;; Package: pcomplete |
6 | ||
4fa9f636 GM |
7 | ;; This file is part of GNU Emacs. |
8 | ||
eb3fa2cf | 9 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
4fa9f636 | 10 | ;; it under the terms of the GNU General Public License as published by |
eb3fa2cf GM |
11 | ;; the Free Software Foundation, either version 3 of the License, or |
12 | ;; (at your option) any later version. | |
4fa9f636 GM |
13 | |
14 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;; GNU General Public License for more details. | |
18 | ||
19 | ;; You should have received a copy of the GNU General Public License | |
eb3fa2cf | 20 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
4fa9f636 | 21 | |
60370d40 PJ |
22 | ;;; Commentary: |
23 | ||
4fa9f636 GM |
24 | ;;; Code: |
25 | ||
4fa9f636 GM |
26 | (require 'pcomplete) |
27 | ||
28 | ;; User Variables: | |
29 | ||
30 | (defcustom pcmpl-unix-group-file "/etc/group" | |
1e2eefdd GM |
31 | "If non-nil, a string naming the group file on your system." |
32 | :type '(choice file (const nil)) | |
4fa9f636 GM |
33 | :group 'pcmpl-unix) |
34 | ||
35 | (defcustom pcmpl-unix-passwd-file "/etc/passwd" | |
1e2eefdd GM |
36 | "If non-nil, a string naming the passwd file on your system." |
37 | :type '(choice file (const nil)) | |
4fa9f636 GM |
38 | :group 'pcmpl-unix) |
39 | ||
9c519cf2 | 40 | (defcustom pcmpl-ssh-known-hosts-file "~/.ssh/known_hosts" |
1e2eefdd | 41 | "If non-nil, a string naming your SSH \"known_hosts\" file. |
6b072b27 PH |
42 | This allows one method of completion of SSH host names, the other |
43 | being via `pcmpl-ssh-config-file'. Note that newer versions of | |
44 | ssh hash the hosts by default, to prevent Island-hopping SSH | |
45 | attacks. This can be disabled, at some risk, with the SSH option | |
46 | \"HashKnownHosts no\"." | |
1e2eefdd GM |
47 | :type '(choice file (const nil)) |
48 | :group 'pcmpl-unix | |
49 | :version "23.1") | |
9c519cf2 | 50 | |
6b072b27 PH |
51 | (defcustom pcmpl-ssh-config-file "~/.ssh/config" |
52 | "If non-nil, a string naming your SSH \"config\" file. | |
53 | This allows one method of completion of SSH host names, the other | |
54 | being via `pcmpl-ssh-known-hosts-file'." | |
55 | :type '(choice file (const nil)) | |
56 | :group 'pcmpl-unix | |
57 | :version "24.1") | |
58 | ||
4fa9f636 GM |
59 | ;; Functions: |
60 | ||
61 | ;;;###autoload | |
62 | (defun pcomplete/cd () | |
63 | "Completion for `cd'." | |
f3b757f5 | 64 | (while (pcomplete-here (pcomplete-dirs)))) |
4fa9f636 GM |
65 | |
66 | ;;;###autoload | |
67 | (defalias 'pcomplete/pushd 'pcomplete/cd) | |
68 | ||
69 | ;;;###autoload | |
70 | (defun pcomplete/rmdir () | |
71 | "Completion for `rmdir'." | |
72 | (while (pcomplete-here (pcomplete-dirs)))) | |
73 | ||
74 | ;;;###autoload | |
75 | (defun pcomplete/rm () | |
76 | "Completion for `rm'." | |
77 | (let ((pcomplete-help "(fileutils)rm invocation")) | |
78 | (pcomplete-opt "dfirRv") | |
79 | (while (pcomplete-here (pcomplete-all-entries) nil | |
80 | 'expand-file-name)))) | |
81 | ||
82 | ;;;###autoload | |
83 | (defun pcomplete/xargs () | |
84 | "Completion for `xargs'." | |
85 | (pcomplete-here (funcall pcomplete-command-completion-function)) | |
86 | (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1)) | |
87 | pcomplete-default-completion-function))) | |
88 | ||
89 | ;;;###autoload | |
90 | (defalias 'pcomplete/time 'pcomplete/xargs) | |
91 | ||
92 | ;;;###autoload | |
93 | (defun pcomplete/which () | |
94 | "Completion for `which'." | |
95 | (while (pcomplete-here (funcall pcomplete-command-completion-function)))) | |
96 | ||
97 | (defun pcmpl-unix-read-passwd-file (file) | |
abd5cfe8 CY |
98 | "Return an alist correlating gids to group names in FILE. |
99 | ||
100 | If FILE is in hashed format (as described in the OpenSSH | |
101 | documentation), this function returns nil." | |
4fa9f636 GM |
102 | (let (names) |
103 | (when (file-readable-p file) | |
104 | (with-temp-buffer | |
105 | (insert-file-contents file) | |
106 | (goto-char (point-min)) | |
107 | (while (not (eobp)) | |
108 | (let* ((fields | |
109 | (split-string (buffer-substring | |
110 | (point) (progn (end-of-line) | |
111 | (point))) ":"))) | |
112 | (setq names (cons (nth 0 fields) names))) | |
113 | (forward-line)))) | |
114 | (pcomplete-uniqify-list names))) | |
115 | ||
116 | (defsubst pcmpl-unix-group-names () | |
117 | "Read the contents of /etc/group for group names." | |
118 | (if pcmpl-unix-group-file | |
119 | (pcmpl-unix-read-passwd-file pcmpl-unix-group-file))) | |
120 | ||
121 | (defsubst pcmpl-unix-user-names () | |
122 | "Read the contents of /etc/passwd for user names." | |
123 | (if pcmpl-unix-passwd-file | |
124 | (pcmpl-unix-read-passwd-file pcmpl-unix-passwd-file))) | |
125 | ||
126 | ;;;###autoload | |
127 | (defun pcomplete/chown () | |
128 | "Completion for the `chown' command." | |
129 | (unless (pcomplete-match "\\`-") | |
130 | (if (pcomplete-match "\\`[^.]*\\'" 0) | |
131 | (pcomplete-here* (pcmpl-unix-user-names)) | |
132 | (if (pcomplete-match "\\.\\([^.]*\\)\\'" 0) | |
133 | (pcomplete-here* (pcmpl-unix-group-names) | |
134 | (pcomplete-match-string 1 0)) | |
135 | (pcomplete-here*)))) | |
136 | (while (pcomplete-here (pcomplete-entries)))) | |
137 | ||
138 | ;;;###autoload | |
139 | (defun pcomplete/chgrp () | |
140 | "Completion for the `chgrp' command." | |
141 | (unless (pcomplete-match "\\`-") | |
142 | (pcomplete-here* (pcmpl-unix-group-names))) | |
143 | (while (pcomplete-here (pcomplete-entries)))) | |
144 | ||
1e2eefdd | 145 | |
9c519cf2 GM |
146 | ;; ssh support by Phil Hagelberg. |
147 | ;; http://www.emacswiki.org/cgi-bin/wiki/pcmpl-ssh.el | |
148 | ||
6b072b27 | 149 | (defun pcmpl-ssh-known-hosts () |
1e2eefdd GM |
150 | "Return a list of hosts found in `pcmpl-ssh-known-hosts-file'." |
151 | (when (and pcmpl-ssh-known-hosts-file | |
152 | (file-readable-p pcmpl-ssh-known-hosts-file)) | |
153 | (with-temp-buffer | |
154 | (insert-file-contents-literally pcmpl-ssh-known-hosts-file) | |
7dd37071 ML |
155 | (let ((host-re "\\(?:\\([-.[:alnum:]]+\\)\\|\\[\\([-.[:alnum:]]+\\)\\]:[0-9]+\\)[, ]") |
156 | ssh-hosts-list) | |
157 | (while (re-search-forward (concat "^ *" host-re) nil t) | |
158 | (add-to-list 'ssh-hosts-list (concat (match-string 1) | |
159 | (match-string 2))) | |
1e2eefdd | 160 | (while (and (looking-back ",") |
7dd37071 ML |
161 | (re-search-forward host-re (line-end-position) t)) |
162 | (add-to-list 'ssh-hosts-list (concat (match-string 1) | |
163 | (match-string 2))))) | |
1e2eefdd | 164 | ssh-hosts-list)))) |
9c519cf2 | 165 | |
6b072b27 PH |
166 | (defun pcmpl-ssh-config-hosts () |
167 | "Return a list of hosts found in `pcmpl-ssh-config-file'." | |
168 | (when (and pcmpl-ssh-config-file | |
169 | (file-readable-p pcmpl-ssh-config-file)) | |
170 | (with-temp-buffer | |
171 | (insert-file-contents-literally pcmpl-ssh-config-file) | |
172 | (let (ssh-hosts-list | |
173 | (case-fold-search t)) | |
174 | (while (re-search-forward "^ *host\\(name\\)? +\\([-.[:alnum:]]+\\)" | |
175 | nil t) | |
176 | (add-to-list 'ssh-hosts-list (match-string 2))) | |
177 | ssh-hosts-list)))) | |
178 | ||
179 | (defun pcmpl-ssh-hosts () | |
180 | "Return a list of known SSH hosts. | |
181 | Uses both `pcmpl-ssh-config-file' and `pcmpl-ssh-known-hosts-file'." | |
182 | (let ((hosts (pcmpl-ssh-known-hosts))) | |
183 | (dolist (h (pcmpl-ssh-config-hosts)) | |
184 | (add-to-list 'hosts h)) | |
185 | hosts)) | |
186 | ||
9c519cf2 GM |
187 | ;;;###autoload |
188 | (defun pcomplete/ssh () | |
189 | "Completion rules for the `ssh' command." | |
3d1337be | 190 | (pcomplete-opt "1246AaCfgKkMNnqsTtVvXxYbcDeFiLlmOopRSw") |
9c519cf2 GM |
191 | (pcomplete-here (pcmpl-ssh-hosts))) |
192 | ||
193 | ;;;###autoload | |
194 | (defun pcomplete/scp () | |
195 | "Completion rules for the `scp' command. | |
9c519cf2 GM |
196 | Includes files as well as host names followed by a colon." |
197 | (pcomplete-opt "1246BCpqrvcFiloPS") | |
915a9b64 SM |
198 | (while t (pcomplete-here |
199 | (lambda (string pred action) | |
200 | (let ((table | |
201 | (cond | |
202 | ((string-match "\\`[^:/]+:" string) ; Remote file name. | |
203 | (if (and (eq action 'lambda) | |
204 | (eq (match-end 0) (length string))) | |
205 | ;; Avoid connecting to the remote host when we're | |
206 | ;; only completing the host name. | |
207 | (list string) | |
208 | (comint--table-subvert (pcomplete-all-entries) | |
209 | "" "/ssh:"))) | |
210 | ((string-match "/" string) ; Local file name. | |
211 | (pcomplete-all-entries)) | |
212 | (t ;Host name or local file name. | |
213 | (append (all-completions string (pcomplete-all-entries)) | |
214 | (mapcar (lambda (host) (concat host ":")) | |
215 | (pcmpl-ssh-hosts))))))) | |
216 | (complete-with-action action table string pred)))))) | |
9c519cf2 | 217 | |
1e2eefdd GM |
218 | (provide 'pcmpl-unix) |
219 | ||
4fa9f636 | 220 | ;;; pcmpl-unix.el ends here |