mirror of
https://github.com/RGBCube/nu_scripts
synced 2025-08-01 06:37:46 +00:00
some cleanup (#463)
This commit is contained in:
parent
c47ccd42b8
commit
92b29131db
4 changed files with 0 additions and 0 deletions
48
modules/prompt/powerline/README.md
Normal file
48
modules/prompt/powerline/README.md
Normal file
|
@ -0,0 +1,48 @@
|
|||
### configuration
|
||||
```
|
||||
use power.nu
|
||||
use power_git.nu
|
||||
power inject 0 1 {source: git, color: '#504945'}
|
||||
use power_kube.nu
|
||||
power inject 1 2 {source: kube, color: '#504945'} {
|
||||
context: (ansi magenta)
|
||||
}
|
||||
power init
|
||||
```
|
||||
or
|
||||
```
|
||||
let-env NU_POWER_SCHEMA = [
|
||||
[
|
||||
{source: pwd, color: '#353230'}
|
||||
{source: git, color: '#504945'}
|
||||
]
|
||||
[
|
||||
{source: proxy, color: 'dark_gray'}
|
||||
{source: host, color: '#353230'}
|
||||
{source: kube, color: '#504945'}
|
||||
{source: time, color: '#666560'}
|
||||
]
|
||||
]
|
||||
|
||||
use power.nu
|
||||
use power_git.nu
|
||||
use power_kube.nu
|
||||
power init
|
||||
```
|
||||
`$env.NU_POWER_SCHEMA` support configuring dynamically
|
||||
|
||||
## mode
|
||||
- `let-env NU_POWER_DECORATOR = '<power|plain>'` power mode and plain mode
|
||||
- `let-env NU_POWER_FRAME = '<default|fill>'` 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
|
||||
- [ ] implement `power eject`
|
||||
- [ ] `$env.config.menus[].maker` can be restored
|
||||
- [x] support color theme
|
||||
- [x] refactor: theme/decorator/frame/schema
|
||||
|
368
modules/prompt/powerline/power.nu
Normal file
368
modules/prompt/powerline/power.nu
Normal file
|
@ -0,0 +1,368 @@
|
|||
### pwd
|
||||
def related [sub dir] {
|
||||
if $sub == $dir {
|
||||
return { related: '=', path: '' }
|
||||
}
|
||||
let suffix = (do --ignore-errors { $sub | path relative-to $dir })
|
||||
if ($suffix | is-empty) {
|
||||
return { related: '>', path: '' }
|
||||
} else {
|
||||
return { related: '<', path: $suffix}
|
||||
}
|
||||
}
|
||||
|
||||
export def "pwd_abbr" [] {
|
||||
{||
|
||||
let pwd = ($env.PWD)
|
||||
|
||||
let to_home = (related $pwd $nu.home-path)
|
||||
|
||||
let cwd = if $to_home.related == '=' {
|
||||
"~"
|
||||
} else if $to_home.related == '>' {
|
||||
$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 substring ..2 }
|
||||
)
|
||||
$dir_comp = ([$first $body $last] | flatten)
|
||||
}
|
||||
|
||||
let theme = $env.NU_POWER_THEME.pwd
|
||||
let style = if $to_home.related == '>' {
|
||||
$theme.out_home
|
||||
} else {
|
||||
$theme.default
|
||||
}
|
||||
$"($style)($dir_comp | str join (char separator))"
|
||||
}
|
||||
}
|
||||
|
||||
### proxy
|
||||
export def proxy_stat [] {
|
||||
{||
|
||||
let theme = $env.NU_POWER_THEME.proxy
|
||||
if not (($env.https_proxy? | is-empty) and ($env.http_proxy? | is-empty)) {
|
||||
$theme.on
|
||||
} else {
|
||||
$nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### host
|
||||
def host_abbr [] {
|
||||
{||
|
||||
let theme = $env.NU_POWER_THEME.host
|
||||
let n = (hostname | str trim)
|
||||
let ucl = if (is-admin) {
|
||||
$theme.is_admin
|
||||
} else {
|
||||
$theme.default
|
||||
}
|
||||
$"($ucl)($n)"
|
||||
}
|
||||
}
|
||||
|
||||
### time
|
||||
def time_segment [] {
|
||||
{||
|
||||
let theme = $env.NU_POWER_THEME.time
|
||||
$"($theme.now)(date now | date format '%y-%m-%d/%H:%M:%S')"
|
||||
}
|
||||
}
|
||||
|
||||
### prompt
|
||||
def decorator [
|
||||
direction?: string
|
||||
color?: string = 'light_yellow'
|
||||
fg?: string
|
||||
] {
|
||||
match $env.NU_POWER_DECORATOR {
|
||||
'plain' => {
|
||||
match $direction {
|
||||
'>' => {
|
||||
let r = $'(ansi light_yellow)|'
|
||||
{|s| $"($s)($r)" }
|
||||
}
|
||||
'>>' => {
|
||||
{|s| $s }
|
||||
}
|
||||
'<'|'<<' => {
|
||||
let l = $'(ansi light_yellow)|'
|
||||
{|s| $"($l)($s)" }
|
||||
}
|
||||
}
|
||||
}
|
||||
'power' => {
|
||||
match $direction {
|
||||
'>' => {
|
||||
let l = (ansi -e {bg: $fg})
|
||||
let r = $'(ansi -e {fg: $fg, bg: $color})(char nf_left_segment)'
|
||||
{|s| $'($l)($s)($r)' }
|
||||
}
|
||||
'>>' => {
|
||||
let l = (ansi -e {bg: $fg})
|
||||
let r = $'(ansi reset)(ansi -e {fg: $fg})(char nf_left_segment)'
|
||||
{|s| $'($l)($s)($r)' }
|
||||
}
|
||||
'<'|'<<' => {
|
||||
let l = $'(ansi -e {fg: $color})(char nf_right_segment)(ansi -e {bg: $color})'
|
||||
{|s| $'($l)($s)' }
|
||||
}
|
||||
}
|
||||
}
|
||||
'dynamic' => {
|
||||
match $direction {
|
||||
'>' => {
|
||||
}
|
||||
'>>' => {
|
||||
}
|
||||
'<'|'<<' => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def squash [thunk] {
|
||||
mut r = ""
|
||||
for t in $thunk {
|
||||
let v = (do $t.0)
|
||||
if ($v != $nothing) {
|
||||
$r += (do $t.1 $v)
|
||||
}
|
||||
}
|
||||
$r
|
||||
}
|
||||
|
||||
def left_prompt [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})
|
||||
let cs = ($cs | prepend $cs.1?)
|
||||
let thunk = ($vs
|
||||
| zip $cs
|
||||
| enumerate
|
||||
| each {|x|
|
||||
if $x.index == $stop {
|
||||
[$x.item.0.1 (decorator '>>' $x.item.0.0 $x.item.1)]
|
||||
} else {
|
||||
[$x.item.0.1 (decorator '>' $x.item.0.0 $x.item.1)]
|
||||
}
|
||||
})
|
||||
{|| squash $thunk }
|
||||
}
|
||||
|
||||
def right_prompt [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)]
|
||||
} else {
|
||||
[$x.item.1 (decorator '<' $x.item.0)]
|
||||
}
|
||||
})
|
||||
{|| squash $thunk }
|
||||
}
|
||||
|
||||
def up_prompt [segment] {
|
||||
let thunk = ($segment
|
||||
| each {|y| $y | each {|x| $env.NU_PROMPT_COMPONENTS | get $x.source}
|
||||
})
|
||||
{ ||
|
||||
let ss = ($thunk
|
||||
| each {|y|
|
||||
$y
|
||||
| each {|x| do $x }
|
||||
| filter {|x| $x != $nothing }
|
||||
| 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 | columns)) {
|
||||
$env | get $name
|
||||
} else {
|
||||
$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)
|
||||
}
|
||||
'fill' => {
|
||||
let-env PROMPT_COMMAND = (up_prompt $env.NU_POWER_SCHEMA)
|
||||
}
|
||||
}
|
||||
|
||||
let-env PROMPT_INDICATOR = {||
|
||||
match $env.NU_POWER_DECORATOR {
|
||||
'plain' => { "> " }
|
||||
_ => { " " }
|
||||
}
|
||||
}
|
||||
let-env PROMPT_INDICATOR_VI_INSERT = {|| ": " }
|
||||
let-env PROMPT_INDICATOR_VI_NORMAL = {|| "> " }
|
||||
let-env PROMPT_MULTILINE_INDICATOR = {||
|
||||
match $env.NU_POWER_DECORATOR {
|
||||
'plain' => { "::: " }
|
||||
_ => { $"(char haze) " }
|
||||
}
|
||||
}
|
||||
|
||||
let-env config = ( $env.config | update menus ($env.config.menus
|
||||
| each {|x|
|
||||
if ($x.marker in ($env.NU_POWER_MENU_MARKER | columns)) {
|
||||
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 register [name source theme] {
|
||||
let-env NU_PROMPT_COMPONENTS = (
|
||||
$env.NU_PROMPT_COMPONENTS | upsert $name {|| $source }
|
||||
)
|
||||
let-env NU_POWER_THEME = (
|
||||
$env.NU_POWER_THEME | upsert $name $theme
|
||||
)
|
||||
}
|
||||
|
||||
export def-env inject [pos idx define theme?] {
|
||||
let prev = ($env.NU_POWER_SCHEMA | get $pos)
|
||||
let next = if $idx == 0 {
|
||||
$prev | prepend $define
|
||||
} else {
|
||||
[
|
||||
($prev | range 0..($idx - 1))
|
||||
$define
|
||||
($prev | range $idx..)
|
||||
] | flatten
|
||||
}
|
||||
|
||||
let-env NU_POWER_SCHEMA = (
|
||||
$env.NU_POWER_SCHEMA
|
||||
| update $pos $next
|
||||
)
|
||||
|
||||
if not ($theme | is-empty) {
|
||||
let kind = $define.source
|
||||
let prev_theme = ($env.NU_POWER_THEME | get $kind)
|
||||
let prev_cols = ($prev_theme | columns)
|
||||
let next_theme = ($theme | transpose k v)
|
||||
for n in $next_theme {
|
||||
if $n.k in $prev_cols {
|
||||
let-env NU_POWER_THEME = (
|
||||
$env.NU_POWER_THEME | update $kind {|conf|
|
||||
$conf | get $kind | update $n.k $n.v
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export def-env eject [] {
|
||||
"power eject not implement"
|
||||
}
|
||||
|
||||
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_SCHEMA $init
|
||||
| upsert NU_POWER_FRAME $init
|
||||
| upsert NU_POWER_DECORATOR $init
|
||||
| upsert NU_POWER_MENU_MARKER $init
|
||||
# NU_POWER_THEME
|
||||
})
|
||||
}
|
||||
|
||||
export-env {
|
||||
let-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'}
|
||||
]
|
||||
]
|
||||
)
|
||||
|
||||
let-env NU_POWER_FRAME = (default_env
|
||||
NU_POWER_FRAME
|
||||
'default' # default | fill
|
||||
)
|
||||
|
||||
let-env NU_POWER_DECORATOR = (default_env
|
||||
NU_POWER_DECORATOR
|
||||
'power' # power | plain
|
||||
)
|
||||
|
||||
let-env NU_POWER_MENU_MARKER = (default_env
|
||||
NU_POWER_MENU_MARKER
|
||||
{
|
||||
"| " : 'green'
|
||||
": " : 'yellow'
|
||||
"# " : 'blue'
|
||||
"? " : 'red'
|
||||
}
|
||||
)
|
||||
|
||||
let-env NU_POWER_THEME = (default_env
|
||||
NU_POWER_THEME
|
||||
{
|
||||
pwd: {
|
||||
default: (ansi light_green_bold)
|
||||
out_home: (ansi xterm_gold3b)
|
||||
}
|
||||
proxy: {
|
||||
on: (ansi yellow)
|
||||
}
|
||||
host: {
|
||||
is_admin: (ansi yellow)
|
||||
default: (ansi blue)
|
||||
}
|
||||
time: {
|
||||
now: (ansi xterm_tan)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
let-env NU_PROMPT_COMPONENTS = {
|
||||
pwd: (pwd_abbr)
|
||||
proxy: (proxy_stat)
|
||||
host: (host_abbr)
|
||||
time: (time_segment)
|
||||
}
|
||||
}
|
||||
|
148
modules/prompt/powerline/power_git.nu
Normal file
148
modules/prompt/powerline/power_git.nu
Normal file
|
@ -0,0 +1,148 @@
|
|||
### git
|
||||
export def git_status [] {
|
||||
let status = (do -i { gstat })
|
||||
if not ($status | is-empty) {
|
||||
return $status
|
||||
}
|
||||
|
||||
let raw_status = (do -i { git --no-optional-locks status --porcelain=2 --branch | lines })
|
||||
|
||||
mut status = {
|
||||
idx_added_staged : 0
|
||||
idx_modified_staged : 0
|
||||
idx_deleted_staged : 0
|
||||
idx_renamed : 0
|
||||
idx_type_changed : 0
|
||||
wt_untracked : 0
|
||||
wt_modified : 0
|
||||
wt_deleted : 0
|
||||
wt_type_changed : 0
|
||||
wt_renamed : 0
|
||||
ignored : 0
|
||||
conflicts : 0
|
||||
ahead : 0
|
||||
behind : 0
|
||||
stashes : 0
|
||||
repo_name : no_repository
|
||||
tag : no_tag
|
||||
branch : no_branch
|
||||
remote : ''
|
||||
}
|
||||
|
||||
if ($raw_status | is-empty) { return $status }
|
||||
|
||||
for s in $raw_status {
|
||||
let r = ($s | split row ' ')
|
||||
match $r.0 {
|
||||
'#' => {
|
||||
match ($r.1 | str substring 7..) {
|
||||
'oid' => {
|
||||
$status.commit_hash = ($r.2 | str substring 0..8)
|
||||
}
|
||||
'head' => {
|
||||
$status.branch = $r.2
|
||||
}
|
||||
'upstream' => {
|
||||
$status.remote = $r.2
|
||||
}
|
||||
'ab' => {
|
||||
$status.ahead = ($r.2 | into int)
|
||||
$status.behind = ($r.3 | into int | math abs)
|
||||
}
|
||||
}
|
||||
}
|
||||
'1'|'2' => {
|
||||
match ($r.1 | str substring 0..1) {
|
||||
'A' => {
|
||||
$status.idx_added_staged += 1
|
||||
}
|
||||
'M' => {
|
||||
$status.idx_modified_staged += 1
|
||||
}
|
||||
'R' => {
|
||||
$status.idx_renamed += 1
|
||||
}
|
||||
'D' => {
|
||||
$status.idx_deleted_staged += 1
|
||||
}
|
||||
'T' => {
|
||||
$status.idx_type_changed += 1
|
||||
}
|
||||
}
|
||||
match ($r.1 | str substring 1..2) {
|
||||
'M' => {
|
||||
$status.wt_modified += 1
|
||||
}
|
||||
'R' => {
|
||||
$status.wt_renamed += 1
|
||||
}
|
||||
'D' => {
|
||||
$status.wt_deleted += 1
|
||||
}
|
||||
'T' => {
|
||||
$status.wt_type_changed += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
'?' => {
|
||||
$status.wt_untracked += 1
|
||||
}
|
||||
'u' => {
|
||||
$status.conflicts += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return $status
|
||||
}
|
||||
|
||||
export def git_stat [] {
|
||||
{||
|
||||
let status = (git_status)
|
||||
|
||||
if $status.branch == 'no_branch' { return '' }
|
||||
|
||||
let theme = $env.NU_POWER_THEME.git
|
||||
let branch = if ($status.remote | is-empty) {
|
||||
$'($theme.no_upstream)($status.branch)'
|
||||
} else {
|
||||
$'($theme.default)($status.branch)'
|
||||
}
|
||||
|
||||
let summary = (
|
||||
$env.NU_PROMPT_GIT_FORMATTER
|
||||
| filter {|x| ($status | get $x.0) > 0 }
|
||||
| each {|x| $"(ansi $'light_($x.2)_dimmed')($x.1)($status | get $x.0)" }
|
||||
| str join
|
||||
)
|
||||
|
||||
$'($branch)($summary)'
|
||||
}
|
||||
}
|
||||
|
||||
export-env {
|
||||
let-env NU_PROMPT_GIT_FORMATTER = (power default_env
|
||||
NU_PROMPT_GIT_FORMATTER
|
||||
[
|
||||
[behind (char branch_behind) yellow]
|
||||
[ahead (char branch_ahead) yellow]
|
||||
[stashes = blue]
|
||||
[conflicts ! red]
|
||||
[ignored _ purple]
|
||||
[idx_added_staged + green]
|
||||
[idx_modified_staged ~ green]
|
||||
[idx_deleted_staged - green]
|
||||
[idx_renamed % green]
|
||||
[idx_type_changed * green]
|
||||
[wt_untracked + red]
|
||||
[wt_modified ~ red]
|
||||
[wt_deleted - red]
|
||||
[wt_renamed % red]
|
||||
[wt_type_changed * red]
|
||||
]
|
||||
)
|
||||
|
||||
power register git (git_stat) {
|
||||
default : (ansi blue)
|
||||
no_upstream: (ansi red)
|
||||
}
|
||||
}
|
35
modules/prompt/powerline/power_kube.nu
Normal file
35
modules/prompt/powerline/power_kube.nu
Normal file
|
@ -0,0 +1,35 @@
|
|||
### kubernetes
|
||||
def "kube ctx" [] {
|
||||
do -i {
|
||||
kubectl config get-contexts
|
||||
| from ssv -a
|
||||
| where CURRENT == '*'
|
||||
| get 0
|
||||
}
|
||||
}
|
||||
|
||||
def kube_stat [] {
|
||||
{||
|
||||
let ctx = (kube ctx)
|
||||
let theme = $env.NU_POWER_THEME.kube
|
||||
if ($ctx | is-empty) {
|
||||
""
|
||||
} else {
|
||||
let c = if $ctx.AUTHINFO == $ctx.CLUSTER {
|
||||
$ctx.CLUSTER
|
||||
} else {
|
||||
$"($ctx.AUTHINFO)@($ctx.CLUSTER)"
|
||||
}
|
||||
let p = $"($theme.context)($c)($theme.separator)/($theme.namespace)($ctx.NAMESPACE)"
|
||||
$"($p)" | str trim
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export-env {
|
||||
power register kube (kube_stat) {
|
||||
context: (ansi red)
|
||||
separator: (ansi yellow)
|
||||
namespace: (ansi cyan_bold)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue