diff --git a/.gitignore b/.gitignore index 2c1ed47..60ba6e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .zed .vscode + +.zcode diff --git a/nushell/modules/pj_aliases.nu b/nushell/modules/pj_aliases.nu index e033543..a9afab2 100644 --- a/nushell/modules/pj_aliases.nu +++ b/nushell/modules/pj_aliases.nu @@ -16,8 +16,22 @@ export alias .......... = cd ../../../../../../../.. export alias weather = curl wttr.in 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 + +export def quote [] { + try { + curl -sf https://api.quotable.io/random | from json | get content + } catch { + print "Failed to fetch quote (network or API error)." + } +} + +export def dadjoke [] { + try { + curl -sf -H "Accept: application/json" https://icanhazdadjoke.com/ | from json | get joke + } catch { + print "Failed to fetch joke (network or API error)." + } +} # --- System --- export def df [] { diff --git a/nushell/modules/pj_brew.nu b/nushell/modules/pj_brew.nu index 20acbb1..fd074d9 100644 --- a/nushell/modules/pj_brew.nu +++ b/nushell/modules/pj_brew.nu @@ -15,10 +15,10 @@ export def --env "pj brewthu" [] { HOMEBREW_PIP_INDEX_URL: "https://pypi.tuna.tsinghua.edu.cn/simple" } } else { - hide-env HOMEBREW_API_DOMAIN - hide-env HOMEBREW_BOTTLE_DOMAIN - hide-env HOMEBREW_BREW_GIT_REMOTE - hide-env HOMEBREW_CORE_GIT_REMOTE - hide-env HOMEBREW_PIP_INDEX_URL + hide-env --ignore-errors HOMEBREW_API_DOMAIN + hide-env --ignore-errors HOMEBREW_BOTTLE_DOMAIN + hide-env --ignore-errors HOMEBREW_BREW_GIT_REMOTE + hide-env --ignore-errors HOMEBREW_CORE_GIT_REMOTE + hide-env --ignore-errors HOMEBREW_PIP_INDEX_URL } } diff --git a/nushell/modules/pj_completions.nu b/nushell/modules/pj_completions.nu index 1606c38..4177422 100644 --- a/nushell/modules/pj_completions.nu +++ b/nushell/modules/pj_completions.nu @@ -96,11 +96,7 @@ export def "pj completion" [ } let repo_url = "https://github.com/nushell/nu_scripts.git" - let cache_dir = if ('NU_POLYJUICE_PATH' in $env) { - ($env.NU_POLYJUICE_PATH | path join 'cache') - } else { - (pwd | path join 'nushell' 'cache') - } + let cache_dir = $pj_cache_dir let repo_dir = ($cache_dir | path join 'nu_scripts') let completion_dir = ($repo_dir | path join 'custom-completions') @@ -169,7 +165,7 @@ export def "pj completion" [ } export-env { - $env.config = { + $env.config = ($env.config? | default {} | merge { completions: { quick: true partial: true @@ -180,7 +176,7 @@ export-env { max_results: 100 } } - } + }) if not ($pj_completion_registry_module | path exists) { mkdir $pj_cache_dir diff --git a/nushell/modules/pj_deepseek.nu b/nushell/modules/pj_deepseek.nu index 82761c6..1101404 100644 --- a/nushell/modules/pj_deepseek.nu +++ b/nushell/modules/pj_deepseek.nu @@ -39,6 +39,11 @@ export def "pj deepseek printkey" [] { # Query DeepSeek account balance information. export def "pj deepseek" [] { + if (which ^curl | is-empty) { + print "curl is required for `pj deepseek`." + return + } + if not ($key_file | path exists) { print $"(char --unicode '274c') No DeepSeek API key found. Use `pj deepseek setkey ` to set it." return diff --git a/nushell/modules/pj_fzf.nu b/nushell/modules/pj_fzf.nu index ce2556d..f00d13c 100644 --- a/nushell/modules/pj_fzf.nu +++ b/nushell/modules/pj_fzf.nu @@ -55,31 +55,21 @@ const fzf_dir_selector = { ] } -# Update the $env.config +# Append fzf keybindings to $env.config (defensive: works even if keybindings is absent). export-env { - # Only append if not already present (check by name) - let has_history_menu = $env.config.keybindings | any {|kb| $kb.name == "fzf_history_selector"} - if not $has_history_menu { - $env.config.keybindings = $env.config.keybindings | append [ - $fzf_history_selector - ] + mut existing = ($env.config.keybindings? | default []) + + if not ($existing | any {|kb| $kb.name == "fzf_history_selector"}) { + $existing = ($existing | append [$fzf_history_selector]) + } + if not ($existing | any {|kb| $kb.name == "fzf_file_selector"}) { + $existing = ($existing | append [$fzf_file_selector]) + } + if not ($existing | any {|kb| $kb.name == "fzf_dir_selector"}) { + $existing = ($existing | append [$fzf_dir_selector]) } - # Only append if not already present (check by name) - let has_fzf_file_selector = $env.config.keybindings | any {|kb| $kb.name == "fzf_file_selector"} - if not $has_fzf_file_selector { - $env.config.keybindings = $env.config.keybindings | append [ - $fzf_file_selector - ] - } - - # Only append if not already present (check by name) - let has_fzf_dir_selector = $env.config.keybindings | any {|kb| $kb.name == "fzf_dir_selector"} - if not $has_fzf_dir_selector { - $env.config.keybindings = $env.config.keybindings | append [ - $fzf_dir_selector - ] - } + $env.config = ($env.config? | default {} | upsert keybindings $existing) } export alias cdi = cd (ls **/ | get name | str join "\n" | fzf) diff --git a/nushell/modules/pj_helix.nu b/nushell/modules/pj_helix.nu index 30a9f25..80978bd 100644 --- a/nushell/modules/pj_helix.nu +++ b/nushell/modules/pj_helix.nu @@ -2,32 +2,22 @@ export-env { $env.PJ_HELIX_CONFIG_PATH = $env.NU_POLYJUICE_PATH | path join ".." "helix" "config.toml" } -export def hx [...rest: string] { +# Shared launcher: resolves the helix binary, applies the polyjuice config, and +# prints an OS-appropriate install hint when nothing is found. +def _pj_helix_launch [...rest: string] { if (which ^helix | is-not-empty) { ^helix -c $env.PJ_HELIX_CONFIG_PATH ...$rest } else if (which ^hx | is-not-empty) { ^hx -c $env.PJ_HELIX_CONFIG_PATH ...$rest } else { print "Helix editor not found." - if ($env.OS == "Windows_NT") { + if (($nu.os-info.name? | default "" | str lowercase) == "windows") { print "You can install Helix via `winget install Helix.Helix`" } else { - print "You can install Helix from package managers." + print "You can install Helix from your package manager." } } } -export def helix [...rest: string] { - if (which ^helix | is-not-empty) { - ^helix -c $env.PJ_HELIX_CONFIG_PATH ...$rest - } else if (which ^hx | is-not-empty) { - ^hx -c $env.PJ_HELIX_CONFIG_PATH ...$rest - } else { - print "Helix editor not found." - if ($env.OS == "Windows_NT") { - print "You can install Helix via `winget install Helix.Helix`" - } else { - print "You can install Helix from package managers." - } - } -} +export def hx [...rest: string] { _pj_helix_launch ...$rest } +export def helix [...rest: string] { _pj_helix_launch ...$rest } diff --git a/nushell/modules/pj_historyhintcomplete.nu b/nushell/modules/pj_historyhintcomplete.nu index a44e859..4bb1475 100644 --- a/nushell/modules/pj_historyhintcomplete.nu +++ b/nushell/modules/pj_historyhintcomplete.nu @@ -26,17 +26,14 @@ const alt_uppercasel_history_completion = { } export-env { - let has_alt_l_history_completion = $env.config.keybindings | where name == "alt_l_history_completion" | is-not-empty - if not $has_alt_l_history_completion { - $env.config.keybindings = $env.config.keybindings | append [ - $alt_l_history_completion - ] + mut existing = ($env.config.keybindings? | default []) + + if not ($existing | where name == "alt_l_history_completion" | is-not-empty) { + $existing = ($existing | append [$alt_l_history_completion]) + } + if not ($existing | where name == "alt_uppercasel_history_completion" | is-not-empty) { + $existing = ($existing | append [$alt_uppercasel_history_completion]) } - let has_alt_uppercasel_history_completion = $env.config.keybindings | where name == "alt_uppercasel_history_completion" | is-not-empty - if not $has_alt_uppercasel_history_completion { - $env.config.keybindings = $env.config.keybindings | append [ - $alt_uppercasel_history_completion - ] - } + $env.config = ($env.config? | default {} | upsert keybindings $existing) } diff --git a/nushell/modules/pj_prompt.nu b/nushell/modules/pj_prompt.nu index 62ea9b5..59c9181 100644 --- a/nushell/modules/pj_prompt.nu +++ b/nushell/modules/pj_prompt.nu @@ -1,9 +1,9 @@ def _pj_detect_os_key [] { - let host_name = (((sys host | get name?) | default ($nu.os-info.name? | default "")) | into string | str lowercase) - if ($host_name | str contains "darwin") { + let os_name = ($nu.os-info.name? | default "" | into string | str lowercase) + if ($os_name | str contains "darwin") { return "Macos" } - if ($host_name | str contains "windows") { + if ($os_name | str contains "windows") { return "Windows" } @@ -53,7 +53,7 @@ def _pj_detect_os_key [] { _ => "Linux" } } else { - if ($host_name | str contains "linux") { + if ($os_name | str contains "linux") { "Linux" } else { "Unknown" @@ -211,8 +211,8 @@ def _pj_is_path_within [path: string, base: string] { # 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) { +def _pj_git_repo_info [has_git: bool] { + if not $has_git { return { inside: false, root: "" } } @@ -378,7 +378,7 @@ def _pj_git_info [repo: record] { } else { ($oid_line | str replace "# branch.oid " "" | str trim) } - ($oid | str substring 0..7) + ($oid | str substring 0..<7) } else { $head_name } @@ -587,6 +587,7 @@ def _pj_prompt_static_base [] { let in_ssh = (($env.SSH_CONNECTION? | default "") != "" or ($env.SSH_TTY? | default "") != "") # let prompt_newline = if (($nu.os-info.name | str lowercase) == "windows") { "\n\r" } else { "\n\r" } let prompt_newline = "\n\r" + let has_git = (which ^git | is-not-empty) { os_symbol: (_pj_os_symbol) @@ -595,6 +596,7 @@ def _pj_prompt_static_base [] { in_ssh: $in_ssh shell_name: "nu" prompt_newline: $prompt_newline + has_git: $has_git } } @@ -611,7 +613,7 @@ def _pj_left_prompt [] { } let shell_part = $"($p.c_shell) ($static.shell_name) ($p.c_reset)" - let repo = (_pj_git_repo_info) + let repo = (_pj_git_repo_info $static.has_git) let dir = (_pj_truncate_pwd $env.PWD 4 $repo) let git = (_pj_git_info $repo) let git_part = (_pj_git_branch_module $p $git) @@ -681,8 +683,9 @@ export-env { } 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)" + let exit_code = ($env.LAST_EXIT_CODE? | default 0) + if ($exit_code != 0) { + $"($p.c_right_error)Exit code: ($exit_code)($p.c_reset)" } else { "" } diff --git a/nushell/modules/pj_starship.nu b/nushell/modules/pj_starship.nu index 5e46c69..32998d1 100644 --- a/nushell/modules/pj_starship.nu +++ b/nushell/modules/pj_starship.nu @@ -19,10 +19,10 @@ export def "pj starship doctor" [] { let installed = ((which ^starship | length) > 0) let prompt_type = ($env.PROMPT_COMMAND? | describe) let right_prompt_type = ($env.PROMPT_COMMAND_RIGHT? | describe) - let prompt_cmd = (($env.PROMPT_COMMAND? | to nuon --serialize) | default "") - let right_prompt_cmd = (($env.PROMPT_COMMAND_RIGHT? | to nuon --serialize) | default "") - let prompt_uses_starship = ($prompt_cmd | str contains "starship' prompt") - let right_prompt_uses_starship = ($right_prompt_cmd | str contains "starship' prompt") + let prompt_cmd = if ($env.PROMPT_COMMAND? == null) { "" } else { ($env.PROMPT_COMMAND | to nuon --serialize) } + let right_prompt_cmd = if ($env.PROMPT_COMMAND_RIGHT? == null) { "" } else { ($env.PROMPT_COMMAND_RIGHT | to nuon --serialize) } + let prompt_uses_starship = ($prompt_cmd | str contains "starship") + let right_prompt_uses_starship = ($right_prompt_cmd | str contains "starship") { starship_installed: $installed diff --git a/nushell/modules/pj_uv.nu b/nushell/modules/pj_uv.nu index f53563b..c7c1147 100644 --- a/nushell/modules/pj_uv.nu +++ b/nushell/modules/pj_uv.nu @@ -11,6 +11,6 @@ export def --env "pj uvthu" [] { UV_INDEX_URL: "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/" } } else { - hide-env UV_INDEX_URL + hide-env --ignore-errors UV_INDEX_URL } } diff --git a/nushell/modules/pj_zoxide.nu b/nushell/modules/pj_zoxide.nu index 6f0c3b2..f6c0918 100644 --- a/nushell/modules/pj_zoxide.nu +++ b/nushell/modules/pj_zoxide.nu @@ -42,7 +42,7 @@ export-env { # def _pj_normalize_windows_drive [path: string] { - if (($nu.os-info.name | str lowercase) != "windows") { + if (($nu.os-info.name? | default "" | str lowercase) != "windows") { return $path } diff --git a/nushell/nu_polyjuice.nu b/nushell/nu_polyjuice.nu index b5cced7..5ee8daf 100644 --- a/nushell/nu_polyjuice.nu +++ b/nushell/nu_polyjuice.nu @@ -16,3 +16,4 @@ use modules/pj_zoxide.nu * use modules/pj_historyhintcomplete.nu * use modules/pj_deepseek.nu * use modules/pj_prompt.nu * +use modules/pj_starship.nu *