aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Coudron <mattator@gmail.com>2020-01-14 19:50:30 +0100
committerMatthieu Coudron <mattator@gmail.com>2020-02-29 20:27:22 +0100
commit1a2be57da3f7e33af4e4eb3e0d36569feea71253 (patch)
treee38b97171e9539644e2be9eb36f02f17be2d13ee
parent49cd750d6a72efc0571a89d7a874bbb01081227f (diff)
downloadrneovim-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.h10
-rw-r--r--src/nvim/diff.c16
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/ex_cmds.c5
-rw-r--r--src/nvim/fold.c6
-rw-r--r--src/nvim/mouse.c11
-rw-r--r--src/nvim/move.c2
-rw-r--r--src/nvim/normal.c8
-rw-r--r--src/nvim/option.c24
-rw-r--r--src/nvim/options.lua5
-rw-r--r--src/nvim/screen.c2
-rw-r--r--src/nvim/testdir/test_diffmode.vim10
-rw-r--r--src/nvim/window.c25
-rw-r--r--test/functional/options/num_options_spec.lua2
-rw-r--r--test/functional/ui/fold_spec.lua60
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)