Skip to content

Commit 04350a0

Browse files
authored
Merge pull request #17 from cjodo/dev
Fixes #16
2 parents e55d6a7 + 3646b07 commit 04350a0

File tree

4 files changed

+169
-109
lines changed

4 files changed

+169
-109
lines changed

lua/convert/convert_all.lua

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,21 @@ local convert_all = function(bufnr, from, to)
2222
end
2323

2424
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
25-
26-
local num_lines = #lines
27-
local start_row = 1
28-
29-
local selection = utils.get_selection()
30-
31-
if selection ~= nil then
32-
start_row = selection.start_row
33-
num_lines = #selection.lines
34-
end
35-
36-
for row = start_row, num_lines + start_row - 1, 1 do
37-
local line = lines[row]
38-
local found_unit = utils.find_unit_in_line(line, row)
39-
40-
if found_unit ~= nil and found_unit.unit == from then
41-
local converted = calculator.convert(from, to, found_unit.val)
42-
43-
vim.api.nvim_buf_set_text(
44-
bufnr,
45-
found_unit.pos.row - 1,
46-
found_unit.pos.start_col - 1,
47-
found_unit.pos.row - 1,
48-
found_unit.pos.end_col,
49-
{ converted })
25+
local all_units = utils.find_all_units_in_line(line, row)
26+
if all_units ~= nil and #all_units > 0 and all_units[1].unit == from then
27+
for i = #all_units, 1, -1 do
28+
local found = all_units[i]
29+
local converted = calculator.convert(from, to, found.val)
30+
31+
vim.api.nvim_buf_set_text(
32+
bufnr,
33+
found.pos.row - 1,
34+
found.pos.start_col - 1,
35+
found.pos.row - 1,
36+
found.pos.end_col,
37+
{ converted }
38+
)
39+
end
5040
end
5141
end
5242
end

lua/convert/init.lua

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ M.find_next = function()
2525

2626
for row = next_row, #lines, 1 do
2727
local line = lines[row]
28-
local found_unit = utils.find_unit_in_line(line, row)
28+
local found_units = utils.find_all_units_in_line(line, row)
2929

3030

31-
if found_unit ~= nil then
32-
vim.api.nvim_win_set_cursor(current_win, { row, found_unit.pos.start_col - 1 })
33-
ui.open_win(found_unit)
31+
if found_units ~= nil then
32+
vim.api.nvim_win_set_cursor(current_win, { row, found_units[1].pos.start_col - 1 })
33+
ui.open_win(found_units)
3434
return
3535
end
3636
end
@@ -46,11 +46,11 @@ M.find_current = function()
4646

4747
line = string.rep(" ", #current_line - #line) .. line
4848

49-
local found_unit = utils.find_unit_in_line(line, cursor_pos.row)
49+
local found_units = utils.find_all_units_in_line(line, cursor_pos.row)
5050

51-
if found_unit ~= nil then
52-
vim.api.nvim_win_set_cursor(current_win, { cursor_pos.row, found_unit.pos.start_col - 1 })
53-
ui.open_win(found_unit)
51+
if found_units ~= nil and #found_units > 0 then
52+
vim.api.nvim_win_set_cursor(current_win, { cursor_pos.row, found_units[1].pos.start_col - 1 })
53+
ui.open_win(found_units)
5454
end
5555
end
5656

lua/convert/ui/open_popup.lua

Lines changed: 90 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@ local utils = require("convert.utils")
44
local config = require("convert.config")
55

66
local size_units = {
7-
'px',
8-
'rem',
9-
'cm',
10-
'in',
11-
'mm',
12-
'pt',
13-
'pc'
7+
'px',
8+
'rem',
9+
'cm',
10+
'in',
11+
'mm',
12+
'pt',
13+
'pc'
1414
}
1515

1616

1717
local color_units = {
18-
'rgb',
19-
'hex',
20-
'hsl'
18+
'rgb',
19+
'hex',
20+
'hsl'
2121
}
2222

2323
local number_units = {
@@ -27,19 +27,19 @@ local number_units = {
2727
}
2828

2929
local color_menu = {
30-
Menu.item('rgb'),
31-
Menu.item('hex'),
32-
Menu.item('hsl'),
30+
Menu.item('rgb'),
31+
Menu.item('hex'),
32+
Menu.item('hsl'),
3333
}
3434

3535
local size_menu = {
36-
Menu.item('px'),
37-
Menu.item('rem'),
38-
Menu.item('cm'),
39-
Menu.item('in'),
40-
Menu.item('mm'),
41-
Menu.item('pt'),
42-
Menu.item('pc'),
36+
Menu.item('px'),
37+
Menu.item('rem'),
38+
Menu.item('cm'),
39+
Menu.item('in'),
40+
Menu.item('mm'),
41+
Menu.item('pt'),
42+
Menu.item('pc'),
4343
}
4444

4545
local number_menu = {
@@ -48,66 +48,81 @@ local number_menu = {
4848
Menu.item('octal'),
4949
}
5050

51-
local M = {}
51+
--- Opens popup window for convert in a single line
52+
---@param found_units matched[]
53+
M.open_win = function(found_units)
54+
if not found_units or #found_units == 0 then return end
5255

53-
---@param found_unit matched
54-
M.open_win = function(found_unit)
55-
local lines = nil
56+
local from_unit = found_units[1].unit
57+
local from_val = found_units[1].val
5658

57-
if utils.contains(color_units, found_unit.unit) then
58-
lines = color_menu
59-
end
59+
local lines = nil
6060

61-
if utils.contains(size_units, found_unit.unit) then
62-
lines = size_menu
63-
end
64-
65-
if utils.contains(number_units, found_unit.unit) then
66-
lines = number_menu
61+
if utils.contains(color_units, from_unit) then
62+
lines = color_menu
63+
elseif utils.contains(size_units, from_unit) then
64+
lines = size_menu
65+
else
66+
return
6767
end
6868

69-
local popup_opts = {
70-
relative = "cursor",
71-
position = {
72-
row = 2,
73-
col = 1,
74-
},
75-
size = {
76-
width = 40,
77-
height = #lines,
78-
},
79-
border = {
80-
style = "rounded",
81-
text = {
82-
top = "[Convert " .. found_unit.val .. " " .. found_unit.unit .. " To]",
83-
top_align = "center"
84-
},
85-
},
86-
buf_options = {
87-
modifiable = false,
88-
readonly = true,
89-
},
90-
win_options = {
91-
winhighlight = "Normal:Normal"
92-
}
93-
}
94-
local menu = Menu(popup_opts, {
95-
lines = lines,
96-
97-
max_width = 100,
98-
keymap = config.keymaps,
99-
on_submit = function(item)
100-
local from_unit = found_unit.unit
101-
local to_unit = item.text
102-
local from_val = found_unit.val
103-
local converted = calculator.convert(from_unit, to_unit, from_val)
104-
vim.api.nvim_buf_set_text(0, found_unit.pos.row - 1, found_unit.pos.start_col - 1, found_unit.pos.row - 1, found_unit.pos.end_col,
105-
{ converted })
106-
vim.api.nvim_win_set_cursor(0, { found_unit.pos.row, found_unit.pos.end_col + #to_unit })
107-
end
108-
})
109-
110-
menu:mount()
69+
local popup_opts = {
70+
relative = "cursor",
71+
position = {
72+
row = 2,
73+
col = 1,
74+
},
75+
size = {
76+
width = 40,
77+
height = #lines,
78+
},
79+
border = {
80+
style = "rounded",
81+
text = {
82+
top = "[Convert " .. from_val .. " To]",
83+
top_align = "center"
84+
},
85+
},
86+
buf_options = {
87+
modifiable = false,
88+
readonly = true,
89+
},
90+
win_options = {
91+
winhighlight = "Normal:Normal"
92+
}
93+
}
94+
local menu = Menu(popup_opts, {
95+
lines = lines,
96+
97+
max_width = 100,
98+
keymap = config.keymaps,
99+
on_submit = function(item)
100+
local to_unit = item.text
101+
local bufnr = 0
102+
103+
for i = #found_units, 1, -1 do
104+
local match = found_units[i]
105+
if match.unit == from_unit then
106+
local converted = calculator.convert(from_unit, to_unit, match.val)
107+
vim.api.nvim_buf_set_text(
108+
bufnr,
109+
match.pos.row - 1,
110+
match.pos.start_col - 1,
111+
match.pos.row - 1,
112+
match.pos.end_col,
113+
{ converted }
114+
)
115+
end
116+
end
117+
118+
-- Move cursor to end of last converted unit
119+
local last = found_units[#found_units]
120+
vim.api.nvim_win_set_cursor(0, { last.pos.row, last.pos.end_col + #to_unit })
121+
end
122+
})
123+
124+
menu:mount()
125+
111126
end
112127

113128
return M

lua/convert/utils.lua

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,62 @@ M.match_unit = function(line)
5757
return nil
5858
end
5959

60-
---@return matched | nil
60+
61+
---@param line string
62+
---@param cursor_row number
63+
---@return matched[] | nil
64+
M.find_all_units_in_line = function(line, cursor_row)
65+
local results = {}
66+
local matched_unit = nil
67+
68+
for unit, pattern in pairs(units) do
69+
local start_pos = 1
70+
while start_pos <= #line do
71+
local s, e, val = string.find(line, pattern, start_pos)
72+
if s == nil then break end
73+
74+
if unit == 'rgb' or unit == 'hsl' then
75+
val = line:match(pattern, start_pos)
76+
end
77+
78+
local num_val = tonumber(val)
79+
if num_val then
80+
-- If this is the first unit match, set it as the inferred from_unit
81+
if not matched_unit then
82+
matched_unit = unit
83+
end
84+
85+
-- Only collect matches for the same inferred unit
86+
if unit == matched_unit then
87+
table.insert(results, {
88+
unit = unit,
89+
val = num_val,
90+
pos = {
91+
row = cursor_row,
92+
start_col = s,
93+
end_col = e,
94+
}
95+
})
96+
end
97+
end
98+
99+
start_pos = e + 1
100+
end
101+
102+
if matched_unit then
103+
break -- only process one unit type (inferred one)
104+
end
105+
end
106+
107+
if #results > 0 then
108+
return results
109+
end
110+
111+
return nil
112+
end
113+
114+
115+
---@return matched[] | nil
61116
M.find_unit_in_line = function(line, cursor_row)
62117
local unit = M.match_unit(line)
63118
if unit then

0 commit comments

Comments
 (0)