aucmd_prepbuf: also restore prevwin #9741

bisected to f5d5da3917

Other test steps:

    nvim -u NORC
    :terminal tree /    " Produces lots of output
    :edit somefile.txt
    :vsplit
    :vsplit
    <c-w>l
    <c-w>l
    <c-w>h
    <c-w>p
This commit is contained in:
Justin M. Keyes 2019-03-17 02:09:06 +01:00 committed by GitHub
parent 32998731bf
commit 7c38994ff2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 35 deletions

View File

@ -987,18 +987,16 @@ typedef struct {
.relative = 0, .external = false, \ .relative = 0, .external = false, \
.focusable = true }) .focusable = true })
/* /// Structure which contains all information that belongs to a window.
* Structure which contains all information that belongs to a window ///
* /// All row numbers are relative to the start of the window, except w_winrow.
* All row numbers are relative to the start of the window, except w_winrow.
*/
struct window_S { struct window_S {
handle_T handle; ///< unique identifier for the window handle_T handle; ///< unique identifier for the window
buf_T *w_buffer; ///< buffer we are a window into (used buf_T *w_buffer; ///< buffer we are a window into (used
///< often, keep it the first item!) ///< often, keep it the first item!)
synblock_T *w_s; /* for :ownsyntax */ synblock_T *w_s; ///< for :ownsyntax
int w_hl_id_normal; ///< 'winhighlight' normal id int w_hl_id_normal; ///< 'winhighlight' normal id
int w_hl_attr_normal; ///< 'winhighlight' normal final attrs int w_hl_attr_normal; ///< 'winhighlight' normal final attrs
@ -1008,18 +1006,18 @@ struct window_S {
int w_hl_needs_update; ///< attrs need to be recalculated int w_hl_needs_update; ///< attrs need to be recalculated
win_T *w_prev; /* link to previous window */ win_T *w_prev; ///< link to previous window
win_T *w_next; /* link to next window */ win_T *w_next; ///< link to next window
bool w_closing; /* window is being closed, don't let bool w_closing; ///< window is being closed, don't let
autocommands close it too. */ /// autocommands close it too.
frame_T *w_frame; /* frame containing this window */ frame_T *w_frame; ///< frame containing this window
pos_T w_cursor; /* cursor position in buffer */ pos_T w_cursor; ///< cursor position in buffer
colnr_T w_curswant; /* The column we'd like to be at. This is colnr_T w_curswant; ///< Column we want to be at. This is
used to try to stay in the same column /// used to try to stay in the same column
for up/down cursor motions. */ /// for up/down cursor motions.
int w_set_curswant; // If set, then update w_curswant the next int w_set_curswant; // If set, then update w_curswant the next
// time through cursupdate() to the // time through cursupdate() to the

View File

@ -6527,6 +6527,7 @@ aucmd_prepbuf (
win = curwin; win = curwin;
aco->save_curwin = curwin; aco->save_curwin = curwin;
aco->save_prevwin = prevwin;
aco->save_curbuf = curbuf; aco->save_curbuf = curbuf;
if (win != NULL) { if (win != NULL) {
/* There is a window for "buf" in the current tab page, make it the /* There is a window for "buf" in the current tab page, make it the
@ -6624,6 +6625,8 @@ win_found:
// Hmm, original window disappeared. Just use the first one. // Hmm, original window disappeared. Just use the first one.
curwin = firstwin; curwin = firstwin;
} }
prevwin = win_valid(aco->save_prevwin) ? aco->save_prevwin
: firstwin; // window disappeared?
vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables
hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab
curbuf = curwin->w_buffer; curbuf = curwin->w_buffer;
@ -6656,6 +6659,8 @@ win_found:
} }
curwin = aco->save_curwin; curwin = aco->save_curwin;
prevwin = win_valid(aco->save_prevwin) ? aco->save_prevwin
: firstwin; // window disappeared?
curbuf = curwin->w_buffer; curbuf = curwin->w_buffer;
// In case the autocommand moves the cursor to a position that does not // In case the autocommand moves the cursor to a position that does not
// exist in curbuf // exist in curbuf

View File

@ -23,6 +23,7 @@ typedef struct {
buf_T *save_curbuf; ///< saved curbuf buf_T *save_curbuf; ///< saved curbuf
int use_aucmd_win; ///< using aucmd_win int use_aucmd_win; ///< using aucmd_win
win_T *save_curwin; ///< saved curwin win_T *save_curwin; ///< saved curwin
win_T *save_prevwin; ///< saved prevwin
win_T *new_curwin; ///< new curwin win_T *new_curwin; ///< new curwin
bufref_T new_curbuf; ///< new curbuf bufref_T new_curbuf; ///< new curbuf
char_u *globaldir; ///< saved value of globaldir char_u *globaldir; ///< saved value of globaldir

View File

@ -24,8 +24,8 @@ describe('api/buf', function()
end end
describe('line_count, insert and del_line', function() describe('nvim_buf_set_lines, nvim_buf_line_count', function()
it('works', function() it('deprecated forms', function()
eq(1, curbuf_depr('line_count')) eq(1, curbuf_depr('line_count'))
curbuf_depr('insert', -1, {'line'}) curbuf_depr('insert', -1, {'line'})
eq(2, curbuf_depr('line_count')) eq(2, curbuf_depr('line_count'))
@ -70,7 +70,7 @@ describe('api/buf', function()
end) end)
end) end)
describe('{get,set,del}_line', function() describe('deprecated: {get,set,del}_line', function()
it('works', function() it('works', function()
eq('', curbuf_depr('get_line', 0)) eq('', curbuf_depr('get_line', 0))
curbuf_depr('set_line', 0, 'line1') curbuf_depr('set_line', 0, 'line1')
@ -102,7 +102,7 @@ describe('api/buf', function()
end) end)
end) end)
describe('{get,set}_line_slice', function() describe('deprecated: {get,set}_line_slice', function()
it('get_line_slice: out-of-bounds returns empty array', function() it('get_line_slice: out-of-bounds returns empty array', function()
curbuf_depr('set_line_slice', 0, 0, true, true, {'a', 'b', 'c'}) curbuf_depr('set_line_slice', 0, 0, true, true, {'a', 'b', 'c'})
eq({'a', 'b', 'c'}, curbuf_depr('get_line_slice', 0, 2, true, true)) --sanity eq({'a', 'b', 'c'}, curbuf_depr('get_line_slice', 0, 2, true, true)) --sanity
@ -149,7 +149,7 @@ describe('api/buf', function()
end) end)
end) end)
describe('{get,set}_lines', function() describe('nvim_buf_get_lines, nvim_buf_set_lines', function()
local get_lines, set_lines = curbufmeths.get_lines, curbufmeths.set_lines local get_lines, set_lines = curbufmeths.get_lines, curbufmeths.set_lines
local line_count = curbufmeths.line_count local line_count = curbufmeths.line_count
@ -272,7 +272,7 @@ describe('api/buf', function()
eq({}, get_lines(-3, -4, true)) eq({}, get_lines(-3, -4, true))
end) end)
it('set_line_slice: out-of-bounds can extend past end', function() it('set_lines: out-of-bounds can extend past end', function()
set_lines(0, -1, true, {'a', 'b', 'c'}) set_lines(0, -1, true, {'a', 'b', 'c'})
eq({'a', 'b', 'c'}, get_lines(0, -1, true)) --sanity eq({'a', 'b', 'c'}, get_lines(0, -1, true)) --sanity
@ -286,7 +286,7 @@ describe('api/buf', function()
eq({'e', 'a', 'b', 'c', 'd'}, get_lines(0, -1, true)) eq({'e', 'a', 'b', 'c', 'd'}, get_lines(0, -1, true))
end) end)
it("set_line on alternate buffer does not access invalid line (E315)", function() it("set_lines on alternate buffer does not access invalid line (E315)", function()
feed_command('set hidden') feed_command('set hidden')
insert('Initial file') insert('Initial file')
command('enew') command('enew')
@ -334,9 +334,27 @@ describe('api/buf', function()
{2:-- INSERT --} | {2:-- INSERT --} |
]]) ]])
end) end)
it('set_lines on hidden buffer preserves "previous window" #9741', function()
insert([[
visible buffer line 1
line 2
]])
local hiddenbuf = meths.create_buf(false,true)
command('vsplit')
command('vsplit')
feed('<c-w>l<c-w>l<c-w>l')
eq(3, funcs.winnr())
feed('<c-w>h')
eq(2, funcs.winnr())
meths.buf_set_lines(hiddenbuf, 0, -1, true,
{'hidden buffer line 1', 'line 2'})
feed('<c-w>p')
eq(3, funcs.winnr())
end)
end) end)
describe('get_offset', function() describe('nvim_buf_get_offset', function()
local get_offset = curbufmeths.get_offset local get_offset = curbufmeths.get_offset
it('works', function() it('works', function()
curbufmeths.set_lines(0,-1,true,{'Some\r','exa\000mple', '', 'buf\rfer', 'text'}) curbufmeths.set_lines(0,-1,true,{'Some\r','exa\000mple', '', 'buf\rfer', 'text'})
@ -373,7 +391,7 @@ describe('api/buf', function()
end) end)
end) end)
describe('{get,set,del}_var', function() describe('nvim_buf_get_var, nvim_buf_set_var, nvim_buf_del_var', function()
it('works', function() it('works', function()
curbuf('set_var', 'lua', {1, 2, {['3'] = 1}}) curbuf('set_var', 'lua', {1, 2, {['3'] = 1}})
eq({1, 2, {['3'] = 1}}, curbuf('get_var', 'lua')) eq({1, 2, {['3'] = 1}}, curbuf('get_var', 'lua'))
@ -393,7 +411,7 @@ describe('api/buf', function()
end) end)
end) end)
describe('get_changedtick', function() describe('nvim_buf_get_changedtick', function()
it('works', function() it('works', function()
eq(2, curbufmeths.get_changedtick()) eq(2, curbufmeths.get_changedtick())
curbufmeths.set_lines(0, 1, false, {'abc\0', '\0def', 'ghi'}) curbufmeths.set_lines(0, 1, false, {'abc\0', '\0def', 'ghi'})
@ -417,7 +435,7 @@ describe('api/buf', function()
end) end)
end) end)
describe('{get,set}_option', function() describe('nvim_buf_get_option, nvim_buf_set_option', function()
it('works', function() it('works', function()
eq(8, curbuf('get_option', 'shiftwidth')) eq(8, curbuf('get_option', 'shiftwidth'))
curbuf('set_option', 'shiftwidth', 4) curbuf('set_option', 'shiftwidth', 4)
@ -430,7 +448,7 @@ describe('api/buf', function()
end) end)
end) end)
describe('{get,set}_name', function() describe('nvim_buf_get_name, nvim_buf_set_name', function()
it('works', function() it('works', function()
nvim('command', 'new') nvim('command', 'new')
eq('', curbuf('get_name')) eq('', curbuf('get_name'))
@ -438,14 +456,12 @@ describe('api/buf', function()
curbuf('set_name', new_name) curbuf('set_name', new_name)
eq(new_name, curbuf('get_name')) eq(new_name, curbuf('get_name'))
nvim('command', 'w!') nvim('command', 'w!')
local f = io.open(new_name) eq(1, funcs.filereadable(new_name))
ok(f ~= nil)
f:close()
os.remove(new_name) os.remove(new_name)
end) end)
end) end)
describe('is_loaded', function() describe('nvim_buf_is_loaded', function()
it('works', function() it('works', function()
-- record our buffer number for when we unload it -- record our buffer number for when we unload it
local bufnr = curbuf('get_number') local bufnr = curbuf('get_number')
@ -470,7 +486,7 @@ describe('api/buf', function()
end) end)
end) end)
describe('is_valid', function() describe('nvim_buf_is_valid', function()
it('works', function() it('works', function()
nvim('command', 'new') nvim('command', 'new')
local b = nvim('get_current_buf') local b = nvim('get_current_buf')
@ -480,12 +496,12 @@ describe('api/buf', function()
end) end)
end) end)
describe('get_mark', function() describe('nvim_buf_get_mark', function()
it('works', function() it('works', function()
curbuf('set_lines', -1, -1, true, {'a', 'bit of', 'text'}) curbuf('set_lines', -1, -1, true, {'a', 'bit of', 'text'})
curwin('set_cursor', {3, 4}) curwin('set_cursor', {3, 4})
nvim('command', 'mark V') nvim('command', 'mark v')
eq({3, 0}, curbuf('get_mark', 'V')) eq({3, 0}, curbuf('get_mark', 'v'))
end) end)
end) end)
end) end)