comparison src/ops.c @ 29451:057c26b5c33a v9.0.0067

patch 9.0.0067: cannot show virtual text Commit: https://github.com/vim/vim/commit/7f9969c559b51446632ac7e8f76cde07e7d0078d Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jul 25 18:13:54 2022 +0100 patch 9.0.0067: cannot show virtual text Problem: Cannot show virtual text. Solution: Initial changes for virtual text support, using text properties.
author Bram Moolenaar <Bram@vim.org>
date Mon, 25 Jul 2022 19:15:06 +0200
parents fba9e366ced4
children 8a243ecfe2dd
comparison
equal deleted inserted replaced
29450:67f31c24291b 29451:057c26b5c33a
305 305
306 oldp = ml_get_curline(); 306 oldp = ml_get_curline();
307 307
308 if (!left) 308 if (!left)
309 { 309 {
310 int tabs = 0, spaces = 0; 310 int tabs = 0, spaces = 0;
311 chartabsize_T cts;
311 312
312 /* 313 /*
313 * 1. Get start vcol 314 * 1. Get start vcol
314 * 2. Total ws vcols 315 * 2. Total ws vcols
315 * 3. Divvy into TABs & spp 316 * 3. Divvy into TABs & spp
330 } 331 }
331 } 332 }
332 else 333 else
333 ++bd.textstart; 334 ++bd.textstart;
334 } 335 }
335 for ( ; VIM_ISWHITE(*bd.textstart); ) 336
336 { 337 // TODO: is passing bd.textstart for start of the line OK?
337 // TODO: is passing bd.textstart for start of the line OK? 338 init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum,
338 incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, bd.start_vcol); 339 bd.start_vcol, bd.textstart, bd.textstart);
340 for ( ; VIM_ISWHITE(*cts.cts_ptr); )
341 {
342 incr = lbr_chartabsize_adv(&cts);
339 total += incr; 343 total += incr;
340 bd.start_vcol += incr; 344 cts.cts_vcol += incr;
341 } 345 }
346 bd.textstart = cts.cts_ptr;
347 bd.start_vcol = cts.cts_vcol;
348 clear_chartabsize_arg(&cts);
349
342 // OK, now total=all the VWS reqd, and textstart points at the 1st 350 // OK, now total=all the VWS reqd, and textstart points at the 1st
343 // non-ws char in the block. 351 // non-ws char in the block.
344 #ifdef FEAT_VARTABS 352 #ifdef FEAT_VARTABS
345 if (!curbuf->b_p_et) 353 if (!curbuf->b_p_et)
346 tabstop_fromto(ws_vcol, ws_vcol + total, 354 tabstop_fromto(ws_vcol, ws_vcol + total,
379 unsigned fill; // nr of spaces that replace a TAB 387 unsigned fill; // nr of spaces that replace a TAB
380 size_t block_space_width; 388 size_t block_space_width;
381 size_t shift_amount; 389 size_t shift_amount;
382 char_u *non_white = bd.textstart; 390 char_u *non_white = bd.textstart;
383 colnr_T non_white_col; 391 colnr_T non_white_col;
392 chartabsize_T cts;
384 393
385 /* 394 /*
386 * Firstly, let's find the first non-whitespace character that is 395 * Firstly, let's find the first non-whitespace character that is
387 * displayed after the block's start column and the character's column 396 * displayed after the block's start column and the character's column
388 * number. Also, let's calculate the width of all the whitespace 397 * number. Also, let's calculate the width of all the whitespace
397 MB_PTR_ADV(non_white); 406 MB_PTR_ADV(non_white);
398 407
399 // The character's column is in "bd.start_vcol". 408 // The character's column is in "bd.start_vcol".
400 non_white_col = bd.start_vcol; 409 non_white_col = bd.start_vcol;
401 410
402 while (VIM_ISWHITE(*non_white)) 411 init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum,
403 { 412 non_white_col, bd.textstart, non_white);
404 incr = lbr_chartabsize_adv(bd.textstart, &non_white, non_white_col); 413 while (VIM_ISWHITE(*cts.cts_ptr))
405 non_white_col += incr; 414 {
406 } 415 incr = lbr_chartabsize_adv(&cts);
416 cts.cts_vcol += incr;
417 }
418 non_white_col = cts.cts_vcol;
419 non_white = cts.cts_ptr;
420 clear_chartabsize_arg(&cts);
407 421
408 block_space_width = non_white_col - oap->start_vcol; 422 block_space_width = non_white_col - oap->start_vcol;
409 // We will shift by "total" or "block_space_width", whichever is less. 423 // We will shift by "total" or "block_space_width", whichever is less.
410 shift_amount = (block_space_width < (size_t)total 424 shift_amount = (block_space_width < (size_t)total
411 ? block_space_width : (size_t)total); 425 ? block_space_width : (size_t)total);
421 // If "bd.startspaces" is set, "bd.textstart" points to the character 435 // If "bd.startspaces" is set, "bd.textstart" points to the character
422 // preceding the block. We have to subtract its width to obtain its 436 // preceding the block. We have to subtract its width to obtain its
423 // column number. 437 // column number.
424 if (bd.startspaces) 438 if (bd.startspaces)
425 verbatim_copy_width -= bd.start_char_vcols; 439 verbatim_copy_width -= bd.start_char_vcols;
426 while (verbatim_copy_width < destination_col) 440 init_chartabsize_arg(&cts, curwin, 0, verbatim_copy_width,
427 { 441 bd.textstart, verbatim_copy_end);
428 char_u *line = verbatim_copy_end; 442 while (cts.cts_vcol < destination_col)
429 443 {
430 // TODO: is passing verbatim_copy_end for start of the line OK? 444 incr = lbr_chartabsize(&cts);
431 incr = lbr_chartabsize(line, verbatim_copy_end, 445 if (cts.cts_vcol + incr > destination_col)
432 verbatim_copy_width);
433 if (verbatim_copy_width + incr > destination_col)
434 break; 446 break;
435 verbatim_copy_width += incr; 447 cts.cts_vcol += incr;
436 MB_PTR_ADV(verbatim_copy_end); 448 MB_PTR_ADV(cts.cts_ptr);
437 } 449 }
450 verbatim_copy_width = cts.cts_vcol;
451 verbatim_copy_end = cts.cts_ptr;
452 clear_chartabsize_arg(&cts);
438 453
439 // If "destination_col" is different from the width of the initial 454 // If "destination_col" is different from the width of the initial
440 // part of the line that will be copied, it means we encountered a tab 455 // part of the line that will be copied, it means we encountered a tab
441 // character, which we will have to partly replace with spaces. 456 // character, which we will have to partly replace with spaces.
442 fill = destination_col - verbatim_copy_width; 457 fill = destination_col - verbatim_copy_width;
701 716
702 /* 717 /*
703 * Put deleted text into register 1 and shift number registers if the 718 * Put deleted text into register 1 and shift number registers if the
704 * delete contains a line break, or when using a specific operator (Vi 719 * delete contains a line break, or when using a specific operator (Vi
705 * compatible) 720 * compatible)
706 * Use the register name from before adjust_clip_reg() may have
707 * changed it.
708 */ 721 */
709 if (oap->motion_type == MLINE || oap->line_count > 1 722 if (oap->motion_type == MLINE || oap->line_count > 1
710 || oap->use_reg_one) 723 || oap->use_reg_one)
711 { 724 {
712 shift_delete_registers(); 725 shift_delete_registers();
2211 char_u *pend; 2224 char_u *pend;
2212 char_u *pstart; 2225 char_u *pstart;
2213 char_u *line; 2226 char_u *line;
2214 char_u *prev_pstart; 2227 char_u *prev_pstart;
2215 char_u *prev_pend; 2228 char_u *prev_pend;
2229 chartabsize_T cts;
2216 #ifdef FEAT_LINEBREAK 2230 #ifdef FEAT_LINEBREAK
2217 int lbr_saved = curwin->w_p_lbr; 2231 int lbr_saved = curwin->w_p_lbr;
2218 2232
2219 // Avoid a problem with unwanted linebreaks in block mode. 2233 // Avoid a problem with unwanted linebreaks in block mode.
2220 curwin->w_p_lbr = FALSE; 2234 curwin->w_p_lbr = FALSE;
2230 bdp->pre_whitesp_c = 0; 2244 bdp->pre_whitesp_c = 0;
2231 bdp->end_char_vcols = 0; 2245 bdp->end_char_vcols = 0;
2232 bdp->start_char_vcols = 0; 2246 bdp->start_char_vcols = 0;
2233 2247
2234 line = ml_get(lnum); 2248 line = ml_get(lnum);
2235 pstart = line;
2236 prev_pstart = line; 2249 prev_pstart = line;
2237 while (bdp->start_vcol < oap->start_vcol && *pstart) 2250 init_chartabsize_arg(&cts, curwin, lnum, bdp->start_vcol, line, line);
2251 while (cts.cts_vcol < oap->start_vcol && *cts.cts_ptr != NUL)
2238 { 2252 {
2239 // Count a tab for what it's worth (if list mode not on) 2253 // Count a tab for what it's worth (if list mode not on)
2240 incr = lbr_chartabsize(line, pstart, bdp->start_vcol); 2254 incr = lbr_chartabsize(&cts);
2241 bdp->start_vcol += incr; 2255 cts.cts_vcol += incr;
2242 if (VIM_ISWHITE(*pstart)) 2256 if (VIM_ISWHITE(*cts.cts_ptr))
2243 { 2257 {
2244 bdp->pre_whitesp += incr; 2258 bdp->pre_whitesp += incr;
2245 bdp->pre_whitesp_c++; 2259 bdp->pre_whitesp_c++;
2246 } 2260 }
2247 else 2261 else
2248 { 2262 {
2249 bdp->pre_whitesp = 0; 2263 bdp->pre_whitesp = 0;
2250 bdp->pre_whitesp_c = 0; 2264 bdp->pre_whitesp_c = 0;
2251 } 2265 }
2252 prev_pstart = pstart; 2266 prev_pstart = cts.cts_ptr;
2253 MB_PTR_ADV(pstart); 2267 MB_PTR_ADV(cts.cts_ptr);
2254 } 2268 }
2269 bdp->start_vcol = cts.cts_vcol;
2270 pstart = cts.cts_ptr;
2271 clear_chartabsize_arg(&cts);
2272
2255 bdp->start_char_vcols = incr; 2273 bdp->start_char_vcols = incr;
2256 if (bdp->start_vcol < oap->start_vcol) // line too short 2274 if (bdp->start_vcol < oap->start_vcol) // line too short
2257 { 2275 {
2258 bdp->end_vcol = bdp->start_vcol; 2276 bdp->end_vcol = bdp->start_vcol;
2259 bdp->is_short = TRUE; 2277 bdp->is_short = TRUE;
2293 } 2311 }
2294 } 2312 }
2295 } 2313 }
2296 else 2314 else
2297 { 2315 {
2316 init_chartabsize_arg(&cts, curwin, lnum, bdp->end_vcol,
2317 line, pend);
2298 prev_pend = pend; 2318 prev_pend = pend;
2299 while (bdp->end_vcol <= oap->end_vcol && *pend != NUL) 2319 while (cts.cts_vcol <= oap->end_vcol && *cts.cts_ptr != NUL)
2300 { 2320 {
2301 // Count a tab for what it's worth (if list mode not on) 2321 // count a tab for what it's worth (if list mode not on)
2302 prev_pend = pend; 2322 prev_pend = cts.cts_ptr;
2303 incr = lbr_chartabsize_adv(line, &pend, bdp->end_vcol); 2323 incr = lbr_chartabsize_adv(&cts);
2304 bdp->end_vcol += incr; 2324 cts.cts_vcol += incr;
2305 } 2325 }
2326 bdp->end_vcol = cts.cts_vcol;
2327 pend = cts.cts_ptr;
2328 clear_chartabsize_arg(&cts);
2329
2306 if (bdp->end_vcol <= oap->end_vcol 2330 if (bdp->end_vcol <= oap->end_vcol
2307 && (!is_del 2331 && (!is_del
2308 || oap->op_type == OP_APPEND 2332 || oap->op_type == OP_APPEND
2309 || oap->op_type == OP_REPLACE)) // line too short 2333 || oap->op_type == OP_REPLACE)) // line too short
2310 { 2334 {