@@ -174,6 +174,7 @@ static void nv_drop __ARGS((cmdarg_T *cap));
174174#ifdef FEAT_AUTOCMD
175175static void nv_cursorhold __ARGS ((cmdarg_T * cap ));
176176#endif
177+ static void get_op_vcol __ARGS ((oparg_T * oap , colnr_T col , int initial ));
177178
178179static char * e_noident = N_ ("E349: No identifier under cursor" );
179180
@@ -1418,6 +1419,8 @@ do_pending_operator(cap, old_col, gui_yank)
14181419 {
14191420#ifdef FEAT_LINEBREAK
14201421 /* Avoid a problem with unwanted linebreaks in block mode. */
1422+ if (curwin -> w_p_lbr )
1423+ curwin -> w_valid &= ~VALID_VIRTCOL ;
14211424 curwin -> w_p_lbr = FALSE;
14221425#endif
14231426 oap -> is_VIsual = VIsual_active ;
@@ -1631,61 +1634,7 @@ do_pending_operator(cap, old_col, gui_yank)
16311634
16321635 if (VIsual_active || redo_VIsual_busy )
16331636 {
1634- if (VIsual_mode == Ctrl_V ) /* block mode */
1635- {
1636- colnr_T start , end ;
1637-
1638- oap -> block_mode = TRUE;
1639-
1640- getvvcol (curwin , & (oap -> start ),
1641- & oap -> start_vcol , NULL , & oap -> end_vcol );
1642- if (!redo_VIsual_busy )
1643- {
1644- getvvcol (curwin , & (oap -> end ), & start , NULL , & end );
1645-
1646- if (start < oap -> start_vcol )
1647- oap -> start_vcol = start ;
1648- if (end > oap -> end_vcol )
1649- {
1650- if (* p_sel == 'e' && start >= 1
1651- && start - 1 >= oap -> end_vcol )
1652- oap -> end_vcol = start - 1 ;
1653- else
1654- oap -> end_vcol = end ;
1655- }
1656- }
1657-
1658- /* if '$' was used, get oap->end_vcol from longest line */
1659- if (curwin -> w_curswant == MAXCOL )
1660- {
1661- curwin -> w_cursor .col = MAXCOL ;
1662- oap -> end_vcol = 0 ;
1663- for (curwin -> w_cursor .lnum = oap -> start .lnum ;
1664- curwin -> w_cursor .lnum <= oap -> end .lnum ;
1665- ++ curwin -> w_cursor .lnum )
1666- {
1667- getvvcol (curwin , & curwin -> w_cursor , NULL , NULL , & end );
1668- if (end > oap -> end_vcol )
1669- oap -> end_vcol = end ;
1670- }
1671- }
1672- else if (redo_VIsual_busy )
1673- oap -> end_vcol = oap -> start_vcol + redo_VIsual_vcol - 1 ;
1674- /*
1675- * Correct oap->end.col and oap->start.col to be the
1676- * upper-left and lower-right corner of the block area.
1677- *
1678- * (Actually, this does convert column positions into character
1679- * positions)
1680- */
1681- curwin -> w_cursor .lnum = oap -> end .lnum ;
1682- coladvance (oap -> end_vcol );
1683- oap -> end = curwin -> w_cursor ;
1684-
1685- curwin -> w_cursor = oap -> start ;
1686- coladvance (oap -> start_vcol );
1687- oap -> start = curwin -> w_cursor ;
1688- }
1637+ get_op_vcol (oap , redo_VIsual_vcol , TRUE);
16891638
16901639 if (!redo_VIsual_busy && !gui_yank )
16911640 {
@@ -1982,7 +1931,11 @@ do_pending_operator(cap, old_col, gui_yank)
19821931#ifdef FEAT_LINEBREAK
19831932 /* Restore linebreak, so that when the user edits it looks as
19841933 * before. */
1985- curwin -> w_p_lbr = lbr_saved ;
1934+ if (curwin -> w_p_lbr != lbr_saved )
1935+ {
1936+ curwin -> w_p_lbr = lbr_saved ;
1937+ get_op_vcol (oap , redo_VIsual_mode , FALSE);
1938+ }
19861939#endif
19871940 /* Reset finish_op now, don't want it set inside edit(). */
19881941 finish_op = FALSE;
@@ -2082,7 +2035,11 @@ do_pending_operator(cap, old_col, gui_yank)
20822035#ifdef FEAT_LINEBREAK
20832036 /* Restore linebreak, so that when the user edits it looks as
20842037 * before. */
2085- curwin -> w_p_lbr = lbr_saved ;
2038+ if (curwin -> w_p_lbr != lbr_saved )
2039+ {
2040+ curwin -> w_p_lbr = lbr_saved ;
2041+ get_op_vcol (oap , redo_VIsual_mode , FALSE);
2042+ }
20862043#endif
20872044 op_insert (oap , cap -> count1 );
20882045#ifdef FEAT_LINEBREAK
@@ -2114,11 +2071,15 @@ do_pending_operator(cap, old_col, gui_yank)
21142071#ifdef FEAT_VISUALEXTRA
21152072 else
21162073 {
2117- #ifdef FEAT_LINEBREAK
2074+ # ifdef FEAT_LINEBREAK
21182075 /* Restore linebreak, so that when the user edits it looks as
21192076 * before. */
2120- curwin -> w_p_lbr = lbr_saved ;
2121- #endif
2077+ if (curwin -> w_p_lbr != lbr_saved )
2078+ {
2079+ curwin -> w_p_lbr = lbr_saved ;
2080+ get_op_vcol (oap , redo_VIsual_mode , FALSE);
2081+ }
2082+ # endif
21222083 op_replace (oap , cap -> nchar );
21232084 }
21242085#endif
@@ -9576,3 +9537,70 @@ nv_cursorhold(cap)
95769537 cap -> retval |= CA_COMMAND_BUSY ; /* don't call edit() now */
95779538}
95789539#endif
9540+
9541+ /*
9542+ * calculate start/end virtual columns for operating in block mode
9543+ */
9544+ static void
9545+ get_op_vcol (oap , redo_VIsual_vcol , initial )
9546+ oparg_T * oap ;
9547+ colnr_T redo_VIsual_vcol ;
9548+ int initial ; /* when true: adjust position for 'selectmode' */
9549+ {
9550+ colnr_T start , end ;
9551+
9552+ if (VIsual_mode != Ctrl_V )
9553+ return ;
9554+
9555+ oap -> block_mode = TRUE;
9556+
9557+ #ifdef FEAT_MBYTE
9558+ /* prevent from moving onto a trail byte */
9559+ if (has_mbyte )
9560+ mb_adjustpos (curwin -> w_buffer , & oap -> end );
9561+ #endif
9562+
9563+ getvvcol (curwin , & (oap -> start ), & oap -> start_vcol , NULL , & oap -> end_vcol );
9564+ getvvcol (curwin , & (oap -> end ), & start , NULL , & end );
9565+
9566+ if (start < oap -> start_vcol )
9567+ oap -> start_vcol = start ;
9568+ if (end > oap -> end_vcol )
9569+ {
9570+ if (initial && * p_sel == 'e' && start >= 1
9571+ && start - 1 >= oap -> end_vcol )
9572+ oap -> end_vcol = start - 1 ;
9573+ else
9574+ oap -> end_vcol = end ;
9575+ }
9576+ /* if '$' was used, get oap->end_vcol from longest line */
9577+ if (curwin -> w_curswant == MAXCOL )
9578+ {
9579+ curwin -> w_cursor .col = MAXCOL ;
9580+ oap -> end_vcol = 0 ;
9581+ for (curwin -> w_cursor .lnum = oap -> start .lnum ;
9582+ curwin -> w_cursor .lnum <= oap -> end .lnum ;
9583+ ++ curwin -> w_cursor .lnum )
9584+ {
9585+ getvvcol (curwin , & curwin -> w_cursor , NULL , NULL , & end );
9586+ if (end > oap -> end_vcol )
9587+ oap -> end_vcol = end ;
9588+ }
9589+ }
9590+ else if (redo_VIsual_busy )
9591+ oap -> end_vcol = oap -> start_vcol + redo_VIsual_vcol - 1 ;
9592+ /*
9593+ * Correct oap->end.col and oap->start.col to be the
9594+ * upper-left and lower-right corner of the block area.
9595+ *
9596+ * (Actually, this does convert column positions into character
9597+ * positions)
9598+ */
9599+ curwin -> w_cursor .lnum = oap -> end .lnum ;
9600+ coladvance (oap -> end_vcol );
9601+ oap -> end = curwin -> w_cursor ;
9602+
9603+ curwin -> w_cursor = oap -> start ;
9604+ coladvance (oap -> start_vcol );
9605+ oap -> start = curwin -> w_cursor ;
9606+ }
0 commit comments