Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ zoxide can be installed in 4 easy steps:
> ```
>
> **Note:**
> zoxide only supports Nushell v0.89.0+.
> zoxide only supports Nushell v0.106.0+.

</details>

Expand Down
191 changes: 112 additions & 79 deletions templates/nushell.txt
Original file line number Diff line number Diff line change
@@ -1,101 +1,134 @@
{%- let section = "# =============================================================================\n#" -%}
{%- let section = "# =============================================================================" -%}
{%- let not_configured = "# -- not configured --" -%}

# Code generated by zoxide. DO NOT EDIT.

{{ section }}
# Hook configuration for zoxide.
#
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 }

{% 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}
})
{{ section }}
#
# Hook configuration for zoxide.
#

{% if hook == InitHook::None -%}
{{ not_configured }}

{%- else -%}
# 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? | default 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 %}
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,
code: {|_, dir| ^zoxide add -- $dir}
})
}
{%- endif %}
}
{%- endif %}
}

{%- endif %}
{%- endif %}

{{ section }}
# When using zoxide with --no-cmd, alias these internal functions as desired.
#
{{ 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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think $ast will be nonempty only if you add a space after the first argument. ast -f "z foo" (no space after foo) is still a length 2 list.

Suggested change
# If the user has typed a space after the first argument, use the custom
# If the user has entered an argument, use the custom

Copy link
Author

@Juhan280 Juhan280 Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you look at the next few lines, I compare the output of ast with the length of the $context, thats how I tell if there is an extra space after the first arg or not.

    if $ast.0.span.end >= ($context | str length) { return null }

# 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 display_override
| insert value { get display_override | debug --raw-value }
| insert span { start: ($ast | first).span.start, end: ($ast | last).span.end }

# Jump to a directory using only keywords.
def --env --wrapped __zoxide_z [...rest: string] {
let path = match $rest {
[] => {'~'},
[ '-' ] => {'-'},
[ $arg ] if ($arg | path expand | path type) == 'dir' => {$arg}
_ => {
^zoxide query --exclude $env.PWD -- ...$rest | str trim -r -c "\n"
{
options: {
sort: false,
filter: false,
case_sensitive: false,
completion_algorithm: "substring",
}
completions: $completions,
}
}
cd $path
{%- if echo %}
echo $env.PWD
{%- endif %}
}

# Jump to a directory using interactive search.
def --env --wrapped __zoxide_zi [...rest:string] {
cd $'(^zoxide query --interactive -- ...$rest | str trim -r -c "\n")'
{%- if echo %}
echo $env.PWD
{%- endif %}
}
{{ section }}
#
# When using zoxide with --no-cmd, alias these internal functions as desired.
#

{{ section }}
# Commands for zoxide. Disable these using --no-cmd.
#
# 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 %}
}

{%- match cmd %}
{%- when Some with (cmd) %}
# 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) %}

alias {{cmd}} = __zoxide_z
alias {{cmd}}i = __zoxide_zi
export alias {{cmd}} = __zoxide_z
export alias {{cmd}}i = __zoxide_zi

{%- when None %}
{%- when None %}

{{ not_configured }}
{{ not_configured }}

{%- endmatch %}
{%- endmatch %}
}

export use zoxide_integration *

{{ section }}
#
# Add this to your env file (find it by running `$nu.env-path` in Nushell):
#
# zoxide init nushell | save -f ~/.zoxide.nu
Expand All @@ -105,4 +138,4 @@ alias {{cmd}}i = __zoxide_zi
#
# source ~/.zoxide.nu
#
# Note: zoxide only supports Nushell v0.89.0+.
# Note: zoxide only supports Nushell v0.106.0+.
Loading