695 lines
21 KiB
Nu
695 lines
21 KiB
Nu
def _pj_detect_os_key [] {
|
||
let host_name = (((sys host | get name?) | default ($nu.os-info.name? | default "")) | into string | str downcase)
|
||
if ($host_name | str contains "darwin") {
|
||
return "Macos"
|
||
}
|
||
if ($host_name | str contains "windows") {
|
||
return "Windows"
|
||
}
|
||
|
||
let os_release = if ("/etc/os-release" | path exists) {
|
||
"/etc/os-release"
|
||
} else if ("/usr/lib/os-release" | path exists) {
|
||
"/usr/lib/os-release"
|
||
} else {
|
||
""
|
||
}
|
||
|
||
if ($os_release != "") {
|
||
let id_line = (open $os_release | lines | where {|l| $l | str starts-with "ID=" } | get 0?)
|
||
let id = if ($id_line == null) { "" } else { (($id_line | str replace "ID=" "") | str trim -c '"') }
|
||
match ($id | str downcase) {
|
||
"alpine" => "Alpine"
|
||
"alma" => "AlmaLinux"
|
||
"almalinux" => "AlmaLinux"
|
||
"amzn" => "Amazon"
|
||
"arch" => "Arch"
|
||
"artix" => "Artix"
|
||
"centos" => "CentOS"
|
||
"debian" => "Debian"
|
||
"endeavouros" => "EndeavourOS"
|
||
"fedora" => "Fedora"
|
||
"garuda" => "Garuda"
|
||
"gentoo" => "Gentoo"
|
||
"kali" => "Kali"
|
||
"linuxmint" => "Mint"
|
||
"manjaro" => "Manjaro"
|
||
"mariner" => "Mariner"
|
||
"nixos" => "NixOS"
|
||
"nobara" => "Nobara"
|
||
"opensuse" => "openSUSE"
|
||
"opensuse-leap" => "openSUSE"
|
||
"opensuse-tumbleweed" => "openSUSE"
|
||
"ol" => "OracleLinux"
|
||
"pop" => "Pop"
|
||
"raspbian" => "Raspbian"
|
||
"rhel" => "RedHatEnterprise"
|
||
"rocky" => "RockyLinux"
|
||
"solus" => "Solus"
|
||
"sles" => "SUSE"
|
||
"opensuse-slowroll" => "openSUSE"
|
||
"ubuntu" => "Ubuntu"
|
||
"void" => "Void"
|
||
_ => "Linux"
|
||
}
|
||
} else {
|
||
if ($host_name | str contains "linux") {
|
||
"Linux"
|
||
} else {
|
||
"Unknown"
|
||
}
|
||
}
|
||
}
|
||
|
||
def _pj_os_symbol_from_key [key: string] {
|
||
match $key {
|
||
"Alpaquita" => " "
|
||
"Alpine" => " "
|
||
"AlmaLinux" => " "
|
||
"Amazon" => " "
|
||
"Android" => " "
|
||
"Arch" => " "
|
||
"Artix" => " "
|
||
"CachyOS" => " "
|
||
"CentOS" => " "
|
||
"Debian" => " "
|
||
"DragonFly" => " "
|
||
"Emscripten" => " "
|
||
"EndeavourOS" => " "
|
||
"Fedora" => " "
|
||
"FreeBSD" => " "
|
||
"Garuda" => " "
|
||
"Gentoo" => " "
|
||
"HardenedBSD" => " "
|
||
"Illumos" => " "
|
||
"Kali" => " "
|
||
"Linux" => " "
|
||
"Mabox" => " "
|
||
"Macos" => " "
|
||
"Manjaro" => " "
|
||
"Mariner" => " "
|
||
"MidnightBSD" => " "
|
||
"Mint" => " "
|
||
"NetBSD" => " "
|
||
"NixOS" => " "
|
||
"Nobara" => " "
|
||
"OpenBSD" => " "
|
||
"openSUSE" => " "
|
||
"OracleLinux" => " "
|
||
"Pop" => " "
|
||
"Raspbian" => " "
|
||
"Redhat" => " "
|
||
"RedHatEnterprise" => " "
|
||
"RockyLinux" => " "
|
||
"Redox" => " "
|
||
"Solus" => " "
|
||
"SUSE" => " "
|
||
"Ubuntu" => " "
|
||
"Unknown" => " "
|
||
"Void" => " "
|
||
"Windows" => " "
|
||
_ => " "
|
||
}
|
||
}
|
||
|
||
def _pj_os_symbol [] {
|
||
let key = ($env.PJ_OS_KEY? | default (_pj_detect_os_key))
|
||
_pj_os_symbol_from_key $key
|
||
}
|
||
|
||
def _pj_palette_default [] {
|
||
{
|
||
c_reset: (ansi reset)
|
||
c_os: (ansi '#6b6b6b')
|
||
c_user: (ansi '#4ca47b')
|
||
c_root: (ansi '#c2295b')
|
||
c_host: (ansi '#4ca47b')
|
||
c_ssh: (ansi '#d65d0e')
|
||
c_dir: (ansi '#9d8fbe')
|
||
c_c: (ansi '#306898')
|
||
c_cpp: (ansi '#306898')
|
||
c_rust: (ansi '#000000')
|
||
c_zig: (ansi '#306898')
|
||
c_python: (ansi '#4685b7')
|
||
c_git: (ansi '#4ca47b')
|
||
c_alert: (ansi '#c2295b')
|
||
c_time: (ansi '#a6356f')
|
||
c_duration: (ansi '#a6356f')
|
||
c_shell: (ansi cyan_bold)
|
||
c_indicator_ok: (ansi green_bold)
|
||
c_indicator_err: (ansi red_bold)
|
||
c_right_error: (ansi red_bold)
|
||
}
|
||
}
|
||
|
||
# Disabled along with the language-version probing. See the commented block
|
||
# near `_pj_lang_segments` to restore.
|
||
#
|
||
# def _pj_first_version [text: string] {
|
||
# let parsed = ($text | parse -r '(?<ver>\d+(?:\.\d+)+)')
|
||
# if (($parsed | length) > 0) {
|
||
# ($parsed | get ver.0)
|
||
# } else {
|
||
# ""
|
||
# }
|
||
# }
|
||
|
||
def _pj_cmd_duration_ms [] {
|
||
let raw = ($env.CMD_DURATION_MS? | default 0)
|
||
let kind = ($raw | describe)
|
||
if ($kind == "int") {
|
||
return $raw
|
||
}
|
||
if ($kind == "duration") {
|
||
return (($raw | into int) / 1_000_000)
|
||
}
|
||
|
||
let s = ($raw | into string | str trim)
|
||
let parsed = ($s | parse -r '^(?<n>\d+)')
|
||
if (($parsed | length) > 0) {
|
||
(($parsed | get n.0) | into int)
|
||
} else {
|
||
0
|
||
}
|
||
}
|
||
|
||
def _pj_format_duration [ms: int] {
|
||
if ($ms < 1000) {
|
||
return $"($ms)ms"
|
||
}
|
||
|
||
let ms_part = ($ms mod 1000)
|
||
if ($ms < 60_000) {
|
||
let s = ($ms // 1000)
|
||
return $"($s)s ($ms_part)ms"
|
||
}
|
||
|
||
if ($ms < 3_600_000) {
|
||
let total_s = ($ms // 1000)
|
||
let s = ($total_s mod 60)
|
||
let m = ($total_s // 60)
|
||
return $"($m)m ($s)s ($ms_part)ms"
|
||
}
|
||
|
||
let total_s = ($ms // 1000)
|
||
let s = ($total_s mod 60)
|
||
let total_m = ($total_s // 60)
|
||
let m = ($total_m mod 60)
|
||
let h = ($total_m // 60)
|
||
$"($h)h ($m)m ($s)s ($ms_part)ms"
|
||
}
|
||
|
||
def _pj_is_path_within [path: string, base: string] {
|
||
if ($base == "") {
|
||
return false
|
||
}
|
||
if ($path == $base) {
|
||
return true
|
||
}
|
||
($path | str starts-with $"($base)/")
|
||
}
|
||
|
||
# Single `git rev-parse` call: returns whether we are inside a work tree and the
|
||
# normalized repo root (empty string when not in a repo).
|
||
def _pj_git_repo_info [] {
|
||
if (which ^git | is-empty) {
|
||
return { inside: false, root: "" }
|
||
}
|
||
|
||
let res = (^git rev-parse --is-inside-work-tree --show-toplevel | complete)
|
||
if ($res.exit_code != 0) {
|
||
return { inside: false, root: "" }
|
||
}
|
||
|
||
let parts = ($res.stdout | lines)
|
||
let inside_raw = ($parts | get 0? | default "")
|
||
let root_raw = ($parts | get 1? | default "")
|
||
let root_norm = if ($root_raw == "") {
|
||
""
|
||
} else {
|
||
let raw = (($root_raw | str trim) | str replace -a "\\" "/")
|
||
if ($raw == "/") { "/" } else { ($raw | str trim -r -c "/") }
|
||
}
|
||
|
||
{ inside: (($inside_raw | str trim) == "true"), root: $root_norm }
|
||
}
|
||
|
||
def _pj_truncate_pwd [pwd: string, length: int = 4, repo: record = {inside: false, root: ""}] {
|
||
let home = (($nu.home-dir? | default ($nu.home-path? | default ($env.HOME? | default ""))) | into string)
|
||
let normalized_pwd_raw = (($pwd | into string) | str replace -a "\\" "/")
|
||
let normalized_home_raw = (($home | into string) | str replace -a "\\" "/")
|
||
|
||
let normalized_pwd = if ($normalized_pwd_raw == "/") {
|
||
"/"
|
||
} else {
|
||
($normalized_pwd_raw | str trim -r -c "/")
|
||
}
|
||
|
||
let normalized_home = if ($normalized_home_raw == "/") {
|
||
"/"
|
||
} else {
|
||
($normalized_home_raw | str trim -r -c "/")
|
||
}
|
||
|
||
let in_home = if ($normalized_home == "") {
|
||
false
|
||
} else {
|
||
(_pj_is_path_within $normalized_pwd $normalized_home)
|
||
}
|
||
|
||
let repo_root = $repo.root
|
||
let in_repo = ($repo.inside and (_pj_is_path_within $normalized_pwd $repo_root))
|
||
|
||
if $in_repo {
|
||
let repo_name = ($repo_root | path basename)
|
||
let rel = if ($normalized_pwd == $repo_root) {
|
||
""
|
||
} else {
|
||
($normalized_pwd | str substring (($repo_root | str length) + 1)..)
|
||
}
|
||
|
||
let rel_parts = if ($rel == "") {
|
||
[]
|
||
} else {
|
||
($rel | split row "/" | where {|it| $it != "" })
|
||
}
|
||
|
||
let keep_rel_count = if ($length <= 1) { 0 } else { $length - 1 }
|
||
let shown_rel_parts = if (($rel_parts | length) <= $keep_rel_count) {
|
||
$rel_parts
|
||
} else {
|
||
($rel_parts | last $keep_rel_count)
|
||
}
|
||
|
||
if (($shown_rel_parts | length) == 0) {
|
||
return $"…/($repo_name)"
|
||
} else {
|
||
return $"…/($repo_name)/($shown_rel_parts | str join '/')"
|
||
}
|
||
}
|
||
|
||
let shown = if $in_home {
|
||
let rest = ($normalized_pwd | str substring ($normalized_home | str length)..)
|
||
if ($rest == "") { "~" } else { $"~($rest)" }
|
||
} else {
|
||
$normalized_pwd
|
||
}
|
||
|
||
if ($shown == "~") {
|
||
return "~"
|
||
}
|
||
|
||
let parts = if ($shown | str starts-with "~/") {
|
||
($shown | str substring 2.. | split row "/" | where {|it| $it != "" })
|
||
} else if ($shown | str starts-with "/") {
|
||
($shown | str substring 1.. | split row "/" | where {|it| $it != "" })
|
||
} else if ($shown =~ '^[A-Za-z]:(/|$)') {
|
||
let start = if ($shown =~ '^[A-Za-z]:/') { 3 } else { 2 }
|
||
($shown | str substring $start.. | split row "/" | where {|it| $it != "" })
|
||
} else {
|
||
($shown | split row "/" | where {|it| $it != "" })
|
||
}
|
||
|
||
let prefix = if ($shown | str starts-with "~/") {
|
||
"~/"
|
||
} else if ($shown | str starts-with "/") {
|
||
"/"
|
||
} else if ($shown =~ '^[A-Za-z]:(/|$)') {
|
||
let drive = ($shown | str substring 0..1)
|
||
$"($drive)/"
|
||
} else {
|
||
""
|
||
}
|
||
|
||
if (($parts | length) <= $length) {
|
||
if ($prefix == "") { ($parts | str join "/") } else { $"($prefix)($parts | str join '/')" }
|
||
} else {
|
||
let tail = ($parts | last $length | str join "/")
|
||
$"($prefix)…/($tail)"
|
||
}
|
||
}
|
||
|
||
def _pj_git_info [repo: record] {
|
||
let empty = {
|
||
branch: ""
|
||
changed: 0
|
||
untracked: 0
|
||
stashed: 0
|
||
ahead: 0
|
||
behind: 0
|
||
}
|
||
# `repo.inside` can only be true when git exists, so no separate `which`
|
||
# check is needed here.
|
||
if (not $repo.inside) {
|
||
return $empty
|
||
}
|
||
|
||
# One `git status` call carries: branch name, ahead/behind, stash count,
|
||
# and the changed/untracked entries. Previously this was 4 separate git
|
||
# invocations (rev-parse, branch --show-current, status, stash list).
|
||
let status = (^git status --porcelain=2 --branch --show-stash | complete)
|
||
if ($status.exit_code != 0) {
|
||
return $empty
|
||
}
|
||
|
||
let lines = ($status.stdout | lines)
|
||
let changed = ($lines | where {|l| ($l | str starts-with "1 ") or ($l | str starts-with "2 ") or ($l | str starts-with "u ") } | length)
|
||
let untracked = ($lines | where {|l| $l | str starts-with "? " } | length)
|
||
|
||
let stashed = ($lines | where {|l| $l | str starts-with "# stash " } | get 0? | default "")
|
||
let stashed_n = if ($stashed == "") {
|
||
0
|
||
} else {
|
||
(($stashed | parse -r '# stash (?<n>\d+)' | get 0? | default {n: "0"} | get n) | into int)
|
||
}
|
||
|
||
let head_line = ($lines | where {|l| $l | str starts-with "# branch.head " } | get 0? | default "")
|
||
let head_name = if ($head_line == "") {
|
||
""
|
||
} else {
|
||
($head_line | str replace "# branch.head " "" | str trim)
|
||
}
|
||
# Detached HEAD: fall back to the short oid (first 7 chars), matching the
|
||
# previous `git rev-parse --short HEAD` behaviour.
|
||
let branch_text = if ($head_name == "(detached)") {
|
||
let oid_line = ($lines | where {|l| $l | str starts-with "# branch.oid " } | get 0? | default "")
|
||
let oid = if ($oid_line == "") {
|
||
""
|
||
} else {
|
||
($oid_line | str replace "# branch.oid " "" | str trim)
|
||
}
|
||
($oid | str substring 0..7)
|
||
} else {
|
||
$head_name
|
||
}
|
||
|
||
let ab = ($lines | where {|l| $l | str starts-with "# branch.ab " } | get 0?)
|
||
let ab_match = if ($ab == null) {
|
||
null
|
||
} else {
|
||
($ab | parse -r '# branch.ab \+(?<a>\d+) -(?<b>\d+)' | get 0?)
|
||
}
|
||
let ahead = if ($ab_match == null) { 0 } else { (($ab_match | get a) | into int) }
|
||
let behind = if ($ab_match == null) { 0 } else { (($ab_match | get b) | into int) }
|
||
|
||
{
|
||
branch: $branch_text
|
||
changed: $changed
|
||
untracked: $untracked
|
||
stashed: $stashed_n
|
||
ahead: $ahead
|
||
behind: $behind
|
||
}
|
||
}
|
||
|
||
def _pj_git_branch_module [p: record, git: record] {
|
||
let branch = ($git.branch | default "")
|
||
|
||
mut status_parts = []
|
||
if (($git.changed | default 0) > 0) {
|
||
$status_parts = ($status_parts | append $"($p.c_alert)!($git.changed)($p.c_reset)")
|
||
}
|
||
if (($git.untracked | default 0) > 0) {
|
||
$status_parts = ($status_parts | append $"($p.c_alert)?($git.untracked)($p.c_reset)")
|
||
}
|
||
if (($git.stashed | default 0) > 0) {
|
||
$status_parts = ($status_parts | append $"($p.c_alert)\$($git.stashed)($p.c_reset)")
|
||
}
|
||
if (($git.ahead | default 0) > 0) {
|
||
$status_parts = ($status_parts | append $"($p.c_alert)⇡($git.ahead)($p.c_reset)")
|
||
}
|
||
if (($git.behind | default 0) > 0) {
|
||
$status_parts = ($status_parts | append $"($p.c_alert)⇣($git.behind)($p.c_reset)")
|
||
}
|
||
|
||
let git_status = if (($status_parts | length) > 0) {
|
||
$" (($status_parts | str join ' '))"
|
||
} else {
|
||
""
|
||
}
|
||
|
||
if ($branch == "") {
|
||
""
|
||
} else {
|
||
$"($p.c_git)on ($branch)($git_status) ($p.c_reset)"
|
||
}
|
||
}
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Programming-language detection and version probing — DISABLED.
|
||
#
|
||
# These were the dominant cost in prompt rendering (up to ~660ms/frame in
|
||
# projects with source files, mostly from spawning cc/c++/python --version).
|
||
# They are commented out for now. To re-enable, uncomment the block below and
|
||
# remove (or rename) the stub `_pj_lang_segments` that returns an empty list.
|
||
#
|
||
# def _pj_has_glob [pattern: string] {
|
||
# ((glob $pattern | length) > 0)
|
||
# }
|
||
#
|
||
# def _pj_c_version [] {
|
||
# if (which ^cc | is-empty) {
|
||
# return ""
|
||
# }
|
||
# let out = (^cc --version | complete)
|
||
# _pj_first_version (($out.stdout | str trim) + " " + ($out.stderr | str trim))
|
||
# }
|
||
#
|
||
# def _pj_cpp_version [] {
|
||
# if (which ^'c++' | is-empty) {
|
||
# return ""
|
||
# }
|
||
# let out = (^'c++' --version | complete)
|
||
# _pj_first_version (($out.stdout | str trim) + " " + ($out.stderr | str trim))
|
||
# }
|
||
#
|
||
# def _pj_rust_version [] {
|
||
# if (which ^rustc | is-empty) {
|
||
# return ""
|
||
# }
|
||
# let out = (^rustc --version | complete)
|
||
# _pj_first_version (($out.stdout | str trim) + " " + ($out.stderr | str trim))
|
||
# }
|
||
#
|
||
# def _pj_zig_version [] {
|
||
# if (which ^zig | is-empty) {
|
||
# return ""
|
||
# }
|
||
# let out = (^zig version | complete)
|
||
# _pj_first_version (($out.stdout | str trim) + " " + ($out.stderr | str trim))
|
||
# }
|
||
#
|
||
# def _pj_python_version [] {
|
||
# if (which ^python | is-not-empty) {
|
||
# let out = (^python --version | complete)
|
||
# return (_pj_first_version (($out.stdout | str trim) + " " + ($out.stderr | str trim)))
|
||
# }
|
||
#
|
||
# if (which ^python3 | is-not-empty) {
|
||
# let out = (^python3 --version | complete)
|
||
# return (_pj_first_version (($out.stdout | str trim) + " " + ($out.stderr | str trim)))
|
||
# }
|
||
#
|
||
# ""
|
||
# }
|
||
#
|
||
# def _pj_python_venv [] {
|
||
# let venv = ($env.VIRTUAL_ENV? | default "")
|
||
# if ($venv != "") {
|
||
# return ($venv | path basename)
|
||
# }
|
||
# ($env.CONDA_DEFAULT_ENV? | default "")
|
||
# }
|
||
#
|
||
# def _pj_lang_segments [] {
|
||
# # One glob sweep replaces 11 separate glob calls. The resulting set of
|
||
# # lowercase extensions is checked per-language below. glob is
|
||
# # case-insensitive on Windows, so *.CPP is matched by "cpp" too.
|
||
# let exts = (glob *.{c,h,cpp,cc,cxx,hpp,hh,hxx,rs,zig,py}
|
||
# | each {|f| $f | path parse | get extension | str downcase }
|
||
# | uniq)
|
||
#
|
||
# let has_c = ("c" in $exts or "h" in $exts)
|
||
# let has_cpp = (["cpp" "cc" "cxx" "hpp" "hh" "hxx"] | any {|e| $e in $exts })
|
||
# let has_rust = (("Cargo.toml" | path exists) or ("rs" in $exts))
|
||
# let has_zig = (("build.zig" | path exists) or ("zig" in $exts))
|
||
# let has_python = (("pyproject.toml" | path exists) or ("requirements.txt" | path exists) or (".python-version" | path exists) or ("py" in $exts))
|
||
#
|
||
# mut out = []
|
||
# if $has_c {
|
||
# let v = (_pj_c_version)
|
||
# if ($v != "") {
|
||
# $out = ($out | append $" v($v)")
|
||
# } else {
|
||
# $out = ($out | append "")
|
||
# }
|
||
# }
|
||
#
|
||
# if $has_cpp {
|
||
# let v = (_pj_cpp_version)
|
||
# if ($v != "") {
|
||
# $out = ($out | append $" v($v)")
|
||
# } else {
|
||
# $out = ($out | append "")
|
||
# }
|
||
# }
|
||
#
|
||
# if $has_rust {
|
||
# let v = (_pj_rust_version)
|
||
# if ($v != "") {
|
||
# $out = ($out | append $" v($v)")
|
||
# } else {
|
||
# $out = ($out | append "")
|
||
# }
|
||
# }
|
||
#
|
||
# if $has_zig {
|
||
# let v = (_pj_zig_version)
|
||
# if ($v != "") {
|
||
# $out = ($out | append $" v($v)")
|
||
# } else {
|
||
# $out = ($out | append "")
|
||
# }
|
||
# }
|
||
#
|
||
# if $has_python {
|
||
# let pyver = (_pj_python_version)
|
||
# let venv = (_pj_python_venv)
|
||
# let py_base = if ($pyver != "") { $" v($pyver)" } else { "" }
|
||
# if ($venv != "") {
|
||
# $out = ($out | append $"($py_base) \(($venv)\)")
|
||
# } else {
|
||
# $out = ($out | append $py_base)
|
||
# }
|
||
# }
|
||
#
|
||
# $out
|
||
# }
|
||
# ---------------------------------------------------------------------------
|
||
|
||
# Stub: language segments are disabled. Returns an empty list so the prompt
|
||
# simply omits the "via <lang>" parts. See the commented block above to
|
||
# restore full language detection.
|
||
def _pj_lang_segments [] {
|
||
[]
|
||
}
|
||
|
||
|
||
def _pj_prompt_static_base [] {
|
||
let user = (try { whoami } catch { "" } | into string | str trim)
|
||
let effective_user = if ($user != "") {
|
||
$user
|
||
} else {
|
||
($env.USER? | default ($env.USERNAME? | default "user"))
|
||
}
|
||
|
||
let host = (sys host | get hostname? | default "")
|
||
let in_ssh = (($env.SSH_CONNECTION? | default "") != "" or ($env.SSH_TTY? | default "") != "")
|
||
# let prompt_newline = if (($nu.os-info.name | str downcase) == "windows") { "\n\r" } else { "\n\r" }
|
||
let prompt_newline = "\n\r"
|
||
|
||
{
|
||
os_symbol: (_pj_os_symbol)
|
||
effective_user: $effective_user
|
||
host: $host
|
||
in_ssh: $in_ssh
|
||
shell_name: "nu"
|
||
prompt_newline: $prompt_newline
|
||
}
|
||
}
|
||
|
||
def _pj_left_prompt [] {
|
||
let p = ($env.PJ_PROMPT_PALETTE? | default (_pj_palette_default))
|
||
let static = ($env.PJ_LEFT_PROMPT_STATIC_PART? | default (_pj_prompt_static_base))
|
||
|
||
let user_color = if ($static.effective_user == "root") { $p.c_root } else { $p.c_user }
|
||
|
||
let host_part = if $static.in_ssh {
|
||
$"($p.c_host)@($static.host)($p.c_reset)($p.c_ssh) ($p.c_reset)"
|
||
} else {
|
||
""
|
||
}
|
||
|
||
let shell_part = $"($p.c_shell) ($static.shell_name) ($p.c_reset)"
|
||
let repo = (_pj_git_repo_info)
|
||
let dir = (_pj_truncate_pwd $env.PWD 4 $repo)
|
||
let git = (_pj_git_info $repo)
|
||
let git_part = (_pj_git_branch_module $p $git)
|
||
|
||
let langs = (_pj_lang_segments)
|
||
let lang_parts = ($langs | each {|seg|
|
||
if ($seg | str starts-with "") {
|
||
$"($p.c_python)via ($seg) ($p.c_reset)"
|
||
} else if ($seg | str starts-with "") {
|
||
$"($p.c_rust)via ($seg) ($p.c_reset)"
|
||
} else if ($seg | str starts-with "") {
|
||
$"($p.c_cpp)via ($seg) ($p.c_reset)"
|
||
} else if ($seg | str starts-with "") {
|
||
$"($p.c_c)via ($seg) ($p.c_reset)"
|
||
} else if ($seg | str starts-with "") {
|
||
$"($p.c_zig)via ($seg) ($p.c_reset)"
|
||
} else {
|
||
$seg
|
||
}
|
||
})
|
||
|
||
let now = (date now | format date "%R")
|
||
let time_part = $"($p.c_time) ($now) ($p.c_reset)"
|
||
let duration_text = (_pj_format_duration (_pj_cmd_duration_ms))
|
||
let duration_part = $"($p.c_duration) ($duration_text) ($p.c_reset)"
|
||
|
||
mut out = ""
|
||
$out = $"($out)($p.c_os)($static.os_symbol)($p.c_reset)"
|
||
$out = $"($out)($user_color)($static.effective_user)($p.c_reset)"
|
||
if ($host_part != "") { $out = $"($out)($host_part)" }
|
||
$out = $"($out)($shell_part)"
|
||
$out = $"($out)($p.c_dir) ($dir) ($p.c_reset)"
|
||
if ($git_part != "") { $out = $"($out)($git_part)" }
|
||
for m in $lang_parts {
|
||
$out = $"($out)($m)"
|
||
}
|
||
$out = $"($static.prompt_newline)($out)($time_part)($duration_part)($static.prompt_newline)"
|
||
$out
|
||
}
|
||
|
||
def _pj_prompt_indicator [] {
|
||
let p = ($env.PJ_PROMPT_PALETTE? | default (_pj_palette_default))
|
||
if (($env.LAST_EXIT_CODE? | default 0) == 0) {
|
||
$"($p.c_indicator_ok)❯($p.c_reset) "
|
||
} else {
|
||
$"($p.c_indicator_err)❯($p.c_reset) "
|
||
}
|
||
}
|
||
|
||
export-env {
|
||
load-env {
|
||
PJ_PROMPT_PALETTE: (_pj_palette_default)
|
||
PJ_OS_KEY: (_pj_detect_os_key)
|
||
PJ_LEFT_PROMPT_STATIC_PART: (_pj_prompt_static_base)
|
||
PROMPT_MULTILINE_INDICATOR: ":"
|
||
PROMPT_INDICATOR: {||
|
||
_pj_prompt_indicator
|
||
}
|
||
PROMPT_INDICATOR_VI_INSERT: {||
|
||
_pj_prompt_indicator
|
||
}
|
||
PROMPT_INDICATOR_VI_NORMAL: {||
|
||
_pj_prompt_indicator
|
||
}
|
||
PROMPT_COMMAND: {||
|
||
_pj_left_prompt
|
||
}
|
||
PROMPT_COMMAND_RIGHT: {||
|
||
let p = ($env.PJ_PROMPT_PALETTE? | default (_pj_palette_default))
|
||
if (($env.LAST_EXIT_CODE? | default 0) != 0) {
|
||
$"($p.c_right_error)Exit code: ($env.LAST_EXIT_CODE)($p.c_reset)"
|
||
} else {
|
||
""
|
||
}
|
||
}
|
||
config: ($env.config? | default {} | merge {
|
||
render_right_prompt_on_last_line: true
|
||
})
|
||
}
|
||
}
|