From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2700 invoked by alias); 22 Mar 2018 01:10:26 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 42491 Received: (qmail 7273 invoked by uid 1010); 22 Mar 2018 01:10:26 -0000 X-Qmail-Scanner-Diagnostics: from park01.gkg.net by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(205.235.26.22):SA:0(-1.4/5.0):. Processed in 2.294067 secs); 22 Mar 2018 01:10:26 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,SPF_PASS,T_DKIM_INVALID,T_RP_MATCHES_RCVD autolearn=no autolearn_force=no version=3.4.1 X-Envelope-From: SRS0=BFS/=GM=yahoo.co.uk=okiddle@bounces.park01.gkg.net X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | X-Virus-Scanned: by amavisd-new at gkg.net Authentication-Results: amavisd4.gkg.net (amavisd-new); dkim=pass (2048-bit key) header.d=yahoo.co.uk X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1521681002; bh=EGdLIIjaaOLPCEj8q1Cdu2GReOB40WrcjS48IQTXMlk=; h=From:References:To:Subject:Date:From:Subject; b=bIDPUh+GbszPDlAHXp/Ahey9AqB5KbtYkNhy4KhlNq1aefvIjrDMfvOnJOs5cxkiUR4FxLXvNkgcs46LElD7IPPD6njzeWVtwxNbb8HwWCR3jwy+drsvkFnlO3P+b8zL5HXaNYducnAwgWNMnZOmYe3HN7VFP3mNpe8ima4U2uaRHv1spJUe/akWd6UHKaG56bcAgNE4JXQndooPIuEXsRVLtP6UWZUIidNbaYOKqrT55UWp+BfAJRIKBUnmSIoKf1g6IF5RnyS4kh/z+pbsoJ2kDLMPQT8kdd82PlbWme5qH+qKZ8wFWyPI9s/NCU27ZnZiOU+8R8ZA+dGHJNBnsA== X-YMail-OSG: Hh7vfrkVM1kJc9gziodJdM6xWs_FwKsK5zVCtqZhf28bC.zHfLhLlEKcJV13bo5 e_K0pWaDZLjtsuNFyaonDnsBAa600RwTaF03N6Ykm6rimKW_HrZlLunwHFLZkW2tbbtsFAgKtnPW xxFPVqazId.8FhktxmsFOKQX5.XSif4BdWshTjRAjv3hqnBiwPtai0CM8I0iCiN057VaDEilhhNB Y07XslFvpxvZK.a7q9YQASicIaK77_0_dpiQV7fDCPHvNHuo9yniamqUFnC4iSu8G4kqw6aNxGbr EKB00JCkF_wsY46eJ3iEWH2dHfebA8VOWJHpxGje7RRntAQ8G9yDvgSxqxW_rqQpwTmtL0JF2nv1 sgb1QlQNkrnn8.GhtbB0KdShh5BkbQjNmZOwPWT2R95M8msxxPUo1S3QUNNzPcWPTGnofsIaiPfo e9LYkZMi0VueqsChsPLf0P6ZduLwfBRjv2juvMnq5x4ouZdMyWkGqfZfuryD3D68CuBnaRqsax4L w1W47NsKLUw-- In-reply-to: <1510274104.17218.0@smtp.gmail.com> From: Oliver Kiddle References: <1510274104.17218.0@smtp.gmail.com> To: zsh-workers@zsh.org Subject: Re: PATCH: Improve Mosh completion MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <26124.1521680997.1@thecus> Date: Thu, 22 Mar 2018 02:09:57 +0100 Message-ID: <26125.1521680997@thecus> On 10 Nov, Andrei Shevchuk wrote: > This adds ~/.ssh/config based completion support (_ssh_hosts and > _ssh_users functions and userhost state handling taken without > modifications from ssh completion file), existing code was just wrapped > into _mosh function without modifications (except userhost state > handling mentioned above). Daniel and I commented here and on github at the time that it'd be nicer to factor _ssh_hosts out than to duplicate it. In fact _git also makes use of _ssh_hosts. So this is a fresh patch based on the original. It also made no sense to check $opt_args[-l] for mosh as mosh doesn't have a -l option. I'm not so sure about _ssh_users. I've expanded it inline in _mosh here. I've never been entirely happy with the way _combination works for one thing. For ssh, it is mostly sensible to configure usernames in .ssh/config anyway so usernames are only relevant when using more than one on a remote machine. The users-hosts style also disables completion of hosts from .ssh/config. Given an ssh configuration of: ControlPath /tmp/ssh-%r@%h:%p It'd be useful to complete established connections conveniently, especially for scp. So, I can try: zstyle -e ':completion:*:(scp|ssh):*:my-accounts' users-hosts \ 'reply=( /tmp/ssh-*@*:*(=N) ); reply=( ${${${reply:t}#*-}%:*} )' That still breaks up username and hostname completion, requiring two tabs but also blocks normal completion of hosts from .ssh/config Oliver diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 30ca80835..dccbcc67f 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -6897,10 +6897,6 @@ __git_tree_files () { (( $+functions[__git_remote_repositories] )) || __git_remote_repositories () { - local service - - service= _ssh - if compset -P '*:'; then _remote_files -/ -- ssh else diff --git a/Completion/Unix/Command/_mosh b/Completion/Unix/Command/_mosh index 431fdbf9e..aa97587bb 100644 --- a/Completion/Unix/Command/_mosh +++ b/Completion/Unix/Command/_mosh @@ -1,6 +1,6 @@ #compdef mosh -local curcontext="$curcontext" state line +local curcontext="$curcontext" state line expl ret=1 local -a _comp_priv_prefix _arguments -C \ @@ -15,12 +15,20 @@ _arguments -C \ '--server[specify command to run server helper]:remote file:_files' \ '--client[specify command to run client helper]:_command_names -e' \ '1:remote host name:->userhost' \ - '*:::args:_normal' && return + '*:::args:_normal' && ret=0 case $state in userhost) - _hosts || _user_at_host && return + if compset -P '*@'; then + _wanted hosts expl 'remote host name' _ssh_hosts && ret=0 + elif compset -S '@*'; then + _wanted users expl 'login name' _combination -s '[:@]' my-accounts users-hosts users -S '' && ret=0 + else + _alternative \ + 'hosts:remote host name:_ssh_hosts' \ + 'users:login name:_combination -s "[:@]" my-accounts users-hosts users -qS@' && ret=0 + fi ;; esac -return 1 +return ret diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh index 8a122a5b3..20a5536ee 100644 --- a/Completion/Unix/Command/_ssh +++ b/Completion/Unix/Command/_ssh @@ -647,46 +647,4 @@ _ssh_users () { _combination -s '[:@]' my-accounts users-hosts users "$@" } -_ssh_hosts () { - local -a config_hosts - local config - integer ind - - # If users-hosts matches, we shouldn't complete anything else. - if [[ "$IPREFIX" == *@ ]]; then - _combination -s '[:@]' my-accounts users-hosts "users=${IPREFIX/@}" hosts "$@" && return - else - _combination -s '[:@]' my-accounts users-hosts \ - ${opt_args[-l]:+"users=${opt_args[-l]:q}"} hosts "$@" && return - fi - if (( ind = ${words[(I)-F]} )); then - config=${~words[ind+1]} 2>/dev/null - else - config="$HOME/.ssh/config" - fi - if [[ -r $config ]]; then - local key line host - local -a lines=("${(@f)$(<"$config")}") 2>/dev/null - while (($#lines)); do - IFS=$'=\t ' read -r key line <<<"${lines[1]}" - case "$key" in - ((#i)include) - lines[1]=("${(@f)$(cd $HOME/.ssh; cat ${(z)~line})}") 2>/dev/null;; - ((#i)host(|name)) - for host in ${(z)line}; do - case $host in - (*[*?]*) ;; - (*) config_hosts+=("$host") ;; - esac - done ;& - (*) shift lines;; - esac - done - if (( ${#config_hosts} )); then - _wanted hosts expl 'remote host name' \ - compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" $config_hosts - fi - fi -} - _ssh "$@" diff --git a/Completion/Unix/Type/_ssh_hosts b/Completion/Unix/Type/_ssh_hosts new file mode 100644 index 000000000..e20142cfd --- /dev/null +++ b/Completion/Unix/Type/_ssh_hosts @@ -0,0 +1,41 @@ +#autoload + +local -a config_hosts +local config +integer ind + +# If users-hosts matches, we shouldn't complete anything else. +if [[ "$IPREFIX" == *@ ]]; then + _combination -s '[:@]' my-accounts users-hosts "users=${IPREFIX/@}" hosts "$@" && return +else + _combination -s '[:@]' my-accounts users-hosts \ + ${opt_args[-l]:+"users=${opt_args[-l]:q}"} hosts "$@" && return +fi +if (( ind = ${words[(I)-F]} )); then + config=${~words[ind+1]} 2>/dev/null +else + config="$HOME/.ssh/config" +fi +if [[ -r $config ]]; then + local key line host + local -a lines=("${(@f)$(<"$config")}") 2>/dev/null + while (($#lines)); do + IFS=$'=\t ' read -r key line <<<"${lines[1]}" + case "$key" in + ((#i)include) + lines[1]=("${(@f)$(cd $HOME/.ssh; cat ${(z)~line})}") 2>/dev/null;; + ((#i)host(|name)) + for host in ${(z)line}; do + case $host in + (*[*?]*) ;; + (*) config_hosts+=("$host") ;; + esac + done ;& + (*) shift lines;; + esac + done + if (( ${#config_hosts} )); then + _wanted hosts expl 'remote host name' \ + compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" $config_hosts + fi +fi