1edf3f97aSBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet:
2071d4279SBram Moolenaar *
3071d4279SBram Moolenaar * VIM - Vi IMproved by Bram Moolenaar
4071d4279SBram Moolenaar *
5071d4279SBram Moolenaar * Do ":help uganda" in Vim to read copying and usage conditions.
6071d4279SBram Moolenaar * Do ":help credits" in Vim to see a list of people who contributed.
7071d4279SBram Moolenaar * See README.txt for an overview of the Vim source code.
8071d4279SBram Moolenaar */
9071d4279SBram Moolenaar
10071d4279SBram Moolenaar /*
11071d4279SBram Moolenaar * mark.c: functions for setting marks and jumping to them
12071d4279SBram Moolenaar */
13071d4279SBram Moolenaar
14071d4279SBram Moolenaar #include "vim.h"
15071d4279SBram Moolenaar
16071d4279SBram Moolenaar /*
17071d4279SBram Moolenaar * This file contains routines to maintain and manipulate marks.
18071d4279SBram Moolenaar */
19071d4279SBram Moolenaar
20071d4279SBram Moolenaar /*
21071d4279SBram Moolenaar * If a named file mark's lnum is non-zero, it is valid.
22071d4279SBram Moolenaar * If a named file mark's fnum is non-zero, it is for an existing buffer,
23071d4279SBram Moolenaar * otherwise it is from .viminfo and namedfm[n].fname is the file name.
24071d4279SBram Moolenaar * There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing
25071d4279SBram Moolenaar * viminfo).
26071d4279SBram Moolenaar */
274ba37b58SBram Moolenaar static xfmark_T namedfm[NMARKS + EXTRA_MARKS]; // marks with file nr
28071d4279SBram Moolenaar
295843f5f3SBram Moolenaar static void fname2fnum(xfmark_T *fm);
3092b8b2d3SBram Moolenaar static void fmarks_check_one(xfmark_T *fm, char_u *name, buf_T *buf);
3192b8b2d3SBram Moolenaar static char_u *mark_line(pos_T *mp, int lead_len);
3292b8b2d3SBram Moolenaar static void show_one_mark(int, char_u *, pos_T *, char_u *, int current);
3388d298aeSBram Moolenaar static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount,
3488d298aeSBram Moolenaar long amount_after, int adjust_folds);
35071d4279SBram Moolenaar
36071d4279SBram Moolenaar /*
37bfb2d40bSBram Moolenaar * Set named mark "c" at current cursor position.
38071d4279SBram Moolenaar * Returns OK on success, FAIL if bad name given.
39071d4279SBram Moolenaar */
40071d4279SBram Moolenaar int
setmark(int c)4152ea13daSBram Moolenaar setmark(int c)
42071d4279SBram Moolenaar {
43bfb2d40bSBram Moolenaar return setmark_pos(c, &curwin->w_cursor, curbuf->b_fnum);
44bfb2d40bSBram Moolenaar }
45bfb2d40bSBram Moolenaar
46bfb2d40bSBram Moolenaar /*
47bfb2d40bSBram Moolenaar * Set named mark "c" to position "pos".
48bfb2d40bSBram Moolenaar * When "c" is upper case use file "fnum".
49bfb2d40bSBram Moolenaar * Returns OK on success, FAIL if bad name given.
50bfb2d40bSBram Moolenaar */
51bfb2d40bSBram Moolenaar int
setmark_pos(int c,pos_T * pos,int fnum)5252ea13daSBram Moolenaar setmark_pos(int c, pos_T *pos, int fnum)
53bfb2d40bSBram Moolenaar {
54071d4279SBram Moolenaar int i;
55f13e00b2SBram Moolenaar buf_T *buf;
56071d4279SBram Moolenaar
574ba37b58SBram Moolenaar // Check for a special key (may cause islower() to crash).
58071d4279SBram Moolenaar if (c < 0)
59071d4279SBram Moolenaar return FAIL;
60071d4279SBram Moolenaar
61071d4279SBram Moolenaar if (c == '\'' || c == '`')
62071d4279SBram Moolenaar {
63bfb2d40bSBram Moolenaar if (pos == &curwin->w_cursor)
64bfb2d40bSBram Moolenaar {
65071d4279SBram Moolenaar setpcmark();
664ba37b58SBram Moolenaar // keep it even when the cursor doesn't move
67071d4279SBram Moolenaar curwin->w_prev_pcmark = curwin->w_pcmark;
68bfb2d40bSBram Moolenaar }
69bfb2d40bSBram Moolenaar else
70bfb2d40bSBram Moolenaar curwin->w_pcmark = *pos;
71071d4279SBram Moolenaar return OK;
72071d4279SBram Moolenaar }
73071d4279SBram Moolenaar
74f13e00b2SBram Moolenaar buf = buflist_findnr(fnum);
75f13e00b2SBram Moolenaar if (buf == NULL)
76f13e00b2SBram Moolenaar return FAIL;
77f13e00b2SBram Moolenaar
7808250430SBram Moolenaar if (c == '"')
7908250430SBram Moolenaar {
80f13e00b2SBram Moolenaar buf->b_last_cursor = *pos;
8108250430SBram Moolenaar return OK;
8208250430SBram Moolenaar }
8308250430SBram Moolenaar
844ba37b58SBram Moolenaar // Allow setting '[ and '] for an autocommand that simulates reading a
854ba37b58SBram Moolenaar // file.
86071d4279SBram Moolenaar if (c == '[')
87071d4279SBram Moolenaar {
88f13e00b2SBram Moolenaar buf->b_op_start = *pos;
89071d4279SBram Moolenaar return OK;
90071d4279SBram Moolenaar }
91071d4279SBram Moolenaar if (c == ']')
92071d4279SBram Moolenaar {
93f13e00b2SBram Moolenaar buf->b_op_end = *pos;
94071d4279SBram Moolenaar return OK;
95071d4279SBram Moolenaar }
96071d4279SBram Moolenaar
97bc88a275SBram Moolenaar if (c == '<' || c == '>')
98bc88a275SBram Moolenaar {
990306ac33SBram Moolenaar if (c == '<')
100f13e00b2SBram Moolenaar buf->b_visual.vi_start = *pos;
101bc88a275SBram Moolenaar else
102f13e00b2SBram Moolenaar buf->b_visual.vi_end = *pos;
103f13e00b2SBram Moolenaar if (buf->b_visual.vi_mode == NUL)
1044ba37b58SBram Moolenaar // Visual_mode has not yet been set, use a sane default.
105f13e00b2SBram Moolenaar buf->b_visual.vi_mode = 'v';
1060306ac33SBram Moolenaar return OK;
1070306ac33SBram Moolenaar }
1080306ac33SBram Moolenaar
1092d358997SBram Moolenaar if (ASCII_ISLOWER(c))
110071d4279SBram Moolenaar {
111071d4279SBram Moolenaar i = c - 'a';
112f13e00b2SBram Moolenaar buf->b_namedm[i] = *pos;
113071d4279SBram Moolenaar return OK;
114071d4279SBram Moolenaar }
1152d358997SBram Moolenaar if (ASCII_ISUPPER(c) || VIM_ISDIGIT(c))
116071d4279SBram Moolenaar {
1172d358997SBram Moolenaar if (VIM_ISDIGIT(c))
1182d358997SBram Moolenaar i = c - '0' + NMARKS;
1192d358997SBram Moolenaar else
120071d4279SBram Moolenaar i = c - 'A';
121bfb2d40bSBram Moolenaar namedfm[i].fmark.mark = *pos;
122bfb2d40bSBram Moolenaar namedfm[i].fmark.fnum = fnum;
123d23a8236SBram Moolenaar VIM_CLEAR(namedfm[i].fname);
1242d358997SBram Moolenaar #ifdef FEAT_VIMINFO
1252d358997SBram Moolenaar namedfm[i].time_set = vim_time();
1262d358997SBram Moolenaar #endif
127071d4279SBram Moolenaar return OK;
128071d4279SBram Moolenaar }
129071d4279SBram Moolenaar return FAIL;
130071d4279SBram Moolenaar }
131071d4279SBram Moolenaar
132071d4279SBram Moolenaar /*
133071d4279SBram Moolenaar * Set the previous context mark to the current position and add it to the
134071d4279SBram Moolenaar * jump list.
135071d4279SBram Moolenaar */
136071d4279SBram Moolenaar void
setpcmark(void)13752ea13daSBram Moolenaar setpcmark(void)
138071d4279SBram Moolenaar {
139071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
140071d4279SBram Moolenaar int i;
141071d4279SBram Moolenaar xfmark_T *fm;
142071d4279SBram Moolenaar #endif
143071d4279SBram Moolenaar
1444ba37b58SBram Moolenaar // for :global the mark is set only once
145e1004401SBram Moolenaar if (global_busy || listcmd_busy || (cmdmod.cmod_flags & CMOD_KEEPJUMPS))
146071d4279SBram Moolenaar return;
147071d4279SBram Moolenaar
148071d4279SBram Moolenaar curwin->w_prev_pcmark = curwin->w_pcmark;
149071d4279SBram Moolenaar curwin->w_pcmark = curwin->w_cursor;
150071d4279SBram Moolenaar
151071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
1524ba37b58SBram Moolenaar // If jumplist is full: remove oldest entry
153071d4279SBram Moolenaar if (++curwin->w_jumplistlen > JUMPLISTSIZE)
154071d4279SBram Moolenaar {
155071d4279SBram Moolenaar curwin->w_jumplistlen = JUMPLISTSIZE;
156071d4279SBram Moolenaar vim_free(curwin->w_jumplist[0].fname);
157071d4279SBram Moolenaar for (i = 1; i < JUMPLISTSIZE; ++i)
158071d4279SBram Moolenaar curwin->w_jumplist[i - 1] = curwin->w_jumplist[i];
159071d4279SBram Moolenaar }
160071d4279SBram Moolenaar curwin->w_jumplistidx = curwin->w_jumplistlen;
161071d4279SBram Moolenaar fm = &curwin->w_jumplist[curwin->w_jumplistlen - 1];
162071d4279SBram Moolenaar
163071d4279SBram Moolenaar fm->fmark.mark = curwin->w_pcmark;
164071d4279SBram Moolenaar fm->fmark.fnum = curbuf->b_fnum;
165071d4279SBram Moolenaar fm->fname = NULL;
1662d358997SBram Moolenaar # ifdef FEAT_VIMINFO
1672d358997SBram Moolenaar fm->time_set = vim_time();
1682d358997SBram Moolenaar # endif
169071d4279SBram Moolenaar #endif
170071d4279SBram Moolenaar }
171071d4279SBram Moolenaar
172071d4279SBram Moolenaar /*
173071d4279SBram Moolenaar * To change context, call setpcmark(), then move the current position to
174071d4279SBram Moolenaar * where ever, then call checkpcmark(). This ensures that the previous
175071d4279SBram Moolenaar * context will only be changed if the cursor moved to a different line.
176071d4279SBram Moolenaar * If pcmark was deleted (with "dG") the previous mark is restored.
177071d4279SBram Moolenaar */
178071d4279SBram Moolenaar void
checkpcmark(void)17952ea13daSBram Moolenaar checkpcmark(void)
180071d4279SBram Moolenaar {
181071d4279SBram Moolenaar if (curwin->w_prev_pcmark.lnum != 0
182b5aedf3eSBram Moolenaar && (EQUAL_POS(curwin->w_pcmark, curwin->w_cursor)
183071d4279SBram Moolenaar || curwin->w_pcmark.lnum == 0))
184071d4279SBram Moolenaar curwin->w_pcmark = curwin->w_prev_pcmark;
185*e08aee60SBram Moolenaar curwin->w_prev_pcmark.lnum = 0; // it has been checked
186071d4279SBram Moolenaar }
187071d4279SBram Moolenaar
188071d4279SBram Moolenaar #if defined(FEAT_JUMPLIST) || defined(PROTO)
189071d4279SBram Moolenaar /*
190071d4279SBram Moolenaar * move "count" positions in the jump list (count may be negative)
191071d4279SBram Moolenaar */
192071d4279SBram Moolenaar pos_T *
movemark(int count)19352ea13daSBram Moolenaar movemark(int count)
194071d4279SBram Moolenaar {
195071d4279SBram Moolenaar pos_T *pos;
196071d4279SBram Moolenaar xfmark_T *jmp;
197071d4279SBram Moolenaar
19848679741SBram Moolenaar cleanup_jumplist(curwin, TRUE);
199071d4279SBram Moolenaar
2004ba37b58SBram Moolenaar if (curwin->w_jumplistlen == 0) // nothing to jump to
201071d4279SBram Moolenaar return (pos_T *)NULL;
202071d4279SBram Moolenaar
203071d4279SBram Moolenaar for (;;)
204071d4279SBram Moolenaar {
205071d4279SBram Moolenaar if (curwin->w_jumplistidx + count < 0
206071d4279SBram Moolenaar || curwin->w_jumplistidx + count >= curwin->w_jumplistlen)
207071d4279SBram Moolenaar return (pos_T *)NULL;
208071d4279SBram Moolenaar
209071d4279SBram Moolenaar /*
210071d4279SBram Moolenaar * if first CTRL-O or CTRL-I command after a jump, add cursor position
211f711faf0SBram Moolenaar * to list. Careful: If there are duplicates (CTRL-O immediately after
212071d4279SBram Moolenaar * starting Vim on a file), another entry may have been removed.
213071d4279SBram Moolenaar */
214071d4279SBram Moolenaar if (curwin->w_jumplistidx == curwin->w_jumplistlen)
215071d4279SBram Moolenaar {
216071d4279SBram Moolenaar setpcmark();
2174ba37b58SBram Moolenaar --curwin->w_jumplistidx; // skip the new entry
218071d4279SBram Moolenaar if (curwin->w_jumplistidx + count < 0)
219071d4279SBram Moolenaar return (pos_T *)NULL;
220071d4279SBram Moolenaar }
221071d4279SBram Moolenaar
222071d4279SBram Moolenaar curwin->w_jumplistidx += count;
223071d4279SBram Moolenaar
224071d4279SBram Moolenaar jmp = curwin->w_jumplist + curwin->w_jumplistidx;
225071d4279SBram Moolenaar if (jmp->fmark.fnum == 0)
226071d4279SBram Moolenaar fname2fnum(jmp);
227071d4279SBram Moolenaar if (jmp->fmark.fnum != curbuf->b_fnum)
228071d4279SBram Moolenaar {
2294ba37b58SBram Moolenaar // jump to other file
230071d4279SBram Moolenaar if (buflist_findnr(jmp->fmark.fnum) == NULL)
2314ba37b58SBram Moolenaar { // Skip this one ..
232071d4279SBram Moolenaar count += count < 0 ? -1 : 1;
233071d4279SBram Moolenaar continue;
234071d4279SBram Moolenaar }
235071d4279SBram Moolenaar if (buflist_getfile(jmp->fmark.fnum, jmp->fmark.mark.lnum,
236071d4279SBram Moolenaar 0, FALSE) == FAIL)
237071d4279SBram Moolenaar return (pos_T *)NULL;
2384ba37b58SBram Moolenaar // Set lnum again, autocommands my have changed it
239071d4279SBram Moolenaar curwin->w_cursor = jmp->fmark.mark;
240071d4279SBram Moolenaar pos = (pos_T *)-1;
241071d4279SBram Moolenaar }
242071d4279SBram Moolenaar else
243071d4279SBram Moolenaar pos = &(jmp->fmark.mark);
244071d4279SBram Moolenaar return pos;
245071d4279SBram Moolenaar }
246071d4279SBram Moolenaar }
247071d4279SBram Moolenaar
248071d4279SBram Moolenaar /*
249071d4279SBram Moolenaar * Move "count" positions in the changelist (count may be negative).
250071d4279SBram Moolenaar */
251071d4279SBram Moolenaar pos_T *
movechangelist(int count)25252ea13daSBram Moolenaar movechangelist(int count)
253071d4279SBram Moolenaar {
254071d4279SBram Moolenaar int n;
255071d4279SBram Moolenaar
2564ba37b58SBram Moolenaar if (curbuf->b_changelistlen == 0) // nothing to jump to
257071d4279SBram Moolenaar return (pos_T *)NULL;
258071d4279SBram Moolenaar
259071d4279SBram Moolenaar n = curwin->w_changelistidx;
260071d4279SBram Moolenaar if (n + count < 0)
261071d4279SBram Moolenaar {
262071d4279SBram Moolenaar if (n == 0)
263071d4279SBram Moolenaar return (pos_T *)NULL;
264071d4279SBram Moolenaar n = 0;
265071d4279SBram Moolenaar }
266071d4279SBram Moolenaar else if (n + count >= curbuf->b_changelistlen)
267071d4279SBram Moolenaar {
268071d4279SBram Moolenaar if (n == curbuf->b_changelistlen - 1)
269071d4279SBram Moolenaar return (pos_T *)NULL;
270071d4279SBram Moolenaar n = curbuf->b_changelistlen - 1;
271071d4279SBram Moolenaar }
272071d4279SBram Moolenaar else
273071d4279SBram Moolenaar n += count;
274071d4279SBram Moolenaar curwin->w_changelistidx = n;
275071d4279SBram Moolenaar return curbuf->b_changelist + n;
276071d4279SBram Moolenaar }
277071d4279SBram Moolenaar #endif
278071d4279SBram Moolenaar
279071d4279SBram Moolenaar /*
2809d182dd0SBram Moolenaar * Find mark "c" in buffer pointed to by "buf".
281bfb2d40bSBram Moolenaar * If "changefile" is TRUE it's allowed to edit another file for '0, 'A, etc.
282bfb2d40bSBram Moolenaar * If "fnum" is not NULL store the fnum there for '0, 'A etc., don't edit
283bfb2d40bSBram Moolenaar * another file.
284071d4279SBram Moolenaar * Returns:
285071d4279SBram Moolenaar * - pointer to pos_T if found. lnum is 0 when mark not set, -1 when mark is
286071d4279SBram Moolenaar * in another file which can't be gotten. (caller needs to check lnum!)
287071d4279SBram Moolenaar * - NULL if there is no mark called 'c'.
288071d4279SBram Moolenaar * - -1 if mark is in other file and jumped there (only if changefile is TRUE)
289071d4279SBram Moolenaar */
290071d4279SBram Moolenaar pos_T *
getmark_buf(buf_T * buf,int c,int changefile)29152ea13daSBram Moolenaar getmark_buf(buf_T *buf, int c, int changefile)
2929d182dd0SBram Moolenaar {
2939d182dd0SBram Moolenaar return getmark_buf_fnum(buf, c, changefile, NULL);
2949d182dd0SBram Moolenaar }
2959d182dd0SBram Moolenaar
2969d182dd0SBram Moolenaar pos_T *
getmark(int c,int changefile)29752ea13daSBram Moolenaar getmark(int c, int changefile)
298bfb2d40bSBram Moolenaar {
2999d182dd0SBram Moolenaar return getmark_buf_fnum(curbuf, c, changefile, NULL);
300bfb2d40bSBram Moolenaar }
301bfb2d40bSBram Moolenaar
302bfb2d40bSBram Moolenaar pos_T *
getmark_buf_fnum(buf_T * buf,int c,int changefile,int * fnum)30352ea13daSBram Moolenaar getmark_buf_fnum(
30452ea13daSBram Moolenaar buf_T *buf,
30552ea13daSBram Moolenaar int c,
30652ea13daSBram Moolenaar int changefile,
30752ea13daSBram Moolenaar int *fnum)
308071d4279SBram Moolenaar {
309071d4279SBram Moolenaar pos_T *posp;
310071d4279SBram Moolenaar pos_T *startp, *endp;
311071d4279SBram Moolenaar static pos_T pos_copy;
312071d4279SBram Moolenaar
313071d4279SBram Moolenaar posp = NULL;
314071d4279SBram Moolenaar
3154ba37b58SBram Moolenaar // Check for special key, can't be a mark name and might cause islower()
3164ba37b58SBram Moolenaar // to crash.
317071d4279SBram Moolenaar if (c < 0)
318071d4279SBram Moolenaar return posp;
319071d4279SBram Moolenaar #ifndef EBCDIC
3204ba37b58SBram Moolenaar if (c > '~') // check for islower()/isupper()
321071d4279SBram Moolenaar ;
322071d4279SBram Moolenaar else
323071d4279SBram Moolenaar #endif
3244ba37b58SBram Moolenaar if (c == '\'' || c == '`') // previous context mark
325071d4279SBram Moolenaar {
3264ba37b58SBram Moolenaar pos_copy = curwin->w_pcmark; // need to make a copy because
3274ba37b58SBram Moolenaar posp = &pos_copy; // w_pcmark may be changed soon
328071d4279SBram Moolenaar }
3294ba37b58SBram Moolenaar else if (c == '"') // to pos when leaving buffer
3309d182dd0SBram Moolenaar posp = &(buf->b_last_cursor);
3314ba37b58SBram Moolenaar else if (c == '^') // to where Insert mode stopped
3329d182dd0SBram Moolenaar posp = &(buf->b_last_insert);
3334ba37b58SBram Moolenaar else if (c == '.') // to where last change was made
3349d182dd0SBram Moolenaar posp = &(buf->b_last_change);
3354ba37b58SBram Moolenaar else if (c == '[') // to start of previous operator
3369d182dd0SBram Moolenaar posp = &(buf->b_op_start);
3374ba37b58SBram Moolenaar else if (c == ']') // to end of previous operator
3389d182dd0SBram Moolenaar posp = &(buf->b_op_end);
3394ba37b58SBram Moolenaar else if (c == '{' || c == '}') // to previous/next paragraph
340071d4279SBram Moolenaar {
341071d4279SBram Moolenaar pos_T pos;
342071d4279SBram Moolenaar oparg_T oa;
343071d4279SBram Moolenaar int slcb = listcmd_busy;
344071d4279SBram Moolenaar
345071d4279SBram Moolenaar pos = curwin->w_cursor;
3464ba37b58SBram Moolenaar listcmd_busy = TRUE; // avoid that '' is changed
3478b96d64cSBram Moolenaar if (findpar(&oa.inclusive,
3488b96d64cSBram Moolenaar c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE))
349071d4279SBram Moolenaar {
350071d4279SBram Moolenaar pos_copy = curwin->w_cursor;
351071d4279SBram Moolenaar posp = &pos_copy;
352071d4279SBram Moolenaar }
353071d4279SBram Moolenaar curwin->w_cursor = pos;
354071d4279SBram Moolenaar listcmd_busy = slcb;
355071d4279SBram Moolenaar }
3564ba37b58SBram Moolenaar else if (c == '(' || c == ')') // to previous/next sentence
357071d4279SBram Moolenaar {
358071d4279SBram Moolenaar pos_T pos;
359071d4279SBram Moolenaar int slcb = listcmd_busy;
360071d4279SBram Moolenaar
361071d4279SBram Moolenaar pos = curwin->w_cursor;
3624ba37b58SBram Moolenaar listcmd_busy = TRUE; // avoid that '' is changed
363071d4279SBram Moolenaar if (findsent(c == ')' ? FORWARD : BACKWARD, 1L))
364071d4279SBram Moolenaar {
365071d4279SBram Moolenaar pos_copy = curwin->w_cursor;
366071d4279SBram Moolenaar posp = &pos_copy;
367071d4279SBram Moolenaar }
368071d4279SBram Moolenaar curwin->w_cursor = pos;
369071d4279SBram Moolenaar listcmd_busy = slcb;
370071d4279SBram Moolenaar }
3714ba37b58SBram Moolenaar else if (c == '<' || c == '>') // start/end of visual area
372071d4279SBram Moolenaar {
3739d182dd0SBram Moolenaar startp = &buf->b_visual.vi_start;
3749d182dd0SBram Moolenaar endp = &buf->b_visual.vi_end;
375b5aedf3eSBram Moolenaar if (((c == '<') == LT_POS(*startp, *endp) || endp->lnum == 0)
376f13e00b2SBram Moolenaar && startp->lnum != 0)
377071d4279SBram Moolenaar posp = startp;
378071d4279SBram Moolenaar else
379071d4279SBram Moolenaar posp = endp;
380071d4279SBram Moolenaar /*
381071d4279SBram Moolenaar * For Visual line mode, set mark at begin or end of line
382071d4279SBram Moolenaar */
3839d182dd0SBram Moolenaar if (buf->b_visual.vi_mode == 'V')
384071d4279SBram Moolenaar {
385071d4279SBram Moolenaar pos_copy = *posp;
386071d4279SBram Moolenaar posp = &pos_copy;
387071d4279SBram Moolenaar if (c == '<')
388071d4279SBram Moolenaar pos_copy.col = 0;
389071d4279SBram Moolenaar else
390071d4279SBram Moolenaar pos_copy.col = MAXCOL;
391071d4279SBram Moolenaar pos_copy.coladd = 0;
392071d4279SBram Moolenaar }
393071d4279SBram Moolenaar }
3944ba37b58SBram Moolenaar else if (ASCII_ISLOWER(c)) // normal named mark
395071d4279SBram Moolenaar {
3969d182dd0SBram Moolenaar posp = &(buf->b_namedm[c - 'a']);
397071d4279SBram Moolenaar }
3984ba37b58SBram Moolenaar else if (ASCII_ISUPPER(c) || VIM_ISDIGIT(c)) // named file mark
399071d4279SBram Moolenaar {
400071d4279SBram Moolenaar if (VIM_ISDIGIT(c))
401071d4279SBram Moolenaar c = c - '0' + NMARKS;
402071d4279SBram Moolenaar else
403071d4279SBram Moolenaar c -= 'A';
404071d4279SBram Moolenaar posp = &(namedfm[c].fmark.mark);
405071d4279SBram Moolenaar
406071d4279SBram Moolenaar if (namedfm[c].fmark.fnum == 0)
407071d4279SBram Moolenaar fname2fnum(&namedfm[c]);
408bfb2d40bSBram Moolenaar
409bfb2d40bSBram Moolenaar if (fnum != NULL)
410bfb2d40bSBram Moolenaar *fnum = namedfm[c].fmark.fnum;
4119d182dd0SBram Moolenaar else if (namedfm[c].fmark.fnum != buf->b_fnum)
412071d4279SBram Moolenaar {
4134ba37b58SBram Moolenaar // mark is in another file
414071d4279SBram Moolenaar posp = &pos_copy;
415071d4279SBram Moolenaar
416071d4279SBram Moolenaar if (namedfm[c].fmark.mark.lnum != 0
417071d4279SBram Moolenaar && changefile && namedfm[c].fmark.fnum)
418071d4279SBram Moolenaar {
419071d4279SBram Moolenaar if (buflist_getfile(namedfm[c].fmark.fnum,
420071d4279SBram Moolenaar (linenr_T)1, GETF_SETMARK, FALSE) == OK)
421071d4279SBram Moolenaar {
4224ba37b58SBram Moolenaar // Set the lnum now, autocommands could have changed it
423071d4279SBram Moolenaar curwin->w_cursor = namedfm[c].fmark.mark;
424071d4279SBram Moolenaar return (pos_T *)-1;
425071d4279SBram Moolenaar }
4264ba37b58SBram Moolenaar pos_copy.lnum = -1; // can't get file
427071d4279SBram Moolenaar }
428071d4279SBram Moolenaar else
4294ba37b58SBram Moolenaar pos_copy.lnum = 0; // mark exists, but is not valid in
4304ba37b58SBram Moolenaar // current buffer
431071d4279SBram Moolenaar }
432071d4279SBram Moolenaar }
433071d4279SBram Moolenaar
434071d4279SBram Moolenaar return posp;
435071d4279SBram Moolenaar }
436071d4279SBram Moolenaar
437071d4279SBram Moolenaar /*
438071d4279SBram Moolenaar * Search for the next named mark in the current file.
439071d4279SBram Moolenaar *
440071d4279SBram Moolenaar * Returns pointer to pos_T of the next mark or NULL if no mark is found.
441071d4279SBram Moolenaar */
442071d4279SBram Moolenaar pos_T *
getnextmark(pos_T * startpos,int dir,int begin_line)44352ea13daSBram Moolenaar getnextmark(
4444ba37b58SBram Moolenaar pos_T *startpos, // where to start
4454ba37b58SBram Moolenaar int dir, // direction for search
44652ea13daSBram Moolenaar int begin_line)
447071d4279SBram Moolenaar {
448071d4279SBram Moolenaar int i;
449071d4279SBram Moolenaar pos_T *result = NULL;
450071d4279SBram Moolenaar pos_T pos;
451071d4279SBram Moolenaar
452071d4279SBram Moolenaar pos = *startpos;
453071d4279SBram Moolenaar
4544ba37b58SBram Moolenaar // When searching backward and leaving the cursor on the first non-blank,
4554ba37b58SBram Moolenaar // position must be in a previous line.
4564ba37b58SBram Moolenaar // When searching forward and leaving the cursor on the first non-blank,
4574ba37b58SBram Moolenaar // position must be in a next line.
458071d4279SBram Moolenaar if (dir == BACKWARD && begin_line)
459071d4279SBram Moolenaar pos.col = 0;
460071d4279SBram Moolenaar else if (dir == FORWARD && begin_line)
461071d4279SBram Moolenaar pos.col = MAXCOL;
462071d4279SBram Moolenaar
463071d4279SBram Moolenaar for (i = 0; i < NMARKS; i++)
464071d4279SBram Moolenaar {
465071d4279SBram Moolenaar if (curbuf->b_namedm[i].lnum > 0)
466071d4279SBram Moolenaar {
467071d4279SBram Moolenaar if (dir == FORWARD)
468071d4279SBram Moolenaar {
469b5aedf3eSBram Moolenaar if ((result == NULL || LT_POS(curbuf->b_namedm[i], *result))
470b5aedf3eSBram Moolenaar && LT_POS(pos, curbuf->b_namedm[i]))
471071d4279SBram Moolenaar result = &curbuf->b_namedm[i];
472071d4279SBram Moolenaar }
473071d4279SBram Moolenaar else
474071d4279SBram Moolenaar {
475b5aedf3eSBram Moolenaar if ((result == NULL || LT_POS(*result, curbuf->b_namedm[i]))
476b5aedf3eSBram Moolenaar && LT_POS(curbuf->b_namedm[i], pos))
477071d4279SBram Moolenaar result = &curbuf->b_namedm[i];
478071d4279SBram Moolenaar }
479071d4279SBram Moolenaar }
480071d4279SBram Moolenaar }
481071d4279SBram Moolenaar
482071d4279SBram Moolenaar return result;
483071d4279SBram Moolenaar }
484071d4279SBram Moolenaar
485071d4279SBram Moolenaar /*
486071d4279SBram Moolenaar * For an xtended filemark: set the fnum from the fname.
487071d4279SBram Moolenaar * This is used for marks obtained from the .viminfo file. It's postponed
488071d4279SBram Moolenaar * until the mark is used to avoid a long startup delay.
489071d4279SBram Moolenaar */
4905843f5f3SBram Moolenaar static void
fname2fnum(xfmark_T * fm)49152ea13daSBram Moolenaar fname2fnum(xfmark_T *fm)
492071d4279SBram Moolenaar {
493071d4279SBram Moolenaar char_u *p;
494071d4279SBram Moolenaar
495071d4279SBram Moolenaar if (fm->fname != NULL)
496071d4279SBram Moolenaar {
497071d4279SBram Moolenaar /*
498071d4279SBram Moolenaar * First expand "~/" in the file name to the home directory.
499525ad4d0SBram Moolenaar * Don't expand the whole name, it may contain other '~' chars.
500071d4279SBram Moolenaar */
501525ad4d0SBram Moolenaar if (fm->fname[0] == '~' && (fm->fname[1] == '/'
502525ad4d0SBram Moolenaar #ifdef BACKSLASH_IN_FILENAME
503525ad4d0SBram Moolenaar || fm->fname[1] == '\\'
504525ad4d0SBram Moolenaar #endif
505525ad4d0SBram Moolenaar ))
506525ad4d0SBram Moolenaar {
507525ad4d0SBram Moolenaar int len;
508525ad4d0SBram Moolenaar
509525ad4d0SBram Moolenaar expand_env((char_u *)"~/", NameBuff, MAXPATHL);
510cb4cef22SBram Moolenaar len = (int)STRLEN(NameBuff);
511525ad4d0SBram Moolenaar vim_strncpy(NameBuff + len, fm->fname + 2, MAXPATHL - len - 1);
512525ad4d0SBram Moolenaar }
513525ad4d0SBram Moolenaar else
514525ad4d0SBram Moolenaar vim_strncpy(NameBuff, fm->fname, MAXPATHL - 1);
515525ad4d0SBram Moolenaar
5164ba37b58SBram Moolenaar // Try to shorten the file name.
517071d4279SBram Moolenaar mch_dirname(IObuff, IOSIZE);
518071d4279SBram Moolenaar p = shorten_fname(NameBuff, IObuff);
519071d4279SBram Moolenaar
5204ba37b58SBram Moolenaar // buflist_new() will call fmarks_check_names()
521071d4279SBram Moolenaar (void)buflist_new(NameBuff, p, (linenr_T)1, 0);
522071d4279SBram Moolenaar }
523071d4279SBram Moolenaar }
524071d4279SBram Moolenaar
525071d4279SBram Moolenaar /*
526071d4279SBram Moolenaar * Check all file marks for a name that matches the file name in buf.
527071d4279SBram Moolenaar * May replace the name with an fnum.
528071d4279SBram Moolenaar * Used for marks that come from the .viminfo file.
529071d4279SBram Moolenaar */
530071d4279SBram Moolenaar void
fmarks_check_names(buf_T * buf)53152ea13daSBram Moolenaar fmarks_check_names(buf_T *buf)
532071d4279SBram Moolenaar {
533071d4279SBram Moolenaar char_u *name;
534071d4279SBram Moolenaar int i;
535071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
536071d4279SBram Moolenaar win_T *wp;
537071d4279SBram Moolenaar #endif
538071d4279SBram Moolenaar
539071d4279SBram Moolenaar if (buf->b_ffname == NULL)
540071d4279SBram Moolenaar return;
541071d4279SBram Moolenaar
542071d4279SBram Moolenaar name = home_replace_save(buf, buf->b_ffname);
543071d4279SBram Moolenaar if (name == NULL)
544071d4279SBram Moolenaar return;
545071d4279SBram Moolenaar
546071d4279SBram Moolenaar for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
547071d4279SBram Moolenaar fmarks_check_one(&namedfm[i], name, buf);
548071d4279SBram Moolenaar
549071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
550071d4279SBram Moolenaar FOR_ALL_WINDOWS(wp)
551071d4279SBram Moolenaar {
552071d4279SBram Moolenaar for (i = 0; i < wp->w_jumplistlen; ++i)
553071d4279SBram Moolenaar fmarks_check_one(&wp->w_jumplist[i], name, buf);
554071d4279SBram Moolenaar }
555071d4279SBram Moolenaar #endif
556071d4279SBram Moolenaar
557071d4279SBram Moolenaar vim_free(name);
558071d4279SBram Moolenaar }
559071d4279SBram Moolenaar
560071d4279SBram Moolenaar static void
fmarks_check_one(xfmark_T * fm,char_u * name,buf_T * buf)56152ea13daSBram Moolenaar fmarks_check_one(xfmark_T *fm, char_u *name, buf_T *buf)
562071d4279SBram Moolenaar {
563071d4279SBram Moolenaar if (fm->fmark.fnum == 0
564071d4279SBram Moolenaar && fm->fname != NULL
565071d4279SBram Moolenaar && fnamecmp(name, fm->fname) == 0)
566071d4279SBram Moolenaar {
567071d4279SBram Moolenaar fm->fmark.fnum = buf->b_fnum;
568d23a8236SBram Moolenaar VIM_CLEAR(fm->fname);
569071d4279SBram Moolenaar }
570071d4279SBram Moolenaar }
571071d4279SBram Moolenaar
572071d4279SBram Moolenaar /*
573071d4279SBram Moolenaar * Check a if a position from a mark is valid.
574071d4279SBram Moolenaar * Give and error message and return FAIL if not.
575071d4279SBram Moolenaar */
576071d4279SBram Moolenaar int
check_mark(pos_T * pos)57752ea13daSBram Moolenaar check_mark(pos_T *pos)
578071d4279SBram Moolenaar {
579071d4279SBram Moolenaar if (pos == NULL)
580071d4279SBram Moolenaar {
581f9e3e09fSBram Moolenaar emsg(_(e_umark));
582071d4279SBram Moolenaar return FAIL;
583071d4279SBram Moolenaar }
584071d4279SBram Moolenaar if (pos->lnum <= 0)
585071d4279SBram Moolenaar {
5864ba37b58SBram Moolenaar // lnum is negative if mark is in another file can can't get that
5874ba37b58SBram Moolenaar // file, error message already give then.
588071d4279SBram Moolenaar if (pos->lnum == 0)
589108010aaSBram Moolenaar emsg(_(e_mark_not_set));
590071d4279SBram Moolenaar return FAIL;
591071d4279SBram Moolenaar }
592071d4279SBram Moolenaar if (pos->lnum > curbuf->b_ml.ml_line_count)
593071d4279SBram Moolenaar {
594108010aaSBram Moolenaar emsg(_(e_mark_has_invalid_line_number));
595071d4279SBram Moolenaar return FAIL;
596071d4279SBram Moolenaar }
597071d4279SBram Moolenaar return OK;
598071d4279SBram Moolenaar }
599071d4279SBram Moolenaar
600071d4279SBram Moolenaar /*
601071d4279SBram Moolenaar * clrallmarks() - clear all marks in the buffer 'buf'
602071d4279SBram Moolenaar *
603071d4279SBram Moolenaar * Used mainly when trashing the entire buffer during ":e" type commands
604071d4279SBram Moolenaar */
605071d4279SBram Moolenaar void
clrallmarks(buf_T * buf)60652ea13daSBram Moolenaar clrallmarks(buf_T *buf)
607071d4279SBram Moolenaar {
608071d4279SBram Moolenaar static int i = -1;
609071d4279SBram Moolenaar
6104ba37b58SBram Moolenaar if (i == -1) // first call ever: initialize
611071d4279SBram Moolenaar for (i = 0; i < NMARKS + 1; i++)
612071d4279SBram Moolenaar {
613071d4279SBram Moolenaar namedfm[i].fmark.mark.lnum = 0;
614071d4279SBram Moolenaar namedfm[i].fname = NULL;
6152d358997SBram Moolenaar #ifdef FEAT_VIMINFO
6162d358997SBram Moolenaar namedfm[i].time_set = 0;
6172d358997SBram Moolenaar #endif
618071d4279SBram Moolenaar }
619071d4279SBram Moolenaar
620071d4279SBram Moolenaar for (i = 0; i < NMARKS; i++)
621071d4279SBram Moolenaar buf->b_namedm[i].lnum = 0;
6224ba37b58SBram Moolenaar buf->b_op_start.lnum = 0; // start/end op mark cleared
623071d4279SBram Moolenaar buf->b_op_end.lnum = 0;
6244ba37b58SBram Moolenaar buf->b_last_cursor.lnum = 1; // '" mark cleared
625071d4279SBram Moolenaar buf->b_last_cursor.col = 0;
626071d4279SBram Moolenaar buf->b_last_cursor.coladd = 0;
6274ba37b58SBram Moolenaar buf->b_last_insert.lnum = 0; // '^ mark cleared
6284ba37b58SBram Moolenaar buf->b_last_change.lnum = 0; // '. mark cleared
629071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
630071d4279SBram Moolenaar buf->b_changelistlen = 0;
631071d4279SBram Moolenaar #endif
632071d4279SBram Moolenaar }
633071d4279SBram Moolenaar
634071d4279SBram Moolenaar /*
635071d4279SBram Moolenaar * Get name of file from a filemark.
636071d4279SBram Moolenaar * When it's in the current buffer, return the text at the mark.
637071d4279SBram Moolenaar * Returns an allocated string.
638071d4279SBram Moolenaar */
639071d4279SBram Moolenaar char_u *
fm_getname(fmark_T * fmark,int lead_len)64052ea13daSBram Moolenaar fm_getname(fmark_T *fmark, int lead_len)
641071d4279SBram Moolenaar {
6424ba37b58SBram Moolenaar if (fmark->fnum == curbuf->b_fnum) // current buffer
643071d4279SBram Moolenaar return mark_line(&(fmark->mark), lead_len);
644071d4279SBram Moolenaar return buflist_nr2name(fmark->fnum, FALSE, TRUE);
645071d4279SBram Moolenaar }
646071d4279SBram Moolenaar
647071d4279SBram Moolenaar /*
648071d4279SBram Moolenaar * Return the line at mark "mp". Truncate to fit in window.
649071d4279SBram Moolenaar * The returned string has been allocated.
650071d4279SBram Moolenaar */
651071d4279SBram Moolenaar static char_u *
mark_line(pos_T * mp,int lead_len)65252ea13daSBram Moolenaar mark_line(pos_T *mp, int lead_len)
653071d4279SBram Moolenaar {
654071d4279SBram Moolenaar char_u *s, *p;
655071d4279SBram Moolenaar int len;
656071d4279SBram Moolenaar
657071d4279SBram Moolenaar if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count)
658071d4279SBram Moolenaar return vim_strsave((char_u *)"-invalid-");
6599d5185bfSBram Moolenaar // Allow for up to 5 bytes per character.
66071ccd03eSBram Moolenaar s = vim_strnsave(skipwhite(ml_get(mp->lnum)), Columns * 5);
661071d4279SBram Moolenaar if (s == NULL)
662071d4279SBram Moolenaar return NULL;
6639d5185bfSBram Moolenaar // Truncate the line to fit it in the window.
664071d4279SBram Moolenaar len = 0;
66591acfffcSBram Moolenaar for (p = s; *p != NUL; MB_PTR_ADV(p))
666071d4279SBram Moolenaar {
667071d4279SBram Moolenaar len += ptr2cells(p);
668071d4279SBram Moolenaar if (len >= Columns - lead_len)
669071d4279SBram Moolenaar break;
670071d4279SBram Moolenaar }
671071d4279SBram Moolenaar *p = NUL;
672071d4279SBram Moolenaar return s;
673071d4279SBram Moolenaar }
674071d4279SBram Moolenaar
675071d4279SBram Moolenaar /*
676071d4279SBram Moolenaar * print the marks
677071d4279SBram Moolenaar */
678071d4279SBram Moolenaar void
ex_marks(exarg_T * eap)6794bd78233SBram Moolenaar ex_marks(exarg_T *eap)
680071d4279SBram Moolenaar {
681071d4279SBram Moolenaar char_u *arg = eap->arg;
682071d4279SBram Moolenaar int i;
683071d4279SBram Moolenaar char_u *name;
68454c3fcd8SBram Moolenaar pos_T *posp, *startp, *endp;
685071d4279SBram Moolenaar
686071d4279SBram Moolenaar if (arg != NULL && *arg == NUL)
687071d4279SBram Moolenaar arg = NULL;
688071d4279SBram Moolenaar
689071d4279SBram Moolenaar show_one_mark('\'', arg, &curwin->w_pcmark, NULL, TRUE);
690071d4279SBram Moolenaar for (i = 0; i < NMARKS; ++i)
691071d4279SBram Moolenaar show_one_mark(i + 'a', arg, &curbuf->b_namedm[i], NULL, TRUE);
692071d4279SBram Moolenaar for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
693071d4279SBram Moolenaar {
694071d4279SBram Moolenaar if (namedfm[i].fmark.fnum != 0)
695071d4279SBram Moolenaar name = fm_getname(&namedfm[i].fmark, 15);
696071d4279SBram Moolenaar else
697071d4279SBram Moolenaar name = namedfm[i].fname;
698071d4279SBram Moolenaar if (name != NULL)
699071d4279SBram Moolenaar {
700071d4279SBram Moolenaar show_one_mark(i >= NMARKS ? i - NMARKS + '0' : i + 'A',
701071d4279SBram Moolenaar arg, &namedfm[i].fmark.mark, name,
702071d4279SBram Moolenaar namedfm[i].fmark.fnum == curbuf->b_fnum);
703071d4279SBram Moolenaar if (namedfm[i].fmark.fnum != 0)
704071d4279SBram Moolenaar vim_free(name);
705071d4279SBram Moolenaar }
706071d4279SBram Moolenaar }
707071d4279SBram Moolenaar show_one_mark('"', arg, &curbuf->b_last_cursor, NULL, TRUE);
708071d4279SBram Moolenaar show_one_mark('[', arg, &curbuf->b_op_start, NULL, TRUE);
709071d4279SBram Moolenaar show_one_mark(']', arg, &curbuf->b_op_end, NULL, TRUE);
710071d4279SBram Moolenaar show_one_mark('^', arg, &curbuf->b_last_insert, NULL, TRUE);
711071d4279SBram Moolenaar show_one_mark('.', arg, &curbuf->b_last_change, NULL, TRUE);
71254c3fcd8SBram Moolenaar
71354c3fcd8SBram Moolenaar // Show the marks as where they will jump to.
71454c3fcd8SBram Moolenaar startp = &curbuf->b_visual.vi_start;
71554c3fcd8SBram Moolenaar endp = &curbuf->b_visual.vi_end;
71654c3fcd8SBram Moolenaar if ((LT_POS(*startp, *endp) || endp->lnum == 0) && startp->lnum != 0)
71754c3fcd8SBram Moolenaar posp = startp;
71854c3fcd8SBram Moolenaar else
71954c3fcd8SBram Moolenaar posp = endp;
72054c3fcd8SBram Moolenaar show_one_mark('<', arg, posp, NULL, TRUE);
72154c3fcd8SBram Moolenaar show_one_mark('>', arg, posp == startp ? endp : startp, NULL, TRUE);
72254c3fcd8SBram Moolenaar
723071d4279SBram Moolenaar show_one_mark(-1, arg, NULL, NULL, FALSE);
724071d4279SBram Moolenaar }
725071d4279SBram Moolenaar
726071d4279SBram Moolenaar static void
show_one_mark(int c,char_u * arg,pos_T * p,char_u * name_arg,int current)72752ea13daSBram Moolenaar show_one_mark(
72852ea13daSBram Moolenaar int c,
72952ea13daSBram Moolenaar char_u *arg,
73052ea13daSBram Moolenaar pos_T *p,
731ad6dc49aSBram Moolenaar char_u *name_arg,
7324ba37b58SBram Moolenaar int current) // in current file
733071d4279SBram Moolenaar {
734071d4279SBram Moolenaar static int did_title = FALSE;
735071d4279SBram Moolenaar int mustfree = FALSE;
736ad6dc49aSBram Moolenaar char_u *name = name_arg;
737071d4279SBram Moolenaar
7384ba37b58SBram Moolenaar if (c == -1) // finish up
739071d4279SBram Moolenaar {
740071d4279SBram Moolenaar if (did_title)
741071d4279SBram Moolenaar did_title = FALSE;
742071d4279SBram Moolenaar else
743071d4279SBram Moolenaar {
744071d4279SBram Moolenaar if (arg == NULL)
74532526b3cSBram Moolenaar msg(_("No marks set"));
746071d4279SBram Moolenaar else
747f9e3e09fSBram Moolenaar semsg(_("E283: No marks matching \"%s\""), arg);
748071d4279SBram Moolenaar }
749071d4279SBram Moolenaar }
750ad6dc49aSBram Moolenaar // don't output anything if 'q' typed at --more-- prompt
751071d4279SBram Moolenaar else if (!got_int
752071d4279SBram Moolenaar && (arg == NULL || vim_strchr(arg, c) != NULL)
753071d4279SBram Moolenaar && p->lnum != 0)
754071d4279SBram Moolenaar {
755ad6dc49aSBram Moolenaar if (name == NULL && current)
756ad6dc49aSBram Moolenaar {
757ad6dc49aSBram Moolenaar name = mark_line(p, 15);
758ad6dc49aSBram Moolenaar mustfree = TRUE;
759ad6dc49aSBram Moolenaar }
760ad6dc49aSBram Moolenaar if (!message_filtered(name))
761ad6dc49aSBram Moolenaar {
762071d4279SBram Moolenaar if (!did_title)
763071d4279SBram Moolenaar {
764ad6dc49aSBram Moolenaar // Highlight title
76532526b3cSBram Moolenaar msg_puts_title(_("\nmark line col file/text"));
766071d4279SBram Moolenaar did_title = TRUE;
767071d4279SBram Moolenaar }
768071d4279SBram Moolenaar msg_putchar('\n');
769071d4279SBram Moolenaar if (!got_int)
770071d4279SBram Moolenaar {
771071d4279SBram Moolenaar sprintf((char *)IObuff, " %c %6ld %4d ", c, p->lnum, p->col);
772071d4279SBram Moolenaar msg_outtrans(IObuff);
773071d4279SBram Moolenaar if (name != NULL)
774071d4279SBram Moolenaar {
7758820b486SBram Moolenaar msg_outtrans_attr(name, current ? HL_ATTR(HLF_D) : 0);
776ad6dc49aSBram Moolenaar }
777ad6dc49aSBram Moolenaar }
778ad6dc49aSBram Moolenaar out_flush(); // show one line at a time
779ad6dc49aSBram Moolenaar }
780071d4279SBram Moolenaar if (mustfree)
781071d4279SBram Moolenaar vim_free(name);
782071d4279SBram Moolenaar }
783071d4279SBram Moolenaar }
784071d4279SBram Moolenaar
785c0197e28SBram Moolenaar /*
786c0197e28SBram Moolenaar * ":delmarks[!] [marks]"
787c0197e28SBram Moolenaar */
788c0197e28SBram Moolenaar void
ex_delmarks(exarg_T * eap)78952ea13daSBram Moolenaar ex_delmarks(exarg_T *eap)
790c0197e28SBram Moolenaar {
791c0197e28SBram Moolenaar char_u *p;
792c0197e28SBram Moolenaar int from, to;
793c0197e28SBram Moolenaar int i;
794c0197e28SBram Moolenaar int lower;
795c0197e28SBram Moolenaar int digit;
796c0197e28SBram Moolenaar int n;
797c0197e28SBram Moolenaar
798c0197e28SBram Moolenaar if (*eap->arg == NUL && eap->forceit)
7994ba37b58SBram Moolenaar // clear all marks
800c0197e28SBram Moolenaar clrallmarks(curbuf);
801c0197e28SBram Moolenaar else if (eap->forceit)
802f9e3e09fSBram Moolenaar emsg(_(e_invarg));
803c0197e28SBram Moolenaar else if (*eap->arg == NUL)
804f9e3e09fSBram Moolenaar emsg(_(e_argreq));
805c0197e28SBram Moolenaar else
806c0197e28SBram Moolenaar {
8074ba37b58SBram Moolenaar // clear specified marks only
808c0197e28SBram Moolenaar for (p = eap->arg; *p != NUL; ++p)
809c0197e28SBram Moolenaar {
810c0197e28SBram Moolenaar lower = ASCII_ISLOWER(*p);
811c0197e28SBram Moolenaar digit = VIM_ISDIGIT(*p);
812c0197e28SBram Moolenaar if (lower || digit || ASCII_ISUPPER(*p))
813c0197e28SBram Moolenaar {
814c0197e28SBram Moolenaar if (p[1] == '-')
815c0197e28SBram Moolenaar {
8164ba37b58SBram Moolenaar // clear range of marks
817c0197e28SBram Moolenaar from = *p;
818c0197e28SBram Moolenaar to = p[2];
819c0197e28SBram Moolenaar if (!(lower ? ASCII_ISLOWER(p[2])
820c0197e28SBram Moolenaar : (digit ? VIM_ISDIGIT(p[2])
821c0197e28SBram Moolenaar : ASCII_ISUPPER(p[2])))
822c0197e28SBram Moolenaar || to < from)
823c0197e28SBram Moolenaar {
824f9e3e09fSBram Moolenaar semsg(_(e_invarg2), p);
825c0197e28SBram Moolenaar return;
826c0197e28SBram Moolenaar }
827c0197e28SBram Moolenaar p += 2;
828c0197e28SBram Moolenaar }
829c0197e28SBram Moolenaar else
8304ba37b58SBram Moolenaar // clear one lower case mark
831c0197e28SBram Moolenaar from = to = *p;
832c0197e28SBram Moolenaar
833c0197e28SBram Moolenaar for (i = from; i <= to; ++i)
834c0197e28SBram Moolenaar {
835c0197e28SBram Moolenaar if (lower)
836c0197e28SBram Moolenaar curbuf->b_namedm[i - 'a'].lnum = 0;
837c0197e28SBram Moolenaar else
838c0197e28SBram Moolenaar {
839c0197e28SBram Moolenaar if (digit)
840c0197e28SBram Moolenaar n = i - '0' + NMARKS;
841c0197e28SBram Moolenaar else
842c0197e28SBram Moolenaar n = i - 'A';
843c0197e28SBram Moolenaar namedfm[n].fmark.mark.lnum = 0;
8448cd6cd80SBram Moolenaar namedfm[n].fmark.fnum = 0;
845d23a8236SBram Moolenaar VIM_CLEAR(namedfm[n].fname);
8462d358997SBram Moolenaar #ifdef FEAT_VIMINFO
8478cd6cd80SBram Moolenaar namedfm[n].time_set = digit ? 0 : vim_time();
8482d358997SBram Moolenaar #endif
849c0197e28SBram Moolenaar }
850c0197e28SBram Moolenaar }
851c0197e28SBram Moolenaar }
852c0197e28SBram Moolenaar else
853c0197e28SBram Moolenaar switch (*p)
854c0197e28SBram Moolenaar {
855c0197e28SBram Moolenaar case '"': curbuf->b_last_cursor.lnum = 0; break;
856c0197e28SBram Moolenaar case '^': curbuf->b_last_insert.lnum = 0; break;
857c0197e28SBram Moolenaar case '.': curbuf->b_last_change.lnum = 0; break;
858c0197e28SBram Moolenaar case '[': curbuf->b_op_start.lnum = 0; break;
859c0197e28SBram Moolenaar case ']': curbuf->b_op_end.lnum = 0; break;
860a226a6ddSBram Moolenaar case '<': curbuf->b_visual.vi_start.lnum = 0; break;
861a226a6ddSBram Moolenaar case '>': curbuf->b_visual.vi_end.lnum = 0; break;
862c0197e28SBram Moolenaar case ' ': break;
863f9e3e09fSBram Moolenaar default: semsg(_(e_invarg2), p);
864c0197e28SBram Moolenaar return;
865c0197e28SBram Moolenaar }
866c0197e28SBram Moolenaar }
867c0197e28SBram Moolenaar }
868c0197e28SBram Moolenaar }
869c0197e28SBram Moolenaar
870071d4279SBram Moolenaar #if defined(FEAT_JUMPLIST) || defined(PROTO)
871071d4279SBram Moolenaar /*
872071d4279SBram Moolenaar * print the jumplist
873071d4279SBram Moolenaar */
874071d4279SBram Moolenaar void
ex_jumps(exarg_T * eap UNUSED)87552ea13daSBram Moolenaar ex_jumps(exarg_T *eap UNUSED)
876071d4279SBram Moolenaar {
877071d4279SBram Moolenaar int i;
878071d4279SBram Moolenaar char_u *name;
879071d4279SBram Moolenaar
88048679741SBram Moolenaar cleanup_jumplist(curwin, TRUE);
881a7e18d23SBram Moolenaar
8824ba37b58SBram Moolenaar // Highlight title
88332526b3cSBram Moolenaar msg_puts_title(_("\n jump line col file/text"));
884071d4279SBram Moolenaar for (i = 0; i < curwin->w_jumplistlen && !got_int; ++i)
885071d4279SBram Moolenaar {
886071d4279SBram Moolenaar if (curwin->w_jumplist[i].fmark.mark.lnum != 0)
887071d4279SBram Moolenaar {
888071d4279SBram Moolenaar name = fm_getname(&curwin->w_jumplist[i].fmark, 16);
889f86db78fSBram Moolenaar
890f86db78fSBram Moolenaar // apply :filter /pat/ or file name not available
891f86db78fSBram Moolenaar if (name == NULL || message_filtered(name))
892d93090f4SBram Moolenaar {
893d93090f4SBram Moolenaar vim_free(name);
894071d4279SBram Moolenaar continue;
895d93090f4SBram Moolenaar }
896071d4279SBram Moolenaar
897071d4279SBram Moolenaar msg_putchar('\n');
898071d4279SBram Moolenaar if (got_int)
899ed39e1d5SBram Moolenaar {
900ed39e1d5SBram Moolenaar vim_free(name);
901071d4279SBram Moolenaar break;
902ed39e1d5SBram Moolenaar }
903071d4279SBram Moolenaar sprintf((char *)IObuff, "%c %2d %5ld %4d ",
904071d4279SBram Moolenaar i == curwin->w_jumplistidx ? '>' : ' ',
905071d4279SBram Moolenaar i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx
906071d4279SBram Moolenaar : curwin->w_jumplistidx - i,
907071d4279SBram Moolenaar curwin->w_jumplist[i].fmark.mark.lnum,
908071d4279SBram Moolenaar curwin->w_jumplist[i].fmark.mark.col);
909071d4279SBram Moolenaar msg_outtrans(IObuff);
910071d4279SBram Moolenaar msg_outtrans_attr(name,
911071d4279SBram Moolenaar curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
9128820b486SBram Moolenaar ? HL_ATTR(HLF_D) : 0);
913071d4279SBram Moolenaar vim_free(name);
914071d4279SBram Moolenaar ui_breakcheck();
915071d4279SBram Moolenaar }
916071d4279SBram Moolenaar out_flush();
917071d4279SBram Moolenaar }
918071d4279SBram Moolenaar if (curwin->w_jumplistidx == curwin->w_jumplistlen)
91932526b3cSBram Moolenaar msg_puts("\n>");
920071d4279SBram Moolenaar }
921071d4279SBram Moolenaar
9222d358997SBram Moolenaar void
ex_clearjumps(exarg_T * eap UNUSED)9232d358997SBram Moolenaar ex_clearjumps(exarg_T *eap UNUSED)
9242d358997SBram Moolenaar {
9252d358997SBram Moolenaar free_jumplist(curwin);
9262d358997SBram Moolenaar curwin->w_jumplistlen = 0;
9272d358997SBram Moolenaar curwin->w_jumplistidx = 0;
9282d358997SBram Moolenaar }
9292d358997SBram Moolenaar
930071d4279SBram Moolenaar /*
931071d4279SBram Moolenaar * print the changelist
932071d4279SBram Moolenaar */
933071d4279SBram Moolenaar void
ex_changes(exarg_T * eap UNUSED)93452ea13daSBram Moolenaar ex_changes(exarg_T *eap UNUSED)
935071d4279SBram Moolenaar {
936071d4279SBram Moolenaar int i;
937071d4279SBram Moolenaar char_u *name;
938071d4279SBram Moolenaar
9394ba37b58SBram Moolenaar // Highlight title
94032526b3cSBram Moolenaar msg_puts_title(_("\nchange line col text"));
941071d4279SBram Moolenaar
942071d4279SBram Moolenaar for (i = 0; i < curbuf->b_changelistlen && !got_int; ++i)
943071d4279SBram Moolenaar {
944071d4279SBram Moolenaar if (curbuf->b_changelist[i].lnum != 0)
945071d4279SBram Moolenaar {
946071d4279SBram Moolenaar msg_putchar('\n');
947071d4279SBram Moolenaar if (got_int)
948071d4279SBram Moolenaar break;
949071d4279SBram Moolenaar sprintf((char *)IObuff, "%c %3d %5ld %4d ",
950071d4279SBram Moolenaar i == curwin->w_changelistidx ? '>' : ' ',
951071d4279SBram Moolenaar i > curwin->w_changelistidx ? i - curwin->w_changelistidx
952071d4279SBram Moolenaar : curwin->w_changelistidx - i,
953071d4279SBram Moolenaar (long)curbuf->b_changelist[i].lnum,
954071d4279SBram Moolenaar curbuf->b_changelist[i].col);
955071d4279SBram Moolenaar msg_outtrans(IObuff);
956071d4279SBram Moolenaar name = mark_line(&curbuf->b_changelist[i], 17);
957071d4279SBram Moolenaar if (name == NULL)
958071d4279SBram Moolenaar break;
9598820b486SBram Moolenaar msg_outtrans_attr(name, HL_ATTR(HLF_D));
960071d4279SBram Moolenaar vim_free(name);
961071d4279SBram Moolenaar ui_breakcheck();
962071d4279SBram Moolenaar }
963071d4279SBram Moolenaar out_flush();
964071d4279SBram Moolenaar }
965071d4279SBram Moolenaar if (curwin->w_changelistidx == curbuf->b_changelistlen)
96632526b3cSBram Moolenaar msg_puts("\n>");
967071d4279SBram Moolenaar }
968071d4279SBram Moolenaar #endif
969071d4279SBram Moolenaar
970071d4279SBram Moolenaar #define one_adjust(add) \
971071d4279SBram Moolenaar { \
972071d4279SBram Moolenaar lp = add; \
973071d4279SBram Moolenaar if (*lp >= line1 && *lp <= line2) \
974071d4279SBram Moolenaar { \
975071d4279SBram Moolenaar if (amount == MAXLNUM) \
976071d4279SBram Moolenaar *lp = 0; \
977071d4279SBram Moolenaar else \
978071d4279SBram Moolenaar *lp += amount; \
979071d4279SBram Moolenaar } \
980071d4279SBram Moolenaar else if (amount_after && *lp > line2) \
981071d4279SBram Moolenaar *lp += amount_after; \
982071d4279SBram Moolenaar }
983071d4279SBram Moolenaar
9844ba37b58SBram Moolenaar // don't delete the line, just put at first deleted line
985071d4279SBram Moolenaar #define one_adjust_nodel(add) \
986071d4279SBram Moolenaar { \
987071d4279SBram Moolenaar lp = add; \
988071d4279SBram Moolenaar if (*lp >= line1 && *lp <= line2) \
989071d4279SBram Moolenaar { \
990071d4279SBram Moolenaar if (amount == MAXLNUM) \
991071d4279SBram Moolenaar *lp = line1; \
992071d4279SBram Moolenaar else \
993071d4279SBram Moolenaar *lp += amount; \
994071d4279SBram Moolenaar } \
995071d4279SBram Moolenaar else if (amount_after && *lp > line2) \
996071d4279SBram Moolenaar *lp += amount_after; \
997071d4279SBram Moolenaar }
998071d4279SBram Moolenaar
999071d4279SBram Moolenaar /*
1000071d4279SBram Moolenaar * Adjust marks between line1 and line2 (inclusive) to move 'amount' lines.
1001071d4279SBram Moolenaar * Must be called before changed_*(), appended_lines() or deleted_lines().
1002071d4279SBram Moolenaar * May be called before or after changing the text.
1003071d4279SBram Moolenaar * When deleting lines line1 to line2, use an 'amount' of MAXLNUM: The marks
1004071d4279SBram Moolenaar * within this range are made invalid.
1005071d4279SBram Moolenaar * If 'amount_after' is non-zero adjust marks after line2.
1006071d4279SBram Moolenaar * Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2);
1007071d4279SBram Moolenaar * Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
1008071d4279SBram Moolenaar * or: mark_adjust(56, 55, MAXLNUM, 2);
1009071d4279SBram Moolenaar */
1010071d4279SBram Moolenaar void
mark_adjust(linenr_T line1,linenr_T line2,long amount,long amount_after)101152ea13daSBram Moolenaar mark_adjust(
101252ea13daSBram Moolenaar linenr_T line1,
101352ea13daSBram Moolenaar linenr_T line2,
101452ea13daSBram Moolenaar long amount,
101552ea13daSBram Moolenaar long amount_after)
1016071d4279SBram Moolenaar {
101788d298aeSBram Moolenaar mark_adjust_internal(line1, line2, amount, amount_after, TRUE);
101888d298aeSBram Moolenaar }
101988d298aeSBram Moolenaar
102088d298aeSBram Moolenaar void
mark_adjust_nofold(linenr_T line1,linenr_T line2,long amount,long amount_after)102188d298aeSBram Moolenaar mark_adjust_nofold(
102288d298aeSBram Moolenaar linenr_T line1,
102388d298aeSBram Moolenaar linenr_T line2,
102488d298aeSBram Moolenaar long amount,
102588d298aeSBram Moolenaar long amount_after)
102688d298aeSBram Moolenaar {
102788d298aeSBram Moolenaar mark_adjust_internal(line1, line2, amount, amount_after, FALSE);
102888d298aeSBram Moolenaar }
102988d298aeSBram Moolenaar
103088d298aeSBram Moolenaar static void
mark_adjust_internal(linenr_T line1,linenr_T line2,long amount,long amount_after,int adjust_folds UNUSED)103188d298aeSBram Moolenaar mark_adjust_internal(
103288d298aeSBram Moolenaar linenr_T line1,
103388d298aeSBram Moolenaar linenr_T line2,
103488d298aeSBram Moolenaar long amount,
103588d298aeSBram Moolenaar long amount_after,
103688d298aeSBram Moolenaar int adjust_folds UNUSED)
103788d298aeSBram Moolenaar {
1038071d4279SBram Moolenaar int i;
1039071d4279SBram Moolenaar int fnum = curbuf->b_fnum;
1040071d4279SBram Moolenaar linenr_T *lp;
1041071d4279SBram Moolenaar win_T *win;
1042bd1e5d2eSBram Moolenaar tabpage_T *tab;
104329ddebefSBram Moolenaar static pos_T initpos = {1, 0, 0};
1044071d4279SBram Moolenaar
10454ba37b58SBram Moolenaar if (line2 < line1 && amount_after == 0L) // nothing to do
1046071d4279SBram Moolenaar return;
1047071d4279SBram Moolenaar
1048e1004401SBram Moolenaar if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0)
1049071d4279SBram Moolenaar {
10504ba37b58SBram Moolenaar // named marks, lower case and upper case
1051071d4279SBram Moolenaar for (i = 0; i < NMARKS; i++)
1052071d4279SBram Moolenaar {
1053071d4279SBram Moolenaar one_adjust(&(curbuf->b_namedm[i].lnum));
1054071d4279SBram Moolenaar if (namedfm[i].fmark.fnum == fnum)
1055071d4279SBram Moolenaar one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
1056071d4279SBram Moolenaar }
1057071d4279SBram Moolenaar for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++)
1058071d4279SBram Moolenaar {
1059071d4279SBram Moolenaar if (namedfm[i].fmark.fnum == fnum)
1060071d4279SBram Moolenaar one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
1061071d4279SBram Moolenaar }
1062071d4279SBram Moolenaar
10634ba37b58SBram Moolenaar // last Insert position
1064071d4279SBram Moolenaar one_adjust(&(curbuf->b_last_insert.lnum));
1065071d4279SBram Moolenaar
10664ba37b58SBram Moolenaar // last change position
1067071d4279SBram Moolenaar one_adjust(&(curbuf->b_last_change.lnum));
1068071d4279SBram Moolenaar
10694ba37b58SBram Moolenaar // last cursor position, if it was set
1070b5aedf3eSBram Moolenaar if (!EQUAL_POS(curbuf->b_last_cursor, initpos))
1071b6a76ffcSBram Moolenaar one_adjust(&(curbuf->b_last_cursor.lnum));
1072b6a76ffcSBram Moolenaar
1073b6a76ffcSBram Moolenaar
1074071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
10754ba37b58SBram Moolenaar // list of change positions
1076071d4279SBram Moolenaar for (i = 0; i < curbuf->b_changelistlen; ++i)
1077071d4279SBram Moolenaar one_adjust_nodel(&(curbuf->b_changelist[i].lnum));
1078071d4279SBram Moolenaar #endif
1079071d4279SBram Moolenaar
10804ba37b58SBram Moolenaar // Visual area
1081a226a6ddSBram Moolenaar one_adjust_nodel(&(curbuf->b_visual.vi_start.lnum));
1082a226a6ddSBram Moolenaar one_adjust_nodel(&(curbuf->b_visual.vi_end.lnum));
1083071d4279SBram Moolenaar
1084071d4279SBram Moolenaar #ifdef FEAT_QUICKFIX
10854ba37b58SBram Moolenaar // quickfix marks
108628c258fdSBram Moolenaar qf_mark_adjust(NULL, line1, line2, amount, amount_after);
10874ba37b58SBram Moolenaar // location lists
1088bd1e5d2eSBram Moolenaar FOR_ALL_TAB_WINDOWS(tab, win)
108928c258fdSBram Moolenaar qf_mark_adjust(win, line1, line2, amount, amount_after);
1090071d4279SBram Moolenaar #endif
1091071d4279SBram Moolenaar
1092071d4279SBram Moolenaar #ifdef FEAT_SIGNS
1093071d4279SBram Moolenaar sign_mark_adjust(line1, line2, amount, amount_after);
1094071d4279SBram Moolenaar #endif
1095071d4279SBram Moolenaar }
1096071d4279SBram Moolenaar
10974ba37b58SBram Moolenaar // previous context mark
1098071d4279SBram Moolenaar one_adjust(&(curwin->w_pcmark.lnum));
1099071d4279SBram Moolenaar
11004ba37b58SBram Moolenaar // previous pcmark
1101071d4279SBram Moolenaar one_adjust(&(curwin->w_prev_pcmark.lnum));
1102071d4279SBram Moolenaar
11034ba37b58SBram Moolenaar // saved cursor for formatting
1104071d4279SBram Moolenaar if (saved_cursor.lnum != 0)
1105071d4279SBram Moolenaar one_adjust_nodel(&(saved_cursor.lnum));
1106071d4279SBram Moolenaar
1107071d4279SBram Moolenaar /*
1108071d4279SBram Moolenaar * Adjust items in all windows related to the current buffer.
1109071d4279SBram Moolenaar */
1110bd1e5d2eSBram Moolenaar FOR_ALL_TAB_WINDOWS(tab, win)
1111071d4279SBram Moolenaar {
1112071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
1113e1004401SBram Moolenaar if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0)
11144ba37b58SBram Moolenaar // Marks in the jumplist. When deleting lines, this may create
11154ba37b58SBram Moolenaar // duplicate marks in the jumplist, they will be removed later.
1116071d4279SBram Moolenaar for (i = 0; i < win->w_jumplistlen; ++i)
1117071d4279SBram Moolenaar if (win->w_jumplist[i].fmark.fnum == fnum)
1118071d4279SBram Moolenaar one_adjust_nodel(&(win->w_jumplist[i].fmark.mark.lnum));
1119071d4279SBram Moolenaar #endif
1120071d4279SBram Moolenaar
1121071d4279SBram Moolenaar if (win->w_buffer == curbuf)
1122071d4279SBram Moolenaar {
1123e1004401SBram Moolenaar if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0)
11244ba37b58SBram Moolenaar // marks in the tag stack
1125071d4279SBram Moolenaar for (i = 0; i < win->w_tagstacklen; i++)
1126071d4279SBram Moolenaar if (win->w_tagstack[i].fmark.fnum == fnum)
1127071d4279SBram Moolenaar one_adjust_nodel(&(win->w_tagstack[i].fmark.mark.lnum));
1128071d4279SBram Moolenaar
11294ba37b58SBram Moolenaar // the displayed Visual area
1130071d4279SBram Moolenaar if (win->w_old_cursor_lnum != 0)
1131071d4279SBram Moolenaar {
1132071d4279SBram Moolenaar one_adjust_nodel(&(win->w_old_cursor_lnum));
1133071d4279SBram Moolenaar one_adjust_nodel(&(win->w_old_visual_lnum));
1134071d4279SBram Moolenaar }
1135071d4279SBram Moolenaar
11364ba37b58SBram Moolenaar // topline and cursor position for windows with the same buffer
11374ba37b58SBram Moolenaar // other than the current window
1138071d4279SBram Moolenaar if (win != curwin)
1139071d4279SBram Moolenaar {
1140071d4279SBram Moolenaar if (win->w_topline >= line1 && win->w_topline <= line2)
1141071d4279SBram Moolenaar {
11424ba37b58SBram Moolenaar if (amount == MAXLNUM) // topline is deleted
1143071d4279SBram Moolenaar {
1144071d4279SBram Moolenaar if (line1 <= 1)
1145071d4279SBram Moolenaar win->w_topline = 1;
1146071d4279SBram Moolenaar else
1147071d4279SBram Moolenaar win->w_topline = line1 - 1;
1148071d4279SBram Moolenaar }
11494ba37b58SBram Moolenaar else // keep topline on the same line
1150071d4279SBram Moolenaar win->w_topline += amount;
1151071d4279SBram Moolenaar #ifdef FEAT_DIFF
1152071d4279SBram Moolenaar win->w_topfill = 0;
1153071d4279SBram Moolenaar #endif
1154071d4279SBram Moolenaar }
1155071d4279SBram Moolenaar else if (amount_after && win->w_topline > line2)
1156071d4279SBram Moolenaar {
1157071d4279SBram Moolenaar win->w_topline += amount_after;
1158071d4279SBram Moolenaar #ifdef FEAT_DIFF
1159071d4279SBram Moolenaar win->w_topfill = 0;
1160071d4279SBram Moolenaar #endif
1161071d4279SBram Moolenaar }
1162071d4279SBram Moolenaar if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2)
1163071d4279SBram Moolenaar {
11644ba37b58SBram Moolenaar if (amount == MAXLNUM) // line with cursor is deleted
1165071d4279SBram Moolenaar {
1166071d4279SBram Moolenaar if (line1 <= 1)
1167071d4279SBram Moolenaar win->w_cursor.lnum = 1;
1168071d4279SBram Moolenaar else
1169071d4279SBram Moolenaar win->w_cursor.lnum = line1 - 1;
1170071d4279SBram Moolenaar win->w_cursor.col = 0;
1171071d4279SBram Moolenaar }
11724ba37b58SBram Moolenaar else // keep cursor on the same line
1173071d4279SBram Moolenaar win->w_cursor.lnum += amount;
1174071d4279SBram Moolenaar }
1175071d4279SBram Moolenaar else if (amount_after && win->w_cursor.lnum > line2)
1176071d4279SBram Moolenaar win->w_cursor.lnum += amount_after;
1177071d4279SBram Moolenaar }
1178071d4279SBram Moolenaar
1179071d4279SBram Moolenaar #ifdef FEAT_FOLDING
11804ba37b58SBram Moolenaar // adjust folds
118188d298aeSBram Moolenaar if (adjust_folds)
1182071d4279SBram Moolenaar foldMarkAdjust(win, line1, line2, amount, amount_after);
1183071d4279SBram Moolenaar #endif
1184071d4279SBram Moolenaar }
1185071d4279SBram Moolenaar }
1186071d4279SBram Moolenaar
1187071d4279SBram Moolenaar #ifdef FEAT_DIFF
11884ba37b58SBram Moolenaar // adjust diffs
1189071d4279SBram Moolenaar diff_mark_adjust(line1, line2, amount, amount_after);
1190071d4279SBram Moolenaar #endif
1191071d4279SBram Moolenaar }
1192071d4279SBram Moolenaar
11934ba37b58SBram Moolenaar // This code is used often, needs to be fast.
1194071d4279SBram Moolenaar #define col_adjust(pp) \
1195071d4279SBram Moolenaar { \
1196071d4279SBram Moolenaar posp = pp; \
1197071d4279SBram Moolenaar if (posp->lnum == lnum && posp->col >= mincol) \
1198071d4279SBram Moolenaar { \
1199071d4279SBram Moolenaar posp->lnum += lnum_amount; \
1200071d4279SBram Moolenaar if (col_amount < 0 && posp->col <= (colnr_T)-col_amount) \
1201071d4279SBram Moolenaar posp->col = 0; \
1202e1e714efSBram Moolenaar else if (posp->col < spaces_removed) \
1203e1e714efSBram Moolenaar posp->col = col_amount + spaces_removed; \
1204071d4279SBram Moolenaar else \
1205071d4279SBram Moolenaar posp->col += col_amount; \
1206071d4279SBram Moolenaar } \
1207071d4279SBram Moolenaar }
1208071d4279SBram Moolenaar
1209071d4279SBram Moolenaar /*
1210071d4279SBram Moolenaar * Adjust marks in line "lnum" at column "mincol" and further: add
1211071d4279SBram Moolenaar * "lnum_amount" to the line number and add "col_amount" to the column
1212071d4279SBram Moolenaar * position.
1213e1e714efSBram Moolenaar * "spaces_removed" is the number of spaces that were removed, matters when the
1214e1e714efSBram Moolenaar * cursor is inside them.
1215071d4279SBram Moolenaar */
1216071d4279SBram Moolenaar void
mark_col_adjust(linenr_T lnum,colnr_T mincol,long lnum_amount,long col_amount,int spaces_removed)121752ea13daSBram Moolenaar mark_col_adjust(
121852ea13daSBram Moolenaar linenr_T lnum,
121952ea13daSBram Moolenaar colnr_T mincol,
122052ea13daSBram Moolenaar long lnum_amount,
1221e1e714efSBram Moolenaar long col_amount,
1222e1e714efSBram Moolenaar int spaces_removed)
1223071d4279SBram Moolenaar {
1224071d4279SBram Moolenaar int i;
1225071d4279SBram Moolenaar int fnum = curbuf->b_fnum;
1226071d4279SBram Moolenaar win_T *win;
1227071d4279SBram Moolenaar pos_T *posp;
1228071d4279SBram Moolenaar
1229e1004401SBram Moolenaar if ((col_amount == 0L && lnum_amount == 0L)
1230e1004401SBram Moolenaar || (cmdmod.cmod_flags & CMOD_LOCKMARKS))
12314ba37b58SBram Moolenaar return; // nothing to do
1232071d4279SBram Moolenaar
12334ba37b58SBram Moolenaar // named marks, lower case and upper case
1234071d4279SBram Moolenaar for (i = 0; i < NMARKS; i++)
1235071d4279SBram Moolenaar {
1236071d4279SBram Moolenaar col_adjust(&(curbuf->b_namedm[i]));
1237071d4279SBram Moolenaar if (namedfm[i].fmark.fnum == fnum)
1238071d4279SBram Moolenaar col_adjust(&(namedfm[i].fmark.mark));
1239071d4279SBram Moolenaar }
1240071d4279SBram Moolenaar for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++)
1241071d4279SBram Moolenaar {
1242071d4279SBram Moolenaar if (namedfm[i].fmark.fnum == fnum)
1243071d4279SBram Moolenaar col_adjust(&(namedfm[i].fmark.mark));
1244071d4279SBram Moolenaar }
1245071d4279SBram Moolenaar
12464ba37b58SBram Moolenaar // last Insert position
1247071d4279SBram Moolenaar col_adjust(&(curbuf->b_last_insert));
1248071d4279SBram Moolenaar
12494ba37b58SBram Moolenaar // last change position
1250071d4279SBram Moolenaar col_adjust(&(curbuf->b_last_change));
1251071d4279SBram Moolenaar
1252071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
12534ba37b58SBram Moolenaar // list of change positions
1254071d4279SBram Moolenaar for (i = 0; i < curbuf->b_changelistlen; ++i)
1255071d4279SBram Moolenaar col_adjust(&(curbuf->b_changelist[i]));
1256071d4279SBram Moolenaar #endif
1257071d4279SBram Moolenaar
12584ba37b58SBram Moolenaar // Visual area
1259a226a6ddSBram Moolenaar col_adjust(&(curbuf->b_visual.vi_start));
1260a226a6ddSBram Moolenaar col_adjust(&(curbuf->b_visual.vi_end));
1261071d4279SBram Moolenaar
12624ba37b58SBram Moolenaar // previous context mark
1263071d4279SBram Moolenaar col_adjust(&(curwin->w_pcmark));
1264071d4279SBram Moolenaar
12654ba37b58SBram Moolenaar // previous pcmark
1266071d4279SBram Moolenaar col_adjust(&(curwin->w_prev_pcmark));
1267071d4279SBram Moolenaar
12684ba37b58SBram Moolenaar // saved cursor for formatting
1269071d4279SBram Moolenaar col_adjust(&saved_cursor);
1270071d4279SBram Moolenaar
1271071d4279SBram Moolenaar /*
1272071d4279SBram Moolenaar * Adjust items in all windows related to the current buffer.
1273071d4279SBram Moolenaar */
1274071d4279SBram Moolenaar FOR_ALL_WINDOWS(win)
1275071d4279SBram Moolenaar {
1276071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
12774ba37b58SBram Moolenaar // marks in the jumplist
1278071d4279SBram Moolenaar for (i = 0; i < win->w_jumplistlen; ++i)
1279071d4279SBram Moolenaar if (win->w_jumplist[i].fmark.fnum == fnum)
1280071d4279SBram Moolenaar col_adjust(&(win->w_jumplist[i].fmark.mark));
1281071d4279SBram Moolenaar #endif
1282071d4279SBram Moolenaar
1283071d4279SBram Moolenaar if (win->w_buffer == curbuf)
1284071d4279SBram Moolenaar {
12854ba37b58SBram Moolenaar // marks in the tag stack
1286071d4279SBram Moolenaar for (i = 0; i < win->w_tagstacklen; i++)
1287071d4279SBram Moolenaar if (win->w_tagstack[i].fmark.fnum == fnum)
1288071d4279SBram Moolenaar col_adjust(&(win->w_tagstack[i].fmark.mark));
1289071d4279SBram Moolenaar
12904ba37b58SBram Moolenaar // cursor position for other windows with the same buffer
1291071d4279SBram Moolenaar if (win != curwin)
1292071d4279SBram Moolenaar col_adjust(&win->w_cursor);
1293071d4279SBram Moolenaar }
1294071d4279SBram Moolenaar }
1295071d4279SBram Moolenaar }
1296071d4279SBram Moolenaar
1297071d4279SBram Moolenaar #ifdef FEAT_JUMPLIST
1298071d4279SBram Moolenaar /*
1299071d4279SBram Moolenaar * When deleting lines, this may create duplicate marks in the
1300a7e18d23SBram Moolenaar * jumplist. They will be removed here for the specified window.
130148679741SBram Moolenaar * When "loadfiles" is TRUE first ensure entries have the "fnum" field set
130248679741SBram Moolenaar * (this may be a bit slow).
1303071d4279SBram Moolenaar */
1304a7e18d23SBram Moolenaar void
cleanup_jumplist(win_T * wp,int loadfiles)130548679741SBram Moolenaar cleanup_jumplist(win_T *wp, int loadfiles)
1306071d4279SBram Moolenaar {
1307071d4279SBram Moolenaar int i;
1308071d4279SBram Moolenaar int from, to;
1309071d4279SBram Moolenaar
131048679741SBram Moolenaar if (loadfiles)
131148679741SBram Moolenaar {
13124ba37b58SBram Moolenaar // If specified, load all the files from the jump list. This is
13134ba37b58SBram Moolenaar // needed to properly clean up duplicate entries, but will take some
13144ba37b58SBram Moolenaar // time.
131548679741SBram Moolenaar for (i = 0; i < wp->w_jumplistlen; ++i)
131648679741SBram Moolenaar {
131748679741SBram Moolenaar if ((wp->w_jumplist[i].fmark.fnum == 0) &&
131848679741SBram Moolenaar (wp->w_jumplist[i].fmark.mark.lnum != 0))
131948679741SBram Moolenaar fname2fnum(&wp->w_jumplist[i]);
132048679741SBram Moolenaar }
132148679741SBram Moolenaar }
132248679741SBram Moolenaar
1323071d4279SBram Moolenaar to = 0;
1324a7e18d23SBram Moolenaar for (from = 0; from < wp->w_jumplistlen; ++from)
1325071d4279SBram Moolenaar {
1326a7e18d23SBram Moolenaar if (wp->w_jumplistidx == from)
1327a7e18d23SBram Moolenaar wp->w_jumplistidx = to;
1328a7e18d23SBram Moolenaar for (i = from + 1; i < wp->w_jumplistlen; ++i)
1329a7e18d23SBram Moolenaar if (wp->w_jumplist[i].fmark.fnum
1330a7e18d23SBram Moolenaar == wp->w_jumplist[from].fmark.fnum
1331a7e18d23SBram Moolenaar && wp->w_jumplist[from].fmark.fnum != 0
1332a7e18d23SBram Moolenaar && wp->w_jumplist[i].fmark.mark.lnum
1333a7e18d23SBram Moolenaar == wp->w_jumplist[from].fmark.mark.lnum)
1334071d4279SBram Moolenaar break;
13354ba37b58SBram Moolenaar if (i >= wp->w_jumplistlen) // no duplicate
1336a7e18d23SBram Moolenaar wp->w_jumplist[to++] = wp->w_jumplist[from];
1337071d4279SBram Moolenaar else
1338a7e18d23SBram Moolenaar vim_free(wp->w_jumplist[from].fname);
1339071d4279SBram Moolenaar }
1340a7e18d23SBram Moolenaar if (wp->w_jumplistidx == wp->w_jumplistlen)
1341a7e18d23SBram Moolenaar wp->w_jumplistidx = to;
1342a7e18d23SBram Moolenaar wp->w_jumplistlen = to;
1343071d4279SBram Moolenaar }
1344071d4279SBram Moolenaar
1345071d4279SBram Moolenaar /*
1346071d4279SBram Moolenaar * Copy the jumplist from window "from" to window "to".
1347071d4279SBram Moolenaar */
1348071d4279SBram Moolenaar void
copy_jumplist(win_T * from,win_T * to)134952ea13daSBram Moolenaar copy_jumplist(win_T *from, win_T *to)
1350071d4279SBram Moolenaar {
1351071d4279SBram Moolenaar int i;
1352071d4279SBram Moolenaar
1353071d4279SBram Moolenaar for (i = 0; i < from->w_jumplistlen; ++i)
1354071d4279SBram Moolenaar {
1355071d4279SBram Moolenaar to->w_jumplist[i] = from->w_jumplist[i];
1356071d4279SBram Moolenaar if (from->w_jumplist[i].fname != NULL)
1357071d4279SBram Moolenaar to->w_jumplist[i].fname = vim_strsave(from->w_jumplist[i].fname);
1358071d4279SBram Moolenaar }
1359071d4279SBram Moolenaar to->w_jumplistlen = from->w_jumplistlen;
1360071d4279SBram Moolenaar to->w_jumplistidx = from->w_jumplistidx;
1361071d4279SBram Moolenaar }
1362071d4279SBram Moolenaar
1363071d4279SBram Moolenaar /*
1364071d4279SBram Moolenaar * Free items in the jumplist of window "wp".
1365071d4279SBram Moolenaar */
1366071d4279SBram Moolenaar void
free_jumplist(win_T * wp)136752ea13daSBram Moolenaar free_jumplist(win_T *wp)
1368071d4279SBram Moolenaar {
1369071d4279SBram Moolenaar int i;
1370071d4279SBram Moolenaar
1371071d4279SBram Moolenaar for (i = 0; i < wp->w_jumplistlen; ++i)
1372071d4279SBram Moolenaar vim_free(wp->w_jumplist[i].fname);
1373071d4279SBram Moolenaar }
13744ba37b58SBram Moolenaar #endif // FEAT_JUMPLIST
1375071d4279SBram Moolenaar
1376071d4279SBram Moolenaar void
set_last_cursor(win_T * win)137752ea13daSBram Moolenaar set_last_cursor(win_T *win)
1378071d4279SBram Moolenaar {
13799db12933SBram Moolenaar if (win->w_buffer != NULL)
1380071d4279SBram Moolenaar win->w_buffer->b_last_cursor = win->w_cursor;
1381071d4279SBram Moolenaar }
1382071d4279SBram Moolenaar
1383ea408854SBram Moolenaar #if defined(EXITFREE) || defined(PROTO)
1384ea408854SBram Moolenaar void
free_all_marks(void)138552ea13daSBram Moolenaar free_all_marks(void)
1386ea408854SBram Moolenaar {
1387ea408854SBram Moolenaar int i;
1388ea408854SBram Moolenaar
1389ea408854SBram Moolenaar for (i = 0; i < NMARKS + EXTRA_MARKS; i++)
1390ea408854SBram Moolenaar if (namedfm[i].fmark.mark.lnum != 0)
1391ea408854SBram Moolenaar vim_free(namedfm[i].fname);
1392ea408854SBram Moolenaar }
1393ea408854SBram Moolenaar #endif
1394ea408854SBram Moolenaar
13952d358997SBram Moolenaar /*
13961e78e696SBram Moolenaar * Return a pointer to the named file marks.
13972d358997SBram Moolenaar */
13981e78e696SBram Moolenaar xfmark_T *
get_namedfm(void)13991e78e696SBram Moolenaar get_namedfm(void)
14002d358997SBram Moolenaar {
14011e78e696SBram Moolenaar return namedfm;
1402071d4279SBram Moolenaar }
1403cfb4b47dSBram Moolenaar
1404cfb4b47dSBram Moolenaar #if defined(FEAT_EVAL) || defined(PROTO)
1405cfb4b47dSBram Moolenaar /*
1406cfb4b47dSBram Moolenaar * Add information about mark 'mname' to list 'l'
1407cfb4b47dSBram Moolenaar */
1408cfb4b47dSBram Moolenaar static int
add_mark(list_T * l,char_u * mname,pos_T * pos,int bufnr,char_u * fname)1409cfb4b47dSBram Moolenaar add_mark(list_T *l, char_u *mname, pos_T *pos, int bufnr, char_u *fname)
1410cfb4b47dSBram Moolenaar {
1411cfb4b47dSBram Moolenaar dict_T *d;
1412cfb4b47dSBram Moolenaar list_T *lpos;
1413cfb4b47dSBram Moolenaar
1414cfb4b47dSBram Moolenaar if (pos->lnum <= 0)
1415cfb4b47dSBram Moolenaar return OK;
1416cfb4b47dSBram Moolenaar
1417cfb4b47dSBram Moolenaar d = dict_alloc();
1418cfb4b47dSBram Moolenaar if (d == NULL)
1419cfb4b47dSBram Moolenaar return FAIL;
1420cfb4b47dSBram Moolenaar
1421cfb4b47dSBram Moolenaar if (list_append_dict(l, d) == FAIL)
1422cfb4b47dSBram Moolenaar {
1423cfb4b47dSBram Moolenaar dict_unref(d);
1424cfb4b47dSBram Moolenaar return FAIL;
1425cfb4b47dSBram Moolenaar }
1426cfb4b47dSBram Moolenaar
1427cfb4b47dSBram Moolenaar lpos = list_alloc();
1428cfb4b47dSBram Moolenaar if (lpos == NULL)
1429cfb4b47dSBram Moolenaar return FAIL;
1430cfb4b47dSBram Moolenaar
1431cfb4b47dSBram Moolenaar list_append_number(lpos, bufnr);
1432cfb4b47dSBram Moolenaar list_append_number(lpos, pos->lnum);
1433f17e7ea6SBram Moolenaar list_append_number(lpos, pos->col + 1);
1434cfb4b47dSBram Moolenaar list_append_number(lpos, pos->coladd);
1435cfb4b47dSBram Moolenaar
1436cfb4b47dSBram Moolenaar if (dict_add_string(d, "mark", mname) == FAIL
1437cfb4b47dSBram Moolenaar || dict_add_list(d, "pos", lpos) == FAIL
1438cfb4b47dSBram Moolenaar || (fname != NULL && dict_add_string(d, "file", fname) == FAIL))
1439cfb4b47dSBram Moolenaar return FAIL;
1440cfb4b47dSBram Moolenaar
1441cfb4b47dSBram Moolenaar return OK;
1442cfb4b47dSBram Moolenaar }
1443cfb4b47dSBram Moolenaar
1444cfb4b47dSBram Moolenaar /*
1445cfb4b47dSBram Moolenaar * Get information about marks local to a buffer.
1446cfb4b47dSBram Moolenaar */
1447cfb4b47dSBram Moolenaar static void
get_buf_local_marks(buf_T * buf,list_T * l)1448cfb4b47dSBram Moolenaar get_buf_local_marks(buf_T *buf, list_T *l)
1449cfb4b47dSBram Moolenaar {
1450cfb4b47dSBram Moolenaar char_u mname[3] = "' ";
1451cfb4b47dSBram Moolenaar int i;
1452cfb4b47dSBram Moolenaar
1453cfb4b47dSBram Moolenaar // Marks 'a' to 'z'
1454cfb4b47dSBram Moolenaar for (i = 0; i < NMARKS; ++i)
1455cfb4b47dSBram Moolenaar {
1456cfb4b47dSBram Moolenaar mname[1] = 'a' + i;
1457cfb4b47dSBram Moolenaar add_mark(l, mname, &buf->b_namedm[i], buf->b_fnum, NULL);
1458cfb4b47dSBram Moolenaar }
1459cfb4b47dSBram Moolenaar
1460cfb4b47dSBram Moolenaar // Mark '' is a window local mark and not a buffer local mark
1461cfb4b47dSBram Moolenaar add_mark(l, (char_u *)"''", &curwin->w_pcmark, curbuf->b_fnum, NULL);
1462cfb4b47dSBram Moolenaar
1463cfb4b47dSBram Moolenaar add_mark(l, (char_u *)"'\"", &buf->b_last_cursor, buf->b_fnum, NULL);
1464cfb4b47dSBram Moolenaar add_mark(l, (char_u *)"'[", &buf->b_op_start, buf->b_fnum, NULL);
1465cfb4b47dSBram Moolenaar add_mark(l, (char_u *)"']", &buf->b_op_end, buf->b_fnum, NULL);
1466cfb4b47dSBram Moolenaar add_mark(l, (char_u *)"'^", &buf->b_last_insert, buf->b_fnum, NULL);
1467cfb4b47dSBram Moolenaar add_mark(l, (char_u *)"'.", &buf->b_last_change, buf->b_fnum, NULL);
1468cfb4b47dSBram Moolenaar add_mark(l, (char_u *)"'<", &buf->b_visual.vi_start, buf->b_fnum, NULL);
1469cfb4b47dSBram Moolenaar add_mark(l, (char_u *)"'>", &buf->b_visual.vi_end, buf->b_fnum, NULL);
1470cfb4b47dSBram Moolenaar }
1471cfb4b47dSBram Moolenaar
1472cfb4b47dSBram Moolenaar /*
1473cfb4b47dSBram Moolenaar * Get information about global marks ('A' to 'Z' and '0' to '9')
1474cfb4b47dSBram Moolenaar */
1475cfb4b47dSBram Moolenaar static void
get_global_marks(list_T * l)1476cfb4b47dSBram Moolenaar get_global_marks(list_T *l)
1477cfb4b47dSBram Moolenaar {
1478cfb4b47dSBram Moolenaar char_u mname[3] = "' ";
1479cfb4b47dSBram Moolenaar int i;
1480cfb4b47dSBram Moolenaar char_u *name;
1481cfb4b47dSBram Moolenaar
1482cfb4b47dSBram Moolenaar // Marks 'A' to 'Z' and '0' to '9'
1483cfb4b47dSBram Moolenaar for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
1484cfb4b47dSBram Moolenaar {
1485cfb4b47dSBram Moolenaar if (namedfm[i].fmark.fnum != 0)
1486cfb4b47dSBram Moolenaar name = buflist_nr2name(namedfm[i].fmark.fnum, TRUE, TRUE);
1487cfb4b47dSBram Moolenaar else
1488cfb4b47dSBram Moolenaar name = namedfm[i].fname;
1489cfb4b47dSBram Moolenaar if (name != NULL)
1490cfb4b47dSBram Moolenaar {
1491cfb4b47dSBram Moolenaar mname[1] = i >= NMARKS ? i - NMARKS + '0' : i + 'A';
1492cfb4b47dSBram Moolenaar add_mark(l, mname, &namedfm[i].fmark.mark,
1493cfb4b47dSBram Moolenaar namedfm[i].fmark.fnum, name);
1494cfb4b47dSBram Moolenaar if (namedfm[i].fmark.fnum != 0)
1495cfb4b47dSBram Moolenaar vim_free(name);
1496cfb4b47dSBram Moolenaar }
1497cfb4b47dSBram Moolenaar }
1498cfb4b47dSBram Moolenaar }
1499cfb4b47dSBram Moolenaar
1500cfb4b47dSBram Moolenaar /*
1501cfb4b47dSBram Moolenaar * getmarklist() function
1502cfb4b47dSBram Moolenaar */
1503cfb4b47dSBram Moolenaar void
f_getmarklist(typval_T * argvars,typval_T * rettv)1504cfb4b47dSBram Moolenaar f_getmarklist(typval_T *argvars, typval_T *rettv)
1505cfb4b47dSBram Moolenaar {
1506cfb4b47dSBram Moolenaar buf_T *buf = NULL;
1507cfb4b47dSBram Moolenaar
1508cfb4b47dSBram Moolenaar if (rettv_list_alloc(rettv) != OK)
1509cfb4b47dSBram Moolenaar return;
1510cfb4b47dSBram Moolenaar
15114490ec4eSYegappan Lakshmanan if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL)
15124490ec4eSYegappan Lakshmanan return;
15134490ec4eSYegappan Lakshmanan
1514cfb4b47dSBram Moolenaar if (argvars[0].v_type == VAR_UNKNOWN)
1515cfb4b47dSBram Moolenaar {
1516cfb4b47dSBram Moolenaar get_global_marks(rettv->vval.v_list);
1517cfb4b47dSBram Moolenaar return;
1518cfb4b47dSBram Moolenaar }
1519cfb4b47dSBram Moolenaar
1520cfb4b47dSBram Moolenaar buf = tv_get_buf(&argvars[0], FALSE);
1521cfb4b47dSBram Moolenaar if (buf == NULL)
1522cfb4b47dSBram Moolenaar return;
1523cfb4b47dSBram Moolenaar
1524cfb4b47dSBram Moolenaar get_buf_local_marks(buf, rettv->vval.v_list);
1525cfb4b47dSBram Moolenaar }
1526cfb4b47dSBram Moolenaar #endif
1527