diff --git a/nushell/modules/pj_prompt.nu b/nushell/modules/pj_prompt.nu index 6b5eaa4..dbfd692 100644 --- a/nushell/modules/pj_prompt.nu +++ b/nushell/modules/pj_prompt.nu @@ -1,14 +1,11 @@ def _pj_detect_os_key [] { - let host_name = (((sys host | get name?) | default ($nu.os-info.name? | default "")) | into string) - if ($host_name == "Darwin") { + 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 =~ "Windows") { + if ($host_name | str contains "windows") { return "Windows" } - if ($host_name != "Linux") { - return "Unknown" - } let os_release = if ("/etc/os-release" | path exists) { "/etc/os-release" @@ -56,7 +53,11 @@ def _pj_detect_os_key [] { _ => "Linux" } } else { - "Linux" + if ($host_name | str contains "linux") { + "Linux" + } else { + "Unknown" + } } } @@ -116,6 +117,50 @@ def _pj_os_symbol [] { _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) + } +} + +def _pj_palette [] { + ($env.PJ_PROMPT_PALETTE? | default (_pj_palette_default)) +} + +def _pj_runtime_default [] { + let user = ($env.USER? | default ($env.USERNAME? | default "user")) + let host = (sys host | get hostname? | default "") + { + user: $user + is_root: ($user == "root") + host: $host + in_ssh: (($env.SSH_CONNECTION? | default "") != "" or ($env.SSH_TTY? | default "") != "") + } +} + +def _pj_runtime [] { + (_pj_runtime_default) +} + def _pj_first_version [text: string] { let parsed = ($text | parse -r '(?\d+(?:\.\d+)+)') if (($parsed | length) > 0) { @@ -144,6 +189,32 @@ def _pj_cmd_duration_ms [] { } } +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_truncate_pwd [pwd: string, length: int = 4] { let home = ($env.HOME? | default "") let normalized_pwd = (($pwd | into string) | str replace -a "\\" "/") @@ -258,13 +329,6 @@ def _pj_git_info [] { if ($m == null) { 0 } else { (($m | get b) | into int) } } - mut parts = [] - if ($changed > 0) { $parts = ($parts | append $"!($changed)") } - if ($untracked > 0) { $parts = ($parts | append $"?($untracked)") } - if ($stashed > 0) { $parts = ($parts | append $"\$($stashed)") } - if ($ahead > 0) { $parts = ($parts | append $"⇡($ahead)") } - if ($behind > 0) { $parts = ($parts | append $"⇣($behind)") } - { branch: $branch_text changed: $changed @@ -275,28 +339,25 @@ def _pj_git_info [] { } } -def _pj_git_branch_module [] { - let c_git = (ansi '#4ca47b') - let c_alert = (ansi '#c2295b') - let reset = (ansi reset) +def _pj_git_branch_module [p: record] { let git = (_pj_git_info) let branch = ($git.branch | default "") mut status_parts = [] if (($git.changed | default 0) > 0) { - $status_parts = ($status_parts | append $"($c_alert)!($git.changed)($reset)") + $status_parts = ($status_parts | append $"($p.c_alert)!($git.changed)($p.c_reset)") } if (($git.untracked | default 0) > 0) { - $status_parts = ($status_parts | append $"($c_alert)?($git.untracked)($reset)") + $status_parts = ($status_parts | append $"($p.c_alert)?($git.untracked)($p.c_reset)") } if (($git.stashed | default 0) > 0) { - $status_parts = ($status_parts | append $"($c_alert)\$($git.stashed)($reset)") + $status_parts = ($status_parts | append $"($p.c_alert)\$($git.stashed)($p.c_reset)") } if (($git.ahead | default 0) > 0) { - $status_parts = ($status_parts | append $"($c_git)⇡($git.ahead)($reset)") + $status_parts = ($status_parts | append $"($p.c_git)⇡($git.ahead)($p.c_reset)") } if (($git.behind | default 0) > 0) { - $status_parts = ($status_parts | append $"($c_git)⇣($git.behind)($reset)") + $status_parts = ($status_parts | append $"($p.c_git)⇣($git.behind)($p.c_reset)") } let git_status = if (($status_parts | length) > 0) { @@ -308,7 +369,7 @@ def _pj_git_branch_module [] { if ($branch == "") { "" } else { - $"($c_git)on  ($branch)($git_status) ($reset)" + $"($p.c_git)on  ($branch)($git_status) ($p.c_reset)" } } @@ -428,122 +489,107 @@ def _pj_lang_segments [] { $out } -def _pj_shell_module [] { - let reset = (ansi reset) - $"(ansi cyan_bold) nu ($reset)" +def _pj_shell_module [p: record] { + $"($p.c_shell) nu ($p.c_reset)" } -def _pj_time_module [] { - let c_time = (ansi '#a6356f') - let reset = (ansi reset) +def _pj_time_module [p: record] { let now = (date now | format date "%R") - $"($c_time)  ($now) ($reset)" + $"($p.c_time)  ($now) ($p.c_reset)" } -def _pj_duration_module [] { - let c_duration = (ansi '#a6356f') - let reset = (ansi reset) +def _pj_duration_module [p: record] { let ms = (_pj_cmd_duration_ms) - let duration_text = if ($ms >= 1000) { - let s = (($ms / 1000) | into int) - $"($s)s" - } else { - $"($ms)ms" - } - $"($c_duration) 󱫑 ($duration_text) ($reset)" + let duration_text = (_pj_format_duration $ms) + $"($p.c_duration) 󱫑 ($duration_text) ($p.c_reset)" } def _pj_left_prompt [] { - let c_os = (ansi '#6b6b6b') - let c_user = (ansi '#4ca47b') - let c_root = (ansi '#c2295b') - let c_host = (ansi '#4ca47b') - let c_ssh = (ansi '#d65d0e') - let c_dir = (ansi '#9d8fbe') - let c_c = (ansi '#306898') - let c_cpp = (ansi '#306898') - let c_rust = (ansi '#000000') - let c_zig = (ansi '#306898') - let c_python = (ansi '#4685b7') - let reset = (ansi reset) + let p = (_pj_palette) + let runtime = (_pj_runtime) - let user = ($env.USER? | default ($env.USERNAME? | default "user")) - let is_root = ($user == "root") - let user_color = if $is_root { $c_root } else { $c_user } + let user_color = if ($runtime.is_root | default false) { $p.c_root } else { $p.c_user } - let host = (sys host | get hostname? | default "") - let in_ssh = (($env.SSH_CONNECTION? | default "") != "" or ($env.SSH_TTY? | default "") != "") - let host_part = if $in_ssh { - $"($c_host)@($host)($reset)($c_ssh)  󰬚󰬚󰬏 ($reset)" + let host_part = if ($runtime.in_ssh | default false) { + $"($p.c_host)@($runtime.host)($p.c_reset)($p.c_ssh)  󰬚󰬚󰬏 ($p.c_reset)" } else { "" } - let shell_part = (_pj_shell_module) + let shell_part = (_pj_shell_module $p) let dir = (_pj_truncate_pwd $env.PWD 4) - let git_part = (_pj_git_branch_module) + let git_part = (_pj_git_branch_module $p) let langs = (_pj_lang_segments) let lang_parts = ($langs | each {|seg| if ($seg | str starts-with "") { - $"($c_python)via ($seg) ($reset)" + $"($p.c_python)via ($seg) ($p.c_reset)" } else if ($seg | str starts-with "󱘗") { - $"($c_rust)via ($seg) ($reset)" + $"($p.c_rust)via ($seg) ($p.c_reset)" } else if ($seg | str starts-with "") { - $"($c_cpp)via ($seg) ($reset)" + $"($p.c_cpp)via ($seg) ($p.c_reset)" } else if ($seg | str starts-with "") { - $"($c_c)via ($seg) ($reset)" + $"($p.c_c)via ($seg) ($p.c_reset)" } else if ($seg | str starts-with "") { - $"($c_zig)via ($seg) ($reset)" + $"($p.c_zig)via ($seg) ($p.c_reset)" } else { $seg } }) - let time_part = (_pj_time_module) - let duration_part = (_pj_duration_module) + let time_part = (_pj_time_module $p) + let duration_part = (_pj_duration_module $p) mut out = "" - $out = $"($out)($c_os)(_pj_os_symbol)($reset)" - $out = $"($out)($user_color)($user)($reset)" + $out = $"($out)($p.c_os)(_pj_os_symbol)($p.c_reset)" + $out = $"($out)($user_color)($runtime.user)($p.c_reset)" if ($host_part != "") { $out = $"($out)($host_part)" } $out = $"($out)($shell_part)" - $out = $"($out)($c_dir) ($dir) ($reset)" + $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 = $"($out)($time_part)($duration_part)" + $out = $"\n($out)($time_part)($duration_part)\n" $out } def _pj_prompt_indicator [] { + let p = (_pj_palette) if (($env.LAST_EXIT_CODE? | default 0) == 0) { - $"(ansi green_bold)❯(ansi reset) " + $"($p.c_indicator_ok)❯($p.c_reset) " } else { - $"(ansi red_bold)❯(ansi reset) " + $"($p.c_indicator_err)❯($p.c_reset) " } } -def _pj_prompt_content [] { - $"(_pj_left_prompt)\n(_pj_prompt_indicator)" +def _pj_right_prompt [] { + let p = (_pj_palette) + if (($env.LAST_EXIT_CODE? | default 0) != 0) { + $"($p.c_right_error)Exit code: ($env.LAST_EXIT_CODE)($p.c_reset)" + } else { + $"" + } } export-env { load-env { + PJ_PROMPT_PALETTE: (_pj_palette_default) PJ_OS_KEY: (_pj_detect_os_key) - PROMPT_MULTILINE_INDICATOR: "" - PROMPT_INDICATOR: "" + PROMPT_MULTILINE_INDICATOR: ":" + PROMPT_INDICATOR: {|| + _pj_prompt_indicator + } PROMPT_INDICATOR_VI_INSERT: "" PROMPT_INDICATOR_VI_NORMAL: "" PROMPT_COMMAND: {|| - (_pj_prompt_content) + _pj_left_prompt } PROMPT_COMMAND_RIGHT: {|| - "" + _pj_right_prompt } config: ($env.config? | default {} | merge { - render_right_prompt_on_last_line: false + render_right_prompt_on_last_line: true }) } }