Last active
December 22, 2021 21:35
-
-
Save joerohde/446f96054b287a0dff102ace02f2d160 to your computer and use it in GitHub Desktop.
TakeCommand improved cd / cdd command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
setlocal | |
rem arbitrary max directories to show | |
set MAX=32 | |
setarray directories[%MAX] | |
setarray searchResults[%MAX] | |
rem used to set value that conveniently escapes setlocal | |
setarray __CD[1] | |
on break goto END | |
on errormsg goto END | |
set tmpfile="%TEMP\_cds_%RANDOM.tmpfile" | |
>! %tmpfile | |
set pushcp=%_CODEPAGE | |
chcp 437 >nul: | |
rem make ^$ regex symbols easier | |
setdos /p@ | |
setdos /e# | |
rem show directory names relative to .\ unless '/g' global search | |
local pathTrimPrefix | |
iff "%1" eq "/g" then | |
set pathTrimPrefix= | |
shift /1 | |
elseiff "%1" eq "/?" then | |
goto Usage | |
else | |
rem trim it. Only root dirs have a '\' hanging. (i.e. C:\) | |
set pathTrimPrefix=%@rtrim[\,%_CWD] | |
endiff | |
rem hack to join all remaining arguments into 1 | |
set param="%@unquote[%@]" | |
rem all \ become \\ to not break regexp processing. | |
rem tradeoff: can't search for special chars like this: \(x86\) | |
set match=%@replace[\,\\,%param] | |
rem escape hatch: escape special chars with '/' like this: /(x86/) | |
set match=%@replace[/,\,%match] | |
rem echo %match | |
set lastindex=0 | |
gosub AppendList ^%[match]$ | |
gosub AppendList \\%[match][^\\]+$ | |
gosub AppendList [^\\]%[match][^\\]*$ | |
iff %lastindex eq 0 gosub Error "No matching directories found." | |
iff "%@search[dialog]" ne "" then | |
rem source & binaries: http://andrear.altervista.org/home/cdialog.php | |
dialog --menu "Select Directory" 0 0 0 %@replace[#r#n,,%listing] 2>! %tmpfile | |
screen %@eval[%_ROWS-1] 0. | |
rem bail if ESC | |
if %? ne 0 goto END | |
rem strip the selected tag to a number, decrement it and store dir | |
set index=%@line[%tmpfile,0] | |
rem echo "Index: %index" | |
else | |
input /c /d /l2 Select Directory:%@unquote[%listing#r#n]choice? %%index | |
if %index lt 1 .or. %index gt %lastindex gosub Error "Selected index out of range." | |
endiff | |
set index=%@dec[%index] | |
set __CD[0]=%directories[%index] | |
goto END | |
rem subroutine for common code | |
:AppendList [match] | |
rem base command. Under the prefix path, find up to MAX directories(/ad) | |
rem sorted by change time, using a regular expression | |
local CMD | |
set CMD=es %pathTrimPrefix /n %@eval[%MAX-%lastindex] /ad /sort date-accessed /r | |
set success=%@execarray[searchResults,%CMD %match] | |
iff %success ne 0 gosub Error "Everything Error: %cmd %match" | |
rem _EXECARRAY is count of how many lines gathered, dec for index | |
set count=%@dec[%_EXECARRAY] | |
rem If there is only 1 match, and we have not found any matches before, cd directly to it | |
iff %count eq 0 .and. %lastindex eq 0 .and. "%searchResults[0]" ne "%_CWD" then | |
__CD[0]="%searchResults[0]" | |
goto END | |
endiff | |
rem do is inclusive '0 to 0' runs once | |
do index = 0 to %count ( | |
rem store this iteration of the result to the global directory list | |
local directory, label | |
set directory=%searchResults[%index] | |
rem if there was a subirectory matching prefix, convert it to .\ | |
if "%pathTrimPrefix" ne "" set label=%@replace[%pathTrimPrefix,.,%directory] | |
if %label eq . iterate | |
set directories[%lastindex]="%directory" | |
set lastindex=%@inc[%lastindex] | |
rem pretty version for dialog | |
set width=%@eval[%_COLUMNS-15] | |
set label=%directory | |
iff %@len[%directory] ge %width then | |
set label=...%@right[%@eval[%width],%directory] | |
endiff | |
rem echo %label | |
set line= #r#n"%@formatn[2.0,%lastindex]" "%label" | |
set listing=%[listing]%[line] | |
rem if no more room, leave the loop | |
if %lastindex ge %MAX leave | |
) | |
return | |
rem clean up, change dir if appropriate | |
:END | |
on errormsg | |
on break | |
unsetarray directories searchResults | |
*del /kfq %tmpfile | |
chcp %pushcp >nul: | |
endlocal | |
rem uh... yeah. | |
iff "%__CD[0]" ne "" then | |
pushd %__CD[0] | |
rem echos cd %__CD[0] | |
rem toast /duration=1 /expire=1 /audiostate=1 /template=4 /text1="%_CWD" | |
endiff | |
unsetarray __CD | |
quit | |
:Error [message] | |
echo Error: %@unquote[%message] | |
goto END | |
:Usage | |
local cds | |
set cds=%~n0 | |
type << EndUsage | |
usage: | |
%cds: [/g #| /?] search-string | |
search-string can contain spaces without quotes or path seperator | |
%cds program files (spaces gathered to single argument) | |
%cds windows\sys (works as expected. '\' escaped in regex) | |
%cds progr.* .x86 (can contain any regex) | |
%cds "windows m(ail|edia)" (double quotes because of | pipe) | |
%cds \Pro.*/(x86/) (anti-*nix: escape regex chars with '/') | |
/g: search globally instead of just subdirectories of _CWD | |
/?: this help | |
to use 'dialog' text menu system, get source or binary from: | |
http://andrear.altervista.org/home/cdialog.php | |
EndUsage | |
goto END |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment