Skip to content

Commit a0c6535

Browse files
committed
Make percent characters work in all contexts
1 parent 70321ca commit a0c6535

File tree

4 files changed

+138
-127
lines changed

4 files changed

+138
-127
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,17 @@ zoxide can be installed in 4 easy steps:
180180
181181
</details>
182182
183+
<details>
184+
<summary>`cmd.exe`</summary>
185+
186+
> Add this to the **end** of your config file or AutoRun command:
187+
>
188+
> ```batchfile
189+
> zoxide init cmd | cmd /d >nul
190+
> ```
191+
192+
</details>
193+
183194
<details>
184195
<summary>Elvish</summary>
185196

src/shell.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,10 @@ mod tests {
104104
let source = Cmd(&opts).render().unwrap();
105105

106106
Command::new("cmd.exe")
107-
.args(["/a", "/d", "/e:on", "/q", "/v:off", "/k", "@doskey", "/macros:cmd.exe"])
107+
.args(["/a", "/d", "/e:on", "/q", "/v:off", "/k", "@doskey", "/macros:all"])
108108
.write_stdin(source)
109109
.assert()
110110
.success()
111-
.stdout("")
112111
.stderr("");
113112
}
114113

templates/cmd.txt

Lines changed: 117 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,91 @@
1+
{%- import "utils/batch.txt" as batch -%}
2+
3+
{%- macro cd(directory, tabs) -%} if /i not "%$p%CD%$p%"=="{{ directory }}" (^
4+
{%- call batch::indent(tabs) %} %__builtin_cd% {{ directory|safe }}^
5+
{%- call batch::indent(tabs) %} ^&^& set "OLDPWD=%$p%CD%$p%"^
6+
{%- if echo -%}
7+
{%- call batch::indent(tabs) %} ^&^& {%~ call pwd(tabs + 1) ~%}^
8+
{%- endif -%}
9+
{%- if hook != InitHook::None -%}
10+
{%- call batch::indent(tabs) %} ^&^& (for /f "delims=" %$p%a in ('"%__builtin_pwd%"') do @(zoxide add -- "%$p%~fa\."))^
11+
{%- endif -%}
12+
{%- call batch::indent(tabs) %})
13+
{%- endmacro cd -%}
14+
15+
{%- macro pwd(tabs) -%} (^
16+
{%- if resolve_symlinks -%}
17+
{%- call batch::indent(tabs) %} (^
18+
{%- call batch::indent(tabs) %} for /f "skip=9 tokens=1,2,*" %$p%j in ('""%$fsutil%" reparsepoint query ."') do @(^
19+
{%- call batch::indent(tabs) %} if "%$p%~j"=="Print" if "%$p%~k"=="Name:" if not "%$p%~l"=="" (echo(%$p%~l)^
20+
{%- call batch::indent(tabs) %} )^
21+
{%- call batch::indent(tabs) %} ) ^|^| %__builtin_pwd%^
22+
{%- else -%}
23+
{%- call batch::indent(tabs) %} %__builtin_pwd%^
24+
{%- endif -%}
25+
{%- call batch::indent(tabs) %})
26+
{%- endmacro pwd -%}
27+
128
{%- let section = "@rem ==========================================================================\n@rem" -%}
229
{%- let not_configured = "@rem -- not configured --" -%}
3-
@setlocal EnableDelayedExpansion EnableExtensions & set "CMD=!CMDCMDLINE!" 2>nul
4-
@if /i not "!CMD!"=="!CMD:/=!" (goto :EOF) else @if not defined DEBUG (echo off)
5-
@reg query "HKCU\Software\Microsoft\Command Processor" /v "AutoRun" /z >nul 2>&1
6-
@if !ERRORLEVEL! equ 0 (endlocal & set "CMD_ENV=%~0") else (echo(cmd& goto :EOF)
730

8-
{{ section }}
9-
@rem Utility functions for zoxide.
10-
@rem
31+
@echo off & setlocal EnableDelayedExpansion EnableExtensions
1132

12-
@rem Full credits to jeb for this - https://stackoverflow.com/a/76213522/6724141
13-
set i_AS_$*=%%^^^^ in ("") do @for /f "delims=" %%i in (^^""$*%%~^^"^")
33+
@if "%~f0"=="%~dpnx0" (
34+
set ^"$p=%%<nul"
35+
) else (
36+
set ^"$p=^%<nul"
37+
)
1438

15-
set __ZOXIDE_CD=chdir /d
16-
set __ZOXIDE_PWD=chdir
39+
set ^"$true=(call )"
40+
set ^"$false=(call)"
1741

18-
@rem cd + custom logic based on the value of _ZO_ECHO.
19-
doskey cd = ( ^
20-
{#- Full credits to jeb (see https://stackoverflow.com/a/76213522/6724141) #}
21-
for %%^^^^ in ("") do @for /f "delims=" %%i in (^^""$*%%~^^"^") do @( ^
22-
if "%%~i"=="" ( ^
23-
if defined USERPROFILE ( ^
24-
if /i not "%%CD%%"=="%%USERPROFILE%%" ( ^
25-
%__ZOXIDE_CD% "%%USERPROFILE%%" ^&^& ^
26-
}
27-
{%- if echo %}
28-
%__ZOXIDE_PWD% ^&^& ^
42+
set root=%SystemRoot%\System32
43+
set ^"$doskey=%root%\doskey.exe"
44+
{%- if resolve_symlinks %}
45+
set ^"$fsutil=%root%\fsutil.exe"
2946
{%- endif %}
30-
{% if hook != InitHook::None -%}
31-
if defined __ZOXIDE_HOOK (%%__ZOXIDE_HOOK%%) ^&^& ^
32-
{%- endif %}
33-
set "OLDCD=%%CD%%" ^
34-
) ^
35-
) ^
36-
) else if "%%~i"=="-" ( ^
37-
if defined OLDCD ( ^
38-
if /i not "%%CD%%"=="%%OLDCD%%" ( ^
39-
%__ZOXIDE_CD% "%%OLDCD%%" ^&^& ^
40-
{%- if echo %}
41-
%__ZOXIDE_PWD% ^&^& ^
42-
{%- endif %}
43-
{% if hook != InitHook::None -%}
44-
if defined __ZOXIDE_HOOK (%%__ZOXIDE_HOOK%%) ^&^& ^
45-
{%- endif %}
46-
set "OLDCD=%%CD%%" ^
47-
) ^
48-
) ^
49-
) else ( ^
50-
( ^
51-
if /i not "%%CD%%"=="%%~fi" ( ^
52-
%__ZOXIDE_CD% %%~fi ^&^& ^
53-
{%- if echo %}
54-
%__ZOXIDE_PWD% ^&^& ^
55-
{%- endif %}
56-
{% if hook != InitHook::None -%}
57-
if defined __ZOXIDE_HOOK (%%__ZOXIDE_HOOK%%) ^&^& ^
58-
{%- endif %}
59-
set "OLDCD=%%CD%%" ^
60-
) ^
61-
) ^
62-
) ^
63-
) ^
64-
)
65-
66-
doskey pwd = (%__ZOXIDE_PWD%)
6747

6848
{{ section }}
69-
@rem Hook configuration for zoxide.
49+
@rem Utility functions for zoxide.
7050
@rem
7151

72-
if not defined __ZOXIDE_HOOKED (
73-
set __ZOXIDE_HOOKED=1
74-
{% if hook == InitHook::None -%}
75-
@rem {{ not_configured }}
76-
set __ZOXIDE_HOOK=
77-
{%- else -%}
78-
@rem Initialize hook to add new entries to the database.
79-
set __ZOXIDE_HOOK=for /f "delims=" %%z in ('%__ZOXIDE_PWD%') do (zoxide add -- "%%~fz ")
80-
{%- endif %}
81-
)
52+
set __builtin_cd=chdir /d
53+
set __builtin_pwd=chdir
54+
55+
set __zoxide_cd=cd
56+
set __zoxide_pwd=pwd
57+
58+
@rem cd + custom logic based on the value of _ZO_ECHO.
59+
"%$doskey%" %__zoxide_cd% = (^
60+
{% call batch::for_caret("%$p%", "i") ~%} @(^
61+
if "%$p%~i"=="" (^
62+
if defined USERPROFILE (^
63+
{% call cd("%$p%USERPROFILE%$p%", 4) %}^
64+
) else (^
65+
(echo(%__zoxide_cd%: USERPROFILE is not defined) ^>^&2 ^& %$false%^
66+
)^
67+
) else if "%$p%~i"=="~" (^
68+
if defined USERPROFILE (^
69+
{% call cd("%$p%USERPROFILE%$p%", 4) %}^
70+
) else (^
71+
(echo(%__zoxide_cd%: USERPROFILE is not defined) ^>^&2 ^& %$false%^
72+
)^
73+
) else if "%$p%~i"=="-" (^
74+
if defined OLDPWD (^
75+
{% call cd("%$p%OLDPWD%$p%", 4) %}^
76+
) else (^
77+
(echo(%__zoxide_cd%: OLDPWD is not defined) ^>^&2 ^& %$false%^
78+
)^
79+
) else (^
80+
(^
81+
{% call cd("%$p%~fi", 4) %}^
82+
)^
83+
)^
84+
)^
85+
) ^&^& %$true%
86+
87+
@rem pwd based on the value of _ZO_RESOLVE_SYMLINKS.
88+
"%$doskey%" %__zoxide_pwd% = {%~ call pwd(0) %}
8289

8390
{{ section }}
8491
@rem Commands for zoxide. Disable these using --no-cmd.
@@ -87,70 +94,55 @@ if not defined __ZOXIDE_HOOKED (
8794
{%- match cmd %}
8895
{%- when Some with (cmd) %}
8996

97+
set __zoxide_z_prefix={{cmd}}
98+
9099
@rem Jump to a directory using only keywords.
91-
doskey {{cmd}} = ( ^
92-
for %%^^^^ in ("") do @for /f "delims=" %%i in (^^""$*%%~^^"^") do @( ^
93-
if "%%~i"=="" ( ^
94-
if defined HOME ( ^
95-
if /i not "%%CD%%"=="%%HOME%%" ( ^
96-
%__CD% "%%HOME%%" ^&^& ^
97-
{%- if echo %}
98-
%__ZOXIDE_PWD% ^&^& ^
99-
{%- endif %}
100-
set "OLDCD=%%CD%%" ^&^& ^
101-
%__ZOXIDE_HOOK% ^
102-
) ^
103-
) ^
104-
) else if "%%~i"=="-" ( ^
105-
if defined OLDCD ( ^
106-
if /i not "%%CD%%"=="%%OLDCD%%" ( ^
107-
%__CD% "%%OLDCD%%" ^&^& ^
108-
{%- if echo %}
109-
%__ZOXIDE_PWD% ^&^& ^
110-
{%- endif %}
111-
set "OLDCD=%%CD%%" ^&^& ^
112-
%__ZOXIDE_HOOK% ^
113-
) ^
114-
) ^
115-
) else ( ^
116-
for /f "delims=" %%p in ('zoxide query --exclude "%%CD%%" -- "%%~i"') do @( ^
117-
if /i not "%%CD%%"=="%%~fp" ( ^
118-
%__CD% %%~fp ^&^& ^
119-
{%- if echo %}
120-
%__ZOXIDE_PWD% ^&^& ^
121-
{%- endif %}
122-
set "OLDCD=%%CD%%" ^&^& ^
123-
%__ZOXIDE_HOOK% ^
124-
) ^
125-
) ^
126-
) ^
127-
) ^
128-
)
100+
"%$doskey%" %__zoxide_z_prefix% = (^
101+
{% call batch::for_caret("%$p%", "i") ~%} @(^
102+
if "%$p%~i"=="" (^
103+
if defined USERPROFILE (^
104+
{% call cd("%$p%USERPROFILE%$p%", 4) %}^
105+
) else (^
106+
(echo(%__zoxide_z_prefix%: USERPROFILE is not defined) ^>^&2 ^& %$false%^
107+
)^
108+
) else if "%$p%~i"=="~" (^
109+
if defined USERPROFILE (^
110+
{% call cd("%$p%USERPROFILE%$p%", 4) %}^
111+
) else (^
112+
(echo(%__zoxide_z_prefix%: USERPROFILE is not defined) ^>^&2 ^& %$false%^
113+
)^
114+
) else if "%$p%~i"=="-" (^
115+
if defined OLDPWD (^
116+
{% call cd("%$p%OLDPWD%$p%", 4) %}^
117+
) else (^
118+
(echo(%__zoxide_z_prefix%: OLDPWD is not defined) ^>^&2 ^& %$false%^
119+
)^
120+
) else (^
121+
for /f "delims=" %$p%p in ('"zoxide query --exclude "%$p%CD%$p%\." -- %$p%~i"') do @(^
122+
{% call cd("%$p%~fp", 4) %}^
123+
)^
124+
)^
125+
)^
126+
) ^&^& %$true%
129127

130128
@rem Jump to a directory using interactive search.
131-
doskey {{cmd}}i = ( ^
132-
for %%^^^^ in ("") do @for /f "delims=" %%i in (^^""$*%%~^^"^") do @( ^
133-
for /f "delims=" %%q in ('zoxide query --interactive -- "%%~i"') do @( ^
134-
%__CD% %%~fq ^&^& ^
135-
{%- if echo %}
136-
%__ZOXIDE_PWD% ^&^& ^
137-
{%- endif %}
138-
set "OLDCD=%%CD%%" ^&^& ^
139-
%__ZOXIDE_HOOK% ^
140-
) ^
141-
) ^
142-
)
129+
"%$doskey%" %__zoxide_z_prefix%i = (^
130+
{% call batch::for_caret("%$p%", "i") ~%} @(^
131+
for /f "delims=" %$p%p in ('"zoxide query --interactive -- %$p%~i"') do @(^
132+
{% call cd("%$p%~fp", 3) %}^
133+
)^
134+
)^
135+
) ^&^& %$true%
143136

144137
{%- when None %}
145138

146139
{{ not_configured }}
147140

148141
{%- endmatch %}
149142

143+
@endlocal
144+
150145
{{ section }}
151-
@rem To initialize zoxide, add the contents of the following command to your
152-
@rem configuration:
153-
@rem
154-
@rem zoxide init cmd
146+
@rem To initialize zoxide, add this to your configuration or AutoRun command:
155147
@rem
156-
@rem If you don't have one: <TODO: explain how to run `AutoRun` scripts>
148+
@rem zoxide init cmd | cmd /d >nul

templates/utils/batch.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{%- macro indent(tabs) %}
2+
{% for tab in 0..tabs %} {% endfor -%}
3+
{%- endmacro indent -%}
4+
5+
{%- macro for_caret(percent, for_parameter) -%}
6+
{#- `for /f` statement with disappearing carets suitable for use in aliases. -#}
7+
{#- Credits for this go to jeb: https://stackoverflow.com/a/76213522/6724141 -#}
8+
for {{ percent }}^^^^ in ("") do @for /f "delims=" {{ percent }}{{ for_parameter }} in (^^""$*{{ percent }}~^^"^") do
9+
{%- endmacro for_caret -%}

0 commit comments

Comments
 (0)