Add support for csh (#1047)

This commit is contained in:
Ajeet D'Souza 2025-05-05 22:58:54 -07:00 committed by GitHub
parent 7691d7e9a5
commit 09aa626a86
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 115 additions and 8 deletions

View file

@ -9,10 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Support for Csh.
- Added `--score` flag to `zoxide add`.
### Changed
- Bash: zoxide will now rewrite the prompt when using Space-Tab completions.
### Fixed
- Nushell: stop ignoring symlinks when `cd`-ing into a directory.
- Fzf: updated minimum supported version to v0.51.0.
- PowerShell: avoid setting `$error` when defining `__zoxide_hooked`.
## [0.9.7] - 2025-02-10
### Added

View file

@ -323,7 +323,7 @@ zoxide can be installed in 4 easy steps:
interactive selection. It can be installed from [here][fzf-installation].
> **Note**
> The minimum supported fzf version is v0.33.0 on most platforms and v0.51.0 on Windows.
> The minimum supported fzf version is v0.51.0.
4. **Import your data** <sup>(optional)</sup>

View file

@ -114,7 +114,7 @@ _arguments "${_arguments_options[@]}" : \
'--help[Print help]' \
'-V[Print version]' \
'--version[Print version]' \
':shell:(bash elvish fish nushell posix powershell xonsh zsh)' \
':shell:(bash csh elvish fish nushell posix powershell xonsh zsh)' \
&& ret=0
;;
(query)

View file

@ -173,7 +173,7 @@ _zoxide() {
return 0
;;
zoxide__init)
opts="-h -V --no-cmd --cmd --hook --help --version bash elvish fish nushell posix powershell xonsh zsh"
opts="-h -V --no-cmd --cmd --hook --help --version bash csh elvish fish nushell posix powershell xonsh zsh"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0

View file

@ -189,6 +189,7 @@ const completion: Fig.Spec = {
name: "shell",
suggestions: [
"bash",
"csh",
"elvish",
"fish",
"nushell",

View file

@ -1,10 +1,10 @@
let
pkgs = import (builtins.fetchTarball
"https://github.com/NixOS/nixpkgs/archive/056faf24027e12f0ba6edebe299ed136e030d29a.tar.gz") {
"https://github.com/NixOS/nixpkgs/archive/ec9ef366451af88284d7dfd18ee017b7e86a0710.tar.gz") {
overlays = [ rust ];
};
rust = import (builtins.fetchTarball
"https://github.com/oxalica/rust-overlay/archive/f61820fa2c3844d6940cce269a6afdec30aa2e6c.tar.gz");
"https://github.com/oxalica/rust-overlay/archive/026e8fedefd6b167d92ed04b195c658d95ffc7a5.tar.gz");
rust-nightly =
pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.minimal);
@ -27,6 +27,7 @@ in pkgs.mkShell {
pkgs.ksh
pkgs.nushell
pkgs.powershell
pkgs.tcsh
pkgs.xonsh
pkgs.zsh

View file

@ -59,7 +59,8 @@ pub struct Add {
#[clap(num_args = 1.., required = true, value_hint = ValueHint::DirPath)]
pub paths: Vec<PathBuf>,
/// The rank to increment the entry if it exists or initialize it with if it doesn't
/// The rank to increment the entry if it exists or initialize it with if it
/// doesn't
#[clap(short, long)]
pub score: Option<f64>,
}
@ -146,6 +147,8 @@ pub enum InitHook {
#[derive(ValueEnum, Clone, Debug)]
pub enum InitShell {
Bash,
#[clap(alias = "tcsh")]
Csh,
Elvish,
Fish,
Nushell,

View file

@ -6,7 +6,7 @@ use rinja::Template;
use crate::cmd::{Init, InitShell, Run};
use crate::config;
use crate::error::BrokenPipeHandler;
use crate::shell::{Bash, Elvish, Fish, Nushell, Opts, Posix, Powershell, Xonsh, Zsh};
use crate::shell::{Bash, Csh, Elvish, Fish, Nushell, Opts, Posix, Powershell, Xonsh, Zsh};
impl Run for Init {
fn run(&self) -> Result<()> {
@ -17,6 +17,7 @@ impl Run for Init {
let source = match self.shell {
InitShell::Bash => Bash(opts).render(),
InitShell::Csh => Csh(opts).render(),
InitShell::Elvish => Elvish(opts).render(),
InitShell::Fish => Fish(opts).render(),
InitShell::Nushell => Nushell(opts).render(),

View file

@ -24,6 +24,7 @@ macro_rules! make_template {
}
make_template!(Bash, "bash.txt");
make_template!(Csh, "csh.txt");
make_template!(Elvish, "elvish.txt");
make_template!(Fish, "fish.txt");
make_template!(Nushell, "nushell.txt");
@ -93,6 +94,20 @@ mod tests {
.stderr("");
}
#[apply(opts)]
fn csh_tcsh(cmd: Option<&str>, hook: InitHook, echo: bool, resolve_symlinks: bool) {
let opts = Opts { cmd, hook, echo, resolve_symlinks };
let source = Csh(&opts).render().unwrap();
Command::new("tcsh")
.args(["-e", "-f", "-s"])
.write_stdin(source)
.assert()
.success()
.stdout("")
.stderr("");
}
#[apply(opts)]
fn elvish_elvish(cmd: Option<&str>, hook: InitHook, echo: bool, resolve_symlinks: bool) {
let opts = Opts { cmd, hook, echo, resolve_symlinks };

View file

@ -160,6 +160,7 @@ if [[ ${BASH_VERSINFO[0]:-0} -eq 4 && ${BASH_VERSINFO[1]:-0} -ge 4 || ${BASH_VER
\builtin bind '"\e[0n": redraw-current-line'
\builtin printf '\e[5n'
# shellcheck disable=SC2016
\builtin bind -x '"\e[0n": __zoxide_z_complete_helper "${result}"'
\builtin printf '\e[5n'
}

74
templates/csh.txt Normal file
View file

@ -0,0 +1,74 @@
{%- let section = "# =============================================================================\n#" -%}
{%- let not_configured = "# -- not configured --" -%}
{%- let pwd_cmd -%}
{%- if resolve_symlinks -%}
{%- let pwd_cmd = "pwd -P" -%}
{%- else -%}
{%- let pwd_cmd = "pwd -L" -%}
{%- endif -%}
{{ section }}
# Hook configuration for zoxide.
#
{%- if hook != InitHook::None %}
# Hook to add new entries to the database.
{%- if hook == InitHook::Prompt %}
alias __zoxide_hook 'zoxide add -- "`{{ pwd_cmd }}`"'
{%- else if hook == InitHook::Pwd %}
set __zoxide_pwd_old = `{{ pwd_cmd }}`
alias __zoxide_hook 'set __zoxide_pwd_tmp = "`{{ pwd_cmd }}`"; test "$__zoxide_pwd_tmp" != "$__zoxide_pwd_old" && zoxide add -- "$__zoxide_pwd_tmp"; set __zoxide_pwd_old = "$__zoxide_pwd_tmp"'
{%- endif %}
# Initialize hook.
alias precmd ';__zoxide_hook'
{%- endif %}
{{ section }}
# When using zoxide with --no-cmd, alias these internal functions as desired.
#
# Jump to a directory using only keywords.
alias __zoxide_z 'set __zoxide_args = (\!*)\
if ("$#__zoxide_args" == 0) then\
cd ~\
else\
if ("$#__zoxide_args" == 1 && "$__zoxide_args[1]" == "-") then\
cd -\
else if ("$#__zoxide_args" == 1 && -d "$__zoxide_args[1]") then\
cd "$__zoxide_args[1]"\
else\
set __zoxide_pwd = `{{ pwd_cmd }}`\
set __zoxide_result = "`zoxide query --exclude '"'"'$__zoxide_pwd'"'"' -- $__zoxide_args`" && cd "$__zoxide_result"\
endif\
endif'
# Jump to a directory using interactive search.
alias __zoxide_zi 'set __zoxide_args = (\!*)\
set __zoxide_pwd = `{{ pwd_cmd }}`\
set __zoxide_result = "`zoxide query --exclude '"'"'$__zoxide_pwd'"'"' --interactive -- $__zoxide_args`" && cd "$__zoxide_result"'
{{ section }}
# Commands for zoxide. Disable these using --no-cmd.
#
{%- match cmd %}
{%- when Some with (cmd) %}
alias {{cmd}} __zoxide_z
alias {{cmd}}i __zoxide_zi
{%- when None %}
{{ not_configured }}
{%- endmatch %}
{{ section }}
# To initialize zoxide, add this to your shell configuration file (usually ~/.cshrc or ~/.tcshrc):
#
# zoxide init csh > ~/.zoxide.csh
# source ~/.zoxide.csh

View file

@ -64,7 +64,7 @@ class ZoxideSilentException(Exception):
def __zoxide_errhandler(
func: typing.Callable[[list[str]], None]
func: typing.Callable[[list[str]], None],
) -> typing.Callable[[list[str]], int]:
"""Print exception and exit with error code 1."""