diff options
Diffstat (limited to 'src/fold.c')
-rw-r--r-- | src/fold.c | 181 |
1 files changed, 178 insertions, 3 deletions
diff --git a/src/fold.c b/src/fold.c index 6200578fc..14c664042 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 |