aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/fold.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/fold.c')
-rw-r--r--src/nvim/fold.c191
1 files changed, 106 insertions, 85 deletions
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 1872558669..7306131574 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -5,10 +5,15 @@
// fold.c: code for folding
+#include <assert.h>
#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "nvim/ascii.h"
+#include "nvim/buffer_defs.h"
#include "nvim/buffer_updates.h"
#include "nvim/change.h"
#include "nvim/charset.h"
@@ -16,14 +21,17 @@
#include "nvim/diff.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
-#include "nvim/ex_docmd.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/typval_defs.h"
#include "nvim/ex_session.h"
#include "nvim/extmark.h"
#include "nvim/fold.h"
-#include "nvim/func_attr.h"
#include "nvim/garray.h"
+#include "nvim/gettext.h"
+#include "nvim/globals.h"
#include "nvim/indent.h"
#include "nvim/mark.h"
+#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
@@ -35,6 +43,7 @@
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
+#include "nvim/types.h"
#include "nvim/undo.h"
#include "nvim/vim.h"
@@ -57,9 +66,11 @@ typedef struct {
// folds too
} fold_T;
-#define FD_OPEN 0 // fold is open (nested ones can be closed)
-#define FD_CLOSED 1 // fold is closed
-#define FD_LEVEL 2 // depends on 'foldlevel' (nested folds too)
+enum {
+ FD_OPEN = 0, // fold is open (nested ones can be closed)
+ FD_CLOSED = 1, // fold is closed
+ FD_LEVEL = 2, // depends on 'foldlevel' (nested folds too)
+};
#define MAX_LEVEL 20 // maximum fold depth
@@ -466,12 +477,15 @@ static void newFoldLevelWin(win_T *wp)
/// Apply 'foldlevel' to all folds that don't contain the cursor.
void foldCheckClose(void)
{
- if (*p_fcl != NUL) { // can only be "all" right now
- checkupdate(curwin);
- if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
- (int)curwin->w_p_fdl)) {
- changed_window_setting();
- }
+ if (*p_fcl == NUL) {
+ return;
+ }
+
+ // 'foldclose' can only be "all" right now
+ checkupdate(curwin);
+ if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
+ (int)curwin->w_p_fdl)) {
+ changed_window_setting();
}
}
@@ -994,15 +1008,18 @@ void foldAdjustVisual(void)
if (hasFolding(start->lnum, &start->lnum, NULL)) {
start->col = 0;
}
- if (hasFolding(end->lnum, NULL, &end->lnum)) {
- ptr = ml_get(end->lnum);
- end->col = (colnr_T)strlen(ptr);
- if (end->col > 0 && *p_sel == 'o') {
- end->col--;
- }
- // prevent cursor from moving on the trail byte
- mb_adjust_cursor();
+
+ if (!hasFolding(end->lnum, NULL, &end->lnum)) {
+ return;
+ }
+
+ ptr = ml_get(end->lnum);
+ end->col = (colnr_T)strlen(ptr);
+ if (end->col > 0 && *p_sel == 'o') {
+ end->col--;
}
+ // prevent cursor from moving on the trail byte
+ mb_adjust_cursor();
}
// cursor_foldstart() {{{2
@@ -1083,7 +1100,7 @@ static int foldLevelWin(win_T *wp, linenr_T lnum)
{
fold_T *fp;
linenr_T lnum_rel = lnum;
- int level = 0;
+ int level = 0;
// Recursively search for a fold that contains "lnum".
garray_T *gap = &wp->w_folds;
@@ -1104,10 +1121,12 @@ static int foldLevelWin(win_T *wp, linenr_T lnum)
/// Check if the folds in window "wp" are invalid and update them if needed.
static void checkupdate(win_T *wp)
{
- if (wp->w_foldinvalid) {
- foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); // will update all
- wp->w_foldinvalid = false;
+ if (!wp->w_foldinvalid) {
+ return;
}
+
+ foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); // will update all
+ wp->w_foldinvalid = false;
}
// setFoldRepeat() {{{2
@@ -1425,15 +1444,13 @@ static void foldMarkAdjustRecurse(win_T *wp, garray_T *gap, linenr_T line1, line
// 5. fold is below line1 and contains line2; need to
// correct nested folds too
if (amount == MAXLNUM) {
- foldMarkAdjustRecurse(wp, &fp->fd_nested, line1 - fp->fd_top,
- line2 - fp->fd_top, amount,
- amount_after + (fp->fd_top - top));
+ foldMarkAdjustRecurse(wp, &fp->fd_nested, 0, line2 - fp->fd_top,
+ amount, amount_after + (fp->fd_top - top));
fp->fd_len -= line2 - fp->fd_top + 1;
fp->fd_top = line1;
} else {
- foldMarkAdjustRecurse(wp, &fp->fd_nested, line1 - fp->fd_top,
- line2 - fp->fd_top, amount,
- amount_after - amount);
+ foldMarkAdjustRecurse(wp, &fp->fd_nested, 0, line2 - fp->fd_top,
+ amount, amount_after - amount);
fp->fd_len += amount_after - amount;
fp->fd_top += amount;
}
@@ -1514,23 +1531,25 @@ static bool check_closed(win_T *const wp, fold_T *const fp, bool *const use_leve
/// @param lnum_off offset for fp->fd_top
static void checkSmall(win_T *const wp, fold_T *const fp, const linenr_T lnum_off)
{
- if (fp->fd_small == kNone) {
- // Mark any nested folds to maybe-small
- setSmallMaybe(&fp->fd_nested);
+ if (fp->fd_small != kNone) {
+ return;
+ }
- if (fp->fd_len > wp->w_p_fml) {
- fp->fd_small = kFalse;
- } else {
- int count = 0;
- for (int n = 0; n < fp->fd_len; n++) {
- count += plines_win_nofold(wp, fp->fd_top + lnum_off + n);
- if (count > wp->w_p_fml) {
- fp->fd_small = kFalse;
- return;
- }
+ // Mark any nested folds to maybe-small
+ setSmallMaybe(&fp->fd_nested);
+
+ if (fp->fd_len > wp->w_p_fml) {
+ fp->fd_small = kFalse;
+ } else {
+ int count = 0;
+ for (int n = 0; n < fp->fd_len; n++) {
+ count += plines_win_nofold(wp, fp->fd_top + lnum_off + n);
+ if (count > wp->w_p_fml) {
+ fp->fd_small = kFalse;
+ return;
}
- fp->fd_small = kTrue;
}
+ fp->fd_small = kTrue;
}
}
@@ -1583,29 +1602,31 @@ static void foldAddMarker(buf_T *buf, pos_T pos, const char *marker, size_t mark
// Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end
char *line = ml_get_buf(buf, lnum, false);
- size_t line_len = STRLEN(line);
+ size_t line_len = strlen(line);
size_t added = 0;
- if (u_save(lnum - 1, lnum + 1) == OK) {
- // Check if the line ends with an unclosed comment
- skip_comment(line, false, false, &line_is_comment);
- newline = xmalloc(line_len + markerlen + strlen(cms) + 1);
- STRCPY(newline, line);
- // Append the marker to the end of the line
- if (p == NULL || line_is_comment) {
- STRLCPY(newline + line_len, marker, markerlen + 1);
- added = markerlen;
- } else {
- STRCPY(newline + line_len, cms);
- memcpy(newline + line_len + (p - cms), marker, markerlen);
- STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
- added = markerlen + strlen(cms) - 2;
- }
- ml_replace_buf(buf, lnum, newline, false);
- if (added) {
- extmark_splice_cols(buf, (int)lnum - 1, (int)line_len,
- 0, (int)added, kExtmarkUndo);
- }
+ if (u_save(lnum - 1, lnum + 1) != OK) {
+ return;
+ }
+
+ // Check if the line ends with an unclosed comment
+ skip_comment(line, false, false, &line_is_comment);
+ newline = xmalloc(line_len + markerlen + strlen(cms) + 1);
+ STRCPY(newline, line);
+ // Append the marker to the end of the line
+ if (p == NULL || line_is_comment) {
+ xstrlcpy(newline + line_len, marker, markerlen + 1);
+ added = markerlen;
+ } else {
+ STRCPY(newline + line_len, cms);
+ memcpy(newline + line_len + (p - cms), marker, markerlen);
+ STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
+ added = markerlen + strlen(cms) - 2;
+ }
+ ml_replace_buf(buf, lnum, newline, false);
+ if (added) {
+ extmark_splice_cols(buf, (int)lnum - 1, (int)line_len,
+ 0, (int)added, kExtmarkUndo);
}
}
@@ -1642,7 +1663,7 @@ static void foldDelMarker(buf_T *buf, linenr_T lnum, char *marker, size_t marker
char *cms = buf->b_p_cms;
char *line = ml_get_buf(buf, lnum, false);
for (char *p = line; *p != NUL; p++) {
- if (STRNCMP(p, marker, markerlen) != 0) {
+ if (strncmp(p, marker, markerlen) != 0) {
continue;
}
// Found the marker, include a digit if it's there.
@@ -1654,8 +1675,8 @@ static void foldDelMarker(buf_T *buf, linenr_T lnum, char *marker, size_t marker
// Also delete 'commentstring' if it matches.
char *cms2 = strstr(cms, "%s");
if (p - line >= cms2 - cms
- && STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0
- && STRNCMP(p + len, cms2 + 2, strlen(cms2 + 2)) == 0) {
+ && strncmp(p - (cms2 - cms), cms, (size_t)(cms2 - cms)) == 0
+ && strncmp(p + len, cms2 + 2, strlen(cms2 + 2)) == 0) {
p -= cms2 - cms;
len += strlen(cms) - 2;
}
@@ -1772,7 +1793,7 @@ char *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldinfo
}
}
if (text == NULL) {
- unsigned long count = (unsigned long)(lnume - lnum + 1);
+ long count = lnume - lnum + 1;
vim_snprintf(buf, FOLD_TEXT_LEN,
NGETTEXT("+--%3ld line folded",
@@ -1818,9 +1839,9 @@ static void foldtext_cleanup(char *str)
for (char *s = str; *s != NUL;) {
size_t len = 0;
- if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0) {
+ if (strncmp(s, curwin->w_p_fmr, foldstartmarkerlen) == 0) {
len = foldstartmarkerlen;
- } else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0) {
+ } else if (strncmp(s, foldendmarker, foldendmarkerlen) == 0) {
len = foldendmarkerlen;
}
if (len > 0) {
@@ -1833,16 +1854,16 @@ static void foldtext_cleanup(char *str)
char *p;
for (p = s; p > str && ascii_iswhite(p[-1]); p--) {}
if (p >= str + cms_slen
- && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0) {
+ && strncmp(p - cms_slen, cms_start, cms_slen) == 0) {
len += (size_t)(s - p) + cms_slen;
s = p - cms_slen;
}
} else if (cms_end != NULL) {
- if (!did1 && cms_slen > 0 && STRNCMP(s, cms_start, cms_slen) == 0) {
+ if (!did1 && cms_slen > 0 && strncmp(s, cms_start, cms_slen) == 0) {
len = cms_slen;
did1 = true;
} else if (!did2 && cms_elen > 0
- && STRNCMP(s, cms_end, cms_elen) == 0) {
+ && strncmp(s, cms_end, cms_elen) == 0) {
len = cms_elen;
did2 = true;
}
@@ -2852,7 +2873,7 @@ static void foldlevelIndent(fline_T *flp)
// empty line or lines starting with a character in 'foldignore': level
// depends on surrounding lines
- if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) {
+ if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, (uint8_t)(*s)) != NULL) {
// first and last line can't be undefined, use level 0
if (lnum == 1 || lnum == buf->b_ml.ml_line_count) {
flp->lvl = 0;
@@ -3013,7 +3034,7 @@ static void foldlevelMarker(fline_T *flp)
char *s = ml_get_buf(flp->wp->w_buffer, flp->lnum + flp->off, false);
while (*s) {
if (*s == cstart
- && STRNCMP(s + 1, startmarker, foldstartmarkerlen - 1) == 0) {
+ && strncmp(s + 1, startmarker, foldstartmarkerlen - 1) == 0) {
// found startmarker: set flp->lvl
s += foldstartmarkerlen;
if (ascii_isdigit(*s)) {
@@ -3033,7 +3054,7 @@ static void foldlevelMarker(fline_T *flp)
flp->start++;
}
} else if (*s == cend
- && STRNCMP(s + 1, foldendmarker + 1, foldendmarkerlen - 1) == 0) {
+ && strncmp(s + 1, foldendmarker + 1, foldendmarkerlen - 1) == 0) {
// found endmarker: set flp->lvl_next
s += foldendmarkerlen;
if (ascii_isdigit(*s)) {
@@ -3115,7 +3136,7 @@ static int put_folds_recurse(FILE *fd, garray_T *gap, linenr_T off)
return FAIL;
}
if (fprintf(fd, "%" PRId64 ",%" PRId64 "fold",
- (int64_t)(fp->fd_top + off),
+ (int64_t)fp->fd_top + off,
(int64_t)(fp->fd_top + off + fp->fd_len - 1)) < 0
|| put_eol(fd) == FAIL) {
return FAIL;
@@ -3136,7 +3157,7 @@ static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off
if (fp->fd_flags != FD_LEVEL) {
if (!GA_EMPTY(&fp->fd_nested)) {
// open nested folds while this fold is open
- if (fprintf(fd, "%" PRId64, (int64_t)(fp->fd_top + off)) < 0
+ if (fprintf(fd, "%" PRId64, (int64_t)fp->fd_top + off) < 0
|| put_eol(fd) == FAIL
|| put_line(fd, "normal! zo") == FAIL) {
return FAIL;
@@ -3249,23 +3270,23 @@ void f_foldtext(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
}
// Find interesting text in this line.
- char_u *s = (char_u *)skipwhite(ml_get(lnum));
+ char *s = skipwhite(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(ml_get(lnum + 1));
+ s = skipwhite(s + 2);
+ if (*skipwhite(s) == NUL && lnum + 1 < foldend) {
+ s = skipwhite(ml_get(lnum + 1));
if (*s == '*') {
- s = (char_u *)skipwhite((char *)s + 1);
+ s = skipwhite(s + 1);
}
}
}
- int count = foldend - foldstart + 1;
+ long 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
+ + strlen(s); // concatenated
char *r = xmalloc(len);
snprintf(r, len, txt, dashes, count);
len = strlen(r);