summaryrefslogtreecommitdiffstats
path: root/src/fold.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-09-01 17:52:32 +0200
committerBram Moolenaar <Bram@vim.org>2019-09-01 17:52:32 +0200
commitdb022f3ffb57c5ff4b97b4e93a994d11e4c10466 (patch)
treeff0dacb002fe1224be8ebd9f6ac8f88e786cc73f /src/fold.c
parenta112f2d0035b0800b4a70dbb6f0e5f85e8ec84e5 (diff)
patch 8.1.1960: fold code is spread outv8.1.1960
Problem: Fold code is spread out. Solution: Move fold functions to fold.c.
Diffstat (limited to 'src/fold.c')
-rw-r--r--src/fold.c181
1 files changed, 178 insertions, 3 deletions
diff --git a/src/fold.c b/src/fold.c
index 6200578fce..14c6640429 100644
--- a/src/fold.c
+++ b/src/fold.c
@@ -244,10 +244,11 @@ hasFoldingWin(
}
/* foldLevel() {{{2 */
+#ifdef FEAT_EVAL
/*
* Return fold level at line number "lnum" in the current window.
*/
- int
+ static int
foldLevel(linenr_T lnum)
{
/* While updating the folds lines between invalid_top and invalid_bot have
@@ -265,6 +266,7 @@ foldLevel(linenr_T lnum)
return foldLevelWin(curwin, lnum);
}
+#endif
/* lineFolded() {{{2 */
/*
@@ -1989,10 +1991,11 @@ get_foldtext(
}
/* foldtext_cleanup() {{{2 */
+#ifdef FEAT_EVAL
/*
* Remove 'foldmarker' and 'commentstring' from "str" (in-place).
*/
- void
+ static void
foldtext_cleanup(char_u *str)
{
char_u *cms_start; /* first part or the whole comment */
@@ -2078,6 +2081,7 @@ foldtext_cleanup(char_u *str)
}
}
}
+#endif
/* Folding by indent, expr, marker and syntax. {{{1 */
/* Define "fline_T", passed to get fold level for a line. {{{2 */
@@ -3616,4 +3620,175 @@ put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off)
#endif /* FEAT_SESSION */
/* }}}1 */
-#endif /* defined(FEAT_FOLDING) || defined(PROTO) */
+#endif // defined(FEAT_FOLDING) || defined(PROTO)
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+
+/*
+ * "foldclosed()" and "foldclosedend()" functions
+ */
+ static void
+foldclosed_both(
+ typval_T *argvars UNUSED,
+ typval_T *rettv,
+ int end UNUSED)
+{
+# ifdef FEAT_FOLDING
+ linenr_T lnum;
+ linenr_T first, last;
+
+ lnum = tv_get_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+ {
+ if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL))
+ {
+ if (end)
+ rettv->vval.v_number = (varnumber_T)last;
+ else
+ rettv->vval.v_number = (varnumber_T)first;
+ return;
+ }
+ }
+#endif
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * "foldclosed()" function
+ */
+ void
+f_foldclosed(typval_T *argvars, typval_T *rettv)
+{
+ foldclosed_both(argvars, rettv, FALSE);
+}
+
+/*
+ * "foldclosedend()" function
+ */
+ void
+f_foldclosedend(typval_T *argvars, typval_T *rettv)
+{
+ foldclosed_both(argvars, rettv, TRUE);
+}
+
+/*
+ * "foldlevel()" function
+ */
+ void
+f_foldlevel(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+{
+# ifdef FEAT_FOLDING
+ linenr_T lnum;
+
+ lnum = tv_get_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+ rettv->vval.v_number = foldLevel(lnum);
+# endif
+}
+
+/*
+ * "foldtext()" function
+ */
+ void
+f_foldtext(typval_T *argvars UNUSED, typval_T *rettv)
+{
+# ifdef FEAT_FOLDING
+ linenr_T foldstart;
+ linenr_T foldend;
+ char_u *dashes;
+ linenr_T lnum;
+ char_u *s;
+ char_u *r;
+ int len;
+ char *txt;
+ long count;
+# endif
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+# ifdef FEAT_FOLDING
+ foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART);
+ foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND);
+ dashes = get_vim_var_str(VV_FOLDDASHES);
+ if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count
+ && dashes != NULL)
+ {
+ // Find first non-empty line in the fold.
+ for (lnum = foldstart; lnum < foldend; ++lnum)
+ if (!linewhite(lnum))
+ break;
+
+ // Find interesting text in this line.
+ s = skipwhite(ml_get(lnum));
+ // skip C comment-start
+ if (s[0] == '/' && (s[1] == '*' || s[1] == '/'))
+ {
+ s = skipwhite(s + 2);
+ if (*skipwhite(s) == NUL
+ && lnum + 1 < (linenr_T)get_vim_var_nr(VV_FOLDEND))
+ {
+ s = skipwhite(ml_get(lnum + 1));
+ if (*s == '*')
+ s = skipwhite(s + 1);
+ }
+ }
+ count = (long)(foldend - foldstart + 1);
+ txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count);
+ r = alloc(STRLEN(txt)
+ + STRLEN(dashes) // for %s
+ + 20 // for %3ld
+ + STRLEN(s)); // concatenated
+ if (r != NULL)
+ {
+ sprintf((char *)r, txt, dashes, count);
+ len = (int)STRLEN(r);
+ STRCAT(r, s);
+ // remove 'foldmarker' and 'commentstring'
+ foldtext_cleanup(r + len);
+ rettv->vval.v_string = r;
+ }
+ }
+# endif
+}
+
+/*
+ * "foldtextresult(lnum)" function
+ */
+ void
+f_foldtextresult(typval_T *argvars UNUSED, typval_T *rettv)
+{
+# ifdef FEAT_FOLDING
+ linenr_T lnum;
+ char_u *text;
+ char_u buf[FOLD_TEXT_LEN];
+ foldinfo_T foldinfo;
+ int fold_count;
+ static int entered = FALSE;
+# endif
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+# ifdef FEAT_FOLDING
+ if (entered)
+ return; // reject recursive use
+ entered = TRUE;
+
+ lnum = tv_get_lnum(argvars);
+ // treat illegal types and illegal string values for {lnum} the same
+ if (lnum < 0)
+ lnum = 0;
+ fold_count = foldedCount(curwin, lnum, &foldinfo);
+ if (fold_count > 0)
+ {
+ text = get_foldtext(curwin, lnum, lnum + fold_count - 1,
+ &foldinfo, buf);
+ if (text == buf)
+ text = vim_strsave(text);
+ rettv->vval.v_string = text;
+ }
+
+ entered = FALSE;
+# endif
+}
+
+#endif // FEAT_EVAL