summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-01-28 18:23:54 +0100
committerBram Moolenaar <Bram@vim.org>2017-01-28 18:23:54 +0100
commitf13e00b2cf381e13fd327b5387a5bd6f004ac2a3 (patch)
tree31105fdbc8e8c7894b986619c65e14d369fa0090
parentc7b831ca154537505f5a22d01335a86b2e9cb023 (diff)
patch 8.0.0255: setpos() does not use the buffer argument for all marksv8.0.0255
Problem: When calling setpos() with a buffer argument it often is ignored. (Matthew Malcomson) Solution: Make the buffer argument work for all marks local to a buffer. (neovim #5713) Add more tests.
-rw-r--r--runtime/doc/eval.txt10
-rw-r--r--src/mark.c24
-rw-r--r--src/testdir/test_marks.vim44
-rw-r--r--src/version.c2
4 files changed, 67 insertions, 13 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 687c60532d..f69bf06a1a 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -6798,10 +6798,12 @@ setpos({expr}, {list})
[bufnum, lnum, col, off, curswant]
"bufnum" is the buffer number. Zero can be used for the
- current buffer. Setting the cursor is only possible for
- the current buffer. To set a mark in another buffer you can
- use the |bufnr()| function to turn a file name into a buffer
- number.
+ current buffer. When setting an uppercase mark "bufnum" is
+ used for the mark position. For other marks it specifies the
+ buffer to set the mark in. You can use the |bufnr()| function
+ to turn a file name into a buffer number.
+ For setting the cursor and the ' mark "bufnum" is ignored,
+ since these are associated with a window, not a buffer.
Does not change the jumplist.
"lnum" and "col" are the position in the buffer. The first
diff --git a/src/mark.c b/src/mark.c
index 9c84bc40dc..59ac01dc51 100644
--- a/src/mark.c
+++ b/src/mark.c
@@ -57,6 +57,7 @@ setmark(int c)
setmark_pos(int c, pos_T *pos, int fnum)
{
int i;
+ buf_T *buf;
/* Check for a special key (may cause islower() to crash). */
if (c < 0)
@@ -75,9 +76,13 @@ setmark_pos(int c, pos_T *pos, int fnum)
return OK;
}
+ buf = buflist_findnr(fnum);
+ if (buf == NULL)
+ return FAIL;
+
if (c == '"')
{
- curbuf->b_last_cursor = *pos;
+ buf->b_last_cursor = *pos;
return OK;
}
@@ -85,31 +90,31 @@ setmark_pos(int c, pos_T *pos, int fnum)
* file. */
if (c == '[')
{
- curbuf->b_op_start = *pos;
+ buf->b_op_start = *pos;
return OK;
}
if (c == ']')
{
- curbuf->b_op_end = *pos;
+ buf->b_op_end = *pos;
return OK;
}
if (c == '<' || c == '>')
{
if (c == '<')
- curbuf->b_visual.vi_start = *pos;
+ buf->b_visual.vi_start = *pos;
else
- curbuf->b_visual.vi_end = *pos;
- if (curbuf->b_visual.vi_mode == NUL)
+ buf->b_visual.vi_end = *pos;
+ if (buf->b_visual.vi_mode == NUL)
/* Visual_mode has not yet been set, use a sane default. */
- curbuf->b_visual.vi_mode = 'v';
+ buf->b_visual.vi_mode = 'v';
return OK;
}
if (ASCII_ISLOWER(c))
{
i = c - 'a';
- curbuf->b_namedm[i] = *pos;
+ buf->b_namedm[i] = *pos;
return OK;
}
if (ASCII_ISUPPER(c) || VIM_ISDIGIT(c))
@@ -396,7 +401,8 @@ getmark_buf_fnum(
{
startp = &buf->b_visual.vi_start;
endp = &buf->b_visual.vi_end;
- if ((c == '<') == lt(*startp, *endp))
+ if (((c == '<') == lt(*startp, *endp) || endp->lnum == 0)
+ && startp->lnum != 0)
posp = startp;
else
posp = endp;
diff --git a/src/testdir/test_marks.vim b/src/testdir/test_marks.vim
index d00b1ddc88..18a0c71aab 100644
--- a/src/testdir/test_marks.vim
+++ b/src/testdir/test_marks.vim
@@ -24,3 +24,47 @@ function! Test_Incr_Marks()
call assert_equal("XXX 123 123", getline(3))
enew!
endfunction
+
+func Test_setpos()
+ new one
+ let onebuf = bufnr('%')
+ let onewin = win_getid()
+ call setline(1, ['aaa', 'bbb', 'ccc'])
+ new two
+ let twobuf = bufnr('%')
+ let twowin = win_getid()
+ call setline(1, ['aaa', 'bbb', 'ccc'])
+
+ " for the cursor the buffer number is ignored
+ call setpos(".", [0, 2, 1, 0])
+ call assert_equal([0, 2, 1, 0], getpos("."))
+ call setpos(".", [onebuf, 3, 3, 0])
+ call assert_equal([0, 3, 3, 0], getpos("."))
+
+ call setpos("''", [0, 1, 3, 0])
+ call assert_equal([0, 1, 3, 0], getpos("''"))
+ call setpos("''", [onebuf, 2, 2, 0])
+ call assert_equal([0, 2, 2, 0], getpos("''"))
+
+ " buffer-local marks
+ for mark in ["'a", "'\"", "'[", "']", "'<", "'>"]
+ call win_gotoid(twowin)
+ call setpos(mark, [0, 2, 1, 0])
+ call assert_equal([0, 2, 1, 0], getpos(mark), "for mark " . mark)
+ call setpos(mark, [onebuf, 1, 3, 0])
+ call win_gotoid(onewin)
+ call assert_equal([0, 1, 3, 0], getpos(mark), "for mark " . mark)
+ endfor
+
+ " global marks
+ call win_gotoid(twowin)
+ call setpos("'N", [0, 2, 1, 0])
+ call assert_equal([twobuf, 2, 1, 0], getpos("'N"))
+ call setpos("'N", [onebuf, 1, 3, 0])
+ call assert_equal([onebuf, 1, 3, 0], getpos("'N"))
+
+ call win_gotoid(onewin)
+ bwipe!
+ call win_gotoid(twowin)
+ bwipe!
+endfunc
diff --git a/src/version.c b/src/version.c
index e66e1b97c5..4d73ae64c8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 255,
+/**/
254,
/**/
253,