terminal: Keep cursor position.

Let the terminal dictate the normal-mode cursor position. This will be
disorienting sometimes, but it is closer to what users expect vs always
going to the last line.
This commit is contained in:
Justin M. Keyes 2017-02-27 03:10:55 +01:00
parent 504693ce66
commit 937e54f865
9 changed files with 52 additions and 109 deletions

View File

@ -16,14 +16,12 @@ Normal commands ~
*]f* *]f*
*[f* Same as "gf". *[f* Same as "gf".
Commands ~ Commands ~
*:rv* *:rv*
*:rviminfo* Deprecated alias to |:rshada| command. *:rviminfo* Deprecated alias to |:rshada| command.
*:wv* *:wv*
*:wviminfo* Deprecated alias to |:wshada| command. *:wviminfo* Deprecated alias to |:wshada| command.
Events ~ Events ~
*EncodingChanged* Never fired; 'encoding' is always "utf-8". *EncodingChanged* Never fired; 'encoding' is always "utf-8".
*FileEncoding* Never fired; equivalent to |EncodingChanged|. *FileEncoding* Never fired; equivalent to |EncodingChanged|.
@ -31,6 +29,10 @@ Events ~
Highlight groups ~ Highlight groups ~
*hl-VisualNOS* Obsolete. |vim-differences| {Nvim} *hl-VisualNOS* Obsolete. |vim-differences| {Nvim}
Keycodes ~
*<MouseDown>* Use <ScrollWheelUp> instead.
*<MouseUp>* Use <ScrollWheelDown> instead.
Functions ~ Functions ~
*buffer_exists()* Obsolete name for |bufexists()|. *buffer_exists()* Obsolete name for |bufexists()|.
*buffer_name()* Obsolete name for |bufname()|. *buffer_name()* Obsolete name for |bufname()|.

View File

@ -235,15 +235,9 @@ This allows quick adjustment of the relative offset of 'scrollbind' windows.
============================================================================== ==============================================================================
6. Scrolling with a mouse wheel *scroll-mouse-wheel* 6. Scrolling with a mouse wheel *scroll-mouse-wheel*
When your mouse has a scroll wheel, it should work with Vim in the GUI. How When your mouse has a scroll wheel, it should work with Nvim in the GUI and
it works depends on your system. It might also work in an xterm any terminal that has mouse support. By default only vertical scroll wheels
|xterm-mouse-wheel|. By default only vertical scroll wheels are supported, are supported, but some GUIs also support horizontal scroll wheels.
but some GUIs also support horizontal scroll wheels.
For the Win32 GUI the scroll action is hard coded. It works just like
dragging the scrollbar of the current window. How many lines are scrolled
depends on your mouse driver. If the scroll action causes input focus
problems, see |intellimouse-wheel-problems|.
Note that horizontal scrolling only works if 'nowrap' is set. Also, unless Note that horizontal scrolling only works if 'nowrap' is set. Also, unless
the "h" flag in 'guioptions' is set, the cursor moves to the longest visible the "h" flag in 'guioptions' is set, the cursor moves to the longest visible
@ -258,43 +252,4 @@ the scroll wheel move one line or half a page in Normal mode: >
:map <S-ScrollWheelDown> <C-D> :map <S-ScrollWheelDown> <C-D>
You can also use Alt and Ctrl modifiers. You can also use Alt and Ctrl modifiers.
This only works when Vim gets the scroll wheel events, of course. You can
check if this works with the "xev" program.
*<MouseDown>* *<MouseUp>*
The keys <MouseDown> and <MouseUp> have been deprecated. Use <ScrollWheelUp>
instead of <MouseDown> and use <ScrollWheelDown> instead of <MouseUp>.
*xterm-mouse-wheel*
To use the mouse wheel in a new xterm you only have to make the scroll wheel
work in your Xserver, as mentioned above.
To use the mouse wheel in an older xterm you must do this:
1. Make it work in your Xserver, as mentioned above.
2. Add translations for the xterm, so that the xterm will pass a scroll event
to Vim as an escape sequence.
3. Add mappings in Vim, to interpret the escape sequences as <ScrollWheelDown>
or <ScrollWheelUp> keys.
You can do the translations by adding this to your ~.Xdefaults file (or other
file where your X resources are kept): >
XTerm*VT100.Translations: #override \n\
s<Btn4Down>: string("0x9b") string("[64~") \n\
s<Btn5Down>: string("0x9b") string("[65~") \n\
<Btn4Down>: string("0x9b") string("[62~") \n\
<Btn5Down>: string("0x9b") string("[63~") \n\
<Btn4Up>: \n\
<Btn5Up>:
Add these mappings to your vimrc file: >
:map <M-Esc>[62~ <ScrollWheelUp>
:map! <M-Esc>[62~ <ScrollWheelUp>
:map <M-Esc>[63~ <ScrollWheelDown>
:map! <M-Esc>[63~ <ScrollWheelDown>
:map <M-Esc>[64~ <S-ScrollWheelUp>
:map! <M-Esc>[64~ <S-ScrollWheelUp>
:map <M-Esc>[65~ <S-ScrollWheelDown>
:map! <M-Esc>[65~ <S-ScrollWheelDown>
<
vim:tw=78:ts=8:ft=help:norl: vim:tw=78:ts=8:ft=help:norl:

View File

@ -1126,18 +1126,17 @@ static void redraw(bool restore_cursor)
update_screen(0); update_screen(0);
} }
if (term && is_focused(term)) { if (restore_cursor) {
curwin->w_wrow = term->cursor.row;
curwin->w_wcol = term->cursor.col + win_col_off(curwin);
setcursor();
} else if (restore_cursor) {
ui_cursor_goto(save_row, save_col); ui_cursor_goto(save_row, save_col);
} else if (term) { } else if (term) {
// exiting terminal focus, put the window cursor in a valid position curwin->w_wrow = term->cursor.row;
int height, width; curwin->w_wcol = term->cursor.col + win_col_off(curwin);
vterm_get_size(term->vt, &height, &width); curwin->w_cursor.lnum = MIN(curbuf->b_ml.ml_line_count,
curwin->w_wrow = height - 1; row_to_linenr(term, term->cursor.row));
curwin->w_wcol = 0; // Nudge cursor when returning to normal-mode.
int off = is_focused(term) ? 0 : (curwin->w_p_rl ? 1 : -1);
curwin->w_cursor.col = MAX(0, term->cursor.col + win_col_off(curwin) + off);
curwin->w_cursor.coladd = 0;
setcursor(); setcursor();
} }
@ -1153,6 +1152,7 @@ static void adjust_topline(Terminal *term, buf_T *buf, long added)
if (wp->w_buffer == buf) { if (wp->w_buffer == buf) {
linenr_T ml_end = buf->b_ml.ml_line_count; linenr_T ml_end = buf->b_ml.ml_line_count;
bool following = ml_end == wp->w_cursor.lnum + added; // cursor at end? bool following = ml_end == wp->w_cursor.lnum + added; // cursor at end?
if (following || (wp == curwin && is_focused(term))) { if (following || (wp == curwin && is_focused(term))) {
// "Follow" the terminal output // "Follow" the terminal output
wp->w_cursor.lnum = ml_end; wp->w_cursor.lnum = ml_end;

View File

@ -22,9 +22,9 @@ describe('TermClose event', function()
execute('terminal') execute('terminal')
feed('<c-\\><c-n>') feed('<c-\\><c-n>')
screen:expect([[ screen:expect([[
ready $ | ^ready $ |
[Process exited 0] | [Process exited 0] |
^ | |
TermClose works! | TermClose works! |
]]) ]])
end) end)

View File

@ -50,11 +50,11 @@ describe('terminal buffer', function()
feed('<c-\\><c-n>') feed('<c-\\><c-n>')
screen:expect([[ screen:expect([[
tty ready | tty ready |
{2: } | {2:^ } |
|
| |
| |
| |
^ |
| |
]]) ]])
end) end)
@ -74,11 +74,11 @@ describe('terminal buffer', function()
feed('<c-\\><c-n>dd') feed('<c-\\><c-n>dd')
screen:expect([[ screen:expect([[
tty ready | tty ready |
{2: } | {2:^ } |
|
| |
| |
| |
^ |
{8:E21: Cannot make changes, 'modifiable' is off} | {8:E21: Cannot make changes, 'modifiable' is off} |
]]) ]])
end) end)

View File

@ -34,11 +34,11 @@ describe('terminal cursor', function()
feed('<c-\\><c-n>') feed('<c-\\><c-n>')
screen:expect([[ screen:expect([[
tty ready | tty ready |
{2: } | {2:^ } |
|
| |
| |
| |
^ |
| |
]]) ]])
end) end)
@ -51,11 +51,11 @@ describe('terminal cursor', function()
it('is positioned correctly when unfocused', function() it('is positioned correctly when unfocused', function()
screen:expect([[ screen:expect([[
{7: 1 }tty ready | {7: 1 }tty ready |
{7: 2 }{2: } | {7: 2 }{2:^ } |
{7: 3 } | {7: 3 } |
{7: 4 } | {7: 4 } |
{7: 5 } | {7: 5 } |
{7: 6 }^ | {7: 6 } |
:set number | :set number |
]]) ]])
end) end)
@ -101,21 +101,21 @@ describe('terminal cursor', function()
hide_cursor() hide_cursor()
screen:expect([[ screen:expect([[
tty ready | tty ready |
|
|
|
|
^ | ^ |
| |
|
|
|
|
]]) ]])
show_cursor() show_cursor()
screen:expect([[ screen:expect([[
tty ready | tty ready |
{2: } | {2:^ } |
|
| |
| |
| |
^ |
| |
]]) ]])
end) end)
@ -153,11 +153,11 @@ describe('cursor with customized highlighting', function()
feed('<c-\\><c-n>') feed('<c-\\><c-n>')
screen:expect([[ screen:expect([[
tty ready | tty ready |
{2: } | {2:^ } |
|
| |
| |
| |
^ |
| |
]]) ]])
end) end)

View File

@ -1,6 +1,6 @@
local helpers = require('test.functional.helpers')(after_each) local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers') local thelpers = require('test.functional.terminal.helpers')
local clear = helpers.clear local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval
local feed, nvim = helpers.feed, helpers.nvim local feed, nvim = helpers.feed, helpers.nvim
local feed_data = thelpers.feed_data local feed_data = thelpers.feed_data
@ -38,31 +38,17 @@ describe('terminal mouse', function()
end) end)
describe('when the terminal has focus', function() describe('when the terminal has focus', function()
it('will exit focus when scrolled', function() it('will exit focus on mouse-scroll', function()
feed('<MouseDown><0,0>') eq('t', eval('mode()'))
screen:expect([[ feed('<ScrollWheelUp><0,0>')
line23 | eq('n', eval('mode()'))
line24 |
line25 |
line26 |
line27 |
^line28 |
|
]])
end) end)
it('will exit focus after <C-\\>, then scrolled', function() it('will exit focus on <C-\\> + mouse-scroll', function()
eq('t', eval('mode()'))
feed('<C-\\>') feed('<C-\\>')
feed('<MouseDown><0,0>') feed('<ScrollWheelUp><0,0>')
screen:expect([[ eq('n', eval('mode()'))
line23 |
line24 |
line25 |
line26 |
line27 |
^line28 |
|
]])
end) end)
describe('with mouse events enabled by the program', function() describe('with mouse events enabled by the program', function()
@ -94,7 +80,7 @@ describe('terminal mouse', function()
end) end)
it('will forward mouse scroll to the program', function() it('will forward mouse scroll to the program', function()
feed('<MouseDown><0,0>') feed('<ScrollWheelUp><0,0>')
screen:expect([[ screen:expect([[
line27 | line27 |
line28 | line28 |
@ -164,7 +150,7 @@ describe('terminal mouse', function()
end) end)
it('wont lose focus if another window is scrolled', function() it('wont lose focus if another window is scrolled', function()
feed('<MouseDown><0,0><MouseDown><0,0>') feed('<ScrollWheelUp><0,0><ScrollWheelUp><0,0>')
screen:expect([[ screen:expect([[
{7: 21 }line |line30 | {7: 21 }line |line30 |
{7: 22 }line |rows: 5, cols: 25 | {7: 22 }line |rows: 5, cols: 25 |
@ -174,7 +160,7 @@ describe('terminal mouse', function()
========== ========== | ========== ========== |
{3:-- TERMINAL --} | {3:-- TERMINAL --} |
]]) ]])
feed('<S-MouseUp><0,0>') feed('<S-ScrollWheelDown><0,0>')
screen:expect([[ screen:expect([[
{7: 26 }line |line30 | {7: 26 }line |line30 |
{7: 27 }line |rows: 5, cols: 25 | {7: 27 }line |rows: 5, cols: 25 |

View File

@ -18,11 +18,11 @@ describe('terminal window', function()
feed('<c-\\><c-n>') feed('<c-\\><c-n>')
screen:expect([[ screen:expect([[
tty ready | tty ready |
{2: } | {2:^ } |
|
| |
| |
| |
^ |
| |
]]) ]])
feed(':set colorcolumn=20<cr>i') feed(':set colorcolumn=20<cr>i')

View File

@ -658,7 +658,7 @@ describe('Mouse input', function()
{4:[No Name] [+] }| {4:[No Name] [+] }|
:vsp | :vsp |
]]) ]])
feed('<MouseUp><0,0>') feed('<ScrollWheelDown><0,0>')
screen:expect([[ screen:expect([[
mouse scrolling {4:|}lines | mouse scrolling {4:|}lines |
^ {4:|}to | ^ {4:|}to |
@ -675,7 +675,7 @@ describe('Mouse input', function()
{4:[No Name] [+] }| {4:[No Name] [+] }|
| |
]]) ]])
feed('<MouseDown><27,0>') feed('<ScrollWheelUp><27,0>')
screen:expect([[ screen:expect([[
mouse scrolling {4:|}text | mouse scrolling {4:|}text |
^ {4:|}with | ^ {4:|}with |
@ -692,7 +692,7 @@ describe('Mouse input', function()
{4:[No Name] [+] }| {4:[No Name] [+] }|
| |
]]) ]])
feed('<MouseDown><27,7><MouseDown>') feed('<ScrollWheelUp><27,7><ScrollWheelUp>')
screen:expect([[ screen:expect([[
mouse scrolling {4:|}text | mouse scrolling {4:|}text |
^ {4:|}with | ^ {4:|}with |