From 32ed3ec28a50122c55b11f058cde36dee2130916 Mon Sep 17 00:00:00 2001 From: Juhan280 Date: Tue, 4 Nov 2025 13:15:25 +0600 Subject: [PATCH 1/7] Add nushell completion for __zoxide_z --- templates/nushell.txt | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/templates/nushell.txt b/templates/nushell.txt index 4153b39..dbd09e6 100644 --- a/templates/nushell.txt +++ b/templates/nushell.txt @@ -3,6 +3,8 @@ # Code generated by zoxide. DO NOT EDIT. +const homedir = if $nu.home-dir? != null { $nu.home-dir } else { $nu.home-path } + {{ section }} # Hook configuration for zoxide. # @@ -51,12 +53,42 @@ export-env { {%- endif %} +{{ section }} +# Completion for __zoxide_z +# + +def "nu-complete __zoxide_z" [context: string] { + let ast = ast --flatten $context | skip 1 + + # If the user has typed a space after the first argument, use the custom + # completer. If not, use the built-in directory completion. + if ($ast | is-empty) { return null } + if $ast.0.span.end >= ($context | str length) { return null } + + let completions = ^zoxide query --exclude $env.PWD --list -- ...$ast.content + | lines | each { + if $in starts-with $"($homedir)(char psep)" { + str replace $homedir "~" + } else {} + } | wrap value + | insert span { start: ($ast | first).span.start, end: ($ast | last).span.end } + + { + options: { + sort: false, + case_sensitive: false, + completion_algorithm: "substring", + } + completions: $completions, + } +} + {{ section }} # When using zoxide with --no-cmd, alias these internal functions as desired. # # Jump to a directory using only keywords. -def --env --wrapped __zoxide_z [...rest: string] { +export def --env --wrapped __zoxide_z [...rest: directory@"nu-complete __zoxide_z"] { let path = match $rest { [] => {'~'}, [ '-' ] => {'-'}, @@ -72,7 +104,7 @@ def --env --wrapped __zoxide_z [...rest: string] { } # Jump to a directory using interactive search. -def --env --wrapped __zoxide_zi [...rest:string] { +export def --env --wrapped __zoxide_zi [...rest: string] { cd $'(^zoxide query --interactive -- ...$rest | str trim -r -c "\n")' {%- if echo %} echo $env.PWD @@ -86,8 +118,8 @@ def --env --wrapped __zoxide_zi [...rest:string] { {%- match cmd %} {%- when Some with (cmd) %} -alias {{cmd}} = __zoxide_z -alias {{cmd}}i = __zoxide_zi +export alias {{cmd}} = __zoxide_z +export alias {{cmd}}i = __zoxide_zi {%- when None %} From bdedc2a813b37dc5abbd7159247df0bc01b0f123 Mon Sep 17 00:00:00 2001 From: Juhan280 Date: Thu, 12 Feb 2026 17:08:30 +0600 Subject: [PATCH 2/7] Wrap nushell integration script in a module This prevents the completion command "nu-complete __zoxide_z" from polluting the command namespace. --- templates/nushell.txt | 233 ++++++++++++++++++++++-------------------- 1 file changed, 121 insertions(+), 112 deletions(-) diff --git a/templates/nushell.txt b/templates/nushell.txt index dbd09e6..e3b45f4 100644 --- a/templates/nushell.txt +++ b/templates/nushell.txt @@ -1,133 +1,142 @@ -{%- let section = "# =============================================================================\n#" -%} +{%- let section = "# =============================================================================" -%} {%- let not_configured = "# -- not configured --" -%} # Code generated by zoxide. DO NOT EDIT. -const homedir = if $nu.home-dir? != null { $nu.home-dir } else { $nu.home-path } +module zoxide_integration { + const homedir = if $nu.home-dir? != null { $nu.home-dir } else { $nu.home-path } -{{ section }} -# Hook configuration for zoxide. -# + {{ section }} + # + # Hook configuration for zoxide. + # -{% if hook == InitHook::None -%} -{{ not_configured }} + {% if hook == InitHook::None -%} + {{ not_configured }} -{%- else -%} -# Initialize hook to add new entries to the database. -export-env { -{%- if hook == InitHook::Prompt %} - $env.config = ( - $env.config? - | default {} - | upsert hooks { default {} } - | upsert hooks.pre_prompt { default [] } - ) - let __zoxide_hooked = ( - $env.config.hooks.pre_prompt | any { try { get __zoxide_hook } catch { false } } - ) - if not $__zoxide_hooked { - $env.config.hooks.pre_prompt = ($env.config.hooks.pre_prompt | append { - __zoxide_hook: true, - code: {|| ^zoxide add -- $env.PWD} - }) - } -{%- else if hook == InitHook::Pwd %} - $env.config = ( - $env.config? - | default {} - | upsert hooks { default {} } - | upsert hooks.env_change { default {} } - | upsert hooks.env_change.PWD { default [] } - ) - let __zoxide_hooked = ( - $env.config.hooks.env_change.PWD | any { try { get __zoxide_hook } catch { false } } - ) - if not $__zoxide_hooked { - $env.config.hooks.env_change.PWD = ($env.config.hooks.env_change.PWD | append { - __zoxide_hook: true, - code: {|_, dir| ^zoxide add -- $dir} - }) - } -{%- endif %} -} - -{%- endif %} - -{{ section }} -# Completion for __zoxide_z -# - -def "nu-complete __zoxide_z" [context: string] { - let ast = ast --flatten $context | skip 1 - - # If the user has typed a space after the first argument, use the custom - # completer. If not, use the built-in directory completion. - if ($ast | is-empty) { return null } - if $ast.0.span.end >= ($context | str length) { return null } - - let completions = ^zoxide query --exclude $env.PWD --list -- ...$ast.content - | lines | each { - if $in starts-with $"($homedir)(char psep)" { - str replace $homedir "~" - } else {} - } | wrap value - | insert span { start: ($ast | first).span.start, end: ($ast | last).span.end } - - { - options: { - sort: false, - case_sensitive: false, - completion_algorithm: "substring", + {%- else -%} + # Initialize hook to add new entries to the database. + export-env { + {%- if hook == InitHook::Prompt %} + $env.config = ( + $env.config? + | default {} + | upsert hooks { default {} } + | upsert hooks.pre_prompt { default [] } + ) + let __zoxide_hooked = ( + $env.config.hooks.pre_prompt | any { try { get __zoxide_hook } catch { false } } + ) + if not $__zoxide_hooked { + $env.config.hooks.pre_prompt = ($env.config.hooks.pre_prompt | append { + __zoxide_hook: true, + code: {|| ^zoxide add -- $env.PWD} + }) } - completions: $completions, + {%- else if hook == InitHook::Pwd %} + $env.config = ( + $env.config? + | default {} + | upsert hooks { default {} } + | upsert hooks.env_change { default {} } + | upsert hooks.env_change.PWD { default [] } + ) + let __zoxide_hooked = ( + $env.config.hooks.env_change.PWD | any { try { get __zoxide_hook } catch { false } } + ) + if not $__zoxide_hooked { + $env.config.hooks.env_change.PWD = ($env.config.hooks.env_change.PWD | append { + __zoxide_hook: true, + code: {|_, dir| ^zoxide add -- $dir} + }) + } + {%- endif %} } -} -{{ section }} -# When using zoxide with --no-cmd, alias these internal functions as desired. -# + {%- endif %} -# Jump to a directory using only keywords. -export def --env --wrapped __zoxide_z [...rest: directory@"nu-complete __zoxide_z"] { - let path = match $rest { - [] => {'~'}, - [ '-' ] => {'-'}, - [ $arg ] if ($arg | path expand | path type) == 'dir' => {$arg} - _ => { - ^zoxide query --exclude $env.PWD -- ...$rest | str trim -r -c "\n" + {{ section }} + # + # Completion for __zoxide_z + # + + def "nu-complete __zoxide_z" [context: string] { + let ast = ast --flatten $context | skip 1 + + # If the user has typed a space after the first argument, use the custom + # completer. If not, use the built-in directory completion. + if ($ast | is-empty) { return null } + if $ast.0.span.end >= ($context | str length) { return null } + + let completions = ^zoxide query --exclude $env.PWD --list -- ...$ast.content + | lines | each { + if $in starts-with $"($homedir)(char psep)" { + str replace $homedir "~" + } else {} + } | wrap value + | insert span { start: ($ast | first).span.start, end: ($ast | last).span.end } + + { + options: { + sort: false, + case_sensitive: false, + completion_algorithm: "substring", + } + completions: $completions, } } - cd $path -{%- if echo %} - echo $env.PWD -{%- endif %} + + {{ section }} + # + # When using zoxide with --no-cmd, alias these internal functions as desired. + # + + # Jump to a directory using only keywords. + export def --env --wrapped __zoxide_z [...rest: directory@"nu-complete __zoxide_z"] { + let path = match $rest { + [] => {'~'}, + [ '-' ] => {'-'}, + [ $arg ] if ($arg | path expand | path type) == 'dir' => {$arg} + _ => { + ^zoxide query --exclude $env.PWD -- ...$rest | str trim -r -c "\n" + } + } + cd $path + {%- if echo %} + echo $env.PWD + {%- endif %} + } + + # Jump to a directory using interactive search. + export def --env --wrapped __zoxide_zi [...rest: string] { + cd $'(^zoxide query --interactive -- ...$rest | str trim -r -c "\n")' + {%- if echo %} + echo $env.PWD + {%- endif %} + } + + {{ section }} + # + # Commands for zoxide. Disable these using --no-cmd. + # + + {%- match cmd %} + {%- when Some with (cmd) %} + + export alias {{cmd}} = __zoxide_z + export alias {{cmd}}i = __zoxide_zi + + {%- when None %} + + {{ not_configured }} + + {%- endmatch %} } -# Jump to a directory using interactive search. -export def --env --wrapped __zoxide_zi [...rest: string] { - cd $'(^zoxide query --interactive -- ...$rest | str trim -r -c "\n")' -{%- if echo %} - echo $env.PWD -{%- endif %} -} +export use zoxide_integration * {{ section }} -# Commands for zoxide. Disable these using --no-cmd. # - -{%- match cmd %} -{%- when Some with (cmd) %} - -export alias {{cmd}} = __zoxide_z -export alias {{cmd}}i = __zoxide_zi - -{%- when None %} - -{{ not_configured }} - -{%- endmatch %} - -{{ section }} # Add this to your env file (find it by running `$nu.env-path` in Nushell): # # zoxide init nushell | save -f ~/.zoxide.nu From 79f5f6671b8ff4a9ac2158b8b8ee3246386d1b09 Mon Sep 17 00:00:00 2001 From: Juhan280 Date: Thu, 12 Feb 2026 19:15:37 +0600 Subject: [PATCH 3/7] update minimum nushell version 0.106.0 --- README.md | 2 +- templates/nushell.txt | 26 +++++--------------------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index b397f82..1a354b0 100644 --- a/README.md +++ b/README.md @@ -257,7 +257,7 @@ zoxide can be installed in 4 easy steps: > ``` > > **Note** - > zoxide only supports Nushell v0.89.0+. + > zoxide only supports Nushell v0.106.0+. diff --git a/templates/nushell.txt b/templates/nushell.txt index e3b45f4..5a0d330 100644 --- a/templates/nushell.txt +++ b/templates/nushell.txt @@ -4,6 +4,7 @@ # Code generated by zoxide. DO NOT EDIT. module zoxide_integration { + # From version 0.110.0, $nu.home-path has been renamed to $nu.home-dir const homedir = if $nu.home-dir? != null { $nu.home-dir } else { $nu.home-path } {{ section }} @@ -18,15 +19,7 @@ module zoxide_integration { # Initialize hook to add new entries to the database. export-env { {%- if hook == InitHook::Prompt %} - $env.config = ( - $env.config? - | default {} - | upsert hooks { default {} } - | upsert hooks.pre_prompt { default [] } - ) - let __zoxide_hooked = ( - $env.config.hooks.pre_prompt | any { try { get __zoxide_hook } catch { false } } - ) + let __zoxide_hooked = $env.config.hooks.pre_prompt | any { get __zoxide_hook? } if not $__zoxide_hooked { $env.config.hooks.pre_prompt = ($env.config.hooks.pre_prompt | append { __zoxide_hook: true, @@ -34,18 +27,9 @@ module zoxide_integration { }) } {%- else if hook == InitHook::Pwd %} - $env.config = ( - $env.config? - | default {} - | upsert hooks { default {} } - | upsert hooks.env_change { default {} } - | upsert hooks.env_change.PWD { default [] } - ) - let __zoxide_hooked = ( - $env.config.hooks.env_change.PWD | any { try { get __zoxide_hook } catch { false } } - ) + let __zoxide_hooked = $env.config.hooks.env_change.PWD? | default [] | any { get __zoxide_hook? } if not $__zoxide_hooked { - $env.config.hooks.env_change.PWD = ($env.config.hooks.env_change.PWD | append { + $env.config.hooks.env_change.PWD = ($env.config.hooks.env_change.PWD? | append { __zoxide_hook: true, code: {|_, dir| ^zoxide add -- $dir} }) @@ -146,4 +130,4 @@ export use zoxide_integration * # # source ~/.zoxide.nu # -# Note: zoxide only supports Nushell v0.89.0+. +# Note: zoxide only supports Nushell v0.106.0+. From 9ae8519506a2bb123cfb9ab48b13136236a57731 Mon Sep 17 00:00:00 2001 From: Juhan280 Date: Thu, 12 Feb 2026 20:09:10 +0600 Subject: [PATCH 4/7] always escape the paths --- templates/nushell.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/nushell.txt b/templates/nushell.txt index 5a0d330..cefa049 100644 --- a/templates/nushell.txt +++ b/templates/nushell.txt @@ -56,7 +56,7 @@ module zoxide_integration { | lines | each { if $in starts-with $"($homedir)(char psep)" { str replace $homedir "~" - } else {} + } else {} | debug --raw-value } | wrap value | insert span { start: ($ast | first).span.start, end: ($ast | last).span.end } From b106d384e7f21e4b94c8c9cd0afa400a99c9efa6 Mon Sep 17 00:00:00 2001 From: Juhan280 Date: Fri, 13 Feb 2026 17:48:16 +0600 Subject: [PATCH 5/7] disble filtering --- templates/nushell.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/nushell.txt b/templates/nushell.txt index cefa049..4ea1ad6 100644 --- a/templates/nushell.txt +++ b/templates/nushell.txt @@ -63,6 +63,7 @@ module zoxide_integration { { options: { sort: false, + filter: false, case_sensitive: false, completion_algorithm: "substring", } From b8844cd373ffd92aa022e7d1b08f900d067a9bd7 Mon Sep 17 00:00:00 2001 From: Juhan280 Date: Thu, 19 Feb 2026 01:48:13 +0600 Subject: [PATCH 6/7] make closures in `any` command return boolean --- templates/nushell.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/templates/nushell.txt b/templates/nushell.txt index 4ea1ad6..14782a0 100644 --- a/templates/nushell.txt +++ b/templates/nushell.txt @@ -19,7 +19,10 @@ module zoxide_integration { # Initialize hook to add new entries to the database. export-env { {%- if hook == InitHook::Prompt %} - let __zoxide_hooked = $env.config.hooks.pre_prompt | any { get __zoxide_hook? } + let __zoxide_hooked = ( + $env.config.hooks.pre_prompt + | any { get __zoxide_hook? | default false } + ) if not $__zoxide_hooked { $env.config.hooks.pre_prompt = ($env.config.hooks.pre_prompt | append { __zoxide_hook: true, @@ -27,7 +30,10 @@ module zoxide_integration { }) } {%- else if hook == InitHook::Pwd %} - let __zoxide_hooked = $env.config.hooks.env_change.PWD? | default [] | any { get __zoxide_hook? } + let __zoxide_hooked = ( + $env.config.hooks.env_change.PWD? | default [] + | any { get __zoxide_hook? | default false } + ) if not $__zoxide_hooked { $env.config.hooks.env_change.PWD = ($env.config.hooks.env_change.PWD? | append { __zoxide_hook: true, From be220c9542a793562bac873894ee5a57c604f394 Mon Sep 17 00:00:00 2001 From: Juhan280 Date: Sat, 21 Feb 2026 02:28:23 +0600 Subject: [PATCH 7/7] use display_override --- templates/nushell.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/nushell.txt b/templates/nushell.txt index 14782a0..31f19de 100644 --- a/templates/nushell.txt +++ b/templates/nushell.txt @@ -62,8 +62,9 @@ module zoxide_integration { | lines | each { if $in starts-with $"($homedir)(char psep)" { str replace $homedir "~" - } else {} | debug --raw-value - } | wrap value + } else {} + } | wrap display_override + | insert value { get display_override | debug --raw-value } | insert span { start: ($ast | first).span.start, end: ($ast | last).span.end } {