ProgerXP / Notepad2e

Word highlighting, simultaneous editing, split views, math evaluation, un/grep, comment reformatting, UAC elevation, complete regexps (PCRE), Lua lexers, DPI awareness and more (XP+)
Other
370 stars 52 forks source link

Quoting commandline arguments #476

Open ProgerXP opened 7 months ago

ProgerXP commented 7 months ago

Hi, I'm using notepad2e with AstroGrep and there's one thing that really bothers me. It has an option to pass the highlighted string, but it fails with quoted strings. Can this be fixed on n2e's side?

Example: Notepad2e.exe /g 33,10 /m "class="red blue"" c:\ex.txt

Originally posted by @babanga in https://github.com/ProgerXP/Notepad2e/issues/413#issuecomment-1918335245

ProgerXP commented 7 months ago

Using quotes in Windows commandline is always tricky. You can't just pass the search text unchanged if you want it recognized as part of one argument:

v start of argument 
/m "class="red blue""
   ^ start of another argument (quoted)
    ^^^^^^ content
          ^ end of quoted string (allows spaces within)
           ^^^ part of content
              v space marks end of the argument since it's no longer quoted
/m "class="red blue""
               ^^^^ start of yet other argument and its content
                   ^ start of quoted part
                    ^ end of quoted part (i.e. empty quoted string)

As a result, you are passing 3 different arguments: /m, class=red and blue (note absence of quotes).

WinAPI doesn't have a function to parse the commandline so every program invents its own method, but if we take Paint as an example, you'll have to use this line to pass class="foo bar" literally:

mspaint "class="""part of first arg""""" second_arg

p

Naturally, Notepad2 has its own ExtractFirstArgument() that doesn't work that way but even if it did, AstroGrep isn't capable of properly quoting the argument it passes.

That said, the problem you've voiced is valid but the best (read, less dirty) solution I see is surrounding a complex argument with unique terminators, e.g. /m $class="red blue"$ file.txt, potentially long enough to ensure they don't appear literal in the argument's value (else we'd have to escape them, kinda going back to square one).