Skip to content
This repository was archived by the owner on May 23, 2025. It is now read-only.

Commit f354654

Browse files
author
Cristhian Melo
committed
refactor(*): separate code
1 parent fbb916c commit f354654

File tree

5 files changed

+129
-98
lines changed

5 files changed

+129
-98
lines changed

lua/template-string.lua

Lines changed: 4 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,11 @@
1-
---@class TemplateStringConfig
2-
---@field jsx_brackets boolean | nil
3-
41
local M = {}
52

6-
local allowed_filetypes = {
7-
javascript = true,
8-
typescript = true,
9-
javascriptreact = true,
10-
typescriptreact = true,
11-
}
12-
13-
local function is_allowed_filetype()
14-
local filetype = vim.bo.filetype
15-
return allowed_filetypes[filetype] or false
16-
end
17-
18-
-- Function to wrap with {``} if inside a JSX/TSX component
19-
local function wrap_with_brackets_if_necessary(content)
20-
if content:find("%${") then
21-
return "={`" .. content .. "`}"
22-
else
23-
return '="' .. content .. '"'
24-
end
25-
end
26-
27-
-- Function to replace quotes in the current line
28-
local function replace_quotes_in_line()
29-
if not is_allowed_filetype() then
30-
return
31-
end
32-
33-
local row = vim.api.nvim_win_get_cursor(0)[1]
34-
local line = vim.api.nvim_buf_get_lines(0, row - 1, row, false)[1]
35-
36-
if not line then
37-
return
38-
end
39-
40-
local new_line = line
41-
42-
-- Replace quotes with backticks when ${ is found
43-
new_line = new_line:gsub("(['\"])(.-)%${(.-)}(.-)%1", function(quote, before, inside, after)
44-
return "`" .. before .. "${" .. inside .. "}" .. after .. "`"
45-
end)
46-
47-
if M.jsx_brackets then
48-
-- Wrap with {``} if inside a JSX/TSX component
49-
new_line = new_line:gsub("=%s*`([^`]*)`", wrap_with_brackets_if_necessary)
50-
51-
-- Revert backticks to original quotes if ${ is not found
52-
new_line = new_line:gsub("={[`{]+([^`]*)[`}]+}", function(content)
53-
if not content:find("%${") then
54-
-- Determine the original type of quotes, double or single
55-
local original_quote = line:match("=[\"']") and '"' or line:match("=['\"]") and "'" or '"'
56-
return "=" .. original_quote .. content .. original_quote
57-
end
58-
return "={" .. "`" .. content .. "`" .. "}"
59-
end)
60-
end
61-
62-
-- Also handle reverting solitary backticks on normal lines
63-
new_line = new_line:gsub("`([^`]*)`", function(content)
64-
if not content:find("%${") then
65-
-- Determine the original type of quotes, double or single
66-
local original_quote = line:match("[\"']") or '"'
67-
return original_quote .. content .. original_quote
68-
end
69-
return "`" .. content .. "`"
70-
end)
71-
72-
if new_line ~= line then
73-
vim.api.nvim_buf_set_lines(0, row - 1, row, false, { new_line })
74-
end
75-
end
76-
77-
-- Function to execute update with debounce
78-
local function debounce(fn, ms)
79-
local timer = vim.loop.new_timer()
80-
return function(...)
81-
timer:stop()
82-
local argv = { ... }
83-
timer:start(
84-
ms,
85-
0,
86-
vim.schedule_wrap(function()
87-
fn(unpack(argv))
88-
end)
89-
)
90-
end
91-
end
3+
local debounce = require("utils.debounce")
4+
local quotes = require("utils.replace_quotes")
925

936
--- Configures the plugin behavior.
94-
---@param opts TemplateStringConfig | nil Optional plugin configuration.
95-
function M.setup(opts)
96-
opts = opts or {}
97-
-- Enable brackets for JSX/TSX
98-
local jsx_brackets = opts.jsx_brackets == nil or opts.jsx_brackets
99-
M.jsx_brackets = jsx_brackets
100-
101-
-- Enable debounce
102-
local debounced_replace = debounce(replace_quotes_in_line, 100)
7+
function M.setup()
8+
local debounced_replace = debounce.debounce(quotes.replace_quotes_in_line, 100)
1039
vim.api.nvim_create_autocmd({ "TextChanged", "TextChangedI" }, {
10410
callback = debounced_replace,
10511
})

lua/utils/allowed_filetypes.lua

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
local vim = vim
2+
3+
local M = {}
4+
5+
local allowed_filetypes = {
6+
javascript = true,
7+
typescript = true,
8+
javascriptreact = true,
9+
typescriptreact = true,
10+
}
11+
12+
function M.is_allowed_filetype()
13+
local filetype = vim.bo.filetype
14+
return allowed_filetypes[filetype] or false
15+
end
16+
17+
return M

lua/utils/debounce.lua

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
local vim = vim
2+
3+
local M = {}
4+
5+
function M.debounce(fn, ms)
6+
local timer = vim.loop.new_timer()
7+
return function(...)
8+
timer:stop()
9+
local argv = { ... }
10+
timer:start(
11+
ms,
12+
0,
13+
vim.schedule_wrap(function()
14+
fn(unpack(argv))
15+
end)
16+
)
17+
end
18+
end
19+
20+
return M

lua/utils/react_utils.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
local ts = require("nvim-treesitter.ts_utils")
2+
3+
local M = {}
4+
5+
-- Función para verificar si el cursor está dentro de una prop de React
6+
function M.is_inside_react_opening_element()
7+
local node = ts.get_node_at_cursor()
8+
9+
if not node then
10+
return false
11+
end
12+
13+
-- Verificar si el nodo es un elemento de apertura JSX/TSX or prop
14+
if node:type() == "string" or node:type() == "template_string" then
15+
local prev_node = ts.get_previous_node(node)
16+
17+
if not prev_node then
18+
return false
19+
end
20+
21+
if prev_node:type() == "property_identifier" then
22+
return true
23+
end
24+
end
25+
26+
return false
27+
end
28+
29+
return M

lua/utils/replace_quotes.lua

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
local filetypes = require("utils.allowed_filetypes")
2+
local u = require("utils.react_utils")
3+
local M = {}
4+
5+
-- Reemplazar comillas por brackets y backticks cuando se encuentran "${}" en el valor de una prop. Ex. propName={'hello ${value}'}
6+
local function replace_quotes_with_backticks_and_brackets(line)
7+
-- Reemplazar comillas por backticks y brackets
8+
line = line:gsub("(['\"])(.-)%${(.-)}(.-)%1", function(_, before, inside, after)
9+
return "{`" .. before .. "${" .. inside .. "}" .. after .. "`}"
10+
end)
11+
12+
-- Also handle reverting solitary backticks on normal lines
13+
line = line:gsub("`([^`]*)`", function(content)
14+
if not content:find("%${") then
15+
local original_quote = line:match("[\"']") or '"'
16+
return original_quote .. content .. original_quote
17+
end
18+
return "`" .. content .. "`"
19+
end)
20+
21+
return line
22+
end
23+
24+
function M.replace_quotes_in_line()
25+
if not filetypes.is_allowed_filetype() then
26+
return
27+
end
28+
29+
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
30+
31+
local line = vim.api.nvim_buf_get_lines(0, row - 1, row, false)[1]
32+
local new_line = line
33+
34+
-- Check if inside a JSX/TSX element or opening element
35+
if u.is_inside_react_opening_element() then
36+
new_line = replace_quotes_with_backticks_and_brackets(new_line)
37+
else
38+
-- Replace quotes with backticks only when ${} is found
39+
new_line = new_line:gsub("(['\"])(.-)%${(.-)}(.-)%1", function(_, before, inside, after)
40+
return "`" .. before .. "${" .. inside .. "}" .. after .. "`"
41+
end)
42+
43+
-- Also handle reverting solitary backticks on normal lines
44+
new_line = new_line:gsub("`([^`]*)`", function(content)
45+
if not content:find("%${") then
46+
local original_quote = line:match("[\"']") or '"'
47+
return original_quote .. content .. original_quote
48+
end
49+
return "`" .. content .. "`"
50+
end)
51+
end
52+
53+
-- Update the buffer if there were changes
54+
if new_line ~= line then
55+
vim.api.nvim_buf_set_lines(0, row - 1, row, false, { new_line })
56+
end
57+
end
58+
59+
return M

0 commit comments

Comments
 (0)