comparison src/ops.c @ 28854:647d7f439622 v8.2.4950

patch 8.2.4950: text properties position wrong after shifting text Commit: https://github.com/vim/vim/commit/4b93674159d60c985de906c30f45dbaf2b64056f Author: LemonBoy <thatlemon@gmail.com> Date: Fri May 13 21:56:28 2022 +0100 patch 8.2.4950: text properties position wrong after shifting text Problem: Text properties position wrong after shifting text. Solution: Adjust the text properties when shifting a block of text. (closes #10418)
author Bram Moolenaar <Bram@vim.org>
date Fri, 13 May 2022 23:00:03 +0200
parents d0241e74bfdb
children 948877671c54
comparison
equal deleted inserted replaced
28853:e397a7fd7fc1 28854:647d7f439622
284 int sw_val = (int)get_sw_value_indent(curbuf); 284 int sw_val = (int)get_sw_value_indent(curbuf);
285 int ts_val = (int)curbuf->b_p_ts; 285 int ts_val = (int)curbuf->b_p_ts;
286 struct block_def bd; 286 struct block_def bd;
287 int incr; 287 int incr;
288 colnr_T ws_vcol; 288 colnr_T ws_vcol;
289 int i = 0, j = 0; 289 int added;
290 int len; 290 unsigned new_line_len; // the length of the line after the
291 // block shift
291 #ifdef FEAT_RIGHTLEFT 292 #ifdef FEAT_RIGHTLEFT
292 int old_p_ri = p_ri; 293 int old_p_ri = p_ri;
293 294
294 p_ri = 0; // don't want revins in indent 295 p_ri = 0; // don't want revins in indent
295 #endif 296 #endif
306 307
307 oldp = ml_get_curline(); 308 oldp = ml_get_curline();
308 309
309 if (!left) 310 if (!left)
310 { 311 {
312 int tabs = 0, spaces = 0;
313
311 /* 314 /*
312 * 1. Get start vcol 315 * 1. Get start vcol
313 * 2. Total ws vcols 316 * 2. Total ws vcols
314 * 3. Divvy into TABs & spp 317 * 3. Divvy into TABs & spp
315 * 4. Construct new string 318 * 4. Construct new string
341 // OK, now total=all the VWS reqd, and textstart points at the 1st 344 // OK, now total=all the VWS reqd, and textstart points at the 1st
342 // non-ws char in the block. 345 // non-ws char in the block.
343 #ifdef FEAT_VARTABS 346 #ifdef FEAT_VARTABS
344 if (!curbuf->b_p_et) 347 if (!curbuf->b_p_et)
345 tabstop_fromto(ws_vcol, ws_vcol + total, 348 tabstop_fromto(ws_vcol, ws_vcol + total,
346 ts_val, curbuf->b_p_vts_array, &i, &j); 349 ts_val, curbuf->b_p_vts_array, &tabs, &spaces);
347 else 350 else
348 j = total; 351 spaces = total;
349 #else 352 #else
350 if (!curbuf->b_p_et) 353 if (!curbuf->b_p_et)
351 i = ((ws_vcol % ts_val) + total) / ts_val; // number of tabs 354 tabs = ((ws_vcol % ts_val) + total) / ts_val; // number of tabs
352 if (i) 355 if (tabs > 0)
353 j = ((ws_vcol % ts_val) + total) % ts_val; // number of spp 356 spaces = ((ws_vcol % ts_val) + total) % ts_val; // number of spp
354 else 357 else
355 j = total; 358 spaces = total;
356 #endif 359 #endif
357 // if we're splitting a TAB, allow for it 360 // if we're splitting a TAB, allow for it
358 bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0); 361 bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
359 len = (int)STRLEN(bd.textstart) + 1; 362
360 newp = alloc(bd.textcol + i + j + len); 363 new_line_len = bd.textcol + tabs + spaces + (int)STRLEN(bd.textstart);
364 newp = alloc(new_line_len + 1);
361 if (newp == NULL) 365 if (newp == NULL)
362 return; 366 return;
363 vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + len));
364 mch_memmove(newp, oldp, (size_t)bd.textcol); 367 mch_memmove(newp, oldp, (size_t)bd.textcol);
365 vim_memset(newp + bd.textcol, TAB, (size_t)i); 368 vim_memset(newp + bd.textcol, TAB, (size_t)tabs);
366 vim_memset(newp + bd.textcol + i, ' ', (size_t)j); 369 vim_memset(newp + bd.textcol + tabs, ' ', (size_t)spaces);
367 // the end 370 // Note that STRMOVE() copies the trailing NUL.
368 mch_memmove(newp + bd.textcol + i + j, bd.textstart, (size_t)len); 371 STRMOVE(newp + bd.textcol + tabs + spaces, bd.textstart);
369 } 372 }
370 else // left 373 else // left
371 { 374 {
372 colnr_T destination_col; // column to which text in block will 375 colnr_T destination_col; // column to which text in block will
373 // be shifted 376 // be shifted
374 char_u *verbatim_copy_end; // end of the part of the line which is 377 char_u *verbatim_copy_end; // end of the part of the line which is
375 // copied verbatim 378 // copied verbatim
376 colnr_T verbatim_copy_width;// the (displayed) width of this part 379 colnr_T verbatim_copy_width;// the (displayed) width of this part
377 // of line 380 // of line
378 unsigned fill; // nr of spaces that replace a TAB 381 unsigned fill; // nr of spaces that replace a TAB
379 unsigned new_line_len; // the length of the line after the
380 // block shift
381 size_t block_space_width; 382 size_t block_space_width;
382 size_t shift_amount; 383 size_t shift_amount;
383 char_u *non_white = bd.textstart; 384 char_u *non_white = bd.textstart;
384 colnr_T non_white_col; 385 colnr_T non_white_col;
385 386
446 // - the beginning of the original line up to "verbatim_copy_end", 447 // - the beginning of the original line up to "verbatim_copy_end",
447 // - "fill" number of spaces, 448 // - "fill" number of spaces,
448 // - the rest of the line, pointed to by non_white. 449 // - the rest of the line, pointed to by non_white.
449 new_line_len = (unsigned)(verbatim_copy_end - oldp) 450 new_line_len = (unsigned)(verbatim_copy_end - oldp)
450 + fill 451 + fill
451 + (unsigned)STRLEN(non_white) + 1; 452 + (unsigned)STRLEN(non_white);
452 453
453 newp = alloc(new_line_len); 454 newp = alloc(new_line_len + 1);
454 if (newp == NULL) 455 if (newp == NULL)
455 return; 456 return;
456 mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp)); 457 mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
457 vim_memset(newp + (verbatim_copy_end - oldp), ' ', (size_t)fill); 458 vim_memset(newp + (verbatim_copy_end - oldp), ' ', (size_t)fill);
459 // Note that STRMOVE() copies the trailing NUL.
458 STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white); 460 STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
459 } 461 }
460 // replace the line 462 // replace the line
463 added = new_line_len - (int)STRLEN(oldp);
461 ml_replace(curwin->w_cursor.lnum, newp, FALSE); 464 ml_replace(curwin->w_cursor.lnum, newp, FALSE);
462 changed_bytes(curwin->w_cursor.lnum, bd.textcol); 465 inserted_bytes(curwin->w_cursor.lnum, bd.textcol, added);
463 State = oldstate; 466 State = oldstate;
464 curwin->w_cursor.col = oldcol; 467 curwin->w_cursor.col = oldcol;
465 #ifdef FEAT_RIGHTLEFT 468 #ifdef FEAT_RIGHTLEFT
466 p_ri = old_p_ri; 469 p_ri = old_p_ri;
467 #endif 470 #endif