aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Coudron <mattator@gmail.com>2020-04-16 21:29:04 +0200
committerGitHub <noreply@github.com>2020-04-16 21:29:04 +0200
commitfb4c7a53cfe4d4c8a786c8a5dc3c4b999c2df815 (patch)
tree199bd3bbba8744358c79cf58bdf872f1b4768d76
parenta5818204b1124efea432377fc447a742cfec9ad1 (diff)
downloadrneovim-fb4c7a53cfe4d4c8a786c8a5dc3c4b999c2df815.tar.gz
rneovim-fb4c7a53cfe4d4c8a786c8a5dc3c4b999c2df815.tar.bz2
rneovim-fb4c7a53cfe4d4c8a786c8a5dc3c4b999c2df815.zip
folds: decrease reliance on global "curwin" (#12132)
Pass the window in which to create/delete folds instead of using the global "curwin" (current window). Preliminary work for a fold API. TODO: I kept changed_lines prototype unchanged. This should be updated when a fold API sees the light.
-rw-r--r--src/nvim/ex_docmd.c5
-rw-r--r--src/nvim/fold.c126
-rw-r--r--src/nvim/normal.c27
3 files changed, 86 insertions, 72 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index a86b8ec871..27d5e4998f 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -9291,8 +9291,9 @@ static void ex_match(exarg_T *eap)
static void ex_fold(exarg_T *eap)
{
- if (foldManualAllowed(TRUE))
- foldCreate(eap->line1, eap->line2);
+ if (foldManualAllowed(true)) {
+ foldCreate(curwin, eap->line1, eap->line2);
+ }
}
static void ex_foldopen(exarg_T *eap)
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index c14a64fa38..405f15d751 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -539,12 +539,10 @@ int foldManualAllowed(int create)
return FALSE;
}
-/* foldCreate() {{{2 */
-/*
- * Create a fold from line "start" to line "end" (inclusive) in the current
- * window.
- */
-void foldCreate(linenr_T start, linenr_T end)
+// foldCreate() {{{2
+/// Create a fold from line "start" to line "end" (inclusive) in the current
+/// window.
+void foldCreate(win_T *wp, linenr_T start, linenr_T end)
{
fold_T *fp;
garray_T *gap;
@@ -565,16 +563,16 @@ void foldCreate(linenr_T start, linenr_T end)
end_rel = end;
}
- /* When 'foldmethod' is "marker" add markers, which creates the folds. */
- if (foldmethodIsMarker(curwin)) {
- foldCreateMarkers(start, end);
+ // When 'foldmethod' is "marker" add markers, which creates the folds.
+ if (foldmethodIsMarker(wp)) {
+ foldCreateMarkers(wp, start, end);
return;
}
- checkupdate(curwin);
+ checkupdate(wp);
- /* Find the place to insert the new fold. */
- gap = &curwin->w_folds;
+ // Find the place to insert the new fold
+ gap = &wp->w_folds;
for (;; ) {
if (!foldFind(gap, start_rel, &fp))
break;
@@ -584,12 +582,14 @@ void foldCreate(linenr_T start, linenr_T end)
start_rel -= fp->fd_top;
end_rel -= fp->fd_top;
if (use_level || fp->fd_flags == FD_LEVEL) {
- use_level = TRUE;
- if (level >= curwin->w_p_fdl)
- closed = TRUE;
- } else if (fp->fd_flags == FD_CLOSED)
- closed = TRUE;
- ++level;
+ use_level = true;
+ if (level >= wp->w_p_fdl) {
+ closed = true;
+ }
+ } else if (fp->fd_flags == FD_CLOSED) {
+ closed = true;
+ }
+ level++;
} else {
/* This fold and new fold overlap: Insert here and move some folds
* inside the new fold. */
@@ -655,13 +655,13 @@ void foldCreate(linenr_T start, linenr_T end)
}
-/* deleteFold() {{{2 */
-/*
- * Delete a fold at line "start" in the current window.
- * When "end" is not 0, delete all folds from "start" to "end".
- * When "recursive" is TRUE delete recursively.
- */
+// deleteFold() {{{2
+/// @param start delete all folds from start to end when not 0
+/// @param end delete all folds from start to end when not 0
+/// @param recursive delete recursively if true
+/// @param had_visual true when Visual selection used
void deleteFold(
+ win_T *const wp,
const linenr_T start,
const linenr_T end,
const int recursive,
@@ -678,11 +678,11 @@ void deleteFold(
linenr_T first_lnum = MAXLNUM;
linenr_T last_lnum = 0;
- checkupdate(curwin);
+ checkupdate(wp);
while (lnum <= end) {
// Find the deepest fold for "start".
- garray_T *gap = &curwin->w_folds;
+ garray_T *gap = &wp->w_folds;
garray_T *found_ga = NULL;
linenr_T lnum_off = 0;
bool use_level = false;
@@ -694,10 +694,11 @@ void deleteFold(
found_fp = fp;
found_off = lnum_off;
- /* if "lnum" is folded, don't check nesting */
- if (check_closed(curwin, fp, &use_level, level,
- &maybe_small, lnum_off))
+ // if "lnum" is folded, don't check nesting
+ if (check_closed(wp, fp, &use_level, level,
+ &maybe_small, lnum_off)) {
break;
+ }
/* check nested folds */
gap = &fp->fd_nested;
@@ -709,16 +710,20 @@ void deleteFold(
} else {
lnum = found_fp->fd_top + found_fp->fd_len + found_off;
- if (foldmethodIsManual(curwin))
+ if (foldmethodIsManual(wp)) {
deleteFoldEntry(found_ga,
- (int)(found_fp - (fold_T *)found_ga->ga_data), recursive);
- else {
- if (first_lnum > found_fp->fd_top + found_off)
+ (int)(found_fp - (fold_T *)found_ga->ga_data),
+ recursive);
+ } else {
+ if (first_lnum > found_fp->fd_top + found_off) {
first_lnum = found_fp->fd_top + found_off;
- if (last_lnum < lnum)
+ }
+ if (last_lnum < lnum) {
last_lnum = lnum;
- if (!did_one)
- parseMarker(curwin);
+ }
+ if (!did_one) {
+ parseMarker(wp);
+ }
deleteFoldMarkers(found_fp, recursive, found_off);
}
did_one = true;
@@ -737,6 +742,7 @@ void deleteFold(
check_cursor_col();
if (last_lnum > 0) {
+ // TODO(teto): pass the buffer
changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L, false);
// send one nvim_buf_lines_event at the end
@@ -1048,7 +1054,7 @@ void cloneFoldGrowArray(garray_T *from, garray_T *to)
* the first fold below it (careful: it can be beyond the end of the array!).
* Returns FALSE when there is no fold that contains "lnum".
*/
-static int foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp)
+static int foldFind(const garray_T *gap, linenr_T lnum, fold_T **fpp)
{
linenr_T low, high;
fold_T *fp;
@@ -1487,12 +1493,15 @@ static int getDeepestNestingRecurse(garray_T *gap)
return maxlevel;
}
-/* check_closed() {{{2 */
-/*
- * Check if a fold is closed and update the info needed to check nested folds.
- */
+// check_closed() {{{2
+/// Check if a fold is closed and update the info needed to check nested folds.
+///
+/// @param[in,out] use_levelp true: outer fold had FD_LEVEL
+/// @param level folding depth
+/// @param[out] maybe_smallp TRUE: outer this had fd_small == kNone
+/// @param lnum_off line number offset for fp->fd_top
static bool check_closed(
- win_T *const win,
+ win_T *const wp,
fold_T *const fp,
bool *const use_levelp, // true: outer fold had FD_LEVEL
const int level, // folding depth
@@ -1506,7 +1515,7 @@ static bool check_closed(
* fold and all folds it contains depend on 'foldlevel'. */
if (*use_levelp || fp->fd_flags == FD_LEVEL) {
*use_levelp = true;
- if (level >= win->w_p_fdl) {
+ if (level >= wp->w_p_fdl) {
closed = true;
}
} else if (fp->fd_flags == FD_CLOSED) {
@@ -1521,7 +1530,7 @@ static bool check_closed(
if (*maybe_smallp) {
fp->fd_small = kNone;
}
- checkSmall(win, fp, lnum_off);
+ checkSmall(wp, fp, lnum_off);
if (fp->fd_small == kTrue) {
closed = false;
}
@@ -1529,10 +1538,9 @@ static bool check_closed(
return closed;
}
-/* checkSmall() {{{2 */
-/*
- * Update fd_small field of fold "fp".
- */
+// checkSmall() {{{2
+/// Update fd_small field of fold "fp".
+/// @param lnum_off offset for fp->fd_top
static void
checkSmall(
win_T *const wp,
@@ -1575,19 +1583,21 @@ static void setSmallMaybe(garray_T *gap)
* Create a fold from line "start" to line "end" (inclusive) in the current
* window by adding markers.
*/
-static void foldCreateMarkers(linenr_T start, linenr_T end)
+static void foldCreateMarkers(win_T *wp, linenr_T start, linenr_T end)
{
- if (!MODIFIABLE(curbuf)) {
+ buf_T *buf = wp->w_buffer;
+ if (!MODIFIABLE(buf)) {
EMSG(_(e_modifiable));
return;
}
- parseMarker(curwin);
+ parseMarker(wp);
- foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen);
- foldAddMarker(end, foldendmarker, foldendmarkerlen);
+ foldAddMarker(buf, start, wp->w_p_fmr, foldstartmarkerlen);
+ foldAddMarker(buf, end, foldendmarker, foldendmarkerlen);
/* Update both changes here, to avoid all folds after the start are
* changed when the start marker is inserted and the end isn't. */
+ // TODO(teto): pass the buffer
changed_lines(start, (colnr_T)0, end, 0L, false);
// Note: foldAddMarker() may not actually change start and/or end if
@@ -1601,12 +1611,13 @@ static void foldCreateMarkers(linenr_T start, linenr_T end)
/*
* Add "marker[markerlen]" in 'commentstring' to line "lnum".
*/
-static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen)
+static void foldAddMarker(
+ buf_T *buf, linenr_T lnum, const char_u *marker, size_t markerlen)
{
- char_u *cms = curbuf->b_p_cms;
+ char_u *cms = buf->b_p_cms;
char_u *line;
char_u *newline;
- char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
+ char_u *p = (char_u *)strstr((char *)buf->b_p_cms, "%s");
bool line_is_comment = false;
// Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end
@@ -1631,7 +1642,7 @@ static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen)
}
ml_replace(lnum, newline, false);
if (added) {
- extmark_splice(curbuf, (int)lnum-1, (int)line_len,
+ extmark_splice(buf, (int)lnum-1, (int)line_len,
0, 0,
0, (int)added, kExtmarkUndo);
}
@@ -1893,6 +1904,7 @@ void foldtext_cleanup(char_u *str)
/*
* Update the folding for window "wp", at least from lines "top" to "bot".
* Return TRUE if any folds did change.
+ * IEMS = "Indent Expr Marker Syntax"
*/
static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
{
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index aca27e0208..58993426dd 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1967,8 +1967,8 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_FOLD:
- VIsual_reselect = false; /* don't reselect now */
- foldCreate(oap->start.lnum, oap->end.lnum);
+ VIsual_reselect = false; // don't reselect now
+ foldCreate(curwin, oap->start.lnum, oap->end.lnum);
break;
case OP_FOLDOPEN:
@@ -1986,9 +1986,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
case OP_FOLDDEL:
case OP_FOLDDELREC:
- VIsual_reselect = false; /* don't reselect now */
- deleteFold(oap->start.lnum, oap->end.lnum,
- oap->op_type == OP_FOLDDELREC, oap->is_VIsual);
+ VIsual_reselect = false; // don't reselect now
+ deleteFold(curwin, oap->start.lnum, oap->end.lnum,
+ oap->op_type == OP_FOLDDELREC, oap->is_VIsual);
break;
case OP_NR_ADD:
@@ -4345,11 +4345,12 @@ dozet:
/* "zD": delete fold at cursor recursively */
case 'd':
case 'D': if (foldManualAllowed(false)) {
- if (VIsual_active)
+ if (VIsual_active) {
nv_operator(cap);
- else
- deleteFold(curwin->w_cursor.lnum,
- curwin->w_cursor.lnum, nchar == 'D', false);
+ } else {
+ deleteFold(curwin, curwin->w_cursor.lnum,
+ curwin->w_cursor.lnum, nchar == 'D', false);
+ }
}
break;
@@ -4357,11 +4358,11 @@ dozet:
case 'E': if (foldmethodIsManual(curwin)) {
clearFolding(curwin);
changed_window_setting();
- } else if (foldmethodIsMarker(curwin))
- deleteFold((linenr_T)1, curbuf->b_ml.ml_line_count,
- true, false);
- else
+ } else if (foldmethodIsMarker(curwin)) {
+ deleteFold(curwin, (linenr_T)1, curbuf->b_ml.ml_line_count, true, false);
+ } else {
EMSG(_("E352: Cannot erase folds with current 'foldmethod'"));
+ }
break;
/* "zn": fold none: reset 'foldenable' */