diff --git a/lua/tailwind-tools/classes.lua b/lua/tailwind-tools/classes.lua index c6229e6..4b82010 100644 --- a/lua/tailwind-tools/classes.lua +++ b/lua/tailwind-tools/classes.lua @@ -19,7 +19,7 @@ M.get_ranges = function(bufnr) end if vim.tbl_contains(query_list, ft) then - vim.list_extend(results, tresitter.find_class_ranges(bufnr, ft) or {}) + vim.list_extend(results, tresitter.find_class_ranges(bufnr, ft)) end return results diff --git a/lua/tailwind-tools/filetypes.lua b/lua/tailwind-tools/filetypes.lua index 5b476e6..713040b 100644 --- a/lua/tailwind-tools/filetypes.lua +++ b/lua/tailwind-tools/filetypes.lua @@ -5,11 +5,14 @@ return { "php", "twig", "vue", - "svelte", - "astro", "heex", + "astro", + "templ", + "svelte", "elixir", "htmldjango", + "javascript", + "typescript", "javascriptreact", "typescriptreact", }, diff --git a/lua/tailwind-tools/treesitter.lua b/lua/tailwind-tools/treesitter.lua index ccf38d9..f410c15 100644 --- a/lua/tailwind-tools/treesitter.lua +++ b/lua/tailwind-tools/treesitter.lua @@ -28,32 +28,36 @@ local function find_class_nodes(bufnr, ft) end ---@param node TSNode ----@param bufnr number -local function get_class_range(node, bufnr) +local function get_class_range(node) local start_row, start_col, end_row, end_col = node:range() local children = node:named_children() - -- A special case for extracting postcss class range - if children[1] and vim.treesitter.get_node_text(children[1], bufnr) == "@apply" then + -- PostCSS @apply rules + if children[1] and children[1]:type() == "at_keyword" then start_row, start_col, _, _ = children[2]:range() _, _, end_row, end_col = children[#children]:range() end + -- JS/TS function arguments + if node:type() == "arguments" then + start_row, start_col, _, _ = children[1]:range() + _, _, end_row, end_col = children[#children]:range() + end + return start_row, start_col, end_row, end_col end ---@param bufnr number ---@param ft string M.find_class_ranges = function(bufnr, ft) - local nodes = find_class_nodes(bufnr, ft) - - if not nodes then return end - local results = {} + local nodes = find_class_nodes(bufnr, ft) - for _, node in pairs(nodes) do - local sr, sc, er, ec = get_class_range(node, bufnr) - results[#results + 1] = { sr, sc, er, ec } + if nodes then + for _, node in pairs(nodes) do + local sr, sc, er, ec = get_class_range(node) + results[#results + 1] = { sr, sc, er, ec } + end end return results diff --git a/queries/javascript/class.scm b/queries/javascript/class.scm new file mode 100644 index 0000000..ad537b3 --- /dev/null +++ b/queries/javascript/class.scm @@ -0,0 +1,12 @@ +(call_expression + function: [ + (identifier) @ident (#any-of? @ident "clsx" "classnames" "tw" "css") + (member_expression + object: (identifier) @object-ident (#eq? @object-ident "tw")) + ] + arguments: [ + (arguments + (_)+) @tailwind ; the actual class range is extracted in the code + (template_string + (string_fragment) @tailwind) + ]) diff --git a/queries/templ/class.scm b/queries/templ/class.scm new file mode 100644 index 0000000..1f2129c --- /dev/null +++ b/queries/templ/class.scm @@ -0,0 +1 @@ +; inherits: html diff --git a/queries/tsx/class.scm b/queries/tsx/class.scm index 7bdbb2d..be5d2f0 100644 --- a/queries/tsx/class.scm +++ b/queries/tsx/class.scm @@ -1,10 +1,9 @@ (jsx_attribute (property_identifier) @_attribute_name - (#any-of? @_attribute_name "class" "className") + (#any-of? @_attribute_name "class" "className" "style" "css" "tw") [ (string (string_fragment) @tailwind) (jsx_expression - (template_string - (string_fragment) @tailwind)) + (_) @tailwind) ]) diff --git a/queries/typescript/class.scm b/queries/typescript/class.scm new file mode 100644 index 0000000..ff0ddfa --- /dev/null +++ b/queries/typescript/class.scm @@ -0,0 +1 @@ +; inherits: javascript diff --git a/tests/queries/javascript/test.js b/tests/queries/javascript/test.js new file mode 100644 index 0000000..203a66f --- /dev/null +++ b/tests/queries/javascript/test.js @@ -0,0 +1,4 @@ +clsx("p-4", "text-center"); +classnames("bg-red-500", "uppercase"); +tw`font-mono text-sm` +tw.input`border hover:border-black` diff --git a/tests/queries/javascript_spec.lua b/tests/queries/javascript_spec.lua new file mode 100644 index 0000000..6f52ec9 --- /dev/null +++ b/tests/queries/javascript_spec.lua @@ -0,0 +1,11 @@ +require("tests.queries.runner").test({ + name = "javascript", + provider = "treesitter", + file = "tests/queries/javascript/test.js", + ranges = { + { 0, 5, 0, 25 }, + { 1, 11, 1, 36 }, + { 2, 3, 2, 20 }, + { 3, 9, 3, 34 }, + }, +}) diff --git a/tests/queries/tsx_spec.lua b/tests/queries/tsx_spec.lua index 423c242..9312dcd 100644 --- a/tests/queries/tsx_spec.lua +++ b/tests/queries/tsx_spec.lua @@ -5,6 +5,6 @@ require("tests.queries.runner").test({ ranges = { { 6, 19, 7, 55 }, { 9, 24, 9, 47 }, - { 13, 33, 13, 45 }, + { 13, 24, 13, 46 }, }, }) diff --git a/tests/queries/vue_spec.lua b/tests/queries/vue_spec.lua index d3ea426..1c864b9 100644 --- a/tests/queries/vue_spec.lua +++ b/tests/queries/vue_spec.lua @@ -1,4 +1,4 @@ -local spec = { +require("tests.queries.runner").test({ name = "vue", provider = "treesitter", file = "tests/queries/vue/test.vue", @@ -7,6 +7,4 @@ local spec = { { 2, 16, 2, 43 }, { 4, 39, 4, 49 }, }, -} - -require("tests.queries.runner").test(spec) +})