Skip to content

Commit 0fef5ac

Browse files
committed
feat: Repeat delimiters for add.
TODO: Repeat deletions, unit test stuff.
1 parent dca2e99 commit 0fef5ac

File tree

5 files changed

+54
-15
lines changed

5 files changed

+54
-15
lines changed

lua/nvim-surround/annotations.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
---@field left selection|nil
2020
---@field right selection|nil
2121

22+
-- TODO: Figure out a better name for this, since it's stupid for get_input to NOT return user_input
23+
---@class user_input
24+
---@field char string|nil
25+
---@field count integer
26+
2227
--[====================================================================================================================[
2328
Internal Options
2429
--]====================================================================================================================]

lua/nvim-surround/config.lua

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,13 @@ M.get_alias = function(char)
350350
end
351351

352352
-- Gets a delimiter pair for a user-inputted character.
353-
---@param char string|nil The user-given character.
353+
---@param user_input user_input The user-given character, and number of times to repeat the delimiters.
354354
---@param line_mode boolean Whether or not the delimiters should be put on new lines.
355355
---@return delimiter_pair|nil @A pair of delimiters for the given input, or nil if not applicable.
356356
---@nodiscard
357-
M.get_delimiters = function(char, line_mode)
358-
char = M.get_alias(char)
357+
M.get_delimiters = function(user_input, line_mode)
358+
local utils = require("nvim-surround.utils")
359+
local char = M.get_alias(user_input.char)
359360
-- Get the delimiters, using invalid_key_behavior if the add function is undefined for the character
360361
local delimiters = M.get_add(char)(char)
361362
if delimiters == nil then
@@ -378,7 +379,7 @@ M.get_delimiters = function(char, line_mode)
378379
table.insert(lhs, "")
379380
end
380381

381-
return { lhs, rhs }
382+
return utils.repeat_delimiters({ lhs, rhs }, user_input.count)
382383
end
383384

384385
-- Returns the add key for the surround associated with a given character, if one exists.
@@ -547,8 +548,7 @@ M.translate_opts = function(user_opts)
547548
local input = require("nvim-surround.input")
548549
local opts = {}
549550
for key, value in pairs(user_opts) do
550-
if key == "surrounds" then
551-
elseif key == "indent_lines" then
551+
if key == "indent_lines" then
552552
opts[key] = value or function() end
553553
else
554554
opts[key] = value

lua/nvim-surround/init.lua

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,9 @@ M.delete_callback = function()
328328
-- Save the current position of the cursor
329329
local curpos = buffer.get_curpos()
330330
-- Get a character input if not cached
331-
cache.delete.char = cache.delete.char or input.get_char()
331+
-- TODO: repeat deletions!
332+
local user_input = input.get_char()
333+
cache.delete.char = cache.delete.char or user_input.char
332334
if not cache.delete.char then
333335
return
334336
end
@@ -348,7 +350,8 @@ M.change_callback = function()
348350
-- Save the current position of the cursor
349351
local curpos = buffer.get_curpos()
350352
if not cache.change.del_char or not cache.change.add_delimiters then
351-
local del_char = config.get_alias(input.get_char())
353+
local user_input = input.get_char()
354+
local del_char = config.get_alias(user_input.char)
352355
local change = config.get_change(del_char)
353356
local selections = utils.get_nearest_selections(del_char, "change")
354357
if not (del_char and change and selections) then

lua/nvim-surround/input.lua

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,31 @@ M.replace_termcodes = function(char)
1414
end
1515

1616
-- Gets a character input from the user.
17-
---@return string|nil @The input character, or nil if an escape character is pressed.
17+
---@return user_input @The input character, or nil if an escape character is pressed, with optional count.
1818
---@nodiscard
1919
M.get_char = function()
20-
local ok, char = pcall(vim.fn.getcharstr)
21-
-- Return nil if input is cancelled (e.g. <C-c> or <Esc>)
22-
if not ok or char == "\27" then
23-
return nil
24-
end
25-
return M.replace_termcodes(char)
20+
local output = { count = nil, char = nil }
21+
22+
repeat
23+
local ok, char = pcall(vim.fn.getcharstr)
24+
-- Return nil if input is cancelled (e.g. <C-c> or <Esc>)
25+
if not ok or char == "\27" then
26+
return { count = 0, char = nil }
27+
end
28+
29+
local digit = tonumber(char)
30+
if digit then
31+
output.count = output.count == nil and 0 or output.count
32+
output.count = output.count * 10 + digit
33+
else
34+
output.char = M.replace_termcodes(char)
35+
end
36+
until output.char ~= nil
37+
38+
return {
39+
count = output.count == nil and 1 or output.count,
40+
char = output.char,
41+
}
2642
end
2743

2844
-- Gets a string input from the user.

lua/nvim-surround/utils.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ local M = {}
77
-- Do nothing.
88
M.NOOP = function() end
99

10+
-- Repeats a delimiter pair n times.
11+
---@param delimiters delimiter_pair The delimiters to be repeated.
12+
---@param n integer The number of times to repeat the delimiters.
13+
---@nodiscard
14+
M.repeat_delimiters = function(delimiters, n)
15+
local acc = { { "" }, { "" } }
16+
for _ = 1, n do
17+
acc[1][#acc[1]] = acc[1][#acc[1]] .. delimiters[1][1]
18+
vim.list_extend(acc[1], delimiters[1], 2)
19+
acc[2][#acc[2]] = acc[2][#acc[2]] .. delimiters[2][1]
20+
vim.list_extend(acc[2], delimiters[2], 2)
21+
end
22+
return acc
23+
end
24+
1025
-- Gets the nearest two selections for the left and right surrounding pair.
1126
---@param char string|nil A character representing what kind of surrounding pair is to be selected.
1227
---@param action "delete"|"change" A string representing what action is being performed.

0 commit comments

Comments
 (0)