aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c2
-rw-r--r--src/nvim/eval.c13
-rw-r--r--src/nvim/globals.h4
-rw-r--r--src/nvim/mark.c2
-rw-r--r--src/nvim/normal.c2
-rw-r--r--src/nvim/pos.h1
-rw-r--r--src/nvim/regexp.c73
-rw-r--r--src/nvim/regexp_nfa.c8
-rw-r--r--src/nvim/search.c2
-rw-r--r--src/nvim/tag.c2
-rw-r--r--src/nvim/testdir/test_functions.vim8
-rw-r--r--src/nvim/testdir/test_true_false.vim5
-rw-r--r--src/nvim/testdir/test_visual.vim103
13 files changed, 166 insertions, 59 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 6e4e7afeb2..8cb4e32815 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -2446,7 +2446,7 @@ void get_winopts(buf_T *buf)
*/
pos_T *buflist_findfpos(buf_T *buf)
{
- static pos_T no_position = INIT_POS_T(1, 0, 0);
+ static pos_T no_position = { 1, 0, 0 };
wininfo_T *wip = find_wininfo(buf, FALSE);
return (wip == NULL) ? &no_position : &(wip->wi_fpos);
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index aa0d925ff2..57777f049a 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -10086,10 +10086,23 @@ static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos)
tv_list_append_number(
l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
if (getcurpos) {
+ const int save_set_curswant = curwin->w_set_curswant;
+ const colnr_T save_curswant = curwin->w_curswant;
+ const colnr_T save_virtcol = curwin->w_virtcol;
+
update_curswant();
tv_list_append_number(l, (curwin->w_curswant == MAXCOL
? (varnumber_T)MAXCOL
: (varnumber_T)curwin->w_curswant + 1));
+
+ // Do not change "curswant", as it is unexpected that a get
+ // function has a side effect.
+ if (save_set_curswant) {
+ curwin->w_set_curswant = save_set_curswant;
+ curwin->w_curswant = save_curswant;
+ curwin->w_virtcol = save_virtcol;
+ curwin->w_valid &= ~VALID_VIRTCOL;
+ }
}
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 52c5d65512..004b3252da 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -602,7 +602,7 @@ EXTERN bool can_si INIT(= false);
EXTERN bool can_si_back INIT(= false);
// w_cursor before formatting text.
-EXTERN pos_T saved_cursor INIT(= INIT_POS_T(0, 0, 0));
+EXTERN pos_T saved_cursor INIT(= { 0, 0, 0 });
/*
* Stuff for insert mode.
@@ -789,7 +789,7 @@ EXTERN int autocmd_bufnr INIT(= 0); // fnum for <abuf> on cmdline
EXTERN char_u *autocmd_match INIT(= NULL); // name for <amatch> on cmdline
EXTERN int did_cursorhold INIT(= false); // set when CursorHold t'gerd
// for CursorMoved event
-EXTERN pos_T last_cursormoved INIT(= INIT_POS_T(0, 0, 0));
+EXTERN pos_T last_cursormoved INIT(= { 0, 0, 0 });
EXTERN int postponed_split INIT(= 0); /* for CTRL-W CTRL-] command */
EXTERN int postponed_split_flags INIT(= 0); /* args for win_split() */
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 05f78c76bc..602648c27c 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -924,7 +924,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2,
int i;
int fnum = curbuf->b_fnum;
linenr_T *lp;
- static pos_T initpos = INIT_POS_T(1, 0, 0);
+ static pos_T initpos = { 1, 0, 0 };
if (line2 < line1 && amount_after == 0L) /* nothing to do */
return;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 0b85714e39..f12abd362f 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -5444,7 +5444,7 @@ static void nv_csearch(cmdarg_T *cap)
*/
static void nv_brackets(cmdarg_T *cap)
{
- pos_T new_pos = INIT_POS_T(0, 0, 0);
+ pos_T new_pos = { 0, 0, 0 };
pos_T prev_pos;
pos_T *pos = NULL; /* init for GCC */
pos_T old_pos; /* cursor position before command */
diff --git a/src/nvim/pos.h b/src/nvim/pos.h
index 0a2afd5847..47d253e083 100644
--- a/src/nvim/pos.h
+++ b/src/nvim/pos.h
@@ -24,7 +24,6 @@ typedef struct {
colnr_T coladd;
} pos_T;
-# define INIT_POS_T(l, c, ca) {l, c, ca}
/*
* Same, but without coladd.
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 55490446e5..ab1a7c7b3e 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -1210,13 +1210,10 @@ char_u *skip_regexp(char_u *startp, int dirc, int magic, char_u **newp)
return p;
}
-///
/// Return TRUE if the back reference is legal. We must have seen the close
/// brace.
-/// TODO(billy4195): Should also check that we don't refer to something that is
-/// repeated
+/// TODO(vim): Should also check that we don't refer to something repeated
/// (+*=): what instance of the repetition should we match?
-///
static int seen_endbrace(int refnum)
{
if (!had_endbrace[refnum]) {
@@ -3388,17 +3385,13 @@ static long bt_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
return bt_regexec_both(NULL, col, tm, timed_out);
}
-/*
- * Match a regexp against a string ("line" points to the string) or multiple
- * lines ("line" is NULL, use reg_getline()).
- * Returns 0 for failure, number of lines contained in the match otherwise.
- */
+/// Match a regexp against a string ("line" points to the string) or multiple
+/// lines ("line" is NULL, use reg_getline()).
+/// @return 0 for failure, or number of lines contained in the match.
static long bt_regexec_both(char_u *line,
- // column to start looking for match
- colnr_T col,
+ colnr_T col, // column to start search
proftime_T *tm, // timeout limit or NULL
- int *timed_out // flag set on timeout or NULL
- )
+ int *timed_out) // flag set on timeout or NULL
{
bt_regprog_T *prog;
char_u *s;
@@ -3604,12 +3597,12 @@ void unref_extmatch(reg_extmatch_T *em)
}
}
-/*
- * regtry - try match of "prog" with at regline["col"].
- * Returns 0 for failure, number of lines contained in the match otherwise.
- */
-static long regtry(bt_regprog_T *prog, colnr_T col,
- proftime_T *tm, int *timed_out)
+/// Try match of "prog" with at regline["col"].
+/// @returns 0 for failure, or number of lines contained in the match.
+static long regtry(bt_regprog_T *prog,
+ colnr_T col,
+ proftime_T *tm, // timeout limit or NULL
+ int *timed_out) // flag set on timeout or NULL
{
reginput = regline + col;
need_clear_subexpr = TRUE;
@@ -3760,26 +3753,23 @@ static int reg_match_visual(void)
static long bl_minval;
static long bl_maxval;
-/*
- * regmatch - main matching routine
- *
- * Conceptually the strategy is simple: Check to see whether the current node
- * matches, push an item onto the regstack and loop to see whether the rest
- * matches, and then act accordingly. In practice we make some effort to
- * avoid using the regstack, in particular by going through "ordinary" nodes
- * (that don't need to know whether the rest of the match failed) by a nested
- * loop.
- *
- * Returns TRUE when there is a match. Leaves reginput and reglnum just after
- * the last matched character.
- * Returns FALSE when there is no match. Leaves reginput and reglnum in an
- * undefined state!
- */
-static int
-regmatch(
+/// Main matching routine
+///
+/// Conceptually the strategy is simple: Check to see whether the current node
+/// matches, push an item onto the regstack and loop to see whether the rest
+/// matches, and then act accordingly. In practice we make some effort to
+/// avoid using the regstack, in particular by going through "ordinary" nodes
+/// (that don't need to know whether the rest of the match failed) by a nested
+/// loop.
+///
+/// Returns TRUE when there is a match. Leaves reginput and reglnum just after
+/// the last matched character.
+/// Returns FALSE when there is no match. Leaves reginput and reglnum in an
+/// undefined state!
+static int regmatch(
char_u *scan, // Current node.
- proftime_T *tm,
- int *timed_out
+ proftime_T *tm, // timeout limit or NULL
+ int *timed_out // flag set on timeout or NULL
)
{
char_u *next; /* Next node. */
@@ -3788,14 +3778,13 @@ regmatch(
regitem_T *rp;
int no;
int status; // one of the RA_ values:
- int tm_count; // counter for checking timeout
+ int tm_count = 0;
#define RA_FAIL 1 // something failed, abort
#define RA_CONT 2 // continue in inner loop
#define RA_BREAK 3 // break inner loop
#define RA_MATCH 4 // successful match
#define RA_NOMATCH 5 // didn't match
- tm_count = 0;
// Make "regstack" and "backpos" empty. They are allocated and freed in
// bt_regexec_both() to reduce malloc()/free() calls.
regstack.ga_len = 0;
@@ -3825,9 +3814,13 @@ regmatch(
status = RA_FAIL;
break;
}
+ // Check for timeout once in a 100 times to avoid overhead.
if (tm != NULL && ++tm_count == 100) {
tm_count = 0;
if (profile_passed_limit(*tm)) {
+ if (timed_out != NULL) {
+ *timed_out = true;
+ }
status = RA_FAIL;
break;
}
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index e7ea036a3b..e0e8820b87 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -6276,8 +6276,10 @@ theend:
// Try match of "prog" with at regline["col"].
// Returns <= 0 for failure, number of lines contained in the match otherwise.
-static long nfa_regtry(nfa_regprog_T *prog, colnr_T col,
- proftime_T *tm, int *timed_out)
+static long nfa_regtry(nfa_regprog_T *prog,
+ colnr_T col,
+ proftime_T *tm, // timeout limit or NULL
+ int *timed_out) // flag set on timeout or NULL
{
int i;
regsubs_T subs, m;
@@ -6397,6 +6399,7 @@ static long nfa_regtry(nfa_regprog_T *prog, colnr_T col,
/// @param line String in which to search or NULL
/// @param startcol Column to start looking for match
/// @param tm Timeout limit or NULL
+/// @param timed_out Flag set on timeout or NULL
///
/// @return <= 0 if there is no match and number of lines contained in the
/// match otherwise.
@@ -6642,6 +6645,7 @@ nfa_regexec_nl (
/// @param lnum Number of line to start looking for match
/// @param col Column to start looking for match
/// @param tm Timeout limit or NULL
+/// @param timed_out Flag set on timeout or NULL
///
/// @return <= 0 if there is no match and number of lines contained in the match
/// otherwise.
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 3d95ad0e92..777ea07a21 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -526,7 +526,7 @@ int searchit(
int pat_use, // which pattern to use when "pat" is empty
linenr_T stop_lnum, // stop after this line number when != 0
proftime_T *tm, // timeout limit or NULL
- int *timed_out // set when timed out or NULL
+ int *timed_out // set when timed out or NULL
)
{
int found;
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index bd837a531d..410b9dfcbd 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -109,7 +109,7 @@ static char_u *tagmatchname = NULL; /* name of last used tag */
* Tag for preview window is remembered separately, to avoid messing up the
* normal tagstack.
*/
-static taggy_T ptag_entry = {NULL, {INIT_POS_T(0, 0, 0), 0, 0, NULL}, 0, 0};
+static taggy_T ptag_entry = { NULL, { { 0, 0, 0 }, 0, 0, NULL }, 0, 0 };
/*
* Jump to tag; handling of tag commands and tag stack
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index bfe13d6b2d..824baffbc9 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -956,8 +956,8 @@ func Test_balloon_show()
endfunc
func Test_shellescape()
- let save_shell = &shell
- set shell=bash
+ let [save_shell, save_shellslash] = [&shell, &shellslash]
+ set shell=bash shellslash
call assert_equal("'text'", shellescape('text'))
call assert_equal("'te\"xt'", shellescape('te"xt'))
call assert_equal("'te'\\''xt'", shellescape("te'xt"))
@@ -971,13 +971,13 @@ func Test_shellescape()
call assert_equal("'te\nxt'", shellescape("te\nxt"))
call assert_equal("'te\\\nxt'", shellescape("te\nxt", 1))
- set shell=tcsh
+ set shell=tcsh shellslash
call assert_equal("'te\\!xt'", shellescape("te!xt"))
call assert_equal("'te\\\\!xt'", shellescape("te!xt", 1))
call assert_equal("'te\\\nxt'", shellescape("te\nxt"))
call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1))
- let &shell = save_shell
+ let [&shell, &shellslash] = [save_shell, save_shellslash]
endfunc
func Test_redo_in_nested_functions()
diff --git a/src/nvim/testdir/test_true_false.vim b/src/nvim/testdir/test_true_false.vim
index 84aca737ac..4a5d47471d 100644
--- a/src/nvim/testdir/test_true_false.vim
+++ b/src/nvim/testdir/test_true_false.vim
@@ -57,6 +57,9 @@ endfunc
" Test using TRUE or FALSE values for an argument.
func Test_true_false_arg()
+ let shellslash = &shellslash
+ let wildignore = &wildignore
+ set shellslash
call Try_arg_true_false('count(["a", "A"], "a", %v%)', 1, 2)
set wildignore=*.swp
@@ -110,6 +113,8 @@ func Test_true_false_arg()
let here_id = synID(1, 3, 0)
call Try_arg_true_false('synID(1, 3, %v%)', here_id, brackets_id)
bwipe!
+ let &wildignore = wildignore
+ let &shellslash = shellslash
endfunc
function Try_arg_non_zero(expr, false_val, true_val)
diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim
index 4a143d665d..74afc72f03 100644
--- a/src/nvim/testdir/test_visual.vim
+++ b/src/nvim/testdir/test_visual.vim
@@ -1,8 +1,4 @@
" Tests for various Visual mode.
-if !has('visual')
- finish
-endif
-
func Test_block_shift_multibyte()
" Uses double-wide character.
@@ -278,9 +274,46 @@ func Test_visual_mode_reset()
set belloff&
endfunc
+func Test_Visual_word_textobject()
+ new
+ call setline(1, ['First sentence. Second sentence.'])
+
+ " When start and end of visual area are identical, 'aw' or 'iw' select
+ " the whole word.
+ norm! 1go2fcvawy
+ call assert_equal('Second ', @")
+ norm! 1go2fcviwy
+ call assert_equal('Second', @")
+
+ " When start and end of visual area are not identical, 'aw' or 'iw'
+ " extend the word in direction of the end of the visual area.
+ norm! 1go2fcvlawy
+ call assert_equal('cond ', @")
+ norm! gv2awy
+ call assert_equal('cond sentence.', @")
+
+ norm! 1go2fcvliwy
+ call assert_equal('cond', @")
+ norm! gv2iwy
+ call assert_equal('cond sentence', @")
+
+ " Extend visual area in opposite direction.
+ norm! 1go2fcvhawy
+ call assert_equal(' Sec', @")
+ norm! gv2awy
+ call assert_equal(' sentence. Sec', @")
+
+ norm! 1go2fcvhiwy
+ call assert_equal('Sec', @")
+ norm! gv2iwy
+ call assert_equal('. Sec', @")
+
+ bwipe!
+endfunc
+
func Test_Visual_sentence_textobject()
new
- call setline(1, ['First sentence. Second sentence. Third', 'sentence. Fouth sentence'])
+ call setline(1, ['First sentence. Second sentence. Third', 'sentence. Fourth sentence'])
" When start and end of visual area are identical, 'as' or 'is' select
" the whole sentence.
@@ -318,3 +351,63 @@ func Test_Visual_sentence_textobject()
bwipe!
endfunc
+
+func Test_curswant_not_changed()
+ new
+ call setline(1, ['one', 'two'])
+ au InsertLeave * call getcurpos()
+ call feedkeys("gg0\<C-V>jI123 \<Esc>j", 'xt')
+ call assert_equal([0, 2, 1, 0, 1], getcurpos())
+
+ bwipe!
+ au! InsertLeave
+endfunc
+
+func Test_Visual_paragraph_textobject()
+ new
+ call setline(1, ['First line.',
+ \ '',
+ \ 'Second line.',
+ \ 'Third line.',
+ \ 'Fourth line.',
+ \ 'Fifth line.',
+ \ '',
+ \ 'Sixth line.'])
+
+ " When start and end of visual area are identical, 'ap' or 'ip' select
+ " the whole paragraph.
+ norm! 4ggvapy
+ call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n\n", @")
+ norm! 4ggvipy
+ call assert_equal("Second line.\nThird line.\nFourth line.\nFifth line.\n", @")
+
+ " When start and end of visual area are not identical, 'ap' or 'ip'
+ " extend the sentence in direction of the end of the visual area.
+ " FIXME: actually, it is not sufficient to have different start and
+ " end of visual selection, the start line and end line have to differ,
+ " which is not consistent with the documentation.
+ norm! 4ggVjapy
+ call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
+ norm! gvapy
+ call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
+ norm! 4ggVjipy
+ call assert_equal("Third line.\nFourth line.\nFifth line.\n", @")
+ norm! gvipy
+ call assert_equal("Third line.\nFourth line.\nFifth line.\n\n", @")
+ norm! gvipy
+ call assert_equal("Third line.\nFourth line.\nFifth line.\n\nSixth line.\n", @")
+
+ " Extend visual area in opposite direction.
+ norm! 5ggVkapy
+ call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
+ norm! gvapy
+ call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
+ norm! 5ggVkipy
+ call assert_equal("Second line.\nThird line.\nFourth line.\n", @")
+ norma gvipy
+ call assert_equal("\nSecond line.\nThird line.\nFourth line.\n", @")
+ norm! gvipy
+ call assert_equal("First line.\n\nSecond line.\nThird line.\nFourth line.\n", @")
+
+ bwipe!
+endfunc