diff --git a/nushell/modules/pj_prompt.nu b/nushell/modules/pj_prompt.nu index 44972f5..57cf3d6 100644 --- a/nushell/modules/pj_prompt.nu +++ b/nushell/modules/pj_prompt.nu @@ -215,12 +215,89 @@ def _pj_format_duration [ms: int] { $"($h)h ($m)m ($s)s ($ms_part)ms" } -def _pj_truncate_pwd [pwd: string, length: int = 4] { - let home = ($env.HOME? | default "") - let normalized_pwd = (($pwd | into string) | str replace -a "\\" "/") - let normalized_home = (($home | into string) | str replace -a "\\" "/") +def _pj_is_path_within [path: string, base: string] { + if ($base == "") { + return false + } + if ($path == $base) { + return true + } + ($path | str starts-with $"($base)/") +} - let shown = if ($normalized_home != "" and ($normalized_pwd | str starts-with $normalized_home)) { +def _pj_git_root_normalized [] { + if (which ^git | is-empty) { + return "" + } + + let top = (^git rev-parse --show-toplevel | complete) + if ($top.exit_code != 0) { + return "" + } + + let raw = (($top.stdout | str trim) | str replace -a "\\" "/") + if ($raw == "/") { + "/" + } else { + ($raw | str trim -r -c "/") + } +} + +def _pj_truncate_pwd [pwd: string, length: int = 4] { + 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 = (_pj_git_root_normalized) + let in_repo = (_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 { @@ -235,8 +312,9 @@ def _pj_truncate_pwd [pwd: string, length: int = 4] { ($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]:/') { - ($shown | str substring 3.. | 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 != "" }) } @@ -245,7 +323,7 @@ def _pj_truncate_pwd [pwd: string, length: int = 4] { "~/" } else if ($shown | str starts-with "/") { "/" - } else if ($shown =~ '^[A-Za-z]:/') { + } else if ($shown =~ '^[A-Za-z]:(/|$)') { let drive = ($shown | str substring 0..1) $"($drive)/" } else { diff --git a/nushell/modules/pj_zoxide.nu b/nushell/modules/pj_zoxide.nu index 7673acb..db24da7 100644 --- a/nushell/modules/pj_zoxide.nu +++ b/nushell/modules/pj_zoxide.nu @@ -59,6 +59,23 @@ def --env --wrapped __zoxide_zi [...rest:string] { cd $'(zoxide query --interactive -- ...$rest | str trim -r -c "\n")' } +# Jump to git repository root when currently inside a repository. +def --env __zoxide_zg [] { + if (which ^git | is-empty) { + return + } + + let top = (^git rev-parse --show-toplevel | complete) + if ($top.exit_code != 0) { + return + } + + let root = ($top.stdout | str trim -r -c "\n") + if ($root != "") { + cd $root + } +} + # ============================================================================= # # Commands for zoxide. Disable these using --no-cmd. @@ -66,6 +83,7 @@ def --env --wrapped __zoxide_zi [...rest:string] { export alias z = __zoxide_z export alias zi = __zoxide_zi +export alias zg = __zoxide_zg # ============================================================================= #