diff --git a/custom-menus/zoxide-menu.nu b/custom-menus/zoxide-menu.nu new file mode 100644 index 0000000..dbfbd2a --- /dev/null +++ b/custom-menus/zoxide-menu.nu @@ -0,0 +1,51 @@ +def __zoxide_menu [] { + { + name: zoxide_menu + only_buffer_difference: true + marker: "| " + type: { + layout: columnar + page_size: 20 + } + style: { + text: green + selected_text: green_reverse + description_text: yellow + } + source: { |buffer, position| + zoxide query -ls $buffer + | parse -r '(?P[0-9]+) (?P.+)' + } + } +} + +def __zoxide_keybinding [] { + { + name: zoxide_menu + modifier: control + keycode: char_o + mode: [emacs, vi_normal, vi_insert] + event: [ + { send: menu name: zoxide_menu } + ] + } +} + +def __edit_keybinding [] { + { + name: edit + modifier: alt + keycode: char_e + mode: [emacs, vi_normal, vi_insert] + event: [ + { send: OpenEditor } + ] + } +} + +export-env { + let-env config = ($env.config + | upsert menus ($env.config.menus | append (__zoxide_menu)) + | upsert keybindings ($env.config.keybindings | append [(__zoxide_keybinding) (__edit_keybinding)]) + ) +} diff --git a/hooks/direnv/direnv.nu b/hooks/direnv/direnv.nu new file mode 100644 index 0000000..6777bf0 --- /dev/null +++ b/hooks/direnv/direnv.nu @@ -0,0 +1,32 @@ +def direnv [] { + [ + { + condition: {|before, after| ($before != $after) and ($after | path join .env.yaml | path exists) } + code: " + open .env.yaml | load-env + " + } + { + condition: {|before, after| ($before != $after) and ($after | path join '.env' | path exists) } + code: " + open .env + | lines + | parse -r '(?P.+?)=(?P.+)' + | reduce -f {} {|x, acc| $acc | upsert $x.k $x.v} + | load-env + " + } + ] +} + +export-env { + let-env config = ( $env.config | upsert hooks.env_change.PWD { |config| + let o = ($config | get -i hooks.env_change.PWD) + let val = (direnv) + if $o == $nothing { + $val + } else { + $o | append $val + } + }) +} diff --git a/hooks/dynamic-load/dynamic-load.nu b/hooks/dynamic-load/dynamic-load.nu new file mode 100644 index 0000000..ecf398a --- /dev/null +++ b/hooks/dynamic-load/dynamic-load.nu @@ -0,0 +1,20 @@ +def dynamic_load [] { + [ + { + condition: {|before, after| (not ('.nu' in (overlay list))) and ('~/.nu' | path exists) } + code: "overlay use ~/.nu as .nu" + } + ] +} + +export-env { + let-env config = ( $env.config | upsert hooks.env_change.PWD { |config| + let o = ($config | get -i hooks.env_change.PWD) + let val = (dynamic_load) + if $o == $nothing { + $val + } else { + $o | append $val + } + }) +} diff --git a/modules/after/after.nu b/modules/after/after.nu index 463127b..9525c82 100644 --- a/modules/after/after.nu +++ b/modules/after/after.nu @@ -1,9 +1,9 @@ def "nu-complete ps" [] { - ps | each {|x| { value: $x.pid, description: $x.name } } + ps -l | each {|x| { value: $"($x.pid)", description: $x.command } } } -# after { do something ... } -export def main [pid: string@"nu-complete ps" action ] { +# after { do something ... } +export def main [action, pid: string@"nu-complete ps"] { do -i { tail --pid $pid -f /dev/null } do $action } diff --git a/modules/git/git.nu b/modules/git/git.nu index b47e97a..6adf8af 100644 --- a/modules/git/git.nu +++ b/modules/git/git.nu @@ -50,20 +50,18 @@ export def _git_log [v num] { } } -# FIXME: number-like def "nu-complete git log" [] { git log -n 32 --pretty=%h»¦«%s | lines | split column "»¦«" value description - | each {|x| $x | update value $"`($x.value)`"} + | each {|x| $x | update value $"($x.value)"} } -# FIXME: number-like def "nu-complete git branches" [] { git branch | lines | filter {|x| not ($x | str starts-with '*')} - | each {|x| $"'($x|str trim)'"} + | each {|x| $"($x|str trim)"} } export def gl [ @@ -181,7 +179,6 @@ export alias gapt = git apply --3way export alias gb = git branch export alias gba = git branch -a export alias gbd = git branch -d -export alias gbda = 'git branch --no-color --merged | command grep -vE "^(\+|\*|\s*($(git_main_branch)|development|develop|devel|dev)\s*$)" | command xargs -n 1 git branch -d' export alias gbl = git blame -b -w export alias gbnm = git branch --no-merged export alias gbr = git branch --remote diff --git a/modules/kubernetes/kubernetes.nu b/modules/kubernetes/kubernetes.nu index a547207..4d18568 100644 --- a/modules/kubernetes/kubernetes.nu +++ b/modules/kubernetes/kubernetes.nu @@ -514,7 +514,7 @@ export def "kclean evicted" [] { | each { |x| kdel pod -n $x.NAMESPACE $x.NAME } } -### fixme: +### FIXME: export def "kclean stucked ns" [ns: string] { kubectl get namespace $ns -o json \ | tr -d "\n" diff --git a/modules/log/log.nu b/modules/log/log.nu new file mode 100644 index 0000000..1a9e0bc --- /dev/null +++ b/modules/log/log.nu @@ -0,0 +1,24 @@ +def logtime [msg act] { + let start = (date now) + let result = (do $act) + let period = ((date now) - $start + | into duration -c ns + | into string + | str replace ' ' '') + + echo $'($start | date format '%Y-%m-%d_%H:%M:%S%z')(char tab)($period)(char tab)($msg)(char newline)' + | save -a ~/.cache/nushell/time.log + + return $result +} + +export def timelog [] { + open ~/.cache/nushell/time.log + | from tsv -n + | rename start duration message + | each {|x| + $x + | update start ($x.start | into datetime -f '%Y-%m-%d_%H:%M:%S%z') + | update duration ($x.duration | into duration) + } +} diff --git a/modules/prompt/powerline/README.md b/modules/prompt/powerline/README.md index e2c5bd0..426c915 100644 --- a/modules/prompt/powerline/README.md +++ b/modules/prompt/powerline/README.md @@ -32,15 +32,14 @@ power init `$env.NU_POWER_SCHEMA` support configuring dynamically ## mode +- `let-env NU_POWER_MODE = ''` fast mode and default mode (experimental) - `let-env NU_POWER_DECORATOR = ''` power mode and plain mode - `let-env NU_POWER_FRAME = ''` two line prompt (experimental) ## todo - [x] source return `$nothing` for hiding - - FRAME can't dynamically, or can't optimize performance - - if can't predetermine '<' or '<<', it can't precalculate - - so '<<' not longer hide separator - [x] proxy stat invalid in plain mode + - '<<' not longer hide separator in `fast` mode - [ ] implement `power eject` - [ ] `$env.config.menus[].maker` can be restored - [x] support color theme diff --git a/modules/prompt/powerline/power.nu b/modules/prompt/powerline/power.nu index c58343d..db47379 100644 --- a/modules/prompt/powerline/power.nu +++ b/modules/prompt/powerline/power.nu @@ -78,12 +78,138 @@ def host_abbr [] { def time_segment [] { {|| let theme = $env.NU_POWER_THEME.time - $"($theme.now)(date now | date format '%y-%m-%d/%H:%M:%S')" + $"($theme.now)(date now | date format '%y-%m-%d_%H:%M:%S')" + } +} + +### utils +def logtime [msg act] { + let start = (date now) + let result = (do $act) + let period = ((date now) - $start + | into duration -c ns + | into string + | str replace ' ' '') + + echo $'($start | date format '%Y-%m-%d_%H:%M:%S%z')(char tab)($period)(char tab)($msg)(char newline)' + | save -a ~/.cache/nushell/time.log + + return $result +} + +def-env wraptime [message action] { + if $env.NU_POWER_BENCHMARK? == true { + {|| logtime $message $action } + } else { + $action + } +} + +export def timelog [] { + open ~/.cache/nushell/time.log + | from tsv -n + | rename start duration message + | each {|x| + $x + | update start ($x.start | into datetime -f '%Y-%m-%d_%H:%M:%S%z') + | update duration ($x.duration | into duration) } } ### prompt -def decorator [ +def decorator [ ] { + match $env.NU_POWER_DECORATOR { + 'plain' => { + {|s, direction?: string, color?: string = 'light_yellow', fg?: string| + match $direction { + '>' => { + let r = $'(ansi light_yellow)|' + $"($s)($r)" + } + '>>'|'<<' => { + $s + } + '<' => { + let l = $'(ansi light_yellow)|' + $"($l)($s)" + } + } + } + } + 'power' => { + {|s, direction?: string, color?: string = 'light_yellow', fg?: string| + match $direction { + '>' => { + let l = (ansi -e {bg: $fg}) + let r = $'(ansi -e {fg: $fg, bg: $color})(char nf_left_segment)' + $'($l)($s)($r)' + } + '>>' => { + let l = (ansi -e {bg: $fg}) + let r = $'(ansi reset)(ansi -e {fg: $fg})(char nf_left_segment)' + $'($l)($s)($r)' + } + '<'|'<<' => { + let l = $'(ansi -e {fg: $color})(char nf_right_segment)(ansi -e {bg: $color})' + $'($l)($s)' + } + } + } + } + } +} + +def left_prompt [segment] { + let decorator = (decorator) + let segment = ($segment + | each {|x| + [$x.color ($env.NU_PROMPT_COMPONENTS | get $x.source)] + }) + {|| + let segment = ($segment + | each {|x| [$x.0 (do $x.1)] } + | filter {|x| $x.1 != $nothing } + ) + let stop = ($segment | length) - 1 + let cs = ($segment | each {|x| $x.0 }) + let cs = ($cs | prepend $cs.1?) + $segment + | zip $cs + | enumerate + | each {|x| + if $x.index == $stop { + do $decorator $x.item.0.1 '>>' $x.item.0.0 $x.item.1 + } else { + do $decorator $x.item.0.1 '>' $x.item.0.0 $x.item.1 + } + } + | str join + } +} + +def right_prompt [segment] { + let decorator = (decorator) + let segment = ($segment + | each {|x| + [$x.color ($env.NU_PROMPT_COMPONENTS | get $x.source)] + }) + {|| + $segment + | each {|x| [$x.0 (do $x.1)] } + | filter {|x| $x.1 != $nothing } + | enumerate + | each {|x| + if $x.index == 0 { + do $decorator $x.item.1 '<<' $x.item.0 + } else { + do $decorator $x.item.1 '<' $x.item.0 + } + } + | str join + } +} + +def decorator_gen [ direction?: string color?: string = 'light_yellow' fg?: string @@ -122,16 +248,6 @@ def decorator [ } } } - 'dynamic' => { - match $direction { - '>' => { - } - '>>' => { - } - '<'|'<<' => { - } - } - } } } @@ -146,7 +262,7 @@ def squash [thunk] { $r } -def left_prompt [segment] { +def left_prompt_gen [segment] { let stop = ($segment | length) - 1 let vs = ($segment | each {|x| [$x.color ($env.NU_PROMPT_COMPONENTS | get $x.source)]}) let cs = ($vs | each {|x| $x.0}) @@ -156,23 +272,23 @@ def left_prompt [segment] { | enumerate | each {|x| if $x.index == $stop { - [$x.item.0.1 (decorator '>>' $x.item.0.0 $x.item.1)] + [$x.item.0.1 (decorator_gen '>>' $x.item.0.0 $x.item.1)] } else { - [$x.item.0.1 (decorator '>' $x.item.0.0 $x.item.1)] + [$x.item.0.1 (decorator_gen '>' $x.item.0.0 $x.item.1)] } }) {|| squash $thunk } } -def right_prompt [segment] { +def right_prompt_gen [segment] { let thunk = ( $segment | each {|x| [$x.color ($env.NU_PROMPT_COMPONENTS | get $x.source)]} | enumerate | each {|x| if $x.index == 0 { - [$x.item.1 (decorator '<<' $x.item.0)] + [$x.item.1 (decorator_gen '<<' $x.item.0)] } else { - [$x.item.1 (decorator '<' $x.item.0)] + [$x.item.1 (decorator_gen '<' $x.item.0)] } }) {|| squash $thunk } @@ -207,8 +323,28 @@ export def default_env [name value] { export def-env init [] { match $env.NU_POWER_FRAME { 'default' => { - let-env PROMPT_COMMAND = (left_prompt $env.NU_POWER_SCHEMA.0) - let-env PROMPT_COMMAND_RIGHT = (right_prompt $env.NU_POWER_SCHEMA.1) + match $env.NU_POWER_MODE { + 'default' => { + let-env PROMPT_COMMAND = (wraptime + 'power dynamic left' + (left_prompt $env.NU_POWER_SCHEMA.0) + ) + let-env PROMPT_COMMAND_RIGHT = (wraptime + 'power dynamic right' + (right_prompt $env.NU_POWER_SCHEMA.1) + ) + } + 'fast' => { + let-env PROMPT_COMMAND = (wraptime + 'power static left' + (left_prompt_gen $env.NU_POWER_SCHEMA.0) + ) + let-env PROMPT_COMMAND_RIGHT = (wraptime + 'power static right' + (right_prompt_gen $env.NU_POWER_SCHEMA.1) + ) + } + } } 'fill' => { let-env PROMPT_COMMAND = (up_prompt $env.NU_POWER_SCHEMA) @@ -295,15 +431,24 @@ export def-env hook [] { let-env config = ( $env.config | upsert hooks.env_change { |config| let init = [{|before, after| if not ($before | is-empty) { init } }] $config.hooks.env_change + | upsert NU_POWER_MODE $init | upsert NU_POWER_SCHEMA $init | upsert NU_POWER_FRAME $init | upsert NU_POWER_DECORATOR $init | upsert NU_POWER_MENU_MARKER $init + | upsert NU_POWER_BENCHMARK $init # NU_POWER_THEME }) } export-env { + let-env NU_POWER_BENCHMARK = false + + let-env NU_POWER_MODE = (default_env + NU_POWER_MODE + 'fast' # default | fast + ) + let-env NU_POWER_SCHEMA = (default_env NU_POWER_SCHEMA [ diff --git a/modules/prompt/powerline/power_git.nu b/modules/prompt/powerline/power_git.nu index d137328..0f8358f 100644 --- a/modules/prompt/powerline/power_git.nu +++ b/modules/prompt/powerline/power_git.nu @@ -1,10 +1,5 @@ ### git -export def git_status [] { - let status = (do -i { gstat }) - if not ($status | is-empty) { - return $status - } - +export def git_status_raw [] { let raw_status = (do -i { git --no-optional-locks status --porcelain=2 --branch | lines }) mut status = { @@ -92,9 +87,19 @@ export def git_status [] { } } } + return $status } +export def git_status [] { + let status = (do -i { gstat }) + if not ($status | is-empty) { + return $status + } else { + git_status_raw + } +} + export def git_stat [] { {|| let status = (git_status)