X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/4586442a5abbb9ccd6e7c4de0730763c0170cc12..f82248004d0f5ef84bbe03d83467bb3c43afa765:/lisp/pcmpl-unix.el diff --git a/lisp/pcmpl-unix.el b/lisp/pcmpl-unix.el index 9cd5de1e4d..d4939d8d17 100644 --- a/lisp/pcmpl-unix.el +++ b/lisp/pcmpl-unix.el @@ -1,14 +1,15 @@ ;;; pcmpl-unix.el --- standard UNIX completions -;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, -;; 2005, 2006, 2007 Free Software Foundation, Inc. +;; Copyright (C) 1999-2016 Free Software Foundation, Inc. + +;; Package: pcomplete ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,36 +17,51 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: ;;; Code: -(provide 'pcmpl-unix) - (require 'pcomplete) ;; User Variables: (defcustom pcmpl-unix-group-file "/etc/group" - "*If non-nil, a string naming the group file on your system." - :type 'file + "If non-nil, a string naming the group file on your system." + :type '(choice file (const nil)) :group 'pcmpl-unix) (defcustom pcmpl-unix-passwd-file "/etc/passwd" - "*If non-nil, a string naming the passwd file on your system." - :type 'file + "If non-nil, a string naming the passwd file on your system." + :type '(choice file (const nil)) :group 'pcmpl-unix) +(defcustom pcmpl-ssh-known-hosts-file "~/.ssh/known_hosts" + "If non-nil, a string naming your SSH \"known_hosts\" file. +This allows one method of completion of SSH host names, the other +being via `pcmpl-ssh-config-file'. Note that newer versions of +ssh hash the hosts by default, to prevent Island-hopping SSH +attacks. This can be disabled, at some risk, with the SSH option +\"HashKnownHosts no\"." + :type '(choice file (const nil)) + :group 'pcmpl-unix + :version "23.1") + +(defcustom pcmpl-ssh-config-file "~/.ssh/config" + "If non-nil, a string naming your SSH \"config\" file. +This allows one method of completion of SSH host names, the other +being via `pcmpl-ssh-known-hosts-file'." + :type '(choice file (const nil)) + :group 'pcmpl-unix + :version "24.1") + ;; Functions: ;;;###autoload (defun pcomplete/cd () "Completion for `cd'." - (pcomplete-here (pcomplete-dirs))) + (while (pcomplete-here (pcomplete-dirs)))) ;;;###autoload (defalias 'pcomplete/pushd 'pcomplete/cd) @@ -79,7 +95,10 @@ (while (pcomplete-here (funcall pcomplete-command-completion-function)))) (defun pcmpl-unix-read-passwd-file (file) - "Return an alist correlating gids to group names in FILE." + "Return an alist correlating gids to group names in FILE. + +If FILE is in hashed format (as described in the OpenSSH +documentation), this function returns nil." (let (names) (when (file-readable-p file) (with-temp-buffer @@ -123,5 +142,79 @@ (pcomplete-here* (pcmpl-unix-group-names))) (while (pcomplete-here (pcomplete-entries)))) -;;; arch-tag: 3f9eb5af-7e0e-449d-b586-381cbbf8fc5c + +;; ssh support by Phil Hagelberg. +;; http://www.emacswiki.org/cgi-bin/wiki/pcmpl-ssh.el + +(defun pcmpl-ssh-known-hosts () + "Return a list of hosts found in `pcmpl-ssh-known-hosts-file'." + (when (and pcmpl-ssh-known-hosts-file + (file-readable-p pcmpl-ssh-known-hosts-file)) + (with-temp-buffer + (insert-file-contents-literally pcmpl-ssh-known-hosts-file) + (let ((host-re "\\(?:\\([-.[:alnum:]]+\\)\\|\\[\\([-.[:alnum:]]+\\)\\]:[0-9]+\\)[, ]") + ssh-hosts-list) + (while (re-search-forward (concat "^ *" host-re) nil t) + (add-to-list 'ssh-hosts-list (concat (match-string 1) + (match-string 2))) + (while (and (eq (char-before) ?,) + (re-search-forward host-re (line-end-position) t)) + (add-to-list 'ssh-hosts-list (concat (match-string 1) + (match-string 2))))) + ssh-hosts-list)))) + +(defun pcmpl-ssh-config-hosts () + "Return a list of hosts found in `pcmpl-ssh-config-file'." + (when (and pcmpl-ssh-config-file + (file-readable-p pcmpl-ssh-config-file)) + (with-temp-buffer + (insert-file-contents-literally pcmpl-ssh-config-file) + (let (ssh-hosts-list + (case-fold-search t)) + (while (re-search-forward "^ *host\\(name\\)? +\\([-.[:alnum:]]+\\)" + nil t) + (add-to-list 'ssh-hosts-list (match-string 2))) + ssh-hosts-list)))) + +(defun pcmpl-ssh-hosts () + "Return a list of known SSH hosts. +Uses both `pcmpl-ssh-config-file' and `pcmpl-ssh-known-hosts-file'." + (let ((hosts (pcmpl-ssh-known-hosts))) + (dolist (h (pcmpl-ssh-config-hosts)) + (add-to-list 'hosts h)) + hosts)) + +;;;###autoload +(defun pcomplete/ssh () + "Completion rules for the `ssh' command." + (pcomplete-opt "1246AaCfgKkMNnqsTtVvXxYbcDeFiLlmOopRSw") + (pcomplete-here (pcmpl-ssh-hosts))) + +;;;###autoload +(defun pcomplete/scp () + "Completion rules for the `scp' command. +Includes files as well as host names followed by a colon." + (pcomplete-opt "1246BCpqrvcFiloPS") + (while t (pcomplete-here + (lambda (string pred action) + (let ((table + (cond + ((string-match "\\`[^:/]+:" string) ; Remote file name. + (if (and (eq action 'lambda) + (eq (match-end 0) (length string))) + ;; Avoid connecting to the remote host when we're + ;; only completing the host name. + (list string) + (completion-table-subvert (pcomplete-all-entries) + "" "/ssh:"))) + ((string-match "/" string) ; Local file name. + (pcomplete-all-entries)) + (t ;Host name or local file name. + (append (all-completions string (pcomplete-all-entries)) + (mapcar (lambda (host) (concat host ":")) + (pcmpl-ssh-hosts))))))) + (complete-with-action action table string pred)))))) + +(provide 'pcmpl-unix) + ;;; pcmpl-unix.el ends here