From b2b88423aa0087e5d4aaa122e63dffb97f85222f Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Mon, 27 Feb 2017 09:46:50 +0000 Subject: 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 --- src/nvim/mark.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/nvim/mark.c') 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 @@ -886,6 +886,23 @@ void ex_changes(exarg_T *eap) * or: mark_adjust(56, 55, MAXLNUM, 2); */ 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; @@ -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); + } } } -- cgit From fb146e80aa1ead96518f38b9684e39249bc83485 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 26 Jul 2016 23:16:23 +0300 Subject: eval: Split eval.c into smaller files --- src/nvim/mark.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/nvim/mark.c') diff --git a/src/nvim/mark.c b/src/nvim/mark.c index de2fdd7f13..1d1e13e7e0 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1431,3 +1431,26 @@ void free_all_marks(void) memset(&namedfm[0], 0, sizeof(namedfm)); } #endif + +/// Adjust position to point to the first byte of a multi-byte character +/// +/// If it points to a tail byte it is move backwards to the head byte. +/// +/// @param[in] buf Buffer to adjust position in. +/// @param[out] lp Position to adjust. +void mark_mb_adjustpos(buf_T *buf, pos_T *lp) + FUNC_ATTR_NONNULL_ALL +{ + if (lp->col > 0 || lp->coladd > 1) { + const char_u *const p = ml_get_buf(buf, lp->lnum, false); + lp->col -= (*mb_head_off)(p, p + lp->col); + // Reset "coladd" when the cursor would be on the right half of a + // double-wide character. + if (lp->coladd == 1 + && p[lp->col] != TAB + && vim_isprintc((*mb_ptr2char)(p + lp->col)) + && ptr2cells(p + lp->col) > 1) { + lp->coladd = 0; + } + } +} -- cgit From e18a5783080f7c94f408ec5f53dedffdb69789e1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 20 Aug 2016 22:24:34 +0300 Subject: *: Move some dictionary functions to typval.h and use char* Also fixes buffer reusage in setmatches() and complete(). --- src/nvim/mark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/mark.c') diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 1d1e13e7e0..ae94ec7ecd 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -62,7 +62,7 @@ int setmark(int c) /// Free fmark_T item void free_fmark(fmark_T fm) { - dict_unref(fm.additional_data); + tv_dict_unref(fm.additional_data); } /// Free xfmark_T item -- cgit From c2f3e361c52ec4e7149ea1d8c6a1202e0873da8e Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 19 Apr 2017 19:11:50 +0300 Subject: *: Add comment to all C files --- src/nvim/mark.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/nvim/mark.c') diff --git a/src/nvim/mark.c b/src/nvim/mark.c index ae94ec7ecd..675fe4d57f 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + /* * mark.c: functions for setting marks and jumping to them */ -- cgit From 8b375cf471359ad7632af7fa6a2298c9b7596691 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 28 Aug 2016 15:36:18 +0200 Subject: bufhl: fix move --- src/nvim/mark.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/nvim/mark.c') diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 675fe4d57f..7889fabd45 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -888,9 +888,13 @@ void ex_changes(exarg_T *eap) * Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0); * or: mark_adjust(56, 55, MAXLNUM, 2); */ -void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) +void mark_adjust(linenr_T line1, + linenr_T line2, + long amount, + long amount_after, + bool end_temp) { - mark_adjust_internal(line1, line2, amount, amount_after, true); + mark_adjust_internal(line1, line2, amount, amount_after, true, end_temp); } // mark_adjust_nofold() does the same as mark_adjust() but without adjusting @@ -899,13 +903,14 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) // 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) + long amount_after, bool end_temp) { - mark_adjust_internal(line1, line2, amount, amount_after, false); + mark_adjust_internal(line1, line2, amount, amount_after, false, end_temp); } -static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, - long amount_after, bool adjust_folds) +static void mark_adjust_internal(linenr_T line1, linenr_T line2, + long amount, long amount_after, + bool adjust_folds, bool end_temp) { int i; int fnum = curbuf->b_fnum; @@ -954,7 +959,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, } sign_mark_adjust(line1, line2, amount, amount_after); - bufhl_mark_adjust(curbuf, line1, line2, amount, amount_after); + bufhl_mark_adjust(curbuf, line1, line2, amount, amount_after, end_temp); } /* previous context mark */ -- cgit From ff819d8ad72b6a7404d28707f1f9ef460c35c472 Mon Sep 17 00:00:00 2001 From: Lech Lorens Date: Sun, 1 Oct 2017 15:37:27 +0200 Subject: quickfix: fix location list updates. Fix quickfix performance optimization which prevented quickfix items from being updated when there were multiple windows with location lists but the buffer with errors only in one of the lists. --- src/nvim/mark.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/nvim/mark.c') diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 7889fabd45..1ba400972c 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -951,11 +951,17 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, one_adjust_nodel(&(curbuf->b_visual.vi_start.lnum)); one_adjust_nodel(&(curbuf->b_visual.vi_end.lnum)); - /* quickfix marks */ - qf_mark_adjust(NULL, line1, line2, amount, amount_after); - /* location lists */ + // quickfix marks + if (!qf_mark_adjust(NULL, line1, line2, amount, amount_after)) { + curbuf->b_has_qf_entry &= ~BUF_HAS_QF_ENTRY; + } + // location lists + bool found_one = false; FOR_ALL_TAB_WINDOWS(tab, win) { - qf_mark_adjust(win, line1, line2, amount, amount_after); + found_one |= qf_mark_adjust(win, line1, line2, amount, amount_after); + } + if (!found_one) { + curbuf->b_has_qf_entry &= ~BUF_HAS_LL_ENTRY; } sign_mark_adjust(line1, line2, amount, amount_after); -- cgit