Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Double escaping carets required with doskey macro using %cd% #280

Closed
adamkerz opened this issue Jan 14, 2015 · 4 comments
Closed

Double escaping carets required with doskey macro using %cd% #280

adamkerz opened this issue Jan 14, 2015 · 4 comments

Comments

@adamkerz
Copy link

In relation to this comment.

I finally got to the bottom of this - the $T fix was NOT the issue.

The carets escaping the percent signs must be shown in the doskey macros list, then all works fine:

D:\pe\home>doskey /macros
cd=cd $* $T call title ^%cd^%

In Windows without clink, both:

D:\pe\home>doskey cd=cd $* $T call title ^^%cd^^%

and

D:\pe\home>doskey cd=cd $* $T call title ^%cd^%

function the same but, with clink, only the first one changes the title to match the cwd. The second one always displays the cwd that you just changed FROM.

My workaround is just to double the carets but I guess that's a bit of a bug in clink's doskey implementation?

@mridgers
Copy link
Owner

I get slightly different behaviour to that that you've reported for a Clink-less cmd.exe. The "^^%cd^^%" verison always sets a title of "%cd%", which I would expect as the "^" has been escaped (with another "^"). Only the second version you've posted works as I've expect.

With Clink active the first variant is the same (title becomes "%cd%"). However the second one doesn't work as expected - the %cd% is expanded before the whole line is executed, hence it showing the directory you changed from. Clink should escape the % characters after expanding the macro.

Strange that we get different results - what version of Windows are you using?

@adamkerz
Copy link
Author

I just re-tested the above on Windows 7 (Microsoft Windows [Version 6.1.7601]) and am getting the same result. I DO have command line extensions enabled if that makes a different. I will also test tonight on Windows 8 at home and let you know my results there.

My results again for clarity (I was a bit confused for a second when re-reading my comment):
doskey cd=cd $* $T call title ^^%cd^^%
CMD only: sets title to the cwd, CLINK: sets title to the cwd

doskey cd=cd $* $T call title ^%cd^%
CMD only: sets title to the cwd, CLINK: sets title to the PREVIOUS cwd

None of the combinations resulted in the title being set to the string "%cd%"!

Curious indeed!

@mridgers
Copy link
Owner

Okay, I can reproduce this now - thanks for your patience.

When I tried previously I hadn't included the "call", so the results I was seeing where when setting the macro to "cd $* $t title ^%cd^%". Given "title" is an builtin command of cmd.exe I have no idea why "call title ^%cd^%" differs from "title ^%cd^%", but it does. Cmd.exe's a mysterious beast at times.

@mridgers
Copy link
Owner

I dug into this in some detail and found that's it is a little bit more complicated that it appears on the surface. I knew that it is conhost.exe that does that actual alias expansion inside a ReadConsoleW() call and not cmd.exe (this is why Clink has to emulate it as it hooks ReadConsoleW() calls). What I haven't realised is that when using separators like $T they are not returned by ReadConsoleW() as a single line but are instead split and returned a command at a time.

This is an important detail as it means %cd% is expanded differently compared to entering it all on a single line (because %X% expansion is done on the whole line prior to executing it unless the command is suffixed with "call"). This explains cmd.exe's spurious printing of the prompt when using the above macros - because it always prints the prompt prior to calling ReadConsoleW(), unaware it is actually in the middle of alias expansion.

I think the best way forward is to continue to expand a $T delimited alias as a single line but condition it such that it works as the same as cmd.exe.

Bonus note; cmd.exe doesn't handle "doskey cd=$t $t $t $t $t" very well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants