summaryrefslogtreecommitdiff
path: root/src/syntax.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-05-31 19:48:53 +0200
committerBram Moolenaar <Bram@vim.org>2020-05-31 19:48:53 +0200
commite35a52aee718c881bdfa69a47a1068df6ab6c60a (patch)
tree2b0b7da0fa124d685a6885e2b3476ffd8021e66c /src/syntax.c
parentd881b516da0184052d2f9d33c3f72c5c014316bd (diff)
downloadvim-git-e35a52aee718c881bdfa69a47a1068df6ab6c60a.tar.gz
patch 8.2.0865: syntax foldlevel is taken from the start of the linev8.2.0865
Problem: Syntax foldlevel is taken from the start of the line. Solution: Add ":syn foldlevel" to be able to use the minimal foldlevel in the line. (Brad King, closes #6087)
Diffstat (limited to 'src/syntax.c')
-rw-r--r--src/syntax.c89
1 files changed, 82 insertions, 7 deletions
diff --git a/src/syntax.c b/src/syntax.c
index cda1f953b..f2f74a181 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -30,6 +30,8 @@
static char *(spo_name_tab[SPO_COUNT]) =
{"ms=", "me=", "hs=", "he=", "rs=", "re=", "lc="};
+static char e_illegal_arg[] = N_("E390: Illegal argument: %s");
+
/*
* The patterns that are being searched for are stored in a syn_pattern.
* A match item consists of one pattern.
@@ -3340,7 +3342,7 @@ syn_cmd_conceal(exarg_T *eap UNUSED, int syncing UNUSED)
else if (STRNICMP(arg, "off", 3) == 0 && next - arg == 3)
curwin->w_s->b_syn_conceal = FALSE;
else
- semsg(_("E390: Illegal argument: %s"), arg);
+ semsg(_(e_illegal_arg), arg);
#endif
}
@@ -3370,7 +3372,49 @@ syn_cmd_case(exarg_T *eap, int syncing UNUSED)
else if (STRNICMP(arg, "ignore", 6) == 0 && next - arg == 6)
curwin->w_s->b_syn_ic = TRUE;
else
- semsg(_("E390: Illegal argument: %s"), arg);
+ semsg(_(e_illegal_arg), arg);
+}
+
+/*
+ * Handle ":syntax foldlevel" command.
+ */
+ static void
+syn_cmd_foldlevel(exarg_T *eap, int syncing UNUSED)
+{
+ char_u *arg = eap->arg;
+ char_u *arg_end;
+
+ eap->nextcmd = find_nextcmd(arg);
+ if (eap->skip)
+ return;
+
+ if (*arg == NUL)
+ {
+ switch (curwin->w_s->b_syn_foldlevel)
+ {
+ case SYNFLD_START: msg(_("syntax foldlevel start")); break;
+ case SYNFLD_MINIMUM: msg(_("syntax foldlevel minimum")); break;
+ default: break;
+ }
+ return;
+ }
+
+ arg_end = skiptowhite(arg);
+ if (STRNICMP(arg, "start", 5) == 0 && arg_end - arg == 5)
+ curwin->w_s->b_syn_foldlevel = SYNFLD_START;
+ else if (STRNICMP(arg, "minimum", 7) == 0 && arg_end - arg == 7)
+ curwin->w_s->b_syn_foldlevel = SYNFLD_MINIMUM;
+ else
+ {
+ semsg(_(e_illegal_arg), arg);
+ return;
+ }
+
+ arg = skipwhite(arg_end);
+ if (*arg != NUL)
+ {
+ semsg(_(e_illegal_arg), arg);
+ }
}
/*
@@ -3404,7 +3448,7 @@ syn_cmd_spell(exarg_T *eap, int syncing UNUSED)
curwin->w_s->b_syn_spell = SYNSPL_DEFAULT;
else
{
- semsg(_("E390: Illegal argument: %s"), arg);
+ semsg(_(e_illegal_arg), arg);
return;
}
@@ -3476,6 +3520,7 @@ syntax_clear(synblock_T *block)
block->b_syn_slow = FALSE; // clear previous timeout
#endif
block->b_syn_ic = FALSE; // Use case, by default
+ block->b_syn_foldlevel = SYNFLD_START;
block->b_syn_spell = SYNSPL_DEFAULT; // default spell checking
block->b_syn_containedin = FALSE;
#ifdef FEAT_CONCEAL
@@ -6192,6 +6237,7 @@ static struct subcommand subcommands[] =
{"cluster", syn_cmd_cluster},
{"conceal", syn_cmd_conceal},
{"enable", syn_cmd_enable},
+ {"foldlevel", syn_cmd_foldlevel},
{"include", syn_cmd_include},
{"iskeyword", syn_cmd_iskeyword},
{"keyword", syn_cmd_keyword},
@@ -6489,6 +6535,18 @@ syn_get_stack_item(int i)
#endif
#if defined(FEAT_FOLDING) || defined(PROTO)
+ static int
+syn_cur_foldlevel(void)
+{
+ int level = 0;
+ int i;
+
+ for (i = 0; i < current_state.ga_len; ++i)
+ if (CUR_STATE(i).si_flags & HL_FOLD)
+ ++level;
+ return level;
+}
+
/*
* Function called to get folding level for line "lnum" in window "wp".
*/
@@ -6496,7 +6554,8 @@ syn_get_stack_item(int i)
syn_get_foldlevel(win_T *wp, long lnum)
{
int level = 0;
- int i;
+ int low_level;
+ int cur_level;
// Return quickly when there are no fold items at all.
if (wp->w_s->b_syn_folditems != 0
@@ -6508,9 +6567,25 @@ syn_get_foldlevel(win_T *wp, long lnum)
{
syntax_start(wp, lnum);
- for (i = 0; i < current_state.ga_len; ++i)
- if (CUR_STATE(i).si_flags & HL_FOLD)
- ++level;
+ // Start with the fold level at the start of the line.
+ level = syn_cur_foldlevel();
+
+ if (wp->w_s->b_syn_foldlevel == SYNFLD_MINIMUM)
+ {
+ // Find the lowest fold level that is followed by a higher one.
+ cur_level = level;
+ low_level = cur_level;
+ while (!current_finished)
+ {
+ (void)syn_current_attr(FALSE, FALSE, NULL, FALSE);
+ cur_level = syn_cur_foldlevel();
+ if (cur_level < low_level)
+ low_level = cur_level;
+ else if (cur_level > low_level)
+ level = low_level;
+ ++current_col;
+ }
+ }
}
if (level > wp->w_p_fdn)
{