vim-patch:8.1.1960: fold code is spread out (#19777)

Problem:    Fold code is spread out.
Solution:   Move fold functions to fold.c.
db022f3ffb
This commit is contained in:
zeertzjq 2022-08-15 06:33:30 +08:00 committed by GitHub
parent 41d6b8a6d0
commit d3569e8337
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 119 additions and 118 deletions

View File

@ -2418,122 +2418,6 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(fbuf);
}
/// "foldclosed()" function
static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
{
const linenr_T lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
linenr_T first;
linenr_T last;
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;
}
}
rettv->vval.v_number = -1;
}
/// "foldclosed()" function
static void f_foldclosed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, false);
}
/// "foldclosedend()" function
static void f_foldclosedend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, true);
}
/// "foldlevel()" function
static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
rettv->vval.v_number = foldLevel(lnum);
}
}
/// "foldtext()" function
static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
linenr_T foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART);
linenr_T foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND);
char_u *dashes = (char_u *)get_vim_var_str(VV_FOLDDASHES);
if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count) {
// Find first non-empty line in the fold.
linenr_T lnum;
for (lnum = foldstart; lnum < foldend; lnum++) {
if (!linewhite(lnum)) {
break;
}
}
// Find interesting text in this line.
char_u *s = (char_u *)skipwhite((char *)ml_get(lnum));
// skip C comment-start
if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) {
s = (char_u *)skipwhite((char *)s + 2);
if (*skipwhite((char *)s) == NUL && lnum + 1 < foldend) {
s = (char_u *)skipwhite((char *)ml_get(lnum + 1));
if (*s == '*') {
s = (char_u *)skipwhite((char *)s + 1);
}
}
}
int count = foldend - foldstart + 1;
char *txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count);
size_t len = STRLEN(txt)
+ STRLEN(dashes) // for %s
+ 20 // for %3ld
+ STRLEN(s); // concatenated
char_u *r = xmalloc(len);
snprintf((char *)r, len, txt, dashes, count);
len = STRLEN(r);
STRCAT(r, s);
// remove 'foldmarker' and 'commentstring'
foldtext_cleanup(r + len);
rettv->vval.v_string = (char *)r;
}
}
/// "foldtextresult(lnum)" function
static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u buf[FOLD_TEXT_LEN];
static bool entered = false;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
if (entered) {
return; // reject recursive use
}
entered = true;
linenr_T lnum = tv_get_lnum(argvars);
// Treat illegal types and illegal string values for {lnum} the same.
if (lnum < 0) {
lnum = 0;
}
foldinfo_T info = fold_info(curwin, lnum);
if (info.fi_lines > 0) {
char_u *text = get_foldtext(curwin, lnum, lnum + info.fi_lines - 1, info, buf);
if (text == buf) {
text = vim_strsave(text);
}
rettv->vval.v_string = (char *)text;
}
entered = false;
}
/// "foreground()" function
static void f_foreground(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{}

View File

@ -32,6 +32,7 @@
#include "nvim/os/input.h"
#include "nvim/plines.h"
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/undo.h"
@ -247,7 +248,7 @@ bool hasFoldingWin(win_T *const win, const linenr_T lnum, linenr_T *const firstp
// foldLevel() {{{2
/// @return fold level at line number "lnum" in the current window.
int foldLevel(linenr_T lnum)
static int foldLevel(linenr_T lnum)
{
// While updating the folds lines between invalid_top and invalid_bot have
// an undefined fold level. Otherwise update the folds first.
@ -1786,7 +1787,7 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldin
// foldtext_cleanup() {{{2
/// Remove 'foldmarker' and 'commentstring' from "str" (in-place).
void foldtext_cleanup(char_u *str)
static void foldtext_cleanup(char_u *str)
{
// Ignore leading and trailing white space in 'commentstring'.
char_u *cms_start = (char_u *)skipwhite((char *)curbuf->b_p_cms);
@ -3190,3 +3191,119 @@ static int put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off)
}
// }}}1
/// "foldclosed()" and "foldclosedend()" functions
static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
{
const linenr_T lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
linenr_T first;
linenr_T last;
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;
}
}
rettv->vval.v_number = -1;
}
/// "foldclosed()" function
void f_foldclosed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, false);
}
/// "foldclosedend()" function
void f_foldclosedend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, true);
}
/// "foldlevel()" function
void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
const linenr_T lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
rettv->vval.v_number = foldLevel(lnum);
}
}
/// "foldtext()" function
void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
linenr_T foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART);
linenr_T foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND);
char_u *dashes = (char_u *)get_vim_var_str(VV_FOLDDASHES);
if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count) {
// Find first non-empty line in the fold.
linenr_T lnum;
for (lnum = foldstart; lnum < foldend; lnum++) {
if (!linewhite(lnum)) {
break;
}
}
// Find interesting text in this line.
char_u *s = (char_u *)skipwhite((char *)ml_get(lnum));
// skip C comment-start
if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) {
s = (char_u *)skipwhite((char *)s + 2);
if (*skipwhite((char *)s) == NUL && lnum + 1 < foldend) {
s = (char_u *)skipwhite((char *)ml_get(lnum + 1));
if (*s == '*') {
s = (char_u *)skipwhite((char *)s + 1);
}
}
}
int count = foldend - foldstart + 1;
char *txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count);
size_t len = STRLEN(txt)
+ STRLEN(dashes) // for %s
+ 20 // for %3ld
+ STRLEN(s); // concatenated
char_u *r = xmalloc(len);
snprintf((char *)r, len, txt, dashes, count);
len = STRLEN(r);
STRCAT(r, s);
// remove 'foldmarker' and 'commentstring'
foldtext_cleanup(r + len);
rettv->vval.v_string = (char *)r;
}
}
/// "foldtextresult(lnum)" function
void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u buf[FOLD_TEXT_LEN];
static bool entered = false;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
if (entered) {
return; // reject recursive use
}
entered = true;
linenr_T lnum = tv_get_lnum(argvars);
// Treat illegal types and illegal string values for {lnum} the same.
if (lnum < 0) {
lnum = 0;
}
foldinfo_T info = fold_info(curwin, lnum);
if (info.fi_lines > 0) {
char_u *text = get_foldtext(curwin, lnum, lnum + info.fi_lines - 1, info, buf);
if (text == buf) {
text = vim_strsave(text);
}
rettv->vval.v_string = (char *)text;
}
entered = false;
}