aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/mark.c
diff options
context:
space:
mode:
authorMatthew Malcomson <hardenedapple@gmail.com>2017-02-27 09:46:50 +0000
committerMatthew Malcomson <hardenedapple@gmail.com>2017-03-23 14:37:47 +0000
commitb2b88423aa0087e5d4aaa122e63dffb97f85222f (patch)
tree66db0a33d4855f16b950a7d9d5981aa65efe7132 /src/nvim/mark.c
parent06ed7a189b2c1dca88f307538b9739b989776068 (diff)
downloadrneovim-b2b88423aa0087e5d4aaa122e63dffb97f85222f.tar.gz
rneovim-b2b88423aa0087e5d4aaa122e63dffb97f85222f.tar.bz2
rneovim-b2b88423aa0087e5d4aaa122e63dffb97f85222f.zip
Robustly handle folds during a :move command
In order to re-order marks according to the :move command, do_move() uses mark_adjust() in a non-standard manner. The non-standard action is that it moves some marks *past* other marks. This doesn't matter for marks, but mark_adjust() calls foldMarkAdjust() which simply changes fold starts and lengths and doesn't have enough information to know that other folds have to be checked and reordered. The array of folds for each window are assumed to be in order of increasing line number, and if this gets broken some folds can get "lost". There has been a previous patch to avoid this problem by deleting and recalculating all folds in the window, but this comes at the cost of closing all folds when executing :move, and doesn't cover the case of manual folds. This patch adds a new function foldMoveRange() specifically for the :move command that handles reordering folds as well as simply moving them. Additionally, we allow calling mark_adjust_nofold() that does the same as mark_adjust() but doesn't affect any fold array. Calling mark_adjust_nofold() should be done in the same manner as calling mark_adjust(), but according changes to the fold arrays must be done seperately by the calling function. vim-patch:8.0.0457 vim-patch:8.0.0459 vim-patch:8.0.0461 vim-patch:8.0.0465
Diffstat (limited to 'src/nvim/mark.c')
-rw-r--r--src/nvim/mark.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 4e05845eb5..de2fdd7f13 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -887,6 +887,23 @@ void ex_changes(exarg_T *eap)
*/
void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
{
+ mark_adjust_internal(line1, line2, amount, amount_after, true);
+}
+
+// mark_adjust_nofold() does the same as mark_adjust() but without adjusting
+// folds in any way. Folds must be adjusted manually by the caller.
+// This is only useful when folds need to be moved in a way different to
+// calling foldMarkAdjust() with arguments line1, line2, amount, amount_after,
+// for an example of why this may be necessary, see do_move().
+void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount,
+ long amount_after)
+{
+ mark_adjust_internal(line1, line2, amount, amount_after, false);
+}
+
+static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount,
+ long amount_after, bool adjust_folds)
+{
int i;
int fnum = curbuf->b_fnum;
linenr_T *lp;
@@ -1011,8 +1028,9 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
}
}
- /* adjust folds */
- foldMarkAdjust(win, line1, line2, amount, amount_after);
+ if (adjust_folds) {
+ foldMarkAdjust(win, line1, line2, amount, amount_after);
+ }
}
}