chrisant996 / clink

Bash's powerful command line editing in cmd.exe
https://chrisant996.github.io/clink/
GNU General Public License v3.0
3.44k stars 135 forks source link

Change color for cmd command? #613

Closed vict0rfr closed 3 months ago

vict0rfr commented 3 months ago

When I run the cmd /C "commands here" command, the text in the quotes is red, which is very misleading because it is not an error, how can I change the color for whatever is in the quotes?

chrisant996 commented 3 months ago

What is the specific text in "commands here"?

I'm guessing that it isn't a program, and instead it's a CMD command like if ... or for ... do ... or etc?

vict0rfr commented 3 months ago

"c:\Users\victo.vscode\extensions\ms-vscode.cpptools-1.20.5-win32-x64\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-cjnjhnqy.ovv --stdout=Microsoft-MIEngine-Out-mxax5mwy.zip --stderr=Microsoft-MIEngine-Error-ka2yim3k.5no --pid=Microsoft-MIEngine-Pid-jfms5ffr.104 --dbgExe=C:\msys64\ucrt64\bin\gdb.exe --interpreter=mi" This. When I run c++ files.

chrisant996 commented 3 months ago

Ah ok, thanks.

The issue here isn't the color, it's the parser that's running on the text after cmd /c.

(Interestingly, in the cited example, the quotes aren't needed. But the parser needs to better handle when quotes are present.)

The problem in the parser is that CMD can end up treating cmd /c "..." two different ways depending on what specific ... text is inside the quotes. It can end up getting treated as a quoted program name, or as a quoted command line.

I'll work on a fix.

You can clink set color.unrecognized clear, but of course that will also remove coloring from places where the input parser accurately recognized that the input isn't executable.

vict0rfr commented 3 months ago

Thank you for your support. clink set color.unrecognized clear will do for me. As I only use cmd /C in vscode.

chrisant996 commented 3 months ago

Yes, but I wanted to warn you that it affects more than just cmd /c.

chrisant996 commented 3 months ago
And here are some quirky cases: Command Line Behavior
echo hello & world Echoes "hello" and executes "world":
hello
'"world"' is not recognized...
"echo hello & world" Executes "echo hello & world":
'"echo hello & world"' is not recognized...
"echo hello" & world Executes "echo hello" and "world":
'"echo hello"' is not recognized...
'"world"' is not recognized...
cmd /c "echo hello" & world Echoes "hello" and executes "world.exe":
hello
'"world"' is not recognized...
cmd /c "echo hello & world" Echoes "hello" and executes "world.exe":
hello
'"world"' is not recognized...

This is because CMD has a bunch of special case rules for whether to strip a pair of quotes after /c, /k, and /r. Depending on how many quotes exist and what's between the quotes, CMD may or may not strip the first and last quotes.

That makes it quite difficult to accurately parse an input line that contains cmd followed by /cor/kor/r` (or an alias that expands to that). I intend to try...

chrisant996 commented 3 months ago

It's way too convoluted to try to parse all the edge case and nested weirdnesses.

So instead, I've made it simply disable input line coloring by argmatchers for the rest of the line if the next thing after /C or /K or /R is a quote.

(It doesn't disable all input line coloring, it just applies the color.input color to the rest of the line, and prevents argmatchers from applying further colors. But other things can still apply coloring past that point; for example history expansion will still apply coloring past that point. This is a very nice compromise which achieves exactly what's desired the vast majority of the time.)