diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-12-31 23:58:24 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-12-31 23:58:24 +0100 |
commit | e1e714ef0d1f4bb8b1712795e9106e3b4ff4c7bd (patch) | |
tree | a8140991365c6a83af9d501ef7e471dc0c9160d4 | |
parent | 3d631cb0b34b03c7bdf45ad852d3644c7cf62743 (diff) | |
download | vim-git-e1e714ef0d1f4bb8b1712795e9106e3b4ff4c7bd.tar.gz |
patch 8.1.0671: cursor in the wrong column after auto-formattingv8.1.0671
Problem: Cursor in the wrong column after auto-formatting.
Solution: Check for deleting more spaces than adding. (closes #3748)
-rw-r--r-- | src/mark.c | 7 | ||||
-rw-r--r-- | src/misc1.c | 2 | ||||
-rw-r--r-- | src/ops.c | 13 | ||||
-rw-r--r-- | src/proto/mark.pro | 2 | ||||
-rw-r--r-- | src/testdir/test_textformat.vim | 11 | ||||
-rw-r--r-- | src/version.c | 2 |
6 files changed, 31 insertions, 6 deletions
diff --git a/src/mark.c b/src/mark.c index f9e3ce3cf..e3e209c4a 100644 --- a/src/mark.c +++ b/src/mark.c @@ -1211,6 +1211,8 @@ mark_adjust_internal( posp->lnum += lnum_amount; \ if (col_amount < 0 && posp->col <= (colnr_T)-col_amount) \ posp->col = 0; \ + else if (posp->col < spaces_removed) \ + posp->col = col_amount + spaces_removed; \ else \ posp->col += col_amount; \ } \ @@ -1220,13 +1222,16 @@ mark_adjust_internal( * Adjust marks in line "lnum" at column "mincol" and further: add * "lnum_amount" to the line number and add "col_amount" to the column * position. + * "spaces_removed" is the number of spaces that were removed, matters when the + * cursor is inside them. */ void mark_col_adjust( linenr_T lnum, colnr_T mincol, long lnum_amount, - long col_amount) + long col_amount, + int spaces_removed) { int i; int fnum = curbuf->b_fnum; diff --git a/src/misc1.c b/src/misc1.c index a55275100..00a549d66 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -1705,7 +1705,7 @@ open_line( if (flags & OPENLINE_MARKFIX) mark_col_adjust(curwin->w_cursor.lnum, curwin->w_cursor.col + less_cols_off, - 1L, (long)-less_cols); + 1L, (long)-less_cols, 0); } else changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col); @@ -4707,6 +4707,8 @@ do_join( */ for (t = count - 1; ; --t) { + int spaces_removed; + cend -= currsize; mch_memmove(cend, curr, (size_t)currsize); if (spaces[t] > 0) @@ -4714,8 +4716,13 @@ do_join( cend -= spaces[t]; vim_memset(cend, ' ', (size_t)(spaces[t])); } + + // If deleting more spaces than adding, the cursor moves no more than + // what is added if it is inside these spaces. + spaces_removed = (curr - curr_start) - spaces[t]; + mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t, - (long)(cend - newp + spaces[t] - (curr - curr_start))); + (long)(cend - newp - spaces_removed), spaces_removed); if (t == 0) break; curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1)); @@ -5225,7 +5232,7 @@ format_lines( { (void)del_bytes((long)next_leader_len, FALSE, FALSE); mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L, - (long)-next_leader_len); + (long)-next_leader_len, 0); } else #endif if (second_indent > 0) /* the "leader" for FO_Q_SECOND */ @@ -5236,7 +5243,7 @@ format_lines( { (void)del_bytes(indent, FALSE, FALSE); mark_col_adjust(curwin->w_cursor.lnum, - (colnr_T)0, 0L, (long)-indent); + (colnr_T)0, 0L, (long)-indent, 0); } } curwin->w_cursor.lnum--; diff --git a/src/proto/mark.pro b/src/proto/mark.pro index 623a0599e..150e986c5 100644 --- a/src/proto/mark.pro +++ b/src/proto/mark.pro @@ -21,7 +21,7 @@ void ex_clearjumps(exarg_T *eap); void ex_changes(exarg_T *eap); void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after); void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount, long amount_after); -void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount); +void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount, int spaces_removed); void cleanup_jumplist(win_T *wp, int loadfiles); void copy_jumplist(win_T *from, win_T *to); void free_jumplist(win_T *wp); diff --git a/src/testdir/test_textformat.vim b/src/testdir/test_textformat.vim index 377f761b7..0f8e09532 100644 --- a/src/testdir/test_textformat.vim +++ b/src/testdir/test_textformat.vim @@ -450,5 +450,16 @@ func Test_format_undo() \ ], getline(1, '$')) unmap gg + set tw& enew! endfunc + +func Test_format_list_auto() + new + call setline(1, ['1. abc', '2. def', '3. ghi']) + set fo=tan ai bs=2 + call feedkeys("3G0lli\<BS>\<BS>x\<Esc>", 'tx') + call assert_equal('2. defx ghi', getline(2)) + bwipe! + set fo& ai& bs& +endfunc diff --git a/src/version.c b/src/version.c index 222624124..3de44618f 100644 --- a/src/version.c +++ b/src/version.c @@ -800,6 +800,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 671, +/**/ 670, /**/ 669, |