Skip to content

Instantly share code, notes, and snippets.

@blindFS
Created January 1, 2025 03:34
Show Gist options
  • Save blindFS/64e42fd570ae62426ecdf01efbc2bd87 to your computer and use it in GitHub Desktop.
Save blindFS/64e42fd570ae62426ecdf01efbc2bd87 to your computer and use it in GitHub Desktop.
### 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