Skip to content

Commit ecd4d6b

Browse files
committed
fix: range commands
1 parent ea38606 commit ecd4d6b

8 files changed

Lines changed: 117 additions & 78 deletions

File tree

doc/tags

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
TextTransform.config text-transform.txt /*TextTransform.config*
2-
TextTransform.enable() text-transform.txt /*TextTransform.enable()*
32
TextTransform.get_visual_selection_details() text-transform.txt /*TextTransform.get_visual_selection_details()*
43
TextTransform.init_commands() text-transform.txt /*TextTransform.init_commands()*
54
TextTransform.replace_columns() text-transform.txt /*TextTransform.replace_columns()*
65
TextTransform.replace_selection() text-transform.txt /*TextTransform.replace_selection()*
76
TextTransform.replace_word() text-transform.txt /*TextTransform.replace_word()*
8-
TextTransform.restore_positions() text-transform.txt /*TextTransform.restore_positions()*
9-
TextTransform.save_positions() text-transform.txt /*TextTransform.save_positions()*
107
TextTransform.setup() text-transform.txt /*TextTransform.setup()*
118
TextTransform.to_camel_case() text-transform.txt /*TextTransform.to_camel_case()*
129
TextTransform.to_const_case() text-transform.txt /*TextTransform.to_const_case()*
@@ -16,10 +13,13 @@ TextTransform.to_pascal_case() text-transform.txt /*TextTransform.to_pascal_case
1613
TextTransform.to_snake_case() text-transform.txt /*TextTransform.to_snake_case()*
1714
TextTransform.to_title_case() text-transform.txt /*TextTransform.to_title_case()*
1815
TextTransform.to_words() text-transform.txt /*TextTransform.to_words()*
19-
TextTransform.toggle() text-transform.txt /*TextTransform.toggle()*
2016
TextTransform.transform_words() text-transform.txt /*TextTransform.transform_words()*
2117
find_word_boundaries() text-transform.txt /*find_word_boundaries()*
2218
init() text-transform.txt /*init()*
19+
state.enable() text-transform.txt /*state.enable()*
20+
state.restore_positions() text-transform.txt /*state.restore_positions()*
21+
state.save_positions() text-transform.txt /*state.save_positions()*
22+
state.toggle() text-transform.txt /*state.toggle()*
2323
telescope.telescope_popup() text-transform.txt /*telescope.telescope_popup()*
2424
utils.dump() text-transform.txt /*utils.dump()*
2525
utils.merge() text-transform.txt /*utils.merge()*

doc/text-transform.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,26 +117,26 @@ the full information around the selection logic.
117117

118118
==============================================================================
119119
------------------------------------------------------------------------------
120-
*TextTransform.toggle()*
121-
`TextTransform.toggle`()
120+
*state.toggle()*
121+
`state.toggle`()
122122
Toggle the plugin by calling the `enable`/`disable` methods respectively.
123123
@private
124124

125125
------------------------------------------------------------------------------
126-
*TextTransform.enable()*
127-
`TextTransform.enable`()
126+
*state.enable()*
127+
`state.enable`()
128128
Enables the plugin
129129
@private
130130

131131
------------------------------------------------------------------------------
132-
*TextTransform.save_positions()*
133-
`TextTransform.save_positions`()
132+
*state.save_positions()*
133+
`state.save_positions`()
134134
Save the current cursor position, mode, and visual selection ranges
135135
@private
136136

137137
------------------------------------------------------------------------------
138-
*TextTransform.restore_positions()*
139-
`TextTransform.restore_positions`({state})
138+
*state.restore_positions()*
139+
`state.restore_positions`({new_state})
140140
Restore the cursor position, mode, and visual selection ranges saved using `save_position()`,
141141
or a given modified state, if passed as the first argument
142142

lua/text-transform/commands.lua

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
-- local D = require("text-transform.util.debug")
12
local state = require("text-transform.state")
23
local replacers = require("text-transform.replacers")
34
local popup = require("text-transform.popup")
@@ -16,22 +17,24 @@ function TextTransform.init_commands()
1617
TtTitle = "title_case",
1718
}
1819

20+
local cmdopts = { range = true, force = true }
21+
1922
for cmd, transformer_name in pairs(map) do
2023
vim.api.nvim_create_user_command(cmd, function()
2124
state.save_positions()
2225
replacers.replace_selection(transformer_name)
23-
end, {})
26+
end, cmdopts)
2427
end
2528

2629
-- specific popups
2730
vim.api.nvim_create_user_command("TtTelescope", function()
2831
local telescope = require("text-transform.telescope")
2932
telescope.telescope_popup()
30-
end, {})
33+
end, cmdopts)
3134
vim.api.nvim_create_user_command("TtSelect", function()
3235
local select = require("text-transform.select")
3336
select.select_popup()
34-
end, {})
37+
end, cmdopts)
3538

3639
-- auto popup by config
3740
vim.api.nvim_create_user_command("TextTransform", popup.show_popup, {})

lua/text-transform/replacers.lua

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ local function find_word_boundaries(line, start_col)
1919
local word_end_col = vim.fn.match(line_text:sub(word_start_col), non_word_pat)
2020
+ word_start_col
2121
- 1
22-
D.log("replacers", "Found word boundaries: %s", vim.inspect({ word_start_col, word_end_col }))
23-
D.log("replacers", "Word text: %s", line_text:sub(word_start_col, word_end_col))
24-
D.log("replacers", "Line text: %s", line_text)
22+
D.log(
23+
"find_word_boundaries",
24+
"Found word boundaries: %s",
25+
vim.inspect({ word_start_col, word_end_col })
26+
)
27+
D.log("find_word_boundaries", "Word text: %s", line_text:sub(word_start_col, word_end_col))
28+
D.log("find_word_boundaries", "Line text: %s", line_text)
2529
return word_start_col, word_end_col
2630
end
2731

2832
function TextTransform.replace_range(start_line, start_col, end_line, end_col, transform_name)
29-
D.log("replacers", "Replacing range with %s", transform_name)
33+
D.log("replace_range", "Replacing range with %s", transform_name)
3034
local transform = t["to_" .. transform_name]
3135
local lines = vim.fn.getline(start_line, end_line) --- @type any
3236
local transformed = {}
@@ -58,7 +62,7 @@ end
5862
--- @param transform_name string The transformer name
5963
--- @param position table|nil A table containing the position of the word to replace
6064
function TextTransform.replace_word(transform_name, position)
61-
D.log("replacers", "Replacing word with %s", transform_name)
65+
D.log("replace_word", "Replacing word with %s", transform_name)
6266
local word, line, col, start_col, end_col
6367
if not position then
6468
word = vim.fn.expand("<cword>")
@@ -67,11 +71,11 @@ function TextTransform.replace_word(transform_name, position)
6771
start_col, end_col = find_word_boundaries(line, col)
6872
word = vim.fn.getline(line):sub(start_col, end_col)
6973
end
70-
D.log("replacers", "Found word %s", word)
71-
D.log("replacers", "Using transformer %s", transform_name)
74+
D.log("replace_word", "Found word %s", word)
75+
D.log("replace_word", "Using transformer %s", transform_name)
7276
local transformer = t["to_" .. transform_name]
7377
local transformed = transformer(word)
74-
D.log("replacers", "New value %s", transformed)
78+
D.log("replace_word", "New value %s", transformed)
7579
if not position then
7680
vim.cmd("normal ciw" .. transformed)
7781
else
@@ -83,7 +87,7 @@ end
8387
--- Assumes that the each selection is 1 character and operates on the whole word under each cursor.
8488
function TextTransform.replace_columns(transform_name)
8589
local selections = TextTransform.get_visual_selection_details()
86-
D.log("replacers", "Replacing columns with %s", transform_name)
90+
D.log("replace_columns", "Replacing columns with %s", transform_name)
8791
for _, sel in ipairs(selections) do
8892
TextTransform.replace_word(transform_name, { 0, sel.start_line, sel.start_col, 0 })
8993
end
@@ -95,20 +99,22 @@ end
9599
---
96100
--- @param transform_name string The transformer name
97101
function TextTransform.replace_selection(transform_name)
98-
D.log("replacers", "Replacing selection with %s", transform_name)
102+
D.log("replace_selection", "Replacing selection with %s", transform_name)
99103
-- determine if cursor is a 1-width column across multiple lines or a normal selection
100104
-- local start_line, start_col, end_line, end_col = unpack(vim.fn.getpos("'<"))
101105
local selections = TextTransform.get_visual_selection_details()
102106

103-
D.log("replacers", "Selections: %s", utils.dump(selections))
107+
D.log("replace_selection", "Selections: %s", utils.dump(selections))
104108
local is_multiline = #selections > 1
105109
local is_column = is_multiline and selections[1].start_col == selections[#selections].end_col
106110
local is_single_cursor = not is_multiline
107111
and not is_column
112+
and selections
113+
and selections[1]
108114
and selections[1].start_col == selections[1].end_col
109115

110116
D.log(
111-
"replacers",
117+
"replace_selection",
112118
"is_multiline: %s, is_column: %s, is_word: %s",
113119
is_multiline,
114120
is_column,
@@ -139,19 +145,31 @@ end
139145
--- the full information around the selection logic.
140146
function TextTransform.get_visual_selection_details()
141147
if not state.positions then
142-
D.log("replacers", "No positions saved")
148+
D.log("get_visual_selection_details", "No positions saved")
143149
return {}
144150
end
145151
D.log(
146-
"replacers",
152+
"get_visual_selection_details",
147153
"Getting visual selection details - mode: %s, is_visual: %s, is_block: %s",
148154
state.positions.mode,
149155
utils.is_visual_mode(),
150156
utils.is_block_visual_mode()
151157
)
158+
159+
-- Get the start and end positions of the selection
160+
local start_pos = state.positions.visual_start
161+
local end_pos = state.positions.visual_end
162+
local start_line, start_col = start_pos[2], start_pos[3]
163+
local end_line, end_col = end_pos[2], end_pos[3]
164+
152165
-- Check if currently in visual mode; if not, return the cursor position
153-
if not utils.is_visual_mode() and not utils.is_block_visual_mode() then
166+
if
167+
not utils.is_visual_mode()
168+
and not utils.is_block_visual_mode()
169+
and not state.has_range(start_pos, end_pos)
170+
then
154171
local pos = state.positions.pos
172+
D.log("get_visual_selection_details", "Returning single cursor position")
155173
return {
156174
{
157175
start_line = pos[2],
@@ -162,20 +180,14 @@ function TextTransform.get_visual_selection_details()
162180
}
163181
end
164182

165-
-- Get the start and end positions of the selection
166-
local start_pos = state.positions.visual_start
167-
local end_pos = state.positions.visual_end
168-
local start_line, start_col = start_pos[2], start_pos[3]
169-
local end_line, end_col = end_pos[2], end_pos[3]
170-
171183
-- Swap if selection is made upwards or backwards
172184
if start_line > end_line or (start_line == end_line and start_col > end_col) then
173185
start_line, end_line = end_line, start_line
174186
start_col, end_col = end_col, start_col
175187
end
176188

177189
-- If it's block visual mode, return table for each row
178-
if utils.is_block_visual_mode() then
190+
if utils.is_block_visual_mode() or state.has_range(start_pos, end_pos) then
179191
local block_selection = {}
180192
for line = start_line, end_line do
181193
if start_col == end_col then
@@ -189,9 +201,15 @@ function TextTransform.get_visual_selection_details()
189201
end_col = start_col,
190202
})
191203
end
204+
D.log(
205+
"get_visual_selection_details",
206+
"Returning block selection: %s",
207+
utils.dump(block_selection)
208+
)
192209
return block_selection
193210
else
194211
-- Normal visual mode, return single table entry
212+
D.log("get_visual_selection_details", "Returning normal selection")
195213
return {
196214
{
197215
start_line = start_line,

0 commit comments

Comments
 (0)