mirror of
https://github.com/Cian-H/dotfiles.git
synced 2026-03-11 23:58:03 +00:00
Changed . token to _dot
This change allows the dotfiles to work with chezmoi (e.g: on windows) and improves grepability with neovim/telescope
This commit is contained in:
31
dot_config/nushell/nu_scripts/modules/prompt/README.md
Normal file
31
dot_config/nushell/nu_scripts/modules/prompt/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Prompt Scripts
|
||||
|
||||
### Definition
|
||||
|
||||
These scripts should be used to draw a custom command prompt in nushell. They can include anything that we think is appropriate for prompts such as `git` commands, `starship`, `oh-my-posh`, etc.
|
||||
|
||||
#### starship.nu
|
||||
|
||||
File is in [starship](./starship.nu)
|
||||
|
||||
This describe how to use starship to make a leftprompt, the repo of starship is [here](https://github.com/starship/starship).
|
||||
|
||||
This script set the output of starship as leftprompt
|
||||
|
||||

|
||||
|
||||
#### shell_space.nu
|
||||
|
||||
File is in [shell_space](./shell_space.nu)
|
||||
|
||||
Use the function of shells in nu, you can view the function with the command following
|
||||
|
||||
```
|
||||
help shells
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### jalon-git.nu
|
||||
From https://github.com/JalonWong/nushell-prompt
|
||||

|
||||
@@ -0,0 +1,33 @@
|
||||
This module exports commands for creating a nushell prompt that computes git status (staged and
|
||||
unstaged changes) asynchronously. This can be useful in large git repos when it is slow to obtain
|
||||
this information synchronously.
|
||||
|
||||
To use this module:
|
||||
|
||||
0. Place the file `async-git-prompt.nu` in the `$nu.config-path` directory (this is the directory
|
||||
containing `init.nu` and `env.nu`).
|
||||
|
||||
1. Use the command `async-git-prompt-string` in your own `PROMPT_COMMAND` (the file prompt.nu
|
||||
contains an example of doing this.)
|
||||
At this point, your prompt will be computing the information synchronously, because the cache
|
||||
file does not yet exist.
|
||||
|
||||
2. In a repo where git is slow, run the command `async-git-prompt-refresh-cache`.
|
||||
Now, your prompt will be fast, but it also won't update automatically. You could investigate a good
|
||||
way to invalidate the cache automatically, but the manual alternative is:
|
||||
|
||||
3. Whenever you think your prompt might be stale, re-run the command `async-git-prompt-refresh-cache`.
|
||||
Your prompt will update on one of the next times that you hit <enter>.
|
||||
|
||||
4. It will probably be convenient to alias this, e.g.
|
||||
|
||||
```nu
|
||||
alias r = async-git-prompt-refresh-cache
|
||||
```
|
||||
|
||||
5. To go back to synchronous mode, run `async-git-prompt-delete-cache`.
|
||||
|
||||
### TODO
|
||||
|
||||
- Automatic cache invalidation
|
||||
- Show untracked files (this can be very expensive in large repos)
|
||||
@@ -0,0 +1,77 @@
|
||||
# This module exports commands for creating a nushell prompt that computes git status (staged and
|
||||
# unstaged changes) asynchronously. This can be useful in large git repos when it is slow to obtain
|
||||
# this information synchronously.
|
||||
|
||||
# See README.md for usage.
|
||||
|
||||
def unstaged-symbol [] { 'અ' }
|
||||
def staged-symbol [] { 'જ' }
|
||||
def in-progress-symbol [] { '…' }
|
||||
def cached-result-symbol [] { $"·" } #〈
|
||||
def cache-file [] { '.nu-async-git-prompt-cache'}
|
||||
|
||||
def do-async [commands: string] {
|
||||
bash -c $"nu -c '($commands)' &"
|
||||
}
|
||||
|
||||
export def async-git-prompt-string [] {
|
||||
let cache_path = (cache-path)
|
||||
if ($cache_path | is-empty) {
|
||||
""
|
||||
} else if ($cache_path | path exists) {
|
||||
$"(cached-result-symbol)(open $cache_path | str trim)"
|
||||
} else {
|
||||
async-git-prompt-compute-sync
|
||||
}
|
||||
}
|
||||
|
||||
export def async-git-prompt-compute-sync [] {
|
||||
let unstaged = {
|
||||
let symbol = if ((git diff --quiet | complete).exit_code == 1) {
|
||||
(unstaged-symbol)
|
||||
} else {
|
||||
''
|
||||
}
|
||||
{ unstaged: $symbol}
|
||||
}
|
||||
let staged = {
|
||||
let symbol = if ((git diff --cached --quiet | complete).exit_code == 1) {
|
||||
(staged-symbol)
|
||||
} else {
|
||||
''
|
||||
}
|
||||
{ staged: $symbol}
|
||||
}
|
||||
# Execute the two slow git commands in parallel and merge the results into a single record
|
||||
let symbols = ([ $unstaged $staged ] | par-each { |it| do $it } | reduce {|a b| $a | merge {$b}})
|
||||
|
||||
$"($symbols | get 'unstaged') ($symbols | get 'staged')" | str trim
|
||||
}
|
||||
|
||||
export def async-git-prompt-refresh-cache [] {
|
||||
let cache_path = (cache-path)
|
||||
if ($cache_path != null) {
|
||||
echo (in-progress-symbol) | save $cache_path
|
||||
do-async $"use ($nu.config-path | path expand | path dirname)/async-git-prompt.nu *; async-git-prompt-compute-sync | save ($cache_path)"
|
||||
}
|
||||
}
|
||||
|
||||
export def async-git-prompt-delete-cache [] {
|
||||
let cache_path = (cache-path)
|
||||
if ($cache_path != null) {
|
||||
rm -f $cache_path
|
||||
}
|
||||
}
|
||||
|
||||
def cache-path [] {
|
||||
let dir = if ('.git' | path exists) {
|
||||
'.'
|
||||
} else {
|
||||
do -i { git rev-parse --show-toplevel | str trim -r }
|
||||
}
|
||||
if ($dir | is-empty) {
|
||||
null
|
||||
} else {
|
||||
$dir | path join (cache-file)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
# This file contains an example nushell prompt, making use of the async-git-prompt module.
|
||||
use async-git-prompt.nu *
|
||||
|
||||
def prompt-concat [parts: table] {
|
||||
$parts
|
||||
| where (not ($it.text | is-empty))
|
||||
| each { |it| $"($it.color)($it.text)" }
|
||||
| str join ' '
|
||||
}
|
||||
|
||||
def prompt-git-branch [] {
|
||||
do -i { git rev-parse --abbrev-ref HEAD | str trim -r}
|
||||
}
|
||||
|
||||
def prompt-create-left-prompt [] {
|
||||
let pwd = ($env.PWD | str replace $env.HOME '~')
|
||||
prompt-concat [
|
||||
[text color];
|
||||
[pwd (ansi green_bold)]
|
||||
[(prompt-git-branch) (ansi blue_bold)]
|
||||
[(async-git-prompt-string) (ansi green_bold)]
|
||||
]
|
||||
}
|
||||
|
||||
def prompt-create-right-prompt [] {
|
||||
null
|
||||
}
|
||||
|
||||
$env.PROMPT_COMMAND = { prompt-create-left-prompt }
|
||||
$env.PROMPT_COMMAND_RIGHT = { prompt-create-right-prompt }
|
||||
$env.PROMPT_INDICATOR = { $" (ansi green_bold)〉" }
|
||||
70
dot_config/nushell/nu_scripts/modules/prompt/basic-git.nu
Normal file
70
dot_config/nushell/nu_scripts/modules/prompt/basic-git.nu
Normal file
@@ -0,0 +1,70 @@
|
||||
# Max Brown
|
||||
# a very basic git prompt
|
||||
# sort of like panache-git, but fewer than 60 lines of code.
|
||||
|
||||
# use as below without the comments and in your
|
||||
# env.nu file
|
||||
|
||||
|
||||
# use path/to/basic-git.nu basic-git-left-prompt
|
||||
|
||||
# $env.PROMPT_COMMAND = {||
|
||||
# let left = create_left_prompt
|
||||
# basic-git-left-prompt $left
|
||||
# }
|
||||
|
||||
def in_git_repo [] {
|
||||
(do --ignore-errors { git rev-parse --abbrev-ref HEAD } | is-empty) == false
|
||||
}
|
||||
|
||||
export def basic-git-left-prompt [in_left_prompt] {
|
||||
|
||||
# if we're in a repo, let's go!
|
||||
let currently_in_git_repo = in_git_repo
|
||||
|
||||
if $currently_in_git_repo {
|
||||
# get the branch info first
|
||||
let branch_info = git branch -l
|
||||
| lines
|
||||
| filter {|e| $e | str contains "*" }
|
||||
| each {|e| $e | str replace "* " "="}
|
||||
| get 0
|
||||
let git_status = git status -s
|
||||
|
||||
# get the status in short
|
||||
let git_status = $git_status
|
||||
| lines
|
||||
| str replace -r '(.* ).*' '$1'
|
||||
| sort
|
||||
| uniq -c
|
||||
| insert type {
|
||||
|e| if ($e.value | str contains "M") {
|
||||
"blue_bold"
|
||||
} else if ($e.value | str contains "??") {
|
||||
"yellow_bold"
|
||||
} else if ($e.value | str contains "D") {
|
||||
"red_bold"
|
||||
} else if ($e.value | str contains "A") {
|
||||
"cyan_bold"
|
||||
} else ""
|
||||
}
|
||||
| each {
|
||||
|e| $"(ansi $e.type)($e.count)($e.value | str trim)(ansi reset)"
|
||||
}
|
||||
| reduce --fold '' {|str all| $"($all),($str)" }
|
||||
| str substring 1..
|
||||
|
||||
let final_git_status = if $git_status == "" {
|
||||
""
|
||||
} else {
|
||||
$" ($git_status)"
|
||||
}
|
||||
|
||||
# construct the prompt
|
||||
$"($in_left_prompt)(ansi reset) [($branch_info)($final_git_status)]"
|
||||
|
||||
} else {
|
||||
# otherwise just return the normal prompt
|
||||
$in_left_prompt
|
||||
}
|
||||
}
|
||||
512
dot_config/nushell/nu_scripts/modules/prompt/full-line.nu
Normal file
512
dot_config/nushell/nu_scripts/modules/prompt/full-line.nu
Normal file
@@ -0,0 +1,512 @@
|
||||
# Build a full-line prompt with widgets for:
|
||||
# activated python virtual environment (from `overlay use <ve>/bin/activate.nu`)
|
||||
# current working directory
|
||||
# git status (branch, branch ahead/behind remote, files changed)
|
||||
# current position in remembered working directories (`std dirs`, a.k.a. `shells`)
|
||||
# also, as a nu dev special, widget for active nu executable (flags `cargo run` vs "installed" and which branch built from).
|
||||
#
|
||||
# to use:
|
||||
# 1. copy this file to `($nu.default-config-dir | path add 'scripts')` (Or someplace on your $env.NU_LIB_DIRS path, defined in env.nu)
|
||||
# 2. cut `$env.PROMPT_COMMAND` and `PROMPT_OMMAND_RIGHT' from your env.nu.
|
||||
# These will depend on `use full-line`, which can not be done in env.nu.
|
||||
# You can leave the `PROMPT-*INDICATOR*` statements in env.nu or
|
||||
# consolidate all prompt stuff in config.nu.
|
||||
# 3. Add new prompt setup stuff somewhere in config.nu:
|
||||
# ```
|
||||
# use full-line.nu
|
||||
# $env.PROMPT_COMMAND = {|| full-line }
|
||||
# $env.PROMPT_COMMAND_RIGHT = ""
|
||||
# ```
|
||||
#
|
||||
# credit panache-git for the git status widget.
|
||||
|
||||
use std dirs
|
||||
use std assert
|
||||
|
||||
# build the prompt from segments, looks like:
|
||||
#
|
||||
# ^(<py ve>) ------------ <workingDirectory> ------ <gitRepoStatus> --- <dirs>$
|
||||
#
|
||||
# or, if no git repo current directory
|
||||
#
|
||||
# ^------------------------------------ <workingDirectory> ------------ <dirs>$
|
||||
export def main [
|
||||
--pad_char (-p) = '-' # character to fill with
|
||||
] {
|
||||
let left_content = ($"(
|
||||
if 'VIRTUAL_ENV_PROMPT' in $env {'(' + $env.VIRTUAL_ENV_PROMPT + ') '}
|
||||
)($pad_char + $pad_char + $pad_char)(current_exe)")
|
||||
let left_content_len = ($left_content | ansi strip | str length -g)
|
||||
|
||||
let mid_content = ($" (dir_string) ")
|
||||
let mid_content_len = ($mid_content | ansi strip | str length -g)
|
||||
|
||||
let dirs_segment = $" |(dirs show | each {|it| if $it.active {'V'} else {'.'}} | str join '')|"
|
||||
let right_content = ($"(repo-styled)($pad_char + $pad_char + $pad_char)($dirs_segment)")
|
||||
let right_content_len = ($right_content | ansi strip | str length -g)
|
||||
|
||||
let term_width = ((term size) | get columns)
|
||||
let mid_padding = ($term_width - $left_content_len - $right_content_len)
|
||||
|
||||
[(ansi reset),
|
||||
$left_content,
|
||||
($mid_content | fill --character $pad_char --width $mid_padding --alignment center),
|
||||
$right_content,
|
||||
"\n"
|
||||
] | str join ''
|
||||
}
|
||||
|
||||
# build current exe widget
|
||||
def current_exe [] {
|
||||
let content = ([
|
||||
($nu.current-exe | path dirname | path basename | str replace "bin" ""),
|
||||
(version | get branch | str replace "main" ""),
|
||||
] | str join " " | str trim)
|
||||
(if (($content | str length) > 0) {
|
||||
$"(' <' | bright-yellow)($content)('> ' | bright-yellow)"
|
||||
} else {
|
||||
""
|
||||
})
|
||||
}
|
||||
|
||||
# build current working directory segment
|
||||
## don't get sucked into the path syntax wars: simply color portions of path to flag priviliged vs normal user mode.
|
||||
def dir_string [] {
|
||||
|
||||
let path_color = (if (is-admin) { ansi red_bold } else { ansi green_bold })
|
||||
let separator_color = (if (is-admin) { ansi light_red_bold } else { ansi light_green_bold })
|
||||
$"($path_color)($env.PWD)(ansi reset)" | str replace --all (char path_sep) $"($separator_color)(char path_sep)($path_color)"
|
||||
}
|
||||
|
||||
# Following code cheerfully ~~stolen~~ adapted from:
|
||||
# https://github.com/nushell/nu_scripts/blob/ab0d3aaad015ca8ac2c2004d728cc8bac32cda1b/modules/prompt/panache-git.nu
|
||||
|
||||
# Get repository status as structured data
|
||||
def repo-structured [] {
|
||||
let in_git_repo = ((git rev-parse HEAD err> /dev/null | complete | get exit_code) == 0)
|
||||
|
||||
let status = (if $in_git_repo {
|
||||
git --no-optional-locks status --porcelain=2 --branch | lines
|
||||
} else {
|
||||
[]
|
||||
})
|
||||
|
||||
let on_named_branch = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.head')
|
||||
| first
|
||||
| str contains '(detached)'
|
||||
| nope
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let branch_name = (if $on_named_branch {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.head')
|
||||
| split column ' ' col1 col2 branch
|
||||
| get branch
|
||||
| first
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let commit_hash = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.oid')
|
||||
| split column ' ' col1 col2 full_hash
|
||||
| get full_hash
|
||||
| first
|
||||
| str substring 0..7
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let tracking_upstream_branch = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.upstream')
|
||||
| str join
|
||||
| is-empty
|
||||
| nope
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let upstream_exists_on_remote = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.ab')
|
||||
| str join
|
||||
| is-empty
|
||||
| nope
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let ahead_behind_table = (if $upstream_exists_on_remote {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.ab')
|
||||
| split column ' ' col1 col2 ahead behind
|
||||
} else {
|
||||
[[]]
|
||||
})
|
||||
|
||||
let commits_ahead = (if $upstream_exists_on_remote {
|
||||
$ahead_behind_table
|
||||
| get ahead
|
||||
| first
|
||||
| into int
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let commits_behind = (if $upstream_exists_on_remote {
|
||||
$ahead_behind_table
|
||||
| get behind
|
||||
| first
|
||||
| into int
|
||||
| math abs
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let has_staging_or_worktree_changes = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '1') or ($it | str starts-with '2')
|
||||
| str join
|
||||
| is-empty
|
||||
| nope
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let has_untracked_files = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '?')
|
||||
| str join
|
||||
| is-empty
|
||||
| nope
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let has_unresolved_merge_conflicts = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with 'u')
|
||||
| str join
|
||||
| is-empty
|
||||
| nope
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let staging_worktree_table = (if $has_staging_or_worktree_changes {
|
||||
$status
|
||||
| where ($it | str starts-with '1') or ($it | str starts-with '2')
|
||||
| split column ' '
|
||||
| get column2
|
||||
| split column '' staging worktree --collapse-empty
|
||||
} else {
|
||||
[[]]
|
||||
})
|
||||
|
||||
let staging_added_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where staging == 'A'
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let staging_modified_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where staging in ['M', 'R']
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let staging_deleted_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where staging == 'D'
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let untracked_count = (if $has_untracked_files {
|
||||
$status
|
||||
| where ($it | str starts-with '?')
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let worktree_modified_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where worktree in ['M', 'R']
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let worktree_deleted_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where worktree == 'D'
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let merge_conflict_count = (if $has_unresolved_merge_conflicts {
|
||||
$status
|
||||
| where ($it | str starts-with 'u')
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
{
|
||||
in_git_repo: $in_git_repo,
|
||||
on_named_branch: $on_named_branch,
|
||||
branch_name: $branch_name,
|
||||
commit_hash: $commit_hash,
|
||||
tracking_upstream_branch: $tracking_upstream_branch,
|
||||
upstream_exists_on_remote: $upstream_exists_on_remote,
|
||||
commits_ahead: $commits_ahead,
|
||||
commits_behind: $commits_behind,
|
||||
staging_added_count: $staging_added_count,
|
||||
staging_modified_count: $staging_modified_count,
|
||||
staging_deleted_count: $staging_deleted_count,
|
||||
untracked_count: $untracked_count,
|
||||
worktree_modified_count: $worktree_modified_count,
|
||||
worktree_deleted_count: $worktree_deleted_count,
|
||||
merge_conflict_count: $merge_conflict_count
|
||||
}
|
||||
}
|
||||
|
||||
# Get repository status as a styled string
|
||||
def repo-styled [] {
|
||||
let status = (repo-structured)
|
||||
|
||||
let is_local_only = ($status.tracking_upstream_branch != true)
|
||||
|
||||
let upstream_deleted = (
|
||||
$status.tracking_upstream_branch and
|
||||
$status.upstream_exists_on_remote != true
|
||||
)
|
||||
|
||||
let is_up_to_date = (
|
||||
$status.upstream_exists_on_remote and
|
||||
$status.commits_ahead == 0 and
|
||||
$status.commits_behind == 0
|
||||
)
|
||||
|
||||
let is_ahead = (
|
||||
$status.upstream_exists_on_remote and
|
||||
$status.commits_ahead > 0 and
|
||||
$status.commits_behind == 0
|
||||
)
|
||||
|
||||
let is_behind = (
|
||||
$status.upstream_exists_on_remote and
|
||||
$status.commits_ahead == 0 and
|
||||
$status.commits_behind > 0
|
||||
)
|
||||
|
||||
let is_ahead_and_behind = (
|
||||
$status.upstream_exists_on_remote and
|
||||
$status.commits_ahead > 0 and
|
||||
$status.commits_behind > 0
|
||||
)
|
||||
|
||||
let branch_name = (if $status.in_git_repo {
|
||||
(if $status.on_named_branch {
|
||||
$status.branch_name
|
||||
} else {
|
||||
['(' $status.commit_hash '...)'] | str join
|
||||
})
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let branch_styled = (if $status.in_git_repo {
|
||||
(if $is_local_only {
|
||||
(branch-local-only $branch_name)
|
||||
} else if $is_up_to_date {
|
||||
(branch-up-to-date $branch_name)
|
||||
} else if $is_ahead {
|
||||
(branch-ahead $branch_name $status.commits_ahead)
|
||||
} else if $is_behind {
|
||||
(branch-behind $branch_name $status.commits_behind)
|
||||
} else if $is_ahead_and_behind {
|
||||
(branch-ahead-and-behind $branch_name $status.commits_ahead $status.commits_behind)
|
||||
} else if $upstream_deleted {
|
||||
(branch-upstream-deleted $branch_name)
|
||||
} else {
|
||||
$branch_name
|
||||
})
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let has_staging_changes = (
|
||||
$status.staging_added_count > 0 or
|
||||
$status.staging_modified_count > 0 or
|
||||
$status.staging_deleted_count > 0
|
||||
)
|
||||
|
||||
let has_worktree_changes = (
|
||||
$status.untracked_count > 0 or
|
||||
$status.worktree_modified_count > 0 or
|
||||
$status.worktree_deleted_count > 0 or
|
||||
$status.merge_conflict_count > 0
|
||||
)
|
||||
|
||||
let has_merge_conflicts = $status.merge_conflict_count > 0
|
||||
|
||||
let staging_summary = (if $has_staging_changes {
|
||||
(staging-changes $status.staging_added_count $status.staging_modified_count $status.staging_deleted_count)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let worktree_summary = (if $has_worktree_changes {
|
||||
(worktree-changes $status.untracked_count $status.worktree_modified_count $status.worktree_deleted_count)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let merge_conflict_summary = (if $has_merge_conflicts {
|
||||
(unresolved-conflicts $status.merge_conflict_count)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let delimiter = (if ($has_staging_changes and $has_worktree_changes) {
|
||||
('|' | bright-yellow)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let local_summary = (
|
||||
$'($staging_summary) ($delimiter) ($worktree_summary) ($merge_conflict_summary)' | str trim
|
||||
)
|
||||
|
||||
let local_indicator = (if $status.in_git_repo {
|
||||
(if $has_worktree_changes {
|
||||
('!' | red)
|
||||
} else if $has_staging_changes {
|
||||
('~' | bright-cyan)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let repo_summary = (
|
||||
$'($branch_styled) ($local_summary) ($local_indicator)' | str trim
|
||||
)
|
||||
|
||||
let left_bracket = ('[' | bright-yellow)
|
||||
let right_bracket = (']' | bright-yellow)
|
||||
|
||||
(if $status.in_git_repo {
|
||||
$' ($left_bracket)($repo_summary)($right_bracket) '
|
||||
} else {
|
||||
''
|
||||
})
|
||||
}
|
||||
|
||||
# Helper commands to encapsulate style and make everything else more readable
|
||||
|
||||
def nope [] {
|
||||
each { |it| $it == false }
|
||||
}
|
||||
|
||||
def bright-cyan [] {
|
||||
each { |it| $"(ansi -e '96m')($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def bright-green [] {
|
||||
each { |it| $"(ansi -e '92m')($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def bright-red [] {
|
||||
each { |it| $"(ansi -e '91m')($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def bright-yellow [] {
|
||||
each { |it| $"(ansi -e '93m')($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def green [] {
|
||||
each { |it| $"(ansi green)($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def red [] {
|
||||
each { |it| $"(ansi red)($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def branch-local-only [
|
||||
branch: string
|
||||
] {
|
||||
$branch | bright-cyan
|
||||
}
|
||||
|
||||
def branch-upstream-deleted [
|
||||
branch: string
|
||||
] {
|
||||
$'($branch) (char failed)' | bright-cyan
|
||||
}
|
||||
|
||||
def branch-up-to-date [
|
||||
branch: string
|
||||
] {
|
||||
$'($branch) (char identical_to)' | bright-cyan
|
||||
}
|
||||
|
||||
def branch-ahead [
|
||||
branch: string
|
||||
ahead: int
|
||||
] {
|
||||
$'($branch) (char branch_ahead)($ahead)' | bright-green
|
||||
}
|
||||
|
||||
def branch-behind [
|
||||
branch: string
|
||||
behind: int
|
||||
] {
|
||||
$'($branch) (char branch_behind)($behind)' | bright-red
|
||||
}
|
||||
|
||||
def branch-ahead-and-behind [
|
||||
branch: string
|
||||
ahead: int
|
||||
behind: int
|
||||
] {
|
||||
$'($branch) (char branch_behind)($behind) (char branch_ahead)($ahead)' | bright-yellow
|
||||
}
|
||||
|
||||
def staging-changes [
|
||||
added: int
|
||||
modified: int
|
||||
deleted: int
|
||||
] {
|
||||
$'+($added) ~($modified) -($deleted)' | green
|
||||
}
|
||||
|
||||
def worktree-changes [
|
||||
added: int
|
||||
modified: int
|
||||
deleted: int
|
||||
] {
|
||||
$'+($added) ~($modified) -($deleted)' | red
|
||||
}
|
||||
|
||||
def unresolved-conflicts [
|
||||
conflicts: int
|
||||
] {
|
||||
$'!($conflicts)' | red
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
# Displays a prompt
|
||||
export def git-status-prompt [] {
|
||||
let not_windows = ($nu.os-info.name !~ "windows")
|
||||
$"(ansi reset)(ansi green)(if $not_windows {
|
||||
$env.USER
|
||||
} else {
|
||||
$env.USERNAME
|
||||
}
|
||||
)(ansi reset)@(hostname | str trim):(ansi green_dimmed)(prompt-pwd)(ansi reset)(git-branch-icon)(ansi reset)(char newline)(char prompt) "
|
||||
}
|
||||
|
||||
# Returns a shortened pwd for use in prompt
|
||||
def prompt-pwd [] {
|
||||
let not_windows = ($nu.os-info.name !~ "windows")
|
||||
let path = (pwd | if $not_windows { split row "/" } else { split row '\' })
|
||||
let home = (if $not_windows {
|
||||
($env.HOME | split row "/")
|
||||
} else {
|
||||
(echo [$env.HOMEDRIVE $env.HOMEPATH] | path join | split row '\')
|
||||
}
|
||||
)
|
||||
|
||||
if ($path | length) > 1 {
|
||||
if ($home | all {|it| $it in $path }) {
|
||||
let path_without_home = ($path | skip ($home | length))
|
||||
if ($path_without_home | wrap path | compact | length) > 0 {
|
||||
let parent = ($path | skip ($home | length) | drop)
|
||||
if ($parent | wrap parent | compact | length) > 0 {
|
||||
let short_part = ($parent | each { |part|
|
||||
if ($part | str starts-with ".") {
|
||||
$"($part | str substring [0 2])/"
|
||||
} else {
|
||||
$"($part | str substring [0 1])/"
|
||||
}
|
||||
})
|
||||
$"~/( | str join)($path | last)"
|
||||
} else {
|
||||
$"~/($path | last)"
|
||||
}
|
||||
} else {
|
||||
"~"
|
||||
}
|
||||
} else {
|
||||
let parent = (echo $path | drop | str substring [0 1] | each {|it| echo $it "/" })
|
||||
$"/($parent)($path | last)"
|
||||
}
|
||||
} else {
|
||||
pwd
|
||||
}
|
||||
}
|
||||
|
||||
# Map of git status codes to ANSI colour codes
|
||||
def git-prompt-map [] {
|
||||
echo a m r c d "??" u |
|
||||
rotate --ccw |
|
||||
reject column0 | append (
|
||||
echo (ansi green) (ansi yellow_bold) (ansi cyan) (ansi blue) (ansi red) (ansi red_dimmed) (ansi red) |
|
||||
rotate --ccw |
|
||||
reject column0
|
||||
) | headers
|
||||
}
|
||||
|
||||
# Gets an icon and a colour for a given git status code
|
||||
def git-prompt-icons [k] {
|
||||
let icns = ["✚ " "* " "➜ " "⇒ " "✖ " "? " "! "];
|
||||
|
||||
git-prompt-map |
|
||||
transpose status colour | enumerate | each { |icon|
|
||||
let idx = $icon.index;
|
||||
if $icon.item.status == $k {
|
||||
$"($icon.item.colour)($icns | get $idx)"
|
||||
}
|
||||
} | compact
|
||||
}
|
||||
|
||||
# Checks git status of current working directory and displays an icon
|
||||
def git-branch-icon [] {
|
||||
do -i {
|
||||
let branch = (do -i { git rev-parse --abbrev-ref HEAD } | str trim)
|
||||
|
||||
if ($branch | str length) > 0 {
|
||||
let modified = (do -i { git status --porcelain } | split row "\n" | str trim | split column " " status file);
|
||||
if ($modified | get 0 | first | is-empty) {
|
||||
$"|(ansi green)($branch)(ansi reset):(ansi green)✓(ansi reset)"
|
||||
} else {
|
||||
let modified2 = (do -i { git status --porcelain } | split row "\n" | str substring [0 1])
|
||||
let branch_colour = (if (echo $modified2 | each {|it| $it in [A M R C D] } | reduce {|it acc| $it or $acc }) {
|
||||
"yellow"
|
||||
} else {
|
||||
"red"
|
||||
}
|
||||
)
|
||||
$"|(ansi $branch_colour)($branch)(ansi reset):($modified | get status | uniq | str downcase | each {|it| git-prompt-icons $it })" | str join
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
BIN
dot_config/nushell/nu_scripts/modules/prompt/images/starship.png
Normal file
BIN
dot_config/nushell/nu_scripts/modules/prompt/images/starship.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
377
dot_config/nushell/nu_scripts/modules/prompt/jalon-git.nu
Normal file
377
dot_config/nushell/nu_scripts/modules/prompt/jalon-git.nu
Normal file
@@ -0,0 +1,377 @@
|
||||
# $env.PROMPT_INDICATOR = {|| "" }
|
||||
#
|
||||
# $env.PROMPT_COMMAND = {|| full-left-prompt }
|
||||
# or
|
||||
# $env.PROMPT_COMMAND = {|| left-prompt [
|
||||
# 'user',
|
||||
# 'dir',
|
||||
# 'fast-git'
|
||||
# 'duration',
|
||||
# ]}
|
||||
#
|
||||
# Optional:
|
||||
# $env.PROMPT_COMMAND_RIGHT = {|| "" }
|
||||
|
||||
export def full-left-prompt [] {
|
||||
(par-left-prompt [
|
||||
'user-host',
|
||||
'dir',
|
||||
'full-git'
|
||||
'duration',
|
||||
'wsl',
|
||||
])
|
||||
}
|
||||
|
||||
# Filter ----------------------------------------------------------------------
|
||||
|
||||
export def left-prompt [modules: list] {
|
||||
let ret = ($modules | each { |name| (exec-module $name)} | append $'(prompt-indicator)' | str join)
|
||||
$'(ansi reset)($ret)'
|
||||
}
|
||||
|
||||
# Parallel run
|
||||
export def par-left-prompt [modules: list] {
|
||||
let str_table = ($modules | par-each { |name|
|
||||
{ name: $name, content: (exec-module $name) }
|
||||
})
|
||||
let ret = ($modules | each { |name| ($str_table | where name == $'($name)' | get content.0)} | append $'(prompt-indicator)' | str join)
|
||||
$'(ansi reset)($ret)'
|
||||
}
|
||||
|
||||
def exec-module [name: string] {
|
||||
if $name == 'user-host' {
|
||||
(username-style true)
|
||||
} else if $name == 'user' {
|
||||
(username-style false)
|
||||
} else if $name == 'dir' {
|
||||
$'(current-dir-style) (read-only-style)'
|
||||
} else if $name == 'fast-git' {
|
||||
(fast-git-style)
|
||||
} else if $name == 'full-git' {
|
||||
(full-git-style)
|
||||
} else if $name == 'duration' {
|
||||
(duration-style)
|
||||
} else if $name == 'wsl' {
|
||||
(wsl-style)
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
# Styles ----------------------------------------------------------------------
|
||||
|
||||
def get-styles [] {
|
||||
{
|
||||
USER_STYLE: (ansi green),
|
||||
PATH_STYLE: (ansi light_blue),
|
||||
BRANCH_STYLE: (ansi dark_gray_bold),
|
||||
AHEAD_STYLE: $'(ansi green)(char branch_ahead)',
|
||||
BEHIND_STYLE: $'(ansi yellow_bold)(char branch_behind)',
|
||||
STAGE_STYLE: $'(ansi blue)S(ansi reset)',
|
||||
UNSTAGE_STYLE: $'(ansi dark_gray)U(ansi reset)',
|
||||
NEW_FILE_STYLE: $'(ansi green)N',
|
||||
ADD_FILE_STYLE: $'(ansi green)A',
|
||||
MODIFY_FILE_STYLE: $'(ansi yellow)M',
|
||||
DELETE_FILE_STYLE: $'(ansi red)D',
|
||||
CONFLICT_FILE_STYLE: $'(ansi light_purple_bold)C',
|
||||
DURATION_STYLE: (ansi yellow),
|
||||
}
|
||||
}
|
||||
|
||||
def prompt-indicator [] {
|
||||
if ($env.LAST_EXIT_CODE | into int) == 0 {
|
||||
$"\r\n(ansi cyan)> "
|
||||
} else {
|
||||
$"\r\n(ansi red)x "
|
||||
}
|
||||
}
|
||||
|
||||
def username-style [show_host: bool] {
|
||||
let s = get-styles
|
||||
let name = (get-username)
|
||||
if $show_host and (is-ssh-session) {
|
||||
$'($s.USER_STYLE)($name)(ansi dark_gray)@($s.USER_STYLE)(get-hostname)(ansi dark_gray):(ansi reset)'
|
||||
} else if (is-self-user $name) == false {
|
||||
$'($s.USER_STYLE)($name)(ansi dark_gray):(ansi reset)'
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
def wsl-style [] {
|
||||
if 'WSLENV' in $env {
|
||||
$'(ansi dark_gray) WSL(ansi reset)'
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
# Get the current directory with home abbreviated
|
||||
def current-dir-style [] {
|
||||
let s = get-styles
|
||||
let current_dir = ($env.PWD)
|
||||
|
||||
let current_dir_abbreviated = if $current_dir == $nu.home-path {
|
||||
'~'
|
||||
} else {
|
||||
let current_dir_relative_to_home = (
|
||||
do --ignore-errors { $current_dir | path relative-to $nu.home-path } | str join
|
||||
)
|
||||
|
||||
if ($current_dir_relative_to_home | is-empty) == false {
|
||||
$'~(char separator)($current_dir_relative_to_home)'
|
||||
} else {
|
||||
$current_dir
|
||||
}
|
||||
}
|
||||
|
||||
if (is-admin) {
|
||||
$'(ansi red_bold)($current_dir_abbreviated)(ansi reset)'
|
||||
} else {
|
||||
$'($s.PATH_STYLE)($current_dir_abbreviated)(ansi reset)'
|
||||
}
|
||||
}
|
||||
|
||||
def read-only-style [] {
|
||||
if (ls -Dl $env.PWD | get readonly.0) {
|
||||
$'[(ansi red_bold)ro(ansi reset)]'
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
def duration-style [] {
|
||||
let s = get-styles
|
||||
mut secs = ($env.CMD_DURATION_MS | into int) / 1000
|
||||
if $secs > 1 {
|
||||
mut ret = [$'[took ($s.DURATION_STYLE)']
|
||||
|
||||
if $secs >= 3600 {
|
||||
$ret = ($ret | append $'($secs // 3600)h ($secs mod 3600 // 60)m ')
|
||||
$secs = $secs mod 60
|
||||
} else if $secs >= 60 {
|
||||
$ret = ($ret | append $'($secs // 60)m ')
|
||||
$secs = $secs mod 60
|
||||
}
|
||||
|
||||
($ret | append $'($secs | math round -p 1)s(ansi reset)]' | str join)
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
def fast-git-style [] {
|
||||
let s = get-styles
|
||||
let b_info = (do -p { git --no-optional-locks branch -v } | str trim)
|
||||
if ($b_info | is-empty) {
|
||||
''
|
||||
} else {
|
||||
let info = ($b_info | parse -r '\* (?<name>(\([\S ]+\))|([\w\/\-\.]+)) +\w+ (\[((?<state>[^\]]+))+\])?')
|
||||
let state_list = ($info.state.0 | split row ', ' | each { |it|
|
||||
let p = ($it | parse "{s} {n}")
|
||||
if ($p | is-empty) {
|
||||
if ($it | str starts-with "gone") {
|
||||
$' (ansi light_red)(char failed)'
|
||||
} else {
|
||||
''
|
||||
}
|
||||
} else if $p.s.0 == 'ahead' {
|
||||
$' ($s.AHEAD_STYLE)($p.n.0)(ansi reset)'
|
||||
} else if $p.s.0 == 'behind' {
|
||||
$' ($s.BEHIND_STYLE)($p.n.0)'
|
||||
} else {
|
||||
$' (ansi red)($p.s.0) ($p.n.0)'
|
||||
}
|
||||
})
|
||||
let state_str = ($state_list | str join)
|
||||
$'[($s.BRANCH_STYLE)($info.name.0)(ansi reset)($state_str)(ansi reset)]'
|
||||
}
|
||||
}
|
||||
|
||||
def full-git-style [] {
|
||||
let s = get-styles
|
||||
let info_lines = (do -p { git --no-optional-locks status --porcelain=2 --branch } | str trim | lines)
|
||||
if ($info_lines | is-empty) {
|
||||
''
|
||||
} else {
|
||||
# Scan lines
|
||||
let info = ($info_lines | reduce -f {
|
||||
out: [],
|
||||
staged: {a: 0, m: 0, d: 0},
|
||||
unstaged: {n: 0, m: 0, d: 0, c: 0},
|
||||
track: false,
|
||||
remote: false,
|
||||
} { |str, ctx|
|
||||
mut track = $ctx.track
|
||||
mut remote = $ctx.remote
|
||||
mut out = $ctx.out
|
||||
mut staged = $ctx.staged
|
||||
mut unstaged = $ctx.unstaged
|
||||
let l = ($str | split row -n 3 ' ')
|
||||
|
||||
if $track == false {
|
||||
if $l.0 == '#' and $l.1 == 'branch.upstream' {
|
||||
$track = true
|
||||
}
|
||||
}
|
||||
|
||||
# Branch
|
||||
if $l.0 == '#' {
|
||||
if $l.1 == 'branch.oid' {
|
||||
let id = ($l.2 | str substring 0..7)
|
||||
$out = [$"($s.BRANCH_STYLE)\(HEAD detached at ($id)\)(ansi reset)"]
|
||||
} else if $l.1 == 'branch.head' {
|
||||
if $l.2 != "\(detached\)" {
|
||||
$out = ($out | update 0 $'($s.BRANCH_STYLE)($l.2)(ansi reset)')
|
||||
}
|
||||
} else if $track {
|
||||
if $l.1 == 'branch.ab' {
|
||||
$remote = true
|
||||
let state = ($l.2 | parse "+{an} -{bn}")
|
||||
if $state.an.0 != '0' {
|
||||
$out = ($out | append $' ($s.AHEAD_STYLE)($state.an.0)(ansi reset)')
|
||||
}
|
||||
|
||||
if $state.bn.0 != '0' {
|
||||
$out = ($out | append $' ($s.BEHIND_STYLE)($state.bn.0)')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Status
|
||||
if $l.0 == '?' {
|
||||
$unstaged = ($unstaged | update n ($unstaged.n + 1))
|
||||
} else if $l.0 == 'u' {
|
||||
$unstaged = ($unstaged | update c ($unstaged.c + 1))
|
||||
} else if $l.0 == '1' or $l.0 == '2' {
|
||||
let state_l = ($l.1 | split chars)
|
||||
$staged = (update-git-status $staged $state_l.0)
|
||||
$unstaged = (update-git-status $unstaged $state_l.1)
|
||||
}
|
||||
|
||||
{
|
||||
out: $out,
|
||||
staged: $staged,
|
||||
unstaged: $unstaged,
|
||||
track: $track,
|
||||
remote: $remote,
|
||||
}
|
||||
})
|
||||
|
||||
# Branch string
|
||||
mut out_list = if $info.track {
|
||||
if $info.remote == false {
|
||||
($info.out | append $' (ansi light_red)(char failed)')
|
||||
} else if ($info.out | length) < 2 {
|
||||
($info.out | append $' (ansi cyan)(char identical_to)')
|
||||
} else {
|
||||
$info.out
|
||||
}
|
||||
} else {
|
||||
$info.out
|
||||
}
|
||||
|
||||
$out_list = ($out_list | append $'(ansi reset)')
|
||||
|
||||
# Stage string
|
||||
mut stage_list = []
|
||||
if $info.staged.a > 0 {
|
||||
$stage_list = ($stage_list | append $' ($s.ADD_FILE_STYLE)($info.staged.a)(ansi reset)')
|
||||
}
|
||||
|
||||
if $info.staged.m > 0 {
|
||||
$stage_list = ($stage_list | append $' ($s.MODIFY_FILE_STYLE)($info.staged.m)(ansi reset)')
|
||||
}
|
||||
|
||||
if $info.staged.d > 0 {
|
||||
$stage_list = ($stage_list | append $' ($s.DELETE_FILE_STYLE)($info.staged.d)(ansi reset)')
|
||||
}
|
||||
|
||||
# Unstage string
|
||||
mut unstage_list = []
|
||||
if $info.unstaged.c > 0 {
|
||||
$unstage_list = ($unstage_list | append $' ($s.CONFLICT_FILE_STYLE)($info.unstaged.c)(ansi reset)')
|
||||
}
|
||||
|
||||
if $info.unstaged.n > 0 {
|
||||
$unstage_list = ($unstage_list | append $' ($s.NEW_FILE_STYLE)($info.unstaged.n)(ansi reset)')
|
||||
}
|
||||
|
||||
if $info.unstaged.m > 0 {
|
||||
$unstage_list = ($unstage_list | append $' ($s.MODIFY_FILE_STYLE)($info.unstaged.m)(ansi reset)')
|
||||
}
|
||||
|
||||
if $info.unstaged.d > 0 {
|
||||
$unstage_list = ($unstage_list | append $' ($s.DELETE_FILE_STYLE)($info.unstaged.d)(ansi reset)')
|
||||
}
|
||||
|
||||
# Append list
|
||||
if ($stage_list | length) > 0 {
|
||||
$out_list = ($out_list | append $' | ($s.STAGE_STYLE):' | append $stage_list)
|
||||
}
|
||||
|
||||
if ($unstage_list | length) > 0 {
|
||||
$out_list = ($out_list | append $' | ($s.UNSTAGE_STYLE):' | append $unstage_list)
|
||||
}
|
||||
|
||||
$'[($out_list | str join)(ansi reset)]'
|
||||
}
|
||||
}
|
||||
|
||||
def update-git-status [
|
||||
status: record
|
||||
m: string
|
||||
] {
|
||||
if $m == 'A' {
|
||||
($status | update a (($status.a | into int) + 1))
|
||||
} else if $m == 'M' {
|
||||
($status | update m (($status.m | into int) + 1))
|
||||
} else if $m == 'D' {
|
||||
($status | update d (($status.d | into int) + 1))
|
||||
} else {
|
||||
$status
|
||||
}
|
||||
}
|
||||
|
||||
# Helper ----------------------------------------------------------------------
|
||||
|
||||
def get-username [] {
|
||||
if 'USERNAME' in $env {
|
||||
$env.USERNAME
|
||||
} else if 'USER' in $env {
|
||||
$env.USER
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
def is-self-user [name: string] {
|
||||
if 'LOGNAME' in $env {
|
||||
($env.LOGNAME == $name)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
def get-hostname [] {
|
||||
if 'COMPUTERNAME' in $env {
|
||||
$env.COMPUTERNAME
|
||||
} else if 'HOSTNAME' in $env {
|
||||
$env.HOSTNAME
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
def is-ssh-session [] {
|
||||
if 'SSH_CONNECTION' in $env {
|
||||
true
|
||||
} else if 'SSH_CLIENT' in $env {
|
||||
true
|
||||
} else if 'SSH_TTY' in $env {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
# This is a work in progress. Not working yet but you can see where I'm going.
|
||||
export def construct_prompt [] {
|
||||
# let decorator = (char prompt)
|
||||
let decorator = (create_second_line)
|
||||
|
||||
# not using machine name
|
||||
# let machine_name = (sys host | get hostname)
|
||||
|
||||
# the current working directory
|
||||
# let current_dir = (pwd)
|
||||
let current_dir = (home_abbrev)
|
||||
|
||||
# the current bit branch
|
||||
# let git_status = (git -c core.quotepath=false -c color.status=false status -uall --short --branch)
|
||||
let git_info = (do -i { git rev-parse --abbrev-ref HEAD } | str trim -c (char nl) | str join )
|
||||
|
||||
# what to put in the title
|
||||
let title_bar = (set_title)
|
||||
|
||||
# get the terminal width
|
||||
let term_width = (term size).columns
|
||||
|
||||
# get the curren time
|
||||
let current_time = (date now | format date '%I:%M:%S%.3f %p')
|
||||
|
||||
# let's construct the left and right prompt
|
||||
# the left side of the prompt with ansi colors
|
||||
let left_colored = $"(ansi gb)($current_dir)(ansi cb)(char lparen)($git_info)(char rparen)(ansi reset)"
|
||||
|
||||
# the left prompt length without the ansi escapes
|
||||
let left_len = ($left_colored | ansi strip | str length)
|
||||
|
||||
# the right side of the prompt with ansi colors
|
||||
let right_colored = $"(ansi blue)($env.CMD_DURATION_MS)|(ansi dark_gray)($current_time)(ansi reset)"
|
||||
|
||||
# let's calcuate the length of the right prompt so we know how much to pad the left prompt
|
||||
let calculated_right_len = ($term_width - $left_len)
|
||||
# finally, let's make the prompt
|
||||
let the_prompt = $"($left_colored)($right_colored | fill -a r -c ' ' -w $calculated_right_len)(char newline)($decorator) "
|
||||
|
||||
# let's update the title bar now
|
||||
print -n $title_bar
|
||||
|
||||
# and last, but not least, let's print the prompt
|
||||
echo $the_prompt
|
||||
|
||||
## put this in your config.toml
|
||||
# prompt = "construct_prompt"
|
||||
|
||||
## also you need to source the file in your startup like
|
||||
# "source C:\\Users\\username\\source\\some\\folder\\nu_scripts\\prompt\\left_and_right_prompt.nu",
|
||||
}
|
||||
|
||||
# Abbreviate home path
|
||||
def home_abbrev [] {
|
||||
let is_home_in_path = (pwd | into string | str starts-with $nu.home-path)
|
||||
if $is_home_in_path {
|
||||
let lin_home = ($nu.home-path | into string | str replace -a '\\' '/' | str downcase)
|
||||
let lin_pwd = (pwd | into string | str replace -a '\\' '/' | str downcase)
|
||||
$lin_pwd | str replace $lin_home '~'
|
||||
} else {
|
||||
pwd
|
||||
}
|
||||
}
|
||||
|
||||
# Get Git Info custom commands
|
||||
|
||||
def git_br [] {
|
||||
$"(ansi gb)(pwd)(ansi reset)(char lparen)(ansi cb)(do -i { git rev-parse --abbrev-ref HEAD } | str trim -c (char nl) | str join)(ansi reset)(char rparen)(char newline)(ansi yb)(date now | format date '%m/%d/%Y %I:%M:%S%.3f %p')(ansi reset)¯\\_(char lparen)ツ)_/¯(char prompt) "
|
||||
}
|
||||
|
||||
# Set Title String custom commands
|
||||
|
||||
def set_title_str [str_arg] {
|
||||
$"(ansi title) ($str_arg) (char bel)"
|
||||
}
|
||||
|
||||
def get_abbrev_pwd_lin [] {
|
||||
home_abbrev | split row '/' | first (home_abbrev | split row '/' | length | each { $in - 1} ) | each { str substring 0..1 | $'($in)/' } | append (home_abbrev | split row '/' | last ) | str join
|
||||
}
|
||||
def set_title [] {
|
||||
set_title_str ([(get_abbrev_pwd_lin) ' ' (term size).columns 'x' (term size).rows ] | str join)
|
||||
}
|
||||
def create_second_line [] {
|
||||
[(ansi gb) (char -u "2514") (char -u "2500") ' $ ' (ansi cb) (char prompt) (ansi reset)] | str join
|
||||
}
|
||||
284
dot_config/nushell/nu_scripts/modules/prompt/oh-my-minimal.nu
Normal file
284
dot_config/nushell/nu_scripts/modules/prompt/oh-my-minimal.nu
Normal file
@@ -0,0 +1,284 @@
|
||||
# NOTE: This is meant to run with engine-q and not nushell yet
|
||||
# It's still being tested. There will be bugs. :)
|
||||
|
||||
# REQUIREMENTS #
|
||||
# you definitely need nerd fonts https://www.nerdfonts.com
|
||||
# nerd fonts repo https://github.com/ryanoasis/nerd-fonts
|
||||
# i use "FiraCode Nerd Font Mono" on mac
|
||||
#
|
||||
# you also must have the engine-q gstat plugin installed and registered
|
||||
|
||||
# ATTRIBUTION #
|
||||
# A little fancier prompt with git information
|
||||
# inspired by https://github.com/xcambar/purs
|
||||
# inspired by https://github.com/IlanCosman/tide
|
||||
# inspired by https://github.com/JanDeDobbeleer/oh-my-posh
|
||||
|
||||
|
||||
# Abbreviate home path
|
||||
def home_abbrev [os] {
|
||||
let is_home_in_path = ($env.PWD | str starts-with $nu.home-path)
|
||||
if ($is_home_in_path == true) {
|
||||
if ($os == "windows") {
|
||||
let home = ($nu.home-path | str replace -ar '\\' '/')
|
||||
let pwd = ($env.PWD | str replace -ar '\\' '/')
|
||||
$pwd | str replace $home '~'
|
||||
} else {
|
||||
$env.PWD | str replace $nu.home-path '~'
|
||||
}
|
||||
} else {
|
||||
$env.PWD | str replace -ar '\\' '/'
|
||||
}
|
||||
}
|
||||
|
||||
export def path_abbrev_if_needed [apath term_width] {
|
||||
# probably shouldn't do coloring here but since we're coloring
|
||||
# only certain parts, it's kind of tricky to do it in another place
|
||||
# if needed, use `ansi strip` to remove coloring
|
||||
let T = (ansi { fg: "#BCBCBC" bg: "#3465A4"}) # truncated
|
||||
let P = (ansi { fg: "#E4E4E4" bg: "#3465A4"}) # path
|
||||
let PB = (ansi { fg: "#E4E4E4" bg: "#3465A4" attr: b}) # path bold
|
||||
let R = (ansi reset)
|
||||
let red = (ansi red)
|
||||
|
||||
# replace the home path first
|
||||
let apath = ($apath | str replace $nu.home-path ~)
|
||||
# split out by path separator into tokens
|
||||
# don't use psep here because in home_abbrev we're making them all '/'
|
||||
let splits = ($apath | split row '/')
|
||||
let splits_len = ($splits | length)
|
||||
|
||||
if (($apath | str length) > ($term_width / 2)) {
|
||||
# get all the tokens except the last
|
||||
let tokens = ($splits | take ($splits_len - 1) | each {|x|
|
||||
$"($T)($x | str substring 0..1)($R)"
|
||||
})
|
||||
|
||||
# append the last part of the path
|
||||
let tokens = ($tokens | append $"($PB)($splits | last)($R)")
|
||||
|
||||
# collect
|
||||
$tokens | str join $"($T)/"
|
||||
} else {
|
||||
if ($splits_len == 0) {
|
||||
# We're at / on the file system
|
||||
$"/($T)"
|
||||
} else if ($splits_len == 1) {
|
||||
let top_part = ($splits | first)
|
||||
let tokens = $"($PB)($top_part)($R)"
|
||||
$tokens | str join $"($T)"
|
||||
} else {
|
||||
let top_part = ($splits | first ($splits_len - 1))
|
||||
let end_part = ($splits | last)
|
||||
let tokens = ($top_part | each {|x|
|
||||
$"/($T)($x | str substring 0..1)($R)"
|
||||
})
|
||||
let tokens = ($tokens | append $"/($PB)($end_part)($R)")
|
||||
$tokens | skip 1 | str join $"($T)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def get_os_icon [os use_nerd_fonts] {
|
||||
# f17c = tux, f179 = apple, f17a = windows
|
||||
if $use_nerd_fonts {
|
||||
if ($os =~ macos) {
|
||||
(char -u f179)
|
||||
} else if ($os =~ linux) {
|
||||
(char -u f17c)
|
||||
} else if ($os =~ windows) {
|
||||
(char -u f17a)
|
||||
} else {
|
||||
''
|
||||
}
|
||||
} else {
|
||||
if ($os =~ macos) {
|
||||
"M"
|
||||
} else if ($os =~ linux) {
|
||||
"L"
|
||||
} else if ($os =~ windows) {
|
||||
"W"
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export def get_left_prompt [os use_nerd_fonts] {
|
||||
# replace this 30 with whatever the width of the terminal is
|
||||
let display_path = (path_abbrev_if_needed (home_abbrev $os) 30)
|
||||
let R = (ansi reset)
|
||||
|
||||
# some icons and the unicode char
|
||||
# e0b0 ▷ 25b7 ⏵ 23f5 ▶ 25b6 ⯈ 2bc8 🞂 1f782
|
||||
# e0b1
|
||||
# e0b2 ◁ 25c1 ⏴ 23f4 ◀ 25c0 ⯇ 2bc7 🞀 1f780
|
||||
# e0b3
|
||||
# f1d3
|
||||
# f07c or f115 📁 1f4c1 🗀 1f5c0
|
||||
# f015 or f7db 🏠 1f3e0 ⌂ 2302
|
||||
|
||||
let TERM_BG = "#0C0C0C"
|
||||
let right_transition_nf = (char -u e0b0)
|
||||
# let right_transition = (char -u 1f782)
|
||||
let right_transition = ""
|
||||
let home_nf = (char -u f015)
|
||||
# let home = (char -u 1f3e0)
|
||||
let home = ""
|
||||
let folder_nf = (char -u f07c)
|
||||
# let folder = (char -u 1f5c0)
|
||||
let folder = ""
|
||||
|
||||
# build segments and then put together the segments for the prompt
|
||||
let os_segment = ([
|
||||
(ansi { fg: "#080808" bg: "#CED7CF"}) # os bg color
|
||||
(char space) # space
|
||||
(get_os_icon $os $use_nerd_fonts) # os icon
|
||||
(char space) # space
|
||||
(ansi { fg: "#CED7CF" bg: "#3465A4"}) # color transition
|
||||
(if $use_nerd_fonts {
|
||||
$right_transition_nf #
|
||||
} else {
|
||||
$right_transition
|
||||
})
|
||||
(char space) # space
|
||||
] | str join)
|
||||
|
||||
let is_home_in_path = ($env.PWD | str starts-with $nu.home-path)
|
||||
let path_segment = (if $is_home_in_path {
|
||||
[
|
||||
(if $use_nerd_fonts {
|
||||
$home_nf # home icon
|
||||
} else {
|
||||
$home
|
||||
})
|
||||
(char space) # space
|
||||
$display_path # ~/src/forks/nushell
|
||||
(ansi { fg: "#CED7CF" bg: "#3465A4"}) # color just to color the next space
|
||||
(char space) # space
|
||||
] | str join
|
||||
} else {
|
||||
[
|
||||
(if $use_nerd_fonts {
|
||||
$folder_nf # folder icon
|
||||
} else {
|
||||
$folder
|
||||
})
|
||||
(char space) # space
|
||||
$display_path # ~/src/forks/nushell
|
||||
(ansi { fg: "#CED7CF" bg: "#3465A4"}) # color just to color the next space
|
||||
(char space) # space
|
||||
] | str join
|
||||
})
|
||||
|
||||
let indicator_segment = (
|
||||
[
|
||||
(ansi { fg: "#3465A4" bg: $TERM_BG}) # color
|
||||
(if $use_nerd_fonts {
|
||||
$right_transition_nf #
|
||||
} else {
|
||||
# $right_transition
|
||||
" >"
|
||||
})
|
||||
($R) # reset color
|
||||
] | str join
|
||||
)
|
||||
|
||||
# assemble all segments for final prompt printing
|
||||
[
|
||||
$os_segment
|
||||
$path_segment
|
||||
$indicator_segment
|
||||
] | str join
|
||||
}
|
||||
|
||||
export def get_right_prompt [os use_nerd_fonts] {
|
||||
# right prompt ideas
|
||||
# 1. just the time on the right
|
||||
# 2. date and time on the right
|
||||
# 3. git information on the right
|
||||
# 4. maybe git and time
|
||||
# 5. would like to get CMD_DURATION_MS going there too when it's implemented
|
||||
# 6. all of the above, chosen by def parameters
|
||||
|
||||
let R = (ansi reset)
|
||||
let TIME_BG = "#D3D7CF"
|
||||
let TERM_FG = "#0C0C0C"
|
||||
let left_transition_nf = (char -u e0b2)
|
||||
# let left_transition = (char -u 1f780)
|
||||
let left_transition = ""
|
||||
|
||||
let datetime_segment = ([
|
||||
(ansi { fg: $TIME_BG bg: $TERM_FG})
|
||||
(if $use_nerd_fonts {
|
||||
$left_transition_nf #
|
||||
} else {
|
||||
$left_transition
|
||||
})
|
||||
(ansi { fg: $TERM_FG bg: $TIME_BG})
|
||||
(char space)
|
||||
(date now | format date '%m/%d/%Y %I:%M:%S%.3f')
|
||||
(char space)
|
||||
($R)
|
||||
] | str join)
|
||||
|
||||
let time_segment = ([
|
||||
(ansi { fg: $TIME_BG bg: $TERM_FG})
|
||||
(if $use_nerd_fonts {
|
||||
$left_transition_nf #
|
||||
} else {
|
||||
$left_transition
|
||||
})
|
||||
(ansi { fg: $TERM_FG bg: $TIME_BG})
|
||||
(char space)
|
||||
(date now | format date '%I:%M:%S %p')
|
||||
(char space)
|
||||
($R)
|
||||
] | str join)
|
||||
|
||||
# 1. datetime - working
|
||||
# $datetime_segment
|
||||
|
||||
# 2. time only - working
|
||||
$time_segment
|
||||
|
||||
# 3. git only - working
|
||||
# $git_segment
|
||||
|
||||
# 4. git + time -> need to fix the transition
|
||||
# [
|
||||
# $git_segment
|
||||
# $time_segment
|
||||
# ] | str join
|
||||
|
||||
# 5. fernando wants this on the left prompt
|
||||
# [
|
||||
# $os_segment
|
||||
# $time_segment
|
||||
# $path_segment
|
||||
# ]
|
||||
}
|
||||
|
||||
export def get_prompt [nerd?] {
|
||||
let use_nerd_fonts = ($nerd != null)
|
||||
let os = $nu.os-info.name
|
||||
let left_prompt = (get_left_prompt $os $use_nerd_fonts)
|
||||
let right_prompt = (get_right_prompt $os $use_nerd_fonts)
|
||||
|
||||
# return in record literal syntax to be used kind of like a tuple
|
||||
# so we don't have to run this script more than once per prompt
|
||||
{
|
||||
left_prompt: $left_prompt
|
||||
right_prompt: $right_prompt
|
||||
}
|
||||
#
|
||||
# in the config.nu you would do something like
|
||||
# use "c:\some\path\to\nu_scripts\engine-q\prompt\oh-my-minimal.nu" get_prompt
|
||||
# $env.PROMPT_COMMAND = { (get_prompt).left_prompt }
|
||||
# $env.PROMPT_COMMAND_RIGHT = { (get_prompt).right_prompt }
|
||||
# $env.PROMPT_INDICATOR = " "
|
||||
# or with nerdfonts
|
||||
# $env.PROMPT_COMMAND = { (get_prompt 1).left_prompt }
|
||||
# $env.PROMPT_COMMAND_RIGHT = { (get_prompt 1).right_prompt }
|
||||
|
||||
}
|
||||
192
dot_config/nushell/nu_scripts/modules/prompt/oh-my-v2-docs.md
Normal file
192
dot_config/nushell/nu_scripts/modules/prompt/oh-my-v2-docs.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# oh-my.nu v2
|
||||
|
||||
This is less a version 2 and more of a different way of thinking. The intent of this script is to start to make oh-my.nu more configurable. We start with that by defining a lot of variables. Then we create a runtime_colors list of records. Those records will have 8bit colors, 24bit colors, or a value. 8bit for terminals like MacOS's Terminal.app and 24bit color for the rest of the world.
|
||||
|
||||
The thought would be that at some point this file source read another file for configured settings. That part is not done yet.
|
||||
|
||||
In order to use this script you need to source it and then set these.
|
||||
```
|
||||
$env.PROMPT_COMMAND = { (get_prompt 8bit).left_prompt }
|
||||
$env.PROMPT_COMMAND_RIGHT = { (get_prompt 8bit).right_prompt }
|
||||
$env.PROMPT_INDICATOR = { "" }
|
||||
```
|
||||
|
||||
I'd love for someone to take up the torch and work on this script in order to make it better, configurable, awesome.
|
||||
|
||||
Below is some rough documentation on what the configuration points are and could be. Not all of these configuration points are implemented. BTW, this is a total rip-off of the fish [tide](https://github.com/IlanCosman/tide) prompt, but not as nice.
|
||||
|
||||
|
||||
### color mode
|
||||
|
||||
* 24bit
|
||||
* 8bit
|
||||
|
||||
### prompt
|
||||
|
||||
| Variable | Description | Type |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------- | ------- |
|
||||
| add_newline_before | print an empty line before the prompt | boolean |
|
||||
| color_frame_and_connection | color of frame and prompt connection | color |
|
||||
| color_separator_same_color | color of the separator between items with the same background color | color |
|
||||
| icon_connection | repeated symbol that spans gap between left and right sides of prompt | string |
|
||||
| min_cols | if using one-line prompt, Tide attempts to have at least this many columns for you to type in | integer |
|
||||
| pad_items | if true, add a space before and after each item | boolean |
|
||||
|
||||
| variable_name | 24bit_color | 8bit_color |
|
||||
| - | - | - |
|
||||
|tide_prompt_color_frame_and_connection|#6C6C6C|242|
|
||||
|tide_prompt_color_separator_same_color|#949494|246|
|
||||
|
||||
### left_prompt
|
||||
|
||||
| Variable | Description | Type |
|
||||
| -------------------- | --------------------------------------------------------- | ------- |
|
||||
| frame_enabled | display the left prompt frame | boolean |
|
||||
| items | order of items to print in the left prompt | list |
|
||||
| prefix | string to put at the beginning the left prompt | string |
|
||||
| separator_diff_color | string to separate items with different background colors | string |
|
||||
| separator_same_color | string to separate items with the same background color | string |
|
||||
| suffix | string to put at the end of the left prompt | string |
|
||||
|
||||
| variable_name | char |
|
||||
| - | - |
|
||||
|tide_left_prompt_separator_diff_color|e0b0|
|
||||
|tide_left_prompt_separator_same_color|e0b1|
|
||||
|
||||
### right_prompt
|
||||
|
||||
| Variable | Description | Type |
|
||||
| -------------------- | --------------------------------------------------------- | ------- |
|
||||
| frame_enabled | display the right prompt frame | boolean |
|
||||
| items | order of items to print in the right prompt | list |
|
||||
| prefix | string to put at the beginning the right prompt | string |
|
||||
| separator_diff_color | string to separate items with different background colors | string |
|
||||
| separator_same_color | string to separate items with the same background color | string |
|
||||
| suffix | string to put at the end of the right prompt | string |
|
||||
|
||||
| variable_name | char |
|
||||
| - | - |
|
||||
|tide_right_prompt_separator_diff_color|e0b2|
|
||||
|tide_right_prompt_separator_same_color|e0b3|
|
||||
|
||||
### cmd_duration
|
||||
|
||||
| Variable | Description | Type |
|
||||
| --------- | ------------------------------------------------------------------ | ------- |
|
||||
| bg_color | background color of the cmd_duration item | color |
|
||||
| color | color of the cmd_duration item | color |
|
||||
| decimals | number of decimals to display after the seconds place | integer |
|
||||
| icon | icon for the cmd_duration item | string |
|
||||
| threshold | number of milliseconds that duration must exceed to produce output | integer |
|
||||
|
||||
| variable_name | 24bit_color | 8bit_color |
|
||||
| - | - | - |
|
||||
|tide_cmd_duration_bg_color|#C4A000|178|
|
||||
|tide_cmd_duration_color|#000000|16|
|
||||
|
||||
### git
|
||||
|
||||
| Variable | Description | Type |
|
||||
| ----------------- | ---------------------------------------------------------------------- | ------ |
|
||||
| bg_color | default background color of the git_item | color |
|
||||
| bg_color_unstable | background color when repository has dirty, staged, or untracked files | color |
|
||||
| bg_color_urgent | background color when repository has conflicts or ongoing operations | color |
|
||||
| color_branch | color of branch/SHA | color |
|
||||
| color_conflicted | color of conflicted files number | color |
|
||||
| color_dirty | color of dirty files number | color |
|
||||
| color_operation | color of the current operation | color |
|
||||
| color_staged | color of staged files number | color |
|
||||
| color_stash | color of stashes number | color |
|
||||
| color_untracked | color of untracked files number | color |
|
||||
| color_upstream | color of upstream behind/ahead numbers | color |
|
||||
| icon | icon of the git item, colored same as branch | string |
|
||||
|
||||
| variable_name | 24bit_color | 8bit_color |
|
||||
| - | - | - |
|
||||
|tide_git_bg_color|#4E9A06|70|
|
||||
|tide_git_bg_color_unstable|#C4A000|178|
|
||||
|tide_git_bg_color_urgent|#CC0000|160|
|
||||
|tide_git_color_branch|#000000|16|
|
||||
|tide_git_color_conflicted|#000000|16|
|
||||
|tide_git_color_dirty|#000000|16|
|
||||
|tide_git_color_operation|#000000|16|
|
||||
|tide_git_color_staged|#000000|16|
|
||||
|tide_git_color_stash|#000000|16|
|
||||
|tide_git_color_untracked|#000000|16|
|
||||
|tide_git_color_upstream|#000000|16|
|
||||
|
||||
### os
|
||||
|
||||
| Variable | Description | Type |
|
||||
| -------- | --------------------------- | ----- |
|
||||
| bg_color | background color of os item | color |
|
||||
| color | color of os item | color |
|
||||
|
||||
| variable_name | 24bit_color | 8bit_color |
|
||||
| - | - | - |
|
||||
|tide_os_bg_color|#CED7CF|188|
|
||||
|tide_os_color|#080808|232|
|
||||
|
||||
### pwd
|
||||
|
||||
| Variable | Description | Type |
|
||||
| -------------------- | ---------------------------------------------------------------------------------------------- | ------ |
|
||||
| bg_color | background color of pwd item | color |
|
||||
| color_anchors | color of anchor directories. These directories are displayed in bold and immune to truncation. | color |
|
||||
| color_dirs | color of normal directories | color |
|
||||
| color_truncated_dirs | color of truncated directories | color |
|
||||
| icon | default icon for pwd item | string |
|
||||
| icon_home | icon when the the current directory is the user's HOME | string |
|
||||
| icon_unwritable | icon when the directory is not writable by the user | string |
|
||||
| markers | if a directory contains any of these files/directories, it will be anchored | list |
|
||||
|
||||
| variable_name | 24bit_color | 8bit_color |
|
||||
| - | - | - |
|
||||
|tide_pwd_bg_color|#3465A4|61|
|
||||
|tide_pwd_color_anchors|#E4E4E4|254|
|
||||
|tide_pwd_color_dirs|#E4E4E4|254|
|
||||
|tide_pwd_color_truncated_dirs|#BCBCBC|250|
|
||||
|
||||
### rustc
|
||||
|
||||
| Variable | Description | Type |
|
||||
| -------- | ---------------------------------------- | ------ |
|
||||
| bg_color | background color of rust item | color |
|
||||
| color | color of rust item | color |
|
||||
| icon | icon to display next to the rust version | string |
|
||||
|
||||
| variable_name | 24bit_color | 8bit_color |
|
||||
| - | - | - |
|
||||
|tide_rustc_bg_color|#F74C00|202|
|
||||
|tide_rustc_color|#000000|16|
|
||||
|
||||
### status
|
||||
|
||||
| Variable | Description | Type |
|
||||
| ---------------- | ----------------------------------- | ------ |
|
||||
| bg_color | background color when `$status` = 0 | color |
|
||||
| bg_color_failure | background color when `$status` > 0 | color |
|
||||
| color | color when `$status` = 0 | string |
|
||||
| color_failure | color when `$status` > 0 | color |
|
||||
| icon | icon when `$status` = 0 | string |
|
||||
| icon_failure | icon when `$status` > 0 | string |
|
||||
|
||||
| variable_name | 24bit_color | 8bit_color |
|
||||
| - | - | - |
|
||||
|tide_status_bg_color|#2E3436|236|
|
||||
|tide_status_bg_color_failure|#CC0000|160|
|
||||
|tide_status_color|#4E9A06|70|
|
||||
|tide_status_color_failure|#FFFF00|226|
|
||||
|
||||
### time
|
||||
|
||||
| Variable | Description | Type |
|
||||
| -------- | ------------------------------------------- | ------ |
|
||||
| bg_color | background color of time item | color |
|
||||
| color | color of time item | color |
|
||||
| format | format of time item. Uses `date` formatting | string |
|
||||
|
||||
| variable_name | 24bit_color | 8bit_color |
|
||||
| - | - | - |
|
||||
|tide_time_bg_color|#D3D7CF|188|
|
||||
|tide_time_color|#000000|16|
|
||||
435
dot_config/nushell/nu_scripts/modules/prompt/oh-my-v2.nu
Normal file
435
dot_config/nushell/nu_scripts/modules/prompt/oh-my-v2.nu
Normal file
@@ -0,0 +1,435 @@
|
||||
# See the readme for how to use this script
|
||||
# modes
|
||||
# * 8bit
|
||||
# * 24bit
|
||||
let color_mode = "8bit"
|
||||
|
||||
# setup separate characters
|
||||
let left_prompt_separator_diff_color = (char -u 'e0b0')
|
||||
let left_prompt_separator_same_color = (char -u 'e0b1')
|
||||
let right_prompt_separator_diff_color = (char -u 'e0b2')
|
||||
let right_prompt_separator_same_color = (char -u 'e0b3')
|
||||
|
||||
# setup color variables for 24bit and 8bit
|
||||
# prompt
|
||||
let prompt_color_frame_and_connection_24 = (ansi -e { fg: "#6C6C6C" })
|
||||
let prompt_color_separator_same_color_24 = (ansi -e { fg: "#949494" })
|
||||
let prompt_color_frame_and_connection_8 = $"(ansi idx_fg)242m"
|
||||
let prompt_color_separator_same_color_8 = $"(ansi idx_fg)246m"
|
||||
let prompt_add_new_line_before = false
|
||||
let prompt_color_frame_and_connection = ""
|
||||
let prompt_color_separator_same_color = ""
|
||||
|
||||
let left_separator_diff_color = ""
|
||||
let left_separator_same_color = ""
|
||||
let left_items = []
|
||||
let left_prefix = ""
|
||||
let left_suffix = ""
|
||||
|
||||
let right_separator_diff_color = ""
|
||||
let right_separator_same_color = ""
|
||||
let right_items = []
|
||||
let right_prefix = ""
|
||||
let right_suffix = ""
|
||||
|
||||
# cmd
|
||||
let cmd_duration_bg_color_24 = (ansi -e { bg: "#C4A000" })
|
||||
let cmd_duration_color_24 = (ansi -e { fg: "#000000" })
|
||||
let cmd_duration_bg_color_8 = $"(ansi idx_bg)178m"
|
||||
let cmd_duration_color_8 = $"(ansi idx_fg)16m"
|
||||
let cmd_bg_color = ""
|
||||
let cmd_color = ""
|
||||
let cmd_decimals = 2
|
||||
let cmd_icon = ""
|
||||
|
||||
# git
|
||||
let git_bg_color_24 = (ansi -e { bg: "#4E9A06" })
|
||||
let git_bg_color_unstable_24 = (ansi -e { bg: "#C4A000" })
|
||||
let git_bg_color_urgent_24 = (ansi -e { bg: "#CC0000" })
|
||||
let git_color_branch_24 = (ansi -e { fg: "#000000" })
|
||||
let git_color_conflicted_24 = (ansi -e { fg: "#000000" })
|
||||
let git_color_dirty_24 = (ansi -e { fg: "#000000" })
|
||||
let git_color_operation_24 = (ansi -e { fg: "#000000" })
|
||||
let git_color_staged_24 = (ansi -e { fg: "#000000" })
|
||||
let git_color_stash_24 = (ansi -e { fg: "#000000" })
|
||||
let git_color_untracked_24 = (ansi -e { fg: "#000000" })
|
||||
let git_color_upstream_24 = (ansi -e { fg: "#000000" })
|
||||
|
||||
let git_bg_color_8 = $"(ansi idx_bg)70m"
|
||||
let git_bg_color_unstable_8 = $"(ansi idx_bg)178m"
|
||||
let git_bg_color_urgent_8 = $"(ansi idx_bg)160m"
|
||||
let git_color_branch_8 = $"(ansi idx_fg)16m"
|
||||
let git_color_conflicted_8 = $"(ansi idx_fg)16m"
|
||||
let git_color_dirty_8 = $"(ansi idx_fg)16m"
|
||||
let git_color_operation_8 = $"(ansi idx_fg)16m"
|
||||
let git_color_staged_8 = $"(ansi idx_fg)16m"
|
||||
let git_color_stash_8 = $"(ansi idx_fg)16m"
|
||||
let git_color_untracked_8 = $"(ansi idx_fg)16m"
|
||||
let git_color_upstream_8 = $"(ansi idx_fg)16m"
|
||||
|
||||
let git_bg_color = ""
|
||||
let git_bg_color_unstable = ""
|
||||
let git_bg_color_urgent = ""
|
||||
let git_color_branch = ""
|
||||
let git_color_conflicted = ""
|
||||
let git_color_dirty = ""
|
||||
let git_color_operation = ""
|
||||
let git_color_staged = ""
|
||||
let git_color_stash = ""
|
||||
let git_color_untracked = ""
|
||||
let git_color_upstream = ""
|
||||
|
||||
# os
|
||||
let os_bg_color_24 = (ansi -e { bg: "#CED7CF" })
|
||||
let os_color_24 = (ansi -e { fg: "#080808" })
|
||||
let os_bg_color_8 = $"(ansi idx_bg)188m"
|
||||
let os_color_8 = $"(ansi idx_fg)232m"
|
||||
let os_bg_color = ""
|
||||
let os_color = ""
|
||||
|
||||
# pwd
|
||||
let pwd_bg_color_24 = (ansi -e { bg: "#3465A4" })
|
||||
let pwd_color_anchors_24 = (ansi -e { fg: "#E4E4E4" })
|
||||
let pwd_color_dirs_24 = (ansi -e { fg: "#E4E4E4" })
|
||||
let pwd_color_truncated_dirs_24 = (ansi -e { fg: "#BCBCBC" })
|
||||
|
||||
let pwd_bg_color_8 = $"(ansi idx_bg)61m"
|
||||
let pwd_color_anchors_8 = $"(ansi idx_fg)254m"
|
||||
let pwd_color_dirs_8 = $"(ansi idx_fg)254m"
|
||||
let pwd_color_truncated_dirs_8 = $"(ansi idx_fg)250m"
|
||||
|
||||
let pwd_bg_color = ""
|
||||
let pwd_color_anchors = ""
|
||||
let pwd_color_dirs = ""
|
||||
let pwd_color_truncated_dirs = ""
|
||||
let pwd_icon = ""
|
||||
let pwd_icon_home = ""
|
||||
let pwd_icon_unwritable = ""
|
||||
let pwd_markers = []
|
||||
|
||||
# rustc
|
||||
let rustc_bg_color_24 = (ansi -e { bg: "#F74C00" })
|
||||
let rustc_color_24 = (ansi -e { fg: "#000000" })
|
||||
let rustc_bg_color_8 = $"(ansi idx_bg)202m"
|
||||
let rustc_color_8 = $"(ansi idx_fg)16m"
|
||||
|
||||
let rustc_bg_color = ""
|
||||
let rustc_color = ""
|
||||
let rustc_icon = ""
|
||||
|
||||
# status
|
||||
let status_bg_color_24 = (ansi -e { bg: "#2E3436" })
|
||||
let status_bg_color_failure_24 = (ansi -e { bg: "#CC0000" })
|
||||
let status_color_24 = (ansi -e { fg: "#4E9A06" })
|
||||
let status_color_failure_24 = (ansi -e { fg: "#FFFF00" })
|
||||
|
||||
let status_bg_color_8 = $"(ansi idx_bg)236m"
|
||||
let status_bg_color_failure_8 = $"(ansi idx_bg)160m"
|
||||
let status_color_8 = $"(ansi idx_fg)70m"
|
||||
let status_color_failure_8 = $"(ansi idx_fg)226m"
|
||||
|
||||
let status_bg_color = ""
|
||||
let status_bg_color_faiure = ""
|
||||
let status_color = ""
|
||||
let status_color_failure = ""
|
||||
let status_icon = ""
|
||||
let status_icon_failure = ""
|
||||
|
||||
# time
|
||||
let time_bg_color_24 = (ansi -e { bg: "#D3D7CF" })
|
||||
let time_color_24 = (ansi -e { fg: "#000000" })
|
||||
let time_bg_color_8 = $"(ansi idx_bg)188m"
|
||||
let time_color_8 = $"(ansi idx_fg)16m"
|
||||
|
||||
let time_bg_color = ""
|
||||
let time_color = ""
|
||||
let time_format = ""
|
||||
|
||||
# indicator
|
||||
let indicator_color_24 = (ansi -e { fg: "#3465a4" })
|
||||
let indicator_bg_color_24 = (ansi -e { bg: "#000000" })
|
||||
let indicator_color_8 = $"(ansi idx_fg)61m"
|
||||
let indicator_bg_color_8 = $"(ansi idx_bg)16m"
|
||||
|
||||
# terminal background color
|
||||
let terminal_color_24 = (ansi -e { fg: "#c7c7c7" })
|
||||
let terminal_color_8 = (ansi white)
|
||||
let terminal_bg_color_24 = (ansi -e { bg: "#000000" })
|
||||
let terminal_bg_color_8 = (ansi black)
|
||||
|
||||
# cmd_duration_ms
|
||||
let cmd_duration_ms_color_24 = (ansi -e { fg: "#606060" })
|
||||
let cmd_duration_ms_color_8 = $"(ansi idx_fg)244m"
|
||||
let cmd_duration_ms_bg_color_24 = (ansi -e { fg: "#000000" })
|
||||
let cmd_duration_ms_bg_color_8 = (ansi black)
|
||||
|
||||
let runtime_colors = [
|
||||
{ name: prompt_color_frame_and_connection, '8bit': $prompt_color_frame_and_connection_8, '24bit': $prompt_color_frame_and_connection_24 },
|
||||
{ name: prompt_color_separator_same_color, '8bit': $prompt_color_separator_same_color_8, '24bit': $prompt_color_separator_same_color_24 },
|
||||
{ name: left_separator_diff_color, '8bit': $left_prompt_separator_diff_color, '24bit': $left_prompt_separator_diff_color },
|
||||
{ name: left_separator_same_color, '8bit': $left_prompt_separator_same_color, '24bit': $left_prompt_separator_same_color },
|
||||
{ name: left_prefix, value: null },
|
||||
{ name: left_suffix, value: null },
|
||||
{ name: right_separator_diff_color, '8bit': $right_prompt_separator_diff_color, '24bit': $right_prompt_separator_diff_color },
|
||||
{ name: right_separator_same_color, '8bit': $right_prompt_separator_same_color, '24bit': $right_prompt_separator_same_color },
|
||||
{ name: right_prefix, value: null },
|
||||
{ name: right_suffix, value: null },
|
||||
|
||||
{ name: cmd_bg_color, '8bit': $cmd_duration_bg_color_8, '24bit': $cmd_duration_bg_color_24 },
|
||||
{ name: cmd_color, '8bit': $cmd_duration_color_8, '24bit': $cmd_duration_color_24 },
|
||||
{ name: cmd_decimals, value: 2 },
|
||||
{ name: cmd_icon, value: },
|
||||
|
||||
{ name: git_bg_color, '8bit': $git_bg_color_8, '24bit': $git_bg_color_24 },
|
||||
{ name: git_bg_color_unstable, '8bit': $git_bg_color_unstable_8, '24bit': $git_bg_color_unstable_24 },
|
||||
{ name: git_bg_color_urgent, '8bit': $git_bg_color_urgent_8 , '24bit': $git_bg_color_urgent_24 },
|
||||
{ name: git_color_branch, '8bit': $git_color_branch_8, '24bit': $git_color_branch_24 },
|
||||
{ name: git_color_conflicted, '8bit': $git_color_conflicted_8, '24bit': $git_color_conflicted_24 },
|
||||
{ name: git_color_dirty, '8bit': $git_color_dirty_8, '24bit': $git_color_dirty_24 },
|
||||
{ name: git_color_operation, '8bit': $git_color_operation_8, '24bit': $git_color_operation_24 },
|
||||
{ name: git_color_staged, '8bit': $git_color_staged_8, '24bit': $git_color_staged_24 },
|
||||
{ name: git_color_stash, '8bit': $git_color_stash_8, '24bit': $git_color_stash_24 },
|
||||
{ name: git_color_untracked, '8bit': $git_color_untracked_8, '24bit': $git_color_untracked_24 },
|
||||
{ name: git_color_upstream, '8bit': $git_color_upstream_8, '24bit': $git_color_upstream_24 },
|
||||
|
||||
{ name: os_bg_color, '8bit': $os_bg_color_8, '24bit': $os_bg_color_24 },
|
||||
{ name: os_color, '8bit': $os_color_8, '24bit': $os_color_24 },
|
||||
|
||||
{ name: pwd_bg_color, '8bit': $pwd_bg_color_8, '24bit': $pwd_bg_color_24 },
|
||||
{ name: pwd_color_anchors, '8bit': $pwd_color_anchors_8, '24bit': $pwd_color_anchors_24 },
|
||||
{ name: pwd_color_dirs, '8bit': $pwd_color_dirs_8, '24bit': $pwd_color_dirs_24 },
|
||||
{ name: pwd_color_truncated_dirs, '8bit': $pwd_color_truncated_dirs_8, '24bit': $pwd_color_truncated_dirs_24 },
|
||||
{ name: pwd_icon, value: null },
|
||||
{ name: pwd_icon_home, value: null },
|
||||
{ name: pwd_icon_unwritable, value: null },
|
||||
|
||||
{ name: rustc_bg_color, '8bit': $rustc_bg_color_8, '24bit': $rustc_bg_color_24 },
|
||||
{ name: rustc_color, '8bit': $rustc_color_8, '24bit': $rustc_color_24 },
|
||||
{ name: rustc_icon, value: },
|
||||
|
||||
{ name: status_bg_color, '8bit': $status_bg_color_8, '24bit': $status_bg_color_24 },
|
||||
{ name: status_bg_color_failure, '8bit': $status_bg_color_failure_8, '24bit': $status_bg_color_failure_24 },
|
||||
{ name: status_color, '8bit': $status_color_8, '24bit': $status_color_24 },
|
||||
{ name: status_color_failure, '8bit': $status_color_failure_8 , '24bit': $status_color_failure_24 },
|
||||
{ name: status_icon, value: null },
|
||||
{ name: status_icon_failure, value: null },
|
||||
|
||||
{ name: time_bg_color, '8bit': $time_bg_color_8, '24bit': $time_bg_color_24 },
|
||||
{ name: time_color, '8bit': $time_color_8, '24bit': $time_color_24 },
|
||||
{ name: time_format, value: null },
|
||||
|
||||
{ name: indicator_bg_color, '8bit': $indicator_bg_color_8, '24bit': $indicator_bg_color_24 },
|
||||
{ name: indicator_color, '8bit': $indicator_color_8, '24bit': $indicator_color_24 },
|
||||
|
||||
{ name: terminal_color, '8bit': $terminal_color_8, '24bit': $terminal_color_24 },
|
||||
{ name: terminal_bg_color, '8bit': $terminal_bg_color_8, '24bit': $terminal_bg_color_24 },
|
||||
|
||||
{name: cmd_duration_ms_color, '8bit': $cmd_duration_ms_color_8, '24bit': $cmd_duration_ms_color_24 },
|
||||
{name: cmd_duration_ms_bg_color, '8bit': $cmd_duration_ms_bg_color_8, '24bit': $cmd_duration_ms_bg_color_24 },
|
||||
]
|
||||
|
||||
# get the color from the $runtime_colors array
|
||||
def get_color [name, mode] {
|
||||
$runtime_colors | where name == $name | get $mode | get 0
|
||||
}
|
||||
|
||||
######################################################
|
||||
|
||||
# Abbreviate home path for the prompt
|
||||
def home_abbrev [os_name] {
|
||||
let is_home_in_path = ($env.PWD | str starts-with $nu.home-path)
|
||||
if $is_home_in_path {
|
||||
if ($os_name == "windows") {
|
||||
let home = ($nu.home-path | str replace -ar '\\' '/')
|
||||
let pwd = ($env.PWD | str replace -ar '\\' '/')
|
||||
$pwd | str replace $home '~'
|
||||
} else {
|
||||
$env.PWD | str replace $nu.home-path '~'
|
||||
}
|
||||
} else {
|
||||
$env.PWD | str replace -ar '\\' '/'
|
||||
}
|
||||
}
|
||||
|
||||
# get the operating system icon for the prompt
|
||||
def get_os_icon [os] {
|
||||
# f17c = tux, f179 = apple, f17a = windows
|
||||
if ($os.name =~ macos) {
|
||||
(char -u f179)
|
||||
} else if ($os.name =~ windows) {
|
||||
(char -u f17a)
|
||||
} else if ($os.kernel_version =~ WSL) {
|
||||
$'(char -u f17a)(char -u f17c)'
|
||||
} else if ($os.family =~ unix) {
|
||||
(char -u f17c)
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
# get the os segment for the prompt
|
||||
def get_os_segment [os color_mode] {
|
||||
let os_bg_color = (get_color os_bg_color $color_mode)
|
||||
let os_color = (get_color os_color $color_mode)
|
||||
let os_icon = (get_os_icon $os)
|
||||
let transition_icon = $left_prompt_separator_diff_color
|
||||
let transition_bg_color = (get_color pwd_bg_color $color_mode)
|
||||
let transition_color = (get_color pwd_color_anchors $color_mode)
|
||||
|
||||
let os_segment = (
|
||||
[
|
||||
($os_color)
|
||||
($os_bg_color)
|
||||
(char space)
|
||||
($os_icon)
|
||||
(char space)
|
||||
($transition_color)
|
||||
($transition_bg_color)
|
||||
($transition_icon)
|
||||
(char space)
|
||||
] | str join
|
||||
)
|
||||
|
||||
$os_segment
|
||||
}
|
||||
|
||||
# get the path segment for the prompt
|
||||
def get_path_segment [os color_mode] {
|
||||
let display_path = (home_abbrev $os.name)
|
||||
let is_home_in_path = ($env.PWD | str starts-with $nu.home-path)
|
||||
let pwd_bg_color = (get_color pwd_bg_color $color_mode)
|
||||
let pwd_color = (get_color pwd_color_dirs $color_mode)
|
||||
let home_or_folder = (if $is_home_in_path { (char nf_house1) } else { (char nf_folder1) })
|
||||
let path_segment = (
|
||||
[
|
||||
$home_or_folder
|
||||
(char space) # space
|
||||
$display_path # ~/src/forks/nushell
|
||||
($pwd_color)
|
||||
($pwd_bg_color)
|
||||
(char space) # space
|
||||
] | str join
|
||||
)
|
||||
|
||||
$path_segment
|
||||
}
|
||||
|
||||
# get the indicator segment for the prompt
|
||||
def get_indicator_segment [os color_mode] {
|
||||
let R = (ansi reset)
|
||||
let indicator_color = (get_color indicator_color $color_mode)
|
||||
let indicator_bg_color = (get_color indicator_bg_color $color_mode)
|
||||
let indicator_segment = (
|
||||
[
|
||||
($indicator_color)
|
||||
($indicator_bg_color)
|
||||
(char nf_segment) #
|
||||
($R) # reset color
|
||||
] | str join
|
||||
)
|
||||
|
||||
$indicator_segment
|
||||
}
|
||||
|
||||
# construct the left prompt
|
||||
def get_left_prompt [os color_mode] {
|
||||
let os_segment = (get_os_segment $os $color_mode)
|
||||
let path_segment = (get_path_segment $os $color_mode)
|
||||
let indicator_segment = (get_indicator_segment $os $color_mode)
|
||||
$os_segment + $path_segment + $indicator_segment
|
||||
}
|
||||
|
||||
# get the time segment for the prompt
|
||||
def get_time_segment [os color_mode] {
|
||||
let R = (ansi reset)
|
||||
let time_bg_color = (get_color time_bg_color $color_mode)
|
||||
let time_color = (get_color time_color $color_mode)
|
||||
|
||||
let time_segment = ([
|
||||
(ansi { fg: $time_bg_color bg: $time_color})
|
||||
(char nf_right_segment) #(char -u e0b2) #
|
||||
($time_color)
|
||||
($time_bg_color)
|
||||
(char space)
|
||||
(date now | format date '%I:%M:%S %p')
|
||||
(char space)
|
||||
($R)
|
||||
] | str join)
|
||||
|
||||
$time_segment
|
||||
}
|
||||
|
||||
# get the status segment for the prompt
|
||||
def get_status_segment [os color_mode] {
|
||||
let R = (ansi reset)
|
||||
|
||||
# set status bg color to foreground since bg is dark
|
||||
let fg_failure = (get_color status_bg_color_failure $color_mode)
|
||||
let term_bg_color = (get_color terminal_bg_color $color_mode)
|
||||
let cmd_dur_fg = (get_color cmd_duration_ms_color $color_mode)
|
||||
let cmd_dur_bg = (get_color cmd_duration_ms_bg_color $color_mode)
|
||||
|
||||
let status_segment = (
|
||||
[
|
||||
(if $env.LAST_EXIT_CODE != 0 {
|
||||
(ansi { fg: $fg_failure bg: $term_bg_color })
|
||||
} else {
|
||||
(ansi { fg: $cmd_dur_fg bg: $cmd_dur_bg })
|
||||
})
|
||||
(char nf_right_segment_thin)
|
||||
(char space)
|
||||
$env.LAST_EXIT_CODE
|
||||
(char space)
|
||||
($R)
|
||||
] | str join
|
||||
)
|
||||
|
||||
$status_segment
|
||||
}
|
||||
|
||||
# get the execution segment for the prompt
|
||||
def get_execution_time_segment [os color_mode] {
|
||||
let R = (ansi reset)
|
||||
let cmd_dur_fg = (get_color cmd_duration_ms_color $color_mode)
|
||||
let cmd_dur_bg = (get_color cmd_duration_ms_bg_color $color_mode)
|
||||
|
||||
let execution_time_segment = (
|
||||
[
|
||||
($cmd_dur_fg)
|
||||
($cmd_dur_bg)
|
||||
# (ansi { fg: $cmd_dur_fg bg: $cmd_dur_bg })
|
||||
(char nf_right_segment_thin)
|
||||
(char space)
|
||||
$env.CMD_DURATION_MS
|
||||
(char space)
|
||||
($R)
|
||||
] | str join
|
||||
)
|
||||
|
||||
$execution_time_segment
|
||||
}
|
||||
|
||||
# construct the right prompt
|
||||
def get_right_prompt [os color_mode] {
|
||||
let status_segment = (get_status_segment $os $color_mode)
|
||||
let execution_time_segment = (get_execution_time_segment $os $color_mode)
|
||||
let time_segment = (get_time_segment $os $color_mode)
|
||||
let exit_if = (if $env.LAST_EXIT_CODE != 0 { $status_segment })
|
||||
[$exit_if $execution_time_segment $time_segment] | str join
|
||||
}
|
||||
|
||||
# constructe the left and right prompt by color_mode (8bit or 24bit)
|
||||
def get_prompt [color_mode] {
|
||||
# modes = 8bit or 24bit
|
||||
# let os = ((sys).host)
|
||||
let os = $nu.os-info
|
||||
let left_prompt = (get_left_prompt $os $color_mode)
|
||||
let right_prompt = (get_right_prompt $os $color_mode)
|
||||
|
||||
# return in record literal syntax to be used kind of like a tuple
|
||||
# so we don't have to run this script more than once per prompt
|
||||
{
|
||||
left_prompt: $left_prompt
|
||||
right_prompt: $right_prompt
|
||||
}
|
||||
}
|
||||
545
dot_config/nushell/nu_scripts/modules/prompt/oh-my.nu
Normal file
545
dot_config/nushell/nu_scripts/modules/prompt/oh-my.nu
Normal file
@@ -0,0 +1,545 @@
|
||||
# REQUIREMENTS #
|
||||
# you definitely need nerd fonts https://www.nerdfonts.com
|
||||
# nerd fonts repo https://github.com/ryanoasis/nerd-fonts
|
||||
# i use "FiraCode Nerd Font Mono" on mac
|
||||
#
|
||||
# you also must have the engine-q gstat plugin installed and registered
|
||||
|
||||
# ATTRIBUTION #
|
||||
# A little fancier prompt with git information
|
||||
# inspired by https://github.com/xcambar/purs
|
||||
# inspired by https://github.com/IlanCosman/tide
|
||||
# inspired by https://github.com/JanDeDobbeleer/oh-my-posh
|
||||
|
||||
|
||||
# Abbreviate home path
|
||||
def home_abbrev [os_name] {
|
||||
let is_home_in_path = ($env.PWD | str starts-with $nu.home-path)
|
||||
if $is_home_in_path {
|
||||
if ($os_name =~ "windows") {
|
||||
let home = ($nu.home-path | str replace -ar '\\' '/')
|
||||
let pwd = ($env.PWD | str replace -ar '\\' '/')
|
||||
$pwd | str replace $home '~'
|
||||
} else {
|
||||
$env.PWD | str replace $nu.home-path '~'
|
||||
}
|
||||
} else {
|
||||
if ($os_name =~ "windows") {
|
||||
# remove the C: from the path
|
||||
$env.PWD | str replace -ar '\\' '/' | str substring 2..
|
||||
} else {
|
||||
$env.PWD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def path_abbrev_if_needed [apath term_width] {
|
||||
# probably shouldn't do coloring here but since we're coloring
|
||||
# only certain parts, it's kind of tricky to do it in another place
|
||||
let T = (ansi { fg: "#BCBCBC" bg: "#3465A4"}) # truncated
|
||||
let P = (ansi { fg: "#E4E4E4" bg: "#3465A4"}) # path
|
||||
let PB = (ansi { fg: "#E4E4E4" bg: "#3465A4" attr: b}) # path bold
|
||||
let R = (ansi reset)
|
||||
let is_home_in_path = ($env.PWD | str starts-with $nu.home-path)
|
||||
|
||||
if (($apath | str length) > ($term_width / 2)) {
|
||||
# split out by path separator into tokens
|
||||
# don't use psep here because in home_abbrev we're making them all '/'
|
||||
let splits = ($apath | split row '/')
|
||||
|
||||
let splits_len = ($splits | length)
|
||||
# get all the tokens except the last
|
||||
let tokens = (1..<($splits_len - 1) | each {|x|
|
||||
$"($T)((($splits) | get $x | split chars) | get 0)($R)"
|
||||
})
|
||||
|
||||
# need an insert command
|
||||
let tokens = ($tokens | prepend $"($T)~")
|
||||
|
||||
# append the last part of the path
|
||||
let tokens = ($tokens | append $"($PB)($splits | last)($R)")
|
||||
|
||||
# collect
|
||||
$tokens | str join $"($T)/"
|
||||
} else {
|
||||
let splits = ($apath | split row '/')
|
||||
let splits_len = ($splits | length)
|
||||
let apath_len = ($apath | str length)
|
||||
if ($splits_len == 2 and $apath_len == 1) {
|
||||
$"/($T)($R)"
|
||||
} else if ($splits_len == 2) {
|
||||
let top_part = ($splits | last)
|
||||
let tokens = $"($PB)($top_part)($R)"
|
||||
$tokens | str join $"($T)"
|
||||
} else if ($splits.0 | is-empty) {
|
||||
let top_part = ($splits | skip | first ($splits_len - 2))
|
||||
let end_part = ($splits | last)
|
||||
let tokens = ($top_part | each {|x|
|
||||
$"($T)/(($x | split chars).0)($R)"
|
||||
})
|
||||
let tokens = ($tokens | append $"/($PB)($end_part)($R)")
|
||||
$tokens | str join $"($T)"
|
||||
} else {
|
||||
let top_part = ($splits | first ($splits_len - 1))
|
||||
let end_part = ($splits | last)
|
||||
let tokens = ($top_part | each {|x|
|
||||
if $x == '~' {
|
||||
$"($T)(($x | split chars).0)($R)"
|
||||
} else {
|
||||
$"/($T)(($x | split chars).0)($R)"
|
||||
}
|
||||
})
|
||||
let tokens = ($tokens | append $"/($PB)($end_part)($R)")
|
||||
$tokens | str join $"($T)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def get_index_change_count [gs] {
|
||||
let index_new = ($gs | get idx_added_staged)
|
||||
let index_modified = ($gs | get idx_modified_staged)
|
||||
let index_deleted = ($gs | get idx_deleted_staged)
|
||||
let index_renamed = ($gs | get idx_renamed)
|
||||
let index_typechanged = ($gs | get idx_type_changed)
|
||||
|
||||
$index_new + $index_modified + $index_deleted + $index_renamed + $index_typechanged
|
||||
}
|
||||
|
||||
def get_working_tree_count [gs] {
|
||||
let wt_modified = ($gs | get wt_modified)
|
||||
let wt_deleted = ($gs | get wt_deleted)
|
||||
let wt_typechanged = ($gs | get wt_type_changed)
|
||||
let wt_renamed = ($gs | get wt_renamed)
|
||||
|
||||
$wt_modified + $wt_deleted + $wt_typechanged + $wt_renamed
|
||||
}
|
||||
|
||||
def get_conflicted_count [gs] {
|
||||
($gs | get conflicts)
|
||||
}
|
||||
|
||||
def get_untracked_count [gs] {
|
||||
($gs | get wt_untracked)
|
||||
}
|
||||
|
||||
def get_branch_name [gs] {
|
||||
let br = ($gs | get branch)
|
||||
if $br == "no_branch" {
|
||||
""
|
||||
} else {
|
||||
$br
|
||||
}
|
||||
}
|
||||
|
||||
def get_ahead_count [gs] {
|
||||
($gs | get ahead)
|
||||
}
|
||||
|
||||
def get_behind_count [gs] {
|
||||
($gs | get behind)
|
||||
}
|
||||
|
||||
def get_icons_list [] {
|
||||
{
|
||||
AHEAD_ICON: (char branch_ahead), # "↑" 2191
|
||||
BEHIND_ICON: (char branch_behind), # "↓" 2193
|
||||
NO_CHANGE_ICON: (char branch_identical) # ≣ 2263
|
||||
HAS_CHANGE_ICON: "*",
|
||||
INDEX_CHANGE_ICON: "♦",
|
||||
WT_CHANGE_ICON: "✚",
|
||||
CONFLICTED_CHANGE_ICON: "✖",
|
||||
UNTRACKED_CHANGE_ICON: (char branch_untracked) # ≢ 2262
|
||||
INSERT_SYMBOL_ICON: "❯",
|
||||
HAMBURGER_ICON: (char hamburger) # "≡" 2261
|
||||
GITHUB_ICON: "", # f408
|
||||
BRANCH_ICON: (char nf_branch) # "" e0a0
|
||||
REBASE_ICON: "", # e728
|
||||
TAG_ICON: "" # f412
|
||||
}
|
||||
}
|
||||
|
||||
def get_icon_by_name [name] {
|
||||
get_icons_list | get $name
|
||||
}
|
||||
|
||||
def get_os_icon [os] {
|
||||
# f17c = tux, f179 = apple, f17a = windows
|
||||
if ($os.name =~ macos) {
|
||||
(char -u f179)
|
||||
} else if ($os.name =~ windows) {
|
||||
(char -u f17a)
|
||||
} else if ($os.kernel_version =~ WSL) {
|
||||
$'(char -u f17a)(char -u f17c)'
|
||||
} else if ($os.family =~ unix) {
|
||||
(char -u f17c)
|
||||
} else {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
# ╭─────────────────────┬───────────────╮
|
||||
# │ idx_added_staged │ 0 │ #INDEX_NEW
|
||||
# │ idx_modified_staged │ 0 │ #INDEX_MODIFIED
|
||||
# │ idx_deleted_staged │ 0 │ #INDEX_DELETED
|
||||
# │ idx_renamed │ 0 │ #INDEX_RENAMED
|
||||
# │ idx_type_changed │ 0 │ #INDEX_TYPECHANGE
|
||||
# │ wt_untracked │ 0 │ #WT_NEW
|
||||
# │ wt_modified │ 0 │ #WT_MODIFIED
|
||||
# │ wt_deleted │ 0 │ #WT_DELETED
|
||||
# │ wt_type_changed │ 0 │ #WT_TYPECHANGE
|
||||
# │ wt_renamed │ 0 │ #WT_RENAMED
|
||||
# │ ignored │ 0 │
|
||||
# │ conflicts │ 0 │ #CONFLICTED
|
||||
# │ ahead │ 0 │
|
||||
# │ behind │ 0 │
|
||||
# │ stashes │ 0 │
|
||||
# │ repo_name │ nushell │
|
||||
# │ tag │ no_tag │
|
||||
# │ branch │ main │
|
||||
# │ remote │ upstream/main │
|
||||
# ╰─────────────────────┴───────────────╯
|
||||
|
||||
def get_repo_status [gs os] {
|
||||
let display_path = (path_abbrev_if_needed (home_abbrev $os.name) (term size).columns)
|
||||
let branch_name = (get_branch_name $gs)
|
||||
let ahead_cnt = (get_ahead_count $gs)
|
||||
let behind_cnt = (get_behind_count $gs)
|
||||
let index_change_cnt = (get_index_change_count $gs)
|
||||
let wt_change_cnt = (get_working_tree_count $gs)
|
||||
let conflicted_cnt = (get_conflicted_count $gs)
|
||||
let untracked_cnt = (get_untracked_count $gs)
|
||||
let has_no_changes = (
|
||||
if ($index_change_cnt <= 0) and
|
||||
($wt_change_cnt <= 0) and
|
||||
($conflicted_cnt <= 0) and
|
||||
($untracked_cnt <= 0) {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
)
|
||||
|
||||
let GIT_BG = "#C4A000"
|
||||
let GIT_FG = "#000000"
|
||||
# let TERM_BG = "#0C0C0C"
|
||||
|
||||
# The multi-color fg colors are good if you just have a black background
|
||||
|
||||
let AHEAD_ICON = (get_icon_by_name AHEAD_ICON)
|
||||
# let A_COLOR = (ansi { fg:"#00ffff" bg: ($GIT_BG) })
|
||||
let A_COLOR = (ansi { fg: ($GIT_FG) bg: ($GIT_BG) })
|
||||
|
||||
let BEHIND_ICON = (get_icon_by_name BEHIND_ICON)
|
||||
# let B_COLOR = (ansi { fg:"#00ffff" bg: ($GIT_BG) })
|
||||
let B_COLOR = (ansi { fg: ($GIT_FG) bg: ($GIT_BG) })
|
||||
|
||||
let INDEX_CHANGE_ICON = (get_icon_by_name INDEX_CHANGE_ICON)
|
||||
# let I_COLOR = (ansi { fg:"#00ff00" bg: ($GIT_BG) })
|
||||
let I_COLOR = (ansi { fg: ($GIT_FG) bg: ($GIT_BG) })
|
||||
|
||||
let CONFLICTED_CHANGE_ICON = (get_icon_by_name CONFLICTED_CHANGE_ICON)
|
||||
# let C_COLOR = (ansi { fg:"#ff0000" bg: ($GIT_BG) })
|
||||
let C_COLOR = (ansi { fg: ($GIT_FG) bg: ($GIT_BG) })
|
||||
|
||||
let WT_CHANGE_ICON = (get_icon_by_name WT_CHANGE_ICON)
|
||||
# let W_COLOR = (ansi { fg:"#ff00ff" bg: ($GIT_BG) })
|
||||
let W_COLOR = (ansi { fg: ($GIT_FG) bg: ($GIT_BG) })
|
||||
|
||||
let UNTRACKED_CHANGE_ICON = (get_icon_by_name UNTRACKED_CHANGE_ICON)
|
||||
# let U_COLOR = (ansi { fg:"#ffff00" bg: ($GIT_BG) })
|
||||
let U_COLOR = (ansi { fg: ($GIT_FG) bg: ($GIT_BG) })
|
||||
|
||||
let NO_CHANGE_ICON = (get_icon_by_name NO_CHANGE_ICON)
|
||||
# let N_COLOR = (ansi { fg:"#00ff00" bg: ($GIT_BG) })
|
||||
let N_COLOR = (ansi { fg: ($GIT_FG) bg: ($GIT_BG) })
|
||||
|
||||
let HAS_CHANGE_ICON = (get_icon_by_name HAS_CHANGE_ICON)
|
||||
# let H_COLOR = (ansi { fg:"#ff0000" bg: ($GIT_BG) attr: b })
|
||||
let H_COLOR = (ansi { fg: ($GIT_FG) bg: ($GIT_BG) attr: b })
|
||||
|
||||
let INSERT_SYMBOL_ICON = (get_icon_by_name INSERT_SYMBOL_ICON)
|
||||
# let S_COLOR = (ansi { fg:"#00ffff" bg: ($GIT_BG) })
|
||||
let S_COLOR = (ansi { fg: ($GIT_FG) bg: ($GIT_BG) })
|
||||
|
||||
let R = (ansi reset)
|
||||
|
||||
let repo_status = (
|
||||
$"(
|
||||
if ($ahead_cnt > 0) { $'($A_COLOR)($AHEAD_ICON)($ahead_cnt)($R)' }
|
||||
)(
|
||||
if ($behind_cnt > 0) { $'($B_COLOR)($BEHIND_ICON)($behind_cnt)($R)' }
|
||||
)(
|
||||
if ($index_change_cnt > 0) { $'($I_COLOR)($INDEX_CHANGE_ICON)($index_change_cnt)($R)' }
|
||||
)(
|
||||
if ($conflicted_cnt > 0) { $'($C_COLOR)($CONFLICTED_CHANGE_ICON)($conflicted_cnt)($R)' }
|
||||
)(
|
||||
if ($wt_change_cnt > 0) { $'($W_COLOR)($WT_CHANGE_ICON)($wt_change_cnt)($R)' }
|
||||
)(
|
||||
if ($untracked_cnt > 0) { $'($U_COLOR)($UNTRACKED_CHANGE_ICON)($untracked_cnt)($R)' }
|
||||
)(
|
||||
if $has_no_changes { $'($N_COLOR)($NO_CHANGE_ICON)($R)' } else { $'($H_COLOR)($HAS_CHANGE_ICON)($R)' }
|
||||
)"
|
||||
)
|
||||
|
||||
$repo_status
|
||||
}
|
||||
|
||||
def git_left_prompt [gs os] {
|
||||
# replace this 30 with whatever the width of the terminal is
|
||||
let display_path = (path_abbrev_if_needed (home_abbrev $os.name) (term size).columns)
|
||||
let branch_name = (get_branch_name $gs)
|
||||
let R = (ansi reset)
|
||||
|
||||
# when reduce is available
|
||||
# echo "one" "two" "three" | reduce { if ($acc | str starts-with 't') { $acc + $it } { $it }}
|
||||
|
||||
# some icons and the unicode char
|
||||
# e0b0
|
||||
# e0b1
|
||||
# e0b2
|
||||
# e0b3
|
||||
# f1d3
|
||||
# f07c or f115
|
||||
# f015 or f7db
|
||||
|
||||
let GIT_BG = "#C4A000"
|
||||
let GIT_FG = "#000000"
|
||||
let TERM_BG = "#0C0C0C"
|
||||
|
||||
let repo_status = (get_repo_status $gs $os)
|
||||
|
||||
# build segments and then put together the segments for the prompt
|
||||
let os_segment = ([
|
||||
(ansi { fg: "#080808" bg: "#CED7CF"}) # os bg color
|
||||
(char space) # space
|
||||
(get_os_icon $os) # os icon
|
||||
(char space) # space
|
||||
(ansi { fg: "#CED7CF" bg: "#3465A4"}) # color transition
|
||||
(char -u e0b0) #
|
||||
(char space) # space
|
||||
] | str join)
|
||||
|
||||
let is_home_in_path = ($env.PWD | str starts-with $nu.home-path)
|
||||
let path_segment = (if (($is_home_in_path) and ($branch_name == "")) {
|
||||
[
|
||||
(char -u f015) # home icon
|
||||
(char space) # space
|
||||
$display_path # ~/src/forks/nushell
|
||||
(ansi { fg: "#CED7CF" bg: "#3465A4"}) # color just to color the next space
|
||||
(char space) # space
|
||||
] | str join
|
||||
} else {
|
||||
[
|
||||
(char -u f07c) # folder icon
|
||||
(char space) # space
|
||||
$display_path # ~/src/forks/nushell
|
||||
(ansi { fg: "#CED7CF" bg: "#3465A4"}) # color just to color the next space
|
||||
(char space) # space
|
||||
] | str join
|
||||
})
|
||||
|
||||
let git_segment = (if ($branch_name != "") {
|
||||
[
|
||||
(ansi { fg: "#3465A4" bg: "#4E9A06"}) # color
|
||||
(char -u e0b0) #
|
||||
(char space) # space
|
||||
(ansi { fg: $TERM_BG bg: "#4E9A06"}) # color
|
||||
# (char -u f1d3) #
|
||||
(char -u e0a0) #
|
||||
(char space) # space
|
||||
($branch_name) # main
|
||||
(char space) # space
|
||||
(ansi { fg: "#4E9A06" bg: $GIT_BG}) # color
|
||||
(char -u e0b0) #
|
||||
(char space) # space
|
||||
($R) # reset color
|
||||
$repo_status # repo status
|
||||
] | str join
|
||||
})
|
||||
|
||||
let git_right = false
|
||||
let indicator_segment = (if ($branch_name == "" or $git_right) {
|
||||
[
|
||||
(ansi { fg: "#3465A4" bg: $TERM_BG}) # color
|
||||
(char -u e0b0) #
|
||||
($R) # reset color
|
||||
] | str join
|
||||
} else {
|
||||
[
|
||||
(ansi { fg: $GIT_BG bg: $TERM_BG}) # color
|
||||
(char -u e0b0) #
|
||||
($R) # reset color
|
||||
] | str join
|
||||
})
|
||||
|
||||
# assemble all segments for final prompt printing
|
||||
[
|
||||
$os_segment
|
||||
$path_segment
|
||||
(if ($git_right == false) {
|
||||
$git_segment
|
||||
})
|
||||
$indicator_segment
|
||||
] | str join
|
||||
}
|
||||
|
||||
def git_right_prompt [gs os] {
|
||||
# right prompt ideas
|
||||
# 1. just the time on the right
|
||||
# 2. date and time on the right
|
||||
# 3. git information on the right
|
||||
# 4. maybe git and time
|
||||
# 5. would like to get CMD_DURATION_MS going there too when it's implemented
|
||||
# 6. all of the above, chosen by def parameters
|
||||
|
||||
let branch_name = (get_branch_name $gs)
|
||||
let repo_status = (get_repo_status $gs $os)
|
||||
let R = (ansi reset)
|
||||
let TIME_BG = "#D3D7CF"
|
||||
let TERM_FG = "#0C0C0C"
|
||||
let GIT_BG = "#C4A000"
|
||||
let GIT_FG = "#000000"
|
||||
let TERM_BG = "#0C0C0C"
|
||||
let TERM_FG_DEFAULT = "\e[39m"
|
||||
let TERM_BG_DEFAULT = "\e[49m"
|
||||
|
||||
let datetime_segment = ([
|
||||
(ansi { fg: $TIME_BG bg: $TERM_FG})
|
||||
(char -u e0b2) #
|
||||
(ansi { fg: $TERM_FG bg: $TIME_BG})
|
||||
(char space)
|
||||
(date now | format date '%m/%d/%Y %I:%M:%S%.3f')
|
||||
(char space)
|
||||
($R)
|
||||
] | str join)
|
||||
|
||||
let time_segment = ([
|
||||
(ansi { fg: $TIME_BG bg: $TERM_FG})
|
||||
(char -u e0b2) #
|
||||
(ansi { fg: $TERM_FG bg: $TIME_BG})
|
||||
(char space)
|
||||
(date now | format date '%I:%M:%S %p')
|
||||
(char space)
|
||||
($R)
|
||||
] | str join)
|
||||
|
||||
let git_segment = (if ($branch_name != "") {
|
||||
[
|
||||
(ansi { fg: $GIT_BG bg: $TERM_BG}) # color
|
||||
(char -u e0b2) #
|
||||
(ansi { fg: $TERM_FG bg: $GIT_BG}) # color
|
||||
(char space) # space
|
||||
$repo_status # repo status
|
||||
(ansi { fg: $TERM_FG bg: $GIT_BG}) # color
|
||||
(char space)
|
||||
(ansi { fg: "#4E9A06" bg: $GIT_BG }) # color
|
||||
(char -u e0b2) #
|
||||
(ansi { fg: $TERM_BG bg: "#4E9A06"}) # color
|
||||
(char space) # space
|
||||
# (char -u f1d3) #
|
||||
# (char -u e0a0) #
|
||||
(char nf_git_branch) #
|
||||
(char space) # space
|
||||
$branch_name # main
|
||||
(char space) # space
|
||||
($R) # reset color
|
||||
] | str join
|
||||
})
|
||||
|
||||
let execution_time_segment = (
|
||||
[
|
||||
# (ansi { fg: "#606060" bg: "#191323"})
|
||||
(ansi { fg: "#606060"})
|
||||
$TERM_BG_DEFAULT
|
||||
(char -u e0b3)
|
||||
(char space)
|
||||
$env.CMD_DURATION_MS
|
||||
(char space)
|
||||
($R)
|
||||
] | str join
|
||||
)
|
||||
|
||||
let status_segment = (
|
||||
[
|
||||
(if $env.LAST_EXIT_CODE != 0 {
|
||||
(ansi { fg: "#CC0000" })
|
||||
} else {
|
||||
(ansi { fg: "#606060" })
|
||||
})
|
||||
(char -u e0b3)
|
||||
(char space)
|
||||
$env.LAST_EXIT_CODE
|
||||
(char space)
|
||||
($R)
|
||||
] | str join
|
||||
)
|
||||
# 1. datetime - working
|
||||
# $datetime_segment
|
||||
|
||||
# 2. time only - working
|
||||
[
|
||||
(if $env.LAST_EXIT_CODE != 0 {
|
||||
$status_segment
|
||||
})
|
||||
$execution_time_segment
|
||||
$time_segment
|
||||
] | str join
|
||||
|
||||
# 3. git only - working
|
||||
# $git_segment
|
||||
|
||||
# 4. git + time -> need to fix the transition
|
||||
# [
|
||||
# $git_segment
|
||||
# $time_segment
|
||||
# ] | str join
|
||||
|
||||
# 5. fernando wants this on the left prompt
|
||||
# [
|
||||
# $os_segment
|
||||
# $time_segment
|
||||
# $path_segment
|
||||
# ]
|
||||
}
|
||||
|
||||
export def git_prompt [] {
|
||||
let gs = (gstat)
|
||||
let os = $nu.os-info
|
||||
let left_prompt = (git_left_prompt $gs $os)
|
||||
let right_prompt = (git_right_prompt $gs $os)
|
||||
|
||||
# set the title of the window/tab
|
||||
# Wezterm accepts:
|
||||
# osc0 \x1b]0;
|
||||
# osc1 \x1b]1;
|
||||
# osc2 \x1b]2;
|
||||
# the typical way to set the terminal title is:
|
||||
# osc2 some_string bel aka (char osc)2;($some_string)(char bel) or "\u001b]2;($some_string)\a"
|
||||
# bel is escape \a or \x7 or \u0007
|
||||
# but i've also seen it as
|
||||
# osc2 some_string string_terminator aka (char osc)2;($some_string)(ansi st) or "\u001b];($some_string)\\"
|
||||
# where string_terminator is \
|
||||
# so you might want to play around with these settings a bit
|
||||
|
||||
#let abbrev = ((path_abbrev_if_needed (home_abbrev $os.name) 30) | ansi strip)
|
||||
|
||||
# $"\u001b]0;($abbrev)"
|
||||
# note that this isn't ending properly with a bel or a st, that's
|
||||
# because it makes the string echo to the screen as an empty line
|
||||
|
||||
# turning off now since a similar thing is built into nushell + it breaks kitty
|
||||
#$"(ansi osc)2;($abbrev)"
|
||||
|
||||
# return in record literal syntax to be used kind of like a tuple
|
||||
# so we don't have to run this script more than once per prompt
|
||||
{
|
||||
left_prompt: $left_prompt
|
||||
right_prompt: $right_prompt
|
||||
}
|
||||
#
|
||||
# in the config.nu you would do something like
|
||||
# use "c:\some\path\to\nu_scripts\prompt\oh-my.nu" git_prompt
|
||||
# $env.PROMPT_COMMAND = { (git_prompt).left_prompt }
|
||||
# $env.PROMPT_COMMAND_RIGHT = { (git_prompt).right_prompt }
|
||||
# $env.PROMPT_INDICATOR = " "
|
||||
}
|
||||
462
dot_config/nushell/nu_scripts/modules/prompt/panache-git.nu
Normal file
462
dot_config/nushell/nu_scripts/modules/prompt/panache-git.nu
Normal file
@@ -0,0 +1,462 @@
|
||||
# panache-git
|
||||
# An opinionated Git prompt for Nushell, styled after posh-git
|
||||
#
|
||||
# Quick Start:
|
||||
# - Download this file (panache-git.nu)
|
||||
# - In your Nushell config:
|
||||
# - Import the main command from the panache-git.nu module file
|
||||
# - Set panache-git as your prompt command
|
||||
# - Disable the separate prompt indicator by setting it to an empty string
|
||||
# - For example, with this file in your home directory:
|
||||
# use ~/panache-git.nu main
|
||||
# $env.PROMPT_COMMAND = {|| panache-git }
|
||||
# $env.PROMPT_INDICATOR = {|| "" }
|
||||
# - Restart Nushell
|
||||
#
|
||||
# For more documentation or to file an issue, see https://github.com/ehdevries/panache-git
|
||||
|
||||
|
||||
# An opinionated Git prompt for Nushell, styled after posh-git
|
||||
export def main [] {
|
||||
let prompt = ($'(current-dir) (repo-styled)' | str trim)
|
||||
$'($prompt)> '
|
||||
}
|
||||
|
||||
# Get the current directory with home abbreviated
|
||||
export def current-dir [] {
|
||||
let current_dir = ($env.PWD)
|
||||
|
||||
let current_dir_relative_to_home = (
|
||||
do --ignore-errors { $current_dir | path relative-to $nu.home-path } | str join
|
||||
)
|
||||
|
||||
let in_sub_dir_of_home = ($current_dir_relative_to_home | is-not-empty)
|
||||
|
||||
let current_dir_abbreviated = (if $in_sub_dir_of_home {
|
||||
$'~(char separator)($current_dir_relative_to_home)' | str replace -ar '\\' '/'
|
||||
} else {
|
||||
$current_dir | str replace -ar '\\' '/'
|
||||
})
|
||||
|
||||
$'(ansi reset)($current_dir_abbreviated)'
|
||||
}
|
||||
|
||||
# Get repository status as structured data
|
||||
export def repo-structured [] {
|
||||
let in_git_repo = (do { git rev-parse --abbrev-ref HEAD } | complete | get stdout | is-not-empty)
|
||||
|
||||
let status = (if $in_git_repo {
|
||||
git --no-optional-locks status --porcelain=2 --branch | lines
|
||||
} else {
|
||||
[]
|
||||
})
|
||||
|
||||
let on_named_branch = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.head')
|
||||
| first
|
||||
| str contains '(detached)'
|
||||
| not $in
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let branch_name = (if $on_named_branch {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.head')
|
||||
| split column ' ' col1 col2 branch
|
||||
| get branch
|
||||
| first
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let commit_hash = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.oid')
|
||||
| split column ' ' col1 col2 full_hash
|
||||
| get full_hash
|
||||
| first
|
||||
| str substring 0..7
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let tracking_upstream_branch = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.upstream')
|
||||
| str join
|
||||
| is-not-empty
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let upstream_exists_on_remote = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.ab')
|
||||
| str join
|
||||
| is-not-empty
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let ahead_behind_table = (if $upstream_exists_on_remote {
|
||||
$status
|
||||
| where ($it | str starts-with '# branch.ab')
|
||||
| split column ' ' col1 col2 ahead behind
|
||||
} else {
|
||||
[[]]
|
||||
})
|
||||
|
||||
let commits_ahead = (if $upstream_exists_on_remote {
|
||||
$ahead_behind_table
|
||||
| get ahead
|
||||
| first
|
||||
| into int
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let commits_behind = (if $upstream_exists_on_remote {
|
||||
$ahead_behind_table
|
||||
| get behind
|
||||
| first
|
||||
| into int
|
||||
| math abs
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let has_staging_or_worktree_changes = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '1') or ($it | str starts-with '2')
|
||||
| str join
|
||||
| is-not-empty
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let has_untracked_files = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with '?')
|
||||
| str join
|
||||
| is-not-empty
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let has_unresolved_merge_conflicts = (if $in_git_repo {
|
||||
$status
|
||||
| where ($it | str starts-with 'u')
|
||||
| str join
|
||||
| is-not-empty
|
||||
} else {
|
||||
false
|
||||
})
|
||||
|
||||
let staging_worktree_table = (if $has_staging_or_worktree_changes {
|
||||
$status
|
||||
| where ($it | str starts-with '1') or ($it | str starts-with '2')
|
||||
| split column ' '
|
||||
| get column2
|
||||
| split column '' staging worktree --collapse-empty
|
||||
} else {
|
||||
[[]]
|
||||
})
|
||||
|
||||
let staging_added_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where staging == 'A'
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let staging_modified_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where staging in ['M', 'R']
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let staging_deleted_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where staging == 'D'
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let untracked_count = (if $has_untracked_files {
|
||||
$status
|
||||
| where ($it | str starts-with '?')
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let worktree_modified_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where worktree in ['M', 'R']
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let worktree_deleted_count = (if $has_staging_or_worktree_changes {
|
||||
$staging_worktree_table
|
||||
| where worktree == 'D'
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
let merge_conflict_count = (if $has_unresolved_merge_conflicts {
|
||||
$status
|
||||
| where ($it | str starts-with 'u')
|
||||
| length
|
||||
} else {
|
||||
0
|
||||
})
|
||||
|
||||
{
|
||||
in_git_repo: $in_git_repo,
|
||||
on_named_branch: $on_named_branch,
|
||||
branch_name: $branch_name,
|
||||
commit_hash: $commit_hash,
|
||||
tracking_upstream_branch: $tracking_upstream_branch,
|
||||
upstream_exists_on_remote: $upstream_exists_on_remote,
|
||||
commits_ahead: $commits_ahead,
|
||||
commits_behind: $commits_behind,
|
||||
staging_added_count: $staging_added_count,
|
||||
staging_modified_count: $staging_modified_count,
|
||||
staging_deleted_count: $staging_deleted_count,
|
||||
untracked_count: $untracked_count,
|
||||
worktree_modified_count: $worktree_modified_count,
|
||||
worktree_deleted_count: $worktree_deleted_count,
|
||||
merge_conflict_count: $merge_conflict_count
|
||||
}
|
||||
}
|
||||
|
||||
# Get repository status as a styled string
|
||||
export def repo-styled [] {
|
||||
let status = (repo-structured)
|
||||
|
||||
let is_local_only = ($status.tracking_upstream_branch != true)
|
||||
|
||||
let upstream_deleted = (
|
||||
$status.tracking_upstream_branch and
|
||||
$status.upstream_exists_on_remote != true
|
||||
)
|
||||
|
||||
let is_up_to_date = (
|
||||
$status.upstream_exists_on_remote and
|
||||
$status.commits_ahead == 0 and
|
||||
$status.commits_behind == 0
|
||||
)
|
||||
|
||||
let is_ahead = (
|
||||
$status.upstream_exists_on_remote and
|
||||
$status.commits_ahead > 0 and
|
||||
$status.commits_behind == 0
|
||||
)
|
||||
|
||||
let is_behind = (
|
||||
$status.upstream_exists_on_remote and
|
||||
$status.commits_ahead == 0 and
|
||||
$status.commits_behind > 0
|
||||
)
|
||||
|
||||
let is_ahead_and_behind = (
|
||||
$status.upstream_exists_on_remote and
|
||||
$status.commits_ahead > 0 and
|
||||
$status.commits_behind > 0
|
||||
)
|
||||
|
||||
let branch_name = (if $status.in_git_repo {
|
||||
(if $status.on_named_branch {
|
||||
$status.branch_name
|
||||
} else {
|
||||
['(' $status.commit_hash '...)'] | str join
|
||||
})
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let branch_styled = (if $status.in_git_repo {
|
||||
(if $is_local_only {
|
||||
(branch-local-only $branch_name)
|
||||
} else if $is_up_to_date {
|
||||
(branch-up-to-date $branch_name)
|
||||
} else if $is_ahead {
|
||||
(branch-ahead $branch_name $status.commits_ahead)
|
||||
} else if $is_behind {
|
||||
(branch-behind $branch_name $status.commits_behind)
|
||||
} else if $is_ahead_and_behind {
|
||||
(branch-ahead-and-behind $branch_name $status.commits_ahead $status.commits_behind)
|
||||
} else if $upstream_deleted {
|
||||
(branch-upstream-deleted $branch_name)
|
||||
} else {
|
||||
$branch_name
|
||||
})
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let has_staging_changes = (
|
||||
$status.staging_added_count > 0 or
|
||||
$status.staging_modified_count > 0 or
|
||||
$status.staging_deleted_count > 0
|
||||
)
|
||||
|
||||
let has_worktree_changes = (
|
||||
$status.untracked_count > 0 or
|
||||
$status.worktree_modified_count > 0 or
|
||||
$status.worktree_deleted_count > 0 or
|
||||
$status.merge_conflict_count > 0
|
||||
)
|
||||
|
||||
let has_merge_conflicts = $status.merge_conflict_count > 0
|
||||
|
||||
let staging_summary = (if $has_staging_changes {
|
||||
(staging-changes $status.staging_added_count $status.staging_modified_count $status.staging_deleted_count)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let worktree_summary = (if $has_worktree_changes {
|
||||
(worktree-changes $status.untracked_count $status.worktree_modified_count $status.worktree_deleted_count)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let merge_conflict_summary = (if $has_merge_conflicts {
|
||||
(unresolved-conflicts $status.merge_conflict_count)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let delimiter = (if ($has_staging_changes and $has_worktree_changes) {
|
||||
('|' | bright-yellow)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let local_summary = (
|
||||
$'($staging_summary) ($delimiter) ($worktree_summary) ($merge_conflict_summary)' | str trim
|
||||
)
|
||||
|
||||
let local_indicator = (if $status.in_git_repo {
|
||||
(if $has_worktree_changes {
|
||||
('!' | red)
|
||||
} else if $has_staging_changes {
|
||||
('~' | bright-cyan)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let repo_summary = (
|
||||
$'($branch_styled) ($local_summary) ($local_indicator)' | str trim
|
||||
)
|
||||
|
||||
let left_bracket = ('[' | bright-yellow)
|
||||
let right_bracket = (']' | bright-yellow)
|
||||
|
||||
(if $status.in_git_repo {
|
||||
$'($left_bracket)($repo_summary)($right_bracket)'
|
||||
} else {
|
||||
''
|
||||
})
|
||||
}
|
||||
|
||||
# Helper commands to encapsulate style and make everything else more readable
|
||||
|
||||
def bright-cyan [] {
|
||||
each { |it| $"(ansi -e '96m')($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def bright-green [] {
|
||||
each { |it| $"(ansi -e '92m')($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def bright-red [] {
|
||||
each { |it| $"(ansi -e '91m')($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def bright-yellow [] {
|
||||
each { |it| $"(ansi -e '93m')($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def green [] {
|
||||
each { |it| $"(ansi green)($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def red [] {
|
||||
each { |it| $"(ansi red)($it)(ansi reset)" }
|
||||
}
|
||||
|
||||
def branch-local-only [
|
||||
branch: string
|
||||
] {
|
||||
$branch | bright-cyan
|
||||
}
|
||||
|
||||
def branch-upstream-deleted [
|
||||
branch: string
|
||||
] {
|
||||
$'($branch) (char failed)' | bright-cyan
|
||||
}
|
||||
|
||||
def branch-up-to-date [
|
||||
branch: string
|
||||
] {
|
||||
$'($branch) (char identical_to)' | bright-cyan
|
||||
}
|
||||
|
||||
def branch-ahead [
|
||||
branch: string
|
||||
ahead: int
|
||||
] {
|
||||
$'($branch) (char branch_ahead)($ahead)' | bright-green
|
||||
}
|
||||
|
||||
def branch-behind [
|
||||
branch: string
|
||||
behind: int
|
||||
] {
|
||||
$'($branch) (char branch_behind)($behind)' | bright-red
|
||||
}
|
||||
|
||||
def branch-ahead-and-behind [
|
||||
branch: string
|
||||
ahead: int
|
||||
behind: int
|
||||
] {
|
||||
$'($branch) (char branch_behind)($behind) (char branch_ahead)($ahead)' | bright-yellow
|
||||
}
|
||||
|
||||
def staging-changes [
|
||||
added: int
|
||||
modified: int
|
||||
deleted: int
|
||||
] {
|
||||
$'+($added) ~($modified) -($deleted)' | green
|
||||
}
|
||||
|
||||
def worktree-changes [
|
||||
added: int
|
||||
modified: int
|
||||
deleted: int
|
||||
] {
|
||||
$'+($added) ~($modified) -($deleted)' | red
|
||||
}
|
||||
|
||||
def unresolved-conflicts [
|
||||
conflicts: int
|
||||
] {
|
||||
$'!($conflicts)' | red
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
### 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: cyan
|
||||
} {
|
||||
reverse: true
|
||||
separator: '@'
|
||||
}
|
||||
use power_utils.nu
|
||||
power inject 0 1 {source: atuin, color: '#4C4B4A'}
|
||||
power set time null { style: compact }
|
||||
power init
|
||||
```
|
||||
or
|
||||
```
|
||||
$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
|
||||
- `$env.NU_POWER_MODE = '<power|fast>'` fast mode and default mode (experimental)
|
||||
- `$env.NU_POWER_DECORATOR = '<power|plain>'` power mode and plain mode
|
||||
- `$env.NU_POWER_FRAME = '<default|fill>'` two line prompt (experimental)
|
||||
|
||||
### benchmark
|
||||
```
|
||||
$env.NU_POWER_BENCHMARK = true
|
||||
```
|
||||
Then execute a few commands casually, such as pressing the Enter key continuously.
|
||||
then execute
|
||||
|
||||
```
|
||||
$env.NU_POWER_MODE = 'fast' # or 'power'
|
||||
```
|
||||
|
||||
Go ahead and press enter,
|
||||
Execute power timelog to analyze the results.
|
||||
```
|
||||
power analyze
|
||||
```
|
||||
|
||||
## todo
|
||||
- [x] source return `null` for hiding
|
||||
- [ ] in fast mode, there is still a problem with hideable components on the left
|
||||
- [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
|
||||
- [x] refactor: theme/decorator/frame/schema
|
||||
|
||||
618
dot_config/nushell/nu_scripts/modules/prompt/powerline/power.nu
Normal file
618
dot_config/nushell/nu_scripts/modules/prompt/powerline/power.nu
Normal file
@@ -0,0 +1,618 @@
|
||||
### 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) {
|
||||
{ related: '>', path: '' }
|
||||
} else {
|
||||
{ related: '<', path: $suffix}
|
||||
}
|
||||
}
|
||||
|
||||
export def "pwd_abbr" [] {
|
||||
{|bg|
|
||||
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
|
||||
}
|
||||
[$bg $"($style)($dir_comp | str join (char separator))"]
|
||||
}
|
||||
}
|
||||
|
||||
### proxy
|
||||
export def proxy_stat [] {
|
||||
{|bg|
|
||||
let theme = $env.NU_POWER_THEME.proxy
|
||||
if not (($env.https_proxy? | is-empty) and ($env.http_proxy? | is-empty)) {
|
||||
[$bg '']
|
||||
} else {
|
||||
[$bg null]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### host
|
||||
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 {
|
||||
$theme.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)
|
||||
# HACK: serialization
|
||||
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 wraptime [message action] {
|
||||
if $env.NU_POWER_BENCHMARK? == true {
|
||||
{|| logtime $message $action }
|
||||
} else {
|
||||
$action
|
||||
}
|
||||
}
|
||||
|
||||
def get_component [schema] {
|
||||
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_segment)'
|
||||
$'($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)]
|
||||
})
|
||||
{||
|
||||
let segment = ($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
|
||||
| enumerate
|
||||
| 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|
|
||||
let y = (do $x.1 $x.0)
|
||||
if $y.1 == null {
|
||||
$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
|
||||
color?: string = 'light_yellow'
|
||||
next_color?: 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: $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 -e {fg: $color})(char nf_left_segment)'
|
||||
{|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|
|
||||
if $x.index == $stop {
|
||||
[$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 | append $y.1
|
||||
}
|
||||
}
|
||||
| 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
|
||||
'dynamic left'
|
||||
(left_prompt $env.NU_POWER_SCHEMA.0)
|
||||
)
|
||||
$env.PROMPT_COMMAND_RIGHT = (wraptime
|
||||
'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' => {
|
||||
$env.PROMPT_COMMAND = (up_prompt $env.NU_POWER_SCHEMA)
|
||||
}
|
||||
}
|
||||
|
||||
$env.PROMPT_INDICATOR = {||
|
||||
match $env.NU_POWER_DECORATOR {
|
||||
'plain' => { "> " }
|
||||
_ => { " " }
|
||||
}
|
||||
}
|
||||
$env.PROMPT_INDICATOR_VI_INSERT = {|| ": " }
|
||||
$env.PROMPT_INDICATOR_VI_NORMAL = {|| "> " }
|
||||
$env.PROMPT_MULTILINE_INDICATOR = {||
|
||||
match $env.NU_POWER_DECORATOR {
|
||||
'plain' => { "::: " }
|
||||
_ => { $"(char haze) " }
|
||||
}
|
||||
}
|
||||
|
||||
$env.config = ( $env.config | update menus ($env.config.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 {
|
||||
$env.NU_POWER_THEME
|
||||
| upsert $name ($theme
|
||||
| transpose k v
|
||||
| reduce -f {} {|it, acc|
|
||||
$acc | insert $it.k (ansi -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?] {
|
||||
set $name $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 {
|
||||
$prev | prepend $define
|
||||
} else {
|
||||
[
|
||||
($prev | range 0..($idx - 1))
|
||||
$define
|
||||
($prev | range $idx..)
|
||||
] | flatten
|
||||
}
|
||||
|
||||
$env.NU_POWER_SCHEMA = (
|
||||
$env.NU_POWER_SCHEMA
|
||||
| update $pos $next
|
||||
)
|
||||
|
||||
let kind = $define.source
|
||||
|
||||
if not ($theme | is-empty) {
|
||||
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 {
|
||||
$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) {
|
||||
let prev_cols = ($env.NU_POWER_CONFIG | get $kind | columns)
|
||||
for n in ($config | transpose k v) {
|
||||
if $n.k in $prev_cols {
|
||||
$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 } }]
|
||||
$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 [{ |before, after|
|
||||
if not ($before | is-empty) {
|
||||
init
|
||||
rm -f ~/.cache/nushell/power_time.log
|
||||
}
|
||||
}]
|
||||
|
||||
# NU_POWER_THEME
|
||||
})
|
||||
}
|
||||
|
||||
export-env {
|
||||
$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
|
||||
NU_POWER_MENU_MARKER
|
||||
{
|
||||
"| " : 'green'
|
||||
": " : 'yellow'
|
||||
"# " : 'blue'
|
||||
"? " : 'red'
|
||||
}
|
||||
)
|
||||
|
||||
$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: {
|
||||
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)
|
||||
proxy: (proxy_stat)
|
||||
host: (host_abbr)
|
||||
time: (time_segment)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
### git
|
||||
def _git_status [] {
|
||||
# TODO: show-stash
|
||||
let raw_status = (do -i { git --no-optional-locks status --porcelain=2 --branch | lines })
|
||||
|
||||
let stashes = (do -i { git stash list | lines | length })
|
||||
|
||||
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 : $stashes
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$status
|
||||
}
|
||||
|
||||
export def git_stat [] {
|
||||
{|bg|
|
||||
let status = (_git_status)
|
||||
|
||||
if $status.branch == 'no_branch' { return [$bg ''] }
|
||||
|
||||
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
|
||||
| reduce -f "" {|x, acc|
|
||||
let y = ($status | get $x.0)
|
||||
if $y > 0 {
|
||||
$acc + $"(ansi $'light_($x.2)_dimmed')($x.1)($y)"
|
||||
} else {
|
||||
$acc
|
||||
}
|
||||
})
|
||||
|
||||
[$bg $'($branch)($summary)']
|
||||
}
|
||||
}
|
||||
|
||||
export-env {
|
||||
$env.NU_PROMPT_GIT_FORMATTER = (power default_env
|
||||
NU_PROMPT_GIT_FORMATTER
|
||||
[
|
||||
[behind (char branch_behind) yellow]
|
||||
[ahead (char branch_ahead) yellow]
|
||||
[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]
|
||||
[stashes = blue]
|
||||
]
|
||||
)
|
||||
|
||||
power register git (git_stat) {
|
||||
default : blue
|
||||
no_upstream: red
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
### kubernetes
|
||||
export def ensure-cache [cache path action] {
|
||||
let ts = (do -i { ls $path | sort-by modified | reverse | get 0.modified })
|
||||
if ($ts | is-empty) { return false }
|
||||
let tc = (do -i { ls $cache | get 0.modified })
|
||||
if not (($cache | path exists) and ($ts < $tc)) {
|
||||
mkdir ($cache | path dirname)
|
||||
do $action | save -f $cache
|
||||
}
|
||||
open $cache
|
||||
}
|
||||
|
||||
def "kube ctx" [] {
|
||||
mut cache = ''
|
||||
mut file = ''
|
||||
if ($env.KUBECONFIG? | is-empty) {
|
||||
$cache = $'($env.HOME)/.cache/nu-power/kube.json'
|
||||
$file = $"($env.HOME)/.kube/config"
|
||||
} else {
|
||||
$cache = $"($env.HOME)/.cache/nu-power/kube-($env.KUBECONFIG | str replace -a '/' ':').json"
|
||||
$file = $env.KUBECONFIG
|
||||
}
|
||||
if not ($file | path exists) { return null }
|
||||
ensure-cache $cache $file {
|
||||
do -i {
|
||||
kubectl config get-contexts
|
||||
| from ssv -a
|
||||
| where CURRENT == '*'
|
||||
| get 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def kube_stat [] {
|
||||
{|bg|
|
||||
let ctx = (kube ctx)
|
||||
if ($ctx | is-empty) {
|
||||
[$bg ""]
|
||||
} else {
|
||||
let theme = $env.NU_POWER_THEME.kube
|
||||
let config = $env.NU_POWER_CONFIG.kube
|
||||
let p = if $config.reverse {
|
||||
$"($theme.namespace)($ctx.NAMESPACE)($theme.separator)($config.separator)($theme.context)($ctx.NAME)"
|
||||
} else {
|
||||
$"($theme.context)($ctx.NAME)($theme.separator)($config.separator)($theme.namespace)($ctx.NAMESPACE)"
|
||||
}
|
||||
[$bg $"($p)"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export-env {
|
||||
power register kube (kube_stat) {
|
||||
context: cyan
|
||||
separator: purple
|
||||
namespace: yellow
|
||||
} {
|
||||
reverse: false
|
||||
separator: ':'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
export def atuin_stat [] {
|
||||
{|bg|
|
||||
let theme = $env.NU_POWER_THEME.atuin
|
||||
if not ($env.ATUIN_SESSION? | is-empty) {
|
||||
[$bg '']
|
||||
} else {
|
||||
['#504945' '']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export-env {
|
||||
power register atuin (atuin_stat) {
|
||||
on: white
|
||||
}
|
||||
}
|
||||
21
dot_config/nushell/nu_scripts/modules/prompt/shell_space.nu
Normal file
21
dot_config/nushell/nu_scripts/modules/prompt/shell_space.nu
Normal file
@@ -0,0 +1,21 @@
|
||||
# use shells to to show workspaces
|
||||
def workspaces [] {
|
||||
shells | each {|item index|
|
||||
if $item.active {
|
||||
$"(ansi green)($index) "
|
||||
} else {
|
||||
$"(ansi blue)($index) "
|
||||
}
|
||||
}| str join
|
||||
}
|
||||
|
||||
def create_right_prompt [] {
|
||||
let time_segment = ([
|
||||
(date now | format date '%r'),
|
||||
" ",
|
||||
(workspaces)
|
||||
] | str join)
|
||||
$time_segment
|
||||
}
|
||||
|
||||
$env.PROMPT_COMMAND_RIGHT = { create_right_prompt }
|
||||
22
dot_config/nushell/nu_scripts/modules/prompt/simple.nu
Normal file
22
dot_config/nushell/nu_scripts/modules/prompt/simple.nu
Normal file
@@ -0,0 +1,22 @@
|
||||
export def create_left_prompt [] {
|
||||
let path_segment = if (is-admin) {
|
||||
$"(ansi red_bold)($env.PWD)"
|
||||
} else {
|
||||
$"(ansi green_bold)($env.PWD)"
|
||||
}
|
||||
let duration_segment = do {
|
||||
let duration_secs = ($env.CMD_DURATION_MS | into int) / 1000
|
||||
if ($duration_secs >= 5) {
|
||||
$"(ansi yellow_bold)($duration_secs | math round | into string | append "sec" | str join | into duration) "
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
let exit_code_segment = if ($env.LAST_EXIT_CODE == 0) {
|
||||
""
|
||||
} else {
|
||||
$"(ansi red_bold)($env.LAST_EXIT_CODE) "
|
||||
}
|
||||
|
||||
[$duration_segment, $exit_code_segment, $path_segment] | str join
|
||||
}
|
||||
11
dot_config/nushell/nu_scripts/modules/prompt/starship.nu
Normal file
11
dot_config/nushell/nu_scripts/modules/prompt/starship.nu
Normal file
@@ -0,0 +1,11 @@
|
||||
def create_left_prompt [] {
|
||||
^starship prompt --cmd-duration $env.CMD_DURATION_MS $'--status=($env.LAST_EXIT_CODE)'
|
||||
}
|
||||
|
||||
$env.PROMPT_COMMAND = { create_left_prompt }
|
||||
|
||||
# avoid same PROMPT_INDICATOR
|
||||
$env.PROMPT_INDICATOR = { "" }
|
||||
$env.PROMPT_INDICATOR_VI_INSERT = { ": " }
|
||||
$env.PROMPT_INDICATOR_VI_NORMAL = { "〉" }
|
||||
$env.PROMPT_MULTILINE_INDICATOR = { "::: " }
|
||||
Reference in New Issue
Block a user