Merge pull request #11716 from teto/folds_auto_backup

[RFC] foldcolumn autowidth
This commit is contained in:
Matthieu Coudron 2020-03-02 13:56:27 +01:00 committed by GitHub
commit d22fd58629
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 149 additions and 50 deletions

View File

@ -527,8 +527,7 @@ FOLDCOLUMN *fold-foldcolumn*
'foldcolumn' is a number, which sets the width for a column on the side of the
window to indicate folds. When it is zero, there is no foldcolumn. A normal
value is 4 or 5. The minimal useful value is 2, although 1 still provides
some information. The maximum is 12.
value is auto:9. The maximum is 9.
An open fold is indicated with a column that has a '-' at the top and '|'
characters below it. This column stops where the open fold stops. When folds

View File

@ -2421,11 +2421,14 @@ A jump table for the options with a short description can be found at |Q_op|.
automatically close when moving out of them.
*'foldcolumn'* *'fdc'*
'foldcolumn' 'fdc' number (default 0)
'foldcolumn' 'fdc' string (default "0")
local to window
When non-zero, a column with the specified width is shown at the side
of the window which indicates open and closed folds. The maximum
value is 12.
When and how to draw the foldcolumn. Valid values are:
"auto": resize to the maximum amount of folds to display.
"auto:[1-9]": resize to accommodate multiple folds up to the
selected level
0: to disable foldcolumn
"[1-9]": to display a fixed number of columns
See |folding|.
*'foldenable'* *'fen'* *'nofoldenable'* *'nofen'*

View File

@ -201,6 +201,7 @@ Options:
'guicursor' works in the terminal
'fillchars' flags: "msgsep" (see 'display'), "eob" for |hl-EndOfBuffer|
marker, "foldopen", "foldsep", "foldclose"
'foldcolumn' supports up to 9 dynamic/fixed columns
'inccommand' shows interactive results for |:substitute|-like commands
'listchars' local to window
'pumblend' pseudo-transparent popupmenu

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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, // no 'foldcolumn'
(char_u *)"0", OPT_FREE, SID_NONE);
return true;
}
}

View File

@ -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)

View File

@ -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 = ' ';
}

View File

@ -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));
}

View File

@ -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 */

View File

@ -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[] = {
@ -3199,6 +3202,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 +4371,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 +5938,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 +5976,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 +6000,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);

View File

@ -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',

View File

@ -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;

View File

@ -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)

View File

@ -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,21 @@ void win_check_anchored_floats(win_T *win)
}
}
/// Return the number of fold columns to display
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 = getDeepestNesting(wp);
return MIN(fdc[5] - '0', needed_fdccols);
} else {
return fdc[0] - '0';
}
}
static void ui_ext_win_position(win_T *wp)
{
if (!wp->w_floating) {

View File

@ -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')

View File

@ -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)