@@ -905,7 +905,7 @@ win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
905905 for ( ; * cts -> cts_ptr != NUL && (len == MAXCOL || cts -> cts_ptr < cts -> cts_line + len );
906906 MB_PTR_ADV (cts -> cts_ptr ))
907907 {
908- vcol += win_lbr_chartabsize (cts , NULL );
908+ vcol += win_lbr_chartabsize (cts , NULL , NULL );
909909 if (vcol > MAXCOL )
910910 {
911911 cts -> cts_vcol = MAXCOL ;
@@ -919,7 +919,7 @@ win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
919919 if (len == MAXCOL && cts -> cts_has_prop_with_text && * cts -> cts_ptr == NUL )
920920 {
921921 int head = 0 ;
922- (void )win_lbr_chartabsize (cts , & head );
922+ (void )win_lbr_chartabsize (cts , & head , NULL );
923923 vcol += cts -> cts_cur_text_width + head ;
924924 // when properties are above or below the empty line must also be
925925 // counted
@@ -1186,7 +1186,7 @@ lbr_chartabsize(chartabsize_T *cts)
11861186 RET_WIN_BUF_CHARTABSIZE (curwin , curbuf , cts -> cts_ptr , cts -> cts_vcol )
11871187#if defined(FEAT_LINEBREAK ) || defined(FEAT_PROP_POPUP )
11881188 }
1189- return win_lbr_chartabsize (cts , NULL );
1189+ return win_lbr_chartabsize (cts , NULL , NULL );
11901190#endif
11911191}
11921192
@@ -1209,19 +1209,24 @@ lbr_chartabsize_adv(chartabsize_T *cts)
12091209 * inserts text.
12101210 * This function is used very often, keep it fast!!!!
12111211 *
1212- * If "headp" not NULL, set "*headp" to the size of 'showbreak'/'breakindent'
1212+ * If "headp" isn't NULL, set "*headp" to the size of 'showbreak'/'breakindent'
12131213 * included in the return value.
12141214 * When "cts->cts_max_head_vcol" is positive, only count in "*headp" the size
12151215 * of 'showbreak'/'breakindent' before "cts->cts_max_head_vcol".
12161216 * When "cts->cts_max_head_vcol" is negative, only count in "*headp" the size
12171217 * of 'showbreak'/'breakindent' before where cursor should be placed.
12181218 *
1219- * Warning: "*headp" may not be set if it's 0, init to 0 before calling.
1219+ * If "tailp" isn't NULL, set "*tailp" to the size of 'linebreak' included in
1220+ * the return value.
1221+ *
1222+ * Warning: "*headp" and "*tailp" may not be set if the value is 0, init to 0
1223+ * before calling.
12201224 */
12211225 int
12221226win_lbr_chartabsize (
12231227 chartabsize_T * cts ,
1224- int * headp UNUSED )
1228+ int * headp UNUSED ,
1229+ int * tailp UNUSED )
12251230{
12261231 win_T * wp = cts -> cts_win ;
12271232#if defined(FEAT_PROP_POPUP ) || defined(FEAT_LINEBREAK )
@@ -1470,6 +1475,7 @@ win_lbr_chartabsize(
14701475 if (headp != NULL )
14711476 * headp = head ;
14721477
1478+ int size_before_lbr = size ;
14731479 int need_lbr = FALSE;
14741480 /*
14751481 * If 'linebreak' set check at a blank before a non-blank if the line
@@ -1522,6 +1528,9 @@ win_lbr_chartabsize(
15221528 }
15231529 }
15241530
1531+ if (tailp != NULL )
1532+ * tailp = size - size_before_lbr ;
1533+
15251534# ifdef FEAT_PROP_POPUP
15261535 size += cts -> cts_first_char ;
15271536# endif
@@ -1598,6 +1607,10 @@ in_win_border(win_T *wp, colnr_T vcol)
15981607 * cursor: where the cursor is on this character (first char, except for TAB)
15991608 * end: on the last position of this character (TAB, ctrl)
16001609 *
1610+ * When 'linebreak' follows this character, "end" is set to the position before
1611+ * 'linebreak' if "flags" contains GETVCOL_END_EXCL_LBR, otherwise it's set to
1612+ * the end of 'linebreak'.
1613+ *
16011614 * This is used very often, keep it fast!
16021615 */
16031616 void
@@ -1606,13 +1619,15 @@ getvcol(
16061619 pos_T * pos ,
16071620 colnr_T * start ,
16081621 colnr_T * cursor ,
1609- colnr_T * end )
1622+ colnr_T * end ,
1623+ int flags )
16101624{
16111625 colnr_T vcol ;
16121626 char_u * ptr ; // points to current char
16131627 char_u * line ; // start of the line
16141628 int incr ;
16151629 int head ;
1630+ int tail ;
16161631#ifdef FEAT_VARTABS
16171632 int * vts = wp -> w_buffer -> b_p_vts_array ;
16181633#endif
@@ -1693,6 +1708,8 @@ getvcol(
16931708 vcol += incr ;
16941709 ptr = next_ptr ;
16951710 }
1711+
1712+ tail = 0 ;
16961713 }
16971714 else
16981715 {
@@ -1701,7 +1718,8 @@ getvcol(
17011718 // A tab gets expanded, depending on the current column.
17021719 // Other things also take up space.
17031720 head = 0 ;
1704- incr = win_lbr_chartabsize (& cts , & head );
1721+ tail = 0 ;
1722+ incr = win_lbr_chartabsize (& cts , & head , & tail );
17051723 // make sure we don't go past the end of the line
17061724 if (* cts .cts_ptr == NUL )
17071725 {
@@ -1736,7 +1754,7 @@ getvcol(
17361754 if (start != NULL )
17371755 * start = vcol + head ;
17381756 if (end != NULL )
1739- * end = vcol + incr - 1 ;
1757+ * end = vcol + incr - ( flags & GETVCOL_END_EXCL_LBR ? tail : 0 ) - 1 ;
17401758 if (cursor != NULL )
17411759 {
17421760 if (* ptr == TAB
@@ -1746,6 +1764,7 @@ getvcol(
17461764 && !(VIsual_active
17471765 && (* p_sel == 'e' || LTOREQ_POS (* pos , VIsual )))
17481766 )
1767+ // TODO: subtracting "tail" may lead to better cursor position
17491768 * cursor = vcol + incr - 1 ; // cursor at end
17501769 else
17511770 {
@@ -1775,9 +1794,9 @@ getvcol_nolist(pos_T *posp)
17751794
17761795 curwin -> w_p_list = FALSE;
17771796 if (posp -> coladd )
1778- getvvcol (curwin , posp , NULL , & vcol , NULL );
1797+ getvvcol (curwin , posp , NULL , & vcol , NULL , 0 );
17791798 else
1780- getvcol (curwin , posp , NULL , & vcol , NULL );
1799+ getvcol (curwin , posp , NULL , & vcol , NULL , 0 );
17811800 curwin -> w_p_list = list_save ;
17821801 return vcol ;
17831802}
@@ -1791,7 +1810,8 @@ getvvcol(
17911810 pos_T * pos ,
17921811 colnr_T * start ,
17931812 colnr_T * cursor ,
1794- colnr_T * end )
1813+ colnr_T * end ,
1814+ int flags )
17951815{
17961816 colnr_T col ;
17971817 colnr_T coladd ;
@@ -1801,7 +1821,7 @@ getvvcol(
18011821 if (virtual_active ())
18021822 {
18031823 // For virtual mode, only want one value
1804- getvcol (wp , pos , & col , NULL , NULL );
1824+ getvcol (wp , pos , & col , NULL , NULL , flags );
18051825
18061826 coladd = pos -> coladd ;
18071827 endadd = 0 ;
@@ -1829,7 +1849,7 @@ getvvcol(
18291849 * end = col + endadd ;
18301850 }
18311851 else
1832- getvcol (wp , pos , start , cursor , end );
1852+ getvcol (wp , pos , start , cursor , end , flags );
18331853}
18341854
18351855/*
@@ -1842,19 +1862,20 @@ getvcols(
18421862 pos_T * pos1 ,
18431863 pos_T * pos2 ,
18441864 colnr_T * left ,
1845- colnr_T * right )
1865+ colnr_T * right ,
1866+ int flags )
18461867{
18471868 colnr_T from1 , from2 , to1 , to2 ;
18481869
18491870 if (LT_POSP (pos1 , pos2 ))
18501871 {
1851- getvvcol (wp , pos1 , & from1 , NULL , & to1 );
1852- getvvcol (wp , pos2 , & from2 , NULL , & to2 );
1872+ getvvcol (wp , pos1 , & from1 , NULL , & to1 , flags );
1873+ getvvcol (wp , pos2 , & from2 , NULL , & to2 , flags );
18531874 }
18541875 else
18551876 {
1856- getvvcol (wp , pos2 , & from1 , NULL , & to1 );
1857- getvvcol (wp , pos1 , & from2 , NULL , & to2 );
1877+ getvvcol (wp , pos2 , & from1 , NULL , & to1 , flags );
1878+ getvvcol (wp , pos1 , & from2 , NULL , & to2 , flags );
18581879 }
18591880 if (from2 < from1 )
18601881 * left = from2 ;
0 commit comments