use re use str use moi/util/condition use moi/util/file use moi/util/ip use moi/util/list use moi/util/map use moi/util/option var options-ssh = [ 1 2 4 6 A D f g I i L l m o v a b C c e F k N n p q R s T t X x ] var options-scp = [ 3 4 6 B C p q r v c F i l o P S ] var names = [ benjamin luence ] fn -kh { cat ~/.ssh/known_hosts | peach [l]{ put [(str:split ' ' $l)] } | peach [e]{ var domains @_ = $@e str:split ',' $domains } } fn -port [cmd @argv]{ var o = (condition:cset (eq $cmd 'ssh') '-p' '-P') var margs = (option:map $argv) var p = (map:value-of $margs $o &default=[]) if (list:empty $p) { put 22 } else { put $p[-1] } } fn -complete-names []{ each [n]{ put $n'@' } $names } fn -complete-domains [name hosts]{ each [h]{ put $name@$h } $hosts } fn -complete-remote-dir [port address dir]{ try { ssh -p $port $address 'ls '$dir | each [f]{ put $address':'$dir$f } } except e { } } fn -complete-args [hosts cmd @argv]{ var arg = $argv[-1] var i = (str:index $arg @) if (< $i 0) { -complete-names all $hosts if (eq $cmd scp) { edit:complete-filename $cmd $@argv } return } var n h = $arg[..$i] $arg[(+ $i 1)..] if (eq $cmd scp) { set i = (str:index $h :) if (>= $i 0) { var d = $h[(+ $i 1)..] set h = $h[..$i] if (list:includes $h $hosts) { var p = (-port $cmd @argv) var e = [ (str:split / $d) ] if (not-eq $e[-1] '') { set d = (str:join / $e[..-1]) if (eq $d '') { set d = / } } -complete-remote-dir $p $n@$h $d } return } } -complete-domains $n $hosts } fn complete [@argv]{ var @hosts = (-kh) var cmd = $argv[0] var is-ssh = (eq $cmd ssh) var po = (condition:cset $is-ssh -p -P) if (<= (count $argv) 2) { all (condition:cset $is-ssh $options-ssh $options-scp) -complete-args $hosts $@argv } elif (eq $argv[-2] $po) { put 22 } else { -complete-args $hosts $@argv } } set edit:completion:arg-completer[scp] = $complete~ set edit:completion:arg-completer[ssh] = $complete~