@@ -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
2630end
2731
2832function 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 = {}
5862--- @param transform_name string The transformer name
5963--- @param position table | nil A table containing the position of the word to replace
6064function 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
8387--- Assumes that the each selection is 1 character and operates on the whole word under each cursor.
8488function 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
9599---
96100--- @param transform_name string The transformer name
97101function 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.
140146function 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