summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-03-22 14:08:59 +0100
committerBram Moolenaar <Bram@vim.org>2020-03-22 14:08:59 +0100
commit515545e11f523d14343b1e588dc0b9bd3d362bc2 (patch)
tree6770a882b96a447d8b455f7c98e6c557c221317a
parent97acfc781bdb7fa2838dc6e0e7f9952ea61bb2fd (diff)
patch 8.2.0425: code for modeless selection not sufficiently testedv8.2.0425
Problem: Code for modeless selection not sufficiently tested. Solution: Add tests. Move mouse code functionality to a common script file. (Yegappan Lakshmanan, closes #5821)
-rw-r--r--src/testdir/Make_all.mak4
-rw-r--r--src/testdir/gen_opt_test.vim2
-rw-r--r--src/testdir/mouse.vim172
-rw-r--r--src/testdir/test_edit.vim16
-rw-r--r--src/testdir/test_global.vim5
-rw-r--r--src/testdir/test_modeless.vim397
-rw-r--r--src/testdir/test_normal.vim24
-rw-r--r--src/testdir/test_selectmode.vim255
-rw-r--r--src/testdir/test_termcodes.vim202
-rw-r--r--src/testdir/test_visual.vim118
-rw-r--r--src/ui.c2
-rw-r--r--src/version.c2
12 files changed, 856 insertions, 343 deletions
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 81b780b648..d0bfe1c7c7 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -180,6 +180,7 @@ NEW_TESTS = \
test_method \
test_mksession \
test_mksession_utf8 \
+ test_modeless \
test_modeline \
test_move \
test_nested_function \
@@ -222,6 +223,7 @@ NEW_TESTS = \
test_search \
test_search_stat \
test_searchpos \
+ test_selectmode \
test_set \
test_sha256 \
test_shift \
@@ -406,6 +408,7 @@ NEW_TESTS_RES = \
test_messages.res \
test_method.res \
test_mksession.res \
+ test_modeless.res \
test_modeline.res \
test_nested_function.res \
test_netbeans.res \
@@ -440,6 +443,7 @@ NEW_TESTS_RES = \
test_scrollbind.res \
test_search.res \
test_search_stat.res \
+ test_selectmode.res \
test_shortpathname.res \
test_signals.res \
test_signs.res \
diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim
index c3b2325cc7..4cb168a8ad 100644
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -73,7 +73,7 @@ let test_values = {
\ 'buftype': [['', 'help', 'nofile'], ['xxx', 'help,nofile']],
\ 'casemap': [['', 'internal'], ['xxx']],
\ 'cedit': [['', '\<Esc>'], ['xxx', 'f']],
- \ 'clipboard': [['', 'unnamed', 'autoselect,unnamed'], ['xxx']],
+ \ 'clipboard': [['', 'unnamed', 'autoselect,unnamed', 'html', 'exclude:vimdisplay'], ['xxx', '\ze*']],
\ 'colorcolumn': [['', '8', '+2'], ['xxx']],
\ 'comments': [['', 'b:#'], ['xxx']],
\ 'commentstring': [['', '/*%s*/'], ['xxx']],
diff --git a/src/testdir/mouse.vim b/src/testdir/mouse.vim
new file mode 100644
index 0000000000..a28a439c19
--- /dev/null
+++ b/src/testdir/mouse.vim
@@ -0,0 +1,172 @@
+" Helper functions for generating mouse events
+
+" xterm2 and sgr always work, urxvt is optional.
+let g:Ttymouse_values = ['xterm2', 'sgr']
+if has('mouse_urxvt')
+ call add(g:Ttymouse_values, 'urxvt')
+endif
+
+" dec doesn't support all the functionality
+if has('mouse_dec')
+ let g:Ttymouse_dec = ['dec']
+else
+ let g:Ttymouse_dec = []
+endif
+
+" netterm only supports left click
+if has('mouse_netterm')
+ let g:Ttymouse_netterm = ['netterm']
+else
+ let g:Ttymouse_netterm = []
+endif
+
+" Helper function to emit a terminal escape code.
+func TerminalEscapeCode(code, row, col, m)
+ if &ttymouse ==# 'xterm2'
+ " need to use byte encoding here.
+ let str = list2str([a:code + 0x20, a:col + 0x20, a:row + 0x20])
+ if has('iconv')
+ let bytes = str->iconv('utf-8', 'latin1')
+ else
+ " Hopefully the numbers are not too big.
+ let bytes = str
+ endif
+ return "\<Esc>[M" .. bytes
+ elseif &ttymouse ==# 'sgr'
+ return printf("\<Esc>[<%d;%d;%d%s", a:code, a:col, a:row, a:m)
+ elseif &ttymouse ==# 'urxvt'
+ return printf("\<Esc>[%d;%d;%dM", a:code + 0x20, a:col, a:row)
+ endif
+endfunc
+
+func DecEscapeCode(code, down, row, col)
+ return printf("\<Esc>[%d;%d;%d;%d&w", a:code, a:down, a:row, a:col)
+endfunc
+
+func NettermEscapeCode(row, col)
+ return printf("\<Esc>}%d,%d\r", a:row, a:col)
+endfunc
+
+func MouseLeftClickCode(row, col)
+ if &ttymouse ==# 'dec'
+ return DecEscapeCode(2, 4, a:row, a:col)
+ elseif &ttymouse ==# 'netterm'
+ return NettermEscapeCode(a:row, a:col)
+ else
+ return TerminalEscapeCode(0, a:row, a:col, 'M')
+ endif
+endfunc
+
+func MouseLeftClick(row, col)
+ call feedkeys(MouseLeftClickCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseMiddleClickCode(row, col)
+ if &ttymouse ==# 'dec'
+ return DecEscapeCode(4, 2, a:row, a:col)
+ else
+ return TerminalEscapeCode(1, a:row, a:col, 'M')
+ endif
+endfunc
+
+func MouseMiddleClick(row, col)
+ call feedkeys(MouseMiddleClickCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseRightClickCode(row, col)
+ if &ttymouse ==# 'dec'
+ return DecEscapeCode(6, 1, a:row, a:col)
+ else
+ return TerminalEscapeCode(2, a:row, a:col, 'M')
+ endif
+endfunc
+
+func MouseRightClick(row, col)
+ call feedkeys(MouseRightClickCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseCtrlLeftClickCode(row, col)
+ let ctrl = 0x10
+ return TerminalEscapeCode(0 + ctrl, a:row, a:col, 'M')
+endfunc
+
+func MouseCtrlLeftClick(row, col)
+ call feedkeys(MouseCtrlLeftClickCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseCtrlRightClickCode(row, col)
+ let ctrl = 0x10
+ return TerminalEscapeCode(2 + ctrl, a:row, a:col, 'M')
+endfunc
+
+func MouseCtrlRightClick(row, col)
+ call feedkeys(MouseCtrlRightClickCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseLeftReleaseCode(row, col)
+ if &ttymouse ==# 'dec'
+ return DecEscapeCode(3, 0, a:row, a:col)
+ elseif &ttymouse ==# 'netterm'
+ return ''
+ else
+ return TerminalEscapeCode(3, a:row, a:col, 'm')
+ endif
+endfunc
+
+func MouseLeftRelease(row, col)
+ call feedkeys(MouseLeftReleaseCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseMiddleReleaseCode(row, col)
+ if &ttymouse ==# 'dec'
+ return DecEscapeCode(5, 0, a:row, a:col)
+ else
+ return TerminalEscapeCode(3, a:row, a:col, 'm')
+ endif
+endfunc
+
+func MouseMiddleRelease(row, col)
+ call feedkeys(MouseMiddleReleaseCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseRightReleaseCode(row, col)
+ if &ttymouse ==# 'dec'
+ return DecEscapeCode(7, 0, a:row, a:col)
+ else
+ return TerminalEscapeCode(3, a:row, a:col, 'm')
+ endif
+endfunc
+
+func MouseRightRelease(row, col)
+ call feedkeys(MouseRightReleaseCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseLeftDragCode(row, col)
+ if &ttymouse ==# 'dec'
+ return DecEscapeCode(1, 4, a:row, a:col)
+ else
+ return TerminalEscapeCode(0x20, a:row, a:col, 'M')
+ endif
+endfunc
+
+func MouseLeftDrag(row, col)
+ call feedkeys(MouseLeftDragCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseWheelUpCode(row, col)
+ return TerminalEscapeCode(0x40, a:row, a:col, 'M')
+endfunc
+
+func MouseWheelUp(row, col)
+ call feedkeys(MouseWheelUpCode(a:row, a:col), 'Lx!')
+endfunc
+
+func MouseWheelDownCode(row, col)
+ return TerminalEscapeCode(0x41, a:row, a:col, 'M')
+endfunc
+
+func MouseWheelDown(row, col)
+ call feedkeys(MouseWheelDownCode(a:row, a:col), 'Lx!')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
index b2d41990fc..32fc92ddb0 100644
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -257,22 +257,6 @@ func Test_edit_09()
bw!
endfunc
-func Test_edit_10()
- " Test for starting selectmode
- new
- set selectmode=key keymodel=startsel
- call setline(1, ['abc', 'def', 'ghi'])
- call cursor(1, 4)
- call feedkeys("A\<s-home>start\<esc>", 'txin')
- call assert_equal(['startdef', 'ghi'], getline(1, '$'))
- " start select mode again with gv
- set selectmode=cmd
- call feedkeys('gvabc', 'xt')
- call assert_equal('abctdef', getline(1))
- set selectmode= keymodel=
- bw!
-endfunc
-
func Test_edit_11()
" Test that indenting kicks in
new
diff --git a/src/testdir/test_global.vim b/src/testdir/test_global.vim
index 7804ca470e..d3bfaa90df 100644
--- a/src/testdir/test_global.vim
+++ b/src/testdir/test_global.vim
@@ -5,7 +5,10 @@ func Test_yank_put_clipboard()
set clipboard=unnamed
g/^/normal yyp
call assert_equal(['a', 'a', 'b', 'b', 'c', 'c'], getline(1, 6))
-
+ set clipboard=unnamed,unnamedplus
+ call setline(1, ['a', 'b', 'c'])
+ g/^/normal yyp
+ call assert_equal(['a', 'a', 'b', 'b', 'c', 'c'], getline(1, 6))
set clipboard&
bwipe!
endfunc
diff --git a/src/testdir/test_modeless.vim b/src/testdir/test_modeless.vim
new file mode 100644
index 0000000000..11ccc2c2ac
--- /dev/null
+++ b/src/testdir/test_modeless.vim
@@ -0,0 +1,397 @@
+" Test for modeless selection
+
+" This only works for Unix in a terminal
+source check.vim
+CheckNotGui
+CheckUnix
+
+source mouse.vim
+
+" Test for modeless characterwise selection (single click)
+func Test_modeless_characterwise_selection()
+ CheckFeature clipboard_working
+ let save_mouse = &mouse
+ let save_term = &term
+ let save_ttymouse = &ttymouse
+ call test_override('no_query_mouse', 1)
+ set mouse=a term=xterm mousetime=200
+ new
+ call setline(1, ['one two three', 'foo bar baz'])
+ redraw!
+
+ for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
+ let msg = 'ttymouse=' .. ttymouse_val
+ exe 'set ttymouse=' .. ttymouse_val
+
+ " select multiple characters within a line
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 6)
+ let keys ..= MouseLeftDragCode(1, 10)
+ let keys ..= MouseLeftReleaseCode(1, 10)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("wo th", @*, msg)
+
+ " select multiple characters including the end of line
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 11)
+ let keys ..= MouseLeftDragCode(1, 16)
+ let keys ..= MouseLeftReleaseCode(1, 16)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("ree\n", @*, msg)
+
+ " extend a selection using right mouse click
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ set mousemodel=extend
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 2)
+ let keys ..= MouseLeftDragCode(1, 5)
+ let keys ..= MouseLeftReleaseCode(1, 5)
+ let keys ..= MouseRightClickCode(1, 10)
+ let keys ..= MouseRightReleaseCode(1, 10)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("ne two th", @*, msg)
+ set mousemodel&
+
+ " extend a selection backwards using right mouse click
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ set mousemodel=extend
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 7)
+ let keys ..= MouseLeftDragCode(1, 11)
+ let keys ..= MouseLeftReleaseCode(1, 11)
+ let keys ..= MouseRightClickCode(1, 3)
+ let keys ..= MouseRightReleaseCode(1, 3)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("e two thr", @*, msg)
+ set mousemodel&
+
+ " select multiple characters within a line backwards
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 9)
+ let keys ..= MouseLeftDragCode(1, 3)
+ let keys ..= MouseLeftReleaseCode(1, 3)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("e two t", @*, msg)
+
+ " select multiple characters across lines with (end row > start row) and
+ " (end column < start column)
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 9)
+ let keys ..= MouseLeftDragCode(2, 3)
+ let keys ..= MouseLeftReleaseCode(2, 3)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("three\nfoo", @*, msg)
+
+ " select multiple characters across lines with (end row > start row) and
+ " (end column > start column)
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 4)
+ let keys ..= MouseLeftDragCode(2, 8)
+ let keys ..= MouseLeftReleaseCode(2, 8)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal(" two three\nfoo bar ", @*, msg)
+
+ " select multiple characters across lines with (end row < start row) and
+ " (end column < start column)
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(2, 7)
+ let keys ..= MouseLeftDragCode(1, 5)
+ let keys ..= MouseLeftReleaseCode(1, 5)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("two three\nfoo bar", @*, msg)
+
+ " select multiple characters across lines with (end row < start row) and
+ " (end column > start column)
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(2, 11)
+ let keys ..= MouseLeftDragCode(1, 13)
+ let keys ..= MouseLeftReleaseCode(1, 13)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("e\nfoo bar baz", @*, msg)
+
+ " select multiple characters across lines with (end row < start row) and
+ " the end column is greater than the line length
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(2, 7)
+ let keys ..= MouseLeftDragCode(1, 16)
+ let keys ..= MouseLeftReleaseCode(1, 16)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("\nfoo bar", @*, msg)
+
+ " select multiple characters across lines with start/end row and start/end
+ " column outside the lines in the buffer
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(4, 3)
+ let keys ..= MouseLeftDragCode(3, 2)
+ let keys ..= MouseLeftReleaseCode(3, 2)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("\n~ ", @*, msg)
+
+ " change selection using right mouse click within the selected text
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ set mousemodel=extend
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 5)
+ let keys ..= MouseLeftDragCode(1, 13)
+ let keys ..= MouseLeftReleaseCode(1, 13)
+ let keys ..= MouseRightClickCode(1, 7)
+ let keys ..= MouseRightReleaseCode(1, 7)
+ let keys ..= MouseRightClickCode(1, 11)
+ let keys ..= MouseRightReleaseCode(1, 11)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("o thr", @*, msg)
+ set mousemodel&
+
+ " select text multiple times at different places
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 3)
+ let keys ..= MouseLeftDragCode(1, 5)
+ let keys ..= MouseLeftReleaseCode(1, 5)
+ let keys ..= MouseLeftClickCode(2, 7)
+ let keys ..= MouseLeftDragCode(2, 9)
+ let keys ..= MouseLeftReleaseCode(2, 9)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("r b", @*, msg)
+
+ " Test for 'clipboard' set to 'autoselectml' to automatically copy the
+ " modeless selection to the clipboard
+ set clipboard=autoselectml
+ let @* = ''
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(2, 5)
+ let keys ..= MouseLeftDragCode(2, 7)
+ let keys ..= MouseLeftReleaseCode(2, 7)
+ let keys ..= "\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("bar", @*)
+ set clipboard&
+
+ " quadruple click should start characterwise selectmode
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 10)
+ let keys ..= MouseLeftReleaseCode(1, 10)
+ let keys ..= MouseLeftClickCode(1, 10)
+ let keys ..= MouseLeftReleaseCode(1, 10)
+ let keys ..= MouseLeftClickCode(1, 10)
+ let keys ..= MouseLeftReleaseCode(1, 10)
+ let keys ..= MouseLeftClickCode(1, 10)
+ let keys ..= MouseLeftDragCode(1, 11)
+ let keys ..= MouseLeftReleaseCode(1, 11)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("hree", @*, msg)
+ endfor
+
+ let &mouse = save_mouse
+ let &term = save_term
+ let &ttymouse = save_ttymouse
+ set mousetime&
+ call test_override('no_query_mouse', 0)
+ close!
+endfunc
+
+" Test for modeless word selection (double click)
+func Test_modeless_word_selection()
+ CheckFeature clipboard_working
+ let save_mouse = &mouse
+ let save_term = &term
+ let save_ttymouse = &ttymouse
+ call test_override('no_query_mouse', 1)
+ set mouse=a term=xterm mousetime=200
+ new
+ call setline(1, ['one two three', 'foo bar baz'])
+ redraw!
+
+ for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
+ let msg = 'ttymouse=' .. ttymouse_val
+ exe 'set ttymouse=' .. ttymouse_val
+
+ " select multiple words within a line
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 6)
+ let keys ..= MouseLeftReleaseCode(1, 6)
+ let keys ..= MouseLeftClickCode(1, 6)
+ let keys ..= MouseLeftDragCode(1, 10)
+ let keys ..= MouseLeftReleaseCode(1, 10)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("two three", @*, msg)
+
+ " select a single word
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(2, 6)
+ let keys ..= MouseLeftReleaseCode(2, 6)
+ let keys ..= MouseLeftClickCode(2, 6)
+ let keys ..= MouseLeftReleaseCode(2, 6)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("bar", @*, msg)
+
+ " select multiple words backwards within a line
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(2, 11)
+ let keys ..= MouseLeftReleaseCode(2, 11)
+ let keys ..= MouseLeftClickCode(2, 11)
+ let keys ..= MouseLeftDragCode(2, 7)
+ let keys ..= MouseLeftReleaseCode(2, 7)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("bar baz", @*, msg)
+
+ " select multiple words backwards across lines
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(2, 7)
+ let keys ..= MouseLeftReleaseCode(2, 7)
+ let keys ..= MouseLeftClickCode(2, 7)
+ let keys ..= MouseLeftDragCode(1, 6)
+ let keys ..= MouseLeftReleaseCode(1, 6)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("two three\nfoo bar", @*, msg)
+ endfor
+
+ let &mouse = save_mouse
+ let &term = save_term
+ let &ttymouse = save_ttymouse
+ set mousetime&
+ call test_override('no_query_mouse', 0)
+ close!
+endfunc
+
+" Test for modeless line selection (triple click)
+func Test_modeless_line_selection()
+ CheckFeature clipboard_working
+ let save_mouse = &mouse
+ let save_term = &term
+ let save_ttymouse = &ttymouse
+ call test_override('no_query_mouse', 1)
+ set mouse=a term=xterm mousetime=200
+ new
+ call setline(1, ['one two three', 'foo bar baz'])
+ redraw!
+
+ for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
+ let msg = 'ttymouse=' .. ttymouse_val
+ exe 'set ttymouse=' .. ttymouse_val
+
+ " select single line
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(2, 6)
+ let keys ..= MouseLeftReleaseCode(2, 6)
+ let keys ..= MouseLeftClickCode(2, 6)
+ let keys ..= MouseLeftReleaseCode(2, 6)
+ let keys ..= MouseLeftClickCode(2, 6)
+ let keys ..= MouseLeftReleaseCode(2, 6)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("foo bar baz\n", @*, msg)
+
+ " select multiple lines
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(1, 6)
+ let keys ..= MouseLeftReleaseCode(1, 6)
+ let keys ..= MouseLeftClickCode(1, 6)
+ let keys ..= MouseLeftReleaseCode(1, 6)
+ let keys ..= MouseLeftClickCode(1, 6)
+ let keys ..= MouseLeftDragCode(2, 12)
+ let keys ..= MouseLeftReleaseCode(2, 12)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("one two three\nfoo bar baz\n", @*, msg)
+
+ " select multiple lines backwards
+ let @* = ''
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+ let keys = ":"
+ let keys ..= MouseLeftClickCode(2, 10)
+ let keys ..= MouseLeftReleaseCode(2, 10)
+ let keys ..= MouseLeftClickCode(2, 10)
+ let keys ..= MouseLeftReleaseCode(2, 10)
+ let keys ..= MouseLeftClickCode(2, 10)
+ let keys ..= MouseLeftDragCode(1, 3)
+ let keys ..= MouseLeftReleaseCode(1, 3)
+ let keys ..= "\<C-Y>\<CR>"
+ call feedkeys(keys, "x")
+ call assert_equal("one two three\nfoo bar baz\n", @*, msg)
+ endfor
+
+ let &mouse = save_mouse
+ let &term = save_term
+ let &ttymouse = save_ttymouse
+ set mousetime&
+ call test_override('no_query_mouse', 0)
+ close!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index 5882f53169..c2cbc3e1b3 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -121,30 +121,6 @@ func Test_normal01_keymodel()
bw!
endfunc
-" Test for select mode
-func Test_normal02_selectmode()
- call Setup_NewWindow()
- 50
- norm! gHy
- call assert_equal('y51', getline('.'))
- call setline(1, range(1,100))
- 50
- exe ":norm! V9jo\<c-g>y"
- call assert_equal('y60', getline('.'))
- " clean up
- bw!
-endfunc
-
-func Test_normal02_selectmode2()
- " some basic select mode tests
- call Setup_NewWindow()
- 50
- call feedkeys(":set im\n\<c-o>gHc\<c-o>:set noim\n", 'tx')
- call assert_equal('c51', getline('.'))
- " clean up
- bw!
-endfunc
-
func Test_normal03_join()
" basic join test
call Setup_NewWindow()
diff --git a/src/testdir/test_selectmode.vim b/src/testdir/test_selectmode.vim
new file mode 100644
index 0000000000..92951efa67
--- /dev/null
+++ b/src/testdir/test_selectmode.vim
@@ -0,0 +1,255 @@
+" Test for Select-mode
+
+" This only works for Unix in a terminal
+source check.vim
+CheckNotGui
+CheckUnix
+
+source mouse.vim
+
+" Test for select mode
+func Test_selectmode_basic()
+ new
+ call setline(1, range(1,100))
+ 50
+ norm! gHy
+ call assert_equal('y51', getline('.'))
+ call setline(1, range(1,100))
+ 50
+ exe ":norm! V9jo\<c-g>y"
+ call assert_equal('y60', getline('.'))
+ call setline(1, range(1,100))
+ 50
+ call feedkeys(":set im\n\<c-o>gHc\<c-o>:set noim\n", 'tx')
+ call assert_equal('c51', getline('.'))
+ " clean up
+ bw!
+endfunc
+
+" Test for starting selectmode
+func Test_selectmode_start()
+ new
+ set selectmode=key keymodel=startsel
+ call setline(1, ['abc', 'def', 'ghi'])
+ call cursor(1, 4)
+ call feedkeys("A\<s-home>start\<esc>", 'txin')
+ call assert_equal(['startdef', 'ghi'], getline(1, '$'))
+ " start select mode again with gv
+ set selectmode=cmd
+ call feedkeys('gvabc', 'xt')
+ call assert_equal('abctdef', getline(1))
+ set selectmode= keymodel=
+ bw!
+endfunc
+
+" Test for characterwise select mode
+func Test_characterwise_select_mode()
+ new
+
+ " Select mode maps
+ snoremap <lt>End> <End>
+ snoremap <lt>Down> <Down>
+ snoremap <lt>Del> <Del>
+
+ " characterwise select mode: delete middle line
+ call deletebufline('', 1, '$')
+ call append('$', ['a', 'b', 'c'])
+ exe "normal Gkkgh\<End>\<Del>"
+ call assert_equal(['', 'b', 'c'], getline(1, '$'))
+
+ " characterwise select mode: delete middle two lines
+ call deletebufline('', 1, '$')
+ call append('$', ['a', 'b', 'c'])
+ exe "normal Gkkgh\<Down>\<End>\<Del>"
+ call assert_equal(['', 'c'], getline(1, '$'))
+
+ " characterwise select mode: delete last line
+ call deletebufline('', 1, '$')
+ call append('$', ['a', 'b', 'c'])
+ exe "normal Ggh\<End>\<Del>"
+ call assert_equal(['', 'a', 'b', ''], getline(1, '$'))
+
+ " characterwise select mode: delete last two lines
+ call deletebufline('', 1, '$')
+ call append('$', ['a', 'b', 'c'])
+ exe "normal Gkgh\<Down>\<End>\<Del>"
+ call assert_equal(['', 'a', ''], getline(1, '$'))
+
+ " CTRL-H in select mode behaves like 'x'
+ call setline(1, 'abcdef')
+ exe "normal! gggh\<Right>\<Right>\<Right>\<C-H>"
+ call assert_equal('ef', getline(1))
+
+ " CTRL-O in select mode switches to visual mode for one command
+ call setline(1, 'abcdef')
+ exe "normal! gggh\<C-O>3lm"
+ call assert_equal('mef', getline(1))
+
+ sunmap <lt>End>
+ sunmap <lt>Down>
+ sunmap <lt>Del>
+ bwipe!
+endfunc
+
+" Test for linewise select mode
+func Test_linewise_select_mode()
+ new
+
+ " linewise select mode: delete middle line
+ call append('$', ['a', 'b', 'c'])
+ exe "normal GkkgH\<Del>"
+ call assert_equal(['', 'b', 'c'], getline(1, '$'))
+
+ " linewise select mode: delete middle two lines
+ call deletebufline('', 1, '$')
+ call append('$', ['a', 'b', 'c'])
+ exe "normal GkkgH\<Down>\<Del>"
+ call assert_equal(['', 'c'], getline(1, '$'))
+
+ " linewise select mode: delete last line
+ call deletebufline('', 1, '$')
+ call append('$', ['a', 'b', 'c'])
+ exe "normal GgH\<Del>"
+ call assert_equal(['', 'a', 'b'], getline(1, '$'))
+
+ " linewise select mode: delete last two lines
+ call deletebufline('', 1, '$')
+ call append('$', ['a', 'b', 'c'])
+ exe "normal GkgH\<Down>\<Del>"
+ call assert_equal(['', 'a'], getline(1, '$'))
+
+ bwipe!
+endfunc
+
+" Test for blockwise select mode (g CTRL-H)
+func Test_blockwise_select_mode()
+ new
+ call setline(1, ['foo', 'bar'])
+ call feedkeys("g\<BS>\<Right>\<Down>mm", 'xt')
+ call assert_equal(['mmo', 'mmr'], getline(1, '$'))
+ close!
+endfunc
+
+" Test for using visual mode maps in select mode
+func Test_select_mode_map()
+ new
+ vmap <buffer> <F2> 3l
+ call setline(1, 'Test line')
+ call feedkeys("gh\<F2>map", 'xt')
+ call assert_equal('map line', getline(1))
+
+ vmap <buffer> <F2> ygV
+ call feedkeys("0gh\<Right>\<Right>\<F2>cwabc", 'xt')
+ call assert_equal('abc line', getline(1))
+
+ vmap <buffer> <F2> :<C-U>let v=100<CR>
+ call feedkeys("gggh\<Right>\<Right>\<F2>foo", 'xt')
+ call assert_equal('foo line', getline(1))
+
+ " reselect the select mode using gv from a visual mode map
+ vmap <buffer> <F2> gv
+ set selectmode=cmd
+ call feedkeys("0gh\<F2>map", 'xt')
+ call assert_equal('map line', getline(1))
+ set selectmode&
+
+ close!
+endfunc
+
+" Test double/triple/quadruple click to start 'select' mode
+func Test_term_mouse_multiple_clicks_to_select_mode()
+ let save_mouse = &mouse
+ let save_term = &term
+ let save_ttymouse = &ttymouse
+ call test_override('no_query_mouse', 1)
+ set mouse=a term=xterm mousetime=200
+ set selectmode=mouse
+ new
+
+ for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
+ let msg = 'ttymouse=' .. ttymouse_val
+ exe 'set ttymouse=' .. ttymouse_val
+
+ " Single-click and drag should 'select' the characters
+ call setline(1, ['foo [foo bar] foo', 'foo'])
+ call MouseLeftClick(1, 3)
+ call assert_equal(0, getcharmod(), msg)
+ call MouseLeftDrag(1, 13)
+ call MouseLeftRelease(1, 13)
+ norm! o
+ call assert_equal(['foo foo', 'foo'], getline(1, '$'), msg)
+
+ " Double-click on word should visually 'select' the word.
+ call setline(1, ['foo [foo bar] foo', 'foo'])
+ call MouseLeftClick(1, 2)
+ call assert_equal(0, getcharmod(), msg)
+ call MouseLeftRelease(1, 2)
+ call MouseLeftClick(1, 2)
+ call assert_equal(32, getcharmod(), msg) " double-click
+ call MouseLeftRelease(1, 2)
+ call assert_equal('s', mode(), msg)
+ norm! bar
+ call assert_equal(['bar [foo bar] foo', 'foo'], getline(1, '$'), msg)
+
+ " Double-click on opening square bracket should visually
+ " 'select' the whole [foo bar].
+ call setline(1, ['foo [foo bar] foo', 'foo'])
+ call MouseLeftClick(1, 5)
+ call assert_equal(0, getcharmod(), msg)
+ call MouseLeftRelease(1, 5)
+ call MouseLeftClick(1, 5)
+ call assert_equal(32, getcharmod(), msg) " double-click
+ call MouseLeftRelease(1, 5)
+ call assert_equal('s', mode(), msg)
+ norm! bar
+ call assert_equal(['foo bar foo', 'foo'], getline(1, '$'), msg)
+
+ " To guarantee that the next click is not counted as a triple click
+ call MouseRightClick(1, 1)
+ call MouseRightRelease(1, 1)
+
+ " Triple-click should visually 'select' the whole line.
+ call setline(1, ['foo [foo bar] foo', 'foo'])
+ call MouseLeftClick(1, 3)
+ call assert_equal(0, getcharmod(), msg)
+ call MouseLeftRelease(1, 3)
+ call MouseLeftClick(1, 3)
+ call assert_equal(32, getcharmod(), msg) " double-click
+ call MouseLeftRelease(1, 3)
+ call MouseLeftClick(1, 3)
+ call assert_equal(64, getcharmod(), msg) " triple-click
+ call MouseLeftRelease(1, 3)
+ call assert_equal('S', mode(), msg)
+ norm! baz
+ call assert_equal(['bazfoo'], getline(1, '$'), msg)
+
+ " Quadruple-click should start visual block 'select'.
+ call setline(1, ['aaaaaa', 'bbbbbb'])
+ call MouseLeftClick(1, 2)
+ call assert_equal(0, getcharmod(), msg)
+ call MouseLeftRelease(1, 2)
+ call MouseLeftClick(1, 2)
+ call assert_equal(32, getcharmod(), msg) " double-click
+ call MouseLeftRelease(1, 2)
+ call MouseLeftClick(1, 2)
+ call assert_equal(64, getcharmod(), msg) " triple-click
+ call MouseLeftRelease(1, 2)
+ call MouseLeftClick(1, 2)
+ call assert_equal(96, getcharmod(), msg) " quadruple-click
+ call MouseLeftDrag(2, 4)
+ call MouseLeftRelease(2, 4)
+ call assert_equal("\<c-s>", mode(), msg)
+ norm! x
+ call assert_equal(['axaa', 'bxbb'], getline(1, '$'), msg)
+ endfor
+
+ let &mouse = save_mouse
+ let &term = save_term
+ let &ttymouse = save_ttymouse
+ set mousetime&
+ set selectmode&
+ call test_override('no_query_mouse', 0)
+ bwipe!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_termcodes.vim b/src/testdir/test_termcodes.vim
index 3925bd7c16..f27648eb5e 100644
--- a/src/testdir/test_termcodes.vim
+++ b/src/testdir/test_termcodes.vim
@@ -6,175 +6,7 @@ CheckNotGui
CheckUnix
source shared.vim
-
-" xterm2 and sgr always work, urxvt is optional.
-let s:ttymouse_values = ['xterm2', 'sgr']
-if has('mouse_urxvt')
- call add(s:ttymouse_values, 'urxvt')
-endif
-
-" dec doesn't support all the functionality
-if has('mouse_dec')
- let s:ttymouse_dec = ['dec']
-else
- let s:ttymouse_dec = []
-endif
-
-" netterm only supports left click
-if has('mouse_netterm')
- let s:ttymouse_netterm = ['netterm']
-else
- let s:ttymouse_netterm = []
-endif
-
-" Helper function to emit a terminal escape code.
-func TerminalEscapeCode(code, row, col, m)
- if &ttymouse ==# 'xterm2'
- " need to use byte encoding here.
- let s