Mercurial > vim
annotate src/fold.c @ 34854:97b5457962ed v9.1.0296
patch 9.1.0296: regexp: engines do not handle case-folding well
Commit: https://github.com/vim/vim/commit/7a27c108e0509f3255ebdcb6558e896c223e4d23
Author: Christian Brabandt <cb@256bit.org>
Date: Tue Apr 9 22:53:19 2024 +0200
patch 9.1.0296: regexp: engines do not handle case-folding well
Problem: Regex engines do not handle case-folding well
Solution: Correctly calculate byte length of characters to skip
When the regexp engine compares two utf-8 codepoints case insensitively
it may match an adjacent character, because it assumes it can step over
as many bytes as the pattern contains.
This however is not necessarily true because of case-folding, a
multi-byte UTF-8 character can be considered equal to some single-byte
value.
Let's consider the pattern '?' and the string 's'. When comparing and
ignoring case, the single character 's' matches, and since it matches
Vim will try to step over the match (by the amount of bytes of the
pattern), assuming that since it matches, the length of both strings is
the same.
However in that case, it should only step over the single byte
value 's' so by 1 byte and try to start matching after it again. So for the
backtracking engine we need to ensure:
- we try to match the correct length for the pattern and the text
- in case of a match, we step over it correctly
The same thing can happen for the NFA engine, when skipping to the next
character to test for a match. We are skipping over the regstart
pointer, however we do not consider the case that because of
case-folding we may need to adjust the number of bytes to skip over. So
this needs to be adjusted in find_match_text() as well.
A related issue turned out, when prog->match_text is actually empty. In
that case we should try to find the next match and skip this condition.
fixes: #14294
closes: #14433
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 09 Apr 2024 23:00:08 +0200 |
parents | fd15dc02c223 |
children |
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 /* |
34552
fd15dc02c223
patch 9.1.0177: Coverity reports dead code
Christian Brabandt <cb@256bit.org>
parents:
34540
diff
changeset
|
110 * Return TRUE if there may be folded lines in window "win". |
7 | 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 | |
34552
fd15dc02c223
patch 9.1.0177: Coverity reports dead code
Christian Brabandt <cb@256bit.org>
parents:
34540
diff
changeset
|
554 // foldManualAllowed() {{{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 | |
1065 if (!VIsual_active || !hasAnyFolding(curwin)) | |
1066 return; | |
1067 | |
11121
778c10516955
patch 8.0.0448: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11038
diff
changeset
|
1068 if (LTOREQ_POS(VIsual, curwin->w_cursor)) |
7 | 1069 { |
1070 start = &VIsual; | |
1071 end = &curwin->w_cursor; | |
1072 } | |
1073 else | |
1074 { | |
1075 start = &curwin->w_cursor; | |
1076 end = &VIsual; | |
1077 } | |
1078 if (hasFolding(start->lnum, &start->lnum, NULL)) | |
1079 start->col = 0; | |
31651
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1080 |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1081 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
|
1082 return; |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1083 |
34540
9e093c96dff6
patch 9.1.0172: More code can use ml_get_buf_len() instead of STRLEN()
Christian Brabandt <cb@256bit.org>
parents:
34065
diff
changeset
|
1084 end->col = ml_get_len(end->lnum); |
31651
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1085 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
|
1086 --end->col; |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1087 // 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
|
1088 if (has_mbyte) |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1089 mb_adjust_cursor(); |
7 | 1090 } |
1091 | |
34552
fd15dc02c223
patch 9.1.0177: Coverity reports dead code
Christian Brabandt <cb@256bit.org>
parents:
34540
diff
changeset
|
1092 // foldAdjustCursor() {{{2 |
7 | 1093 /* |
1094 * Move the cursor to the first line of a closed fold. | |
1095 */ | |
1096 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1097 foldAdjustCursor(void) |
7 | 1098 { |
1099 (void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL); | |
1100 } | |
1101 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1102 // 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
|
1103 // cloneFoldGrowArray() {{{2 |
7 | 1104 /* |
1105 * Will "clone" (i.e deep copy) a garray_T of folds. | |
1106 * | |
1107 * Return FAIL if the operation cannot be completed, otherwise OK. | |
1108 */ | |
1109 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1110 cloneFoldGrowArray(garray_T *from, garray_T *to) |
7 | 1111 { |
1112 int i; | |
1113 fold_T *from_p; | |
1114 fold_T *to_p; | |
1115 | |
1116 ga_init2(to, from->ga_itemsize, from->ga_growsize); | |
1117 if (from->ga_len == 0 || ga_grow(to, from->ga_len) == FAIL) | |
1118 return; | |
1119 | |
1120 from_p = (fold_T *)from->ga_data; | |
1121 to_p = (fold_T *)to->ga_data; | |
1122 | |
1123 for (i = 0; i < from->ga_len; i++) | |
1124 { | |
1125 to_p->fd_top = from_p->fd_top; | |
1126 to_p->fd_len = from_p->fd_len; | |
1127 to_p->fd_flags = from_p->fd_flags; | |
1128 to_p->fd_small = from_p->fd_small; | |
1129 cloneFoldGrowArray(&from_p->fd_nested, &to_p->fd_nested); | |
1130 ++to->ga_len; | |
1131 ++from_p; | |
1132 ++to_p; | |
1133 } | |
1134 } | |
1135 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1136 // foldFind() {{{2 |
7 | 1137 /* |
1138 * 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
|
1139 * Set "*fpp" to the fold struct for the fold that contains "lnum" or |
7 | 1140 * the first fold below it (careful: it can be beyond the end of the array!). |
1141 * Returns FALSE when there is no fold that contains "lnum". | |
1142 */ | |
1143 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1144 foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp) |
7 | 1145 { |
1146 linenr_T low, high; | |
1147 fold_T *fp; | |
1148 int i; | |
1149 | |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1150 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
|
1151 { |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1152 *fpp = NULL; |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1153 return FALSE; |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1154 } |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
1155 |
7 | 1156 /* |
1157 * Perform a binary search. | |
1158 * "low" is lowest index of possible match. | |
1159 * "high" is highest index of possible match. | |
1160 */ | |
1161 fp = (fold_T *)gap->ga_data; | |
1162 low = 0; | |
1163 high = gap->ga_len - 1; | |
1164 while (low <= high) | |
1165 { | |
1166 i = (low + high) / 2; | |
1167 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
|
1168 // fold below lnum, adjust high |
7 | 1169 high = i - 1; |
1170 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
|
1171 // fold above lnum, adjust low |
7 | 1172 low = i + 1; |
1173 else | |
1174 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1175 // lnum is inside this fold |
7 | 1176 *fpp = fp + i; |
1177 return TRUE; | |
1178 } | |
1179 } | |
1180 *fpp = fp + low; | |
1181 return FALSE; | |
1182 } | |
1183 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1184 // foldLevelWin() {{{2 |
7 | 1185 /* |
1186 * Return fold level at line number "lnum" in window "wp". | |
1187 */ | |
1188 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1189 foldLevelWin(win_T *wp, linenr_T lnum) |
7 | 1190 { |
1191 fold_T *fp; | |
1192 linenr_T lnum_rel = lnum; | |
1193 int level = 0; | |
1194 garray_T *gap; | |
1195 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1196 // Recursively search for a fold that contains "lnum". |
7 | 1197 gap = &wp->w_folds; |
1198 for (;;) | |
1199 { | |
1200 if (!foldFind(gap, lnum_rel, &fp)) | |
1201 break; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1202 // Check nested folds. Line number is relative to containing fold. |
7 | 1203 gap = &fp->fd_nested; |
1204 lnum_rel -= fp->fd_top; | |
1205 ++level; | |
1206 } | |
1207 | |
1208 return level; | |
1209 } | |
1210 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1211 // checkupdate() {{{2 |
7 | 1212 /* |
1213 * Check if the folds in window "wp" are invalid and update them if needed. | |
1214 */ | |
1215 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1216 checkupdate(win_T *wp) |
7 | 1217 { |
31651
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1218 if (!wp->w_foldinvalid) |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1219 return; |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1220 |
e5ee2ffd826a
patch 9.0.1158: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31600
diff
changeset
|
1221 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
|
1222 wp->w_foldinvalid = FALSE; |
7 | 1223 } |
1224 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1225 // setFoldRepeat() {{{2 |
7 | 1226 /* |
1227 * Open or close fold for current window at line "lnum". | |
1228 * Repeat "count" times. | |
1229 */ | |
1230 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1231 setFoldRepeat(linenr_T lnum, long count, int do_open) |
7 | 1232 { |
1233 int done; | |
1234 long n; | |
1235 | |
1236 for (n = 0; n < count; ++n) | |
1237 { | |
1238 done = DONE_NOTHING; | |
1757 | 1239 (void)setManualFold(lnum, do_open, FALSE, &done); |
7 | 1240 if (!(done & DONE_ACTION)) |
1241 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1242 // Only give an error message when no fold could be opened. |
7 | 1243 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
|
1244 emsg(_(e_no_fold_found)); |
7 | 1245 break; |
1246 } | |
1247 } | |
1248 } | |
1249 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1250 // setManualFold() {{{2 |
7 | 1251 /* |
1252 * Open or close the fold in the current window which contains "lnum". | |
1253 * Also does this for other windows in diff mode when needed. | |
1254 */ | |
1255 static linenr_T | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1256 setManualFold( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1257 linenr_T lnum, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1258 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
|
1259 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
|
1260 int *donep) |
7 | 1261 { |
1262 #ifdef FEAT_DIFF | |
1263 if (foldmethodIsDiff(curwin) && curwin->w_p_scb) | |
1264 { | |
1265 win_T *wp; | |
1266 linenr_T dlnum; | |
1267 | |
1268 /* | |
1269 * Do the same operation in other windows in diff mode. Calculate the | |
1270 * line number from the diffs. | |
1271 */ | |
1272 FOR_ALL_WINDOWS(wp) | |
1273 { | |
1274 if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb) | |
1275 { | |
1276 dlnum = diff_lnum_win(curwin->w_cursor.lnum, wp); | |
1277 if (dlnum != 0) | |
1278 (void)setManualFoldWin(wp, dlnum, opening, recurse, NULL); | |
1279 } | |
1280 } | |
1281 } | |
1282 #endif | |
1283 | |
1284 return setManualFoldWin(curwin, lnum, opening, recurse, donep); | |
1285 } | |
1286 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1287 // setManualFoldWin() {{{2 |
7 | 1288 /* |
1289 * Open or close the fold in window "wp" which contains "lnum". | |
1290 * "donep", when not NULL, points to flag that is set to DONE_FOLD when some | |
1291 * fold was found and to DONE_ACTION when some fold was opened or closed. | |
1292 * When "donep" is NULL give an error message when no fold was found for | |
1293 * "lnum", but only if "wp" is "curwin". | |
1294 * Return the line number of the next line that could be closed. | |
1295 * It's only valid when "opening" is TRUE! | |
1296 */ | |
1297 static linenr_T | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1298 setManualFoldWin( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1299 win_T *wp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1300 linenr_T lnum, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1301 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
|
1302 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
|
1303 int *donep) |
7 | 1304 { |
1305 fold_T *fp; | |
1306 fold_T *fp2; | |
1307 fold_T *found = NULL; | |
1308 int j; | |
1309 int level = 0; | |
1310 int use_level = FALSE; | |
1311 int found_fold = FALSE; | |
1312 garray_T *gap; | |
1313 linenr_T next = MAXLNUM; | |
1314 linenr_T off = 0; | |
1315 int done = 0; | |
1316 | |
1317 checkupdate(wp); | |
1318 | |
1319 /* | |
1320 * Find the fold, open or close it. | |
1321 */ | |
1322 gap = &wp->w_folds; | |
1323 for (;;) | |
1324 { | |
1325 if (!foldFind(gap, lnum, &fp)) | |
1326 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1327 // 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
|
1328 if (fp != NULL && fp < (fold_T *)gap->ga_data + gap->ga_len) |
7 | 1329 next = fp->fd_top + off; |
1330 break; | |
1331 } | |
1332 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1333 // lnum is inside this fold |
7 | 1334 found_fold = TRUE; |
1335 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1336 // If there is a following fold, continue there next time. |
7 | 1337 if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len) |
1338 next = fp[1].fd_top + off; | |
1339 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1340 // Change from level-dependent folding to manual. |
7 | 1341 if (use_level || fp->fd_flags == FD_LEVEL) |
1342 { | |
1343 use_level = TRUE; | |
1344 if (level >= wp->w_p_fdl) | |
1345 fp->fd_flags = FD_CLOSED; | |
1346 else | |
1347 fp->fd_flags = FD_OPEN; | |
1348 fp2 = (fold_T *)fp->fd_nested.ga_data; | |
1349 for (j = 0; j < fp->fd_nested.ga_len; ++j) | |
1350 fp2[j].fd_flags = FD_LEVEL; | |
1351 } | |
1352 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1353 // Simple case: Close recursively means closing the fold. |
7 | 1354 if (!opening && recurse) |
1355 { | |
1356 if (fp->fd_flags != FD_CLOSED) | |
1357 { | |
1358 done |= DONE_ACTION; | |
1359 fp->fd_flags = FD_CLOSED; | |
1360 } | |
1361 } | |
1362 else if (fp->fd_flags == FD_CLOSED) | |
1363 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1364 // When opening, open topmost closed fold. |
7 | 1365 if (opening) |
1366 { | |
1367 fp->fd_flags = FD_OPEN; | |
1368 done |= DONE_ACTION; | |
1369 if (recurse) | |
1370 foldOpenNested(fp); | |
1371 } | |
1372 break; | |
1373 } | |
1374 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1375 // fold is open, check nested folds |
7 | 1376 found = fp; |
1377 gap = &fp->fd_nested; | |
1378 lnum -= fp->fd_top; | |
1379 off += fp->fd_top; | |
1380 ++level; | |
1381 } | |
1382 if (found_fold) | |
1383 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1384 // When closing and not recurse, close deepest open fold. |
7 | 1385 if (!opening && found != NULL) |
1386 { | |
1387 found->fd_flags = FD_CLOSED; | |
1388 done |= DONE_ACTION; | |
1389 } | |
1390 wp->w_fold_manual = TRUE; | |
1391 if (done & DONE_ACTION) | |
1392 changed_window_setting_win(wp); | |
1393 done |= DONE_FOLD; | |
1394 } | |
1395 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
|
1396 emsg(_(e_no_fold_found)); |
7 | 1397 |
1398 if (donep != NULL) | |
1399 *donep |= done; | |
1400 | |
1401 return next; | |
1402 } | |
1403 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1404 // foldOpenNested() {{{2 |
7 | 1405 /* |
1406 * Open all nested folds in fold "fpr" recursively. | |
1407 */ | |
1408 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1409 foldOpenNested(fold_T *fpr) |
7 | 1410 { |
1411 int i; | |
1412 fold_T *fp; | |
1413 | |
1414 fp = (fold_T *)fpr->fd_nested.ga_data; | |
1415 for (i = 0; i < fpr->fd_nested.ga_len; ++i) | |
1416 { | |
1417 foldOpenNested(&fp[i]); | |
1418 fp[i].fd_flags = FD_OPEN; | |
1419 } | |
1420 } | |
1421 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1422 // deleteFoldEntry() {{{2 |
7 | 1423 /* |
1424 * Delete fold "idx" from growarray "gap". | |
1425 * When "recursive" is TRUE also delete all the folds contained in it. | |
1426 * When "recursive" is FALSE contained folds are moved one level up. | |
1427 */ | |
1428 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1429 deleteFoldEntry(garray_T *gap, int idx, int recursive) |
7 | 1430 { |
1431 fold_T *fp; | |
1432 int i; | |
1433 long moved; | |
1434 fold_T *nfp; | |
1435 | |
1436 fp = (fold_T *)gap->ga_data + idx; | |
1437 if (recursive || fp->fd_nested.ga_len == 0) | |
1438 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1439 // recursively delete the contained folds |
7 | 1440 deleteFoldRecurse(&fp->fd_nested); |
1441 --gap->ga_len; | |
1442 if (idx < gap->ga_len) | |
1443 mch_memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx)); | |
1444 } | |
1445 else | |
1446 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1447 // 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
|
1448 // deleted. |
7 | 1449 moved = fp->fd_nested.ga_len; |
1450 if (ga_grow(gap, (int)(moved - 1)) == OK) | |
1451 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1452 // Get "fp" again, the array may have been reallocated. |
3028 | 1453 fp = (fold_T *)gap->ga_data + idx; |
1454 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1455 // adjust fd_top and fd_flags for the moved folds |
7 | 1456 nfp = (fold_T *)fp->fd_nested.ga_data; |
1457 for (i = 0; i < moved; ++i) | |
1458 { | |
1459 nfp[i].fd_top += fp->fd_top; | |
1460 if (fp->fd_flags == FD_LEVEL) | |
1461 nfp[i].fd_flags = FD_LEVEL; | |
1462 if (fp->fd_small == MAYBE) | |
1463 nfp[i].fd_small = MAYBE; | |
1464 } | |
1465 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1466 // move the existing folds down to make room |
3028 | 1467 if (idx + 1 < gap->ga_len) |
7 | 1468 mch_memmove(fp + moved, fp + 1, |
3028 | 1469 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
|
1470 // move the contained folds one level up |
7 | 1471 mch_memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved)); |
1472 vim_free(nfp); | |
1473 gap->ga_len += moved - 1; | |
1474 } | |
1475 } | |
1476 } | |
1477 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1478 // deleteFoldRecurse() {{{2 |
7 | 1479 /* |
1480 * Delete nested folds in a fold. | |
1481 */ | |
1482 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1483 deleteFoldRecurse(garray_T *gap) |
7 | 1484 { |
1485 int i; | |
1486 | |
1487 for (i = 0; i < gap->ga_len; ++i) | |
1488 deleteFoldRecurse(&(((fold_T *)(gap->ga_data))[i].fd_nested)); | |
1489 ga_clear(gap); | |
1490 } | |
1491 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1492 // foldMarkAdjust() {{{2 |
7 | 1493 /* |
1494 * Update line numbers of folds for inserted/deleted lines. | |
1495 */ | |
1496 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1497 foldMarkAdjust( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1498 win_T *wp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1499 linenr_T line1, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1500 linenr_T line2, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1501 long amount, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1502 long amount_after) |
7 | 1503 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1504 // 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
|
1505 // lines, set line2 so that only deleted lines have their folds removed. |
7 | 1506 if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) |
1507 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
|
1508 // 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
|
1509 // 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
|
1510 if ((State & MODE_INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) |
7 | 1511 --line1; |
1512 foldMarkAdjustRecurse(&wp->w_folds, line1, line2, amount, amount_after); | |
1513 } | |
1514 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1515 // foldMarkAdjustRecurse() {{{2 |
7 | 1516 static void |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1517 foldMarkAdjustRecurse( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1518 garray_T *gap, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1519 linenr_T line1, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1520 linenr_T line2, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1521 long amount, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1522 long amount_after) |
7 | 1523 { |
1524 fold_T *fp; | |
1525 int i; | |
1526 linenr_T last; | |
1527 linenr_T top; | |
1528 | |
22009
24cef4317d92
patch 8.2.1554: crash in normal test
Bram Moolenaar <Bram@vim.org>
parents:
22008
diff
changeset
|
1529 if (gap->ga_len == 0) |
24cef4317d92
patch 8.2.1554: crash in normal test
Bram Moolenaar <Bram@vim.org>
parents:
22008
diff
changeset
|
1530 return; |
24cef4317d92
patch 8.2.1554: crash in normal test
Bram Moolenaar <Bram@vim.org>
parents:
22008
diff
changeset
|
1531 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1532 // 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
|
1533 // 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
|
1534 if ((State & MODE_INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) |
7 | 1535 top = line1 + 1; |
1536 else | |
1537 top = line1; | |
1538 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1539 // Find the fold containing or just below "line1". |
7 | 1540 (void)foldFind(gap, line1, &fp); |
1541 | |
1542 /* | |
1543 * Adjust all folds below "line1" that are affected. | |
1544 */ | |
1545 for (i = (int)(fp - (fold_T *)gap->ga_data); i < gap->ga_len; ++i, ++fp) | |
1546 { | |
1547 /* | |
1548 * Check for these situations: | |
1549 * 1 2 3 | |
1550 * 1 2 3 | |
1551 * line1 2 3 4 5 | |
1552 * 2 3 4 5 | |
1553 * 2 3 4 5 | |
1554 * line2 2 3 4 5 | |
1555 * 3 5 6 | |
1556 * 3 5 6 | |
1557 */ | |
1558 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1559 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
|
1560 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1561 // 1. fold completely above line1: nothing to do |
7 | 1562 if (last < line1) |
1563 continue; | |
1564 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1565 // 6. fold below line2: only adjust for amount_after |
7 | 1566 if (fp->fd_top > line2) |
1567 { | |
1568 if (amount_after == 0) | |
1569 break; | |
1570 fp->fd_top += amount_after; | |
1571 } | |
1572 else | |
1573 { | |
1574 if (fp->fd_top >= top && last <= line2) | |
1575 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1576 // 4. fold completely contained in range |
7 | 1577 if (amount == MAXLNUM) |
1578 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1579 // Deleting lines: delete the fold completely |
7 | 1580 deleteFoldEntry(gap, i, TRUE); |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1581 --i; // adjust index for deletion |
7 | 1582 --fp; |
1583 } | |
1584 else | |
1585 fp->fd_top += amount; | |
1586 } | |
1587 else | |
1588 { | |
1589 if (fp->fd_top < top) | |
1590 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1591 // 2 or 3: need to correct nested folds too |
1964 | 1592 foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top, |
1593 line2 - fp->fd_top, amount, amount_after); | |
7 | 1594 if (last <= line2) |
1595 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1596 // 2. fold contains line1, line2 is below fold |
7 | 1597 if (amount == MAXLNUM) |
1598 fp->fd_len = line1 - fp->fd_top; | |
1599 else | |
1600 fp->fd_len += amount; | |
1601 } | |
1602 else | |
1603 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1604 // 3. fold contains line1 and line2 |
7 | 1605 fp->fd_len += amount_after; |
1606 } | |
1607 } | |
1608 else | |
1609 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1610 // 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
|
1611 // correct nested folds too |
7 | 1612 if (amount == MAXLNUM) |
1613 { | |
10998
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1614 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
|
1615 0, |
10998
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1616 line2 - fp->fd_top, |
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1617 amount, |
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1618 amount_after + (fp->fd_top - top)); |
7 | 1619 fp->fd_len -= line2 - fp->fd_top + 1; |
1620 fp->fd_top = line1; | |
1621 } | |
1622 else | |
1623 { | |
10998
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1624 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
|
1625 0, |
10998
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1626 line2 - fp->fd_top, |
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1627 amount, |
2645a98217fa
patch 8.0.0388: filtering lines changes folds
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1628 amount_after - amount); |
7 | 1629 fp->fd_len += amount_after - amount; |
1630 fp->fd_top += amount; | |
1631 } | |
1632 } | |
1633 } | |
1634 } | |
1635 } | |
1636 } | |
1637 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1638 // getDeepestNesting() {{{2 |
7 | 1639 /* |
1640 * Get the lowest 'foldlevel' value that makes the deepest nested fold in the | |
1641 * current window open. | |
1642 */ | |
1643 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1644 getDeepestNesting(void) |
7 | 1645 { |
1646 checkupdate(curwin); | |
1647 return getDeepestNestingRecurse(&curwin->w_folds); | |
1648 } | |
1649 | |
1650 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1651 getDeepestNestingRecurse(garray_T *gap) |
7 | 1652 { |
1653 int i; | |
1654 int level; | |
1655 int maxlevel = 0; | |
1656 fold_T *fp; | |
1657 | |
1658 fp = (fold_T *)gap->ga_data; | |
1659 for (i = 0; i < gap->ga_len; ++i) | |
1660 { | |
1661 level = getDeepestNestingRecurse(&fp[i].fd_nested) + 1; | |
1662 if (level > maxlevel) | |
1663 maxlevel = level; | |
1664 } | |
1665 | |
1666 return maxlevel; | |
1667 } | |
1668 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1669 // check_closed() {{{2 |
7 | 1670 /* |
1671 * Check if a fold is closed and update the info needed to check nested folds. | |
1672 */ | |
1673 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1674 check_closed( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1675 win_T *win, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1676 fold_T *fp, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1677 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
|
1678 int level, // folding depth |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1679 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
|
1680 linenr_T lnum_off) // line number offset for fp->fd_top |
7 | 1681 { |
1682 int closed = FALSE; | |
1683 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1684 // 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
|
1685 // fold and all folds it contains depend on 'foldlevel'. |
7 | 1686 if (*use_levelp || fp->fd_flags == FD_LEVEL) |
1687 { | |
1688 *use_levelp = TRUE; | |
1689 if (level >= win->w_p_fdl) | |
1690 closed = TRUE; | |
1691 } | |
1692 else if (fp->fd_flags == FD_CLOSED) | |
1693 closed = TRUE; | |
1694 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1695 // Small fold isn't closed anyway. |
7 | 1696 if (fp->fd_small == MAYBE) |
1697 *maybe_smallp = TRUE; | |
1698 if (closed) | |
1699 { | |
1700 if (*maybe_smallp) | |
1701 fp->fd_small = MAYBE; | |
1702 checkSmall(win, fp, lnum_off); | |
1703 if (fp->fd_small == TRUE) | |
1704 closed = FALSE; | |
1705 } | |
1706 return closed; | |
1707 } | |
1708 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1709 // checkSmall() {{{2 |
7 | 1710 /* |
1711 * Update fd_small field of fold "fp". | |
1712 */ | |
1713 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1714 checkSmall( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1715 win_T *wp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1716 fold_T *fp, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1717 linenr_T lnum_off) // offset for fp->fd_top |
7 | 1718 { |
1719 int count; | |
1720 int n; | |
1721 | |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1722 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
|
1723 return; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1724 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1725 // 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
|
1726 setSmallMaybe(&fp->fd_nested); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1727 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1728 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
|
1729 fp->fd_small = FALSE; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1730 else |
7 | 1731 { |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1732 count = 0; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1733 for (n = 0; n < fp->fd_len; ++n) |
7 | 1734 { |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1735 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
|
1736 if (count > curwin->w_p_fml) |
7 | 1737 { |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1738 fp->fd_small = FALSE; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1739 return; |
7 | 1740 } |
1741 } | |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1742 fp->fd_small = TRUE; |
7 | 1743 } |
1744 } | |
1745 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1746 // setSmallMaybe() {{{2 |
7 | 1747 /* |
1748 * Set small flags in "gap" to MAYBE. | |
1749 */ | |
1750 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1751 setSmallMaybe(garray_T *gap) |
7 | 1752 { |
1753 int i; | |
1754 fold_T *fp; | |
1755 | |
1756 fp = (fold_T *)gap->ga_data; | |
1757 for (i = 0; i < gap->ga_len; ++i) | |
1758 fp[i].fd_small = MAYBE; | |
1759 } | |
1760 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1761 // foldCreateMarkers() {{{2 |
7 | 1762 /* |
1763 * Create a fold from line "start" to line "end" (inclusive) in the current | |
1764 * window by adding markers. | |
1765 */ | |
1766 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1767 foldCreateMarkers(linenr_T start, linenr_T end) |
7 | 1768 { |
1769 if (!curbuf->b_p_ma) | |
1770 { | |
25064
8f2262c72178
patch 8.2.3069: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
23812
diff
changeset
|
1771 emsg(_(e_cannot_make_changes_modifiable_is_off)); |
7 | 1772 return; |
1773 } | |
1774 parseMarker(curwin); | |
1775 | |
1776 foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen); | |
1777 foldAddMarker(end, foldendmarker, foldendmarkerlen); | |
1778 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1779 // 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
|
1780 // changed when the start marker is inserted and the end isn't. |
7 | 1781 changed_lines(start, (colnr_T)0, end, 0L); |
1782 } | |
1783 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1784 // foldAddMarker() {{{2 |
7 | 1785 /* |
1786 * Add "marker[markerlen]" in 'commentstring' to line "lnum". | |
1787 */ | |
1788 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1789 foldAddMarker(linenr_T lnum, char_u *marker, int markerlen) |
7 | 1790 { |
1791 char_u *cms = curbuf->b_p_cms; | |
1792 char_u *line; | |
1793 int line_len; | |
1794 char_u *newline; | |
1795 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
|
1796 int line_is_comment = FALSE; |
7 | 1797 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1798 // Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end |
7 | 1799 line = ml_get(lnum); |
34540
9e093c96dff6
patch 9.1.0172: More code can use ml_get_buf_len() instead of STRLEN()
Christian Brabandt <cb@256bit.org>
parents:
34065
diff
changeset
|
1800 line_len = ml_get_len(lnum); |
7 | 1801 |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1802 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
|
1803 return; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1804 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1805 // 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
|
1806 (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
|
1807 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
|
1808 if (newline == NULL) |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1809 return; |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1810 STRCPY(newline, line); |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1811 // 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
|
1812 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
|
1813 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
|
1814 else |
7 | 1815 { |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1816 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
|
1817 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
|
1818 STRCPY(newline + line_len + (p - cms) + markerlen, p + 2); |
7 | 1819 } |
31600
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1820 |
f1d5ad2b978e
patch 9.0.1132: code is indented more than needed
Bram Moolenaar <Bram@vim.org>
parents:
30598
diff
changeset
|
1821 ml_replace(lnum, newline, FALSE); |
7 | 1822 } |
1823 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1824 // deleteFoldMarkers() {{{2 |
7 | 1825 /* |
1826 * Delete the markers for a fold, causing it to be deleted. | |
1827 */ | |
1828 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1829 deleteFoldMarkers( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1830 fold_T *fp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1831 int recursive, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1832 linenr_T lnum_off) // offset for fp->fd_top |
7 | 1833 { |
1834 int i; | |
1835 | |
1836 if (recursive) | |
1837 for (i = 0; i < fp->fd_nested.ga_len; ++i) | |
1838 deleteFoldMarkers((fold_T *)fp->fd_nested.ga_data + i, TRUE, | |
1839 lnum_off + fp->fd_top); | |
1840 foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen); | |
1841 foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1, | |
1842 foldendmarker, foldendmarkerlen); | |
1843 } | |
1844 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1845 // foldDelMarker() {{{2 |
7 | 1846 /* |
1847 * Delete marker "marker[markerlen]" at the end of line "lnum". | |
1848 * 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
|
1849 * If the marker is not found, there is no error message. Could be a missing |
7 | 1850 * close-marker. |
1851 */ | |
1852 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1853 foldDelMarker(linenr_T lnum, char_u *marker, int markerlen) |
7 | 1854 { |
1855 char_u *line; | |
1856 char_u *newline; | |
1857 char_u *p; | |
1858 int len; | |
1859 char_u *cms = curbuf->b_p_cms; | |
1860 char_u *cms2; | |
1861 | |
17787
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
1862 // 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
|
1863 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
|
1864 return; |
7 | 1865 line = ml_get(lnum); |
1866 for (p = line; *p != NUL; ++p) | |
1867 if (STRNCMP(p, marker, markerlen) == 0) | |
1868 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1869 // Found the marker, include a digit if it's there. |
7 | 1870 len = markerlen; |
1871 if (VIM_ISDIGIT(p[len])) | |
1872 ++len; | |
1873 if (*cms != NUL) | |
1874 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1875 // Also delete 'commentstring' if it matches. |
7 | 1876 cms2 = (char_u *)strstr((char *)cms, "%s"); |
1877 if (p - line >= cms2 - cms | |
1878 && STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0 | |
1879 && STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0) | |
1880 { | |
1881 p -= cms2 - cms; | |
1882 len += (int)STRLEN(cms) - 2; | |
1883 } | |
1884 } | |
1885 if (u_save(lnum - 1, lnum + 1) == OK) | |
1886 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1887 // Make new line: text-before-marker + text-after-marker |
34540
9e093c96dff6
patch 9.1.0172: More code can use ml_get_buf_len() instead of STRLEN()
Christian Brabandt <cb@256bit.org>
parents:
34065
diff
changeset
|
1888 newline = alloc(ml_get_len(lnum) - len + 1); |
7 | 1889 if (newline != NULL) |
1890 { | |
1891 STRNCPY(newline, line, p - line); | |
1892 STRCPY(newline + (p - line), p + len); | |
1893 ml_replace(lnum, newline, FALSE); | |
1894 } | |
1895 } | |
1896 break; | |
1897 } | |
1898 } | |
1899 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1900 // get_foldtext() {{{2 |
29 | 1901 /* |
1902 * 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
|
1903 * 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
|
1904 * Otherwise the result is in allocated memory. |
29 | 1905 */ |
1906 char_u * | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1907 get_foldtext( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1908 win_T *wp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1909 linenr_T lnum, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1910 linenr_T lnume, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1911 foldinfo_T *foldinfo, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
1912 char_u *buf) |
29 | 1913 { |
1914 char_u *text = NULL; | |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1915 #ifdef FEAT_EVAL |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1916 // an error occurred when evaluating 'fdt' setting |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1917 static int got_fdt_error = FALSE; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1918 int save_did_emsg = did_emsg; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1919 static win_T *last_wp = NULL; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1920 static linenr_T last_lnum = 0; |
29 | 1921 |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1922 if (last_wp != wp || last_wp == NULL |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1923 || 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
|
1924 // 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
|
1925 got_fdt_error = FALSE; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1926 |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1927 if (!got_fdt_error) |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1928 // 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
|
1929 did_emsg = FALSE; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1930 |
29 | 1931 if (*wp->w_p_fdt != NUL) |
1932 { | |
1981 | 1933 char_u dashes[MAX_LEVEL + 2]; |
29 | 1934 int level; |
1935 char_u *p; | |
1936 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1937 // Set "v:foldstart" and "v:foldend". |
29 | 1938 set_vim_var_nr(VV_FOLDSTART, lnum); |
1939 set_vim_var_nr(VV_FOLDEND, lnume); | |
1940 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1941 // 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
|
1942 // Set "v:foldlevel" to "level". |
29 | 1943 level = foldinfo->fi_level; |
1981 | 1944 if (level > (int)sizeof(dashes) - 1) |
1945 level = (int)sizeof(dashes) - 1; | |
29 | 1946 vim_memset(dashes, '-', (size_t)level); |
1947 dashes[level] = NUL; | |
1948 set_vim_var_string(VV_FOLDDASHES, dashes, -1); | |
1949 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
|
1950 |
27301
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1951 // skip evaluating 'foldtext' on errors |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1952 if (!got_fdt_error) |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1953 { |
27301
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1954 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
|
1955 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
|
1956 |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1957 curwin = wp; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1958 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
|
1959 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
|
1960 |
ebe56a24acb6
patch 8.2.4179: 'foldtext' is evaluated in the current script context
Bram Moolenaar <Bram@vim.org>
parents:
27289
diff
changeset
|
1961 ++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
|
1962 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
|
1963 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
|
1964 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
|
1965 --emsg_off; |
29 | 1966 |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1967 if (text == NULL || did_emsg) |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1968 got_fdt_error = TRUE; |
29 | 1969 |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1970 curwin = save_curwin; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1971 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
|
1972 current_sctx = saved_sctx; |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1973 } |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1974 last_lnum = lnum; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1975 last_wp = wp; |
29 | 1976 set_vim_var_string(VV_FOLDDASHES, NULL, -1); |
1977 | |
4907
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1978 if (!did_emsg && save_did_emsg) |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1979 did_emsg = save_did_emsg; |
be2973afe770
updated for version 7.3.1199
Bram Moolenaar <bram@vim.org>
parents:
3766
diff
changeset
|
1980 |
29 | 1981 if (text != NULL) |
1982 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
1983 // 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
|
1984 // replace a TAB with a space. |
29 | 1985 for (p = text; *p != NUL; ++p) |
1986 { | |
33 | 1987 int len; |
1988 | |
474 | 1989 if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1) |
29 | 1990 { |
1991 if (!vim_isprintc((*mb_ptr2char)(p))) | |
1992 break; | |
1993 p += len - 1; | |
1994 } | |
1995 else | |
1996 if (*p == TAB) | |
1997 *p = ' '; | |
1998 else if (ptr2cells(p) > 1) | |
1999 break; | |
2000 } | |
2001 if (*p != NUL) | |
2002 { | |
2003 p = transstr(text); | |
2004 vim_free(text); | |
2005 text = p; | |
2006 } | |
2007 } | |
2008 } | |
2009 if (text == NULL) | |
2010 #endif | |
2011 { | |
9754
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2012 long count = (long)(lnume - lnum + 1); |
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2013 |
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2014 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
|
2015 NGETTEXT("+--%3ld line folded ", |
9754
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2016 "+--%3ld lines folded ", count), |
a990e7ed260b
commit https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5
Christian Brabandt <cb@256bit.org>
parents:
9389
diff
changeset
|
2017 count); |
29 | 2018 text = buf; |
2019 } | |
2020 return text; | |
2021 } | |
2022 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2023 // foldtext_cleanup() {{{2 |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
2024 #ifdef FEAT_EVAL |
7 | 2025 /* |
2026 * Remove 'foldmarker' and 'commentstring' from "str" (in-place). | |
2027 */ | |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
2028 static void |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2029 foldtext_cleanup(char_u *str) |
7 | 2030 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2031 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
|
2032 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
|
2033 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
|
2034 int cms_elen = 0; // length of cms_end |
7 | 2035 char_u *s; |
45 | 2036 char_u *p; |
7 | 2037 int len; |
2038 int did1 = FALSE; | |
2039 int did2 = FALSE; | |
2040 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2041 // Ignore leading and trailing white space in 'commentstring'. |
7 | 2042 cms_start = skipwhite(curbuf->b_p_cms); |
835 | 2043 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
|
2044 while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1])) |
7 | 2045 --cms_slen; |
2046 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2047 // locate "%s" in 'commentstring', use the part before and after it. |
7 | 2048 cms_end = (char_u *)strstr((char *)cms_start, "%s"); |
2049 if (cms_end != NULL) | |
2050 { | |
835 | 2051 cms_elen = cms_slen - (int)(cms_end - cms_start); |
2052 cms_slen = (int)(cms_end - cms_start); | |
7 | 2053 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2054 // 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
|
2055 while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1])) |
7 | 2056 --cms_slen; |
2057 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2058 // skip "%s" and white space after it |
7 | 2059 s = skipwhite(cms_end + 2); |
835 | 2060 cms_elen -= (int)(s - cms_end); |
7 | 2061 cms_end = s; |
2062 } | |
2063 parseMarker(curwin); | |
2064 | |
2065 for (s = str; *s != NUL; ) | |
2066 { | |
2067 len = 0; | |
2068 if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0) | |
45 | 2069 len = foldstartmarkerlen; |
2070 else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0) | |
2071 len = foldendmarkerlen; | |
2072 if (len > 0) | |
7 | 2073 { |
2074 if (VIM_ISDIGIT(s[len])) | |
2075 ++len; | |
45 | 2076 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2077 // 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
|
2078 // 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
|
2079 for (p = s; p > str && VIM_ISWHITE(p[-1]); --p) |
45 | 2080 ; |
2081 if (p >= str + cms_slen | |
2082 && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0) | |
2083 { | |
835 | 2084 len += (int)(s - p) + cms_slen; |
45 | 2085 s = p - cms_slen; |
2086 } | |
7 | 2087 } |
2088 else if (cms_end != NULL) | |
2089 { | |
45 | 2090 if (!did1 && cms_slen > 0 && STRNCMP(s, cms_start, cms_slen) == 0) |
7 | 2091 { |
2092 len = cms_slen; | |
2093 did1 = TRUE; | |
2094 } | |
45 | 2095 else if (!did2 && cms_elen > 0 |
2096 && STRNCMP(s, cms_end, cms_elen) == 0) | |
7 | 2097 { |
2098 len = cms_elen; | |
2099 did2 = TRUE; | |
2100 } | |
2101 } | |
2102 if (len != 0) | |
2103 { | |
11129
f4ea50924c6d
patch 8.0.0452: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11127
diff
changeset
|
2104 while (VIM_ISWHITE(s[len])) |
7 | 2105 ++len; |
1624 | 2106 STRMOVE(s, s + len); |
7 | 2107 } |
2108 else | |
2109 { | |
11127
506f5d8b7d8b
patch 8.0.0451: some macros are in lower case
Christian Brabandt <cb@256bit.org>
parents:
11121
diff
changeset
|
2110 MB_PTR_ADV(s); |
7 | 2111 } |
2112 } | |
2113 } | |
17928
34639bba19b0
patch 8.1.1960: fold code is spread out
Bram Moolenaar <Bram@vim.org>
parents:
17851
diff
changeset
|
2114 #endif |
7 | 2115 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2116 // 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
|
2117 // Define "fline_T", passed to get fold level for a line. {{{2 |
7 | 2118 typedef struct |
2119 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2120 win_T *wp; // window |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2121 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
|
2122 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
|
2123 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
|
2124 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
|
2125 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
|
2126 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
|
2127 // this line. |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2128 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
|
2129 // this line |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2130 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
|
2131 // this line (copy of "end" of prev. line) |
7 | 2132 } fline_T; |
2133 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2134 // Flag is set when redrawing is needed. |
7 | 2135 static int fold_changed; |
2136 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2137 // Function declarations. {{{2 |
7807
1a5d34492798
commit https://github.com/vim/vim/commit/d99df423c559d85c17779b3685426c489554908c
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2138 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
|
2139 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
|
2140 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
|
2141 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
|
2142 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
|
2143 static void foldlevelIndent(fline_T *flp); |
7 | 2144 #ifdef FEAT_DIFF |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2145 static void foldlevelDiff(fline_T *flp); |
7 | 2146 #endif |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2147 static void foldlevelExpr(fline_T *flp); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2148 static void foldlevelMarker(fline_T *flp); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
2149 static void foldlevelSyntax(fline_T *flp); |
7 | 2150 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2151 // foldUpdateIEMS() {{{2 |
7 | 2152 /* |
2153 * Update the folding for window "wp", at least from lines "top" to "bot". | |
2154 * Return TRUE if any folds did change. | |
2155 */ | |
2156 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2157 foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot) |
7 | 2158 { |
2159 linenr_T start; | |
2160 linenr_T end; | |
2161 fline_T fline; | |
7807
1a5d34492798
commit https://github.com/vim/vim/commit/d99df423c559d85c17779b3685426c489554908c
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2162 void (*getlevel)(fline_T *); |
7 | 2163 int level; |
2164 fold_T *fp; | |
2165 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2166 // Avoid problems when being called recursively. |
7 | 2167 if (invalid_top != (linenr_T)0) |
2168 return; | |
2169 | |
2170 if (wp->w_foldinvalid) | |
2171 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2172 // Need to update all folds. |
7 | 2173 top = 1; |
2174 bot = wp->w_buffer->b_ml.ml_line_count; | |
2175 wp->w_foldinvalid = FALSE; | |
2176 | |
28929
2ac9beab876c
patch 8.2.4987: after deletion a small fold may be closable
Bram Moolenaar <Bram@vim.org>
parents:
28823
diff
changeset
|
2177 // Mark all folds as maybe-small. |
7 | 2178 setSmallMaybe(&wp->w_folds); |
2179 } | |
2180 | |
2181 #ifdef FEAT_DIFF | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2182 // add the context for "diff" folding |
7 | 2183 if (foldmethodIsDiff(wp)) |
2184 { | |
2185 if (top > diff_context) | |
2186 top -= diff_context; | |
2187 else | |
2188 top = 1; | |
2189 bot += diff_context; | |
2190 } | |
2191 #endif | |
2192 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2193 // 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
|
2194 // of the buffer. |
7 | 2195 if (top > wp->w_buffer->b_ml.ml_line_count) |
2196 top = wp->w_buffer->b_ml.ml_line_count; | |
2197 | |
2198 fold_changed = FALSE; | |
2199 fline.wp = wp; | |
2200 fline.off = 0; | |
2201 fline.lvl = 0; | |
2202 fline.lvl_next = -1; | |
2203 fline.start = 0; | |
2204 fline.end = MAX_LEVEL + 1; | |
2205 fline.had_end = MAX_LEVEL + 1; | |
2206 | |
2207 invalid_top = top; | |
2208 invalid_bot = bot; | |
2209 | |
2210 if (foldmethodIsMarker(wp)) | |
2211 { | |
2212 getlevel = foldlevelMarker; | |
2213 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2214 // Init marker variables to speed up foldlevelMarker(). |
7 | 2215 parseMarker(wp); |
2216 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2217 // 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
|
2218 // no marker at the top. |
7 | 2219 if (top > 1) |
2220 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2221 // Get the fold level at top - 1. |
7 | 2222 level = foldLevelWin(wp, top - 1); |
2223 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2224 // The fold may end just above the top, check for that. |
7 | 2225 fline.lnum = top - 1; |
2226 fline.lvl = level; | |
2227 getlevel(&fline); | |
2228 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2229 // 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
|
2230 // 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
|
2231 // in the same line. |
7 | 2232 if (fline.lvl > level) |
2233 fline.lvl = level - (fline.lvl - fline.lvl_next); | |
2234 else | |
2235 fline.lvl = fline.lvl_next; | |
2236 } | |
2237 fline.lnum = top; | |
2238 getlevel(&fline); | |
2239 } | |
2240 else | |
2241 { | |
2242 fline.lnum = top; | |
2243 if (foldmethodIsExpr(wp)) | |
2244 { | |
2245 getlevel = foldlevelExpr; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2246 // 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
|
2247 // fold in the topline |
7 | 2248 if (top > 1) |
2249 --fline.lnum; | |
2250 } | |
2251 else if (foldmethodIsSyntax(wp)) | |
2252 getlevel = foldlevelSyntax; | |
2253 #ifdef FEAT_DIFF | |
2254 else if (foldmethodIsDiff(wp)) | |
2255 getlevel = foldlevelDiff; | |
2256 #endif | |
2257 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
|
2258 { |
7 | 2259 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
|
2260 // 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
|
2261 // 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
|
2262 // 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
|
2263 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
|
2264 --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
|
2265 } |
7 | 2266 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2267 // 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
|
2268 // always defined for line one, we will stop there. |
7 | 2269 fline.lvl = -1; |
2270 for ( ; !got_int; --fline.lnum) | |
2271 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2272 // 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
|
2273 // the next line, but we search backwards here. |
7 | 2274 fline.lvl_next = -1; |
2275 getlevel(&fline); | |
2276 if (fline.lvl >= 0) | |
2277 break; | |
2278 } | |
2279 } | |
2280 | |
1977 | 2281 /* |
2282 * If folding is defined by the syntax, it is possible that a change in | |
2283 * one line will cause all sub-folds of the current fold to change (e.g., | |
2284 * closing a C-style comment can cause folds in the subsequent lines to | |
2285 * appear). To take that into account we should adjust the value of "bot" | |
2286 * to point to the end of the current fold: | |
2287 */ | |
2288 if (foldlevelSyntax == getlevel) | |
2289 { | |
2290 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
|
2291 fold_T *fpn = NULL; |
1977 | 2292 int current_fdl = 0; |
2293 linenr_T fold_start_lnum = 0; | |
2294 linenr_T lnum_rel = fline.lnum; | |
2295 | |
2296 while (current_fdl < fline.lvl) | |
2297 { | |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2298 if (!foldFind(gap, lnum_rel, &fpn)) |
1977 | 2299 break; |
2300 ++current_fdl; | |
2301 | |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2302 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
|
2303 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
|
2304 lnum_rel -= fpn->fd_top; |
1977 | 2305 } |
2271
2b33a7678e7b
Fix compiler warnings for shadowed variables. Make 'conceal' a long instead
Bram Moolenaar <bram@vim.org>
parents:
2114
diff
changeset
|
2306 if (fpn != NULL && current_fdl == fline.lvl) |
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 linenr_T fold_end_lnum = fold_start_lnum + fpn->fd_len; |
1977 | 2309 |
2310 if (fold_end_lnum > bot) | |
2311 bot = fold_end_lnum; | |
2312 } | |
2313 } | |
2314 | |
7 | 2315 start = fline.lnum; |
2316 end = bot; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2317 // Do at least one line. |
7 | 2318 if (start > end && end < wp->w_buffer->b_ml.ml_line_count) |
2319 end = start; | |
2320 while (!got_int) | |
2321 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2322 // 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
|
2323 // the file). |
7 | 2324 if (fline.lnum > wp->w_buffer->b_ml.ml_line_count) |
2325 break; | |
2326 if (fline.lnum > end) | |
2327 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2328 // 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
|
2329 // 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
|
2330 // it ended. |
7 | 2331 if (getlevel != foldlevelMarker |
2332 && getlevel != foldlevelSyntax | |
2333 && getlevel != foldlevelExpr) | |
2334 break; | |
2335 if ((start <= end | |
2336 && foldFind(&wp->w_folds, end, &fp) | |
2337 && fp->fd_top + fp->fd_len - 1 > end) | |
2338 || (fline.lvl == 0 | |
2339 && foldFind(&wp->w_folds, fline.lnum, &fp) | |
2340 && fp->fd_top < fline.lnum)) | |
2341 end = fp->fd_top + fp->fd_len - 1; | |
2342 else if (getlevel == foldlevelSyntax | |
2343 && 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
|
2344 // 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
|
2345 // 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
|
2346 // don't match continue updating folds. |
7 | 2347 end = fline.lnum; |
2348 else | |
2349 break; | |
2350 } | |
2351 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2352 // A level 1 fold starts at a line with foldlevel > 0. |
7 | 2353 if (fline.lvl > 0) |
2354 { | |
2355 invalid_top = fline.lnum; | |
2356 invalid_bot = end; | |
2357 end = foldUpdateIEMSRecurse(&wp->w_folds, | |
2358 1, start, &fline, getlevel, end, FD_LEVEL); | |
2359 start = fline.lnum; | |
2360 } | |
2361 else | |
2362 { | |
2363 if (fline.lnum == wp->w_buffer->b_ml.ml_line_count) | |
2364 break; | |
2365 ++fline.lnum; | |
2366 fline.lvl = fline.lvl_next; | |
2367 getlevel(&fline); | |
2368 } | |
2369 } | |
2370 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2371 // There can't be any folds from start until end now. |
7 | 2372 foldRemove(&wp->w_folds, start, end); |
2373 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2374 // If some fold changed, need to redraw and position cursor. |
7 | 2375 if (fold_changed && wp->w_p_fen) |
1554 | 2376 changed_window_setting_win(wp); |
7 | 2377 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2378 // 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
|
2379 // 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
|
2380 // this method can cause the whole window to be updated. |
7 | 2381 if (end != bot) |
2382 { | |
2383 if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) | |
2384 wp->w_redraw_top = top; | |
2385 if (wp->w_redraw_bot < end) | |
2386 wp->w_redraw_bot = end; | |
2387 } | |
2388 | |
2389 invalid_top = (linenr_T)0; | |
2390 } | |
2391 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2392 // foldUpdateIEMSRecurse() {{{2 |
7 | 2393 /* |
2394 * Update a fold that starts at "flp->lnum". At this line there is always a | |
2395 * valid foldlevel, and its level >= "level". | |
2396 * "flp" is valid for "flp->lnum" when called and it's valid when returning. | |
2397 * "flp->lnum" is set to the lnum just below the fold, if it ends before | |
2398 * "bot", it's "bot" plus one if the fold continues and it's bigger when using | |
2399 * the marker method and a text change made following folds to change. | |
2400 * When returning, "flp->lnum_save" is the line number that was used to get | |
2401 * the level when the level at "flp->lnum" is invalid. | |
2402 * Remove any folds from "startlnum" up to here at this level. | |
2403 * Recursively update nested folds. | |
2404 * Below line "bot" there are no changes in the text. | |
2405 * "flp->lnum", "flp->lnum_save" and "bot" are relative to the start of the | |
2406 * outer fold. | |
2407 * "flp->off" is the offset to the real line number in the buffer. | |
2408 * | |
2409 * All this would be a lot simpler if all folds in the range would be deleted | |
1698 | 2410 * and then created again. But we would lose all information about the |
7 | 2411 * folds, even when making changes that don't affect the folding (e.g. "vj~"). |
2412 * | |
2413 * Returns bot, which may have been increased for lines that also need to be | |
2414 * updated as a result of a detected change in the fold. | |
2415 */ | |
2416 static linenr_T | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2417 foldUpdateIEMSRecurse( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2418 garray_T *gap, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2419 int level, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2420 linenr_T startlnum, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2421 fline_T *flp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2422 void (*getlevel)(fline_T *), |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2423 linenr_T bot, |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2424 int topflags) // flags used by containing fold |
7 | 2425 { |
2426 linenr_T ll; | |
2427 fold_T *fp = NULL; | |
2428 fold_T *fp2; | |
2429 int lvl = level; | |
2430 linenr_T startlnum2 = startlnum; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2431 linenr_T firstlnum = flp->lnum; // first lnum we got |
7 | 2432 int i; |
2433 int finish = FALSE; | |
2434 linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off; | |
2435 int concat; | |
2436 | |
2437 /* | |
2438 * If using the marker method, the start line is not the start of a fold | |
2439 * at the level we're dealing with and the level is non-zero, we must use | |
2440 * the previous fold. But ignore a fold that starts at or below | |
2441 * startlnum, it must be deleted. | |
2442 */ | |
2443 if (getlevel == foldlevelMarker && flp->start <= flp->lvl - level | |
2444 && flp->lvl > 0) | |
2445 { | |
7009 | 2446 (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
|
2447 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
|
2448 || fp->fd_top >= startlnum)) |
7 | 2449 fp = NULL; |
2450 } | |
2451 | |
2452 /* | |
2453 * Loop over all lines in this fold, or until "bot" is hit. | |
2454 * Handle nested folds inside of this fold. | |
2455 * "flp->lnum" is the current line. When finding the end of the fold, it | |
2456 * is just below the end of the fold. | |
2457 * "*flp" contains the level of the line "flp->lnum" or a following one if | |
2458 * there are lines with an invalid fold level. "flp->lnum_save" is the | |
2459 * line number that was used to get the fold level (below "flp->lnum" when | |
2460 * it has an invalid fold level). When called the fold level is always | |
2461 * valid, thus "flp->lnum_save" is equal to "flp->lnum". | |
2462 */ | |
2463 flp->lnum_save = flp->lnum; | |
2464 while (!got_int) | |
2465 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2466 // Updating folds can be slow, check for CTRL-C. |
7 | 2467 line_breakcheck(); |
2468 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2469 // 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
|
2470 // 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
|
2471 // 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
|
2472 // line was marked as end of a fold. |
7 | 2473 lvl = flp->lvl; |
2474 if (lvl > MAX_LEVEL) | |
2475 lvl = MAX_LEVEL; | |
2476 if (flp->lnum > firstlnum | |
2477 && (level > lvl - flp->start || level >= flp->had_end)) | |
2478 lvl = 0; | |
2479 | |
2480 if (flp->lnum > bot && !finish && fp != NULL) | |
2481 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2482 // For "marker" and "syntax" methods: |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2483 // - 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
|
2484 // 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
|
2485 // - 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
|
2486 // to continue below its original end, need to finish this fold. |
7 | 2487 if (getlevel != foldlevelMarker |
2488 && getlevel != foldlevelExpr | |
2489 && getlevel != foldlevelSyntax) | |
2490 break; | |
2491 i = 0; | |
2492 fp2 = fp; | |
2493 if (lvl >= level) | |
2494 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2495 // 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
|
2496 // 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
|
2497 // at least one nested fold. |
7 | 2498 ll = flp->lnum - fp->fd_top; |
2499 while (foldFind(&fp2->fd_nested, ll, &fp2)) | |
2500 { | |
2501 ++i; | |
2502 ll -= fp2->fd_top; | |
2503 } | |
2504 } | |
2505 if (lvl < level + i) | |
2506 { | |
7009 | 2507 (void)foldFind(&fp->fd_nested, flp->lnum - fp->fd_top, &fp2); |
7 | 2508 if (fp2 != NULL) |
2509 bot = fp2->fd_top + fp2->fd_len - 1 + fp->fd_top; | |
2510 } | |
2511 else if (fp->fd_top + fp->fd_len <= flp->lnum && lvl >= level) | |
2512 finish = TRUE; | |
2513 else | |
2514 break; | |
2515 } | |
2516 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2517 // 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
|
2518 // 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
|
2519 // one, need to be deleted or truncated. |
7 | 2520 if (fp == NULL |
2521 && (lvl != level | |
2522 || flp->lnum_save >= bot | |
2523 || flp->start != 0 | |
2524 || flp->had_end <= MAX_LEVEL | |
2525 || flp->lnum == linecount)) | |
2526 { | |
2527 /* | |
2528 * Remove or update folds that have lines between startlnum and | |
2529 * firstlnum. | |
2530 */ | |
2531 while (!got_int) | |
2532 { | |
26771
fc859aea8cec
patch 8.2.3914: various spelling mistakes in comments
Bram Moolenaar <Bram@vim.org>
parents:
26262
diff
changeset
|
2533 // 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
|
2534 // with a previous one that touches it. |
7 | 2535 if (flp->start != 0 || flp->had_end <= MAX_LEVEL) |
2536 concat = 0; | |
2537 else | |
2538 concat = 1; | |
2539 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2540 // 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
|
2541 // 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
|
2542 // 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
|
2543 if (gap->ga_len > 0 && (foldFind(gap, startlnum, &fp) |
7 | 2544 || (fp < ((fold_T *)gap->ga_data) + gap->ga_len |
2545 && fp->fd_top <= firstlnum) | |
2546 || foldFind(gap, firstlnum - concat, &fp) | |
2547 || (fp < ((fold_T *)gap->ga_data) + gap->ga_len | |
2548 && ((lvl < level && fp->fd_top < flp->lnum) | |
2549 || (lvl >= level | |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2550 && fp->fd_top <= flp->lnum_save))))) |
7 | 2551 { |
2552 if (fp->fd_top + fp->fd_len + concat > firstlnum) | |
2553 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2554 // 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
|
2555 // 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
|
2556 // 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
|
2557 // 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
|
2558 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
|
2559 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2560 // 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
|
2561 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2562 else if (fp->fd_top >= startlnum) |
7 | 2563 { |
2564 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
|
2565 // like lines are inserted |
7 | 2566 foldMarkAdjustRecurse(&fp->fd_nested, |
2567 (linenr_T)0, (linenr_T)MAXLNUM, | |
2568 (long)(fp->fd_top - firstlnum), 0L); | |
2569 else | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2570 // like lines are deleted |
7 | 2571 foldMarkAdjustRecurse(&fp->fd_nested, |
2572 (linenr_T)0, | |
2573 (long)(firstlnum - fp->fd_top - 1), | |
2574 (linenr_T)MAXLNUM, | |
2575 (long)(fp->fd_top - firstlnum)); | |
2576 fp->fd_len += fp->fd_top - firstlnum; | |
2577 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
|
2578 fp->fd_small = MAYBE; |
7 | 2579 fold_changed = TRUE; |
2580 } | |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2581 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
|
2582 || firstlnum != startlnum) |
7 | 2583 { |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2584 linenr_T breakstart; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2585 linenr_T breakend; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2586 |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2587 /* |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2588 * 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
|
2589 * 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
|
2590 * 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
|
2591 * 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
|
2592 * it. |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2593 * 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
|
2594 * 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
|
2595 * 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
|
2596 * fline->lnum. |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2597 * 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
|
2598 * [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
|
2599 * 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
|
2600 * range. |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2601 * 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
|
2602 */ |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2603 if (firstlnum != startlnum) |
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 breakstart = startlnum; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2606 breakend = firstlnum; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2607 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2608 else |
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 breakstart = flp->lnum; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2611 breakend = flp->lnum; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2612 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2613 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
|
2614 breakend - fp->fd_top); |
7 | 2615 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
|
2616 foldSplit(gap, i, breakstart, breakend - 1); |
7 | 2617 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
|
2618 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2619 // 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
|
2620 // 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
|
2621 // found. |
7 | 2622 if (getlevel == foldlevelMarker |
2623 || getlevel == foldlevelExpr | |
2624 || getlevel == foldlevelSyntax) | |
2625 finish = TRUE; | |
2626 } | |
11038
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2627 |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2628 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
|
2629 { |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2630 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
|
2631 if (i != 0) |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2632 { |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2633 fp2 = fp - 1; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2634 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
|
2635 { |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2636 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
|
2637 fp = fp2; |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2638 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2639 } |
c8b49300c6b7
patch 8.0.0408: updating folds does not always work properly
Christian Brabandt <cb@256bit.org>
parents:
10998
diff
changeset
|
2640 } |
7 | 2641 break; |
2642 } | |
2643 if (fp->fd_top >= startlnum) | |
2644 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2645 // 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
|
2646 // 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
|
2647 // looking for the next one. |
7 | 2648 deleteFoldEntry(gap, |
2649 (int)(fp - (fold_T *)gap->ga_data), TRUE); | |
2650 } | |
2651 else | |
2652 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2653 // 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
|
2654 // to stop just above startlnum. |
7 | 2655 fp->fd_len = startlnum - fp->fd_top; |
2656 foldMarkAdjustRecurse(&fp->fd_nested, | |
27426
41e0dcf38521
patch 8.2.4241: some type casts are redundant
Bram Moolenaar <Bram@vim.org>
parents:
27301
diff
changeset
|
2657 fp->fd_len, (linenr_T)MAXLNUM, |
7 | 2658 (linenr_T)MAXLNUM, 0L); |
2659 fold_changed = TRUE; | |
2660 } | |
2661 } | |
2662 else | |
2663 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2664 // 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
|
2665 // may change! |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2666 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
|
2667 i = 0; |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2668 else |
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2669 i = (int)(fp - (fold_T *)gap->ga_data); |
7 | 2670 if (foldInsert(gap, i) != OK) |
2671 return bot; | |
2672 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
|
2673 // 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
|
2674 // end earlier. |
7 | 2675 fp->fd_top = firstlnum; |
2676 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
|
2677 // 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
|
2678 // 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
|
2679 // The first fold depends on the containing fold. |
7 | 2680 if (topflags == FD_OPEN) |
2681 { | |
2682 flp->wp->w_fold_manual = TRUE; | |
2683 fp->fd_flags = FD_OPEN; | |
2684 } | |
2685 else if (i <= 0) | |
2686 { | |
2687 fp->fd_flags = topflags; | |
2688 if (topflags != FD_LEVEL) | |
2689 flp->wp->w_fold_manual = TRUE; | |
2690 } | |
2691 else | |
2692 fp->fd_flags = (fp - 1)->fd_flags; | |
2693 fp->fd_small = MAYBE; | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2694 // 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
|
2695 // need to continue until the end of the fold is found. |
7 | 2696 if (getlevel == foldlevelMarker |
2697 || getlevel == foldlevelExpr | |
2698 || getlevel == foldlevelSyntax) | |
2699 finish = TRUE; | |
2700 fold_changed = TRUE; | |
2701 break; | |
2702 } | |
2703 } | |
2704 } | |
2705 | |
2706 if (lvl < level || flp->lnum > linecount) | |
2707 { | |
2708 /* | |
2709 * Found a line with a lower foldlevel, this fold ends just above | |
2710 * "flp->lnum". | |
2711 */ | |
2712 break; | |
2713 } | |
2714 | |
2715 /* | |
2716 * The fold includes the line "flp->lnum" and "flp->lnum_save". | |
840 | 2717 * Check "fp" for safety. |
7 | 2718 */ |
840 | 2719 if (lvl > level && fp != NULL) |
7 | 2720 { |
2721 /* | |
2722 * There is a nested fold, handle it recursively. | |
2723 */ | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2724 // At least do one line (can happen when finish is TRUE). |
7 | 2725 if (bot < flp->lnum) |
2726 bot = flp->lnum; | |
2727 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2728 // 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
|
2729 // this fold. |
7 | 2730 flp->lnum = flp->lnum_save - fp->fd_top; |
2731 flp->off += fp->fd_top; | |
2732 i = (int)(fp - (fold_T *)gap->ga_data); | |
2733 bot = foldUpdateIEMSRecurse(&fp->fd_nested, level + 1, | |
2734 startlnum2 - fp->fd_top, flp, getlevel, | |
2735 bot - fp->fd_top, fp->fd_flags); | |
2736 fp = (fold_T *)gap->ga_data + i; | |
2737 flp->lnum += fp->fd_top; | |
2738 flp->lnum_save += fp->fd_top; | |
2739 flp->off -= fp->fd_top; | |
2740 bot += fp->fd_top; | |
2741 startlnum2 = flp->lnum; | |
2742 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2743 // This fold may end at the same line, don't incr. flp->lnum. |
7 | 2744 } |
2745 else | |
2746 { | |
2747 /* | |
2748 * Get the level of the next line, then continue the loop to check | |
2749 * if it ends there. | |
2750 * Skip over undefined lines, to find the foldlevel after it. | |
2751 * For the last line in the file the foldlevel is always valid. | |
2752 */ | |
2753 flp->lnum = flp->lnum_save; | |
2754 ll = flp->lnum + 1; | |
2755 while (!got_int) | |
2756 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2757 // Make the previous level available to foldlevel(). |
7 | 2758 prev_lnum = flp->lnum; |
2759 prev_lnum_lvl = flp->lvl; | |
2760 | |
2761 if (++flp->lnum > linecount) | |
2762 break; | |
2763 flp->lvl = flp->lvl_next; | |
2764 getlevel(flp); | |
2765 if (flp->lvl >= 0 || flp->had_end <= MAX_LEVEL) | |
2766 break; | |
2767 } | |
2768 prev_lnum = 0; | |
2769 if (flp->lnum > linecount) | |
2770 break; | |
2771 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2772 // 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
|
2773 // the level, flp->lnum to the lnum of the next line. |
7 | 2774 flp->lnum_save = flp->lnum; |
2775 flp->lnum = ll; | |
2776 } | |
2777 } | |
2778 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2779 if (fp == NULL) // only happens when got_int is set |
7 | 2780 return bot; |
2781 | |
2782 /* | |
2783 * Get here when: | |
2784 * lvl < level: the folds ends just above "flp->lnum" | |
2785 * lvl >= level: fold continues below "bot" | |
2786 */ | |
2787 | |
17787
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2788 // Current fold at least extends until lnum. |
7 | 2789 if (fp->fd_len < flp->lnum - fp->fd_top) |
2790 { | |
2791 fp->fd_len = flp->lnum - fp->fd_top; | |
1513 | 2792 fp->fd_small = MAYBE; |
7 | 2793 fold_changed = TRUE; |
2794 } | |
17787
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2795 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
|
2796 // 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
|
2797 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
|
2798 |
92e0996e1cb8
patch 8.1.1890: ml_get error when deleting fold marker
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
2799 // 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
|
2800 // we stopped looking. |
7 | 2801 foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top, |
2802 flp->lnum - 1 - fp->fd_top); | |
2803 | |
2804 if (lvl < level) | |
2805 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2806 // End of fold found, update the length when it got shorter. |
7 | 2807 if (fp->fd_len != flp->lnum - fp->fd_top) |
2808 { | |
11234
8c153d400bf4
patch 8.0.0503: endless loop in updating folds with 32 bit ints
Christian Brabandt <cb@256bit.org>
parents:
11165
diff
changeset
|
2809 if (fp->fd_top + fp->fd_len - 1 > bot) |
7 | 2810 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2811 // fold continued below bot |
7 | 2812 if (getlevel == foldlevelMarker |
2813 || getlevel == foldlevelExpr | |
2814 || getlevel == foldlevelSyntax) | |
2815 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2816 // 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
|
2817 // previously included lines are processed again |
7 | 2818 bot = fp->fd_top + fp->fd_len - 1; |
2819 fp->fd_len = flp->lnum - fp->fd_top; | |
2820 } | |
2821 else | |
2822 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2823 // 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
|
2824 // below bot |
7 | 2825 i = (int)(fp - (fold_T *)gap->ga_data); |
2826 foldSplit(gap, i, flp->lnum, bot); | |
2827 fp = (fold_T *)gap->ga_data + i; | |
2828 } | |
2829 } | |
2830 else | |
2831 fp->fd_len = flp->lnum - fp->fd_top; | |
2832 fold_changed = TRUE; | |
2833 } | |
2834 } | |
2835 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2836 // delete following folds that end before the current line |
7 | 2837 for (;;) |
2838 { | |
2839 fp2 = fp + 1; | |
2840 if (fp2 >= (fold_T *)gap->ga_data + gap->ga_len | |
2841 || fp2->fd_top > flp->lnum) | |
2842 break; | |
2843 if (fp2->fd_top + fp2->fd_len > flp->lnum) | |
2844 { | |
2845 if (fp2->fd_top < flp->lnum) | |
2846 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2847 // Make fold that includes lnum start at lnum. |
7 | 2848 foldMarkAdjustRecurse(&fp2->fd_nested, |
2849 (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1), | |
2850 (linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum)); | |
2851 fp2->fd_len -= flp->lnum - fp2->fd_top; | |
2852 fp2->fd_top = flp->lnum; | |
2853 fold_changed = TRUE; | |
2854 } | |
2855 | |
2856 if (lvl >= level) | |
2857 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2858 // merge new fold with existing fold that follows |
7 | 2859 foldMerge(fp, gap, fp2); |
2860 } | |
2861 break; | |
2862 } | |
2863 fold_changed = TRUE; | |
2864 deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE); | |
2865 } | |
2866 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2867 // 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
|
2868 // was asked for. |
7 | 2869 if (bot < flp->lnum - 1) |
2870 bot = flp->lnum - 1; | |
2871 | |
2872 return bot; | |
2873 } | |
2874 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2875 // foldInsert() {{{2 |
7 | 2876 /* |
2877 * Insert a new fold in "gap" at position "i". | |
2878 * Returns OK for success, FAIL for failure. | |
2879 */ | |
2880 static int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2881 foldInsert(garray_T *gap, int i) |
7 | 2882 { |
2883 fold_T *fp; | |
2884 | |
31837
e16361210675
patch 9.0.1251: checking returned value of ga_grow() is inconsistent
Bram Moolenaar <Bram@vim.org>
parents:
31667
diff
changeset
|
2885 if (ga_grow(gap, 1) == FAIL) |
7 | 2886 return FAIL; |
2887 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
|
2888 if (gap->ga_len > 0 && i < gap->ga_len) |
7 | 2889 mch_memmove(fp + 1, fp, sizeof(fold_T) * (gap->ga_len - i)); |
2890 ++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
|
2891 ga_init2(&fp->fd_nested, sizeof(fold_T), 10); |
7 | 2892 return OK; |
2893 } | |
2894 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2895 // foldSplit() {{{2 |
7 | 2896 /* |
2897 * Split the "i"th fold in "gap", which starts before "top" and ends below | |
2898 * "bot" in two pieces, one ending above "top" and the other starting below | |
2899 * "bot". | |
2900 * The caller must first have taken care of any nested folds from "top" to | |
2901 * "bot"! | |
2902 */ | |
2903 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2904 foldSplit( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2905 garray_T *gap, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2906 int i, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2907 linenr_T top, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2908 linenr_T bot) |
7 | 2909 { |
2910 fold_T *fp; | |
2911 fold_T *fp2; | |
2912 garray_T *gap1; | |
2913 garray_T *gap2; | |
2914 int idx; | |
2915 int len; | |
2916 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2917 // The fold continues below bot, need to split it. |
7 | 2918 if (foldInsert(gap, i + 1) == FAIL) |
2919 return; | |
2920 fp = (fold_T *)gap->ga_data + i; | |
2921 fp[1].fd_top = bot + 1; | |
2922 fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top); | |
2923 fp[1].fd_flags = fp->fd_flags; | |
1985 | 2924 fp[1].fd_small = MAYBE; |
2925 fp->fd_small = MAYBE; | |
7 | 2926 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2927 // 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
|
2928 // any between top and bot, they have been removed by the caller. |
7 | 2929 gap1 = &fp->fd_nested; |
2930 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
|
2931 (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
|
2932 if (fp2 != NULL) |
7 | 2933 { |
22021
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2934 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
|
2935 if (len > 0 && ga_grow(gap2, len) == OK) |
7 | 2936 { |
22021
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2937 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
|
2938 { |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2939 ((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
|
2940 ((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
|
2941 -= 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
|
2942 } |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2943 gap2->ga_len = len; |
514d622473af
patch 8.2.1560: using NULL pointers in some code
Bram Moolenaar <Bram@vim.org>
parents:
22009
diff
changeset
|
2944 gap1->ga_len -= len; |
7 | 2945 } |
2946 } | |
2947 fp->fd_len = top - fp->fd_top; | |
2948 fold_changed = TRUE; | |
2949 } | |
2950 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2951 // foldRemove() {{{2 |
7 | 2952 /* |
2953 * Remove folds within the range "top" to and including "bot". | |
2954 * Check for these situations: | |
2955 * 1 2 3 | |
2956 * 1 2 3 | |
2957 * top 2 3 4 5 | |
2958 * 2 3 4 5 | |
2959 * bot 2 3 4 5 | |
2960 * 3 5 6 | |
2961 * 3 5 6 | |
2962 * | |
2963 * 1: not changed | |
1224 | 2964 * 2: truncate to stop above "top" |
7 | 2965 * 3: split in two parts, one stops above "top", other starts below "bot". |
2966 * 4: deleted | |
2967 * 5: made to start below "bot". | |
2968 * 6: not changed | |
2969 */ | |
2970 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
2971 foldRemove(garray_T *gap, linenr_T top, linenr_T bot) |
7 | 2972 { |
2973 fold_T *fp = NULL; | |
2974 | |
2975 if (bot < top) | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2976 return; // nothing to do |
7 | 2977 |
22006
468569085ab2
patch 8.2.1552: warnings from asan with clang-11
Bram Moolenaar <Bram@vim.org>
parents:
20996
diff
changeset
|
2978 while (gap->ga_len > 0) |
7 | 2979 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2980 // Find fold that includes top or a following one. |
7 | 2981 if (foldFind(gap, top, &fp) && fp->fd_top < top) |
2982 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2983 // 2: or 3: need to delete nested folds |
7 | 2984 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
|
2985 if (fp->fd_top + fp->fd_len - 1 > bot) |
7 | 2986 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2987 // 3: need to split it. |
7 | 2988 foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot); |
2989 } | |
2990 else | |
2991 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
2992 // 2: truncate fold at "top". |
7 | 2993 fp->fd_len = top - fp->fd_top; |
2994 } | |
2995 fold_changed = TRUE; | |
2996 continue; | |
2997 } | |
2998 if (fp >= (fold_T *)(gap->ga_data) + gap->ga_len | |
2999 || fp->fd_top > bot) | |
3000 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3001 // 6: Found a fold below bot, can stop looking. |
7 | 3002 break; |
3003 } | |
3004 if (fp->fd_top >= top) | |
3005 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3006 // Found an entry below top. |
7 | 3007 fold_changed = TRUE; |
36 | 3008 if (fp->fd_top + fp->fd_len - 1 > bot) |
7 | 3009 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3010 // 5: Make fold that includes bot start below bot. |
7 | 3011 foldMarkAdjustRecurse(&fp->fd_nested, |
3012 (linenr_T)0, (long)(bot - fp->fd_top), | |
3013 (linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1)); | |
3014 fp->fd_len -= bot - fp->fd_top + 1; | |
3015 fp->fd_top = bot + 1; | |
3016 break; | |
3017 } | |
3018 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3019 // 4: Delete completely contained fold. |
7 | 3020 deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), TRUE); |
3021 } | |
3022 } | |
3023 } | |
3024 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3025 // foldReverseOrder() {{{2 |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3026 static void |
11396
e9924d19ee37
patch 8.0.0583: fold test hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11392
diff
changeset
|
3027 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
|
3028 { |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3029 fold_T *left, *right; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3030 fold_T tmp; |
11396
e9924d19ee37
patch 8.0.0583: fold test hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11392
diff
changeset
|
3031 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
|
3032 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
|
3033 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3034 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
|
3035 { |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3036 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
|
3037 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
|
3038 tmp = *left; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3039 *left = *right; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3040 *right = tmp; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3041 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3042 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3043 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3044 // foldMoveRange() {{{2 |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3045 /* |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3046 * 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
|
3047 * requires "line1" <= "line2" <= "dest" |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3048 * |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3049 * 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
|
3050 * 1 2 3 4 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3051 * 1 2 3 4 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3052 * line1 2 3 4 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3053 * 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
|
3054 * 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
|
3055 * 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
|
3056 * 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
|
3057 * 4 7 8 10 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3058 * 4 7 8 10 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3059 * |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3060 * 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
|
3061 * the fold array. |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3062 * 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
|
3063 * 1. not changed |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3064 * 2. truncated above line1 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3065 * 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
|
3066 * 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
|
3067 * 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
|
3068 * 5. moved to dest. |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3069 * 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
|
3070 * 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
|
3071 * 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
|
3072 * 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
|
3073 * 9. shifted up |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3074 * 10. not changed |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3075 */ |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3076 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3077 static void |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3078 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
|
3079 { |
11156
80241603dd50
patch 8.0.0465: off-by-one error in using :move with folding
Christian Brabandt <cb@256bit.org>
parents:
11148
diff
changeset
|
3080 end += 1; |
11140
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3081 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
|
3082 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
|
3083 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3084 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3085 #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
|
3086 #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
|
3087 #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
|
3088 |
11148
87779062d706
patch 8.0.0461: test 45 hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11140
diff
changeset
|
3089 void |
87779062d706
patch 8.0.0461: test 45 hangs on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11140
diff
changeset
|
3090 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
|
3091 { |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3092 fold_T *fp; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3093 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
|
3094 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
|
3095 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
|
3096 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
|
3097 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3098 if (at_start) |
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 (fold_end(fp) > dest) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3101 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3102 // Case 4 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3103 // 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
|
3104 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
|
3105 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
|
3106 return; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3107 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3108 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
|
3109 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3110 // Case 3 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3111 // 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
|
3112 // 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
|
3113 // 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
|
3114 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
|
3115 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
|
3116 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
|
3117 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3118 else |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3119 // 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
|
3120 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
|
3121 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3122 // 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
|
3123 // 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
|
3124 fp = fp + 1; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3125 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3126 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3127 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
|
3128 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3129 // Case 10 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3130 // 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
|
3131 return; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3132 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3133 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
|
3134 { |
11156
80241603dd50
patch 8.0.0465: off-by-one error in using :move with folding
Christian Brabandt <cb@256bit.org>
parents:
11148
diff
changeset
|
3135 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
|
3136 // 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
|
3137 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
|
3138 |
11156
80241603dd50
patch 8.0.0465: off-by-one error in using :move with folding
Christian Brabandt <cb@256bit.org>
parents:
11148
diff
changeset
|
3139 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
|
3140 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3141 // 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
|
3142 truncate_fold(fp, dest); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3143 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
|
3144 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3145 return; |
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 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
|
3148 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3149 // 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
|
3150 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
|
3151 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
|
3152 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
|
3153 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
|
3154 return; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3155 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3156 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3157 // Case 5 or 6 |
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3158 // 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
|
3159 // 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
|
3160 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
|
3161 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3162 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
|
3163 { |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3164 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
|
3165 { |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3166 // 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
|
3167 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
|
3168 // 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
|
3169 truncate_fold(fp, line2); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3170 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3171 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
|
3172 continue; |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3173 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3174 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3175 // 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
|
3176 if (move_end == 0) |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3177 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
|
3178 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3179 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
|
3180 truncate_fold(fp, dest); |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3181 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3182 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
|
3183 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3184 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3185 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
|
3186 |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3187 /* |
11392
dc2800c3572b
patch 8.0.0581: moving folded text is sometimes not correct
Christian Brabandt <cb@256bit.org>
parents:
11234
diff
changeset
|
3188 * 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
|
3189 * 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
|
3190 * 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
|
3191 */ |
11392
dc2800c3572b
patch 8.0.0581: moving folded text is sometimes not correct
Christian Brabandt <cb@256bit.org>
parents:
11234
diff
changeset
|
3192 if (move_end == 0) |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3193 // 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
|
3194 // 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
|
3195 return; |
11165
f0602688b8ef
patch 8.0.0469: compiler warnings on MS-Windows
Christian Brabandt <cb@256bit.org>
parents:
11156
diff
changeset
|
3196 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
|
3197 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
|
3198 (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
|
3199 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
|
3200 (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
|
3201 } |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3202 #undef fold_end |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3203 #undef valid_fold |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3204 #undef fold_index |
6b26e044b6f5
patch 8.0.0457: using :move messes up manual folds
Christian Brabandt <cb@256bit.org>
parents:
11131
diff
changeset
|
3205 |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3206 // foldMerge() {{{2 |
7 | 3207 /* |
1224 | 3208 * Merge two adjacent folds (and the nested ones in them). |
3209 * This only works correctly when the folds are really adjacent! Thus "fp1" | |
7 | 3210 * must end just above "fp2". |
3211 * The resulting fold is "fp1", nested folds are moved from "fp2" to "fp1". | |
3212 * Fold entry "fp2" in "gap" is deleted. | |
3213 */ | |
3214 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3215 foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2) |
7 | 3216 { |
3217 fold_T *fp3; | |
3218 fold_T *fp4; | |
3219 int idx; | |
3220 garray_T *gap1 = &fp1->fd_nested; | |
3221 garray_T *gap2 = &fp2->fd_nested; | |
3222 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3223 // 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
|
3224 // merge them recursively. |
7 | 3225 if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4)) |
3226 foldMerge(fp3, gap2, fp4); | |
3227 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3228 // Move nested folds in fp2 to the end of fp1. |
7 | 3229 if (gap2->ga_len > 0 && ga_grow(gap1, gap2->ga_len) == OK) |
3230 { | |
3231 for (idx = 0; idx < gap2->ga_len; ++idx) | |
3232 { | |
3233 ((fold_T *)gap1->ga_data)[gap1->ga_len] | |
3234 = ((fold_T *)gap2->ga_data)[idx]; | |
3235 ((fold_T *)gap1->ga_data)[gap1->ga_len].fd_top += fp1->fd_len; | |
3236 ++gap1->ga_len; | |
3237 } | |
3238 gap2->ga_len = 0; | |
3239 } | |
3240 | |
3241 fp1->fd_len += fp2->fd_len; | |
3242 deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE); | |
3243 fold_changed = TRUE; | |
3244 } | |
3245 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3246 // foldlevelIndent() {{{2 |
7 | 3247 /* |
3248 * Low level function to get the foldlevel for the "indent" method. | |
3249 * Doesn't use any caching. | |
3250 * Returns a level of -1 if the foldlevel depends on surrounding lines. | |
3251 */ | |
3252 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3253 foldlevelIndent(fline_T *flp) |
7 | 3254 { |
3255 char_u *s; | |
3256 buf_T *buf; | |
3257 linenr_T lnum = flp->lnum + flp->off; | |
3258 | |
3259 buf = flp->wp->w_buffer; | |
3260 s = skipwhite(ml_get_buf(buf, lnum, FALSE)); | |
3261 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3262 // 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
|
3263 // depends on surrounding lines |
7 | 3264 if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) |
3265 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3266 // first and last line can't be undefined, use level 0 |
7 | 3267 if (lnum == 1 || lnum == buf->b_ml.ml_line_count) |
3268 flp->lvl = 0; | |
3269 else | |
3270 flp->lvl = -1; | |
3271 } | |
3272 else | |
15031
03831e5ea0de
patch 8.1.0527: using 'shiftwidth' from wrong buffer for folding
Bram Moolenaar <Bram@vim.org>
parents:
12477
diff
changeset
|
3273 flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(buf); |
7 | 3274 if (flp->lvl > flp->wp->w_p_fdn) |
1028 | 3275 { |
7 | 3276 flp->lvl = flp->wp->w_p_fdn; |
1028 | 3277 if (flp->lvl < 0) |
3278 flp->lvl = 0; | |
3279 } | |
7 | 3280 } |
3281 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3282 // foldlevelDiff() {{{2 |
7 | 3283 #ifdef FEAT_DIFF |
3284 /* | |
3285 * Low level function to get the foldlevel for the "diff" method. | |
3286 * Doesn't use any caching. | |
3287 */ | |
3288 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3289 foldlevelDiff(fline_T *flp) |
7 | 3290 { |
3291 if (diff_infold(flp->wp, flp->lnum + flp->off)) | |
3292 flp->lvl = 1; | |
3293 else | |
3294 flp->lvl = 0; | |
3295 } | |
3296 #endif | |
3297 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3298 // foldlevelExpr() {{{2 |
7 | 3299 /* |
3300 * Low level function to get the foldlevel for the "expr" method. | |
3301 * Doesn't use any caching. | |
3302 * Returns a level of -1 if the foldlevel depends on surrounding lines. | |
3303 */ | |
3304 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7807
diff
changeset
|
3305 foldlevelExpr(fline_T *flp) |
7 | 3306 { |
3307 #ifndef FEAT_EVAL | |
3308 flp->start = FALSE; | |
3309 flp->lvl = 0; | |
3310 #else | |
3311 win_T *win; | |
3312 int n; | |
3313 int c; | |
3314 linenr_T lnum = flp->lnum + flp->off; | |
3315 int save_keytyped; | |
3316 | |
3317 win = curwin; | |
3318 curwin = flp->wp; | |
3319 curbuf = flp->wp->w_buffer; | |
3320 set_vim_var_nr(VV_LNUM, lnum); | |
3321 | |
3322 flp->start = 0; | |
3323 flp->had_end = flp->end; | |
3324 flp->end = MAX_LEVEL + 1; | |
3325 if (lnum <= 1) | |
3326 flp->lvl = 0; | |
3327 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3328 // 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
|
3329 // do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. |
7 | 3330 save_keytyped = KeyTyped; |
27289
e11682ba8c80
patch 8.2.4173: cannot use an import in 'foldexpr'
Bram Moolenaar <Bram@vim.org>
parents:
27028
diff
changeset
|
3331 n = eval_foldexpr(flp->wp, &c); |
7 | 3332 KeyTyped = save_keytyped; |
3333 | |
3334 switch (c) | |
3335 { | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3336 // "a1", "a2", .. : add to the fold level |
7 | 3337 case 'a': if (flp->lvl >= 0) |
3338 { | |
3339 flp->lvl += n; | |
3340 flp->lvl_next = flp->lvl; | |
3341 } | |
3342 flp->start = n; | |
3343 break; | |
3344 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3345 // "s1", "s2", .. : subtract from the fold level |
7 | 3346 case 's': if (flp->lvl >= 0) |
3347 { | |
3348 if (n > flp->lvl) | |
3349 flp->lvl_next = 0; | |
3350 else | |
3351 flp->lvl_next = flp->lvl - n; | |
3352 flp->end = flp->lvl_next + 1; | |
3353 } | |
3354 break; | |
3355 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3356 // ">1", ">2", .. : start a fold with a certain level |
7 | 3357 case '>': flp->lvl = n; |
3358 flp->lvl_next = n; | |
3359 flp->start = 1; | |
3360 break; | |
3361 | |
18779
8f05b3cf8557
patch 8.1.2379: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18203
diff
changeset
|
3362 // "<1", "<2", .. : end a fold with a certain level |
34065
48955338edb1
patch 9.1.0002: a closing fold expr, may start a new fold
Christian Brabandt <cb@256bit.org>
parents:
31837
diff
changeset
|
3363 case '<': // To prevent an unexpected start of a new fold, the next |
48955338edb1
patch 9.1.0002: a closing fold expr, may start a new fold
Christian Brabandt <cb@256bit.org>
parents:
31837
diff
changeset
|
3364 // level must not exceed the level of the current fold. |
48955338edb1
patch 9.1.0002: a closing fold expr, may start a new fold
Christian Brabandt <cb@256bit.org>
parents:
31837
diff
changeset
|
3365 flp->lvl_next = MIN(flp->lvl, n - 1); |
7 | 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 |