From 8516c2dc1f301c439695629fff771227dbe00d30 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Sat, 23 Nov 2024 14:22:06 +0600 Subject: refactor(options): autogenerate valid values and flag enums for options (#31089) Problem: Option metadata like list of valid values for an option and option flags are not listed in the `options.lua` file and are instead manually defined in C, which means option metadata is split between several places. Solution: Put metadata such as list of valid values for an option and option flags in `options.lua`, and autogenerate the corresponding C variables and enums. Supersedes #28659 Co-authored-by: glepnir --- src/nvim/diff.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index f1dd08f0e6..20f93049c1 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -2417,7 +2417,7 @@ int diffopt_changed(void) char *p = p_dip; while (*p != NUL) { - // Note: Keep this in sync with p_dip_values + // Note: Keep this in sync with opt_dip_values. if (strncmp(p, "filler", 6) == 0) { p += 6; diff_flags_new |= DIFF_FILLER; @@ -2464,7 +2464,7 @@ int diffopt_changed(void) p += 8; diff_flags_new |= DIFF_INTERNAL; } else if (strncmp(p, "algorithm:", 10) == 0) { - // Note: Keep this in sync with p_dip_algorithm_values. + // Note: Keep this in sync with opt_dip_algorithm_values. p += 10; if (strncmp(p, "myers", 5) == 0) { p += 5; @@ -2745,7 +2745,7 @@ bool diff_infold(win_T *wp, linenr_T lnum) void nv_diffgetput(bool put, size_t count) { if (bt_prompt(curbuf)) { - vim_beep(BO_OPER); + vim_beep(kOptBoFlagOperator); return; } -- cgit From 2a7d0ed6145bf3f8b139c2694563f460f829813a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 23 Dec 2024 05:43:52 -0800 Subject: refactor: iwyu #31637 Result of `make iwyu` (after some "fixups"). --- src/nvim/diff.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 20f93049c1..bd98a31a71 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -44,6 +44,7 @@ #include "nvim/mbyte.h" #include "nvim/mbyte_defs.h" #include "nvim/memline.h" +#include "nvim/memline_defs.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/move.h" -- cgit From 6257270040bc5c61a489f7fb9d4102223c36cf89 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Fri, 8 Nov 2024 11:57:59 +0600 Subject: refactor(options): set option value for non-current context directly Problem: Currently, we use `switch_option_context` to temporarily switch the current option context before setting an option for a different buffer / window. This is not ideal because we already support getting and setting option values for non-current contexts in the underlying implementation. Solution: Set option value for non-current context by passing the context directly to the lower level functions. Also introduce a new `OptCtx` struct to store option context information, this will scale much better if we add more option scopes and other context information in the future. --- src/nvim/diff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index bd98a31a71..ebeb9ba088 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1391,8 +1391,8 @@ void diff_win_options(win_T *wp, bool addbuf) } wp->w_p_fdm_save = xstrdup(wp->w_p_fdm); } - set_option_direct_for(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("diff"), OPT_LOCAL, 0, - kOptScopeWin, wp); + set_option_direct_for(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("diff"), + option_ctx_from(kOptScopeWin, wp), OPT_LOCAL, 0); if (!wp->w_p_diff) { wp->w_p_fen_save = wp->w_p_fen; -- cgit From 19c9572d3626cde8503ee9061fa334b73f257b03 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 9 Jan 2025 12:32:25 +0800 Subject: Revert "refactor(options): set option value for non-current context directly" (#31924) Reverts #31112 --- src/nvim/diff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index ebeb9ba088..bd98a31a71 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1391,8 +1391,8 @@ void diff_win_options(win_T *wp, bool addbuf) } wp->w_p_fdm_save = xstrdup(wp->w_p_fdm); } - set_option_direct_for(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("diff"), - option_ctx_from(kOptScopeWin, wp), OPT_LOCAL, 0); + set_option_direct_for(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("diff"), OPT_LOCAL, 0, + kOptScopeWin, wp); if (!wp->w_p_diff) { wp->w_p_fen_save = wp->w_p_fen; -- cgit From 718e16536052c0e75de61a32ef237a9e87fc03f2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 16 Jan 2025 09:16:25 +0800 Subject: vim-patch:9.1.1018: v9.1.0743 causes regression with diff mode (#32047) Problem: v9.1.0743 causes regression with diff mode Solution: Fix the regression with overlapping regions closes: vim/vim#16454 https://github.com/vim/vim/commit/01f6509fb2de1627cc4ec2c109cd0aa2e3346d50 Co-authored-by: Yukihiro Nakadaira --- src/nvim/diff.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index bd98a31a71..99f70793b3 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1622,6 +1622,11 @@ static void process_hunk(diff_T **dpp, diff_T **dprevp, int idx_orig, int idx_ne } else { // second overlap of new block with existing block dp->df_count[idx_new] += (linenr_T)hunk->count_new; + if ((dp->df_lnum[idx_new] + dp->df_count[idx_new] - 1) + > curtab->tp_diffbuf[idx_new]->b_ml.ml_line_count) { + dp->df_count[idx_new] = curtab->tp_diffbuf[idx_new]->b_ml.ml_line_count + - dp->df_lnum[idx_new] + 1; + } } // Adjust the size of the block to include all the lines to the @@ -1632,6 +1637,11 @@ static void process_hunk(diff_T **dpp, diff_T **dprevp, int idx_orig, int idx_ne if (off < 0) { // new change ends in existing block, adjust the end dp->df_count[idx_new] += -off; + if ((dp->df_lnum[idx_new] + dp->df_count[idx_new] - 1) + > curtab->tp_diffbuf[idx_new]->b_ml.ml_line_count) { + dp->df_count[idx_new] = curtab->tp_diffbuf[idx_new]->b_ml.ml_line_count + - dp->df_lnum[idx_new] + 1; + } off = 0; } -- cgit From 290bb4c64bdcc475c29b857dc8626f5c51aa2b8d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 3 Feb 2025 21:52:53 +0800 Subject: vim-patch:9.1.1009: diff feature can be improved Problem: diff feature can be improved Solution: include the linematch diff alignment algorithm (Jonathon) closes: vim/vim#9661 https://github.com/vim/vim/commit/7c7a4e6d1ad50d5b25b42aa2d5a33a8d04a4cc8a Co-authored-by: Jonathon --- src/nvim/diff.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 99f70793b3..4ead58c74f 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1820,7 +1820,8 @@ static void find_top_diff_block(diff_T **thistopdiff, diff_T **nextblockblock, i topdiffchange = 0; } - // check if the fromwin topline is matched by the current diff. if so, set it to the top of the diff block + // check if the fromwin topline is matched by the current diff. if so, + // set it to the top of the diff block if (topline >= topdiff->df_lnum[fromidx] && topline <= (topdiff->df_lnum[fromidx] + topdiff->df_count[fromidx])) { // this line is inside the current diff block, so we will save the @@ -2021,10 +2022,15 @@ static void run_linematch_algorithm(diff_T *dp) size_t ndiffs = 0; for (int i = 0; i < DB_COUNT; i++) { if (curtab->tp_diffbuf[i] != NULL) { - // write the contents of the entire buffer to - // diffbufs_mm[diffbuffers_count] - diff_write_buffer(curtab->tp_diffbuf[i], &diffbufs_mm[ndiffs], - dp->df_lnum[i], dp->df_lnum[i] + dp->df_count[i] - 1); + if (dp->df_count[i] > 0) { + // write the contents of the entire buffer to + // diffbufs_mm[diffbuffers_count] + diff_write_buffer(curtab->tp_diffbuf[i], &diffbufs_mm[ndiffs], + dp->df_lnum[i], dp->df_lnum[i] + dp->df_count[i] - 1); + } else { + diffbufs_mm[ndiffs].size = 0; + diffbufs_mm[ndiffs].ptr = NULL; + } diffbufs[ndiffs] = &diffbufs_mm[ndiffs]; @@ -2060,6 +2066,12 @@ static void run_linematch_algorithm(diff_T *dp) /// Returns > 0 for inserting that many filler lines above it (never happens /// when 'diffopt' doesn't contain "filler"). /// This should only be used for windows where 'diff' is set. +/// When diffopt contains linematch, a changed/added/deleted line +/// may also have filler lines above it. In such a case, the possibilities +/// are no longer mutually exclusive. The number of filler lines is +/// returned from diff_check, and the integer 'linestatus' passed by +/// pointer is set to -1 to indicate a changed line, and -2 to indicate an +/// added line /// /// @param wp /// @param lnum -- cgit From 4d0c6cae72716eb88d74361c49dc8baefba22c63 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 3 Feb 2025 22:26:05 +0800 Subject: vim-patch:9.1.1023: Coverity complains about dereferencing NULL pointer Problem: Coverity complains about dereferencing NULL pointer Solution: Verify curdiff is not null before dereferencing it closes: vim/vim#16437 https://github.com/vim/vim/commit/a9f77be9223f8b886d89f7fac778d363586beb85 Co-authored-by: Christian Brabandt --- src/nvim/diff.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 4ead58c74f..ee063a330e 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1866,8 +1866,10 @@ static void count_filler_lines_and_topline(int *curlinenum_to, int *linesfiller, } } else { (*linesfiller) = 0; - ch_virtual_lines = get_max_diff_length(curdif); - isfiller = (curdif->df_count[toidx] ? false : true); + if (curdif) { + ch_virtual_lines = get_max_diff_length(curdif); + isfiller = (curdif->df_count[toidx] ? false : true); + } if (isfiller) { while (curdif && curdif->df_next && curdif->df_lnum[toidx] == curdif->df_next->df_lnum[toidx] -- cgit From bd145a6c8398fb7a3fd037bc71c1bacaeba49584 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 3 Feb 2025 22:26:32 +0800 Subject: vim-patch:9.1.1027: no sanitize check when running linematch Problem: no sanitize check when running linematch Solution: add sanitize check before applying the linematch algorithm, similar to diff_find_change() (Jonathon) closes: vim/vim#16446 https://github.com/vim/vim/commit/ca307efe486670b76563a4a287bc94dace57fb74 Co-authored-by: Jonathon --- src/nvim/diff.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index ee063a330e..68441f7adc 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -2127,7 +2127,8 @@ int diff_check_with_linestatus(win_T *wp, linenr_T lnum, int *linestatus) // Useful for scrollbind calculations which need to count all the filler lines // above the screen. if (lnum >= wp->w_topline && lnum < wp->w_botline - && !dp->is_linematched && diff_linematch(dp)) { + && !dp->is_linematched && diff_linematch(dp) + && diff_check_sanity(curtab, dp)) { run_linematch_algorithm(dp); } -- cgit