Skip to content

Commit

Permalink
Add support for cmd.exe (experimental)
Browse files Browse the repository at this point in the history
  • Loading branch information
mataha committed May 10, 2023
1 parent 03df9d4 commit a545534
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- Support for `cmd.exe` (experimental).

### Added

- Fish/Zsh: aliases on `__zoxide_z` will now use completions.
Expand Down
2 changes: 1 addition & 1 deletion contrib/completions/_zoxide

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion contrib/completions/zoxide.bash

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contrib/completions/zoxide.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ in pkgs.mkShell {

# Shells
pkgs.bash
pkgs.cmd
pkgs.dash
pkgs.elvish
pkgs.fish
Expand Down
1 change: 1 addition & 0 deletions src/cmd/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ pub enum InitHook {
#[derive(ValueEnum, Clone, Debug)]
pub enum InitShell {
Bash,
Cmd,
Elvish,
Fish,
Nushell,
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, Xonsh, Zsh};
use crate::shell::{Bash, Cmd, Elvish, Fish, Nushell, Opts, Posix, Powershell, Xonsh, Zsh};

impl Run for Init {
fn run(&self) -> Result<()> {
Expand All @@ -17,6 +17,7 @@ impl Run for Init {

let source = match self.shell {
InitShell::Bash => Bash(opts).render(),
InitShell::Cmd => Cmd(opts).render(),
InitShell::Elvish => Elvish(opts).render(),
InitShell::Fish => Fish(opts).render(),
InitShell::Nushell => Nushell(opts).render(),
Expand Down
17 changes: 17 additions & 0 deletions src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ macro_rules! make_template {
}

make_template!(Bash, "bash.txt");
make_template!(Cmd, "cmd.txt");
make_template!(Elvish, "elvish.txt");
make_template!(Fish, "fish.txt");
make_template!(Nushell, "nushell.txt");
Expand Down Expand Up @@ -93,6 +94,22 @@ mod tests {
.stderr("");
}

#[apply(opts)]
fn cmd_cmd(cmd: Option<&str>, hook: InitHook, echo: bool, resolve_symlinks: bool) {
let opts = Opts { cmd, hook, echo, resolve_symlinks };
let mut source = Cmd(&opts).render().unwrap();

// @TODO test this sometime, somehow
let tempfile = tempfile::tempfile();

Command::new("cmd")
.args(["/c", &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 };
Expand Down
156 changes: 156 additions & 0 deletions templates/cmd.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
{%- let section = "@rem ==========================================================================\n@rem" -%}
{%- let not_configured = "@rem -- not configured --" -%}
@setlocal EnableDelayedExpansion EnableExtensions & set "CMD=!CMDCMDLINE!" 2>nul
@if /i not "!CMD!"=="!CMD:/=!" (goto :EOF) else @if not defined DEBUG (echo off)
@reg query "HKCU\Software\Microsoft\Command Processor" /v "AutoRun" /z >nul 2>&1
@if !ERRORLEVEL! equ 0 (endlocal & set "CMD_ENV=%~0") else (echo(cmd& goto :EOF)

{{ section }}
@rem Utility functions for zoxide.
@rem

@rem Full credits to jeb for this - https://stackoverflow.com/a/76213522/6724141
set i_AS_$*=%%^^^^ in ("") do @for /f "delims=" %%i in (^^""$*%%~^^"^")

set __ZOXIDE_CD=chdir /d
set __ZOXIDE_PWD=chdir

@rem cd + custom logic based on the value of _ZO_ECHO.
doskey cd = ( ^
{#- Full credits to jeb (see https://stackoverflow.com/a/76213522/6724141) #}
for %%^^^^ in ("") do @for /f "delims=" %%i in (^^""$*%%~^^"^") do @( ^
if "%%~i"=="" ( ^
if defined USERPROFILE ( ^
if /i not "%%CD%%"=="%%USERPROFILE%%" ( ^
%__ZOXIDE_CD% "%%USERPROFILE%%" ^&^& ^
}
{%- if echo %}
%__ZOXIDE_PWD% ^&^& ^
{%- endif %}
{% if hook != InitHook::None -%}
if defined __ZOXIDE_HOOK (%%__ZOXIDE_HOOK%%) ^&^& ^
{%- endif %}
set "OLDCD=%%CD%%" ^
) ^
) ^
) else if "%%~i"=="-" ( ^
if defined OLDCD ( ^
if /i not "%%CD%%"=="%%OLDCD%%" ( ^
%__ZOXIDE_CD% "%%OLDCD%%" ^&^& ^
{%- if echo %}
%__ZOXIDE_PWD% ^&^& ^
{%- endif %}
{% if hook != InitHook::None -%}
if defined __ZOXIDE_HOOK (%%__ZOXIDE_HOOK%%) ^&^& ^
{%- endif %}
set "OLDCD=%%CD%%" ^
) ^
) ^
) else ( ^
( ^
if /i not "%%CD%%"=="%%~fi" ( ^
%__ZOXIDE_CD% %%~fi ^&^& ^
{%- if echo %}
%__ZOXIDE_PWD% ^&^& ^
{%- endif %}
{% if hook != InitHook::None -%}
if defined __ZOXIDE_HOOK (%%__ZOXIDE_HOOK%%) ^&^& ^
{%- endif %}
set "OLDCD=%%CD%%" ^
) ^
) ^
) ^
) ^
)

doskey pwd = (%__ZOXIDE_PWD%)

{{ section }}
@rem Hook configuration for zoxide.
@rem

if not defined __ZOXIDE_HOOKED (
set __ZOXIDE_HOOKED=1
{% if hook == InitHook::None -%}
@rem {{ not_configured }}
set __ZOXIDE_HOOK=
{%- else -%}
@rem Initialize hook to add new entries to the database.
set __ZOXIDE_HOOK=for /f "delims=" %%z in ('%__ZOXIDE_PWD%') do (zoxide add -- "%%~fz ")
{%- endif %}
)

{{ section }}
@rem Commands for zoxide. Disable these using --no-cmd.
@rem

{%- match cmd %}
{%- when Some with (cmd) %}

@rem Jump to a directory using only keywords.
doskey {{cmd}} = ( ^
for %%^^^^ in ("") do @for /f "delims=" %%i in (^^""$*%%~^^"^") do @( ^
if "%%~i"=="" ( ^
if defined HOME ( ^
if /i not "%%CD%%"=="%%HOME%%" ( ^
%__CD% "%%HOME%%" ^&^& ^
{%- if echo %}
%__ZOXIDE_PWD% ^&^& ^
{%- endif %}
set "OLDCD=%%CD%%" ^&^& ^
%__ZOXIDE_HOOK% ^
) ^
) ^
) else if "%%~i"=="-" ( ^
if defined OLDCD ( ^
if /i not "%%CD%%"=="%%OLDCD%%" ( ^
%__CD% "%%OLDCD%%" ^&^& ^
{%- if echo %}
%__ZOXIDE_PWD% ^&^& ^
{%- endif %}
set "OLDCD=%%CD%%" ^&^& ^
%__ZOXIDE_HOOK% ^
) ^
) ^
) else ( ^
for /f "delims=" %%p in ('zoxide query --exclude "%%CD%%" -- "%%~i"') do @( ^
if /i not "%%CD%%"=="%%~fp" ( ^
%__CD% %%~fp ^&^& ^
{%- if echo %}
%__ZOXIDE_PWD% ^&^& ^
{%- endif %}
set "OLDCD=%%CD%%" ^&^& ^
%__ZOXIDE_HOOK% ^
) ^
) ^
) ^
) ^
)

@rem Jump to a directory using interactive search.
doskey {{cmd}}i = ( ^
for %%^^^^ in ("") do @for /f "delims=" %%i in (^^""$*%%~^^"^") do @( ^
for /f "delims=" %%q in ('zoxide query --interactive -- "%%~i"') do @( ^
%__CD% %%~fq ^&^& ^
{%- if echo %}
%__ZOXIDE_PWD% ^&^& ^
{%- endif %}
set "OLDCD=%%CD%%" ^&^& ^
%__ZOXIDE_HOOK% ^
) ^
) ^
)

{%- when None %}

{{ not_configured }}

{%- endmatch %}

{{ section }}
@rem To initialize zoxide, add the contents of the following command to your
@rem configuration:
@rem
@rem zoxide init cmd
@rem
@rem If you don't have one: <TODO: explain how to run `AutoRun` scripts>

0 comments on commit a545534

Please sign in to comment.