Skip to content

Commit

Permalink
Convert string concatenations to text blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
JojOatXGME committed Mar 30, 2024
1 parent 4c5b66e commit 85dd4c9
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 234 deletions.
43 changes: 22 additions & 21 deletions src/main/java/org/nixos/idea/settings/NixColorSettingsPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,27 +79,28 @@ public boolean isRainbowType(TextAttributesKey type) {

@Override
public @NonNls @NotNull String getDemoText() {
return "/* This code demonstrates the syntax highlighting for the Nix Expression Language */\n" +
"let\n" +
" <variable>literals</variable>.null = <literal>null</literal>;\n" +
" <variable>literals</variable>.boolean = <literal>true</literal>;\n" +
" <variable>literals</variable>.number = 42;\n" +
" <variable>literals</variable>.string1 = \"This is a normal string\";\n" +
" <variable>literals</variable>.string2 = ''\n" +
" Broken escape sequence: \\${<variable>literals</variable>.number}\n" +
" Escaped interpolation: ''${<variable>literals</variable>.number}\n" +
" Generic escape sequence: $''\\{<variable>literals</variable>.number}\n" +
" '';\n" +
" <variable>literals</variable>.paths = [/etc/gitconfig ~/.gitconfig .git/config];\n" +
" # Note that unquoted URIs were deperecated by RFC 45\n" +
" <variable>literals</variable>.uri = https://github.com/NixOS/rfcs/pull/45;\n" +
"in {\n" +
" inherit (<variable>literals</variable>) number string1 string2 paths uri;\n" +
" nixpkgs = <import>import</import> <nixpkgs>;\n" +
" baseNames = <builtin>map</builtin> <builtin>baseNameOf</builtin> <variable>literals</variable>.paths;\n" +
" f = { <parameter>multiply</parameter> ? 1, <parameter>add</parameter> ? 0, ... }@<parameter>args</parameter>:\n" +
" <builtin>builtins</builtin>.<builtin>mapAttrs</builtin> (<parameter>name</parameter>: <parameter>value</parameter>: <parameter>multiply</parameter> * <parameter>value</parameter> + <parameter>add</parameter>) <parameter>args</parameter>;\n" +
"}";
return """
/* This code demonstrates the syntax highlighting for the Nix Expression Language */
let
<variable>literals</variable>.null = <literal>null</literal>;
<variable>literals</variable>.boolean = <literal>true</literal>;
<variable>literals</variable>.number = 42;
<variable>literals</variable>.string1 = "This is a normal string";
<variable>literals</variable>.string2 = ''
Broken escape sequence: \\${<variable>literals</variable>.number}
Escaped interpolation: ''${<variable>literals</variable>.number}
Generic escape sequence: $''\\{<variable>literals</variable>.number}
'';
<variable>literals</variable>.paths = [/etc/gitconfig ~/.gitconfig .git/config];
# Note that unquoted URIs were deperecated by RFC 45
<variable>literals</variable>.uri = https://github.com/NixOS/rfcs/pull/45;
in {
inherit (<variable>literals</variable>) number string1 string2 paths uri;
nixpkgs = <import>import</import> <nixpkgs>;
baseNames = <builtin>map</builtin> <builtin>baseNameOf</builtin> <variable>literals</variable>.paths;
f = { <parameter>multiply</parameter> ? 1, <parameter>add</parameter> ? 0, ... }@<parameter>args</parameter>:
<builtin>builtins</builtin>.<builtin>mapAttrs</builtin> (<parameter>name</parameter>: <parameter>value</parameter>: <parameter>multiply</parameter> * <parameter>value</parameter> + <parameter>add</parameter>) <parameter>args</parameter>;
}""";
}

@Override
Expand Down
21 changes: 11 additions & 10 deletions src/test/java/org/nixos/idea/lang/LexerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ public final class LexerTest extends LexerTestCase {
public void testRestartabilityWithAntiquotations() {
// Checks that the lexer is restartable. See
// https://intellij-support.jetbrains.com/hc/en-us/community/posts/360010305800
checkCorrectRestart(
"''\n" +
" ${\n" +
" [\n" +
" \"pure string\",\n" +
" \"string with ${antiquotation}\",\n" +
" ''ind string with ${multiple} ${antiquotations}''\n" +
" ]\n" +
" }\n" +
"''\n");
checkCorrectRestart("""
''
${
[
"pure string",
"string with ${antiquotation}",
''ind string with ${multiple} ${antiquotations}''
]
}
''
""");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,135 +18,145 @@ public final class NixHighlightVisitorTest extends BasePlatformTestCase {

public void testSelectExpression() {
// TODO: Highlight x.y as a local variable
doTest("let\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName> = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.\"no-highlighting-for-string-attributes\" = some_value;\n" +
"in [\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y.z\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.z\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.\"no-highlighting-for-string-attributes\"\n" +
"]");
doTest("""
let
<symbolName type="LOCAL_VARIABLE">x</symbolName> = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>."no-highlighting-for-string-attributes" = some_value;
in [
<symbolName type="LOCAL_VARIABLE">x</symbolName>
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y.z
<symbolName type="LOCAL_VARIABLE">x</symbolName>.z
<symbolName type="LOCAL_VARIABLE">x</symbolName>."no-highlighting-for-string-attributes"
]""");
}

public void testInheritExpression() {
doTest("let\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName> = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">y</symbolName> = some_value;\n" +
"in {\n" +
" inherit <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>;\n" +
" inherit <symbolName type=\"LOCAL_VARIABLE\">x</symbolName> <symbolName type=\"LOCAL_VARIABLE\">y</symbolName>;\n" +
" inherit \"no-highlighting-for-string-attributes\";\n" +
" inherit ({}) not-a-variable;\n" +
"}");
doTest("""
let
<symbolName type="LOCAL_VARIABLE">x</symbolName> = some_value;
<symbolName type="LOCAL_VARIABLE">y</symbolName> = some_value;
in {
inherit <symbolName type="LOCAL_VARIABLE">x</symbolName>;
inherit <symbolName type="LOCAL_VARIABLE">x</symbolName> <symbolName type="LOCAL_VARIABLE">y</symbolName>;
inherit "no-highlighting-for-string-attributes";
inherit ({}) not-a-variable;
}""");
}

public void testBuiltins() {
doTest("[\n" +
" <symbolName type=\"LITERAL\">null</symbolName>\n" +
" <symbolName type=\"LITERAL\">true</symbolName>\n" +
" <symbolName type=\"LITERAL\">false</symbolName>\n" +
" <symbolName type=\"IMPORT\">import</symbolName>\n" +
" <symbolName type=\"BUILTIN\">map</symbolName>\n" +
" <symbolName type=\"BUILTIN\">builtins</symbolName>.<symbolName type=\"LITERAL\">null</symbolName>\n" +
" <symbolName type=\"BUILTIN\">builtins</symbolName>.<symbolName type=\"BUILTIN\">map</symbolName>\n" +
" <symbolName type=\"BUILTIN\">builtins</symbolName>.<symbolName type=\"BUILTIN\">compareVersions</symbolName>\n" +
" compareVersions\n" +
"]");
doTest("""
[
<symbolName type="LITERAL">null</symbolName>
<symbolName type="LITERAL">true</symbolName>
<symbolName type="LITERAL">false</symbolName>
<symbolName type="IMPORT">import</symbolName>
<symbolName type="BUILTIN">map</symbolName>
<symbolName type="BUILTIN">builtins</symbolName>.<symbolName type="LITERAL">null</symbolName>
<symbolName type="BUILTIN">builtins</symbolName>.<symbolName type="BUILTIN">map</symbolName>
<symbolName type="BUILTIN">builtins</symbolName>.<symbolName type="BUILTIN">compareVersions</symbolName>
compareVersions
]""");
}

public void testLetExpression() {
doTest("let\n" +
" inherit (some_value) \"no-highlighting-for-string-attributes\" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName> = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y.z = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.\"no-highlighting-for-string-attributes\" = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">copy</symbolName> = <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>;\n" +
"in [\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y.z\n" +
"]");
doTest("""
let
inherit (some_value) "no-highlighting-for-string-attributes" <symbolName type="LOCAL_VARIABLE">x</symbolName>;
<symbolName type="LOCAL_VARIABLE">x</symbolName> = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y.z = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>."no-highlighting-for-string-attributes" = some_value;
<symbolName type="LOCAL_VARIABLE">copy</symbolName> = <symbolName type="LOCAL_VARIABLE">x</symbolName>;
in [
<symbolName type="LOCAL_VARIABLE">x</symbolName>
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y.z
]""");
}

public void testLegacyLetExpression() {
doTest("let {\n" +
" inherit (some_value) \"no-highlighting-for-string-attributes\" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName> = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y.z = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.\"no-highlighting-for-string-attributes\" = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">body</symbolName> = [\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y.z\n" +
" ];\n" +
"}");
doTest("""
let {
inherit (some_value) "no-highlighting-for-string-attributes" <symbolName type="LOCAL_VARIABLE">x</symbolName>;
<symbolName type="LOCAL_VARIABLE">x</symbolName> = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y.z = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>."no-highlighting-for-string-attributes" = some_value;
<symbolName type="LOCAL_VARIABLE">body</symbolName> = [
<symbolName type="LOCAL_VARIABLE">x</symbolName>
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y.z
];
}""");
}

public void testRecursiveSet() {
doTest("rec {\n" +
" inherit (some_value) \"no-highlighting-for-string-attributes\" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName> = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y.z = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.\"no-highlighting-for-string-attributes\" = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">body</symbolName> = [\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y\n" +
" <symbolName type=\"LOCAL_VARIABLE\">x</symbolName>.y.z\n" +
" ];\n" +
"}");
doTest("""
rec {
inherit (some_value) "no-highlighting-for-string-attributes" <symbolName type="LOCAL_VARIABLE">x</symbolName>;
<symbolName type="LOCAL_VARIABLE">x</symbolName> = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y.z = some_value;
<symbolName type="LOCAL_VARIABLE">x</symbolName>."no-highlighting-for-string-attributes" = some_value;
<symbolName type="LOCAL_VARIABLE">body</symbolName> = [
<symbolName type="LOCAL_VARIABLE">x</symbolName>
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y
<symbolName type="LOCAL_VARIABLE">x</symbolName>.y.z
];
}""");
}

public void testNoHighlightingForNonRecursiveSet() {
doTest("{\n" +
" inherit (some_value) \"no-highlighting-for-string-attributes\" x;\n" +
" x = some_value;\n" +
" x.y = some_value;\n" +
" x.\"no-highlighting-for-string-attributes\" = some_value;\n" +
"}");
doTest("""
{
inherit (some_value) "no-highlighting-for-string-attributes" x;
x = some_value;
x.y = some_value;
x."no-highlighting-for-string-attributes" = some_value;
}""");
}

public void testLambda() {
doTest("<symbolName type=\"PARAMETER\">x</symbolName>:\n" +
"{<symbolName type=\"PARAMETER\">y</symbolName>}:\n" +
"<symbolName type=\"PARAMETER\">z</symbolName>@{<symbolName type=\"PARAMETER\">za</symbolName>, ...}: [\n" +
" <symbolName type=\"PARAMETER\">x</symbolName>\n" +
" <symbolName type=\"PARAMETER\">y</symbolName>\n" +
" <symbolName type=\"PARAMETER\">z</symbolName>\n" +
" <symbolName type=\"PARAMETER\">za</symbolName>\n" +
"]");
doTest("""
<symbolName type="PARAMETER">x</symbolName>:
{<symbolName type="PARAMETER">y</symbolName>}:
<symbolName type="PARAMETER">z</symbolName>@{<symbolName type="PARAMETER">za</symbolName>, ...}: [
<symbolName type="PARAMETER">x</symbolName>
<symbolName type="PARAMETER">y</symbolName>
<symbolName type="PARAMETER">z</symbolName>
<symbolName type="PARAMETER">za</symbolName>
]""");
}

public void testVariableHidesParameter() {
doTest("{<symbolName type=\"PARAMETER\">f</symbolName>, <symbolName type=\"PARAMETER\">hidden</symbolName>}: [\n" +
" <symbolName type=\"PARAMETER\">f</symbolName> <symbolName type=\"PARAMETER\">hidden</symbolName>\n" +
" (\n" +
" let <symbolName type=\"LOCAL_VARIABLE\">hidden</symbolName> = some_value;\n" +
" in <symbolName type=\"PARAMETER\">f</symbolName> <symbolName type=\"LOCAL_VARIABLE\">hidden</symbolName>\n" +
" )\n" +
" (let {\n" +
" <symbolName type=\"LOCAL_VARIABLE\">hidden</symbolName> = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">body</symbolName> = <symbolName type=\"PARAMETER\">f</symbolName> <symbolName type=\"LOCAL_VARIABLE\">hidden</symbolName>;\n" +
" })\n" +
" (rec {\n" +
" <symbolName type=\"LOCAL_VARIABLE\">hidden</symbolName> = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">body</symbolName> = <symbolName type=\"PARAMETER\">f</symbolName> <symbolName type=\"LOCAL_VARIABLE\">hidden</symbolName>;\n" +
" })\n" +
"]");
doTest("""
{<symbolName type="PARAMETER">f</symbolName>, <symbolName type="PARAMETER">hidden</symbolName>}: [
<symbolName type="PARAMETER">f</symbolName> <symbolName type="PARAMETER">hidden</symbolName>
(
let <symbolName type="LOCAL_VARIABLE">hidden</symbolName> = some_value;
in <symbolName type="PARAMETER">f</symbolName> <symbolName type="LOCAL_VARIABLE">hidden</symbolName>
)
(let {
<symbolName type="LOCAL_VARIABLE">hidden</symbolName> = some_value;
<symbolName type="LOCAL_VARIABLE">body</symbolName> = <symbolName type="PARAMETER">f</symbolName> <symbolName type="LOCAL_VARIABLE">hidden</symbolName>;
})
(rec {
<symbolName type="LOCAL_VARIABLE">hidden</symbolName> = some_value;
<symbolName type="LOCAL_VARIABLE">body</symbolName> = <symbolName type="PARAMETER">f</symbolName> <symbolName type="LOCAL_VARIABLE">hidden</symbolName>;
})
]""");
}

public void testParameterHidesVariable() {
doTest("let\n" +
" <symbolName type=\"LOCAL_VARIABLE\">f</symbolName> = some_value;\n" +
" <symbolName type=\"LOCAL_VARIABLE\">hidden</symbolName> = some_value;\n" +
"in\n" +
" <symbolName type=\"PARAMETER\">hidden</symbolName>:\n" +
" <symbolName type=\"LOCAL_VARIABLE\">f</symbolName> <symbolName type=\"PARAMETER\">hidden</symbolName>");
doTest("""
let
<symbolName type="LOCAL_VARIABLE">f</symbolName> = some_value;
<symbolName type="LOCAL_VARIABLE">hidden</symbolName> = some_value;
in
<symbolName type="PARAMETER">hidden</symbolName>:
<symbolName type="LOCAL_VARIABLE">f</symbolName> <symbolName type="PARAMETER">hidden</symbolName>""");
}

private void doTest(@NotNull String code) {
Expand Down

0 comments on commit 85dd4c9

Please sign in to comment.