1
Fork 0
mirror of https://github.com/RGBCube/nu_scripts synced 2025-08-02 07:07:46 +00:00

upgrade to nu 0.77 (#413)

* auto detect docker cli

* rename just to main

* upgrade ssh

* upgrade kubernetes

* upgrade nvim.nu

* upgrade git

* rename index-need-update to ensure-index

* new command `after`

---------

Co-authored-by: agent <agent@nuc>
This commit is contained in:
fj0r 2023-03-15 21:29:32 +08:00 committed by GitHub
parent 10bde0657d
commit 2024d52938
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 138 additions and 109 deletions

9
after/after.nu Normal file
View file

@ -0,0 +1,9 @@
def "nu-complete ps" [] {
ps | each {|x| { value: $x.pid, description: $x.name } }
}
# after <pid> { do something ... }
export def after [pid: string@"nu-complete ps" action ] {
do -i { tail --pid $pid -f /dev/null }
do $action
}

View file

@ -1,13 +1,15 @@
export def has [name] { export-env {
$name in ($in | columns) and (not ($in | get $name | is-empty)) for c in [podman nerdctl docker] {
if not (whereis $c | parse -r '.+: (.+)' | is-empty) {
let-env docker-cli = $c
break
}
}
} }
alias docker = podman
export def dp [] { export def dp [] {
# docker ps --all --no-trunc --format='{{json .}}' | jq # ^$env.docker-cli ps --all --no-trunc --format='{{json .}}' | jq
docker ps -a --format '{"id":"{{.ID}}", "image": "{{.Image}}", "name":"{{.Names}}", "cmd":"{{.Command}}", "port":"{{.Ports}}", "status":"{{.Status}}", "created":"{{.Created}}"}' ^$env.docker-cli ps -a --format '{"id":"{{.ID}}", "image": "{{.Image}}", "name":"{{.Names}}", "cmd":"{{.Command}}", "port":"{{.Ports}}", "status":"{{.Status}}", "created":"{{.Created}}"}'
| lines | lines
| each {|x| | each {|x|
let r = ($x | from json) let r = ($x | from json)
@ -17,39 +19,52 @@ export def dp [] {
} }
export def di [] { export def di [] {
docker images ^$env.docker-cli images
| from ssv -a | from ssv -a
| rename repo tag id created size | rename repo tag id created size
| upsert size { |i| $i.size | into filesize } | each {|x|
let size = ($x.size | into filesize)
let path = ($x.repo | split row '/')
let image = ($path | last)
let repo = ($path | range ..(($path|length) - 2) | str join '/')
{
repo: $repo
image: $image
tag: $x.tag
id: $x.id
created: $x.created
size: $size
}
}
} }
def "nu-complete docker ps" [] { def "nu-complete docker ps" [] {
docker ps ^$env.docker-cli ps
| from ssv -a | from ssv -a
| each {|x| {description: $x.NAMES value: $x.'CONTAINER ID'}} | each {|x| {description: $x.NAMES value: $x.'CONTAINER ID'}}
} }
def "nu-complete docker container" [] { def "nu-complete docker container" [] {
docker ps ^$env.docker-cli ps
| from ssv -a | from ssv -a
| each {|x| {description: $x.'CONTAINER ID' value: $x.NAMES}} | each {|x| {description: $x.'CONTAINER ID' value: $x.NAMES}}
} }
def "nu-complete docker all container" [] { def "nu-complete docker all container" [] {
docker ps -a ^$env.docker-cli ps -a
| from ssv -a | from ssv -a
| each {|x| {description: $x.'CONTAINER ID' value: $x.NAMES}} | each {|x| {description: $x.'CONTAINER ID' value: $x.NAMES}}
} }
def "nu-complete docker images" [] { def "nu-complete docker images" [] {
docker images ^$env.docker-cli images
| from ssv | from ssv
| each {|x| $"($x.REPOSITORY):($x.TAG)"} | each {|x| $"($x.REPOSITORY):($x.TAG)"}
} }
export def dl [ctn: string@"nu-complete docker container" -n: int = 100] { export def dl [ctn: string@"nu-complete docker container" -n: int = 100] {
let n = if $n == 0 { [] } else { [--tail $n] } let n = if $n == 0 { [] } else { [--tail $n] }
docker logs -f $n $ctn ^$env.docker-cli logs -f $n $ctn
} }
export def da [ export def da [
@ -57,9 +72,9 @@ export def da [
...args ...args
] { ] {
if ($args|is-empty) { if ($args|is-empty) {
docker exec -it $ctn /bin/sh -c "[ -e /bin/zsh ] && /bin/zsh || [ -e /bin/bash ] && /bin/bash || /bin/sh" ^$env.docker-cli exec -it $ctn /bin/sh -c "[ -e /bin/zsh ] && /bin/zsh || [ -e /bin/bash ] && /bin/bash || /bin/sh"
} else { } else {
docker exec -it $ctn $args ^$env.docker-cli exec -it $ctn $args
} }
} }
@ -67,13 +82,13 @@ def "nu-complete docker cp" [cmd: string, offset: int] {
let argv = ($cmd | str substring [0 $offset] | split row ' ') let argv = ($cmd | str substring [0 $offset] | split row ' ')
let p = if ($argv | length) > 2 { $argv | get 2 } else { $argv | get 1 } let p = if ($argv | length) > 2 { $argv | get 2 } else { $argv | get 1 }
let ctn = ( let ctn = (
docker ps ^$env.docker-cli ps
| from ssv -a | from ssv -a
| each {|x| {description: $x.'CONTAINER ID' value: $"($x.NAMES):" }} | each {|x| {description: $x.'CONTAINER ID' value: $"($x.NAMES):" }}
) )
let n = ($p | split row ':') let n = ($p | split row ':')
if $"($n | get 0):" in ($ctn | get value) { if $"($n | get 0):" in ($ctn | get value) {
docker exec ($n | get 0) sh -c $"ls -dp ($n | get 1)*" ^$env.docker-cli exec ($n | get 0) sh -c $"ls -dp ($n | get 1)*"
| lines | lines
| each {|x| $"($n | get 0):($x)"} | each {|x| $"($n | get 0):($x)"}
} else { } else {
@ -89,50 +104,50 @@ export def dcp [
lhs: string@"nu-complete docker cp", lhs: string@"nu-complete docker cp",
rhs: string@"nu-complete docker cp" rhs: string@"nu-complete docker cp"
] { ] {
docker cp $lhs $rhs ^$env.docker-cli cp $lhs $rhs
} }
export def dcr [ctn: string@"nu-complete docker all container"] { export def dcr [ctn: string@"nu-complete docker all container"] {
docker container rm -f $ctn ^$env.docker-cli container rm -f $ctn
} }
export def dis [img: string@"nu-complete docker images"] { export def dis [img: string@"nu-complete docker images"] {
docker inspect $img ^$env.docker-cli inspect $img
} }
export def dh [img: string@"nu-complete docker images"] { export def dh [img: string@"nu-complete docker images"] {
docker history --no-trunc $img | from ssv -a ^$env.docker-cli history --no-trunc $img | from ssv -a
} }
export def dsv [...img: string@"nu-complete docker images"] { export def dsv [...img: string@"nu-complete docker images"] {
docker save $img ^$env.docker-cli save $img
} }
export alias dld = podman load export alias dld = podman load
export def dsp [] { export def dsp [] {
docker system prune -f ^$env.docker-cli system prune -f
} }
export alias dspall = podman system prune --all --force --volumes export alias dspall = podman system prune --all --force --volumes
export def drmi [img: string@"nu-complete docker images"] { export def drmi [img: string@"nu-complete docker images"] {
docker rmi $img ^$env.docker-cli rmi $img
} }
export def dt [from: string@"nu-complete docker images" to: string] { export def dt [from: string@"nu-complete docker images" to: string] {
docker tag $from $to ^$env.docker-cli tag $from $to
} }
export def dps [img: string@"nu-complete docker images"] { export def dps [img: string@"nu-complete docker images"] {
docker push $img ^$env.docker-cli push $img
} }
export alias dpl = podman pull export alias dpl = podman pull
### volume ### volume
export def dvl [] { export def dvl [] {
docker volume ls | from ssv -a ^$env.docker-cli volume ls | from ssv -a
} }
def "nu-complete docker volume" [] { def "nu-complete docker volume" [] {
@ -140,15 +155,15 @@ def "nu-complete docker volume" [] {
} }
export def dvc [name: string] { export def dvc [name: string] {
docker volume create ^$env.docker-cli volume create
} }
export def dvi [name: string@"nu-complete docker volume"] { export def dvi [name: string@"nu-complete docker volume"] {
docker volume inspect $name ^$env.docker-cli volume inspect $name
} }
export def dvr [...name: string@"nu-complete docker volume"] { export def dvr [...name: string@"nu-complete docker volume"] {
docker volume rm $name ^$env.docker-cli volume rm $name
} }
### run ### run
@ -211,7 +226,7 @@ export def dr [
let netadmin = if $netadmin { [--cap-add=NET_ADMIN --device /dev/net/tun] } else { [] } let netadmin = if $netadmin { [--cap-add=NET_ADMIN --device /dev/net/tun] } else { [] }
let clip = if $with_x { [-e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix] } else { [] } let clip = if $with_x { [-e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix] } else { [] }
let ssh = if ($ssh|is-empty) { [] } else { let ssh = if ($ssh|is-empty) { [] } else {
let sshkey = (cat ([~/.ssh $ssh] | path join) | split row ' ' | get 1) let sshkey = (cat ([$env.HOME .ssh $ssh] | path join) | split row ' ' | get 1)
[-e $"ed25519_($sshuser)=($sshkey)"] [-e $"ed25519_($sshuser)=($sshkey)"]
} }
let proxy = if ($proxy|is-empty) { [] } else { let proxy = if ($proxy|is-empty) { [] } else {
@ -227,7 +242,7 @@ export def dr [
if $dry_run { if $dry_run {
echo $"docker run --name ($name) ($args|str join ' ') ($img) ($cmd | flatten)" echo $"docker run --name ($name) ($args|str join ' ') ($img) ($cmd | flatten)"
} else { } else {
docker run --name $name $args $img ($cmd | flatten) ^$env.docker-cli run --name $name $args $img ($cmd | flatten)
} }
} }
@ -247,23 +262,25 @@ export def dx [
...cmd # command args ...cmd # command args
] { ] {
let __dx_cache = { let __dx_cache = {
hs: 'stack:/opt/stack' hs: 'stack:/opt/stack'
rs: 'cargo:/opt/cargo' rs: 'cargo:/opt/cargo'
go: 'gopkg:/opt/gopkg' go: 'gopkg:/opt/go/pkg'
ng: 'ng:/srv' ng: 'ng:/srv'
pg: 'pg:/var/lib/postgresql/data' pg: 'pg:/var/lib/postgresql/data'
} }
let c = do -i {$__dx_cache | transpose k v | where {|x| $dx | str contains $x.k} | get v.0} let c = do -i {$__dx_cache | transpose k v | where {|x| $dx | str contains $x.k} | get v.0}
let c = if ($c|is-empty) { '' } else if $mount_cache { let c = if ($c|is-empty) {
let c = ( $c ''
| split row ':' } else if $mount_cache {
| each -n {|x| if $x.index == 1 { $"/cache($x.item)" } else { $x.item } } let c = ( $c
| str join ':' | split row ':'
) | each {|x i| if $i == 1 { $"/cache($x)" } else { $x } }
$"($env.HOME)/.cache/($c)" | str join ':'
} else { )
$"($env.HOME)/.cache/($c)" $"($env.HOME)/.cache/($c)"
} } else {
$"($env.HOME)/.cache/($c)"
}
let proxy = if ($proxy|is-empty) { [] } else { [--proxy $proxy] } let proxy = if ($proxy|is-empty) { [] } else { [--proxy $proxy] }
if $dry_run { if $dry_run {
print $"cache: ($c)" print $"cache: ($c)"
@ -281,16 +298,16 @@ def "nu-complete registry list" [cmd: string, offset: int] {
let tag = do -i { $cmd | get 4 } let tag = do -i { $cmd | get 4 }
if ($reg|is-empty) { if ($reg|is-empty) {
if ($env | has 'REGISTRY_TOKEN') { if ($env | has 'REGISTRY_TOKEN') {
fetch -H [authorization $"Basic ($env.REGISTRY_TOKEN)"] $"($url)/v2/_catalog" http get -H [authorization $"Basic ($env.REGISTRY_TOKEN)"] $"($url)/v2/_catalog"
} else { } else {
fetch $"($url)/v2/_catalog" http get $"($url)/v2/_catalog"
} }
| get repositories | get repositories
} else if ($tag|is-empty) { } else if ($tag|is-empty) {
if ($env | has 'REGISTRY_TOKEN') { if ($env | has 'REGISTRY_TOKEN') {
fetch $"($url)/v2/($reg)/tags/list" http get $"($url)/v2/($reg)/tags/list"
} else { } else {
fetch -H [authorization $"Basic ($env.REGISTRY_TOKEN)"] $"($url)/v2/($reg)/tags/list" http get -H [authorization $"Basic ($env.REGISTRY_TOKEN)"] $"($url)/v2/($reg)/tags/list"
} }
| get tags | get tags
} }
@ -301,10 +318,10 @@ export def "registry list" [
url: string url: string
reg: string@"nu-complete registry list" reg: string@"nu-complete registry list"
] { ] {
if ('REGISTRY_TOKEN' in (env).name) { if ('REGISTRY_TOKEN' in ($env | columns)) {
fetch -H [authorization $"Basic ($env.REGISTRY_TOKEN)"] $"($url)/v2/($reg)/tags/list" http get -H [authorization $"Basic ($env.REGISTRY_TOKEN)"] $"($url)/v2/($reg)/tags/list"
} else { } else {
fetch $"($url)/v2/($reg)/tags/list" http get $"($url)/v2/($reg)/tags/list"
} }
| get tags | get tags
} }

View file

@ -80,6 +80,7 @@ export def glgv [
} }
export def gpp! [] { export def gpp! [] {
git pull
git add --all git add --all
git commit -v -a --no-edit --amend git commit -v -a --no-edit --amend
git push --force git push --force
@ -111,11 +112,6 @@ export def gm [branch:string@"nu-complete git branches"] {
git merge $branch git merge $branch
} }
extern "git reset" [
sha?:string@"nu-complete git log"
--hard:bool
]
export alias gp = git push export alias gp = git push
export alias gpf! = git push --force export alias gpf! = git push --force
export alias gl = git pull export alias gl = git pull

View file

@ -31,7 +31,7 @@ export def "nu-complete just args" [context: string, offset: int] {
} }
export extern "just" [ export extern "main" [
recipes?: string@"nu-complete just recipes" recipes?: string@"nu-complete just recipes"
...args: any@"nu-complete just args" ...args: any@"nu-complete just args"
] ]

View file

@ -1,36 +1,35 @@
export def "parse cmd" [] { export def "parse cmd" [] {
let argv = ($in | split row ' ') $in
mut pos = [] | split row ' '
mut opt = {} | reduce -f { args: [], sw: '' } {|it, acc|
mut sw = '' if ($acc.sw|is-empty) {
for i in $argv { if ($it|str starts-with '-') {
if ($i | str starts-with '-') { $acc | upsert sw $it
if not ($sw | is-empty) {
$opt = ($opt | upsert $sw true)
}
$sw = $i
} else {
if ($sw | is-empty) {
$pos ++= [$i]
} else { } else {
$opt = ($opt | upsert $sw $i) let args = ($acc.args | append $it)
$sw = '' $acc | upsert args $args
}
} else {
if ($it|str starts-with '-') {
$acc
| upsert $acc.sw true
| upsert sw $it
} else {
$acc | upsert $acc.sw $it | upsert sw ''
} }
} }
} }
$opt.args = $pos | reject sw
return $opt
} }
export def index-need-update [index path] { export def ensure-index [index path action] {
let ts = do -i { ls $path | sort-by modified | reverse | get 0.modified } let ts = do -i { ls $path | sort-by modified | reverse | get 0.modified }
if ($ts | is-empty) { return false } if ($ts | is-empty) { return false }
let tc = do -i { ls $index | get 0.modified } let tc = do -i { ls $index | get 0.modified }
if not (($index | path exists) and ($ts < $tc)) { if not (($index | path exists) and ($ts < $tc)) {
mkdir (dirname $index) mkdir (dirname $index)
return true do $action
} }
return false
} }
export-env { export-env {
@ -69,14 +68,14 @@ export def kk [p: path] {
### ctx ### ctx
export def "kube-config" [] { export def "kube-config" [] {
let file = if 'KUBECONFIG' in (env).name { $env.KUBECONFIG } else { $"($env.HOME)/.kube/config" } let file = if 'KUBECONFIG' in ($env | columns) { $env.KUBECONFIG } else { $"($env.HOME)/.kube/config" }
{ path: $file, data: (cat $file | from yaml)} { path: $file, data: (cat $file | from yaml)}
} }
def "nu-complete kube ctx" [] { def "nu-complete kube ctx" [] {
let k = (kube-config) let k = (kube-config)
let cache = $'($env.HOME)/.cache/nu-complete/k8s/(basename $k.path).json' let cache = $'($env.HOME)/.cache/nu-complete/k8s/(basename $k.path).json'
if index-need-update $cache $k.path { ensure-index $cache $k.path {
let clusters = ($k.data | get clusters | select name cluster.server) let clusters = ($k.data | get clusters | select name cluster.server)
let data = ( $k.data let data = ( $k.data
| get contexts | get contexts
@ -95,7 +94,7 @@ def "nu-complete kube ctx" [] {
let data = (cat $cache | from json) let data = (cat $cache | from json)
$data.completion | each {|x| $data.completion | each {|x|
let ns = ($x.ns | fill -a r -w $data.max.ns -c ' ') let ns = ($x.ns | fill -a l -w $data.max.ns -c ' ')
let cl = ($x.cluster | fill -a l -w $data.max.cluster -c ' ') let cl = ($x.cluster | fill -a l -w $data.max.cluster -c ' ')
{value: $x.value, description: $"\t($ns) ($cl)"} {value: $x.value, description: $"\t($ns) ($cl)"}
} }
@ -172,7 +171,7 @@ def "nu-complete kube def" [] {
def "nu-complete kube res" [context: string, offset: int] { def "nu-complete kube res" [context: string, offset: int] {
let ctx = ($context | parse cmd) let ctx = ($context | parse cmd)
let def = ($ctx | get args | get 1) let def = ($ctx | get args.1)
let ns = do -i { $ctx | get '-n' } let ns = do -i { $ctx | get '-n' }
let ns = if ($ns|is-empty) { [] } else { [-n $ns] } let ns = if ($ns|is-empty) { [] } else { [-n $ns] }
kubectl get $ns $def | from ssv -a | get NAME kubectl get $ns $def | from ssv -a | get NAME
@ -443,7 +442,6 @@ export def ksd [
kubectl scale $n deployments $d --replicas $num kubectl scale $n deployments $d --replicas $num
} }
} }
export def ksdr [ export def ksdr [
d: string@"nu-complete kube deployments" d: string@"nu-complete kube deployments"
num: int@"nu-complete num9" num: int@"nu-complete num9"

View file

@ -32,7 +32,7 @@
def nvim_tcd [] { def nvim_tcd [] {
[ [
{|before, after| {|before, after|
if 'NVIM' in (env).name { if 'NVIM' in ($env | columns) {
nvim --headless --noplugin --server $env.NVIM --remote-send $"<cmd>lua HookPwdChanged\('($after)', '($before)')<cr>" nvim --headless --noplugin --server $env.NVIM --remote-send $"<cmd>lua HookPwdChanged\('($after)', '($before)')<cr>"
} }
} }
@ -52,7 +52,7 @@ export-env {
} }
def edit [action file] { def edit [action file] {
if 'NVIM' in (env).name { if 'NVIM' in ($env | columns) {
let af = ($file | each {|f| let af = ($file | each {|f|
if ($f|str substring ',1') in ['/', '~'] { if ($f|str substring ',1') in ['/', '~'] {
$f $f
@ -67,6 +67,7 @@ def edit [action file] {
} }
} }
# nvim tcd
export def tcd [path?: string] { export def tcd [path?: string] {
let after = if ($path|is-empty) { let after = if ($path|is-empty) {
$env.PWD $env.PWD
@ -108,8 +109,9 @@ export def x [...file: string] {
} }
} }
# drop stdout to nvim buf
export def drop [] { export def drop [] {
if 'NVIM' in (env).name { if 'NVIM' in ($env | columns) {
let c = $in let c = $in
let temp = (mktemp -t nuvim.XXXXXXXX|str trim) let temp = (mktemp -t nuvim.XXXXXXXX|str trim)
$c | save -f $temp $c | save -f $temp
@ -119,8 +121,8 @@ export def drop [] {
} }
} }
export def nvim_lua [...expr: string] { export def nvim-lua [...expr: string] {
if 'NVIM' in (env).name { if 'NVIM' in ($env | columns) {
nvim --headless --noplugin --server $env.NVIM --remote-send $'<cmd>lua vim.g.remote_expr_lua = ($expr|str join " ")<cr>' nvim --headless --noplugin --server $env.NVIM --remote-send $'<cmd>lua vim.g.remote_expr_lua = ($expr|str join " ")<cr>'
do -i { nvim --headless --noplugin --server $env.NVIM --remote-expr 'g:remote_expr_lua' } | complete | get stderr do -i { nvim --headless --noplugin --server $env.NVIM --remote-expr 'g:remote_expr_lua' } | complete | get stderr
} else { } else {
@ -129,5 +131,13 @@ export def nvim_lua [...expr: string] {
} }
export def opwd [] { export def opwd [] {
nvim_lua 'OppositePwd()' nvim-lua 'OppositePwd()'
}
export def nvim-srv [port: int=1111] {
nvim --headless --listen $"0.0.0.0:($port)"
}
export def nvide-conn [addr: string] {
neovide --multigrid --maximized --remote-tcp addr
} }

View file

@ -1,3 +1,13 @@
export def ensure-index [index path action] {
let ts = do -i { ls $path | sort-by modified | reverse | get 0.modified }
if ($ts | is-empty) { return false }
let tc = do -i { ls $index | get 0.modified }
if not (($index | path exists) and ($ts < $tc)) {
mkdir (dirname $index)
do $action
}
}
export def 'str max-length' [] { export def 'str max-length' [] {
$in | reduce -f 0 {|x, a| $in | reduce -f 0 {|x, a|
if ($x|is-empty) { return $a } if ($x|is-empty) { return $a }
@ -6,17 +16,6 @@ export def 'str max-length' [] {
} }
} }
export def index-need-update [index path] {
let ts = do -i { ls $path | sort-by modified | reverse | get 0.modified }
if ($ts | is-empty) { return false }
let tc = do -i { ls $index | get 0.modified }
if not (($index | path exists) and ($ts < $tc)) {
mkdir (dirname $index)
return true
}
return false
}
def "nu-complete ssh host" [] { def "nu-complete ssh host" [] {
rg -LNI '^Host [a-z0-9_\-\.]+' ~/.ssh | lines | each {|x| $x | split row ' '| get 1} rg -LNI '^Host [a-z0-9_\-\.]+' ~/.ssh | lines | each {|x| $x | split row ' '| get 1}
} }
@ -50,7 +49,7 @@ def fmt-group [p] {
def "ssh-hosts" [] { def "ssh-hosts" [] {
let cache = $'($env.HOME)/.cache/nu-complete/ssh.json' let cache = $'($env.HOME)/.cache/nu-complete/ssh.json'
if index-need-update $cache ~/.ssh/**/* { ensure-index $cache ~/.ssh/**/* {
let data = (ssh-list | each {|x| let data = (ssh-list | each {|x|
let uri = $"($x.User)@($x.HostName):($x.Port)" let uri = $"($x.User)@($x.HostName):($x.Port)"
{ {
@ -78,14 +77,14 @@ def "nu-complete ssh" [] {
let data = (ssh-hosts) let data = (ssh-hosts)
$data.completion $data.completion
| each { |x| | each { |x|
let uri = ($x.uri | str lpad -l $data.max.uri -c ' ') let uri = ($x.uri | fill -a l -w $data.max.uri -c ' ')
let group = ($x.group | fill -w $data.max.group -c ' ' -a l) let group = ($x.group | fill -a l -w $data.max.group -c ' ')
let id = ($x.identfile | fill -w $data.max.identfile -c ' ' -a l) let id = ($x.identfile | fill -a l -w $data.max.identfile -c ' ')
{value: $x.value, description: $"\t($uri) ($group) ($id)" } {value: $x.value, description: $"\t($uri) ($group) ($id)" }
} }
} }
export extern ssh [ export extern main [
host: string@"nu-complete ssh" # host host: string@"nu-complete ssh" # host
...cmd # cmd ...cmd # cmd
-v # verbose -v # verbose