Mercurial > vim
annotate src/fold.c @ 32996:dd8da8f1c2bc v9.0.1790
patch 9.0.1790: Redundant LSP Content-Type header
Commit: https://github.com/vim/vim/commit/8fbd9449e71f2ad93e594be575209a7424eb093e
Author: Magnus Gro? <magnus@mggross.com>
Date: Sun Aug 27 00:49:51 2023 +0200
patch 9.0.1790: Redundant LSP Content-Type header
Problem: The Content-Type header is an optional header that some LSP
servers struggle with and may crash when encountering it.
Solution: Drop the Content-Type header from all messages, because we use
the default value anyway.
Because pretty much all popular LSP clients (e.g. coc.nvim, VSCode) do
not send the Content-Type header, the LSP server ecosystem has developed
such that some LSP servers may even crash when encountering it.
To improve compatibility with these misbehaving LSP servers, we drop
this header as well.
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Magnus Gro? <magnus@mggross.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 27 Aug 2023 11:15:03 +0200 |
parents | e16361210675 |
children | 48955338edb1 |
rev | line source |
---|---|
10042
4aead6a9b7a9
commit https://github.com/vim/vim/commit/edf3f97ae2af024708ebb4ac614227327033ca47
Christian Brabandt <cb@256bit.org>
parents:
9754
diff
changeset
|
1 /* vi:set ts=8 sts=4 sw=4 noet: |
7 | 2 * vim600:fdm=marker fdl=1 fdc=3: |
3 * | |
4 * VIM - Vi IMproved by Bram Moolenaar | |
5 * | |
6 * Do ":help uganda" in Vim to read copying and usage conditions. | |
7 * Do ":help credits" in Vim to see a list of people who contributed. | |
8 * See README.txt for an overview of the Vim source code. | |
9 */ | |
10 | |
11 /* | |
12 * fold.c: code for folding | |
13 */ | |
14 | |
15 #include "vim.h" | |
16 | |
17 #if defined(FEAT_FOLDING) || defined(PROTO) | |
18 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
19 // local declarations. {{{1 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
20 // typedef fold_T {{{2 |
7 | 21 /* |
22 * The toplevel folds for each window are stored in the w_folds growarray. | |
23 * Each toplevel fold can contain an array of second level folds in the | |
24 * fd_nested growarray. | |
25 * The info stored in both growarrays is the same: An array of fold_T. | |
26 */ | |
27 typedef struct | |
28 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
29 linenr_T fd_top; // first line of fold; for nested fold |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
30 // relative to parent |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
31 linenr_T fd_len; // number of lines in the fold |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
32 garray_T fd_nested; // array of nested folds |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
33 char fd_flags; // see below |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
34 char fd_small; // TRUE, FALSE or MAYBE: fold smaller than |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
35 // 'foldminlines'; MAYBE applies to nested |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
36 // folds too |
7 | 37 } fold_T; |
38 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
39 #define FD_OPEN 0 // fold is open (nested ones can be closed) |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
40 #define FD_CLOSED 1 // fold is closed |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
41 #define FD_LEVEL 2 // depends on 'foldlevel' (nested folds too) |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
42 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
43 #define MAX_LEVEL 20 // maximum fold depth |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
44 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
45 // static functions {{{2 |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
46 static void newFoldLevelWin(win_T *wp); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
47 static int checkCloseRec(garray_T *gap, linenr_T lnum, int level); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
48 static int foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
49 static int foldLevelWin(win_T *wp, linenr_T lnum); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
50 static void checkupdate(win_T *wp); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
51 static void setFoldRepeat(linenr_T lnum, long count, int do_open); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
52 static linenr_T setManualFold(linenr_T lnum, int opening, int recurse, int *donep); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
53 static linenr_T setManualFoldWin(win_T *wp, linenr_T lnum, int opening, int recurse, int *donep); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
54 static void foldOpenNested(fold_T *fpr); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
55 static void deleteFoldEntry(garray_T *gap, int idx, int recursive); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
56 static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2, long amount, long amount_after); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
57 static int getDeepestNestingRecurse(garray_T *gap); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
58 static int check_closed(win_T *win, fold_T *fp, int *use_levelp, int level, int *maybe_smallp, linenr_T lnum_off); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
59 static void checkSmall(win_T *wp, fold_T *fp, linenr_T lnum_off); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
60 static void setSmallMaybe(garray_T *gap); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
61 static void foldCreateMarkers(linenr_T start, linenr_T end); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
62 static void foldAddMarker(linenr_T lnum, char_u *marker, int markerlen); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
63 static void deleteFoldMarkers(fold_T *fp, int recursive, linenr_T lnum_off); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
64 static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
65 static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
66 static void parseMarker(win_T *wp); |
7 | 67 |
68 /* | |
69 * While updating the folds lines between invalid_top and invalid_bot have an | |
70 * undefined fold level. Only used for the window currently being updated. | |
71 */ | |
72 static linenr_T invalid_top = (linenr_T)0; | |
73 static linenr_T invalid_bot = (linenr_T)0; | |
74 | |
75 /* | |
76 * When using 'foldexpr' we sometimes get the level of the next line, which | |
77 * calls foldlevel() to get the level of the current line, which hasn't been | |
78 * stored yet. To get around this chicken-egg problem the level of the | |
79 * previous line is stored here when available. prev_lnum is zero when the | |
80 * level is not available. | |
81 */ | |
82 static linenr_T prev_lnum = 0; | |
83 static int prev_lnum_lvl = -1; | |
84 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
85 // Flags used for "done" argument of setManualFold. |
7 | 86 #define DONE_NOTHING 0 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
87 #define DONE_ACTION 1 // did close or open a fold |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
88 #define DONE_FOLD 2 // did find a fold |
7 | 89 |
90 static int foldstartmarkerlen; | |
91 static char_u *foldendmarker; | |
92 static int foldendmarkerlen; | |
93 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
94 // Exported folding functions. {{{1 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
95 // copyFoldingState() {{{2 |
12477
68d7bc045dbe
patch 8.0.1118: FEAT_WINDOWS adds a lot of #ifdefs
Christian Brabandt <cb@256bit.org>
parents:
11396
diff
changeset
|
96 |
7 | 97 /* |
98 * Copy that folding state from window "wp_from" to window "wp_to". | |
99 */ | |
100 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
101 copyFoldingState(win_T *wp_from, win_T *wp_to) |
7 | 102 { |
103 wp_to->w_fold_manual = wp_from->w_fold_manual; | |
104 wp_to->w_foldinvalid = wp_from->w_foldinvalid; | |
105 cloneFoldGrowArray(&wp_from->w_folds, &wp_to->w_folds); | |
106 } | |
107 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
108 // hasAnyFolding() {{{2 |
7 | 109 /* |
110 * Return TRUE if there may be folded lines in the current window. | |
111 */ | |
112 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
113 hasAnyFolding(win_T *win) |
7 | 114 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
115 // very simple now, but can become more complex later |
7 | 116 return (win->w_p_fen |
117 && (!foldmethodIsManual(win) || win->w_folds.ga_len > 0)); | |
118 } | |
119 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
120 // hasFolding() {{{2 |
7 | 121 /* |
122 * Return TRUE if line "lnum" in the current window is part of a closed | |
123 * fold. | |
124 * When returning TRUE, *firstp and *lastp are set to the first and last | |
125 * lnum of the sequence of folded lines (skipped when NULL). | |
126 */ | |
127 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
128 hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp) |
7 | 129 { |
130 return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL); | |
131 } | |
132 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
133 // hasFoldingWin() {{{2 |
7 | 134 int |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
135 hasFoldingWin( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
136 win_T *win, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
137 linenr_T lnum, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
138 linenr_T *firstp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
139 linenr_T *lastp, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
140 int cache, // when TRUE: use cached values of window |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
141 foldinfo_T *infop) // where to store fold info |
7 | 142 { |
143 int had_folded = FALSE; | |
144 linenr_T first = 0; | |
145 linenr_T last = 0; | |
146 linenr_T lnum_rel = lnum; | |
147 int x; | |
148 fold_T *fp; | |
149 int level = 0; | |
150 int use_level = FALSE; | |
151 int maybe_small = FALSE; | |
152 garray_T *gap; | |
9252
c25898cc99c1
commit https://github.com/vim/vim/commit/945ec093cd4ddefab930239990564b12eb232153
Christian Brabandt <cb@256bit.org>
parents:
8891
diff
changeset
|
153 int low_level = 0; |
7 | 154 |
155 checkupdate(win); | |
15031
03831e5ea0de
patch 8.1.0527: using 'shiftwidth' from wrong buffer for folding
Bram Moolenaar <Bram@vim.org>
parents:
12477
diff
changeset
|
156 |
7 | 157 /* |
158 * Return quickly when there is no folding at all in this window. | |
159 */ | |
160 if (!hasAnyFolding(win)) | |
161 { | |
162 if (infop != NULL) | |
163 infop->fi_level = 0; | |
164 return FALSE; | |
165 } | |
166 | |
167 if (cache) | |
168 { | |
169 /* | |
170 * First look in cached info for displayed lines. This is probably | |
171 * the fastest, but it can only be used if the entry is still valid. | |
172 */ | |
173 x = find_wl_entry(win, lnum); | |
174 if (x >= 0) | |
175 { | |
176 first = win->w_lines[x].wl_lnum; | |
177 last = win->w_lines[x].wl_lastlnum; | |
178 had_folded = win->w_lines[x].wl_folded; | |
179 } | |
180 } | |
181 | |
182 if (first == 0) | |
183 { | |
184 /* | |
185 * Recursively search for a fold that contains "lnum". | |
186 */ | |
187 gap = &win->w_folds; | |
188 for (;;) | |
189 { | |
190 if (!foldFind(gap, lnum_rel, &fp)) | |
191 break; | |
192 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
193 // Remember lowest level of fold that starts in "lnum". |
7 | 194 if (lnum_rel == fp->fd_top && low_level == 0) |
195 low_level = level + 1; | |
196 | |
197 first += fp->fd_top; | |
198 last += fp->fd_top; | |
199 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
200 // is this fold closed? |
7 | 201 had_folded = check_closed(win, fp, &use_level, level, |
202 &maybe_small, lnum - lnum_rel); | |
203 if (had_folded) | |
204 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
205 // Fold closed: Set last and quit loop. |
7 | 206 last += fp->fd_len - 1; |
207 break; | |
208 } | |
209 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
210 // Fold found, but it's open: Check nested folds. Line number is |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
211 // relative to containing fold. |
7 | 212 gap = &fp->fd_nested; |
213 lnum_rel -= fp->fd_top; | |
214 ++level; | |
215 } | |
216 } | |
217 | |
218 if (!had_folded) | |
219 { | |
220 if (infop != NULL) | |
221 { | |
222 infop->fi_level = level; | |
223 infop->fi_lnum = lnum - lnum_rel; | |
224 infop->fi_low_level = low_level == 0 ? level : low_level; | |
225 } | |
226 return FALSE; | |
227 } | |
228 | |
6753 | 229 if (last > win->w_buffer->b_ml.ml_line_count) |
230 last = win->w_buffer->b_ml.ml_line_count; | |
7 | 231 if (lastp != NULL) |
232 *lastp = last; | |
233 if (firstp != NULL) | |
234 *firstp = first; | |
235 if (infop != NULL) | |
236 { | |
237 infop->fi_level = level + 1; | |
238 infop->fi_lnum = first; | |
239 infop->fi_low_level = low_level == 0 ? level + 1 : low_level; | |
240 } | |
241 return TRUE; | |
242 } | |
243 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
244 // foldLevel() {{{2 |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
245 #ifdef FEAT_EVAL |
7 | 246 /* |
247 * Return fold level at line number "lnum" in the current window. | |
248 */ | |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
249 static int |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
250 foldLevel(linenr_T lnum) |
7 | 251 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
252 // While updating the folds lines between invalid_top and invalid_bot have |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
253 // an undefined fold level. Otherwise update the folds first. |
7 | 254 if (invalid_top == (linenr_T)0) |
255 checkupdate(curwin); | |
256 else if (lnum == prev_lnum && prev_lnum_lvl >= 0) | |
257 return prev_lnum_lvl; | |
258 else if (lnum >= invalid_top && lnum <= invalid_bot) | |
259 return -1; | |
260 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
261 // Return quickly when there is no folding at all in this window. |
7 | 262 if (!hasAnyFolding(curwin)) |
263 return 0; | |
264 | |
265 return foldLevelWin(curwin, lnum); | |
266 } | |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
267 #endif |
7 | 268 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
269 // lineFolded() {{{2 |
7 | 270 /* |
271 * Low level function to check if a line is folded. Doesn't use any caching. | |
272 * Return TRUE if line is folded. | |
273 * Return FALSE if line is not folded. | |
274 * Return MAYBE if the line is folded when next to a folded line. | |
275 */ | |
276 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
277 lineFolded(win_T *win, linenr_T lnum) |
7 | 278 { |
279 return foldedCount(win, lnum, NULL) != 0; | |
280 } | |
281 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
282 // foldedCount() {{{2 |
7 | 283 /* |
284 * Count the number of lines that are folded at line number "lnum". | |
285 * Normally "lnum" is the first line of a possible fold, and the returned | |
286 * number is the number of lines in the fold. | |
287 * Doesn't use caching from the displayed window. | |
288 * Returns number of folded lines from "lnum", or 0 if line is not folded. | |
289 * When "infop" is not NULL, fills *infop with the fold level info. | |
290 */ | |
291 long | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
292 foldedCount(win_T *win, linenr_T lnum, foldinfo_T *infop) |
7 | 293 { |
294 linenr_T last; | |
295 | |
296 if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop)) | |
297 return (long)(last - lnum + 1); | |
298 return 0; | |
299 } | |
300 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
301 // foldmethodIsManual() {{{2 |
7 | 302 /* |
303 * Return TRUE if 'foldmethod' is "manual" | |
304 */ | |
305 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
306 foldmethodIsManual(win_T *wp) |
7 | 307 { |
26262
2484d6d96166
patch 8.2.3662: illegal memory access if malloc() fails
Bram Moolenaar <Bram@vim.org>
parents:
25384
diff
changeset
|
308 return (wp->w_p_fdm[0] != NUL && wp->w_p_fdm[3] == 'u'); |
7 | 309 } |
310 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
311 // foldmethodIsIndent() {{{2 |
7 | 312 /* |
313 * Return TRUE if 'foldmethod' is "indent" | |
314 */ | |
315 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
316 foldmethodIsIndent(win_T *wp) |
7 | 317 { |
318 return (wp->w_p_fdm[0] == 'i'); | |
319 } | |
320 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
321 // foldmethodIsExpr() {{{2 |
7 | 322 /* |
323 * Return TRUE if 'foldmethod' is "expr" | |
324 */ | |
325 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
326 foldmethodIsExpr(win_T *wp) |
7 | 327 { |
26262
2484d6d96166
patch 8.2.3662: illegal memory access if malloc() fails
Bram Moolenaar <Bram@vim.org>
parents:
25384
diff
changeset
|
328 return (wp->w_p_fdm[0] != NUL && wp->w_p_fdm[1] == 'x'); |
7 | 329 } |
330 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
331 // foldmethodIsMarker() {{{2 |
7 | 332 /* |
333 * Return TRUE if 'foldmethod' is "marker" | |
334 */ | |
335 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
336 foldmethodIsMarker(win_T *wp) |
7 | 337 { |
26262
2484d6d96166
patch 8.2.3662: illegal memory access if malloc() fails
Bram Moolenaar <Bram@vim.org>
parents:
25384
diff
changeset
|
338 return (wp->w_p_fdm[0] != NUL && wp->w_p_fdm[2] == 'r'); |
7 | 339 } |
340 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
341 // foldmethodIsSyntax() {{{2 |
7 | 342 /* |
343 * Return TRUE if 'foldmethod' is "syntax" | |
344 */ | |
345 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
346 foldmethodIsSyntax(win_T *wp) |
7 | 347 { |
348 return (wp->w_p_fdm[0] == 's'); | |
349 } | |
350 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
351 // foldmethodIsDiff() {{{2 |
7 | 352 /* |
353 * Return TRUE if 'foldmethod' is "diff" | |
354 */ | |
355 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
356 foldmethodIsDiff(win_T *wp) |
7 | 357 { |
358 return (wp->w_p_fdm[0] == 'd'); | |
359 } | |
360 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
361 // closeFold() {{{2 |
7 | 362 /* |
363 * Close fold for current window at line "lnum". | |
364 * Repeat "count" times. | |
365 */ | |
366 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
367 closeFold(linenr_T lnum, long count) |
7 | 368 { |
369 setFoldRepeat(lnum, count, FALSE); | |
370 } | |
371 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
372 // closeFoldRecurse() {{{2 |
7 | 373 /* |
374 * Close fold for current window at line "lnum" recursively. | |
375 */ | |
376 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
377 closeFoldRecurse(linenr_T lnum) |
7 | 378 { |
379 (void)setManualFold(lnum, FALSE, TRUE, NULL); | |
380 } | |
381 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
382 // opFoldRange() {{{2 |
7 | 383 /* |
384 * Open or Close folds for current window in lines "first" to "last". | |
385 * Used for "zo", "zO", "zc" and "zC" in Visual mode. | |
386 */ | |
387 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
388 opFoldRange( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
389 linenr_T first, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
390 linenr_T last, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
391 int opening, // TRUE to open, FALSE to close |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
392 int recurse, // TRUE to do it recursively |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
393 int had_visual) // TRUE when Visual selection used |
7 | 394 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
395 int done = DONE_NOTHING; // avoid error messages |
7 | 396 linenr_T lnum; |
397 linenr_T lnum_next; | |
398 | |
399 for (lnum = first; lnum <= last; lnum = lnum_next + 1) | |
400 { | |
401 lnum_next = lnum; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
402 // Opening one level only: next fold to open is after the one going to |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
403 // be opened. |
7 | 404 if (opening && !recurse) |
405 (void)hasFolding(lnum, NULL, &lnum_next); | |
406 (void)setManualFold(lnum, opening, recurse, &done); | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
407 // Closing one level only: next line to close a fold is after just |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
408 // closed fold. |
7 | 409 if (!opening && !recurse) |
410 (void)hasFolding(lnum, NULL, &lnum_next); | |
411 } | |
412 if (done == DONE_NOTHING) | |
26915
3631d2deb36c
patch 8.2.3986: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26913
diff
changeset
|
413 emsg(_(e_no_fold_found)); |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
414 // Force a redraw to remove the Visual highlighting. |
7 | 415 if (had_visual) |
29732
89e1d67814a9
patch 9.0.0206: redraw flags are not named specifically
Bram Moolenaar <Bram@vim.org>
parents:
28974
diff
changeset
|
416 redraw_curbuf_later(UPD_INVERTED); |
7 | 417 } |
418 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
419 // openFold() {{{2 |
7 | 420 /* |
421 * Open fold for current window at line "lnum". | |
422 * Repeat "count" times. | |
423 */ | |
424 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
425 openFold(linenr_T lnum, long count) |
7 | 426 { |
427 setFoldRepeat(lnum, count, TRUE); | |
428 } | |
429 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
430 // openFoldRecurse() {{{2 |
7 | 431 /* |
432 * Open fold for current window at line "lnum" recursively. | |
433 */ | |
434 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
435 openFoldRecurse(linenr_T lnum) |
7 | 436 { |
437 (void)setManualFold(lnum, TRUE, TRUE, NULL); | |
438 } | |
439 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
440 // foldOpenCursor() {{{2 |
7 | 441 /* |
442 * Open folds until the cursor line is not in a closed fold. | |
443 */ | |
444 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
445 foldOpenCursor(void) |
7 | 446 { |
447 int done; | |
448 | |
449 checkupdate(curwin); | |
450 if (hasAnyFolding(curwin)) | |
451 for (;;) | |
452 { | |
453 done = DONE_NOTHING; | |
454 (void)setManualFold(curwin->w_cursor.lnum, TRUE, FALSE, &done); | |
455 if (!(done & DONE_ACTION)) | |
456 break; | |
457 } | |
458 } | |
459 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
460 // newFoldLevel() {{{2 |
7 | 461 /* |
462 * Set new foldlevel for current window. | |
463 */ | |
464 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
465 newFoldLevel(void) |
7 | 466 { |
467 newFoldLevelWin(curwin); | |
468 | |
469 #ifdef FEAT_DIFF | |
470 if (foldmethodIsDiff(curwin) && curwin->w_p_scb) | |
471 { | |
472 win_T *wp; | |
473 | |
474 /* | |
475 * Set the same foldlevel in other windows in diff mode. | |
476 */ | |
477 FOR_ALL_WINDOWS(wp) | |
478 { | |
479 if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb) | |
480 { | |
481 wp->w_p_fdl = curwin->w_p_fdl; | |
482 newFoldLevelWin(wp); | |
483 } | |
484 } | |
485 } | |
486 #endif | |
487 } | |
488 | |
489 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
490 newFoldLevelWin(win_T *wp) |
7 | 491 { |
492 fold_T *fp; | |
493 int i; | |
494 | |
495 checkupdate(wp); | |
496 if (wp->w_fold_manual) | |
497 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
498 // Set all flags for the first level of folds to FD_LEVEL. Following |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
499 // manual open/close will then change the flags to FD_OPEN or |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
500 // FD_CLOSED for those folds that don't use 'foldlevel'. |
7 | 501 fp = (fold_T *)wp->w_folds.ga_data; |
502 for (i = 0; i < wp->w_folds.ga_len; ++i) | |
503 fp[i].fd_flags = FD_LEVEL; | |
504 wp->w_fold_manual = FALSE; | |
505 } | |
506 changed_window_setting_win(wp); | |
507 } | |
508 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
509 // foldCheckClose() {{{2 |
7 | 510 /* |
511 * Apply 'foldlevel' to all folds that don't contain the cursor. | |
512 */ | |
513 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
514 foldCheckClose(void) |
7 | 515 { |
31651
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
516 if (*p_fcl == NUL) |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
517 return; |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
518 |
31667
b89cfd86e18e
patch 9.0.1166: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31651
diff
changeset
|
519 // 'foldclose' can only be "all" right now |
31651
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
520 checkupdate(curwin); |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
521 if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum, |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
522 (int)curwin->w_p_fdl)) |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
523 changed_window_setting(); |
7 | 524 } |
525 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
526 // checkCloseRec() {{{2 |
7 | 527 static int |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
528 checkCloseRec(garray_T *gap, linenr_T lnum, int level) |
7 | 529 { |
530 fold_T *fp; | |
531 int retval = FALSE; | |
532 int i; | |
533 | |
534 fp = (fold_T *)gap->ga_data; | |
535 for (i = 0; i < gap->ga_len; ++i) | |
536 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
537 // Only manually opened folds may need to be closed. |
7 | 538 if (fp[i].fd_flags == FD_OPEN) |
539 { | |
540 if (level <= 0 && (lnum < fp[i].fd_top | |
541 || lnum >= fp[i].fd_top + fp[i].fd_len)) | |
542 { | |
543 fp[i].fd_flags = FD_LEVEL; | |
544 retval = TRUE; | |
545 } | |
546 else | |
547 retval |= checkCloseRec(&fp[i].fd_nested, lnum - fp[i].fd_top, | |
548 level - 1); | |
549 } | |
550 } | |
551 return retval; | |
552 } | |
553 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
554 // foldCreateAllowed() {{{2 |
7 | 555 /* |
556 * Return TRUE if it's allowed to manually create or delete a fold. | |
557 * Give an error message and return FALSE if not. | |
558 */ | |
559 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
560 foldManualAllowed(int create) |
7 | 561 { |
562 if (foldmethodIsManual(curwin) || foldmethodIsMarker(curwin)) | |
563 return TRUE; | |
564 if (create) | |
26913
d4e61d61afd9
patch 8.2.3985: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26771
diff
changeset
|
565 emsg(_(e_cannot_create_fold_with_current_foldmethod)); |
7 | 566 else |
26913
d4e61d61afd9
patch 8.2.3985: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26771
diff
changeset
|
567 emsg(_(e_cannot_delete_fold_with_current_foldmethod)); |
7 | 568 return FALSE; |
569 } | |
570 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
571 // foldCreate() {{{2 |
7 | 572 /* |
573 * Create a fold from line "start" to line "end" (inclusive) in the current | |
574 * window. | |
575 */ | |
576 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
577 foldCreate(linenr_T start, linenr_T end) |
7 | 578 { |
579 fold_T *fp; | |
580 garray_T *gap; | |
581 garray_T fold_ga; | |
582 int i, j; | |
583 int cont; | |
584 int use_level = FALSE; | |
585 int closed = FALSE; | |
586 int level = 0; | |
587 linenr_T start_rel = start; | |
588 linenr_T end_rel = end; | |
589 | |
590 if (start > end) | |
591 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
592 // reverse the range |
7 | 593 end = start_rel; |
594 start = end_rel; | |
595 start_rel = start; | |
596 end_rel = end; | |
597 } | |
598 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
599 // When 'foldmethod' is "marker" add markers, which creates the folds. |
7 | 600 if (foldmethodIsMarker(curwin)) |
601 { | |
602 foldCreateMarkers(start, end); | |
603 return; | |
604 } | |
605 | |
606 checkupdate(curwin); | |
607 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
608 // Find the place to insert the new fold. |
7 | 609 gap = &curwin->w_folds; |
22008
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
610 if (gap->ga_len == 0) |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
611 i = 0; |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
612 else |
7 | 613 { |
22008
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
614 for (;;) |
7 | 615 { |
22008
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
616 if (!foldFind(gap, start_rel, &fp)) |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
617 break; |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
618 if (fp->fd_top + fp->fd_len > end_rel) |
7 | 619 { |
22008
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
620 // New fold is completely inside this fold: Go one level |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
621 // deeper. |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
622 gap = &fp->fd_nested; |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
623 start_rel -= fp->fd_top; |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
624 end_rel -= fp->fd_top; |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
625 if (use_level || fp->fd_flags == FD_LEVEL) |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
626 { |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
627 use_level = TRUE; |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
628 if (level >= curwin->w_p_fdl) |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
629 closed = TRUE; |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
630 } |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
631 else if (fp->fd_flags == FD_CLOSED) |
7 | 632 closed = TRUE; |
22008
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
633 ++level; |
7 | 634 } |
22008
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
635 else |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
636 { |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
637 // This fold and new fold overlap: Insert here and move some |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
638 // folds inside the new fold. |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
639 break; |
3ea6b4a5369a
patch 8.2.1553: crash in edit test
Bram Moolenaar <Bram@vim.org>
parents:
22006
diff
changeset
|
640 } |
7 | 641 } |
22850
b05cfda397dc
patch 8.2.1972: crash when recreating nested fold
Bram Moolenaar <Bram@vim.org>
parents:
22798
diff
changeset
|
642 if (gap->ga_len == 0) |
b05cfda397dc
patch 8.2.1972: crash when recreating nested fold
Bram Moolenaar <Bram@vim.org>
parents:
22798
diff
changeset
|
643 i = 0; |
b05cfda397dc
patch 8.2.1972: crash when recreating nested fold
Bram Moolenaar <Bram@vim.org>
parents:
22798
diff
changeset
|
644 else |
b05cfda397dc
patch 8.2.1972: crash when recreating nested fold
Bram Moolenaar <Bram@vim.org>
parents:
22798
diff
changeset
|
645 i = (int)(fp - (fold_T *)gap->ga_data); |
7 | 646 } |
647 | |
31837
e16361210675
patch 9.0.1251: checking returned value of ga_grow() is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
31667
diff
changeset
|
648 if (ga_grow(gap, 1) == FAIL) |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
649 return; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
650 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
651 fp = (fold_T *)gap->ga_data + i; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
652 ga_init2(&fold_ga, sizeof(fold_T), 10); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
653 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
654 // Count number of folds that will be contained in the new fold. |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
655 for (cont = 0; i + cont < gap->ga_len; ++cont) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
656 if (fp[cont].fd_top > end_rel) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
657 break; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
658 if (cont > 0 && ga_grow(&fold_ga, cont) == OK) |
7 | 659 { |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
660 // If the first fold starts before the new fold, let the new fold |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
661 // start there. Otherwise the existing fold would change. |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
662 if (start_rel > fp->fd_top) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
663 start_rel = fp->fd_top; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
664 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
665 // When last contained fold isn't completely contained, adjust end |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
666 // of new fold. |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
667 if (end_rel < fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
668 end_rel = fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
669 // Move contained folds to inside new fold. |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
670 mch_memmove(fold_ga.ga_data, fp, sizeof(fold_T) * cont); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
671 fold_ga.ga_len += cont; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
672 i += cont; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
673 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
674 // Adjust line numbers in contained folds to be relative to the |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
675 // new fold. |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
676 for (j = 0; j < cont; ++j) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
677 ((fold_T *)fold_ga.ga_data)[j].fd_top -= start_rel; |
7 | 678 } |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
679 // Move remaining entries to after the new fold. |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
680 if (i < gap->ga_len) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
681 mch_memmove(fp + 1, (fold_T *)gap->ga_data + i, |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
682 sizeof(fold_T) * (gap->ga_len - i)); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
683 gap->ga_len = gap->ga_len + 1 - cont; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
684 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
685 // insert new fold |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
686 fp->fd_nested = fold_ga; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
687 fp->fd_top = start_rel; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
688 fp->fd_len = end_rel - start_rel + 1; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
689 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
690 // We want the new fold to be closed. If it would remain open because |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
691 // of using 'foldlevel', need to adjust fd_flags of containing folds. |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
692 if (use_level && !closed && level < curwin->w_p_fdl) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
693 closeFold(start, 1L); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
694 if (!use_level) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
695 curwin->w_fold_manual = TRUE; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
696 fp->fd_flags = FD_CLOSED; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
697 fp->fd_small = MAYBE; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
698 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
699 // redraw |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
700 changed_window_setting(); |
7 | 701 } |
702 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
703 // deleteFold() {{{2 |
7 | 704 /* |
705 * Delete a fold at line "start" in the current window. | |
706 * When "end" is not 0, delete all folds from "start" to "end". | |
707 * When "recursive" is TRUE delete recursively. | |
708 */ | |
709 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
710 deleteFold( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
711 linenr_T start, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
712 linenr_T end, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
713 int recursive, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
714 int had_visual) // TRUE when Visual selection used |
7 | 715 { |
716 garray_T *gap; | |
717 fold_T *fp; | |
718 garray_T *found_ga; | |
719 fold_T *found_fp = NULL; | |
720 linenr_T found_off = 0; | |
1780 | 721 int use_level; |
7 | 722 int maybe_small = FALSE; |
723 int level = 0; | |
724 linenr_T lnum = start; | |
725 linenr_T lnum_off; | |
726 int did_one = FALSE; | |
727 linenr_T first_lnum = MAXLNUM; | |
728 linenr_T last_lnum = 0; | |
729 | |
730 checkupdate(curwin); | |
731 | |
732 while (lnum <= end) | |
733 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
734 // Find the deepest fold for "start". |
7 | 735 gap = &curwin->w_folds; |
736 found_ga = NULL; | |
737 lnum_off = 0; | |
1780 | 738 use_level = FALSE; |
7 | 739 for (;;) |
740 { | |
741 if (!foldFind(gap, lnum - lnum_off, &fp)) | |
742 break; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
743 // lnum is inside this fold, remember info |
7 | 744 found_ga = gap; |
745 found_fp = fp; | |
746 found_off = lnum_off; | |
747 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
748 // if "lnum" is folded, don't check nesting |
7 | 749 if (check_closed(curwin, fp, &use_level, level, |
750 &maybe_small, lnum_off)) | |
751 break; | |
752 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
753 // check nested folds |
7 | 754 gap = &fp->fd_nested; |
755 lnum_off += fp->fd_top; | |
756 ++level; | |
757 } | |
758 if (found_ga == NULL) | |
759 { | |
760 ++lnum; | |
761 } | |
762 else | |
763 { | |
764 lnum = found_fp->fd_top + found_fp->fd_len + found_off; | |
765 | |
766 if (foldmethodIsManual(curwin)) | |
767 deleteFoldEntry(found_ga, | |
768 (int)(found_fp - (fold_T *)found_ga->ga_data), recursive); | |
769 else | |
770 { | |
1780 | 771 if (first_lnum > found_fp->fd_top + found_off) |
772 first_lnum = found_fp->fd_top + found_off; | |
773 if (last_lnum < lnum) | |
7 | 774 last_lnum = lnum; |
1780 | 775 if (!did_one) |
776 parseMarker(curwin); | |
7 | 777 deleteFoldMarkers(found_fp, recursive, found_off); |
778 } | |
1780 | 779 did_one = TRUE; |
7 | 780 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
781 // redraw window |
7 | 782 changed_window_setting(); |
783 } | |
784 } | |
785 if (!did_one) | |
786 { | |
26915
3631d2deb36c
patch 8.2.3986: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26913
diff
changeset
|
787 emsg(_(e_no_fold_found)); |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
788 // Force a redraw to remove the Visual highlighting. |
7 | 789 if (had_visual) |
29732
89e1d67814a9
patch 9.0.0206: redraw flags are not named specifically
Bram Moolenaar <Bram@vim.org>
parents:
28974
diff
changeset
|
790 redraw_curbuf_later(UPD_INVERTED); |
7 | 791 } |
1780 | 792 else |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
793 // Deleting markers may make cursor column invalid. |
1780 | 794 check_cursor_col(); |
795 | |
7 | 796 if (last_lnum > 0) |
797 changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L); | |
798 } | |
799 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
800 // clearFolding() {{{2 |
7 | 801 /* |
802 * Remove all folding for window "win". | |
803 */ | |
804 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
805 clearFolding(win_T *win) |
7 | 806 { |
807 deleteFoldRecurse(&win->w_folds); | |
808 win->w_foldinvalid = FALSE; | |
809 } | |
810 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
811 // foldUpdate() {{{2 |
7 | 812 /* |
813 * Update folds for changes in the buffer of a window. | |
814 * Note that inserted/deleted lines must have already been taken care of by | |
815 * calling foldMarkAdjust(). | |
816 * The changes in lines from top to bot (inclusive). | |
817 */ | |
818 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
819 foldUpdate(win_T *wp, linenr_T top, linenr_T bot) |
7 | 820 { |
821 fold_T *fp; | |
822 | |
8891
d7ba3f9b9ba6
commit https://github.com/vim/vim/commit/429fcfbf9a9275367fe9441a50a3dcd773497d84
Christian Brabandt <cb@256bit.org>
parents:
7821
diff
changeset
|
823 if (disable_fold_update > 0) |
d7ba3f9b9ba6
commit https://github.com/vim/vim/commit/429fcfbf9a9275367fe9441a50a3dcd773497d84
Christian Brabandt <cb@256bit.org>
parents:
7821
diff
changeset
|
824 return; |
17851
ba63a184e6b6
patch 8.1.1922: in diff mode global operations can be very slow
Bram Moolenaar <Bram@vim.org>
parents:
17787
diff
changeset
|
825 #ifdef FEAT_DIFF |
ba63a184e6b6
patch 8.1.1922: in diff mode global operations can be very slow
Bram Moolenaar <Bram@vim.org>
parents:
17787
diff
changeset
|
826 if (need_diff_redraw) |
ba63a184e6b6
patch 8.1.1922: in diff mode global operations can be very slow
Bram Moolenaar <Bram@vim.org>
parents:
17787
diff
changeset
|
827 // will update later |
ba63a184e6b6
patch 8.1.1922: in diff mode global operations can be very slow
Bram Moolenaar <Bram@vim.org>
parents:
17787
diff
changeset
|
828 return; |
ba63a184e6b6
patch 8.1.1922: in diff mode global operations can be very slow
Bram Moolenaar <Bram@vim.org>
parents:
17787
diff
changeset
|
829 #endif |
8891
d7ba3f9b9ba6
commit https://github.com/vim/vim/commit/429fcfbf9a9275367fe9441a50a3dcd773497d84
Christian Brabandt <cb@256bit.org>
parents:
7821
diff
changeset
|
830 |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
831 if (wp->w_folds.ga_len > 0) |
7 | 832 { |
28929
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
833 linenr_T maybe_small_start = top; |
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
834 linenr_T maybe_small_end = bot; |
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
835 |
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
836 // Mark all folds from top to bot (or bot to top) as maybe-small. |
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
837 if (top > bot) |
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
838 { |
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
839 maybe_small_start = bot; |
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
840 maybe_small_end = top; |
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
841 } |
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
842 (void)foldFind(&wp->w_folds, maybe_small_start, &fp); |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
843 while (fp < (fold_T *)wp->w_folds.ga_data + wp->w_folds.ga_len |
28929
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
844 && fp->fd_top <= maybe_small_end) |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
845 { |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
846 fp->fd_small = MAYBE; |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
847 ++fp; |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
848 } |
7 | 849 } |
850 | |
851 if (foldmethodIsIndent(wp) | |
852 || foldmethodIsExpr(wp) | |
853 || foldmethodIsMarker(wp) | |
854 #ifdef FEAT_DIFF | |
855 || foldmethodIsDiff(wp) | |
856 #endif | |
857 || foldmethodIsSyntax(wp)) | |
1424 | 858 { |
859 int save_got_int = got_int; | |
860 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
861 // reset got_int here, otherwise it won't work |
1424 | 862 got_int = FALSE; |
7 | 863 foldUpdateIEMS(wp, top, bot); |
1424 | 864 got_int |= save_got_int; |
865 } | |
7 | 866 } |
867 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
868 // foldUpdateAll() {{{2 |
7 | 869 /* |
870 * Update all lines in a window for folding. | |
871 * Used when a fold setting changes or after reloading the buffer. | |
872 * The actual updating is postponed until fold info is used, to avoid doing | |
873 * every time a setting is changed or a syntax item is added. | |
874 */ | |
875 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
876 foldUpdateAll(win_T *win) |
7 | 877 { |
878 win->w_foldinvalid = TRUE; | |
29732
89e1d67814a9
patch 9.0.0206: redraw flags are not named specifically
Bram Moolenaar <Bram@vim.org>
parents:
28974
diff
changeset
|
879 redraw_win_later(win, UPD_NOT_VALID); |
7 | 880 } |
881 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
882 // foldMoveTo() {{{2 |
7 | 883 /* |
884 * If "updown" is FALSE: Move to the start or end of the fold. | |
885 * If "updown" is TRUE: move to fold at the same level. | |
886 * If not moved return FAIL. | |
887 */ | |
888 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
889 foldMoveTo( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
890 int updown, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
891 int dir, // FORWARD or BACKWARD |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
892 long count) |
7 | 893 { |
894 long n; | |
895 int retval = FAIL; | |
896 linenr_T lnum_off; | |
897 linenr_T lnum_found; | |
898 linenr_T lnum; | |
899 int use_level; | |
900 int maybe_small; | |
901 garray_T *gap; | |
902 fold_T *fp; | |
903 int level; | |
904 int last; | |
905 | |
36 | 906 checkupdate(curwin); |
907 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
908 // Repeat "count" times. |
7 | 909 for (n = 0; n < count; ++n) |
910 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
911 // Find nested folds. Stop when a fold is closed. The deepest fold |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
912 // that moves the cursor is used. |
7 | 913 lnum_off = 0; |
914 gap = &curwin->w_folds; | |
22798
3c72820f88b2
patch 8.2.1947: crash when using "zj" without folds
Bram Moolenaar <Bram@vim.org>
parents:
22306
diff
changeset
|
915 if (gap->ga_len == 0) |
3c72820f88b2
patch 8.2.1947: crash when using "zj" without folds
Bram Moolenaar <Bram@vim.org>
parents:
22306
diff
changeset
|
916 break; |
7 | 917 use_level = FALSE; |
918 maybe_small = FALSE; | |
919 lnum_found = curwin->w_cursor.lnum; | |
920 level = 0; | |
921 last = FALSE; | |
922 for (;;) | |
923 { | |
924 if (!foldFind(gap, curwin->w_cursor.lnum - lnum_off, &fp)) | |
925 { | |
23260
ef4f890f02f6
patch 8.2.2176: crash with a sequence of fold commands
Bram Moolenaar <Bram@vim.org>
parents:
22850
diff
changeset
|
926 if (!updown || gap->ga_len == 0) |
7 | 927 break; |
928 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
929 // When moving up, consider a fold above the cursor; when |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
930 // moving down consider a fold below the cursor. |
7 | 931 if (dir == FORWARD) |
932 { | |
933 if (fp - (fold_T *)gap->ga_data >= gap->ga_len) | |
934 break; | |
935 --fp; | |
936 } | |
937 else | |
938 { | |
939 if (fp == (fold_T *)gap->ga_data) | |
940 break; | |
941 } | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
942 // don't look for contained folds, they will always move |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
943 // the cursor too far. |
7 | 944 last = TRUE; |
945 } | |
946 | |
947 if (!last) | |
948 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
949 // Check if this fold is closed. |
7 | 950 if (check_closed(curwin, fp, &use_level, level, |
951 &maybe_small, lnum_off)) | |
952 last = TRUE; | |
953 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
954 // "[z" and "]z" stop at closed fold |
7 | 955 if (last && !updown) |
956 break; | |
957 } | |
958 | |
959 if (updown) | |
960 { | |
961 if (dir == FORWARD) | |
962 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
963 // to start of next fold if there is one |
7 | 964 if (fp + 1 - (fold_T *)gap->ga_data < gap->ga_len) |
965 { | |
966 lnum = fp[1].fd_top + lnum_off; | |
967 if (lnum > curwin->w_cursor.lnum) | |
968 lnum_found = lnum; | |
969 } | |
970 } | |
971 else | |
972 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
973 // to end of previous fold if there is one |
7 | 974 if (fp > (fold_T *)gap->ga_data) |
975 { | |
976 lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1; | |
977 if (lnum < curwin->w_cursor.lnum) | |
978 lnum_found = lnum; | |
979 } | |
980 } | |
981 } | |
982 else | |
983 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
984 // Open fold found, set cursor to its start/end and then check |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
985 // nested folds. |
7 | 986 if (dir == FORWARD) |
987 { | |
988 lnum = fp->fd_top + lnum_off + fp->fd_len - 1; | |
989 if (lnum > curwin->w_cursor.lnum) | |
990 lnum_found = lnum; | |
991 } | |
992 else | |
993 { | |
994 lnum = fp->fd_top + lnum_off; | |
995 if (lnum < curwin->w_cursor.lnum) | |
996 lnum_found = lnum; | |
997 } | |
998 } | |
999 | |
1000 if (last) | |
1001 break; | |
1002 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1003 // Check nested folds (if any). |
7 | 1004 gap = &fp->fd_nested; |
1005 lnum_off += fp->fd_top; | |
1006 ++level; | |
1007 } | |
1008 if (lnum_found != curwin->w_cursor.lnum) | |
1009 { | |
1010 if (retval == FAIL) | |
1011 setpcmark(); | |
1012 curwin->w_cursor.lnum = lnum_found; | |
1013 curwin->w_cursor.col = 0; | |
1014 retval = OK; | |
1015 } | |
1016 else | |
1017 break; | |
1018 } | |
1019 | |
1020 return retval; | |
1021 } | |
1022 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1023 // foldInitWin() {{{2 |
7 | 1024 /* |
1025 * Init the fold info in a new window. | |
1026 */ | |
1027 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1028 foldInitWin(win_T *new_win) |
7 | 1029 { |
27028
c9474ae175f4
patch 8.2.4043: using int for second argument of ga_init2()
Bram Moolenaar <Bram@vim.org>
parents:
26915
diff
changeset
|
1030 ga_init2(&new_win->w_folds, sizeof(fold_T), 10); |
7 | 1031 } |
1032 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1033 // find_wl_entry() {{{2 |
7 | 1034 /* |
1035 * Find an entry in the win->w_lines[] array for buffer line "lnum". | |
1036 * Only valid entries are considered (for entries where wl_valid is FALSE the | |
1037 * line number can be wrong). | |
1038 * Returns index of entry or -1 if not found. | |
1039 */ | |
1040 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1041 find_wl_entry(win_T *win, linenr_T lnum) |
7 | 1042 { |
1043 int i; | |
1044 | |
2114
5a97d0c03b59
updated for version 7.2.397
Bram Moolenaar <bram@zimbu.org>
parents:
2086
diff
changeset
|
1045 for (i = 0; i < win->w_lines_valid; ++i) |
5a97d0c03b59
updated for version 7.2.397
Bram Moolenaar <bram@zimbu.org>
parents:
2086
diff
changeset
|
1046 if (win->w_lines[i].wl_valid) |
5a97d0c03b59
updated for version 7.2.397
Bram Moolenaar <bram@zimbu.org>
parents:
2086
diff
changeset
|
1047 { |
5a97d0c03b59
updated for version 7.2.397
Bram Moolenaar <bram@zimbu.org>
parents:
2086
diff
changeset
|
1048 if (lnum < win->w_lines[i].wl_lnum) |
5a97d0c03b59
updated for version 7.2.397
Bram Moolenaar <bram@zimbu.org>
parents:
2086
diff
changeset
|
1049 return -1; |
5a97d0c03b59
updated for version 7.2.397
Bram Moolenaar <bram@zimbu.org>
parents:
2086
diff
changeset
|
1050 if (lnum <= win->w_lines[i].wl_lastlnum) |
5a97d0c03b59
updated for version 7.2.397
Bram Moolenaar <bram@zimbu.org>
parents:
2086
diff
changeset
|
1051 return i; |
5a97d0c03b59
updated for version 7.2.397
Bram Moolenaar <bram@zimbu.org>
parents:
2086
diff
changeset
|
1052 } |
7 | 1053 return -1; |
1054 } | |
1055 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1056 // foldAdjustVisual() {{{2 |
7 | 1057 /* |
1058 * Adjust the Visual area to include any fold at the start or end completely. | |
1059 */ | |
1060 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1061 foldAdjustVisual(void) |
7 | 1062 { |
1063 pos_T *start, *end; | |
1064 char_u *ptr; | |
1065 | |
1066 if (!VIsual_active || !hasAnyFolding(curwin)) | |
1067 return; | |
1068 | |
11121
778c10516955
patch 8.0.0448: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11038
diff
changeset
|
1069 if (LTOREQ_POS(VIsual, curwin->w_cursor)) |
7 | 1070 { |
1071 start = &VIsual; | |
1072 end = &curwin->w_cursor; | |
1073 } | |
1074 else | |
1075 { | |
1076 start = &curwin->w_cursor; | |
1077 end = &VIsual; | |
1078 } | |
1079 if (hasFolding(start->lnum, &start->lnum, NULL)) | |
1080 start->col = 0; | |
31651
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1081 |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1082 if (!hasFolding(end->lnum, NULL, &end->lnum)) |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1083 return; |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1084 |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1085 ptr = ml_get(end->lnum); |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1086 end->col = (colnr_T)STRLEN(ptr); |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1087 if (end->col > 0 && *p_sel == 'o') |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1088 --end->col; |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1089 // prevent cursor from moving on the trail byte |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1090 if (has_mbyte) |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1091 mb_adjust_cursor(); |
7 | 1092 } |
1093 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1094 // cursor_foldstart() {{{2 |
7 | 1095 /* |
1096 * Move the cursor to the first line of a closed fold. | |
1097 */ | |
1098 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1099 foldAdjustCursor(void) |
7 | 1100 { |
1101 (void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL); | |
1102 } | |
1103 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1104 // Internal functions for "fold_T" {{{1 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1105 // cloneFoldGrowArray() {{{2 |
7 | 1106 /* |
1107 * Will "clone" (i.e deep copy) a garray_T of folds. | |
1108 * | |
1109 * Return FAIL if the operation cannot be completed, otherwise OK. | |
1110 */ | |
1111 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1112 cloneFoldGrowArray(garray_T *from, garray_T *to) |
7 | 1113 { |
1114 int i; | |
1115 fold_T *from_p; | |
1116 fold_T *to_p; | |
1117 | |
1118 ga_init2(to, from->ga_itemsize, from->ga_growsize); | |
1119 if (from->ga_len == 0 || ga_grow(to, from->ga_len) == FAIL) | |
1120 return; | |
1121 | |
1122 from_p = (fold_T *)from->ga_data; | |
1123 to_p = (fold_T *)to->ga_data; | |
1124 | |
1125 for (i = 0; i < from->ga_len; i++) | |
1126 { | |
1127 to_p->fd_top = from_p->fd_top; | |
1128 to_p->fd_len = from_p->fd_len; | |
1129 to_p->fd_flags = from_p->fd_flags; | |
1130 to_p->fd_small = from_p->fd_small; | |
1131 cloneFoldGrowArray(&from_p->fd_nested, &to_p->fd_nested); | |
1132 ++to->ga_len; | |
1133 ++from_p; | |
1134 ++to_p; | |
1135 } | |
1136 } | |
1137 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1138 // foldFind() {{{2 |
7 | 1139 /* |
1140 * Search for line "lnum" in folds of growarray "gap". | |
28578
8cba27db759a
patch 8.2.4813: pasting text while indent folding may mess up folds
Bram Moolenaar <Bram@vim.org>
parents:
27752
diff
changeset
|
1141 * Set "*fpp" to the fold struct for the fold that contains "lnum" or |
7 | 1142 * the first fold below it (careful: it can be beyond the end of the array!). |
1143 * Returns FALSE when there is no fold that contains "lnum". | |
1144 */ | |
1145 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1146 foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp) |
7 | 1147 { |
1148 linenr_T low, high; | |
1149 fold_T *fp; | |
1150 int i; | |
1151 | |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1152 if (gap->ga_len == 0) |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1153 { |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1154 *fpp = NULL; |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1155 return FALSE; |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1156 } |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1157 |
7 | 1158 /* |
1159 * Perform a binary search. | |
1160 * "low" is lowest index of possible match. | |
1161 * "high" is highest index of possible match. | |
1162 */ | |
1163 fp = (fold_T *)gap->ga_data; | |
1164 low = 0; | |
1165 high = gap->ga_len - 1; | |
1166 while (low <= high) | |
1167 { | |
1168 i = (low + high) / 2; | |
1169 if (fp[i].fd_top > lnum) | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1170 // fold below lnum, adjust high |
7 | 1171 high = i - 1; |
1172 else if (fp[i].fd_top + fp[i].fd_len <= lnum) | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1173 // fold above lnum, adjust low |
7 | 1174 low = i + 1; |
1175 else | |
1176 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1177 // lnum is inside this fold |
7 | 1178 *fpp = fp + i; |
1179 return TRUE; | |
1180 } | |
1181 } | |
1182 *fpp = fp + low; | |
1183 return FALSE; | |
1184 } | |
1185 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1186 // foldLevelWin() {{{2 |
7 | 1187 /* |
1188 * Return fold level at line number "lnum" in window "wp". | |
1189 */ | |
1190 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1191 foldLevelWin(win_T *wp, linenr_T lnum) |
7 | 1192 { |
1193 fold_T *fp; | |
1194 linenr_T lnum_rel = lnum; | |
1195 int level = 0; | |
1196 garray_T *gap; | |
1197 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1198 // Recursively search for a fold that contains "lnum". |
7 | 1199 gap = &wp->w_folds; |
1200 for (;;) | |
1201 { | |
1202 if (!foldFind(gap, lnum_rel, &fp)) | |
1203 break; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1204 // Check nested folds. Line number is relative to containing fold. |
7 | 1205 gap = &fp->fd_nested; |
1206 lnum_rel -= fp->fd_top; | |
1207 ++level; | |
1208 } | |
1209 | |
1210 return level; | |
1211 } | |
1212 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1213 // checkupdate() {{{2 |
7 | 1214 /* |
1215 * Check if the folds in window "wp" are invalid and update them if needed. | |
1216 */ | |
1217 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1218 checkupdate(win_T *wp) |
7 | 1219 { |
31651
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1220 if (!wp->w_foldinvalid) |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1221 return; |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1222 |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1223 foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); // will update all |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1224 wp->w_foldinvalid = FALSE; |
7 | 1225 } |
1226 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1227 // setFoldRepeat() {{{2 |
7 | 1228 /* |
1229 * Open or close fold for current window at line "lnum". | |
1230 * Repeat "count" times. | |
1231 */ | |
1232 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1233 setFoldRepeat(linenr_T lnum, long count, int do_open) |
7 | 1234 { |
1235 int done; | |
1236 long n; | |
1237 | |
1238 for (n = 0; n < count; ++n) | |
1239 { | |
1240 done = DONE_NOTHING; | |
1757 | 1241 (void)setManualFold(lnum, do_open, FALSE, &done); |
7 | 1242 if (!(done & DONE_ACTION)) |
1243 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1244 // Only give an error message when no fold could be opened. |
7 | 1245 if (n == 0 && !(done & DONE_FOLD)) |
26915
3631d2deb36c
patch 8.2.3986: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26913
diff
changeset
|
1246 emsg(_(e_no_fold_found)); |
7 | 1247 break; |
1248 } | |
1249 } | |
1250 } | |
1251 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1252 // setManualFold() {{{2 |
7 | 1253 /* |
1254 * Open or close the fold in the current window which contains "lnum". | |
1255 * Also does this for other windows in diff mode when needed. | |
1256 */ | |
1257 static linenr_T | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1258 setManualFold( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1259 linenr_T lnum, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1260 int opening, // TRUE when opening, FALSE when closing |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1261 int recurse, // TRUE when closing/opening recursive |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1262 int *donep) |
7 | 1263 { |
1264 #ifdef FEAT_DIFF | |
1265 if (foldmethodIsDiff(curwin) && curwin->w_p_scb) | |
1266 { | |
1267 win_T *wp; | |
1268 linenr_T dlnum; | |
1269 | |
1270 /* | |
1271 * Do the same operation in other windows in diff mode. Calculate the | |
1272 * line number from the diffs. | |
1273 */ | |
1274 FOR_ALL_WINDOWS(wp) | |
1275 { | |
1276 if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb) | |
1277 { | |
1278 dlnum = diff_lnum_win(curwin->w_cursor.lnum, wp); | |
1279 if (dlnum != 0) | |
1280 (void)setManualFoldWin(wp, dlnum, opening, recurse, NULL); | |
1281 } | |
1282 } | |
1283 } | |
1284 #endif | |
1285 | |
1286 return setManualFoldWin(curwin, lnum, opening, recurse, donep); | |
1287 } | |
1288 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1289 // setManualFoldWin() {{{2 |
7 | 1290 /* |
1291 * Open or close the fold in window "wp" which contains "lnum". | |
1292 * "donep", when not NULL, points to flag that is set to DONE_FOLD when some | |
1293 * fold was found and to DONE_ACTION when some fold was opened or closed. | |
1294 * When "donep" is NULL give an error message when no fold was found for | |
1295 * "lnum", but only if "wp" is "curwin". | |
1296 * Return the line number of the next line that could be closed. | |
1297 * It's only valid when "opening" is TRUE! | |
1298 */ | |
1299 static linenr_T | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1300 setManualFoldWin( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1301 win_T *wp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1302 linenr_T lnum, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1303 int opening, // TRUE when opening, FALSE when closing |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1304 int recurse, // TRUE when closing/opening recursive |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1305 int *donep) |
7 | 1306 { |
1307 fold_T *fp; | |
1308 fold_T *fp2; | |
1309 fold_T *found = NULL; | |
1310 int j; | |
1311 int level = 0; | |
1312 int use_level = FALSE; | |
1313 int found_fold = FALSE; | |
1314 garray_T *gap; | |
1315 linenr_T next = MAXLNUM; | |
1316 linenr_T off = 0; | |
1317 int done = 0; | |
1318 | |
1319 checkupdate(wp); | |
1320 | |
1321 /* | |
1322 * Find the fold, open or close it. | |
1323 */ | |
1324 gap = &wp->w_folds; | |
1325 for (;;) | |
1326 { | |
1327 if (!foldFind(gap, lnum, &fp)) | |
1328 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1329 // If there is a following fold, continue there next time. |
22021
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
1330 if (fp != NULL && fp < (fold_T *)gap->ga_data + gap->ga_len) |
7 | 1331 next = fp->fd_top + off; |
1332 break; | |
1333 } | |
1334 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1335 // lnum is inside this fold |
7 | 1336 found_fold = TRUE; |
1337 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1338 // If there is a following fold, continue there next time. |
7 | 1339 if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len) |
1340 next = fp[1].fd_top + off; | |
1341 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1342 // Change from level-dependent folding to manual. |
7 | 1343 if (use_level || fp->fd_flags == FD_LEVEL) |
1344 { | |
1345 use_level = TRUE; | |
1346 if (level >= wp->w_p_fdl) | |
1347 fp->fd_flags = FD_CLOSED; | |
1348 else | |
1349 fp->fd_flags = FD_OPEN; | |
1350 fp2 = (fold_T *)fp->fd_nested.ga_data; | |
1351 for (j = 0; j < fp->fd_nested.ga_len; ++j) | |
1352 fp2[j].fd_flags = FD_LEVEL; | |
1353 } | |
1354 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1355 // Simple case: Close recursively means closing the fold. |
7 | 1356 if (!opening && recurse) |
1357 { | |
1358 if (fp->fd_flags != FD_CLOSED) | |
1359 { | |
1360 done |= DONE_ACTION; | |
1361 fp->fd_flags = FD_CLOSED; | |
1362 } | |
1363 } | |
1364 else if (fp->fd_flags == FD_CLOSED) | |
1365 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1366 // When opening, open topmost closed fold. |
7 | 1367 if (opening) |
1368 { | |
1369 fp->fd_flags = FD_OPEN; | |
1370 done |= DONE_ACTION; | |
1371 if (recurse) | |
1372 foldOpenNested(fp); | |
1373 } | |
1374 break; | |
1375 } | |
1376 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1377 // fold is open, check nested folds |
7 | 1378 found = fp; |
1379 gap = &fp->fd_nested; | |
1380 lnum -= fp->fd_top; | |
1381 off += fp->fd_top; | |
1382 ++level; | |
1383 } | |
1384 if (found_fold) | |
1385 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1386 // When closing and not recurse, close deepest open fold. |
7 | 1387 if (!opening && found != NULL) |
1388 { | |
1389 found->fd_flags = FD_CLOSED; | |
1390 done |= DONE_ACTION; | |
1391 } | |
1392 wp->w_fold_manual = TRUE; | |
1393 if (done & DONE_ACTION) | |
1394 changed_window_setting_win(wp); | |
1395 done |= DONE_FOLD; | |
1396 } | |
1397 else if (donep == NULL && wp == curwin) | |
26915
3631d2deb36c
patch 8.2.3986: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26913
diff
changeset
|
1398 emsg(_(e_no_fold_found)); |
7 | 1399 |
1400 if (donep != NULL) | |
1401 *donep |= done; | |
1402 | |
1403 return next; | |
1404 } | |
1405 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1406 // foldOpenNested() {{{2 |
7 | 1407 /* |
1408 * Open all nested folds in fold "fpr" recursively. | |
1409 */ | |
1410 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1411 foldOpenNested(fold_T *fpr) |
7 | 1412 { |
1413 int i; | |
1414 fold_T *fp; | |
1415 | |
1416 fp = (fold_T *)fpr->fd_nested.ga_data; | |
1417 for (i = 0; i < fpr->fd_nested.ga_len; ++i) | |
1418 { | |
1419 foldOpenNested(&fp[i]); | |
1420 fp[i].fd_flags = FD_OPEN; | |
1421 } | |
1422 } | |
1423 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1424 // deleteFoldEntry() {{{2 |
7 | 1425 /* |
1426 * Delete fold "idx" from growarray "gap". | |
1427 * When "recursive" is TRUE also delete all the folds contained in it. | |
1428 * When "recursive" is FALSE contained folds are moved one level up. | |
1429 */ | |
1430 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1431 deleteFoldEntry(garray_T *gap, int idx, int recursive) |
7 | 1432 { |
1433 fold_T *fp; | |
1434 int i; | |
1435 long moved; | |
1436 fold_T *nfp; | |
1437 | |
1438 fp = (fold_T *)gap->ga_data + idx; | |
1439 if (recursive || fp->fd_nested.ga_len == 0) | |
1440 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1441 // recursively delete the contained folds |
7 | 1442 deleteFoldRecurse(&fp->fd_nested); |
1443 --gap->ga_len; | |
1444 if (idx < gap->ga_len) | |
1445 mch_memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx)); | |
1446 } | |
1447 else | |
1448 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1449 // Move nested folds one level up, to overwrite the fold that is |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1450 // deleted. |
7 | 1451 moved = fp->fd_nested.ga_len; |
1452 if (ga_grow(gap, (int)(moved - 1)) == OK) | |
1453 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1454 // Get "fp" again, the array may have been reallocated. |
3028 | 1455 fp = (fold_T *)gap->ga_data + idx; |
1456 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1457 // adjust fd_top and fd_flags for the moved folds |
7 | 1458 nfp = (fold_T *)fp->fd_nested.ga_data; |
1459 for (i = 0; i < moved; ++i) | |
1460 { | |
1461 nfp[i].fd_top += fp->fd_top; | |
1462 if (fp->fd_flags == FD_LEVEL) | |
1463 nfp[i].fd_flags = FD_LEVEL; | |
1464 if (fp->fd_small == MAYBE) | |
1465 nfp[i].fd_small = MAYBE; | |
1466 } | |
1467 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1468 // move the existing folds down to make room |
3028 | 1469 if (idx + 1 < gap->ga_len) |
7 | 1470 mch_memmove(fp + moved, fp + 1, |
3028 | 1471 sizeof(fold_T) * (gap->ga_len - (idx + 1))); |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1472 // move the contained folds one level up |
7 | 1473 mch_memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved)); |
1474 vim_free(nfp); | |
1475 gap->ga_len += moved - 1; | |
1476 } | |
1477 } | |
1478 } | |
1479 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1480 // deleteFoldRecurse() {{{2 |
7 | 1481 /* |
1482 * Delete nested folds in a fold. | |
1483 */ | |
1484 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1485 deleteFoldRecurse(garray_T *gap) |
7 | 1486 { |
1487 int i; | |
1488 | |
1489 for (i = 0; i < gap->ga_len; ++i) | |
1490 deleteFoldRecurse(&(((fold_T *)(gap->ga_data))[i].fd_nested)); | |
1491 ga_clear(gap); | |
1492 } | |
1493 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1494 // foldMarkAdjust() {{{2 |
7 | 1495 /* |
1496 * Update line numbers of folds for inserted/deleted lines. | |
1497 */ | |
1498 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1499 foldMarkAdjust( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1500 win_T *wp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1501 linenr_T line1, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1502 linenr_T line2, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1503 long amount, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1504 long amount_after) |
7 | 1505 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1506 // If deleting marks from line1 to line2, but not deleting all those |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1507 // lines, set line2 so that only deleted lines have their folds removed. |
7 | 1508 if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) |
1509 line2 = line1 - amount_after - 1; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1510 // If appending a line in Insert mode, it should be included in the fold |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1511 // just above the line. |
28773
d770568e6c98
patch 8.2.4911: the mode #defines are not clearly named
Bram Moolenaar <Bram@vim.org>
parents:
28578
diff
changeset
|
1512 if ((State & MODE_INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) |
7 | 1513 --line1; |
1514 foldMarkAdjustRecurse(&wp->w_folds, line1, line2, amount, amount_after); | |
1515 } | |
1516 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1517 // foldMarkAdjustRecurse() {{{2 |
7 | 1518 static void |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1519 foldMarkAdjustRecurse( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1520 garray_T *gap, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1521 linenr_T line1, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1522 linenr_T line2, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1523 long amount, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1524 long amount_after) |
7 | 1525 { |
1526 fold_T *fp; | |
1527 int i; | |
1528 linenr_T last; | |
1529 linenr_T top; | |
1530 | |
22009
24cef4317d92
patch 8.2.1554: crash in normal test
Bram Moolenaar <Bram@vim.org>
parents:
22008
diff
changeset
|
1531 if (gap->ga_len == 0) |
24cef4317d92
patch 8.2.1554: crash in normal test
Bram Moolenaar <Bram@vim.org>
parents:
22008
diff
changeset
|
1532 return; |
24cef4317d92
patch 8.2.1554: crash in normal test
Bram Moolenaar <Bram@vim.org>
parents:
22008
diff
changeset
|
1533 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1534 // In Insert mode an inserted line at the top of a fold is considered part |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1535 // of the fold, otherwise it isn't. |
28773
d770568e6c98
patch 8.2.4911: the mode #defines are not clearly named
Bram Moolenaar <Bram@vim.org>
parents:
28578
diff
changeset
|
1536 if ((State & MODE_INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) |
7 | 1537 top = line1 + 1; |
1538 else | |
1539 top = line1; | |
1540 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1541 // Find the fold containing or just below "line1". |
7 | 1542 (void)foldFind(gap, line1, &fp); |
1543 | |
1544 /* | |
1545 * Adjust all folds below "line1" that are affected. | |
1546 */ | |
1547 for (i = (int)(fp - (fold_T *)gap->ga_data); i < gap->ga_len; ++i, ++fp) | |
1548 { | |
1549 /* | |
1550 * Check for these situations: | |
1551 * 1 2 3 | |
1552 * 1 2 3 | |
1553 * line1 2 3 4 5 | |
1554 * 2 3 4 5 | |
1555 * 2 3 4 5 | |
1556 * line2 2 3 4 5 | |
1557 * 3 5 6 | |
1558 * 3 5 6 | |
1559 */ | |
1560 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1561 last = fp->fd_top + fp->fd_len - 1; // last line of fold |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1562 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1563 // 1. fold completely above line1: nothing to do |
7 | 1564 if (last < line1) |
1565 continue; | |
1566 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1567 // 6. fold below line2: only adjust for amount_after |
7 | 1568 if (fp->fd_top > line2) |
1569 { | |
1570 if (amount_after == 0) | |
1571 break; | |
1572 fp->fd_top += amount_after; | |
1573 } | |
1574 else | |
1575 { | |
1576 if (fp->fd_top >= top && last <= line2) | |
1577 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1578 // 4. fold completely contained in range |
7 | 1579 if (amount == MAXLNUM) |
1580 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1581 // Deleting lines: delete the fold completely |
7 | 1582 deleteFoldEntry(gap, i, TRUE); |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1583 --i; // adjust index for deletion |
7 | 1584 --fp; |
1585 } | |
1586 else | |
1587 fp->fd_top += amount; | |
1588 } | |
1589 else | |
1590 { | |
1591 if (fp->fd_top < top) | |
1592 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1593 // 2 or 3: need to correct nested folds too |
1964 | 1594 foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top, |
1595 line2 - fp->fd_top, amount, amount_after); | |
7 | 1596 if (last <= line2) |
1597 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1598 // 2. fold contains line1, line2 is below fold |
7 | 1599 if (amount == MAXLNUM) |
1600 fp->fd_len = line1 - fp->fd_top; | |
1601 else | |
1602 fp->fd_len += amount; | |
1603 } | |
1604 else | |
1605 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1606 // 3. fold contains line1 and line2 |
7 | 1607 fp->fd_len += amount_after; |
1608 } | |
1609 } | |
1610 else | |
1611 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1612 // 5. fold is below line1 and contains line2; need to |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1613 // correct nested folds too |
7 | 1614 if (amount == MAXLNUM) |
1615 { | |
10998
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1616 foldMarkAdjustRecurse(&fp->fd_nested, |
27734
51a28e8be7c3
patch 8.2.4393: possible number overflow with nested folds
Bram Moolenaar <Bram@vim.org>
parents:
27426
diff
changeset
|
1617 0, |
10998
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1618 line2 - fp->fd_top, |
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1619 amount, |
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1620 amount_after + (fp->fd_top - top)); |
7 | 1621 fp->fd_len -= line2 - fp->fd_top + 1; |
1622 fp->fd_top = line1; | |
1623 } | |
1624 else | |
1625 { | |
10998
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1626 foldMarkAdjustRecurse(&fp->fd_nested, |
27734
51a28e8be7c3
patch 8.2.4393: possible number overflow with nested folds
Bram Moolenaar <Bram@vim.org>
parents:
27426
diff
changeset
|
1627 0, |
10998
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1628 line2 - fp->fd_top, |
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1629 amount, |
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1630 amount_after - amount); |
7 | 1631 fp->fd_len += amount_after - amount; |
1632 fp->fd_top += amount; | |
1633 } | |
1634 } | |
1635 } | |
1636 } | |
1637 } | |
1638 } | |
1639 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1640 // getDeepestNesting() {{{2 |
7 | 1641 /* |
1642 * Get the lowest 'foldlevel' value that makes the deepest nested fold in the | |
1643 * current window open. | |
1644 */ | |
1645 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1646 getDeepestNesting(void) |
7 | 1647 { |
1648 checkupdate(curwin); | |
1649 return getDeepestNestingRecurse(&curwin->w_folds); | |
1650 } | |
1651 | |
1652 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1653 getDeepestNestingRecurse(garray_T *gap) |
7 | 1654 { |
1655 int i; | |
1656 int level; | |
1657 int maxlevel = 0; | |
1658 fold_T *fp; | |
1659 | |
1660 fp = (fold_T *)gap->ga_data; | |
1661 for (i = 0; i < gap->ga_len; ++i) | |
1662 { | |
1663 level = getDeepestNestingRecurse(&fp[i].fd_nested) + 1; | |
1664 if (level > maxlevel) | |
1665 maxlevel = level; | |
1666 } | |
1667 | |
1668 return maxlevel; | |
1669 } | |
1670 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1671 // check_closed() {{{2 |
7 | 1672 /* |
1673 * Check if a fold is closed and update the info needed to check nested folds. | |
1674 */ | |
1675 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1676 check_closed( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1677 win_T *win, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1678 fold_T *fp, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1679 int *use_levelp, // TRUE: outer fold had FD_LEVEL |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1680 int level, // folding depth |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1681 int *maybe_smallp, // TRUE: outer this had fd_small == MAYBE |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1682 linenr_T lnum_off) // line number offset for fp->fd_top |
7 | 1683 { |
1684 int closed = FALSE; | |
1685 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1686 // Check if this fold is closed. If the flag is FD_LEVEL this |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1687 // fold and all folds it contains depend on 'foldlevel'. |
7 | 1688 if (*use_levelp || fp->fd_flags == FD_LEVEL) |
1689 { | |
1690 *use_levelp = TRUE; | |
1691 if (level >= win->w_p_fdl) | |
1692 closed = TRUE; | |
1693 } | |
1694 else if (fp->fd_flags == FD_CLOSED) | |
1695 closed = TRUE; | |
1696 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1697 // Small fold isn't closed anyway. |
7 | 1698 if (fp->fd_small == MAYBE) |
1699 *maybe_smallp = TRUE; | |
1700 if (closed) | |
1701 { | |
1702 if (*maybe_smallp) | |
1703 fp->fd_small = MAYBE; | |
1704 checkSmall(win, fp, lnum_off); | |
1705 if (fp->fd_small == TRUE) | |
1706 closed = FALSE; | |
1707 } | |
1708 return closed; | |
1709 } | |
1710 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1711 // checkSmall() {{{2 |
7 | 1712 /* |
1713 * Update fd_small field of fold "fp". | |
1714 */ | |
1715 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1716 checkSmall( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1717 win_T *wp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1718 fold_T *fp, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1719 linenr_T lnum_off) // offset for fp->fd_top |
7 | 1720 { |
1721 int count; | |
1722 int n; | |
1723 | |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1724 if (fp->fd_small != MAYBE) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1725 return; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1726 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1727 // Mark any nested folds to maybe-small |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1728 setSmallMaybe(&fp->fd_nested); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1729 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1730 if (fp->fd_len > curwin->w_p_fml) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1731 fp->fd_small = FALSE; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1732 else |
7 | 1733 { |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1734 count = 0; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1735 for (n = 0; n < fp->fd_len; ++n) |
7 | 1736 { |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1737 count += plines_win_nofold(wp, fp->fd_top + lnum_off + n); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1738 if (count > curwin->w_p_fml) |
7 | 1739 { |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1740 fp->fd_small = FALSE; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1741 return; |
7 | 1742 } |
1743 } | |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1744 fp->fd_small = TRUE; |
7 | 1745 } |
1746 } | |
1747 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1748 // setSmallMaybe() {{{2 |
7 | 1749 /* |
1750 * Set small flags in "gap" to MAYBE. | |
1751 */ | |
1752 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1753 setSmallMaybe(garray_T *gap) |
7 | 1754 { |
1755 int i; | |
1756 fold_T *fp; | |
1757 | |
1758 fp = (fold_T *)gap->ga_data; | |
1759 for (i = 0; i < gap->ga_len; ++i) | |
1760 fp[i].fd_small = MAYBE; | |
1761 } | |
1762 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1763 // foldCreateMarkers() {{{2 |
7 | 1764 /* |
1765 * Create a fold from line "start" to line "end" (inclusive) in the current | |
1766 * window by adding markers. | |
1767 */ | |
1768 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1769 foldCreateMarkers(linenr_T start, linenr_T end) |
7 | 1770 { |
1771 if (!curbuf->b_p_ma) | |
1772 { | |
25064
8f2262c72178
patch 8.2.3069: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
23812
diff
changeset
|
1773 emsg(_(e_cannot_make_changes_modifiable_is_off)); |
7 | 1774 return; |
1775 } | |
1776 parseMarker(curwin); | |
1777 | |
1778 foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen); | |
1779 foldAddMarker(end, foldendmarker, foldendmarkerlen); | |
1780 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1781 // Update both changes here, to avoid all folds after the start are |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1782 // changed when the start marker is inserted and the end isn't. |
7 | 1783 changed_lines(start, (colnr_T)0, end, 0L); |
1784 } | |
1785 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1786 // foldAddMarker() {{{2 |
7 | 1787 /* |
1788 * Add "marker[markerlen]" in 'commentstring' to line "lnum". | |
1789 */ | |
1790 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1791 foldAddMarker(linenr_T lnum, char_u *marker, int markerlen) |
7 | 1792 { |
1793 char_u *cms = curbuf->b_p_cms; | |
1794 char_u *line; | |
1795 int line_len; | |
1796 char_u *newline; | |
1797 char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s"); | |
11131
8d9ecf09183a
patch 8.0.0453: adding fold marker creates new comment
Christian Brabandt <cb@256bit.org>
parents:
11129
diff
changeset
|
1798 int line_is_comment = FALSE; |
7 | 1799 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1800 // Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end |
7 | 1801 line = ml_get(lnum); |
1802 line_len = (int)STRLEN(line); | |
1803 | |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1804 if (u_save(lnum - 1, lnum + 1) != OK) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1805 return; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1806 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1807 // Check if the line ends with an unclosed comment |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1808 (void)skip_comment(line, FALSE, FALSE, &line_is_comment); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1809 newline = alloc(line_len + markerlen + STRLEN(cms) + 1); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1810 if (newline == NULL) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1811 return; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1812 STRCPY(newline, line); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1813 // Append the marker to the end of the line |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1814 if (p == NULL || line_is_comment) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1815 vim_strncpy(newline + line_len, marker, markerlen); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1816 else |
7 | 1817 { |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1818 STRCPY(newline + line_len, cms); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1819 STRNCPY(newline + line_len + (p - cms), marker, markerlen); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1820 STRCPY(newline + line_len + (p - cms) + markerlen, p + 2); |
7 | 1821 } |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1822 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1823 ml_replace(lnum, newline, FALSE); |
7 | 1824 } |
1825 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1826 // deleteFoldMarkers() {{{2 |
7 | 1827 /* |
1828 * Delete the markers for a fold, causing it to be deleted. | |
1829 */ | |
1830 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1831 deleteFoldMarkers( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1832 fold_T *fp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1833 int recursive, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1834 linenr_T lnum_off) // offset for fp->fd_top |
7 | 1835 { |
1836 int i; | |
1837 | |
1838 if (recursive) | |
1839 for (i = 0; i < fp->fd_nested.ga_len; ++i) | |
1840 deleteFoldMarkers((fold_T *)fp->fd_nested.ga_data + i, TRUE, | |
1841 lnum_off + fp->fd_top); | |
1842 foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen); | |
1843 foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1, | |
1844 foldendmarker, foldendmarkerlen); | |
1845 } | |
1846 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1847 // foldDelMarker() {{{2 |
7 | 1848 /* |
1849 * Delete marker "marker[markerlen]" at the end of line "lnum". | |
1850 * Delete 'commentstring' if it matches. | |
17787
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
1851 * If the marker is not found, there is no error message. Could be a missing |
7 | 1852 * close-marker. |
1853 */ | |
1854 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1855 foldDelMarker(linenr_T lnum, char_u *marker, int markerlen) |
7 | 1856 { |
1857 char_u *line; | |
1858 char_u *newline; | |
1859 char_u *p; | |
1860 int len; | |
1861 char_u *cms = curbuf->b_p_cms; | |
1862 char_u *cms2; | |
1863 | |
17787
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
1864 // end marker may be missing and fold extends below the last line |
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
1865 if (lnum > curbuf->b_ml.ml_line_count) |
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
1866 return; |
7 | 1867 line = ml_get(lnum); |
1868 for (p = line; *p != NUL; ++p) | |
1869 if (STRNCMP(p, marker, markerlen) == 0) | |
1870 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1871 // Found the marker, include a digit if it's there. |
7 | 1872 len = markerlen; |
1873 if (VIM_ISDIGIT(p[len])) | |
1874 ++len; | |
1875 if (*cms != NUL) | |
1876 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1877 // Also delete 'commentstring' if it matches. |
7 | 1878 cms2 = (char_u *)strstr((char *)cms, "%s"); |
1879 if (p - line >= cms2 - cms | |
1880 && STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0 | |
1881 && STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0) | |
1882 { | |
1883 p -= cms2 - cms; | |
1884 len += (int)STRLEN(cms) - 2; | |
1885 } | |
1886 } | |
1887 if (u_save(lnum - 1, lnum + 1) == OK) | |
1888 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1889 // Make new line: text-before-marker + text-after-marker |
16764
ef00b6bc186b
patch 8.1.1384: using "int" for alloc() often results in compiler warnings
Bram Moolenaar <Bram@vim.org>
parents:
15595
diff
changeset
|
1890 newline = alloc(STRLEN(line) - len + 1); |
7 | 1891 if (newline != NULL) |
1892 { | |
1893 STRNCPY(newline, line, p - line); | |
1894 STRCPY(newline + (p - line), p + len); | |
1895 ml_replace(lnum, newline, FALSE); | |
1896 } | |
1897 } | |
1898 break; | |
1899 } | |
1900 } | |
1901 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1902 // get_foldtext() {{{2 |
29 | 1903 /* |
1904 * Return the text for a closed fold at line "lnum", with last line "lnume". | |
9754
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
1905 * When 'foldtext' isn't set puts the result in "buf[FOLD_TEXT_LEN]". |
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
1906 * Otherwise the result is in allocated memory. |
29 | 1907 */ |
1908 char_u * | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1909 get_foldtext( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1910 win_T *wp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1911 linenr_T lnum, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1912 linenr_T lnume, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1913 foldinfo_T *foldinfo, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1914 char_u *buf) |
29 | 1915 { |
1916 char_u *text = NULL; | |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1917 #ifdef FEAT_EVAL |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1918 // an error occurred when evaluating 'fdt' setting |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1919 static int got_fdt_error = FALSE; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1920 int save_did_emsg = did_emsg; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1921 static win_T *last_wp = NULL; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1922 static linenr_T last_lnum = 0; |
29 | 1923 |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1924 if (last_wp != wp || last_wp == NULL |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1925 || last_lnum > lnum || last_lnum == 0) |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1926 // window changed, try evaluating foldtext setting once again |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1927 got_fdt_error = FALSE; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1928 |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1929 if (!got_fdt_error) |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1930 // a previous error should not abort evaluating 'foldexpr' |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1931 did_emsg = FALSE; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1932 |
29 | 1933 if (*wp->w_p_fdt != NUL) |
1934 { | |
1981 | 1935 char_u dashes[MAX_LEVEL + 2]; |
29 | 1936 int level; |
1937 char_u *p; | |
1938 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1939 // Set "v:foldstart" and "v:foldend". |
29 | 1940 set_vim_var_nr(VV_FOLDSTART, lnum); |
1941 set_vim_var_nr(VV_FOLDEND, lnume); | |
1942 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1943 // Set "v:folddashes" to a string of "level" dashes. |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1944 // Set "v:foldlevel" to "level". |
29 | 1945 level = foldinfo->fi_level; |
1981 | 1946 if (level > (int)sizeof(dashes) - 1) |
1947 level = (int)sizeof(dashes) - 1; | |
29 | 1948 vim_memset(dashes, '-', (size_t)level); |
1949 dashes[level] = NUL; | |
1950 set_vim_var_string(VV_FOLDDASHES, dashes, -1); | |
1951 set_vim_var_nr(VV_FOLDLEVEL, (long)level); | |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1952 |
27301
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1953 // skip evaluating 'foldtext' on errors |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1954 if (!got_fdt_error) |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1955 { |
27301
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1956 win_T *save_curwin = curwin; |
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1957 sctx_T saved_sctx = current_sctx; |
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1958 |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1959 curwin = wp; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1960 curbuf = wp->w_buffer; |
27301
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1961 current_sctx = wp->w_p_script_ctx[WV_FDT]; |
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1962 |
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1963 ++emsg_off; // handle exceptions, but don't display errors |
20996
3af71cbcfdbe
patch 8.2.1049: Vim9: leaking memory when using continuation line
Bram Moolenaar <Bram@vim.org>
parents:
18779
diff
changeset
|
1964 text = eval_to_string_safe(wp->w_p_fdt, |
30598
37aa9fd2ed72
patch 9.0.0634: evaluating "expr" options has more overhead than needed
Bram Moolenaar <Bram@vim.org>
parents:
29732
diff
changeset
|
1965 was_set_insecurely((char_u *)"foldtext", OPT_LOCAL), |
37aa9fd2ed72
patch 9.0.0634: evaluating "expr" options has more overhead than needed
Bram Moolenaar <Bram@vim.org>
parents:
29732
diff
changeset
|
1966 TRUE, TRUE); |
27301
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1967 --emsg_off; |
29 | 1968 |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1969 if (text == NULL || did_emsg) |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1970 got_fdt_error = TRUE; |
29 | 1971 |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1972 curwin = save_curwin; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1973 curbuf = curwin->w_buffer; |
27301
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1974 current_sctx = saved_sctx; |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1975 } |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1976 last_lnum = lnum; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1977 last_wp = wp; |
29 | 1978 set_vim_var_string(VV_FOLDDASHES, NULL, -1); |
1979 | |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1980 if (!did_emsg && save_did_emsg) |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1981 did_emsg = save_did_emsg; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1982 |
29 | 1983 if (text != NULL) |
1984 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1985 // Replace unprintable characters, if there are any. But |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1986 // replace a TAB with a space. |
29 | 1987 for (p = text; *p != NUL; ++p) |
1988 { | |
33 | 1989 int len; |
1990 | |
474 | 1991 if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1) |
29 | 1992 { |
1993 if (!vim_isprintc((*mb_ptr2char)(p))) | |
1994 break; | |
1995 p += len - 1; | |
1996 } | |
1997 else | |
1998 if (*p == TAB) | |
1999 *p = ' '; | |
2000 else if (ptr2cells(p) > 1) | |
2001 break; | |
2002 } | |
2003 if (*p != NUL) | |
2004 { | |
2005 p = transstr(text); | |
2006 vim_free(text); | |
2007 text = p; | |
2008 } | |
2009 } | |
2010 } | |
2011 if (text == NULL) | |
2012 #endif | |
2013 { | |
9754
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2014 long count = (long)(lnume - lnum + 1); |
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2015 |
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2016 vim_snprintf((char *)buf, FOLD_TEXT_LEN, |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
2017 NGETTEXT("+--%3ld line folded ", |
9754
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2018 "+--%3ld lines folded ", count), |
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2019 count); |
29 | 2020 text = buf; |
2021 } | |
2022 return text; | |
2023 } | |
2024 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2025 // foldtext_cleanup() {{{2 |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
2026 #ifdef FEAT_EVAL |
7 | 2027 /* |
2028 * Remove 'foldmarker' and 'commentstring' from "str" (in-place). | |
2029 */ | |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
2030 static void |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2031 foldtext_cleanup(char_u *str) |
7 | 2032 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2033 char_u *cms_start; // first part or the whole comment |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2034 int cms_slen = 0; // length of cms_start |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2035 char_u *cms_end; // last part of the comment or NULL |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2036 int cms_elen = 0; // length of cms_end |
7 | 2037 char_u *s; |
45 | 2038 char_u *p; |
7 | 2039 int len; |
2040 int did1 = FALSE; | |
2041 int did2 = FALSE; | |
2042 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2043 // Ignore leading and trailing white space in 'commentstring'. |
7 | 2044 cms_start = skipwhite(curbuf->b_p_cms); |
835 | 2045 cms_slen = (int)STRLEN(cms_start); |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
2046 while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1])) |
7 | 2047 --cms_slen; |
2048 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2049 // locate "%s" in 'commentstring', use the part before and after it. |
7 | 2050 cms_end = (char_u *)strstr((char *)cms_start, "%s"); |
2051 if (cms_end != NULL) | |
2052 { | |
835 | 2053 cms_elen = cms_slen - (int)(cms_end - cms_start); |
2054 cms_slen = (int)(cms_end - cms_start); | |
7 | 2055 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2056 // exclude white space before "%s" |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
2057 while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1])) |
7 | 2058 --cms_slen; |
2059 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2060 // skip "%s" and white space after it |
7 | 2061 s = skipwhite(cms_end + 2); |
835 | 2062 cms_elen -= (int)(s - cms_end); |
7 | 2063 cms_end = s; |
2064 } | |
2065 parseMarker(curwin); | |
2066 | |
2067 for (s = str; *s != NUL; ) | |
2068 { | |
2069 len = 0; | |
2070 if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0) | |
45 | 2071 len = foldstartmarkerlen; |
2072 else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0) | |
2073 len = foldendmarkerlen; | |
2074 if (len > 0) | |
7 | 2075 { |
2076 if (VIM_ISDIGIT(s[len])) | |
2077 ++len; | |
45 | 2078 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2079 // May remove 'commentstring' start. Useful when it's a double |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2080 // quote and we already removed a double quote. |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
2081 for (p = s; p > str && VIM_ISWHITE(p[-1]); --p) |
45 | 2082 ; |
2083 if (p >= str + cms_slen | |
2084 && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0) | |
2085 { | |
835 | 2086 len += (int)(s - p) + cms_slen; |
45 | 2087 s = p - cms_slen; |
2088 } | |
7 | 2089 } |
2090 else if (cms_end != NULL) | |
2091 { | |
45 | 2092 if (!did1 && cms_slen > 0 && STRNCMP(s, cms_start, cms_slen) == 0) |
7 | 2093 { |
2094 len = cms_slen; | |
2095 did1 = TRUE; | |
2096 } | |
45 | 2097 else if (!did2 && cms_elen > 0 |
2098 && STRNCMP(s, cms_end, cms_elen) == 0) | |
7 | 2099 { |
2100 len = cms_elen; | |
2101 did2 = TRUE; | |
2102 } | |
2103 } | |
2104 if (len != 0) | |
2105 { | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
2106 while (VIM_ISWHITE(s[len])) |
7 | 2107 ++len; |
1624 | 2108 STRMOVE(s, s + len); |
7 | 2109 } |
2110 else | |
2111 { | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
2112 MB_PTR_ADV(s); |
7 | 2113 } |
2114 } | |
2115 } | |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
2116 #endif |
7 | 2117 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2118 // Folding by indent, expr, marker and syntax. {{{1 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2119 // Define "fline_T", passed to get fold level for a line. {{{2 |
7 | 2120 typedef struct |
2121 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2122 win_T *wp; // window |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2123 linenr_T lnum; // current line number |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2124 linenr_T off; // offset between lnum and real line number |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2125 linenr_T lnum_save; // line nr used by foldUpdateIEMSRecurse() |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2126 int lvl; // current level (-1 for undefined) |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2127 int lvl_next; // level used for next line |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2128 int start; // number of folds that are forced to start at |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2129 // this line. |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2130 int end; // level of fold that is forced to end below |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2131 // this line |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2132 int had_end; // level of fold that is forced to end above |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2133 // this line (copy of "end" of prev. line) |
7 | 2134 } fline_T; |
2135 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2136 // Flag is set when redrawing is needed. |
7 | 2137 static int fold_changed; |
2138 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2139 // Function declarations. {{{2 |
7807
1a5d34492798
commit https://github.com/vim/vim/commit/d99df423c559d85c17779b3685426c489554908c
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2140 static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, linenr_T startlnum, fline_T *flp, void (*getlevel)(fline_T *), linenr_T bot, int topflags); |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2141 static int foldInsert(garray_T *gap, int i); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2142 static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2143 static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2144 static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2145 static void foldlevelIndent(fline_T *flp); |
7 | 2146 #ifdef FEAT_DIFF |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2147 static void foldlevelDiff(fline_T *flp); |
7 | 2148 #endif |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2149 static void foldlevelExpr(fline_T *flp); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2150 static void foldlevelMarker(fline_T *flp); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2151 static void foldlevelSyntax(fline_T *flp); |
7 | 2152 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2153 // foldUpdateIEMS() {{{2 |
7 | 2154 /* |
2155 * Update the folding for window "wp", at least from lines "top" to "bot". | |
2156 * Return TRUE if any folds did change. | |
2157 */ | |
2158 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2159 foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot) |
7 | 2160 { |
2161 linenr_T start; | |
2162 linenr_T end; | |
2163 fline_T fline; | |
7807
1a5d34492798
commit https://github.com/vim/vim/commit/d99df423c559d85c17779b3685426c489554908c
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2164 void (*getlevel)(fline_T *); |
7 | 2165 int level; |
2166 fold_T *fp; | |
2167 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2168 // Avoid problems when being called recursively. |
7 | 2169 if (invalid_top != (linenr_T)0) |
2170 return; | |
2171 | |
2172 if (wp->w_foldinvalid) | |
2173 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2174 // Need to update all folds. |
7 | 2175 top = 1; |
2176 bot = wp->w_buffer->b_ml.ml_line_count; | |
2177 wp->w_foldinvalid = FALSE; | |
2178 | |
28929
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
2179 // Mark all folds as maybe-small. |
7 | 2180 setSmallMaybe(&wp->w_folds); |
2181 } | |
2182 | |
2183 #ifdef FEAT_DIFF | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2184 // add the context for "diff" folding |
7 | 2185 if (foldmethodIsDiff(wp)) |
2186 { | |
2187 if (top > diff_context) | |
2188 top -= diff_context; | |
2189 else | |
2190 top = 1; | |
2191 bot += diff_context; | |
2192 } | |
2193 #endif | |
2194 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2195 // When deleting lines at the end of the buffer "top" can be past the end |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2196 // of the buffer. |
7 | 2197 if (top > wp->w_buffer->b_ml.ml_line_count) |
2198 top = wp->w_buffer->b_ml.ml_line_count; | |
2199 | |
2200 fold_changed = FALSE; | |
2201 fline.wp = wp; | |
2202 fline.off = 0; | |
2203 fline.lvl = 0; | |
2204 fline.lvl_next = -1; | |
2205 fline.start = 0; | |
2206 fline.end = MAX_LEVEL + 1; | |
2207 fline.had_end = MAX_LEVEL + 1; | |
2208 | |
2209 invalid_top = top; | |
2210 invalid_bot = bot; | |
2211 | |
2212 if (foldmethodIsMarker(wp)) | |
2213 { | |
2214 getlevel = foldlevelMarker; | |
2215 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2216 // Init marker variables to speed up foldlevelMarker(). |
7 | 2217 parseMarker(wp); |
2218 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2219 // Need to get the level of the line above top, it is used if there is |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2220 // no marker at the top. |
7 | 2221 if (top > 1) |
2222 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2223 // Get the fold level at top - 1. |
7 | 2224 level = foldLevelWin(wp, top - 1); |
2225 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2226 // The fold may end just above the top, check for that. |
7 | 2227 fline.lnum = top - 1; |
2228 fline.lvl = level; | |
2229 getlevel(&fline); | |
2230 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2231 // If a fold started here, we already had the level, if it stops |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2232 // here, we need to use lvl_next. Could also start and end a fold |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2233 // in the same line. |
7 | 2234 if (fline.lvl > level) |
2235 fline.lvl = level - (fline.lvl - fline.lvl_next); | |
2236 else | |
2237 fline.lvl = fline.lvl_next; | |
2238 } | |
2239 fline.lnum = top; | |
2240 getlevel(&fline); | |
2241 } | |
2242 else | |
2243 { | |
2244 fline.lnum = top; | |
2245 if (foldmethodIsExpr(wp)) | |
2246 { | |
2247 getlevel = foldlevelExpr; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2248 // start one line back, because a "<1" may indicate the end of a |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2249 // fold in the topline |
7 | 2250 if (top > 1) |
2251 --fline.lnum; | |
2252 } | |
2253 else if (foldmethodIsSyntax(wp)) | |
2254 getlevel = foldlevelSyntax; | |
2255 #ifdef FEAT_DIFF | |
2256 else if (foldmethodIsDiff(wp)) | |
2257 getlevel = foldlevelDiff; | |
2258 #endif | |
2259 else | |
28823
980eaa09f940
patch 8.2.4935: with 'foldmethod' "indent" some lines not included in fold
Bram Moolenaar <Bram@vim.org>
parents:
28773
diff
changeset
|
2260 { |
7 | 2261 getlevel = foldlevelIndent; |
28823
980eaa09f940
patch 8.2.4935: with 'foldmethod' "indent" some lines not included in fold
Bram Moolenaar <Bram@vim.org>
parents:
28773
diff
changeset
|
2262 // Start one line back, because if the line above "top" has an |
980eaa09f940
patch 8.2.4935: with 'foldmethod' "indent" some lines not included in fold
Bram Moolenaar <Bram@vim.org>
parents:
28773
diff
changeset
|
2263 // undefined fold level, folding it relies on the line under it, |
980eaa09f940
patch 8.2.4935: with 'foldmethod' "indent" some lines not included in fold
Bram Moolenaar <Bram@vim.org>
parents:
28773
diff
changeset
|
2264 // which is "top". |
980eaa09f940
patch 8.2.4935: with 'foldmethod' "indent" some lines not included in fold
Bram Moolenaar <Bram@vim.org>
parents:
28773
diff
changeset
|
2265 if (top > 1) |
980eaa09f940
patch 8.2.4935: with 'foldmethod' "indent" some lines not included in fold
Bram Moolenaar <Bram@vim.org>
parents:
28773
diff
changeset
|
2266 --fline.lnum; |
980eaa09f940
patch 8.2.4935: with 'foldmethod' "indent" some lines not included in fold
Bram Moolenaar <Bram@vim.org>
parents:
28773
diff
changeset
|
2267 } |
7 | 2268 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2269 // Backup to a line for which the fold level is defined. Since it's |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2270 // always defined for line one, we will stop there. |
7 | 2271 fline.lvl = -1; |
2272 for ( ; !got_int; --fline.lnum) | |
2273 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2274 // Reset lvl_next each time, because it will be set to a value for |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2275 // the next line, but we search backwards here. |
7 | 2276 fline.lvl_next = -1; |
2277 getlevel(&fline); | |
2278 if (fline.lvl >= 0) | |
2279 break; | |
2280 } | |
2281 } | |
2282 | |
1977 | 2283 /* |
2284 * If folding is defined by the syntax, it is possible that a change in | |
2285 * one line will cause all sub-folds of the current fold to change (e.g., | |
2286 * closing a C-style comment can cause folds in the subsequent lines to | |
2287 * appear). To take that into account we should adjust the value of "bot" | |
2288 * to point to the end of the current fold: | |
2289 */ | |
2290 if (foldlevelSyntax == getlevel) | |
2291 { | |
2292 garray_T *gap = &wp->w_folds; | |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2293 fold_T *fpn = NULL; |
1977 | 2294 int current_fdl = 0; |
2295 linenr_T fold_start_lnum = 0; | |
2296 linenr_T lnum_rel = fline.lnum; | |
2297 | |
2298 while (current_fdl < fline.lvl) | |
2299 { | |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2300 if (!foldFind(gap, lnum_rel, &fpn)) |
1977 | 2301 break; |
2302 ++current_fdl; | |
2303 | |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2304 fold_start_lnum += fpn->fd_top; |
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2305 gap = &fpn->fd_nested; |
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2306 lnum_rel -= fpn->fd_top; |
1977 | 2307 } |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2308 if (fpn != NULL && current_fdl == fline.lvl) |
1977 | 2309 { |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2310 linenr_T fold_end_lnum = fold_start_lnum + fpn->fd_len; |
1977 | 2311 |
2312 if (fold_end_lnum > bot) | |
2313 bot = fold_end_lnum; | |
2314 } | |
2315 } | |
2316 | |
7 | 2317 start = fline.lnum; |
2318 end = bot; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2319 // Do at least one line. |
7 | 2320 if (start > end && end < wp->w_buffer->b_ml.ml_line_count) |
2321 end = start; | |
2322 while (!got_int) | |
2323 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2324 // Always stop at the end of the file ("end" can be past the end of |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2325 // the file). |
7 | 2326 if (fline.lnum > wp->w_buffer->b_ml.ml_line_count) |
2327 break; | |
2328 if (fline.lnum > end) | |
2329 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2330 // For "marker", "expr" and "syntax" methods: If a change caused |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2331 // a fold to be removed, we need to continue at least until where |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2332 // it ended. |
7 | 2333 if (getlevel != foldlevelMarker |
2334 && getlevel != foldlevelSyntax | |
2335 && getlevel != foldlevelExpr) | |
2336 break; | |
2337 if ((start <= end | |
2338 && foldFind(&wp->w_folds, end, &fp) | |
2339 && fp->fd_top + fp->fd_len - 1 > end) | |
2340 || (fline.lvl == 0 | |
2341 && foldFind(&wp->w_folds, fline.lnum, &fp) | |
2342 && fp->fd_top < fline.lnum)) | |
2343 end = fp->fd_top + fp->fd_len - 1; | |
2344 else if (getlevel == foldlevelSyntax | |
2345 && foldLevelWin(wp, fline.lnum) != fline.lvl) | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2346 // For "syntax" method: Compare the foldlevel that the syntax |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2347 // tells us to the foldlevel from the existing folds. If they |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2348 // don't match continue updating folds. |
7 | 2349 end = fline.lnum; |
2350 else | |
2351 break; | |
2352 } | |
2353 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2354 // A level 1 fold starts at a line with foldlevel > 0. |
7 | 2355 if (fline.lvl > 0) |
2356 { | |
2357 invalid_top = fline.lnum; | |
2358 invalid_bot = end; | |
2359 end = foldUpdateIEMSRecurse(&wp->w_folds, | |
2360 1, start, &fline, getlevel, end, FD_LEVEL); | |
2361 start = fline.lnum; | |
2362 } | |
2363 else | |
2364 { | |
2365 if (fline.lnum == wp->w_buffer->b_ml.ml_line_count) | |
2366 break; | |
2367 ++fline.lnum; | |
2368 fline.lvl = fline.lvl_next; | |
2369 getlevel(&fline); | |
2370 } | |
2371 } | |
2372 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2373 // There can't be any folds from start until end now. |
7 | 2374 foldRemove(&wp->w_folds, start, end); |
2375 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2376 // If some fold changed, need to redraw and position cursor. |
7 | 2377 if (fold_changed && wp->w_p_fen) |
1554 | 2378 changed_window_setting_win(wp); |
7 | 2379 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2380 // If we updated folds past "bot", need to redraw more lines. Don't do |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2381 // this in other situations, the changed lines will be redrawn anyway and |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2382 // this method can cause the whole window to be updated. |
7 | 2383 if (end != bot) |
2384 { | |
2385 if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) | |
2386 wp->w_redraw_top = top; | |
2387 if (wp->w_redraw_bot < end) | |
2388 wp->w_redraw_bot = end; | |
2389 } | |
2390 | |
2391 invalid_top = (linenr_T)0; | |
2392 } | |
2393 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2394 // foldUpdateIEMSRecurse() {{{2 |
7 | 2395 /* |
2396 * Update a fold that starts at "flp->lnum". At this line there is always a | |
2397 * valid foldlevel, and its level >= "level". | |
2398 * "flp" is valid for "flp->lnum" when called and it's valid when returning. | |
2399 * "flp->lnum" is set to the lnum just below the fold, if it ends before | |
2400 * "bot", it's "bot" plus one if the fold continues and it's bigger when using | |
2401 * the marker method and a text change made following folds to change. | |
2402 * When returning, "flp->lnum_save" is the line number that was used to get | |
2403 * the level when the level at "flp->lnum" is invalid. | |
2404 * Remove any folds from "startlnum" up to here at this level. | |
2405 * Recursively update nested folds. | |
2406 * Below line "bot" there are no changes in the text. | |
2407 * "flp->lnum", "flp->lnum_save" and "bot" are relative to the start of the | |
2408 * outer fold. | |
2409 * "flp->off" is the offset to the real line number in the buffer. | |
2410 * | |
2411 * All this would be a lot simpler if all folds in the range would be deleted | |
1698 | 2412 * and then created again. But we would lose all information about the |
7 | 2413 * folds, even when making changes that don't affect the folding (e.g. "vj~"). |
2414 * | |
2415 * Returns bot, which may have been increased for lines that also need to be | |
2416 * updated as a result of a detected change in the fold. | |
2417 */ | |
2418 static linenr_T | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2419 foldUpdateIEMSRecurse( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2420 garray_T *gap, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2421 int level, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2422 linenr_T startlnum, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2423 fline_T *flp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2424 void (*getlevel)(fline_T *), |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2425 linenr_T bot, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2426 int topflags) // flags used by containing fold |
7 | 2427 { |
2428 linenr_T ll; | |
2429 fold_T *fp = NULL; | |
2430 fold_T *fp2; | |
2431 int lvl = level; | |
2432 linenr_T startlnum2 = startlnum; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2433 linenr_T firstlnum = flp->lnum; // first lnum we got |
7 | 2434 int i; |
2435 int finish = FALSE; | |
2436 linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off; | |
2437 int concat; | |
2438 | |
2439 /* | |
2440 * If using the marker method, the start line is not the start of a fold | |
2441 * at the level we're dealing with and the level is non-zero, we must use | |
2442 * the previous fold. But ignore a fold that starts at or below | |
2443 * startlnum, it must be deleted. | |
2444 */ | |
2445 if (getlevel == foldlevelMarker && flp->start <= flp->lvl - level | |
2446 && flp->lvl > 0) | |
2447 { | |
7009 | 2448 (void)foldFind(gap, startlnum - 1, &fp); |
22306
86696c617f70
patch 8.2.1702: crash when using undo after deleting folded lines
Bram Moolenaar <Bram@vim.org>
parents:
22023
diff
changeset
|
2449 if (fp != NULL && (fp >= ((fold_T *)gap->ga_data) + gap->ga_len |
86696c617f70
patch 8.2.1702: crash when using undo after deleting folded lines
Bram Moolenaar <Bram@vim.org>
parents:
22023
diff
changeset
|
2450 || fp->fd_top >= startlnum)) |
7 | 2451 fp = NULL; |
2452 } | |
2453 | |
2454 /* | |
2455 * Loop over all lines in this fold, or until "bot" is hit. | |
2456 * Handle nested folds inside of this fold. | |
2457 * "flp->lnum" is the current line. When finding the end of the fold, it | |
2458 * is just below the end of the fold. | |
2459 * "*flp" contains the level of the line "flp->lnum" or a following one if | |
2460 * there are lines with an invalid fold level. "flp->lnum_save" is the | |
2461 * line number that was used to get the fold level (below "flp->lnum" when | |
2462 * it has an invalid fold level). When called the fold level is always | |
2463 * valid, thus "flp->lnum_save" is equal to "flp->lnum". | |
2464 */ | |
2465 flp->lnum_save = flp->lnum; | |
2466 while (!got_int) | |
2467 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2468 // Updating folds can be slow, check for CTRL-C. |
7 | 2469 line_breakcheck(); |
2470 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2471 // Set "lvl" to the level of line "flp->lnum". When flp->start is set |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2472 // and after the first line of the fold, set the level to zero to |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2473 // force the fold to end. Do the same when had_end is set: Previous |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2474 // line was marked as end of a fold. |
7 | 2475 lvl = flp->lvl; |
2476 if (lvl > MAX_LEVEL) | |
2477 lvl = MAX_LEVEL; | |
2478 if (flp->lnum > firstlnum | |
2479 && (level > lvl - flp->start || level >= flp->had_end)) | |
2480 lvl = 0; | |
2481 | |
2482 if (flp->lnum > bot && !finish && fp != NULL) | |
2483 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2484 // For "marker" and "syntax" methods: |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2485 // - If a change caused a nested fold to be removed, we need to |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2486 // delete it and continue at least until where it ended. |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2487 // - If a change caused a nested fold to be created, or this fold |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2488 // to continue below its original end, need to finish this fold. |
7 | 2489 if (getlevel != foldlevelMarker |
2490 && getlevel != foldlevelExpr | |
2491 && getlevel != foldlevelSyntax) | |
2492 break; | |
2493 i = 0; | |
2494 fp2 = fp; | |
2495 if (lvl >= level) | |
2496 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2497 // Compute how deep the folds currently are, if it's deeper |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2498 // than "lvl" then some must be deleted, need to update |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2499 // at least one nested fold. |
7 | 2500 ll = flp->lnum - fp->fd_top; |
2501 while (foldFind(&fp2->fd_nested, ll, &fp2)) | |
2502 { | |
2503 ++i; | |
2504 ll -= fp2->fd_top; | |
2505 } | |
2506 } | |
2507 if (lvl < level + i) | |
2508 { | |
7009 | 2509 (void)foldFind(&fp->fd_nested, flp->lnum - fp->fd_top, &fp2); |
7 | 2510 if (fp2 != NULL) |
2511 bot = fp2->fd_top + fp2->fd_len - 1 + fp->fd_top; | |
2512 } | |
2513 else if (fp->fd_top + fp->fd_len <= flp->lnum && lvl >= level) | |
2514 finish = TRUE; | |
2515 else | |
2516 break; | |
2517 } | |
2518 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2519 // At the start of the first nested fold and at the end of the current |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2520 // fold: check if existing folds at this level, before the current |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2521 // one, need to be deleted or truncated. |
7 | 2522 if (fp == NULL |
2523 && (lvl != level | |
2524 || flp->lnum_save >= bot | |
2525 || flp->start != 0 | |
2526 || flp->had_end <= MAX_LEVEL | |
2527 || flp->lnum == linecount)) | |
2528 { | |
2529 /* | |
2530 * Remove or update folds that have lines between startlnum and | |
2531 * firstlnum. | |
2532 */ | |
2533 while (!got_int) | |
2534 { | |
26771
fc859aea8cec
patch 8.2.3914: various spelling mistakes in comments
Bram Moolenaar <Bram@vim.org>
parents:
26262
diff
changeset
|
2535 // set concat to 1 if it's allowed to concatenate this fold |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2536 // with a previous one that touches it. |
7 | 2537 if (flp->start != 0 || flp->had_end <= MAX_LEVEL) |
2538 concat = 0; | |
2539 else | |
2540 concat = 1; | |
2541 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2542 // Find an existing fold to re-use. Preferably one that |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2543 // includes startlnum, otherwise one that ends just before |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2544 // startlnum or starts after it. |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2545 if (gap->ga_len > 0 && (foldFind(gap, startlnum, &fp) |
7 | 2546 || (fp < ((fold_T *)gap->ga_data) + gap->ga_len |
2547 && fp->fd_top <= firstlnum) | |
2548 || foldFind(gap, firstlnum - concat, &fp) | |
2549 || (fp < ((fold_T *)gap->ga_data) + gap->ga_len | |
2550 && ((lvl < level && fp->fd_top < flp->lnum) | |
2551 || (lvl >= level | |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2552 && fp->fd_top <= flp->lnum_save))))) |
7 | 2553 { |
2554 if (fp->fd_top + fp->fd_len + concat > firstlnum) | |
2555 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2556 // Use existing fold for the new fold. If it starts |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2557 // before where we started looking, extend it. If it |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2558 // starts at another line, update nested folds to keep |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2559 // their position, compensating for the new fd_top. |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2560 if (fp->fd_top == firstlnum) |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2561 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2562 // have found a fold beginning where we want |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2563 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2564 else if (fp->fd_top >= startlnum) |
7 | 2565 { |
2566 if (fp->fd_top > firstlnum) | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2567 // like lines are inserted |
7 | 2568 foldMarkAdjustRecurse(&fp->fd_nested, |
2569 (linenr_T)0, (linenr_T)MAXLNUM, | |
2570 (long)(fp->fd_top - firstlnum), 0L); | |
2571 else | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2572 // like lines are deleted |
7 | 2573 foldMarkAdjustRecurse(&fp->fd_nested, |
2574 (linenr_T)0, | |
2575 (long)(firstlnum - fp->fd_top - 1), | |
2576 (linenr_T)MAXLNUM, | |
2577 (long)(fp->fd_top - firstlnum)); | |
2578 fp->fd_len += fp->fd_top - firstlnum; | |
2579 fp->fd_top = firstlnum; | |
28974
65946c949965
patch 8.2.5009: fold may not be closeable after appending
Bram Moolenaar <Bram@vim.org>
parents:
28929
diff
changeset
|
2580 fp->fd_small = MAYBE; |
7 | 2581 fold_changed = TRUE; |
2582 } | |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2583 else if ((flp->start != 0 && lvl == level) |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2584 || firstlnum != startlnum) |
7 | 2585 { |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2586 linenr_T breakstart; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2587 linenr_T breakend; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2588 |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2589 /* |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2590 * Before there was a fold spanning from above |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2591 * startlnum to below firstlnum. This fold is valid |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2592 * above startlnum (because we are not updating |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2593 * that range), but there should now be a break in |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2594 * it. |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2595 * If the break is because we are now forced to |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2596 * start a new fold at the level "level" at line |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2597 * fline->lnum, then we need to split the fold at |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2598 * fline->lnum. |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2599 * If the break is because the range |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2600 * [startlnum, firstlnum) is now at a lower indent |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2601 * than "level", we need to split the fold in this |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2602 * range. |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2603 * Any splits have to be done recursively. |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2604 */ |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2605 if (firstlnum != startlnum) |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2606 { |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2607 breakstart = startlnum; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2608 breakend = firstlnum; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2609 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2610 else |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2611 { |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2612 breakstart = flp->lnum; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2613 breakend = flp->lnum; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2614 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2615 foldRemove(&fp->fd_nested, breakstart - fp->fd_top, |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2616 breakend - fp->fd_top); |
7 | 2617 i = (int)(fp - (fold_T *)gap->ga_data); |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2618 foldSplit(gap, i, breakstart, breakend - 1); |
7 | 2619 fp = (fold_T *)gap->ga_data + i + 1; |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2620 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2621 // If using the "marker" or "syntax" method, we |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2622 // need to continue until the end of the fold is |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2623 // found. |
7 | 2624 if (getlevel == foldlevelMarker |
2625 || getlevel == foldlevelExpr | |
2626 || getlevel == foldlevelSyntax) | |
2627 finish = TRUE; | |
2628 } | |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2629 |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2630 if (fp->fd_top == startlnum && concat) |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2631 { |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2632 i = (int)(fp - (fold_T *)gap->ga_data); |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2633 if (i != 0) |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2634 { |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2635 fp2 = fp - 1; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2636 if (fp2->fd_top + fp2->fd_len == fp->fd_top) |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2637 { |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2638 foldMerge(fp2, gap, fp); |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2639 fp = fp2; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2640 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2641 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2642 } |
7 | 2643 break; |
2644 } | |
2645 if (fp->fd_top >= startlnum) | |
2646 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2647 // A fold that starts at or after startlnum and stops |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2648 // before the new fold must be deleted. Continue |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2649 // looking for the next one. |
7 | 2650 deleteFoldEntry(gap, |
2651 (int)(fp - (fold_T *)gap->ga_data), TRUE); | |
2652 } | |
2653 else | |
2654 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2655 // A fold has some lines above startlnum, truncate it |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2656 // to stop just above startlnum. |
7 | 2657 fp->fd_len = startlnum - fp->fd_top; |
2658 foldMarkAdjustRecurse(&fp->fd_nested, | |
27426
41e0dcf38521
patch 8.2.4241: some type casts are redundant
Bram Moolenaar <Bram@vim.org>
parents:
27301
diff
changeset
|
2659 fp->fd_len, (linenr_T)MAXLNUM, |
7 | 2660 (linenr_T)MAXLNUM, 0L); |
2661 fold_changed = TRUE; | |
2662 } | |
2663 } | |
2664 else | |
2665 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2666 // Insert new fold. Careful: ga_data may be NULL and it |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2667 // may change! |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2668 if (gap->ga_len == 0) |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2669 i = 0; |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2670 else |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2671 i = (int)(fp - (fold_T *)gap->ga_data); |
7 | 2672 if (foldInsert(gap, i) != OK) |
2673 return bot; | |
2674 fp = (fold_T *)gap->ga_data + i; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2675 // The new fold continues until bot, unless we find the |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2676 // end earlier. |
7 | 2677 fp->fd_top = firstlnum; |
2678 fp->fd_len = bot - firstlnum + 1; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2679 // When the containing fold is open, the new fold is open. |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2680 // The new fold is closed if the fold above it is closed. |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2681 // The first fold depends on the containing fold. |
7 | 2682 if (topflags == FD_OPEN) |
2683 { | |
2684 flp->wp->w_fold_manual = TRUE; | |
2685 fp->fd_flags = FD_OPEN; | |
2686 } | |
2687 else if (i <= 0) | |
2688 { | |
2689 fp->fd_flags = topflags; | |
2690 if (topflags != FD_LEVEL) | |
2691 flp->wp->w_fold_manual = TRUE; | |
2692 } | |
2693 else | |
2694 fp->fd_flags = (fp - 1)->fd_flags; | |
2695 fp->fd_small = MAYBE; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2696 // If using the "marker", "expr" or "syntax" method, we |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2697 // need to continue until the end of the fold is found. |
7 | 2698 if (getlevel == foldlevelMarker |
2699 || getlevel == foldlevelExpr | |
2700 || getlevel == foldlevelSyntax) | |
2701 finish = TRUE; | |
2702 fold_changed = TRUE; | |
2703 break; | |
2704 } | |
2705 } | |
2706 } | |
2707 | |
2708 if (lvl < level || flp->lnum > linecount) | |
2709 { | |
2710 /* | |
2711 * Found a line with a lower foldlevel, this fold ends just above | |
2712 * "flp->lnum". | |
2713 */ | |
2714 break; | |
2715 } | |
2716 | |
2717 /* | |
2718 * The fold includes the line "flp->lnum" and "flp->lnum_save". | |
840 | 2719 * Check "fp" for safety. |
7 | 2720 */ |
840 | 2721 if (lvl > level && fp != NULL) |
7 | 2722 { |
2723 /* | |
2724 * There is a nested fold, handle it recursively. | |
2725 */ | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2726 // At least do one line (can happen when finish is TRUE). |
7 | 2727 if (bot < flp->lnum) |
2728 bot = flp->lnum; | |
2729 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2730 // Line numbers in the nested fold are relative to the start of |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2731 // this fold. |
7 | 2732 flp->lnum = flp->lnum_save - fp->fd_top; |
2733 flp->off += fp->fd_top; | |
2734 i = (int)(fp - (fold_T *)gap->ga_data); | |
2735 bot = foldUpdateIEMSRecurse(&fp->fd_nested, level + 1, | |
2736 startlnum2 - fp->fd_top, flp, getlevel, | |
2737 bot - fp->fd_top, fp->fd_flags); | |
2738 fp = (fold_T *)gap->ga_data + i; | |
2739 flp->lnum += fp->fd_top; | |
2740 flp->lnum_save += fp->fd_top; | |
2741 flp->off -= fp->fd_top; | |
2742 bot += fp->fd_top; | |
2743 startlnum2 = flp->lnum; | |
2744 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2745 // This fold may end at the same line, don't incr. flp->lnum. |
7 | 2746 } |
2747 else | |
2748 { | |
2749 /* | |
2750 * Get the level of the next line, then continue the loop to check | |
2751 * if it ends there. | |
2752 * Skip over undefined lines, to find the foldlevel after it. | |
2753 * For the last line in the file the foldlevel is always valid. | |
2754 */ | |
2755 flp->lnum = flp->lnum_save; | |
2756 ll = flp->lnum + 1; | |
2757 while (!got_int) | |
2758 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2759 // Make the previous level available to foldlevel(). |
7 | 2760 prev_lnum = flp->lnum; |
2761 prev_lnum_lvl = flp->lvl; | |
2762 | |
2763 if (++flp->lnum > linecount) | |
2764 break; | |
2765 flp->lvl = flp->lvl_next; | |
2766 getlevel(flp); | |
2767 if (flp->lvl >= 0 || flp->had_end <= MAX_LEVEL) | |
2768 break; | |
2769 } | |
2770 prev_lnum = 0; | |
2771 if (flp->lnum > linecount) | |
2772 break; | |
2773 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2774 // leave flp->lnum_save to lnum of the line that was used to get |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2775 // the level, flp->lnum to the lnum of the next line. |
7 | 2776 flp->lnum_save = flp->lnum; |
2777 flp->lnum = ll; | |
2778 } | |
2779 } | |
2780 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2781 if (fp == NULL) // only happens when got_int is set |
7 | 2782 return bot; |
2783 | |
2784 /* | |
2785 * Get here when: | |
2786 * lvl < level: the folds ends just above "flp->lnum" | |
2787 * lvl >= level: fold continues below "bot" | |
2788 */ | |
2789 | |
17787
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2790 // Current fold at least extends until lnum. |
7 | 2791 if (fp->fd_len < flp->lnum - fp->fd_top) |
2792 { | |
2793 fp->fd_len = flp->lnum - fp->fd_top; | |
1513 | 2794 fp->fd_small = MAYBE; |
7 | 2795 fold_changed = TRUE; |
2796 } | |
17787
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2797 else if (fp->fd_top + fp->fd_len > linecount) |
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2798 // running into the end of the buffer (deleted last line) |
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2799 fp->fd_len = linecount - fp->fd_top + 1; |
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2800 |
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2801 // Delete contained folds from the end of the last one found until where |
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2802 // we stopped looking. |
7 | 2803 foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top, |
2804 flp->lnum - 1 - fp->fd_top); | |
2805 | |
2806 if (lvl < level) | |
2807 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2808 // End of fold found, update the length when it got shorter. |
7 | 2809 if (fp->fd_len != flp->lnum - fp->fd_top) |
2810 { | |
11234
8c153d400bf4
patch 8.0.0503: endless loop in updating folds with 32 bit ints
Christian Brabandt <cb@256bit.org>
parents:
11165
diff
changeset
|
2811 if (fp->fd_top + fp->fd_len - 1 > bot) |
7 | 2812 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2813 // fold continued below bot |
7 | 2814 if (getlevel == foldlevelMarker |
2815 || getlevel == foldlevelExpr | |
2816 || getlevel == foldlevelSyntax) | |
2817 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2818 // marker method: truncate the fold and make sure the |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2819 // previously included lines are processed again |
7 | 2820 bot = fp->fd_top + fp->fd_len - 1; |
2821 fp->fd_len = flp->lnum - fp->fd_top; | |
2822 } | |
2823 else | |
2824 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2825 // indent or expr method: split fold to create a new one |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2826 // below bot |
7 | 2827 i = (int)(fp - (fold_T *)gap->ga_data); |
2828 foldSplit(gap, i, flp->lnum, bot); | |
2829 fp = (fold_T *)gap->ga_data + i; | |
2830 } | |
2831 } | |
2832 else | |
2833 fp->fd_len = flp->lnum - fp->fd_top; | |
2834 fold_changed = TRUE; | |
2835 } | |
2836 } | |
2837 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2838 // delete following folds that end before the current line |
7 | 2839 for (;;) |
2840 { | |
2841 fp2 = fp + 1; | |
2842 if (fp2 >= (fold_T *)gap->ga_data + gap->ga_len | |
2843 || fp2->fd_top > flp->lnum) | |
2844 break; | |
2845 if (fp2->fd_top + fp2->fd_len > flp->lnum) | |
2846 { | |
2847 if (fp2->fd_top < flp->lnum) | |
2848 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2849 // Make fold that includes lnum start at lnum. |
7 | 2850 foldMarkAdjustRecurse(&fp2->fd_nested, |
2851 (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1), | |
2852 (linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum)); | |
2853 fp2->fd_len -= flp->lnum - fp2->fd_top; | |
2854 fp2->fd_top = flp->lnum; | |
2855 fold_changed = TRUE; | |
2856 } | |
2857 | |
2858 if (lvl >= level) | |
2859 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2860 // merge new fold with existing fold that follows |
7 | 2861 foldMerge(fp, gap, fp2); |
2862 } | |
2863 break; | |
2864 } | |
2865 fold_changed = TRUE; | |
2866 deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE); | |
2867 } | |
2868 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2869 // Need to redraw the lines we inspected, which might be further down than |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2870 // was asked for. |
7 | 2871 if (bot < flp->lnum - 1) |
2872 bot = flp->lnum - 1; | |
2873 | |
2874 return bot; | |
2875 } | |
2876 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2877 // foldInsert() {{{2 |
7 | 2878 /* |
2879 * Insert a new fold in "gap" at position "i". | |
2880 * Returns OK for success, FAIL for failure. | |
2881 */ | |
2882 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2883 foldInsert(garray_T *gap, int i) |
7 | 2884 { |
2885 fold_T *fp; | |
2886 | |
31837
e16361210675
patch 9.0.1251: checking returned value of ga_grow() is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
31667
diff
changeset
|
2887 if (ga_grow(gap, 1) == FAIL) |
7 | 2888 return FAIL; |
2889 fp = (fold_T *)gap->ga_data + i; | |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2890 if (gap->ga_len > 0 && i < gap->ga_len) |
7 | 2891 mch_memmove(fp + 1, fp, sizeof(fold_T) * (gap->ga_len - i)); |
2892 ++gap->ga_len; | |
27028
c9474ae175f4
patch 8.2.4043: using int for second argument of ga_init2()
Bram Moolenaar <Bram@vim.org>
parents:
26915
diff
changeset
|
2893 ga_init2(&fp->fd_nested, sizeof(fold_T), 10); |
7 | 2894 return OK; |
2895 } | |
2896 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2897 // foldSplit() {{{2 |
7 | 2898 /* |
2899 * Split the "i"th fold in "gap", which starts before "top" and ends below | |
2900 * "bot" in two pieces, one ending above "top" and the other starting below | |
2901 * "bot". | |
2902 * The caller must first have taken care of any nested folds from "top" to | |
2903 * "bot"! | |
2904 */ | |
2905 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2906 foldSplit( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2907 garray_T *gap, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2908 int i, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2909 linenr_T top, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2910 linenr_T bot) |
7 | 2911 { |
2912 fold_T *fp; | |
2913 fold_T *fp2; | |
2914 garray_T *gap1; | |
2915 garray_T *gap2; | |
2916 int idx; | |
2917 int len; | |
2918 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2919 // The fold continues below bot, need to split it. |
7 | 2920 if (foldInsert(gap, i + 1) == FAIL) |
2921 return; | |
2922 fp = (fold_T *)gap->ga_data + i; | |
2923 fp[1].fd_top = bot + 1; | |
2924 fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top); | |
2925 fp[1].fd_flags = fp->fd_flags; | |
1985 | 2926 fp[1].fd_small = MAYBE; |
2927 fp->fd_small = MAYBE; | |
7 | 2928 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2929 // Move nested folds below bot to new fold. There can't be |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2930 // any between top and bot, they have been removed by the caller. |
7 | 2931 gap1 = &fp->fd_nested; |
2932 gap2 = &fp[1].fd_nested; | |
28578
8cba27db759a
patch 8.2.4813: pasting text while indent folding may mess up folds
Bram Moolenaar <Bram@vim.org>
parents:
27752
diff
changeset
|
2933 (void)foldFind(gap1, bot + 1 - fp->fd_top, &fp2); |
8cba27db759a
patch 8.2.4813: pasting text while indent folding may mess up folds
Bram Moolenaar <Bram@vim.org>
parents:
27752
diff
changeset
|
2934 if (fp2 != NULL) |
7 | 2935 { |
22021
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2936 len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2); |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2937 if (len > 0 && ga_grow(gap2, len) == OK) |
7 | 2938 { |
22021
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2939 for (idx = 0; idx < len; ++idx) |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2940 { |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2941 ((fold_T *)gap2->ga_data)[idx] = fp2[idx]; |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2942 ((fold_T *)gap2->ga_data)[idx].fd_top |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2943 -= fp[1].fd_top - fp->fd_top; |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2944 } |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2945 gap2->ga_len = len; |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2946 gap1->ga_len -= len; |
7 | 2947 } |
2948 } | |
2949 fp->fd_len = top - fp->fd_top; | |
2950 fold_changed = TRUE; | |
2951 } | |
2952 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2953 // foldRemove() {{{2 |
7 | 2954 /* |
2955 * Remove folds within the range "top" to and including "bot". | |
2956 * Check for these situations: | |
2957 * 1 2 3 | |
2958 * 1 2 3 | |
2959 * top 2 3 4 5 | |
2960 * 2 3 4 5 | |
2961 * bot 2 3 4 5 | |
2962 * 3 5 6 | |
2963 * 3 5 6 | |
2964 * | |
2965 * 1: not changed | |
1224 | 2966 * 2: truncate to stop above "top" |
7 | 2967 * 3: split in two parts, one stops above "top", other starts below "bot". |
2968 * 4: deleted | |
2969 * 5: made to start below "bot". | |
2970 * 6: not changed | |
2971 */ | |
2972 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2973 foldRemove(garray_T *gap, linenr_T top, linenr_T bot) |
7 | 2974 { |
2975 fold_T *fp = NULL; | |
2976 | |
2977 if (bot < top) | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2978 return; // nothing to do |
7 | 2979 |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2980 while (gap->ga_len > 0) |
7 | 2981 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2982 // Find fold that includes top or a following one. |
7 | 2983 if (foldFind(gap, top, &fp) && fp->fd_top < top) |
2984 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2985 // 2: or 3: need to delete nested folds |
7 | 2986 foldRemove(&fp->fd_nested, top - fp->fd_top, bot - fp->fd_top); |
11396
e9924d19ee37
patch 8.0.0583: fold test hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11392
diff
changeset
|
2987 if (fp->fd_top + fp->fd_len - 1 > bot) |
7 | 2988 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2989 // 3: need to split it. |
7 | 2990 foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot); |
2991 } | |
2992 else | |
2993 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2994 // 2: truncate fold at "top". |
7 | 2995 fp->fd_len = top - fp->fd_top; |
2996 } | |
2997 fold_changed = TRUE; | |
2998 continue; | |
2999 } | |
3000 if (fp >= (fold_T *)(gap->ga_data) + gap->ga_len | |
3001 || fp->fd_top > bot) | |
3002 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3003 // 6: Found a fold below bot, can stop looking. |
7 | 3004 break; |
3005 } | |
3006 if (fp->fd_top >= top) | |
3007 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3008 // Found an entry below top. |
7 | 3009 fold_changed = TRUE; |
36 | 3010 if (fp->fd_top + fp->fd_len - 1 > bot) |
7 | 3011 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3012 // 5: Make fold that includes bot start below bot. |
7 | 3013 foldMarkAdjustRecurse(&fp->fd_nested, |
3014 (linenr_T)0, (long)(bot - fp->fd_top), | |
3015 (linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1)); | |
3016 fp->fd_len -= bot - fp->fd_top + 1; | |
3017 fp->fd_top = bot + 1; | |
3018 break; | |
3019 } | |
3020 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3021 // 4: Delete completely contained fold. |
7 | 3022 deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), TRUE); |
3023 } | |
3024 } | |
3025 } | |
3026 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3027 // foldReverseOrder() {{{2 |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3028 static void |
11396
e9924d19ee37
patch 8.0.0583: fold test hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11392
diff
changeset
|
3029 foldReverseOrder(garray_T *gap, linenr_T start_arg, linenr_T end_arg) |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3030 { |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3031 fold_T *left, *right; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3032 fold_T tmp; |
11396
e9924d19ee37
patch 8.0.0583: fold test hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11392
diff
changeset
|
3033 linenr_T start = start_arg; |
e9924d19ee37
patch 8.0.0583: fold test hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11392
diff
changeset
|
3034 linenr_T end = end_arg; |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3035 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3036 for (; start < end; start++, end--) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3037 { |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3038 left = (fold_T *)gap->ga_data + start; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3039 right = (fold_T *)gap->ga_data + end; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3040 tmp = *left; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3041 *left = *right; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3042 *right = tmp; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3043 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3044 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3045 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3046 // foldMoveRange() {{{2 |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3047 /* |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3048 * Move folds within the inclusive range "line1" to "line2" to after "dest" |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3049 * requires "line1" <= "line2" <= "dest" |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3050 * |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3051 * There are the following situations for the first fold at or below line1 - 1. |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3052 * 1 2 3 4 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3053 * 1 2 3 4 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3054 * line1 2 3 4 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3055 * 2 3 4 5 6 7 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3056 * line2 3 4 5 6 7 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3057 * 3 4 6 7 8 9 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3058 * dest 4 7 8 9 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3059 * 4 7 8 10 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3060 * 4 7 8 10 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3061 * |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3062 * In the following descriptions, "moved" means moving in the buffer, *and* in |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3063 * the fold array. |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3064 * Meanwhile, "shifted" just means moving in the buffer. |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3065 * 1. not changed |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3066 * 2. truncated above line1 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3067 * 3. length reduced by line2 - line1, folds starting between the end of 3 and |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3068 * dest are truncated and shifted up |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3069 * 4. internal folds moved (from [line1, line2] to dest) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3070 * 5. moved to dest. |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3071 * 6. truncated below line2 and moved. |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3072 * 7. length reduced by line2 - dest, folds starting between line2 and dest are |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3073 * removed, top is moved down by move_len. |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3074 * 8. truncated below dest and shifted up. |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3075 * 9. shifted up |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3076 * 10. not changed |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3077 */ |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3078 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3079 static void |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3080 truncate_fold(fold_T *fp, linenr_T end) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3081 { |
11156
80241603dd50
patch 8.0.0465: off-by-one error in using :move with folding
Christian Brabandt <cb@256bit.org>
parents:
11148
diff
changeset
|
3082 end += 1; |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3083 foldRemove(&fp->fd_nested, end - fp->fd_top, MAXLNUM); |
11156
80241603dd50
patch 8.0.0465: off-by-one error in using :move with folding
Christian Brabandt <cb@256bit.org>
parents:
11148
diff
changeset
|
3084 fp->fd_len = end - fp->fd_top; |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3085 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3086 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3087 #define fold_end(fp) ((fp)->fd_top + (fp)->fd_len - 1) |
22023
67d3826948ad
patch 8.2.1561: using NULL pointers in fold code
Bram Moolenaar <Bram@vim.org>
parents:
22021
diff
changeset
|
3088 #define valid_fold(fp, gap) ((gap)->ga_len > 0 && (fp) < ((fold_T *)(gap)->ga_data + (gap)->ga_len)) |
27752
c1d1639b52dd
patch 8.2.4402: missing parenthesis may cause unexpected problems
Bram Moolenaar <Bram@vim.org>
parents:
27734
diff
changeset
|
3089 #define fold_index(fp, gap) ((size_t)((fp) - ((fold_T *)(gap)->ga_data))) |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3090 |
11148
87779062d706
patch 8.0.0461: test 45 hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11140
diff
changeset
|
3091 void |
87779062d706
patch 8.0.0461: test 45 hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11140
diff
changeset
|
3092 foldMoveRange(garray_T *gap, linenr_T line1, linenr_T line2, linenr_T dest) |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3093 { |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3094 fold_T *fp; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3095 linenr_T range_len = line2 - line1 + 1; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3096 linenr_T move_len = dest - line2; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3097 int at_start = foldFind(gap, line1 - 1, &fp); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3098 size_t move_start = 0, move_end = 0, dest_index = 0; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3099 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3100 if (at_start) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3101 { |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3102 if (fold_end(fp) > dest) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3103 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3104 // Case 4 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3105 // don't have to change this fold, but have to move nested folds. |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3106 foldMoveRange(&fp->fd_nested, line1 - fp->fd_top, line2 - |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3107 fp->fd_top, dest - fp->fd_top); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3108 return; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3109 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3110 else if (fold_end(fp) > line2) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3111 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3112 // Case 3 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3113 // Remove nested folds between line1 and line2 & reduce the |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3114 // length of fold by "range_len". |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3115 // Folds after this one must be dealt with. |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3116 foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top, line2 - |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3117 fp->fd_top, MAXLNUM, -range_len); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3118 fp->fd_len -= range_len; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3119 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3120 else |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3121 // Case 2 truncate fold, folds after this one must be dealt with. |
11156
80241603dd50
patch 8.0.0465: off-by-one error in using :move with folding
Christian Brabandt <cb@256bit.org>
parents:
11148
diff
changeset
|
3122 truncate_fold(fp, line1 - 1); |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3123 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3124 // Look at the next fold, and treat that one as if it were the first |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3125 // after "line1" (because now it is). |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3126 fp = fp + 1; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3127 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3128 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3129 if (!valid_fold(fp, gap) || fp->fd_top > dest) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3130 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3131 // Case 10 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3132 // No folds after "line1" and before "dest" |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3133 return; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3134 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3135 else if (fp->fd_top > line2) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3136 { |
11156
80241603dd50
patch 8.0.0465: off-by-one error in using :move with folding
Christian Brabandt <cb@256bit.org>
parents:
11148
diff
changeset
|
3137 for (; valid_fold(fp, gap) && fold_end(fp) <= dest; fp++) |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3138 // Case 9. (for all case 9's) -- shift up. |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3139 fp->fd_top -= range_len; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3140 |
11156
80241603dd50
patch 8.0.0465: off-by-one error in using :move with folding
Christian Brabandt <cb@256bit.org>
parents:
11148
diff
changeset
|
3141 if (valid_fold(fp, gap) && fp->fd_top <= dest) |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3142 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3143 // Case 8. -- ensure truncated at dest, shift up |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3144 truncate_fold(fp, dest); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3145 fp->fd_top -= range_len; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3146 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3147 return; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3148 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3149 else if (fold_end(fp) > dest) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3150 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3151 // Case 7 -- remove nested folds and shrink |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3152 foldMarkAdjustRecurse(&fp->fd_nested, line2 + 1 - fp->fd_top, dest - |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3153 fp->fd_top, MAXLNUM, -move_len); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3154 fp->fd_len -= move_len; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3155 fp->fd_top += move_len; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3156 return; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3157 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3158 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3159 // Case 5 or 6 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3160 // changes rely on whether there are folds between the end of |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3161 // this fold and "dest". |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3162 move_start = fold_index(fp, gap); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3163 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3164 for (; valid_fold(fp, gap) && fp->fd_top <= dest; fp++) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3165 { |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3166 if (fp->fd_top <= line2) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3167 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3168 // 1. 2. or 3. |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3169 if (fold_end(fp) > line2) |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3170 // 2. or 3., truncate before moving |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3171 truncate_fold(fp, line2); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3172 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3173 fp->fd_top += move_len; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3174 continue; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3175 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3176 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3177 // Record index of the first fold after the moved range. |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3178 if (move_end == 0) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3179 move_end = fold_index(fp, gap); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3180 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3181 if (fold_end(fp) > dest) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3182 truncate_fold(fp, dest); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3183 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3184 fp->fd_top -= range_len; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3185 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3186 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3187 dest_index = fold_index(fp, gap); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3188 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3189 /* |
11392
dc2800c3572b
patch 8.0.0581: moving folded text is sometimes not correct
Christian Brabandt <cb@256bit.org>
parents:
11234
diff
changeset
|
3190 * All folds are now correct, but not necessarily in the correct order. We |
dc2800c3572b
patch 8.0.0581: moving folded text is sometimes not correct
Christian Brabandt <cb@256bit.org>
parents:
11234
diff
changeset
|
3191 * must swap folds in the range [move_end, dest_index) with those in the |
dc2800c3572b
patch 8.0.0581: moving folded text is sometimes not correct
Christian Brabandt <cb@256bit.org>
parents:
11234
diff
changeset
|
3192 * range [move_start, move_end). |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3193 */ |
11392
dc2800c3572b
patch 8.0.0581: moving folded text is sometimes not correct
Christian Brabandt <cb@256bit.org>
parents:
11234
diff
changeset
|
3194 if (move_end == 0) |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3195 // There are no folds after those moved, hence no folds have been moved |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3196 // out of order. |
11392
dc2800c3572b
patch 8.0.0581: moving folded text is sometimes not correct
Christian Brabandt <cb@256bit.org>
parents:
11234
diff
changeset
|
3197 return; |
11165
f0602688b8ef
patch 8.0.0469: compiler warnings on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11156
diff
changeset
|
3198 foldReverseOrder(gap, (linenr_T)move_start, (linenr_T)dest_index - 1); |
f0602688b8ef
patch 8.0.0469: compiler warnings on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11156
diff
changeset
|
3199 foldReverseOrder(gap, (linenr_T)move_start, |
f0602688b8ef
patch 8.0.0469: compiler warnings on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11156
diff
changeset
|
3200 (linenr_T)(move_start + dest_index - move_end - 1)); |
f0602688b8ef
patch 8.0.0469: compiler warnings on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11156
diff
changeset
|
3201 foldReverseOrder(gap, (linenr_T)(move_start + dest_index - move_end), |
f0602688b8ef
patch 8.0.0469: compiler warnings on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11156
diff
changeset
|
3202 (linenr_T)(dest_index - 1)); |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3203 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3204 #undef fold_end |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3205 #undef valid_fold |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3206 #undef fold_index |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3207 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3208 // foldMerge() {{{2 |
7 | 3209 /* |
1224 | 3210 * Merge two adjacent folds (and the nested ones in them). |
3211 * This only works correctly when the folds are really adjacent! Thus "fp1" | |
7 | 3212 * must end just above "fp2". |
3213 * The resulting fold is "fp1", nested folds are moved from "fp2" to "fp1". | |
3214 * Fold entry "fp2" in "gap" is deleted. | |
3215 */ | |
3216 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3217 foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2) |
7 | 3218 { |
3219 fold_T *fp3; | |
3220 fold_T *fp4; | |
3221 int idx; | |
3222 garray_T *gap1 = &fp1->fd_nested; | |
3223 garray_T *gap2 = &fp2->fd_nested; | |
3224 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3225 // If the last nested fold in fp1 touches the first nested fold in fp2, |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3226 // merge them recursively. |
7 | 3227 if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4)) |
3228 foldMerge(fp3, gap2, fp4); | |
3229 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3230 // Move nested folds in fp2 to the end of fp1. |
7 | 3231 if (gap2->ga_len > 0 && ga_grow(gap1, gap2->ga_len) == OK) |
3232 { | |
3233 for (idx = 0; idx < gap2->ga_len; ++idx) | |
3234 { | |
3235 ((fold_T *)gap1->ga_data)[gap1->ga_len] | |
3236 = ((fold_T *)gap2->ga_data)[idx]; | |
3237 ((fold_T *)gap1->ga_data)[gap1->ga_len].fd_top += fp1->fd_len; | |
3238 ++gap1->ga_len; | |
3239 } | |
3240 gap2->ga_len = 0; | |
3241 } | |
3242 | |
3243 fp1->fd_len += fp2->fd_len; | |
3244 deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE); | |
3245 fold_changed = TRUE; | |
3246 } | |
3247 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3248 // foldlevelIndent() {{{2 |
7 | 3249 /* |
3250 * Low level function to get the foldlevel for the "indent" method. | |
3251 * Doesn't use any caching. | |
3252 * Returns a level of -1 if the foldlevel depends on surrounding lines. | |
3253 */ | |
3254 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3255 foldlevelIndent(fline_T *flp) |
7 | 3256 { |
3257 char_u *s; | |
3258 buf_T *buf; | |
3259 linenr_T lnum = flp->lnum + flp->off; | |
3260 | |
3261 buf = flp->wp->w_buffer; | |
3262 s = skipwhite(ml_get_buf(buf, lnum, FALSE)); | |
3263 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3264 // empty line or lines starting with a character in 'foldignore': level |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3265 // depends on surrounding lines |
7 | 3266 if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) |
3267 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3268 // first and last line can't be undefined, use level 0 |
7 | 3269 if (lnum == 1 || lnum == buf->b_ml.ml_line_count) |
3270 flp->lvl = 0; | |
3271 else | |
3272 flp->lvl = -1; | |
3273 } | |
3274 else | |
15031
03831e5ea0de
patch 8.1.0527: using 'shiftwidth' from wrong buffer for folding
Bram Moolenaar <Bram@vim.org>
parents:
12477
diff
changeset
|
3275 flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(buf); |
7 | 3276 if (flp->lvl > flp->wp->w_p_fdn) |
1028 | 3277 { |
7 | 3278 flp->lvl = flp->wp->w_p_fdn; |
1028 | 3279 if (flp->lvl < 0) |
3280 flp->lvl = 0; | |
3281 } | |
7 | 3282 } |
3283 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3284 // foldlevelDiff() {{{2 |
7 | 3285 #ifdef FEAT_DIFF |
3286 /* | |
3287 * Low level function to get the foldlevel for the "diff" method. | |
3288 * Doesn't use any caching. | |
3289 */ | |
3290 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3291 foldlevelDiff(fline_T *flp) |
7 | 3292 { |
3293 if (diff_infold(flp->wp, flp->lnum + flp->off)) | |
3294 flp->lvl = 1; | |
3295 else | |
3296 flp->lvl = 0; | |
3297 } | |
3298 #endif | |
3299 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3300 // foldlevelExpr() {{{2 |
7 | 3301 /* |
3302 * Low level function to get the foldlevel for the "expr" method. | |
3303 * Doesn't use any caching. | |
3304 * Returns a level of -1 if the foldlevel depends on surrounding lines. | |
3305 */ | |
3306 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3307 foldlevelExpr(fline_T *flp) |
7 | 3308 { |
3309 #ifndef FEAT_EVAL | |
3310 flp->start = FALSE; | |
3311 flp->lvl = 0; | |
3312 #else | |
3313 win_T *win; | |
3314 int n; | |
3315 int c; | |
3316 linenr_T lnum = flp->lnum + flp->off; | |
3317 int save_keytyped; | |
3318 | |
3319 win = curwin; | |
3320 curwin = flp->wp; | |
3321 curbuf = flp->wp->w_buffer; | |
3322 set_vim_var_nr(VV_LNUM, lnum); | |
3323 | |
3324 flp->start = 0; | |
3325 flp->had_end = flp->end; | |
3326 flp->end = MAX_LEVEL + 1; | |
3327 if (lnum <= 1) | |
3328 flp->lvl = 0; | |
3329 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3330 // KeyTyped may be reset to 0 when calling a function which invokes |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3331 // do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. |
7 | 3332 save_keytyped = KeyTyped; |
27289
e11682ba8c80
patch 8.2.4173: cannot use an import in 'foldexpr'
Bram Moolenaar <Bram@vim.org>
parents:
27028
diff
changeset
|
3333 n = eval_foldexpr(flp->wp, &c); |
7 | 3334 KeyTyped = save_keytyped; |
3335 | |
3336 switch (c) | |
3337 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3338 // "a1", "a2", .. : add to the fold level |
7 | 3339 case 'a': if (flp->lvl >= 0) |
3340 { | |
3341 flp->lvl += n; | |
3342 flp->lvl_next = flp->lvl; | |
3343 } | |
3344 flp->start = n; | |
3345 break; | |
3346 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3347 // "s1", "s2", .. : subtract from the fold level |
7 | 3348 case 's': if (flp->lvl >= 0) |
3349 { | |
3350 if (n > flp->lvl) | |
3351 flp->lvl_next = 0; | |
3352 else | |
3353 flp->lvl_next = flp->lvl - n; | |
3354 flp->end = flp->lvl_next + 1; | |
3355 } | |
3356 break; | |
3357 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3358 // ">1", ">2", .. : start a fold with a certain level |
7 | 3359 case '>': flp->lvl = n; |
3360 flp->lvl_next = n; | |
3361 flp->start = 1; | |
3362 break; | |
3363 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3364 // "<1", "<2", .. : end a fold with a certain level |
7 | 3365 case '<': flp->lvl_next = n - 1; |
3366 flp->end = n; | |
3367 break; | |
3368 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3369 // "=": No change in level |
7 | 3370 case '=': flp->lvl_next = flp->lvl; |
3371 break; | |
3372 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3373 // "-1", "0", "1", ..: set fold level |
7 | 3374 default: if (n < 0) |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3375 // Use the current level for the next line, so that "a1" |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3376 // will work there. |
7 | 3377 flp->lvl_next = flp->lvl; |
3378 else | |
3379 flp->lvl_next = n; | |
3380 flp->lvl = n; | |
3381 break; | |
3382 } | |
3383 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3384 // If the level is unknown for the first or the last line in the file, use |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3385 // level 0. |
7 | 3386 if (flp->lvl < 0) |
3387 { | |
3388 if (lnum <= 1) | |
3389 { | |
3390 flp->lvl = 0; | |
3391 flp->lvl_next = 0; | |
3392 } | |
3393 if (lnum == curbuf->b_ml.ml_line_count) | |
3394 flp->lvl_next = 0; | |
3395 } | |
3396 | |
3397 curwin = win; | |
3398 curbuf = curwin->w_buffer; | |
3399 #endif | |
3400 } | |
3401 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3402 // parseMarker() {{{2 |
7 | 3403 /* |
3404 * Parse 'foldmarker' and set "foldendmarker", "foldstartmarkerlen" and | |
3405 * "foldendmarkerlen". | |
3406 * Relies on the option value to have been checked for correctness already. | |
3407 */ | |
3408 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3409 parseMarker(win_T *wp) |
7 | 3410 { |
3411 foldendmarker = vim_strchr(wp->w_p_fmr, ','); | |
3412 foldstartmarkerlen = (int)(foldendmarker++ - wp->w_p_fmr); | |
3413 foldendmarkerlen = (int)STRLEN(foldendmarker); | |
3414 } | |
3415 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3416 // foldlevelMarker() {{{2 |
7 | 3417 /* |
3418 * Low level function to get the foldlevel for the "marker" method. | |
3419 * "foldendmarker", "foldstartmarkerlen" and "foldendmarkerlen" must have been | |
3420 * set before calling this. | |
3421 * Requires that flp->lvl is set to the fold level of the previous line! | |
3422 * Careful: This means you can't call this function twice on the same line. | |
3423 * Doesn't use any caching. | |
3424 * Sets flp->start when a start marker was found. | |
3425 */ | |
3426 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3427 foldlevelMarker(fline_T *flp) |
7 | 3428 { |
3429 char_u *startmarker; | |
3430 int cstart; | |
3431 int cend; | |
3432 int start_lvl = flp->lvl; | |
3433 char_u *s; | |
3434 int n; | |
3435 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3436 // cache a few values for speed |
7 | 3437 startmarker = flp->wp->w_p_fmr; |
3438 cstart = *startmarker; | |
3439 ++startmarker; | |
3440 cend = *foldendmarker; | |
3441 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3442 // Default: no start found, next level is same as current level |
7 | 3443 flp->start = 0; |
3444 flp->lvl_next = flp->lvl; | |
3445 | |
3446 s = ml_get_buf(flp->wp->w_buffer, flp->lnum + flp->off, FALSE); | |
3447 while (*s) | |
3448 { | |
3449 if (*s == cstart | |
3450 && STRNCMP(s + 1, startmarker, foldstartmarkerlen - 1) == 0) | |
3451 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3452 // found startmarker: set flp->lvl |
7 | 3453 s += foldstartmarkerlen; |
3454 if (VIM_ISDIGIT(*s)) | |
3455 { | |
3456 n = atoi((char *)s); | |
3457 if (n > 0) | |
3458 { | |
3459 flp->lvl = n; | |
3460 flp->lvl_next = n; | |
3461 if (n <= start_lvl) | |
3462 flp->start = 1; | |
3463 else | |
3464 flp->start = n - start_lvl; | |
3465 } | |
3466 } | |
3467 else | |
3468 { | |
3469 ++flp->lvl; | |
3470 ++flp->lvl_next; | |
3471 ++flp->start; | |
3472 } | |
3473 } | |
3474 else if (*s == cend | |
3475 && STRNCMP(s + 1, foldendmarker + 1, foldendmarkerlen - 1) == 0) | |
3476 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3477 // found endmarker: set flp->lvl_next |
7 | 3478 s += foldendmarkerlen; |
3479 if (VIM_ISDIGIT(*s)) | |
3480 { | |
3481 n = atoi((char *)s); | |
3482 if (n > 0) | |
3483 { | |
3484 flp->lvl = n; | |
3485 flp->lvl_next = n - 1; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3486 // never start a fold with an end marker |
2054
79b8d69a4588
updated for version 7.2.340
Bram Moolenaar <bram@zimbu.org>
parents:
1985
diff
changeset
|
3487 if (flp->lvl_next > start_lvl) |
79b8d69a4588
updated for version 7.2.340
Bram Moolenaar <bram@zimbu.org>
parents:
1985
diff
changeset
|
3488 flp->lvl_next = start_lvl; |
7 | 3489 } |
3490 } | |
3491 else | |
3492 --flp->lvl_next; | |
3493 } | |
3494 else | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
3495 MB_PTR_ADV(s); |
7 | 3496 } |
3497 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3498 // The level can't go negative, must be missing a start marker. |
7 | 3499 if (flp->lvl_next < 0) |
3500 flp->lvl_next = 0; | |
3501 } | |
3502 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3503 // foldlevelSyntax() {{{2 |
7 | 3504 /* |
3505 * Low level function to get the foldlevel for the "syntax" method. | |
3506 * Doesn't use any caching. | |
3507 */ | |
3508 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3509 foldlevelSyntax(fline_T *flp) |
7 | 3510 { |
3511 #ifndef FEAT_SYN_HL | |
3512 flp->start = 0; | |
3513 flp->lvl = 0; | |
3514 #else | |
3515 linenr_T lnum = flp->lnum + flp->off; | |
3516 int n; | |
3517 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3518 // Use the maximum fold level at the start of this line and the next. |
7 | 3519 flp->lvl = syn_get_foldlevel(flp->wp, lnum); |
3520 flp->start = 0; | |
3521 if (lnum < flp->wp->w_buffer->b_ml.ml_line_count) | |
3522 { | |
3523 n = syn_get_foldlevel(flp->wp, lnum + 1); | |
3524 if (n > flp->lvl) | |
3525 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3526 flp->start = n - flp->lvl; // fold(s) start here |
7 | 3527 flp->lvl = n; |
3528 } | |
3529 } | |
3530 #endif | |
3531 } | |
3532 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3533 // functions for storing the fold state in a View {{{1 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3534 // put_folds() {{{2 |
7 | 3535 #if defined(FEAT_SESSION) || defined(PROTO) |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
3536 static int put_folds_recurse(FILE *fd, garray_T *gap, linenr_T off); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
3537 static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
3538 static int put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off); |
7 | 3539 |
3540 /* | |
3541 * Write commands to "fd" to restore the manual folds in window "wp". | |
3542 * Return FAIL if writing fails. | |
3543 */ | |
3544 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3545 put_folds(FILE *fd, win_T *wp) |
7 | 3546 { |
3547 if (foldmethodIsManual(wp)) | |
3548 { | |
3549 if (put_line(fd, "silent! normal! zE") == FAIL | |
23812
84089558c5df
patch 8.2.2447: 'foldlevel' not applied to folds restored from session
Bram Moolenaar <Bram@vim.org>
parents:
23260
diff
changeset
|
3550 || put_folds_recurse(fd, &wp->w_folds, (linenr_T)0) == FAIL |
84089558c5df
patch 8.2.2447: 'foldlevel' not applied to folds restored from session
Bram Moolenaar <Bram@vim.org>
parents:
23260
diff
changeset
|
3551 || put_line(fd, "let &fdl = &fdl") == FAIL) |
7 | 3552 return FAIL; |
3553 } | |
3554 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3555 // If some folds are manually opened/closed, need to restore that. |
7 | 3556 if (wp->w_fold_manual) |
3392 | 3557 return put_foldopen_recurse(fd, wp, &wp->w_folds, (linenr_T)0); |
7 | 3558 |
3559 return OK; | |
3560 } | |
3561 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3562 // put_folds_recurse() {{{2 |
7 | 3563 /* |
3564 * Write commands to "fd" to recreate manually created folds. | |
3565 * Returns FAIL when writing failed. | |
3566 */ | |
3567 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3568 put_folds_recurse(FILE *fd, garray_T *gap, linenr_T off) |
7 | 3569 { |
3570 int i; | |
3571 fold_T *fp; | |
3572 | |
3573 fp = (fold_T *)gap->ga_data; | |
3574 for (i = 0; i < gap->ga_len; i++) | |
3575 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3576 // Do nested folds first, they will be created closed. |
7 | 3577 if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL) |
3578 return FAIL; | |
3579 if (fprintf(fd, "%ld,%ldfold", fp->fd_top + off, | |
3580 fp->fd_top + off + fp->fd_len - 1) < 0 | |
3581 || put_eol(fd) == FAIL) | |
3582 return FAIL; | |
3583 ++fp; | |
3584 } | |
3585 return OK; | |
3586 } | |
3587 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3588 // put_foldopen_recurse() {{{2 |
7 | 3589 /* |
3590 * Write commands to "fd" to open and close manually opened/closed folds. | |
3591 * Returns FAIL when writing failed. | |
3592 */ | |
3593 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3594 put_foldopen_recurse( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3595 FILE *fd, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3596 win_T *wp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3597 garray_T *gap, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3598 linenr_T off) |
7 | 3599 { |
3600 int i; | |
3392 | 3601 int level; |
7 | 3602 fold_T *fp; |
3603 | |
3604 fp = (fold_T *)gap->ga_data; | |
3605 for (i = 0; i < gap->ga_len; i++) | |
3606 { | |
3607 if (fp->fd_flags != FD_LEVEL) | |
3608 { | |
3609 if (fp->fd_nested.ga_len > 0) | |
3610 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3611 // open nested folds while this fold is open |
7 | 3612 if (fprintf(fd, "%ld", fp->fd_top + off) < 0 |
3613 || put_eol(fd) == FAIL | |
3766 | 3614 || put_line(fd, "normal! zo") == FAIL) |
7 | 3615 return FAIL; |
3392 | 3616 if (put_foldopen_recurse(fd, wp, &fp->fd_nested, |
3617 off + fp->fd_top) | |
7 | 3618 == FAIL) |
3619 return FAIL; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3620 // close the parent when needed |
3392 | 3621 if (fp->fd_flags == FD_CLOSED) |
3622 { | |
3623 if (put_fold_open_close(fd, fp, off) == FAIL) | |
3624 return FAIL; | |
3625 } | |
3626 } | |
3627 else | |
3628 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3629 // Open or close the leaf according to the window foldlevel. |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3630 // Do not close a leaf that is already closed, as it will close |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3631 // the parent. |
3392 | 3632 level = foldLevelWin(wp, off + fp->fd_top); |
3633 if ((fp->fd_flags == FD_CLOSED && wp->w_p_fdl >= level) | |
3634 || (fp->fd_flags != FD_CLOSED && wp->w_p_fdl < level)) | |
3635 if (put_fold_open_close(fd, fp, off) == FAIL) | |
3636 return FAIL; | |
7 | 3637 } |
3638 } | |
3639 ++fp; | |
3640 } | |
3641 | |
3642 return OK; | |
3643 } | |
3392 | 3644 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3645 // put_fold_open_close() {{{2 |
3392 | 3646 /* |
3647 * Write the open or close command to "fd". | |
3648 * Returns FAIL when writing failed. | |
3649 */ | |
3650 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3651 put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off) |
3392 | 3652 { |
3653 if (fprintf(fd, "%ld", fp->fd_top + off) < 0 | |
3654 || put_eol(fd) == FAIL | |
3766 | 3655 || fprintf(fd, "normal! z%c", |
3392 | 3656 fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0 |
3657 || put_eol(fd) == FAIL) | |
3658 return FAIL; | |
3659 | |
3660 return OK; | |
3661 } | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3662 #endif // FEAT_SESSION |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3663 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3664 // }}}1 |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3665 #endif // defined(FEAT_FOLDING) || defined(PROTO) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3666 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3667 #if defined(FEAT_EVAL) || defined(PROTO) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3668 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3669 /* |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3670 * "foldclosed()" and "foldclosedend()" functions |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3671 */ |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3672 static void |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3673 foldclosed_both( |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3674 typval_T *argvars UNUSED, |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3675 typval_T *rettv, |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3676 int end UNUSED) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3677 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3678 # ifdef FEAT_FOLDING |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3679 linenr_T lnum; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3680 linenr_T first, last; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3681 |
25384
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3682 if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) |
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3683 return; |
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3684 |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3685 lnum = tv_get_lnum(argvars); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3686 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3687 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3688 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3689 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3690 if (end) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3691 rettv->vval.v_number = (varnumber_T)last; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3692 else |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3693 rettv->vval.v_number = (varnumber_T)first; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3694 return; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3695 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3696 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3697 #endif |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3698 rettv->vval.v_number = -1; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3699 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3700 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3701 /* |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3702 * "foldclosed()" function |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3703 */ |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3704 void |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3705 f_foldclosed(typval_T *argvars, typval_T *rettv) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3706 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3707 foldclosed_both(argvars, rettv, FALSE); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3708 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3709 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3710 /* |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3711 * "foldclosedend()" function |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3712 */ |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3713 void |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3714 f_foldclosedend(typval_T *argvars, typval_T *rettv) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3715 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3716 foldclosed_both(argvars, rettv, TRUE); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3717 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3718 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3719 /* |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3720 * "foldlevel()" function |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3721 */ |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3722 void |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3723 f_foldlevel(typval_T *argvars UNUSED, typval_T *rettv UNUSED) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3724 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3725 # ifdef FEAT_FOLDING |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3726 linenr_T lnum; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3727 |
25384
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3728 if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) |
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3729 return; |
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3730 |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3731 lnum = tv_get_lnum(argvars); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3732 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3733 rettv->vval.v_number = foldLevel(lnum); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3734 # endif |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3735 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3736 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3737 /* |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3738 * "foldtext()" function |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3739 */ |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3740 void |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3741 f_foldtext(typval_T *argvars UNUSED, typval_T *rettv) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3742 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3743 # ifdef FEAT_FOLDING |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3744 linenr_T foldstart; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3745 linenr_T foldend; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3746 char_u *dashes; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3747 linenr_T lnum; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3748 char_u *s; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3749 char_u *r; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3750 int len; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3751 char *txt; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3752 long count; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3753 # endif |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3754 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3755 rettv->v_type = VAR_STRING; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3756 rettv->vval.v_string = NULL; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3757 # ifdef FEAT_FOLDING |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3758 foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3759 foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3760 dashes = get_vim_var_str(VV_FOLDDASHES); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3761 if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3762 && dashes != NULL) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3763 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3764 // Find first non-empty line in the fold. |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3765 for (lnum = foldstart; lnum < foldend; ++lnum) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3766 if (!linewhite(lnum)) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3767 break; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3768 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3769 // Find interesting text in this line. |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3770 s = skipwhite(ml_get(lnum)); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3771 // skip C comment-start |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3772 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3773 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3774 s = skipwhite(s + 2); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3775 if (*skipwhite(s) == NUL |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3776 && lnum + 1 < (linenr_T)get_vim_var_nr(VV_FOLDEND)) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3777 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3778 s = skipwhite(ml_get(lnum + 1)); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3779 if (*s == '*') |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3780 s = skipwhite(s + 1); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3781 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3782 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3783 count = (long)(foldend - foldstart + 1); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3784 txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3785 r = alloc(STRLEN(txt) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3786 + STRLEN(dashes) // for %s |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3787 + 20 // for %3ld |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3788 + STRLEN(s)); // concatenated |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3789 if (r != NULL) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3790 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3791 sprintf((char *)r, txt, dashes, count); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3792 len = (int)STRLEN(r); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3793 STRCAT(r, s); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3794 // remove 'foldmarker' and 'commentstring' |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3795 foldtext_cleanup(r + len); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3796 rettv->vval.v_string = r; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3797 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3798 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3799 # endif |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3800 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3801 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3802 /* |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3803 * "foldtextresult(lnum)" function |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3804 */ |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3805 void |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3806 f_foldtextresult(typval_T *argvars UNUSED, typval_T *rettv) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3807 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3808 # ifdef FEAT_FOLDING |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3809 linenr_T lnum; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3810 char_u *text; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3811 char_u buf[FOLD_TEXT_LEN]; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3812 foldinfo_T foldinfo; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3813 int fold_count; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3814 static int entered = FALSE; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3815 # endif |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3816 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3817 rettv->v_type = VAR_STRING; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3818 rettv->vval.v_string = NULL; |
25384
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3819 |
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3820 if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL) |
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3821 return; |
e8e2c4d33b9b
patch 8.2.3229: Vim9: runtime and compile time type checks are not the same
Bram Moolenaar <Bram@vim.org>
parents:
25064
diff
changeset
|
3822 |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3823 # ifdef FEAT_FOLDING |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3824 if (entered) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3825 return; // reject recursive use |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3826 entered = TRUE; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3827 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3828 lnum = tv_get_lnum(argvars); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3829 // treat illegal types and illegal string values for {lnum} the same |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3830 if (lnum < 0) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3831 lnum = 0; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3832 fold_count = foldedCount(curwin, lnum, &foldinfo); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3833 if (fold_count > 0) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3834 { |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3835 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3836 &foldinfo, buf); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3837 if (text == buf) |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3838 text = vim_strsave(text); |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3839 rettv->vval.v_string = text; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3840 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3841 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3842 entered = FALSE; |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3843 # endif |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3844 } |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3845 |
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
3846 #endif // FEAT_EVAL |