From 04490ec00786ef277aca82cfdd26491caeee72c9 Mon Sep 17 00:00:00 2001 From: aidancz Date: Wed, 12 Aug 2026 20:54:28 +0800 Subject: [PATCH] add support for schemesh --- README.md | 11 +++ contrib/completions/_zoxide | 2 +- contrib/completions/zoxide.bash | 2 +- contrib/completions/zoxide.nu | 2 +- contrib/completions/zoxide.ts | 1 + src/cmd/cmd.rs | 1 + src/cmd/init.rs | 3 +- src/shell.rs | 13 ++++ templates/schemesh.txt | 115 ++++++++++++++++++++++++++++++++ 9 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 templates/schemesh.txt diff --git a/README.md b/README.md index 6d9af91..4cb3e1b 100644 --- a/README.md +++ b/README.md @@ -284,6 +284,17 @@ zoxide can be installed in 4 easy steps: +
+ Schemesh + + > Add this to the **end** of your config file (usually `~/.config/schemesh/repl_init.ss`): + > + > ```scheme + > (sh-eval-string (sh-run/string {zoxide init schemesh}) 'scheme) + > ``` + +
+
Tcsh diff --git a/contrib/completions/_zoxide b/contrib/completions/_zoxide index 2f4c9f0..2a582d1 100644 --- a/contrib/completions/_zoxide +++ b/contrib/completions/_zoxide @@ -178,7 +178,7 @@ _arguments "${_arguments_options[@]}" : \ '--help[Print help]' \ '-V[Print version]' \ '--version[Print version]' \ -':shell:(bash elvish fish nushell posix powershell tcsh xonsh zsh)' \ +':shell:(bash elvish fish nushell posix powershell schemesh tcsh xonsh zsh)' \ && ret=0 ;; (query) diff --git a/contrib/completions/zoxide.bash b/contrib/completions/zoxide.bash index 1e6fdcf..a979591 100644 --- a/contrib/completions/zoxide.bash +++ b/contrib/completions/zoxide.bash @@ -275,7 +275,7 @@ _zoxide() { return 0 ;; zoxide__subcmd__init) - opts="-h -V --no-cmd --cmd --hook --help --version bash elvish fish nushell posix powershell tcsh xonsh zsh" + opts="-h -V --no-cmd --cmd --hook --help --version bash elvish fish nushell posix powershell schemesh tcsh xonsh zsh" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/contrib/completions/zoxide.nu b/contrib/completions/zoxide.nu index 4d07049..8d24a69 100644 --- a/contrib/completions/zoxide.nu +++ b/contrib/completions/zoxide.nu @@ -93,7 +93,7 @@ module completions { ] def "nu-complete zoxide init shell" [] { - [ "bash" "elvish" "fish" "nushell" "posix" "powershell" "tcsh" "xonsh" "zsh" ] + [ "bash" "elvish" "fish" "nushell" "posix" "powershell" "schemesh" "tcsh" "xonsh" "zsh" ] } def "nu-complete zoxide init hook" [] { diff --git a/contrib/completions/zoxide.ts b/contrib/completions/zoxide.ts index 207da2f..41d1d83 100644 --- a/contrib/completions/zoxide.ts +++ b/contrib/completions/zoxide.ts @@ -288,6 +288,7 @@ const completion: Fig.Spec = { "nushell", "posix", "powershell", + "schemesh", "tcsh", "xonsh", "zsh", diff --git a/src/cmd/cmd.rs b/src/cmd/cmd.rs index 0de2ee5..90541f3 100644 --- a/src/cmd/cmd.rs +++ b/src/cmd/cmd.rs @@ -160,6 +160,7 @@ pub enum InitShell { #[clap(alias = "ksh")] Posix, Powershell, + Schemesh, Tcsh, Xonsh, Zsh, diff --git a/src/cmd/init.rs b/src/cmd/init.rs index 980513e..4f89848 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -6,7 +6,7 @@ use askama::Template; use crate::cmd::{Init, InitShell, Run}; use crate::config; use crate::error::BrokenPipeHandler; -use crate::shell::{Bash, Elvish, Fish, Nushell, Opts, Posix, Powershell, Tcsh, Xonsh, Zsh}; +use crate::shell::{Bash, Elvish, Fish, Nushell, Opts, Posix, Powershell, Schemesh, Tcsh, Xonsh, Zsh}; impl Run for Init { fn run(&self) -> Result<()> { @@ -22,6 +22,7 @@ impl Run for Init { InitShell::Nushell => Nushell(opts).render(), InitShell::Posix => Posix(opts).render(), InitShell::Powershell => Powershell(opts).render(), + InitShell::Schemesh => Schemesh(opts).render(), InitShell::Tcsh => Tcsh(opts).render(), InitShell::Xonsh => Xonsh(opts).render(), InitShell::Zsh => Zsh(opts).render(), diff --git a/src/shell.rs b/src/shell.rs index 8812b1c..bb83727 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -29,6 +29,7 @@ make_template!(Fish, "fish.txt"); make_template!(Nushell, "nushell.txt"); make_template!(Posix, "posix.txt"); make_template!(Powershell, "powershell.txt"); +make_template!(Schemesh, "schemesh.txt"); make_template!(Tcsh, "tcsh.txt"); make_template!(Xonsh, "xonsh.txt"); make_template!(Zsh, "zsh.txt"); @@ -249,6 +250,18 @@ mod tests { .stderr(""); } + #[apply(opts)] + fn schemesh_schemesh(cmd: Option<&str>, hook: InitHook, echo: bool, resolve_symlinks: bool) { + let opts = Opts { cmd, hook, echo, resolve_symlinks }; + let source = Schemesh(&opts).render().unwrap(); + Command::new("schemesh") + .args(["--eval", &source]) + .assert() + .success() + .stdout("") + .stderr(""); + } + #[apply(opts)] fn tcsh_tcsh(cmd: Option<&str>, hook: InitHook, echo: bool, resolve_symlinks: bool) { let opts = Opts { cmd, hook, echo, resolve_symlinks }; diff --git a/templates/schemesh.txt b/templates/schemesh.txt new file mode 100644 index 0000000..2603fb2 --- /dev/null +++ b/templates/schemesh.txt @@ -0,0 +1,115 @@ +{%- let section = ";; =============================================================================\n;;" -%} +{%- let not_configured = ";; -- not configured --" -%} + +{{ section }} +;; Utility functions for zoxide. +;; + +;; pwd based on the value of _ZO_RESOLVE_SYMLINKS. +(define __zoxide_pwd + (lambda () + (let ((pwd (charspan->string (sh-cwd (sh-globals))))) +{%- if resolve_symlinks %} + (sh-run/string-rtrim-newlines {realpath (values pwd)}) +{%- else %} + pwd +{%- endif %} + ))) + +;; cd + custom logic based on the value of _ZO_ECHO. +(define __zoxide_cd + (lambda args + (cond + ((null? args) (sh-cd (sh-globals))) + ((string=? (car args) "-") (sh-cd- (sh-globals))) + (else (sh-cd (sh-globals) (car args)))) +{%- if echo %} + (display (__zoxide_pwd)) + (newline) +{%- endif %} + )) + +{{ section }} +;; Hook configuration for zoxide. +;; + +{%- if hook != InitHook::None %} + +;; Hook to add new entries to the database. +{%- if hook == InitHook::Prompt %} +(define __zoxide_hook + (lambda (pwd-after-eval) + (sh-run {command zoxide add -- (values pwd-after-eval)}))) +{%- else if hook == InitHook::Pwd %} +(define __zoxide_hook + (let ((pwd (__zoxide_pwd))) + (lambda (pwd-after-eval) + (unless (string=? pwd-after-eval pwd) + (set! pwd pwd-after-eval) + (sh-run {command zoxide add -- (values pwd-after-eval)}))))) +{%- endif %} + +;; Initialize hook. +(let ((repl-original-eval (repl-current-eval))) + (repl-current-eval + (lambda (form env) + (let ((vals (repl-original-eval form env))) + (__zoxide_hook (__zoxide_pwd)) + vals)))) + +{%- endif %} + +{{ section }} +;; When using zoxide with --no-cmd, alias these internal functions as desired. +;; + +;; Jump to a directory using only keywords. +(sh-alias "__zoxide_z" + (lambda (args) + (cond + ((null? args) (__zoxide_cd)) + ((and (= (length args) 1) + (string=? (car args) "-")) + (__zoxide_cd (car args))) + ((and (= (length args) 1) + (file-directory? (car args))) + (__zoxide_cd (car args))) + ((and (= (length args) 2) + (string=? (car args) "--")) + (__zoxide_cd (cadr args))) + (else + (let* ((job {command zoxide query --exclude (__zoxide_pwd) -- (values args)}) + (result (sh-run/string-rtrim-newlines job)) + (status (sh-job-status job))) + (when (ok? status) (__zoxide_cd result))))) + (quote ()))) + +;; Jump to a directory using interactive search. +(sh-alias "__zoxide_zi" + (lambda (args) + (let* ((job {command zoxide query --interactive -- (values args)}) + (result (sh-run/string-rtrim-newlines job)) + (status (sh-job-status job))) + (when (ok? status) (__zoxide_cd result))) + (quote ()))) + +{{ section }} +;; Commands for zoxide. Disable these using --no-cmd. +;; + +{%- match cmd %} +{%- when Some with (cmd) %} + +(sh-alias "{{cmd}}" (quote ("__zoxide_z"))) +(sh-alias "{{cmd}}i" (quote ("__zoxide_zi"))) + +{%- when None %} + +{{ not_configured }} + +{%- endmatch %} + +{{ section }} +;; To initialize zoxide, add this to your configuration (usually ~/.config/schemesh/repl_init.ss): +;; +;; (sh-eval-string (sh-run/string {zoxide init schemesh}) 'scheme)