ScintillaOrg / lexilla

A library of language lexers for use with Scintilla
https://www.scintilla.org/Lexilla.html
Other
163 stars 59 forks source link

PowerShell string embedded variables not highlighted correctly #254

Open realslacker opened 1 week ago

realslacker commented 1 week ago

In PowersShell you can use $($Expression) inside of quotes to execute code during string interpolation. Consider this valid PowerShell code example:

'$SomeVariable', $SomeOtherVariable
"$SomeVariable", $SomeOtherVariable
$SomeVariable.Replace('''"',''), $SomeOtherVariable
"$($SomeVariable.Replace('''"',''))", $SomeOtherVariable

Github formats the code as expected, however Notepad++ which uses the current version (532) of lexilla formats the code as shown:

image

Single quotes are handled correctly as variable expansion does not happen between single quotes, however double quotes should allow variable expansion and thus variables should be highlighted.

Finally, in the last example the $() structure should re-evaluate everything inside of the parenthesis as code. In the example it looks like the highlighter is interpreting the embedded quotation mark as the end of the string and the trailing single quote as the beginning of a new string.

zufuliu commented 1 week ago

Duplicate of https://sourceforge.net/p/scintilla/bugs/1761/

realslacker commented 1 week ago

@zufuliu maybe this should be two bugs, I believe that variables inside double quotes not being highlighted is also an issue worth resolving.

zufuliu commented 1 week ago

cc @mpheath, I think this can be fixed with following rough steps (not plan to work on this myself):

  1. Modernize the code (anonymous namespace, use C++ headers, nullptr, remove ctype, etc.).
  2. Convert the big if (sc.state) block to switch statement.
  3. Convert the lexer to a class (class LexerPowerShell final : public DefaultLexer).
  4. Highlight $() inside SCE_POWERSHELL_DEFAULT as operator.
  5. Highlight $() inside SCE_POWERSHELL_STRING and SCE_POWERSHELL_HERE_STRING, which is similar (allows new line and arbitrary expressions) to JavaScript ${}, so can reuse interpolatingAtEol and interpolatingStack from LexCPP.
  6. Highlight $var variables inside SCE_POWERSHELL_STRING and SCE_POWERSHELL_HERE_STRING.
  7. Highlight ${} variables inside SCE_POWERSHELL_DEFAULT, SCE_POWERSHELL_STRING and SCE_POWERSHELL_HERE_STRING.
  8. Highlight @var variables inside SCE_POWERSHELL_DEFAULT.
mpheath commented 1 week ago

not plan to work on this myself

@zufuliu I like basic string styling so I currently have a negative interest with the OP feature request.

zufuliu commented 1 week ago

I like basic string styling

How about configured with Bash like styling.inside.xxx properties?