@@ -131,24 +131,6 @@ static int visual_block_range(Buffer *buf, Window *win, int *sy, int *ey,
131131 return 1 ;
132132}
133133
134- static void sstr_delete_range (SizedStr * s , int start , int end_excl ) {
135- if (!s || !s -> data )
136- return ;
137- if (start < 0 )
138- start = 0 ;
139- if (end_excl < start )
140- end_excl = start ;
141- if (end_excl > (int )s -> len )
142- end_excl = (int )s -> len ;
143- if (start > (int )s -> len )
144- start = (int )s -> len ;
145- int rem = (int )s -> len - end_excl ;
146- memmove (s -> data + start , s -> data + end_excl , (size_t )rem );
147- s -> len -= (end_excl - start );
148- if (s -> data )
149- s -> data [s -> len ] = '\0' ;
150- }
151-
152134static int visual_yank (Buffer * buf , Window * win , int block_mode ) {
153135 if (!buf || !win || win -> sel .type == SEL_NONE )
154136 return 0 ;
@@ -195,69 +177,33 @@ static int visual_delete(Buffer *buf, Window *win, int block_mode) {
195177 block_mode = 1 ;
196178 if (win -> sel .type == SEL_VISUAL_BLOCK )
197179 block_mode = 1 ;
198- if (!visual_yank (buf , win , block_mode ))
199- return 0 ;
200180
181+ /* Convert visual selection to TextSelection */
182+ TextSelection sel ;
201183 if (!block_mode ) {
202184 int sy , sx , ey , ex_excl ;
203185 if (!visual_char_range (buf , win , & sy , & sx , & ey , & ex_excl ))
204186 return 0 ;
205- Row * start = & buf -> rows [sy ];
206- int start_len = (int )start -> chars .len ;
207- if (sx > start_len )
208- sx = start_len ;
209-
210- if (sy == ey ) {
211- int end_ex = ex_excl ;
212- if (end_ex > start_len )
213- end_ex = start_len ;
214- sstr_delete_range (& start -> chars , sx , end_ex );
215- buf_row_update (start );
216- } else {
217- Row * end = & buf -> rows [ey ];
218- int end_ex = ex_excl ;
219- if (end_ex > (int )end -> chars .len )
220- end_ex = (int )end -> chars .len ;
221- SizedStr tail = sstr_from (end -> chars .data + end_ex ,
222- end -> chars .len - (size_t )end_ex );
223- start -> chars .len = (size_t )sx ;
224- if (start -> chars .data )
225- start -> chars .data [sx ] = '\0' ;
226- sstr_append (& start -> chars , tail .data , tail .len );
227- sstr_free (& tail );
228- buf_row_update (start );
229- /* Remove intermediate rows including end row */
230- for (int y = ey ; y > sy ; y -- ) {
231- buf_row_del_in (buf , y );
232- }
233- }
234- buf -> dirty ++ ;
235- win -> cursor .y = sy ;
236- win -> cursor .x = sx ;
187+ sel = textsel_make_range (sy , sx , ey , ex_excl , SEL_VISUAL );
237188 } else {
238189 int sy , ey , start_rx , end_rx_excl ;
239190 if (!visual_block_range (buf , win , & sy , & ey , & start_rx , & end_rx_excl ))
240191 return 0 ;
241- for (int y = sy ; y <= ey ; y ++ ) {
242- Row * r = & buf -> rows [y ];
243- int cx0 = buf_row_rx_to_cx (r , start_rx );
244- int cx1 = buf_row_rx_to_cx (r , end_rx_excl );
245- if (cx0 < 0 )
246- cx0 = 0 ;
247- if (cx1 < cx0 )
248- cx1 = cx0 ;
249- if (cx1 > (int )r -> chars .len )
250- cx1 = (int )r -> chars .len ;
251- if (cx0 == cx1 )
252- continue ;
253- sstr_delete_range (& r -> chars , cx0 , cx1 );
254- buf_row_update (r );
255- }
256- buf -> dirty ++ ;
257- win -> cursor .y = sy ;
258- Row * r = & buf -> rows [win -> cursor .y ];
259- win -> cursor .x = buf_row_rx_to_cx (r , start_rx );
192+ /* For block mode, convert render columns to character columns */
193+ Row * first_row = & buf -> rows [sy ];
194+ int sx = buf_row_rx_to_cx (first_row , start_rx );
195+ int ex = buf_row_rx_to_cx (first_row , end_rx_excl );
196+ sel = textsel_make_range (sy , sx , ey , ex , SEL_VISUAL_BLOCK );
260197 }
198+
199+ /* Yank first (to clipboard) */
200+ EdError err = yank_selection (& sel );
201+ if (err != ED_OK )
202+ return 0 ;
203+
204+ /* Delete the selection */
205+ buf_delete_selection (& sel );
206+
261207 visual_clear (win );
262208 ed_set_mode (MODE_NORMAL );
263209 return 1 ;
0 commit comments