Compare commits

...

2 Commits

2 changed files with 223 additions and 209 deletions
-15
View File
@@ -19,21 +19,6 @@ export alias moon = curl wttr.in/Moon
export alias quote = curl https://api.quotable.io/random | from json | get content
export alias dadjoke = curl -H "Accept: application/json" https://icanhazdadjoke.com/ | from json | get joke
# --- Git ---
export alias g = git
# --- Navigation & Shell ---
export alias c = clear
export def reload [] { exec nu }
export def edit [] { ^$env.EDITOR ($env.NU_POLYJUICE_PATH | path join 'nu_polyjuice.nu') }
# --- File system ---
export alias tree = ls **/*
# --- Network ---
export alias myip = curl -s ifconfig.me
export def ports [] { ^netstat -ano | lines | where {|row| $row | str contains 'LISTENING'} | str trim }
# --- System ---
export def df [] {
if (which ^df | is-not-empty) {
+223 -194
View File
@@ -142,14 +142,17 @@ def _pj_palette_default [] {
}
}
def _pj_first_version [text: string] {
let parsed = ($text | parse -r '(?<ver>\d+(?:\.\d+)+)')
if (($parsed | length) > 0) {
($parsed | get ver.0)
} else {
""
}
}
# 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)
@@ -206,25 +209,32 @@ def _pj_is_path_within [path: string, base: string] {
($path | str starts-with $"($base)/")
}
def _pj_git_root_normalized [] {
# 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 ""
return { inside: false, root: "" }
}
let top = (^git rev-parse --show-toplevel | complete)
if ($top.exit_code != 0) {
return ""
let res = (^git rev-parse --is-inside-work-tree --show-toplevel | complete)
if ($res.exit_code != 0) {
return { inside: false, root: "" }
}
let raw = (($top.stdout | str trim) | str replace -a "\\" "/")
if ($raw == "/") {
"/"
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 {
($raw | str trim -r -c "/")
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] {
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 "\\" "/")
@@ -247,8 +257,8 @@ def _pj_truncate_pwd [pwd: string, length: int = 4] {
(_pj_is_path_within $normalized_pwd $normalized_home)
}
let repo_root = (_pj_git_root_normalized)
let in_repo = (_pj_is_path_within $normalized_pwd $repo_root)
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)
@@ -319,87 +329,80 @@ def _pj_truncate_pwd [pwd: string, length: int = 4] {
}
}
def _pj_git_info [] {
if (which ^git | is-empty) {
return {
branch: ""
changed: 0
untracked: 0
stashed: 0
ahead: 0
behind: 0
}
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
}
let repo_check = (^git rev-parse --is-inside-work-tree | complete)
if ($repo_check.exit_code != 0 or (($repo_check.stdout | str trim) != "true")) {
return {
branch: ""
changed: 0
untracked: 0
stashed: 0
ahead: 0
behind: 0
}
}
let branch_result = (^git branch --show-current | complete)
let branch = ($branch_result.stdout | str trim)
let branch_text = if ($branch != "") {
$branch
} else {
let head_result = (^git rev-parse --short HEAD | complete)
if ($head_result.exit_code == 0) {
($head_result.stdout | str trim)
} else {
""
}
}
let status = (^git status --porcelain=2 --branch | complete)
# 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 {
branch: $branch_text
changed: 0
untracked: 0
stashed: 0
ahead: 0
behind: 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 = ((^git stash list | complete).stdout | lines | 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 ahead = if ($ab == null) {
0
let ab_match = if ($ab == null) {
null
} else {
let m = (($ab | parse -r '# branch.ab \+(?<a>\d+) -(?<b>\d+)') | get 0?)
if ($m == null) { 0 } else { (($m | get a) | into int) }
}
let behind = if ($ab == null) {
0
} else {
let m = (($ab | parse -r '# branch.ab \+(?<a>\d+) -(?<b>\d+)') | get 0?)
if ($m == null) { 0 } else { (($m | get b) | into int) }
($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
stashed: $stashed_n
ahead: $ahead
behind: $behind
}
}
def _pj_git_branch_module [p: record] {
let git = (_pj_git_info)
def _pj_git_branch_module [p: record, git: record] {
let branch = ($git.branch | default "")
mut status_parts = []
@@ -432,122 +435,146 @@ def _pj_git_branch_module [p: record] {
}
}
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 "")
}
# ---------------------------------------------------------------------------
# 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 [] {
let has_c = ((_pj_has_glob "*.c") or (_pj_has_glob "*.h"))
let has_cpp = ((_pj_has_glob "*.cpp") or (_pj_has_glob "*.cc") or (_pj_has_glob "*.cxx") or (_pj_has_glob "*.hpp") or (_pj_has_glob "*.hh") or (_pj_has_glob "*.hxx"))
let has_rust = (("Cargo.toml" | path exists) or (_pj_has_glob "*.rs"))
let has_zig = (("build.zig" | path exists) or (_pj_has_glob "*.zig"))
let has_python = (("pyproject.toml" | path exists) or ("requirements.txt" | path exists) or (".python-version" | path exists) or (_pj_has_glob "*.py"))
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
[]
}
def _pj_prompt_static_base [] {
let user = (try { whoami } catch { "" } | into string | str trim)
let effective_user = if ($user != "") {
@@ -584,8 +611,10 @@ def _pj_left_prompt [] {
}
let shell_part = $"($p.c_shell) ($static.shell_name) ($p.c_reset)"
let dir = (_pj_truncate_pwd $env.PWD 4)
let git_part = (_pj_git_branch_module $p)
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|