From 14ad9a813ba64b9b7662507ac4441f6dc36222da Mon Sep 17 00:00:00 2001 From: Sathiyaraman M Date: Sun, 1 Mar 2026 11:48:46 +0530 Subject: [PATCH 1/4] Support highlighting for C# project files Includes highlighting for csproj, props and targets files --- extension.toml | 5 + languages/csproj/config.toml | 9 ++ languages/csproj/highlights.scm | 168 ++++++++++++++++++++++++++++++++ languages/csproj/indents.scm | 2 + languages/csproj/outline.scm | 9 ++ 5 files changed, 193 insertions(+) create mode 100644 languages/csproj/config.toml create mode 100644 languages/csproj/highlights.scm create mode 100644 languages/csproj/indents.scm create mode 100644 languages/csproj/outline.scm diff --git a/extension.toml b/extension.toml index cbed3a0..85fbb70 100644 --- a/extension.toml +++ b/extension.toml @@ -20,3 +20,8 @@ language = "CSharp" [grammars.c_sharp] repository = "https://github.com/tree-sitter/tree-sitter-c-sharp" commit = "485f0bae0274ac9114797fc10db6f7034e4086e3" + +[grammars.xml] +repository = "https://github.com/tree-sitter-grammars/tree-sitter-xml" +commit = "863dbc381f44f6c136a399e684383b977bb2beaa" +path = "xml" diff --git a/languages/csproj/config.toml b/languages/csproj/config.toml new file mode 100644 index 0000000..62c00a2 --- /dev/null +++ b/languages/csproj/config.toml @@ -0,0 +1,9 @@ +name = "C# Project File" +grammar = "xml" +path_suffixes = ["csproj", "props", "targets"] +block_comment = [""] +autoclose_before = "<" +brackets = [{ start = "<", end = ">", close = true, newline = true }] +prettier_parser_name = "xml" +prettier_plugins = ["@prettier/plugin-xml"] +hard_tabs = true \ No newline at end of file diff --git a/languages/csproj/highlights.scm b/languages/csproj/highlights.scm new file mode 100644 index 0000000..c14be81 --- /dev/null +++ b/languages/csproj/highlights.scm @@ -0,0 +1,168 @@ +;; XML declaration + +"xml" @keyword + +[ "version" "encoding" "standalone" ] @property + +(EncName) @string.special + +(VersionNum) @number + +[ "yes" "no" ] @boolean + +;; Processing instructions + +(PI) @embedded + +(PI (PITarget) @keyword) + +;; Element declaration + +(elementdecl + "ELEMENT" @keyword + (Name) @tag) + +(contentspec + (_ (Name) @property)) + +"#PCDATA" @type.builtin + +[ "EMPTY" "ANY" ] @string.special.symbol + +[ "*" "?" "+" ] @operator + +;; Entity declaration + +(GEDecl + "ENTITY" @keyword + (Name) @constant) + +(GEDecl (EntityValue) @string) + +(NDataDecl + "NDATA" @keyword + (Name) @label) + +;; Parsed entity declaration + +(PEDecl + "ENTITY" @keyword + "%" @operator + (Name) @constant) + +(PEDecl (EntityValue) @string) + +;; Notation declaration + +(NotationDecl + "NOTATION" @keyword + (Name) @constant) + +(NotationDecl + (ExternalID + (SystemLiteral (URI) @string.special))) + +;; Attlist declaration + +(AttlistDecl + "ATTLIST" @keyword + (Name) @tag) + +(AttDef (Name) @property) + +(AttDef (Enumeration (Nmtoken) @string)) + +(DefaultDecl (AttValue) @string) + +[ + (StringType) + (TokenizedType) +] @type.builtin + +(NotationType "NOTATION" @type.builtin) + +[ + "#REQUIRED" + "#IMPLIED" + "#FIXED" +] @attribute + +;; Entities + +(EntityRef) @constant + +((EntityRef) @constant.builtin + (#any-of? @constant.builtin + "&" "<" ">" """ "'")) + +(CharRef) @constant + +(PEReference) @constant + +;; External references + +[ "PUBLIC" "SYSTEM" ] @keyword + +(PubidLiteral) @string.special + +(SystemLiteral (URI) @markup.link) + +;; Processing instructions + +(XmlModelPI "xml-model" @keyword) + +(StyleSheetPI "xml-stylesheet" @keyword) + +(PseudoAtt (Name) @property) + +(PseudoAtt (PseudoAttValue) @string) + +;; Doctype declaration + +(doctypedecl "DOCTYPE" @keyword) + +(doctypedecl (Name) @type) + +;; Tags + +(STag (Name) @tag) + +(ETag (Name) @tag) + +(EmptyElemTag (Name) @tag) + +;; Attributes + +(Attribute (Name) @property) + +(Attribute (AttValue) @string) + +;; Delimiters & punctuation + +[ + "" + "" + "<" ">" + "" +] @punctuation.delimiter + +[ "(" ")" "[" "]" ] @punctuation.bracket + +[ "\"" "'" ] @punctuation.delimiter + +[ "," "|" "=" ] @operator + +;; Text + +(CharData) @markup + +(CDSect + (CDStart) @markup.heading + (CData) @markup.raw + "]]>" @markup.heading) + +;; Misc + +(Comment) @comment + +(ERROR) @error \ No newline at end of file diff --git a/languages/csproj/indents.scm b/languages/csproj/indents.scm new file mode 100644 index 0000000..febed05 --- /dev/null +++ b/languages/csproj/indents.scm @@ -0,0 +1,2 @@ +(STag ">" @end) @indent +(EmptyElemTag "/>" @end) @indent \ No newline at end of file diff --git a/languages/csproj/outline.scm b/languages/csproj/outline.scm new file mode 100644 index 0000000..601af71 --- /dev/null +++ b/languages/csproj/outline.scm @@ -0,0 +1,9 @@ +(element + (STag + (Name) @name)) @item + +(EmptyElemTag + (Name) @name) @item + +(doctypedecl + (Name) @name) @item \ No newline at end of file From 5b837e43e858b2aa411660aa7bd4e99cbb641d28 Mon Sep 17 00:00:00 2001 From: Sathiyaraman M Date: Sun, 1 Mar 2026 11:58:09 +0530 Subject: [PATCH 2/4] Split single grammar separately for each file type --- languages/csproj/config.toml | 2 +- languages/props/config.toml | 9 ++ languages/props/highlights.scm | 168 +++++++++++++++++++++++++++++++ languages/props/indents.scm | 2 + languages/props/outline.scm | 9 ++ languages/targets/config.toml | 9 ++ languages/targets/highlights.scm | 168 +++++++++++++++++++++++++++++++ languages/targets/indents.scm | 2 + languages/targets/outline.scm | 9 ++ 9 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 languages/props/config.toml create mode 100644 languages/props/highlights.scm create mode 100644 languages/props/indents.scm create mode 100644 languages/props/outline.scm create mode 100644 languages/targets/config.toml create mode 100644 languages/targets/highlights.scm create mode 100644 languages/targets/indents.scm create mode 100644 languages/targets/outline.scm diff --git a/languages/csproj/config.toml b/languages/csproj/config.toml index 62c00a2..502a10c 100644 --- a/languages/csproj/config.toml +++ b/languages/csproj/config.toml @@ -1,6 +1,6 @@ name = "C# Project File" grammar = "xml" -path_suffixes = ["csproj", "props", "targets"] +path_suffixes = ["csproj"] block_comment = [""] autoclose_before = "<" brackets = [{ start = "<", end = ">", close = true, newline = true }] diff --git a/languages/props/config.toml b/languages/props/config.toml new file mode 100644 index 0000000..9463048 --- /dev/null +++ b/languages/props/config.toml @@ -0,0 +1,9 @@ +name = "C# Props File" +grammar = "xml" +path_suffixes = ["props"] +block_comment = [""] +autoclose_before = "<" +brackets = [{ start = "<", end = ">", close = true, newline = true }] +prettier_parser_name = "xml" +prettier_plugins = ["@prettier/plugin-xml"] +hard_tabs = true \ No newline at end of file diff --git a/languages/props/highlights.scm b/languages/props/highlights.scm new file mode 100644 index 0000000..c14be81 --- /dev/null +++ b/languages/props/highlights.scm @@ -0,0 +1,168 @@ +;; XML declaration + +"xml" @keyword + +[ "version" "encoding" "standalone" ] @property + +(EncName) @string.special + +(VersionNum) @number + +[ "yes" "no" ] @boolean + +;; Processing instructions + +(PI) @embedded + +(PI (PITarget) @keyword) + +;; Element declaration + +(elementdecl + "ELEMENT" @keyword + (Name) @tag) + +(contentspec + (_ (Name) @property)) + +"#PCDATA" @type.builtin + +[ "EMPTY" "ANY" ] @string.special.symbol + +[ "*" "?" "+" ] @operator + +;; Entity declaration + +(GEDecl + "ENTITY" @keyword + (Name) @constant) + +(GEDecl (EntityValue) @string) + +(NDataDecl + "NDATA" @keyword + (Name) @label) + +;; Parsed entity declaration + +(PEDecl + "ENTITY" @keyword + "%" @operator + (Name) @constant) + +(PEDecl (EntityValue) @string) + +;; Notation declaration + +(NotationDecl + "NOTATION" @keyword + (Name) @constant) + +(NotationDecl + (ExternalID + (SystemLiteral (URI) @string.special))) + +;; Attlist declaration + +(AttlistDecl + "ATTLIST" @keyword + (Name) @tag) + +(AttDef (Name) @property) + +(AttDef (Enumeration (Nmtoken) @string)) + +(DefaultDecl (AttValue) @string) + +[ + (StringType) + (TokenizedType) +] @type.builtin + +(NotationType "NOTATION" @type.builtin) + +[ + "#REQUIRED" + "#IMPLIED" + "#FIXED" +] @attribute + +;; Entities + +(EntityRef) @constant + +((EntityRef) @constant.builtin + (#any-of? @constant.builtin + "&" "<" ">" """ "'")) + +(CharRef) @constant + +(PEReference) @constant + +;; External references + +[ "PUBLIC" "SYSTEM" ] @keyword + +(PubidLiteral) @string.special + +(SystemLiteral (URI) @markup.link) + +;; Processing instructions + +(XmlModelPI "xml-model" @keyword) + +(StyleSheetPI "xml-stylesheet" @keyword) + +(PseudoAtt (Name) @property) + +(PseudoAtt (PseudoAttValue) @string) + +;; Doctype declaration + +(doctypedecl "DOCTYPE" @keyword) + +(doctypedecl (Name) @type) + +;; Tags + +(STag (Name) @tag) + +(ETag (Name) @tag) + +(EmptyElemTag (Name) @tag) + +;; Attributes + +(Attribute (Name) @property) + +(Attribute (AttValue) @string) + +;; Delimiters & punctuation + +[ + "" + "" + "<" ">" + "" +] @punctuation.delimiter + +[ "(" ")" "[" "]" ] @punctuation.bracket + +[ "\"" "'" ] @punctuation.delimiter + +[ "," "|" "=" ] @operator + +;; Text + +(CharData) @markup + +(CDSect + (CDStart) @markup.heading + (CData) @markup.raw + "]]>" @markup.heading) + +;; Misc + +(Comment) @comment + +(ERROR) @error \ No newline at end of file diff --git a/languages/props/indents.scm b/languages/props/indents.scm new file mode 100644 index 0000000..febed05 --- /dev/null +++ b/languages/props/indents.scm @@ -0,0 +1,2 @@ +(STag ">" @end) @indent +(EmptyElemTag "/>" @end) @indent \ No newline at end of file diff --git a/languages/props/outline.scm b/languages/props/outline.scm new file mode 100644 index 0000000..601af71 --- /dev/null +++ b/languages/props/outline.scm @@ -0,0 +1,9 @@ +(element + (STag + (Name) @name)) @item + +(EmptyElemTag + (Name) @name) @item + +(doctypedecl + (Name) @name) @item \ No newline at end of file diff --git a/languages/targets/config.toml b/languages/targets/config.toml new file mode 100644 index 0000000..74d176b --- /dev/null +++ b/languages/targets/config.toml @@ -0,0 +1,9 @@ +name = "C# Targets File" +grammar = "xml" +path_suffixes = ["targets"] +block_comment = [""] +autoclose_before = "<" +brackets = [{ start = "<", end = ">", close = true, newline = true }] +prettier_parser_name = "xml" +prettier_plugins = ["@prettier/plugin-xml"] +hard_tabs = true \ No newline at end of file diff --git a/languages/targets/highlights.scm b/languages/targets/highlights.scm new file mode 100644 index 0000000..c14be81 --- /dev/null +++ b/languages/targets/highlights.scm @@ -0,0 +1,168 @@ +;; XML declaration + +"xml" @keyword + +[ "version" "encoding" "standalone" ] @property + +(EncName) @string.special + +(VersionNum) @number + +[ "yes" "no" ] @boolean + +;; Processing instructions + +(PI) @embedded + +(PI (PITarget) @keyword) + +;; Element declaration + +(elementdecl + "ELEMENT" @keyword + (Name) @tag) + +(contentspec + (_ (Name) @property)) + +"#PCDATA" @type.builtin + +[ "EMPTY" "ANY" ] @string.special.symbol + +[ "*" "?" "+" ] @operator + +;; Entity declaration + +(GEDecl + "ENTITY" @keyword + (Name) @constant) + +(GEDecl (EntityValue) @string) + +(NDataDecl + "NDATA" @keyword + (Name) @label) + +;; Parsed entity declaration + +(PEDecl + "ENTITY" @keyword + "%" @operator + (Name) @constant) + +(PEDecl (EntityValue) @string) + +;; Notation declaration + +(NotationDecl + "NOTATION" @keyword + (Name) @constant) + +(NotationDecl + (ExternalID + (SystemLiteral (URI) @string.special))) + +;; Attlist declaration + +(AttlistDecl + "ATTLIST" @keyword + (Name) @tag) + +(AttDef (Name) @property) + +(AttDef (Enumeration (Nmtoken) @string)) + +(DefaultDecl (AttValue) @string) + +[ + (StringType) + (TokenizedType) +] @type.builtin + +(NotationType "NOTATION" @type.builtin) + +[ + "#REQUIRED" + "#IMPLIED" + "#FIXED" +] @attribute + +;; Entities + +(EntityRef) @constant + +((EntityRef) @constant.builtin + (#any-of? @constant.builtin + "&" "<" ">" """ "'")) + +(CharRef) @constant + +(PEReference) @constant + +;; External references + +[ "PUBLIC" "SYSTEM" ] @keyword + +(PubidLiteral) @string.special + +(SystemLiteral (URI) @markup.link) + +;; Processing instructions + +(XmlModelPI "xml-model" @keyword) + +(StyleSheetPI "xml-stylesheet" @keyword) + +(PseudoAtt (Name) @property) + +(PseudoAtt (PseudoAttValue) @string) + +;; Doctype declaration + +(doctypedecl "DOCTYPE" @keyword) + +(doctypedecl (Name) @type) + +;; Tags + +(STag (Name) @tag) + +(ETag (Name) @tag) + +(EmptyElemTag (Name) @tag) + +;; Attributes + +(Attribute (Name) @property) + +(Attribute (AttValue) @string) + +;; Delimiters & punctuation + +[ + "" + "" + "<" ">" + "" +] @punctuation.delimiter + +[ "(" ")" "[" "]" ] @punctuation.bracket + +[ "\"" "'" ] @punctuation.delimiter + +[ "," "|" "=" ] @operator + +;; Text + +(CharData) @markup + +(CDSect + (CDStart) @markup.heading + (CData) @markup.raw + "]]>" @markup.heading) + +;; Misc + +(Comment) @comment + +(ERROR) @error \ No newline at end of file diff --git a/languages/targets/indents.scm b/languages/targets/indents.scm new file mode 100644 index 0000000..febed05 --- /dev/null +++ b/languages/targets/indents.scm @@ -0,0 +1,2 @@ +(STag ">" @end) @indent +(EmptyElemTag "/>" @end) @indent \ No newline at end of file diff --git a/languages/targets/outline.scm b/languages/targets/outline.scm new file mode 100644 index 0000000..601af71 --- /dev/null +++ b/languages/targets/outline.scm @@ -0,0 +1,9 @@ +(element + (STag + (Name) @name)) @item + +(EmptyElemTag + (Name) @name) @item + +(doctypedecl + (Name) @name) @item \ No newline at end of file From 8e5fee8edadae1691f3fbcf630ea6efca666f712 Mon Sep 17 00:00:00 2001 From: Sathiyaraman M Date: Sun, 1 Mar 2026 11:58:32 +0530 Subject: [PATCH 3/4] Support highlighting for slnx files --- languages/slnx/config.toml | 9 ++ languages/slnx/highlights.scm | 168 ++++++++++++++++++++++++++++++++++ languages/slnx/indents.scm | 2 + languages/slnx/outline.scm | 9 ++ 4 files changed, 188 insertions(+) create mode 100644 languages/slnx/config.toml create mode 100644 languages/slnx/highlights.scm create mode 100644 languages/slnx/indents.scm create mode 100644 languages/slnx/outline.scm diff --git a/languages/slnx/config.toml b/languages/slnx/config.toml new file mode 100644 index 0000000..fa3fffd --- /dev/null +++ b/languages/slnx/config.toml @@ -0,0 +1,9 @@ +name = "C# Solution File" +grammar = "xml" +path_suffixes = ["slnx"] +block_comment = [""] +autoclose_before = "<" +brackets = [{ start = "<", end = ">", close = true, newline = true }] +prettier_parser_name = "xml" +prettier_plugins = ["@prettier/plugin-xml"] +hard_tabs = true \ No newline at end of file diff --git a/languages/slnx/highlights.scm b/languages/slnx/highlights.scm new file mode 100644 index 0000000..c14be81 --- /dev/null +++ b/languages/slnx/highlights.scm @@ -0,0 +1,168 @@ +;; XML declaration + +"xml" @keyword + +[ "version" "encoding" "standalone" ] @property + +(EncName) @string.special + +(VersionNum) @number + +[ "yes" "no" ] @boolean + +;; Processing instructions + +(PI) @embedded + +(PI (PITarget) @keyword) + +;; Element declaration + +(elementdecl + "ELEMENT" @keyword + (Name) @tag) + +(contentspec + (_ (Name) @property)) + +"#PCDATA" @type.builtin + +[ "EMPTY" "ANY" ] @string.special.symbol + +[ "*" "?" "+" ] @operator + +;; Entity declaration + +(GEDecl + "ENTITY" @keyword + (Name) @constant) + +(GEDecl (EntityValue) @string) + +(NDataDecl + "NDATA" @keyword + (Name) @label) + +;; Parsed entity declaration + +(PEDecl + "ENTITY" @keyword + "%" @operator + (Name) @constant) + +(PEDecl (EntityValue) @string) + +;; Notation declaration + +(NotationDecl + "NOTATION" @keyword + (Name) @constant) + +(NotationDecl + (ExternalID + (SystemLiteral (URI) @string.special))) + +;; Attlist declaration + +(AttlistDecl + "ATTLIST" @keyword + (Name) @tag) + +(AttDef (Name) @property) + +(AttDef (Enumeration (Nmtoken) @string)) + +(DefaultDecl (AttValue) @string) + +[ + (StringType) + (TokenizedType) +] @type.builtin + +(NotationType "NOTATION" @type.builtin) + +[ + "#REQUIRED" + "#IMPLIED" + "#FIXED" +] @attribute + +;; Entities + +(EntityRef) @constant + +((EntityRef) @constant.builtin + (#any-of? @constant.builtin + "&" "<" ">" """ "'")) + +(CharRef) @constant + +(PEReference) @constant + +;; External references + +[ "PUBLIC" "SYSTEM" ] @keyword + +(PubidLiteral) @string.special + +(SystemLiteral (URI) @markup.link) + +;; Processing instructions + +(XmlModelPI "xml-model" @keyword) + +(StyleSheetPI "xml-stylesheet" @keyword) + +(PseudoAtt (Name) @property) + +(PseudoAtt (PseudoAttValue) @string) + +;; Doctype declaration + +(doctypedecl "DOCTYPE" @keyword) + +(doctypedecl (Name) @type) + +;; Tags + +(STag (Name) @tag) + +(ETag (Name) @tag) + +(EmptyElemTag (Name) @tag) + +;; Attributes + +(Attribute (Name) @property) + +(Attribute (AttValue) @string) + +;; Delimiters & punctuation + +[ + "" + "" + "<" ">" + "" +] @punctuation.delimiter + +[ "(" ")" "[" "]" ] @punctuation.bracket + +[ "\"" "'" ] @punctuation.delimiter + +[ "," "|" "=" ] @operator + +;; Text + +(CharData) @markup + +(CDSect + (CDStart) @markup.heading + (CData) @markup.raw + "]]>" @markup.heading) + +;; Misc + +(Comment) @comment + +(ERROR) @error \ No newline at end of file diff --git a/languages/slnx/indents.scm b/languages/slnx/indents.scm new file mode 100644 index 0000000..febed05 --- /dev/null +++ b/languages/slnx/indents.scm @@ -0,0 +1,2 @@ +(STag ">" @end) @indent +(EmptyElemTag "/>" @end) @indent \ No newline at end of file diff --git a/languages/slnx/outline.scm b/languages/slnx/outline.scm new file mode 100644 index 0000000..601af71 --- /dev/null +++ b/languages/slnx/outline.scm @@ -0,0 +1,9 @@ +(element + (STag + (Name) @name)) @item + +(EmptyElemTag + (Name) @name) @item + +(doctypedecl + (Name) @name) @item \ No newline at end of file From 625a6e8091dc4baac39ef2a8f0306983c00acf45 Mon Sep 17 00:00:00 2001 From: Sathiyaraman M Date: Sun, 1 Mar 2026 11:58:49 +0530 Subject: [PATCH 4/4] Add tasks for csproj and slnx files --- languages/csproj/tasks.json | 24 ++++++++++++++++++++++++ languages/slnx/tasks.json | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 languages/csproj/tasks.json create mode 100644 languages/slnx/tasks.json diff --git a/languages/csproj/tasks.json b/languages/csproj/tasks.json new file mode 100644 index 0000000..d436a87 --- /dev/null +++ b/languages/csproj/tasks.json @@ -0,0 +1,24 @@ +[ + { + "label": "Restore Current Project", + "command": "dotnet restore", + "args": ["$ZED_FILE"], + "use_new_terminal": false, + "allow_concurrent_runs": false, + "reveal": "always", + "reveal_target": "center", + "hide": "on_success", + "shell": "system" + }, + { + "label": "Build Current Project", + "command": "dotnet build", + "args": ["$ZED_FILE"], + "use_new_terminal": false, + "allow_concurrent_runs": false, + "reveal": "always", + "reveal_target": "center", + "hide": "on_success", + "shell": "system" + } +] diff --git a/languages/slnx/tasks.json b/languages/slnx/tasks.json new file mode 100644 index 0000000..d39c312 --- /dev/null +++ b/languages/slnx/tasks.json @@ -0,0 +1,24 @@ +[ + { + "label": "Restore Current Solution", + "command": "dotnet restore", + "args": ["$ZED_FILE"], + "use_new_terminal": false, + "allow_concurrent_runs": false, + "reveal": "always", + "reveal_target": "center", + "hide": "on_success", + "shell": "system" + }, + { + "label": "Build Current Solution", + "command": "dotnet build", + "args": ["$ZED_FILE"], + "use_new_terminal": false, + "allow_concurrent_runs": false, + "reveal": "always", + "reveal_target": "center", + "hide": "on_success", + "shell": "system" + } +]