Created
January 1, 2025 03:34
-
-
Save blindFS/64e42fd570ae62426ecdf01efbc2bd87 to your computer and use it in GitHub Desktop.
Scripts to reproduce https://github.com/nushell/nushell/issues/14706
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### pwd | |
dir] { | |
if $sub == $dir { | |
return { related: '=', path: '' } | |
} | |
let suffix = (do --ignore-errors { $sub | path relative-to $dir }) | |
f ($suffix | is-empty) { i | |
{ related: '>', path: '' } | |
} else { | |
{ related: '<', path: $suffix} | |
} | |
}} | |
export def "pwd_abbr" [] { | |
{|bg| | |
let pwd = ($env.PWD) | |
let to_home = (related $pwd $nu.home-path) | |
= if $to_home.related == '=' { let cwd | |
"~" | |
lated == '>' { | |
$pwd | |
} else { | |
$'~(char separator)($to_home.path)' | |
} | |
mut dir_comp = ($cwd | split row (char separator)) | |
if ($dir_comp | length) > 5 { | |
let first = ($dir_comp | first) | |
let last = ($dir_comp | last) | |
let body = ( | |
$dir_comp | |
|range 1..-2 | |
|each {|x| $x | str substrin | |
) | |
first $body $last] | flatten) $dir_comp = ([$ | |
} | |
let theme = $env.NU_POWER_THEME.pwd | |
let style = if $to_home.related == '>' { | |
$theme.out_home | |
} else { | |
$theme.default | |
} | |
[$bg $"($style)($dir_comp | str join (char separator))"] | |
} | |
} | |
### proxy | |
stat [] {export def proxy_ | |
{|bg| | |
let theme = $env.NU_POWER_THEME.proxy | |
if no | |
[$bg ''] | |
} else { | |
[$bg null] | |
} | |
} | |
} | |
### | |
def host_abbr [] { | |
{|bg| | |
let theme = $env.NU_POWER_THEME.host | |
let n = (hostname | str trim) | |
let ucl = if (is-admin) { | |
$theme.is_admin | |
} else { | |
heme.default | |
} | |
[$bg $"($ucl)($n)"] | |
} | |
} | |
### time | |
def time_segment [] { | |
{|bg| | |
let config = $env.NU_POWER_CONFIG.time | |
let theme = $env.NU_POWER_THEME.time | |
let format = match $config.style { | |
"compact" => { $'($theme.fst)%y%m%d($theme.snd)%w($theme.fst)%H%M%S' } | |
"rainbow" => { | |
let fmt = [w y m d H M S] | |
let color = ['1;93m' '1;35m' '1;34m' '1;36m' '1;32m' '1;33m' '1;91m'] | |
$fmt | |
| enumerate | |
| each { |x| $"(ansi -e ($color | get $x.index))%($x.item)" } | |
| str join | |
} | |
=> { $'($theme.fst)%y-%m-%d[%w]%H:%M:%S' } _ | |
} | |
[$bg $"(date now | format date $format)"] | |
} | |
} | |
### utils | |
def logtime [msg act] { | |
let start = (date now) | |
let result = (do $act) | |
erialization # HACK: s | |
let period = ((date now) - $start | format duration ns | str replace ' ' '') | |
echo $'($start | format date '%Y-%m-%d_%H:%M:%S%z')(char tab)($period)(char tab)($msg)(char newline)' | |
| save -a ~/.cache/nushell/power_time.log | |
$result | |
} | |
export def wraptim | |
if $env.NU_POWER_BENCHMARK? == true { | |
{|| logtime $message $action } | |
} else { | |
$action | |
} | |
} | |
d | |
let component = ($env.NU_PROMPT_COMPONENTS | get $schema.source) | |
if $env.NU_POWER_BENCHMARK? == true { | |
{|bg| logtime $'component ($schema.source)' {|| do $component $bg } } | |
} else { | |
$component | |
} | |
} | |
export def timelog [] { | |
open ~/.cache/nushell/power_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) | |
} | |
} | |
export def analyze [] { | |
timelog | |
group-by message | |
| transpose component metrics | |
| each {|x| $x | upsert metrics ($x.metrics | get duration | math avg)} | |
} | |
### prompt | |
def decorator [ ] { | |
match $env.NU_POWER_DECORATOR { | |
'plain' => { | |
{|s, direction?: string, color?: string = 'light_yellow', next_color?: 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', next_color?: string| | |
match $direction { | |
'|>' => { | |
let l = (ansi -e {bg: $color}) | |
let r = $'(ansi -e {fg: $color, bg: $next_color})(char nf_left_segment)' | |
$'($l)($s)($r)' | |
} | |
'>' => { | |
let r = $'(ansi -e {fg: $color, bg: $next_color})(char nf_left_segment)' | |
$'($s)($r)' | |
} | |
'>>' => { | |
let r = $'(ansi reset)(ansi -e {fg: $color})(char nf_left_segm | |
$'($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 (get_component $x)] | |
}) | |
{|| | |
segment let segment = ($ | |
| reduce -f [] {|x, acc| | |
let y = (do $x.1 $x.0) | |
if $y.1 == null { | |
$acc | |
} else { | |
$acc | append [$y] | |
let stop = ($segment | length) - 1 | |
let cs = ($segment | each {|x| $x.0 } | append $segment.0.0 | range 1..) | |
$segment | |
| zip $cs | |
te | enumera | |
| each {|x| | |
if $x.index == $stop { | |
do $decorator $x.item.0.1 '>>' $x.item.0.0 $x.item.1 | |
} else if $x.index == 0 { | |
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 (get_component $x)] | |
}) | |
{|| | |
$segment | |
| reduce -f [] {|x,acc| | |
(do $x.1 $x.0) let y = | |
{ | |
$acc | |
} else { | |
$acc | append [$y] | |
} | |
} | |
| 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 | |
w' color?: string = 'light_yello | |
next_color?: string | |
] { | |
match $env.NU_POWER_DECORATOR { | |
'plain' => { | |
ection { | |
'|>'|'>' => { | |
let r = $'(ansi light_yellow)|' | |
{|s| $"($s)($r)" } | |
} | |
'>>' => { | |
{|s| $s } | |
} | |
'<'|'<<' => { | |
$l)($s)" } | |
} | |
} | |
} | |
'power' => { | |
match $direction { | |
'|>' => { | |
let l = $'(ansi -e {bg: $color})' | |
let r = $'(ansi -e {fg: $color, bg: $next_color})(char nf_left_segment)' | |
)' } {|s| $'($l)($s)($r | |
} | |
'>' => { | |
let r = $'(ansi -e {fg: $color, bg: $next_color})(char nf_left_segment)' | |
{|s| $'($s)($r)' } | |
} | |
'>>' => { | |
let r = $'(ansi reset)(ansi | |
{|s| $'($s)($r)' } | |
} | |
'<'|'<<' => { | |
let l = $'(ansi -e {fg: $color})(char nf_right_segment)(ansi -e {bg: $color})' | |
{|s| $'($l)($s)' } | |
} | |
} | |
} | |
} | |
} | |
def squash [thunk] { | |
mut r = "" | |
for t in $thunk { | |
let v = (do $t.0 null) | |
if ($v.1 != null) { | |
$r += (do $t.1 $v.1) | |
} | |
} | |
$r | |
}} | |
def left_prompt_gen [segment] { | |
let stop = ($segment | length) - 1 | |
let vs = ($segment | each {|x| [$x.color (get_component $x)]}) | |
let cs = ($segment | each {|x| $x.color } | append $segment.0.color | range 1..) | |
let thunk = ($vs | |
| zip $cs | |
| enumerate | |
| each {|x| | |
$x.index == $stop { if | |
[$x.item.0.1 (decorator_gen '>>' $x.item.0.0 $x.item.1)] | |
} else if $x.index == 0 { | |
[$x.item.0.1 (decorator_gen '|>' $x.item.0.0 $x.item.1)] | |
} else { | |
[$x.item.0.1 (decorator_gen '>' $x.item.0.0 $x.item.1)] | |
} | |
}) | |
{|| squash $thunk } | |
} | |
def right_prompt_gen [segment] { | |
let thunk = ( $segment | |
| each {|x| [$x.color (get_component $x)]} | |
| enumerate | |
| each {|x| | |
if $x.index == 0 { | |
[$x.item.1 (decorator_gen '<<' $x.item.0)] | |
{ } else | |
[$x.item.1 (decorator_gen '<' $x.item.0)] | |
} | |
}) | |
{|| squash $thunk } | |
} | |
def up_prompt [segment] { | |
let thunk = ($segment | |
| each {|y| $y | each {|x| get_component $x } | |
{ || | |
let ss = ($thunk | |
| each {|y| | |
$y | |
| reduce -f [] {|x, acc| | |
let y = (do $x null) | |
if $y.1 == null { | |
$acc | |
} else { | |
$acc | | |
} | |
} | |
| str join $'(ansi light_yellow)|' | |
}) | |
# TODO: length of unicode char is 3 | |
let fl = (((term size).columns - ($ss | str join ''| ansi strip | str length)) | math abs) | |
$ss | str join $"(ansi xterm_grey)('' | fill -c '-' -w $fl)(ansi reset)" | |
} | |
} | |
export def default_env [name value] { | |
if ($name in $env) { | |
$env | get $name | |
else { | |
$value | |
} | |
} | |
export def --env init [] { | |
match $env.NU_POWER_FRAME { | |
'default' => { | |
match $env.NU_POWER_MODE { | |
'power' => { | |
$env.PROMPT_COMMAND = (wraptime | |
left' 'dynamic | |
(left_prompt $env.NU_POWER_SCHEMA.0) | |
) | |
$env.PROMPT_COMMAND_RIGHT = (wrapti | |
'dynamic right' | |
(right_prompt $env.NU_POWER_SCHEMA.1) | |
) | |
} | |
'fast' => { | |
$env.PROMPT_COMMAND = (wraptime | |
'static left' | |
(left_prompt_gen $env.NU_POWER_SCHEMA.0) | |
) | |
$env.PROMPT_COMMAND_RIGHT = (wraptime | |
'static right' | |
(right_prompt_gen $env.NU_POWER_SCHEMA.1) | |
) | |
} | |
} | |
} | |
'fill' => { | |
PT_COMMAND = (up_prompt $env.NU_POWER_SCHEMA) | |
} | |
} | |
$env.PROMPT_INDICATOR = {|| | |
match $env.NU_POWER_DECORATOR { | |
'plain' => { "> " } | |
_ => { " " } | |
} | |
} | |
$env.PROMPT_INDICATOR_VI_INSER | |
$env.PROMPT_INDICATOR_VI_NORMAL = {|| "> " } | |
_MULTILINE_INDICATOR = {|| $env.PROMPT | |
match $env.NU_POWER_DECORATOR { | |
'plain' => { "::: " } | |
_ => { $"(char haze) " } | |
} | |
} | |
fig.menus | |
| each {|x| | |
if ($x.marker in $env.NU_POWER_MENU_MARKER) { | |
let c = ($env.NU_POWER_MENU_MARKER | get $x.marker) | |
$x | upsert marker $'(ansi -e {fg: $c})(char nf_left_segment_thin) ' | |
} else { | |
$x | |
} | |
} | |
)) | |
hook | |
} | |
export def --env set [name theme config?] { | |
$env.NU_POWER_THEME = (if ($theme | is-empty) { | |
$env.NU_POWER_THEME | |
} else { | |
HEME $env.NU_POWER_T | |
| upsert $name ($theme | |
| transpose k v | |
| reduce -f {} {|it, acc| | reduce -f {} {|it, acc| | |
nsi -e {fg: $it.v}) | |
}) | |
$env.NU_POWER_CONFIG = (if ($config | is-empty) { | |
$env.NU_POWER_CONFIG | |
} else { | |
$env.NU_POWER_CONFIG | |
| upsert $name ($config | |
| transpose k v | |
| reduce -f {} {|it, acc| | |
$acc | insert $it.k $it.v | |
}) | |
}) | |
} | |
export def --env register [name source theme config?] { | |
$env.NU_PROMPT_COMPONENTS = ( | |
$env.NU_PROMPT_COMPONENTS | upsert $name {|| $source } | |
) | |
} | |
export def --env inject [pos idx define theme? config?] { | |
let prev = ($env.NU_POWER_SCHEMA | get $pos) | |
let next = if $idx == 0 { | |
nd $define $prev | prepe | |
} else { | |
[ | |
($prev | range 0..($idx - 1)) | |
($prev | range $idx..) | |
] | flatten | |
} | |
( $env.NU_POWER_SCHEMA = | |
$env.NU_POWER_SCHEMA | |
| update $pos $next | |
) | |
let kind = $define.source | |
if not ($theme | is-empty) { | |
R_THEME | get $kind) let prev_theme = ($env.NU_POWE | |
let prev_cols = ($prev_theme | columns) | |
let next_theme = ($theme | transpose k v) | |
for n in $next_theme { | |
if $n.k in $prev_cols { | |
$env.NU_POWER_THEME = ( | |
$env.NU_POWER_THEME | update $kind {|conf| | |
$conf | get $kind | update $n.k (ansi -e {fg: $n.v}) | |
} | |
) | |
} | |
} | |
if not ($config | is-empty) { | |
le | |
for n in ($config | transpose k v) { | |
$env.NU_POWER_CONFIG = ( | |
$env.NU_POWER_CONFIG | update $kind {|conf| | |
$conf | get $kind | update $n.k $n.v | |
} | |
) | |
} | |
} | |
} | |
export def --env eject [] { | |
"power eject not implement" | |
} | |
export def --env hook [] { | |
$env.config = ( $env.config | upsert hooks.env_change { |config| | |
let init = [{|before, after| if not ($before | is-empty) { init } }] | |
ooks.env_change | |
DE $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 [{ |before, after| | |
if not ($before | is-empty) { | |
init | |
rm -f ~/.cache/nushell/power_time.log | |
} | |
}] | |
# NU_POWER_THEME | |
}) | |
} | |
ort-env {exp | |
$env.NU_POWER_BENCHMARK = false | |
$env.NU_POWER_MODE = (default_env | |
NU_POWER_MODE | |
'power' # power | fast | |
) | |
$env.NU_POWER_SCHEMA = (default_env | |
NU_POWER_SCHEMA | |
[ | |
[ | |
{source: pwd, color: '#353230'} | |
] | |
[ | |
{source: proxy, color: 'dark_gray'} | |
{source: host, color: '#353230'} | |
{source: time, color: '#666560'} | |
] | |
] | |
) | |
$env.NU_POWER_FRAME = (default_env | |
NU_POWER_FRAME | |
'default' # default | fill | |
) | |
$env.NU_POWER_DECORATOR = (default_env | |
NU_POWER_DECORATOR | |
'power' # power | plain | |
) | |
$env.NU_POWER_MENU_MARKER = (default_env | |
ER_MENU_MARKER NU_POW | |
{ | |
"| " : 'green' | |
": " : 'yellow' | |
"# " : 'blue' | |
"? " : 'red' | |
} | |
) | |
{ | |
pwd: { | |
default: (ansi light_green_bold) | |
out_home: (ansi xterm_gold3b) | |
proxy: { | |
on: (ansi yellow) | |
host: { | |
is_admin: (ansi yellow) | |
default: (ansi blue) | |
} | |
time: { | |
fst: (ansi xterm_tan) | |
snd: (ansi xterm_aqua) | |
} | |
} | |
) | |
$env.NU_POWER_CONFIG = (default_env | |
NU_POWER_CONFIG | |
{ | |
time: { | |
style: null | |
} | |
} | |
) | |
$env.NU_PROMPT_COMPONENTS = { | |
pwd: (pwd_abbr) | |
y_stat) proxy: (prox | |
time: (time_segment) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment