From fce44fbbfd1549a64efd7d0f811d6b8071d59d48 Mon Sep 17 00:00:00 2001 From: fj0r <82698591+fj0r@users.noreply.github.com> Date: Wed, 20 Dec 2023 20:03:20 +0800 Subject: [PATCH] new module comma and some updates (#704) update: - cwdhist: openeditor changed from alt+e to alt+o - docker: pull, push add nerdctl insecure-registry support - docker: registry show use curl instead http get (may cause dns resolution problems) - git: status `table -n` changed to `table -i` new module: comma Similar to `pwd-module`, but supports completion and description through custom data formats - `,` or `*` need to be exported in order to use `,` directly - Directly execute `,` to create a new template file or edit an existing file - Custom tasks are written in `$env.comma` and can be nested - Generate completions based on the structure of `$env.comma` - You can use closure to customize completion - In `$env.commax.act` of default closure, you can receive parameters after the current position - In `$env.commax.cmp` , you can receive the parameter before the current position --------- Co-authored-by: nash --- modules/comma/README.md | 60 ++++++++ modules/comma/comma.nu | 234 +++++++++++++++++++++++++++++++ modules/cwdhist/cwdhist.nu | 4 +- modules/docker/docker.nu | 34 ++--- modules/git/git-v2.nu | 8 +- modules/kubernetes/kubernetes.nu | 6 +- 6 files changed, 318 insertions(+), 28 deletions(-) create mode 100644 modules/comma/README.md create mode 100644 modules/comma/comma.nu diff --git a/modules/comma/README.md b/modules/comma/README.md new file mode 100644 index 00000000..6fbc0073 --- /dev/null +++ b/modules/comma/README.md @@ -0,0 +1,60 @@ +Working dir task runner, similar to `pwd-module`, but supports completion and description through custom data formats +- `,` or `*` need to be exported in order to use `,` directly +- Directly execute `,` to create a new template file or edit an existing file +- Custom tasks are written in `$env.comma` and can be nested +- Generate completions based on the structure of `$env.comma` +- You can use closure to customize completion +- In `$env.commax.act` of default closure, you can receive parameters after the current position +- In `$env.commax.cmp` , you can receive the parameter before the current position + +example: +``` +$env.commav = { + +} +$env.comma = { + created: { '2023-12-20[3]16:02:56' } + hello: { + $env.commax.act: {|x| print $'hello ($x)' } + $env.commax.dsc: 'hello (x)' + $env.commax.cmp: {|args| $args} + } + open: { + $env.commax.sub: { + any: { + $env.commax.act: {|x| open $x.0} + $env.commax.cmp: {ls | get name} + $env.commax.dsc: 'open a file' + } + json: { + $env.commax.act: {|x| open $x.0} + $env.commax.cmp: {ls *.json | get name} + $env.commax.dsc: 'open a json file' + } + } + $env.commax.dsc: 'open a file' + } + # Nest as you like + a: { + b: { + c: { + $env.commax.act: {|x| print $x } + $env.commax.dsc: 'description' + $env.commax.cmp: {|| ls | get name } + } + d: { pwd } + } + x: { + $env.commax.sub: { + y: { + $env.commax.act: {|x| print y} + $env.commax.cmp: {|| [y1 y2 y3]} + $env.commax.dsc: 'description' + } + } + $env.commax.dsc: 'xxx' + } + } +} + +``` diff --git a/modules/comma/comma.nu b/modules/comma/comma.nu new file mode 100644 index 00000000..7dc0597c --- /dev/null +++ b/modules/comma/comma.nu @@ -0,0 +1,234 @@ +def unindent [] { + let txt = $in | lines | range 1.. + let indent = $txt.0 | parse --regex '^(?P\s*)' | get indent.0 | str length + $txt + | each {|s| $s | str substring $indent.. } + | str join (char newline) +} + +def 'path parents' [] { + $in + | path expand + | path split + | reduce -f [ '' ] {|x, acc| [( $acc.0 | path join $x ), ...$acc] } + | range ..-2 +} + +def find [] { + $in + | path parents + | filter {|x| $x | path join ',.nu' | path exists } + | get 0? +} + +def comma_file [] { + [ + { + condition: {|_, after| not ($after | path join ',.nu' | path exists)} + code: "$env.comma = null" + } + { + condition: {|_, after| $after | path join ',.nu' | path exists} + code: " + print $'(ansi default_underline)(ansi default_bold),(ansi reset).nu (ansi green_italic)detected(ansi reset)...' + print $'(ansi yellow_italic)activating(ansi reset) (ansi default_underline)(ansi default_bold),(ansi reset) module with `(ansi default_dimmed)(ansi default_italic)source ,.nu(ansi reset)`' + source ,.nu + " + } + ] +} + +export-env { + $env.config = ( $env.config | upsert hooks.env_change.PWD { |config| + let o = ($config | get -i hooks.env_change.PWD) + let val = (comma_file) + if $o == null { + $val + } else { + $o | append $val + } + }) + let k = (gensym) + $env.commax = { + sub: $k.0 + dsc: $k.1 + act: $k.2 + cmp: $k.3 + } +} + +def gensym [] { + mut r = [] + let rk = random chars + for i in 1..4 { + let b = ($i - 1) * 5 + let e = $i * 5 + $r ++= [($rk | str substring $b..$e)] + } + $r + # TODO: debug + # [sub dsc act cmp] +} + +def log [tag? -c] { + let o = $in + if ($c) { + echo $'---(char newline)' | save -f ~/.cache/comma.log + } else { + echo $'---($tag)---($o | describe)(char newline)($o | to yaml)' | save -a ~/.cache/comma.log + } + $o +} + +def 'as act' [] { + let o = $in + let ix = $env.commax + let t = ($o | describe -d).type + if $t == 'closure' { + { $ix.act: $o } + } else if ($ix.sub in $o) { + null + } else if ($ix.act in $o) { + $o + } else { + null + } +} + +def run [tbl] { + let loc = $in + let ix = $env.commax + mut act = $tbl + mut arg = [] + for i in $loc { + let a = $act | as act + if ($a | is-empty) { + if ($ix.sub in $act) and ($i in ($act | get $ix.sub)) { + let n = $act | get $ix.sub | get $i + $act = $n + } else if $i in $act { + let n = $act | get $i + $act = $n + } else { + $act = {|| print $"not found `($i)`"} + break + } + } else { + $arg ++= [$i] + } + } + let a = $act | as act + if ($a | is-empty) { + let c = if $ix.sub in $act { $act | get $ix.sub | columns } else { $act | columns } + print $'require argument: ($c)' + } else { + do ($a | get $ix.act) $arg + } +} + +def complete [tbl] { + let argv = $in + let ix = $env.commax + mut tbl = $env.comma + for i in $argv { + let c = if ($i | is-empty) { + $tbl + } else { + let tp = ($tbl | describe -d).type + if ($tp == 'record') and ($i in $tbl) { + let j = $tbl | get $i + if $ix.sub in $j { + $j | get $ix.sub + } else { + $j + } + } else { + $tbl + } + } + let a = $c | as act + if not ($a | is-empty) { + let r = do ($a | get $ix.cmp) $argv + $tbl = $r + } else { + $tbl = $c + } + } + match ($tbl | describe -d).type { + record => { + $tbl + | transpose k v + | each {|x| + if ($x.v | describe -d).type == 'closure' { + $x.k + } else if $ix.dsc in $x.v { + { value: $x.k, description: ($x.v | get $ix.dsc) } + } else { + $x.k + } + } + } + list => { $tbl } + _ => { $tbl } + } +} + +def 'parse argv' [] { + let context = $in + $context.0 + | str substring 0..$context.1 + | split row -r '\s+' + | range 1.. + | where not ($it | str starts-with '-') +} + +def compos [...context] { + $context + | parse argv + | complete $env.comma +} + +export def , [...args:string@compos] { + if ($args | is-empty) { + if ([$env.PWD, ',.nu'] | path join | path exists) { + ^$env.EDITOR ,.nu + } else { + let a = [yes no] | input list 'create ,.nu?' + if $a == 'yes' { + $" + $env.commav = { + + } + $env.comma = { + created: { '(date now | format date '%Y-%m-%d[%w]%H:%M:%S')' } + hello: { + $env.commax.act: {|x| print $'hello \($x\)' } + $env.commax.dsc: 'hello \(x\)' + $env.commax.cmp: {|args| $args} + } + open: { + $env.commax.sub: { + any: { + $env.commax.act: {|x| open $x.0} + $env.commax.cmp: {ls | get name} + $env.commax.dsc: 'open a file' + } + json: { + $env.commax.act: {|x| open $x.0} + $env.commax.cmp: {ls *.json | get name} + $env.commax.dsc: 'open a json file' + } + } + $env.commax.dsc: 'open a file' + } + } + " + | unindent + | save $",.nu" + #source ',.nu' + } + } + } else { + $args | run $env.comma + } +} diff --git a/modules/cwdhist/cwdhist.nu b/modules/cwdhist/cwdhist.nu index 7ecdddaf..2d0db125 100644 --- a/modules/cwdhist/cwdhist.nu +++ b/modules/cwdhist/cwdhist.nu @@ -53,7 +53,7 @@ def __cwdhist_editing [] { { name: open_command_editor modifier: alt - keycode: char_e + keycode: char_o mode: [emacs, vi_normal, vi_insert] event: { send: openeditor } } @@ -63,7 +63,7 @@ def __cwdhist_switching [] { { name: cwdhist_switching modifier: shift_alt - keycode: char_e + keycode: char_o mode: [emacs, vi_normal, vi_insert] event: [ { send: ExecuteHostCommand, cmd: '$env.cwd_history_full = (not $env.cwd_history_full)' } diff --git a/modules/docker/docker.nu b/modules/docker/docker.nu index ddbdbdf8..387935ab 100644 --- a/modules/docker/docker.nu +++ b/modules/docker/docker.nu @@ -7,10 +7,8 @@ export-env { } } -def --wrapped with-flag [...ns] { - if ($in | is-empty) { [] } else { - [$ns $in] | flatten - } +def --wrapped with-flag [...flag] { + if ($in | is-empty) { [] } else { [...$flag $in] } } def local_image [name] { @@ -209,13 +207,15 @@ export def image-tag [from: string@"nu-complete docker images" to: string -n: s } # push image -export def image-push [img: string@"nu-complete docker images" -n: string@"nu-complete docker ns"] { - ^$env.docker-cli ($n | with-flag -n) push $img +export def image-push [img: string@"nu-complete docker images" -n: string@"nu-complete docker ns" -i] { + let $insecure = if $i {[--insecure-registry]} else {[]} + ^$env.docker-cli ($n | with-flag -n) $insecure push $img } # pull image -export def image-pull [img -n: string@"nu-complete docker ns"] { - ^$env.docker-cli ($n | with-flag -n) pull $img +export def image-pull [img -n: string@"nu-complete docker ns" -i] { + let $insecure = if $i {[--insecure-registry]} else {[]} + ^$env.docker-cli ($n | with-flag -n) $insecure pull $img } ### list volume @@ -349,16 +349,16 @@ def "nu-complete registry show" [cmd: string, offset: int] { let reg = $cmd.3? let tag = $cmd.4? let auth = if ($env | has 'REGISTRY_TOKEN') { - [authorization $"Basic ($env.REGISTRY_TOKEN)"] + [-H $"Authorization: Basic ($env.REGISTRY_TOKEN)"] } else { [] } if ($tag | is-empty) and (not $new) or ($reg | is-empty) { - http get -H $auth $"($url)/v2/_catalog" - | get repositories + curl -sSL $auth $"($url)/v2/_catalog" + | from json | get repositories } else { - http get -H $auth $"($url)/v2/($reg)/tags/list" - | get tags + curl -sSL $auth $"($url)/v2/($reg)/tags/list" + | from json | get tags } } @@ -369,16 +369,16 @@ export def "registry show" [ tag?: string@"nu-complete registry show" ] { let auth = if ($env | has 'REGISTRY_TOKEN') { - [authorization $"Basic ($env.REGISTRY_TOKEN)"] + [-H $"Authorization: Basic ($env.REGISTRY_TOKEN)"] } else { [] } if ($reg | is-empty) { - http get -H $auth $"($url)/v2/_catalog" | get repositories + curl -sSL $auth $"($url)/v2/_catalog" | from json | get repositories } else if ($tag | is-empty) { - http get -H $auth $"($url)/v2/($reg)/tags/list" | get tags + curl -sSL $auth $"($url)/v2/($reg)/tags/list" | from json | get tags } else { - http get -e -H [accept 'application/vnd.oci.image.manifest.v1+json'] -H $auth $"($url)/v2/($reg)/manifests/($tag)" | from json + curl -sSL -H 'Accept: application/vnd.oci.image.manifest.v1+json' $auth $"($url)/v2/($reg)/manifests/($tag)" | from json } } diff --git a/modules/git/git-v2.nu b/modules/git/git-v2.nu index 9f2cf38d..0e4d17a0 100644 --- a/modules/git/git-v2.nu +++ b/modules/git/git-v2.nu @@ -12,10 +12,8 @@ def agree [ ( if $default_not { [no yes] } else { [yes no] } | input list $prompt) in [yes] } -def --wrapped with-flag [...ns] { - if ($in | is-empty) { [] } else { - [$ns $in] | flatten - } +def --wrapped with-flag [...flag] { + if ($in | is-empty) { [] } else { [...$flag $in] } } # git status @@ -80,7 +78,7 @@ export def gb [ remote: (git branch --remote | lines) no-merged: (git branch --no-merged | lines) } - print ($d | table -n 1 -e) + print ($d | table -i 1 -e) } else if $delete { if $branch in $bs and (agree 'branch will be delete!') { git branch -D $branch diff --git a/modules/kubernetes/kubernetes.nu b/modules/kubernetes/kubernetes.nu index f514d01d..953452f1 100644 --- a/modules/kubernetes/kubernetes.nu +++ b/modules/kubernetes/kubernetes.nu @@ -24,10 +24,8 @@ export def normalize-column-names [ ] { $t } -def --wrapped with-flag [...ns] { - if ($in | is-empty) { [] } else { - [$ns $in] | flatten - } +def --wrapped with-flag [...flag] { + if ($in | is-empty) { [] } else { [...$flag $in] } } export def `kcache flush` [] {