From fb56a4bb75121f4797d80e14bceee9feb870cfb2 Mon Sep 17 00:00:00 2001
From: Erasin Wang <erasinoo@gmail.com>
Date: Thu, 16 Mar 2023 05:22:24 +0800
Subject: [PATCH] Improve tree-sitter queries for vlang (#6279)

- Update hightlight
- add indents
- add textobject
- add injections
---
 book/src/generated/lang-support.md |   2 +-
 languages.toml                     |   4 +-
 runtime/queries/v/highlights.scm   | 159 ++++++++++++++++++++---------
 runtime/queries/v/indents.scm      |  17 +++
 runtime/queries/v/injections.scm   |   6 ++
 runtime/queries/v/textobjects.scm  |  27 +++++
 6 files changed, 161 insertions(+), 54 deletions(-)
 create mode 100644 runtime/queries/v/indents.scm
 create mode 100644 runtime/queries/v/injections.scm
 create mode 100644 runtime/queries/v/textobjects.scm

diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md
index 48cb66f1..8aefe581 100644
--- a/book/src/generated/lang-support.md
+++ b/book/src/generated/lang-support.md
@@ -140,7 +140,7 @@
 | typescript | ✓ | ✓ | ✓ | `typescript-language-server` |
 | ungrammar | ✓ |  |  |  |
 | uxntal | ✓ |  |  |  |
-| v | ✓ |  |  | `v` |
+| v | ✓ | ✓ | ✓ | `v` |
 | vala | ✓ |  |  | `vala-language-server` |
 | verilog | ✓ | ✓ |  | `svlangserver` |
 | vhs | ✓ |  |  |  |
diff --git a/languages.toml b/languages.toml
index 5afd36c9..42ebf154 100644
--- a/languages.toml
+++ b/languages.toml
@@ -1687,7 +1687,7 @@ source = { git = "https://github.com/6cdh/tree-sitter-scheme", rev = "c0741320bf
 [[language]]
 name = "v"
 scope = "source.v"
-file-types = ["v", "vv"]
+file-types = ["v", "vv", "vsh"]
 shebangs = ["v run"]
 roots = ["v.mod"]
 language-server = { command = "v", args = ["ls"] }
@@ -1697,7 +1697,7 @@ indent = { tab-width = 4, unit = "\t" }
 
 [[grammar]]
 name = "v"
-source = { git = "https://github.com/vlang/vls", subpath = "tree_sitter_v", rev = "3e8124ea4ab80aa08ec77f03df53f577902a0cdd" }
+source = { git = "https://github.com/vlang/vls", subpath = "tree_sitter_v", rev = "66cf9d3086fb5ecc827cb32c64c5d812ab17d2c6" }
 
 [[language]]
 name = "verilog"
diff --git a/runtime/queries/v/highlights.scm b/runtime/queries/v/highlights.scm
index c71245dc..e014b77d 100644
--- a/runtime/queries/v/highlights.scm
+++ b/runtime/queries/v/highlights.scm
@@ -14,71 +14,130 @@
 
 (field_identifier) @variable.other.member
 (selector_expression
+  operand: (identifier) @variable
   field: (identifier) @variable.other.member)
 
 (int_literal) @constant.numeric.integer
-(interpreted_string_literal) @string
-(rune_literal) @string
+
+(attribute_declaration) @attribute
+(comment) @comment
+[
+  (c_string_literal)
+  (raw_string_literal)
+  (interpreted_string_literal)
+  (string_interpolation)
+  (rune_literal)
+] @string
+
 (escape_sequence) @constant.character.escape
 
 [
-  (type_identifier)
-  (builtin_type)
   (pointer_type)
   (array_type)
 ] @type
 
-[
-  (identifier)
-  (module_identifier)
-  (import_path)
-] @variable
+(const_spec name: (identifier) @constant)
+(global_var_type_initializer name: (identifier) @constant)
+(global_var_spec name: (identifier) @constant)
+((identifier) @constant (#match? @constant "^[A-Z][A-Z\\d_]*$"))
+
 
 [
- "as"
- "asm"
- "assert"
- ;"atomic"
- ;"break"
- "const"
- ;"continue"
- "defer"
- "else"
- "enum"
- "fn"
- "for"
- "$for"
- "go"
- "goto"
- "if"
- "$if"
- "import"
- "in"
- "!in"
- "interface"
- "is"
- "!is"
- "lock"
- "match"
- "module"
- "mut"
- "or"
- "pub"
- "return"
- "rlock"
- "select"
- ;"shared"
- ;"static"
- "struct"
- "type"
- ;"union"
- "unsafe"
-] @keyword
+  (generic_type)
+  (type_identifier)
+] @constructor 
+
+(builtin_type) @type.builtin
 
 [
  (true)
  (false)
-] @boolean
+] @constant.builtin.boolean
+
+
+[
+  (module_identifier)
+  (import_path)
+] @namespace
+
+[
+  (pseudo_comptime_identifier)
+  (label_name)
+] @label
+
+[
+  (identifier)
+] @variable
+
+
+[
+  "pub"
+  "assert"
+  "go"
+  "asm"
+  "defer"
+  "unsafe"
+  "sql"
+  (none)
+] @keyword
+
+[
+  "interface"
+  "enum"
+  "type"
+  "union"
+  "struct"
+  "module"
+] @keyword.storage.type
+
+[
+  "static"
+  "const"
+  "__global"
+] @keyword.storage.modifier
+
+[
+  "mut"
+] @keyword.storage.modifier.mut
+
+[
+  "shared"
+  "lock"
+  "rlock"
+  "spawn"
+] @keyword.control
+
+[
+  "if"
+  "select"
+  "else"
+  "match"
+] @keyword.control.conditional
+
+[
+  "for"
+] @keyword.control.repeat
+
+[
+  "goto"
+  "return"
+] @keyword.control.return
+
+[
+  "fn"
+] @keyword.control.function
+
+
+[
+  "import"
+] @keyword.control.import
+
+[
+  "as"
+  "in"
+  "is"
+  "or"
+] @keyword.operator
 
 [
  "."
@@ -146,5 +205,3 @@
  ".."
  "..."
 ] @operator
-
-(comment) @comment
\ No newline at end of file
diff --git a/runtime/queries/v/indents.scm b/runtime/queries/v/indents.scm
new file mode 100644
index 00000000..5573d489
--- /dev/null
+++ b/runtime/queries/v/indents.scm
@@ -0,0 +1,17 @@
+[
+  (struct_declaration)
+  (function_declaration)
+  (if_expression)
+  (match_expression)
+  (expression_case)
+  (default_case)
+  (for_statement)
+  (unsafe_expression)
+  (short_var_declaration)
+] @indent
+
+[
+  "]"
+  ")"
+  "}"
+] @outdent
diff --git a/runtime/queries/v/injections.scm b/runtime/queries/v/injections.scm
new file mode 100644
index 00000000..f698de83
--- /dev/null
+++ b/runtime/queries/v/injections.scm
@@ -0,0 +1,6 @@
+((comment) @injection.content
+ (#set! injection.language "comment"))
+
+((sql_expression) @injection.content
+ (#set! injection.language "sql"))
+
diff --git a/runtime/queries/v/textobjects.scm b/runtime/queries/v/textobjects.scm
new file mode 100644
index 00000000..40eb101f
--- /dev/null
+++ b/runtime/queries/v/textobjects.scm
@@ -0,0 +1,27 @@
+(function_declaration
+  body: (block)? @function.inside) @function.around
+
+((function_declaration
+   name: (identifier) @_name
+   body: (block)? @test.inside) @test.around
+ (#match? @_name "^test"))
+
+(fn_literal
+  body: (block)? @function.inside) @function.around
+
+(parameter_list
+  ((_) @parameter.inside . ","? @parameter.around) @parameter.around)
+
+(call_expression
+  (argument_list
+    ((_) @parameter.inside) @parameter.around))
+
+(struct_declaration
+  (struct_field_declaration_list) @class.inside) @class.around
+
+(struct_field_declaration_list
+  ((_) @parameter.inside) @parameter.around)
+
+(comment) @comment.inside
+(comment)+ @comment.around
+