diff options
author | Matthieu Coudron <mattator@gmail.com> | 2020-01-14 19:50:30 +0100 |
---|---|---|
committer | Matthieu Coudron <mattator@gmail.com> | 2020-02-29 20:27:22 +0100 |
commit | 1a2be57da3f7e33af4e4eb3e0d36569feea71253 (patch) | |
tree | e38b97171e9539644e2be9eb36f02f17be2d13ee | |
parent | 49cd750d6a72efc0571a89d7a874bbb01081227f (diff) | |
download | rneovim-1a2be57da3f7e33af4e4eb3e0d36569feea71253.tar.gz rneovim-1a2be57da3f7e33af4e4eb3e0d36569feea71253.tar.bz2 rneovim-1a2be57da3f7e33af4e4eb3e0d36569feea71253.zip |
foldcolumn: allow auto:X
Similar to signcolumn, allow foldcolumn to adapt itself to the number of
folds.
Regression:
vim supports a maximum fdc of 12, this limits it to 9.
-rw-r--r-- | src/nvim/buffer_defs.h | 10 | ||||
-rw-r--r-- | src/nvim/diff.c | 16 | ||||
-rw-r--r-- | src/nvim/edit.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 5 | ||||
-rw-r--r-- | src/nvim/fold.c | 6 | ||||
-rw-r--r-- | src/nvim/mouse.c | 11 | ||||
-rw-r--r-- | src/nvim/move.c | 2 | ||||
-rw-r--r-- | src/nvim/normal.c | 8 | ||||
-rw-r--r-- | src/nvim/option.c | 24 | ||||
-rw-r--r-- | src/nvim/options.lua | 5 | ||||
-rw-r--r-- | src/nvim/screen.c | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_diffmode.vim | 10 | ||||
-rw-r--r-- | src/nvim/window.c | 25 | ||||
-rw-r--r-- | test/functional/options/num_options_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/ui/fold_spec.lua | 60 |
15 files changed, 144 insertions, 44 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 9cdf36e4ed..1f943b25b6 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -166,11 +166,11 @@ typedef struct { char_u *wo_briopt; # define w_p_briopt w_onebuf_opt.wo_briopt /* 'breakindentopt' */ int wo_diff; -# define w_p_diff w_onebuf_opt.wo_diff /* 'diff' */ - long wo_fdc; -# define w_p_fdc w_onebuf_opt.wo_fdc /* 'foldcolumn' */ - int wo_fdc_save; -# define w_p_fdc_save w_onebuf_opt.wo_fdc_save /* 'foldenable' saved for diff mode */ +# define w_p_diff w_onebuf_opt.wo_diff // 'diff' + char_u *wo_fdc; +# define w_p_fdc w_onebuf_opt.wo_fdc // 'foldcolumn' + char_u *wo_fdc_save; +# define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode int wo_fen; # define w_p_fen w_onebuf_opt.wo_fen /* 'foldenable' */ int wo_fen_save; diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 04309444d9..b8603c27d2 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1385,11 +1385,17 @@ void diff_win_options(win_T *wp, int addbuf) curbuf = curwin->w_buffer; if (!wp->w_p_diff) { - wp->w_p_fdc_save = wp->w_p_fdc; wp->w_p_fen_save = wp->w_p_fen; wp->w_p_fdl_save = wp->w_p_fdl; + + if (wp->w_p_diff_saved) { + free_string_option(wp->w_p_fdc_save); + } + wp->w_p_fdc_save = vim_strsave(wp->w_p_fdc); } - wp->w_p_fdc = diff_foldcolumn; + xfree(wp->w_p_fdc); + wp->w_p_fdc = (char_u *)xstrdup("2"); + snprintf((char *)wp->w_p_fdc, sizeof(wp->w_p_fdc), "%d", diff_foldcolumn); wp->w_p_fen = true; wp->w_p_fdl = 0; foldUpdateAll(wp); @@ -1443,9 +1449,9 @@ void ex_diffoff(exarg_T *eap) wp->w_p_fdm = vim_strsave(*wp->w_p_fdm_save ? wp->w_p_fdm_save : (char_u *)"manual"); - if (wp->w_p_fdc == diff_foldcolumn) { - wp->w_p_fdc = wp->w_p_fdc_save; - } + free_string_option(wp->w_p_fdc); + wp->w_p_fdc = vim_strsave(wp->w_p_fdc_save); + if (wp->w_p_fdl == 0) { wp->w_p_fdl = wp->w_p_fdl_save; } diff --git a/src/nvim/edit.c b/src/nvim/edit.c index e41f9c0381..f938607f17 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -6215,7 +6215,7 @@ comp_textwidth ( if (cmdwin_type != 0) { textwidth -= 1; } - textwidth -= curwin->w_p_fdc; + textwidth -= win_fdccol_count(curwin); textwidth -= win_signcol_count(curwin); if (curwin->w_p_nu || curwin->w_p_rnu) diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index bc6821f60f..fb21774f14 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -4482,8 +4482,9 @@ prepare_tagpreview ( curwin->w_p_wfh = TRUE; RESET_BINDING(curwin); /* don't take over 'scrollbind' and 'cursorbind' */ - curwin->w_p_diff = FALSE; /* no 'diff' */ - curwin->w_p_fdc = 0; /* no 'foldcolumn' */ + curwin->w_p_diff = false; // no 'diff' + set_string_option_direct((char_u *)"fdc", -1, + (char_u *)"0", OPT_FREE, SID_NONE); return true; } } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 331d7f9e29..c14a64fa38 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -1465,10 +1465,10 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2, * Get the lowest 'foldlevel' value that makes the deepest nested fold in the * current window open. */ -int getDeepestNesting(void) +int getDeepestNesting(win_T *wp) { - checkupdate(curwin); - return getDeepestNestingRecurse(&curwin->w_folds); + checkupdate(wp); + return getDeepestNestingRecurse(&wp->w_folds); } static int getDeepestNestingRecurse(garray_T *gap) diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index e395654e04..32d8352d9b 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -73,6 +73,7 @@ int jump_to_mouse(int flags, int col = mouse_col; int grid = mouse_grid; int mouse_char; + int fdc = 0; mouse_past_bottom = false; mouse_past_eol = false; @@ -131,6 +132,7 @@ retnomove: if (wp == NULL) { return IN_UNKNOWN; } + fdc = win_fdccol_count(wp); dragwin = NULL; // winpos and height may change in win_enter()! if (grid == DEFAULT_GRID_HANDLE && row >= wp->w_height) { @@ -165,9 +167,8 @@ retnomove: || (!on_status_line && !on_sep_line && (wp->w_p_rl - ? col < wp->w_width_inner - wp->w_p_fdc - : col >= wp->w_p_fdc + (cmdwin_type == 0 && wp == curwin - ? 0 : 1)) + ? col < wp->w_width_inner - fdc + : col >= fdc + (cmdwin_type == 0 && wp == curwin ? 0 : 1)) && (flags & MOUSE_MAY_STOP_VIS)))) { end_visual_mode(); redraw_curbuf_later(INVERTED); // delete the inversion @@ -305,8 +306,8 @@ retnomove: } // Check for position outside of the fold column. - if (curwin->w_p_rl ? col < curwin->w_width_inner - curwin->w_p_fdc : - col >= curwin->w_p_fdc + (cmdwin_type == 0 ? 0 : 1)) { + if (curwin->w_p_rl ? col < curwin->w_width_inner - fdc : + col >= fdc + (cmdwin_type == 0 ? 0 : 1)) { mouse_char = ' '; } diff --git a/src/nvim/move.c b/src/nvim/move.c index 3ae4f32a83..f47853e9cb 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -674,7 +674,7 @@ int win_col_off(win_T *wp) { return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0) + (cmdwin_type == 0 || wp != curwin ? 0 : 1) - + (int)wp->w_p_fdc + + win_fdccol_count(wp) + (win_signcol_count(wp) * win_signcol_width(wp)); } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index c69b10f99a..6434bd00d8 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -4458,16 +4458,16 @@ dozet: case 'r': curwin->w_p_fdl += cap->count1; { - int d = getDeepestNesting(); + int d = getDeepestNesting(curwin); if (curwin->w_p_fdl >= d) { curwin->w_p_fdl = d; } } break; - /* "zR": open all folds */ - case 'R': curwin->w_p_fdl = getDeepestNesting(); - old_fdl = -1; /* force an update */ + case 'R': // "zR": open all folds + curwin->w_p_fdl = getDeepestNesting(curwin); + old_fdl = -1; // force an update break; case 'j': /* "zj" move to next fold downwards */ diff --git a/src/nvim/option.c b/src/nvim/option.c index 478c9a0ff8..e990cb5214 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -315,6 +315,9 @@ static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2", "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9", "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6", "yes:7", "yes:8", "yes:9", NULL }; +static char *(p_fdc_values[]) = { "auto:1", "auto:2", + "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL }; /// All possible flags for 'shm'. static char_u SHM_ALL[] = { @@ -2322,6 +2325,7 @@ void check_buf_options(buf_T *buf) * Does NOT check for P_ALLOCED flag! */ void free_string_option(char_u *p) + { if (p != empty_option) { xfree(p); @@ -3199,6 +3203,11 @@ ambw_end: if (check_opt_strings(*varp, p_scl_values, false) != OK) { errmsg = e_invarg; } + } else if (varp == &curwin->w_p_fdc || varp == &curwin->w_allbuf_opt.wo_fdc) { + // 'foldcolumn' + if (check_opt_strings(*varp, p_fdc_values, false) != OK) { + errmsg = e_invarg; + } } else if (varp == &p_pt) { // 'pastetoggle': translate key codes like in a mapping if (*p_pt) { @@ -4363,12 +4372,6 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, if (value < 0) { errmsg = e_positive; } - } else if (pp == &curwin->w_p_fdc || pp == &curwin->w_allbuf_opt.wo_fdc) { - if (value < 0) { - errmsg = e_positive; - } else if (value > 12) { - errmsg = e_invarg; - } } else if (pp == &curwin->w_p_cole || pp == &curwin->w_allbuf_opt.wo_cole) { if (value < 0) { errmsg = e_positive; @@ -5936,8 +5939,9 @@ void copy_winopt(winopt_T *from, winopt_T *to) to->wo_diff_saved = from->wo_diff_saved; to->wo_cocu = vim_strsave(from->wo_cocu); to->wo_cole = from->wo_cole; - to->wo_fdc = from->wo_fdc; - to->wo_fdc_save = from->wo_fdc_save; + to->wo_fdc = vim_strsave(from->wo_fdc); + to->wo_fdc_save = from->wo_diff_saved + ? vim_strsave(from->wo_fdc_save) : empty_option; to->wo_fen = from->wo_fen; to->wo_fen_save = from->wo_fen_save; to->wo_fdi = vim_strsave(from->wo_fdi); @@ -5973,6 +5977,8 @@ void check_win_options(win_T *win) */ static void check_winopt(winopt_T *wop) { + check_string_option(&wop->wo_fdc); + check_string_option(&wop->wo_fdc_save); check_string_option(&wop->wo_fdi); check_string_option(&wop->wo_fdm); check_string_option(&wop->wo_fdm_save); @@ -5995,6 +6001,8 @@ static void check_winopt(winopt_T *wop) */ void clear_winopt(winopt_T *wop) { + clear_string_option(&wop->wo_fdc); + clear_string_option(&wop->wo_fdc_save); clear_string_option(&wop->wo_fdi); clear_string_option(&wop->wo_fdm); clear_string_option(&wop->wo_fdm_save); diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 7d080b8d56..c18b9e0697 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -831,10 +831,11 @@ return { }, { full_name='foldcolumn', abbreviation='fdc', - type='number', scope={'window'}, + type='string', scope={'window'}, vi_def=true, + alloced=true, redraw={'current_window'}, - defaults={if_true={vi=false}} + defaults={if_true={vi="0"}} }, { full_name='foldenable', abbreviation='fen', diff --git a/src/nvim/screen.c b/src/nvim/screen.c index b6da02d9c3..7b680e6807 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1744,7 +1744,7 @@ static int advance_color_col(int vcol, int **color_cols) // space is available for window "wp", minus "col". static int compute_foldcolumn(win_T *wp, int col) { - int fdc = wp->w_p_fdc; + int fdc = win_fdccol_count(wp); int wmw = wp == curwin && p_wmw == 0 ? 1 : p_wmw; int wwidth = wp->w_grid.Columns; diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index 21e0271bda..fed642e34b 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -67,7 +67,7 @@ func Common_vert_split() set foldmethod=marker foldcolumn=4 call assert_equal(0, &diff) call assert_equal('marker', &foldmethod) - call assert_equal(4, &foldcolumn) + call assert_equal('4', &foldcolumn) call assert_equal(0, &scrollbind) call assert_equal(0, &cursorbind) call assert_equal(1, &wrap) @@ -76,7 +76,7 @@ func Common_vert_split() vert diffsplit Xtest2 call assert_equal(1, &diff) call assert_equal('diff', &foldmethod) - call assert_equal(2, &foldcolumn) + call assert_equal('2', &foldcolumn) call assert_equal(1, &scrollbind) call assert_equal(1, &cursorbind) call assert_equal(0, &wrap) @@ -142,7 +142,7 @@ func Common_vert_split() 1wincmd w call assert_equal(0, &diff) call assert_equal('marker', &foldmethod) - call assert_equal(4, &foldcolumn) + call assert_equal('4', &foldcolumn) call assert_equal(0, &scrollbind) call assert_equal(0, &cursorbind) call assert_equal(1, &wrap) @@ -150,7 +150,7 @@ func Common_vert_split() wincmd w call assert_equal(0, &diff) call assert_equal('marker', &foldmethod) - call assert_equal(4, &foldcolumn) + call assert_equal('4', &foldcolumn) call assert_equal(0, &scrollbind) call assert_equal(0, &cursorbind) call assert_equal(1, &wrap) @@ -158,7 +158,7 @@ func Common_vert_split() wincmd w call assert_equal(0, &diff) call assert_equal('marker', &foldmethod) - call assert_equal(4, &foldcolumn) + call assert_equal('4', &foldcolumn) call assert_equal(0, &scrollbind) call assert_equal(0, &cursorbind) call assert_equal(1, &wrap) diff --git a/src/nvim/window.c b/src/nvim/window.c index 8181883426..df0033a203 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -618,7 +618,6 @@ void win_set_minimal_style(win_T *wp) wp->w_p_cuc = false; wp->w_p_spell = false; wp->w_p_list = false; - wp->w_p_fdc = 0; // Hide EOB region: use " " fillchar and cleared highlighting if (wp->w_p_fcs_chars.eob != ' ') { @@ -642,6 +641,12 @@ void win_set_minimal_style(win_T *wp) wp->w_p_scl = (char_u *)xstrdup("auto"); } + // foldcolumn: use 'auto' + if (wp->w_p_fdc[0] != '0') { + xfree(wp->w_p_fdc); + wp->w_p_fdc = (char_u *)xstrdup("0"); + } + // colorcolumn: cleared if (wp->w_p_cc != NULL && *wp->w_p_cc != NUL) { xfree(wp->w_p_cc); @@ -689,6 +694,24 @@ void win_check_anchored_floats(win_T *win) } } +/// Return the number of requested fold columns, based on current +/// folds signs and on user configuration. +int win_fdccol_count(win_T *wp) +{ + const char *fdc = (const char *)wp->w_p_fdc; + + // auto:<NUM> + if (strncmp(fdc, "auto:", 5) == 0) { + int needed_fdccols; + needed_fdccols = getDeepestNesting(wp); + int maximum = fdc[5] - '0'; + return MIN(maximum, needed_fdccols); + } else { + return fdc[0] - '0'; + } +} + + static void ui_ext_win_position(win_T *wp) { if (!wp->w_floating) { diff --git a/test/functional/options/num_options_spec.lua b/test/functional/options/num_options_spec.lua index deda5c9118..abb90b3b7c 100644 --- a/test/functional/options/num_options_spec.lua +++ b/test/functional/options/num_options_spec.lua @@ -72,7 +72,7 @@ describe(':set validation', function() should_fail('updatetime', -1, 'E487') should_fail('foldlevel', -5, 'E487') - should_fail('foldcolumn', 13, 'E474') + should_fail('foldcolumn', '13', 'E474') should_fail('conceallevel', 4, 'E474') should_fail('numberwidth', 21, 'E474') should_fail('numberwidth', 0, 'E487') diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua index f178ed1ac7..6ec45064da 100644 --- a/test/functional/ui/fold_spec.lua +++ b/test/functional/ui/fold_spec.lua @@ -295,4 +295,64 @@ describe("folded lines", function() ]]) end) + + it("work with autoresize", function() + + funcs.setline(1, 'line 1') + funcs.setline(2, 'line 2') + funcs.setline(3, 'line 3') + funcs.setline(4, 'line 4') + + feed("zfj") + command("set foldcolumn=0") + screen:expect{grid=[[ + {5:^+-- 2 lines: line 1·························}| + line 3 | + line 4 | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + -- should adapt to the current nesting of folds (e.g., 1) + command("set foldcolumn=auto:1") + screen:expect{grid=[[ + {7:+}{5:^+-- 2 lines: line 1························}| + {7: }line 3 | + {7: }line 4 | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + -- fdc should not change with a new fold as the maximum is 1 + feed("zf3j") + + screen:expect{grid=[[ + {7:+}{5:^+-- 4 lines: line 1························}| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + -- relax the maximum fdc thus fdc should expand to + -- accomodate the current number of folds + command("set foldcolumn=auto:4") + screen:expect{grid=[[ + {7:+ }{5:^+-- 4 lines: line 1·······················}| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + end) end) |