From 42c922b32c0a22fbe078d03bac5de0cfa7bd0b9f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 12 Jan 2017 02:33:15 +0100 Subject: open_buffer(): Do `BufEnter` for directories. Abuse NOTDONE to give some nuance to the return value of readfile(), so that open_buffer() can distinguish between "failed, lol" and "failed because the path is a directory". Before this change, Vim *already* creates a new buffer when a directory is edited. So there is no reason it should not raise BufEnter, that was an implementation detail of ye olde readfile(). Most of the changes in this commit merely preserve the old semantics. The "implicit" change that we actually are interested in, is this line in `open_buffer()`, where `retval` being non-FAIL allows EVENT_BUFENTER to be applied: apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf, &retval); References https://github.com/vim/vim/issues/1353 --- src/nvim/buffer.c | 11 +++++++---- src/nvim/ex_cmds.c | 4 ++-- src/nvim/ex_docmd.c | 5 +++-- src/nvim/fileio.c | 13 +++++++------ src/nvim/memline.c | 2 +- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index d9fdc80c60..5ab96ca67d 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -193,10 +193,13 @@ open_buffer ( * it can be changed there. */ if (!readonlymode && !bufempty()) changed(); - else if (retval != FAIL) + else if (retval == OK) { unchanged(curbuf, FALSE); - apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE, - curbuf, &retval); + } + if (retval == OK) { + apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE, + curbuf, &retval); + } } } @@ -219,7 +222,7 @@ open_buffer ( || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL) ) changed(); - else if (retval != FAIL && !read_stdin) + else if (retval == OK && !read_stdin) unchanged(curbuf, FALSE); save_file_ff(curbuf); /* keep this fileformat */ diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index b1404abc05..69eed33736 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1193,8 +1193,8 @@ static void do_filter( if (do_out) { if (otmp != NULL) { - if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM, - eap, READ_FILTER) == FAIL) { + if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, + READ_FILTER) != OK) { if (!aborting()) { msg_putchar('\n'); EMSG2(_(e_notread), otmp); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 19691ccc3a..5ff79bcfef 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6910,9 +6910,10 @@ static void ex_read(exarg_T *eap) eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0); } - if (i == FAIL) { - if (!aborting()) + if (i != OK) { + if (!aborting()) { EMSG2(_(e_notopen), eap->arg); + } } else { if (empty && exmode_active) { /* Delete the empty line that remains. Historically ex does diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 29114201d2..c075b05b46 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -249,7 +249,7 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr) * READ_DUMMY read into a dummy buffer (to check if file contents changed) * READ_KEEP_UNDO don't clear undo info or read it from a file * - * return FAIL for failure, OK otherwise + * return FAIL for failure, NOTDONE for directory (failure), or OK */ int readfile ( @@ -258,7 +258,7 @@ readfile ( linenr_T from, linenr_T lines_to_skip, linenr_T lines_to_read, - exarg_T *eap, /* can be NULL! */ + exarg_T *eap, // can be NULL! int flags ) { @@ -444,13 +444,14 @@ readfile ( // ... or a character special file named /dev/fd/ # endif ) { - if (S_ISDIR(perm)) + if (S_ISDIR(perm)) { filemess(curbuf, fname, (char_u *)_("is a directory"), 0); - else + } else { filemess(curbuf, fname, (char_u *)_("is not a file"), 0); + } msg_end(); msg_scroll = msg_save; - return FAIL; + return S_ISDIR(perm) ? NOTDONE : FAIL; } #endif } @@ -5108,7 +5109,7 @@ void buf_reload(buf_T *buf, int orig_mode) keep_filetype = TRUE; /* don't detect 'filetype' */ if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0, (linenr_T)0, - (linenr_T)MAXLNUM, &ea, flags) == FAIL) { + (linenr_T)MAXLNUM, &ea, flags) != OK) { if (!aborting()) EMSG2(_("E321: Could not reload \"%s\""), buf->b_fname); if (savebuf != NULL && buf_valid(savebuf) && buf == curbuf) { diff --git a/src/nvim/memline.c b/src/nvim/memline.c index a9a53ebca7..8deae54706 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1064,7 +1064,7 @@ void ml_recover(void) line_count = pp->pb_pointer[idx].pe_line_count; if (readfile(curbuf->b_ffname, NULL, lnum, pp->pb_pointer[idx].pe_old_lnum - 1, - line_count, NULL, 0) == FAIL) + line_count, NULL, 0) != OK) cannot_open = TRUE; else lnum += line_count; -- cgit From b5e8e2f20d6e0c3d0201f577254d54ae5913a7d2 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 12 Jan 2017 16:40:28 +0100 Subject: lint --- src/nvim/buffer.c | 40 ++++++++++++++++++++-------------------- src/nvim/fileio.c | 12 ++++++------ src/nvim/memline.c | 9 +++++---- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 5ab96ca67d..04a3235dc6 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -189,15 +189,16 @@ open_buffer ( curwin->w_cursor.lnum = 1; curwin->w_cursor.col = 0; - /* Set or reset 'modified' before executing autocommands, so that - * it can be changed there. */ - if (!readonlymode && !bufempty()) + // Set or reset 'modified' before executing autocommands, so that + // it can be changed there. + if (!readonlymode && !bufempty()) { changed(); - else if (retval == OK) { - unchanged(curbuf, FALSE); + } else if (retval == OK) { + unchanged(curbuf, false); } + if (retval == OK) { - apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE, + apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, false, curbuf, &retval); } } @@ -209,22 +210,21 @@ open_buffer ( parse_cino(curbuf); } - /* - * Set/reset the Changed flag first, autocmds may change the buffer. - * Apply the automatic commands, before processing the modelines. - * So the modelines have priority over auto commands. - */ - /* When reading stdin, the buffer contents always needs writing, so set - * the changed flag. Unless in readonly mode: "ls | nvim -R -". - * When interrupted and 'cpoptions' contains 'i' set changed flag. */ + // Set/reset the Changed flag first, autocmds may change the buffer. + // Apply the automatic commands, before processing the modelines. + // So the modelines have priority over auto commands. + + // When reading stdin, the buffer contents always needs writing, so set + // the changed flag. Unless in readonly mode: "ls | nvim -R -". + // When interrupted and 'cpoptions' contains 'i' set changed flag. if ((got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL) - || modified_was_set /* ":set modified" used in autocmd */ - || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL) - ) + || modified_was_set // ":set modified" used in autocmd + || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)) { changed(); - else if (retval == OK && !read_stdin) - unchanged(curbuf, FALSE); - save_file_ff(curbuf); /* keep this fileformat */ + } else if (retval == OK && !read_stdin) { + unchanged(curbuf, false); + } + save_file_ff(curbuf); // keep this fileformat /* require "!" to overwrite the file, because it wasn't read completely */ if (aborting()) diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index c075b05b46..6f95ced147 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -5105,13 +5105,13 @@ void buf_reload(buf_T *buf, int orig_mode) } if (saved == OK) { - curbuf->b_flags |= BF_CHECK_RO; /* check for RO again */ - keep_filetype = TRUE; /* don't detect 'filetype' */ - if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0, - (linenr_T)0, - (linenr_T)MAXLNUM, &ea, flags) != OK) { - if (!aborting()) + curbuf->b_flags |= BF_CHECK_RO; // check for RO again + keep_filetype = true; // don't detect 'filetype' + if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0, (linenr_T)0, + (linenr_T)MAXLNUM, &ea, flags) != OK) { + if (!aborting()) { EMSG2(_("E321: Could not reload \"%s\""), buf->b_fname); + } if (savebuf != NULL && buf_valid(savebuf) && buf == curbuf) { /* Put the text back from the save buffer. First * delete any lines that readfile() added. */ diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 8deae54706..b8891f6560 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1063,11 +1063,12 @@ void ml_recover(void) if (!cannot_open) { line_count = pp->pb_pointer[idx].pe_line_count; if (readfile(curbuf->b_ffname, NULL, lnum, - pp->pb_pointer[idx].pe_old_lnum - 1, - line_count, NULL, 0) != OK) - cannot_open = TRUE; - else + pp->pb_pointer[idx].pe_old_lnum - 1, line_count, + NULL, 0) != OK) { + cannot_open = true; + } else { lnum += line_count; + } } if (cannot_open) { ++error; -- cgit From cc7f1aba46716cf509ca784840d6e77f7bfb2318 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 12 Jan 2017 03:19:30 +0100 Subject: test: BufEnter --- test/functional/autocmd/bufenter_spec.lua | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 test/functional/autocmd/bufenter_spec.lua diff --git a/test/functional/autocmd/bufenter_spec.lua b/test/functional/autocmd/bufenter_spec.lua new file mode 100644 index 0000000000..ccbcdf5c5e --- /dev/null +++ b/test/functional/autocmd/bufenter_spec.lua @@ -0,0 +1,35 @@ +local helpers = require('test.functional.helpers')(after_each) + +local clear = helpers.clear +local command = helpers.command +local eq = helpers.eq +local eval = helpers.eval +local execute = helpers.execute +local request = helpers.request +local source = helpers.source + +describe('autocmd BufEnter', function() + before_each(clear) + + it("triggered by nvim_command('edit ')", function() + command("autocmd BufEnter * if isdirectory(expand('')) | let g:dir_bufenter = 1 | endif") + request("nvim_command", "split .") + eq(1, eval("exists('g:dir_bufenter')")) -- Did BufEnter for the directory. + eq(2, eval("bufnr('%')")) -- Switched to the dir buffer. + end) + + it('triggered by "try|:split |endtry" in a function', function() + command("autocmd BufEnter * if isdirectory(expand('')) | let g:dir_bufenter = 1 | endif") + source([[ + function! Test() + try + exe 'split .' + catch + endtry + endfunction + ]]) + execute("call Test()") + eq(1, eval("exists('g:dir_bufenter')")) -- Did BufEnter for the directory. + eq(2, eval("bufnr('%')")) -- Switched to the dir buffer. + end) +end) -- cgit From 82edcb593b19755187371635d7b5aabdf024bd1f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 12 Jan 2017 05:08:19 +0100 Subject: Windows: enable more tests --- test/functional/api/server_requests_spec.lua | 4 ++-- test/functional/autocmd/tabnew_spec.lua | 9 +++------ test/functional/autocmd/tabnewentered_spec.lua | 8 +++----- test/functional/core/job_partial_spec.lua | 13 ++++++++----- test/functional/eval/server_spec.lua | 17 ++++++++--------- test/functional/helpers.lua | 9 +++++++++ 6 files changed, 33 insertions(+), 27 deletions(-) diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index 3245e1b52d..aa91cd1396 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -8,8 +8,6 @@ local nvim_prog, command, funcs = helpers.nvim_prog, helpers.command, helpers.fu local source, next_message = helpers.source, helpers.next_message local meths = helpers.meths -if helpers.pending_win32(pending) then return end - describe('server -> client', function() local cid @@ -212,6 +210,8 @@ describe('server -> client', function() funcs.jobstop(jobid) end) + if helpers.pending_win32(pending) then return end + it('rpc and text stderr can be combined', function() eq("ok",funcs.rpcrequest(jobid, "poll")) funcs.rpcnotify(jobid, "ping") diff --git a/test/functional/autocmd/tabnew_spec.lua b/test/functional/autocmd/tabnew_spec.lua index 2148b21832..ad40954f76 100644 --- a/test/functional/autocmd/tabnew_spec.lua +++ b/test/functional/autocmd/tabnew_spec.lua @@ -5,8 +5,6 @@ local command = helpers.command local eq = helpers.eq local eval = helpers.eval -if helpers.pending_win32(pending) then return end - describe('autocmd TabNew', function() before_each(clear) @@ -19,12 +17,11 @@ describe('autocmd TabNew', function() end) it('matches when opening a new tab for FILE', function() - local tmp_path = helpers.funcs.tempname() command('let g:test = "foo"') - command('autocmd! TabNew ' .. tmp_path .. ' let g:test = "bar"') - command('tabnew ' .. tmp_path ..'X') + command('autocmd! TabNew Xtest-tabnew let g:test = "bar"') + command('tabnew Xtest-tabnewX') eq('foo', eval('g:test')) - command('tabnew ' .. tmp_path) + command('tabnew Xtest-tabnew') eq('bar', eval('g:test')) end) end) diff --git a/test/functional/autocmd/tabnewentered_spec.lua b/test/functional/autocmd/tabnewentered_spec.lua index f033bd5fe4..bdbe677132 100644 --- a/test/functional/autocmd/tabnewentered_spec.lua +++ b/test/functional/autocmd/tabnewentered_spec.lua @@ -1,8 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq -if helpers.pending_win32(pending) then return end - describe('TabNewEntered', function() describe('au TabNewEntered', function() describe('with * as ', function() @@ -15,9 +13,9 @@ describe('TabNewEntered', function() end) describe('with FILE as ', function() it('matches when opening a new tab for FILE', function() - local tmp_path = nvim('eval', 'tempname()') - nvim('command', 'au! TabNewEntered '..tmp_path..' echom "tabnewentered:match"') - eq("\n\""..tmp_path.."\" [New File]\ntabnewentered:4:4\ntabnewentered:match", nvim('command_output', 'tabnew '..tmp_path)) + nvim('command', 'au! TabNewEntered Xtest-tabnewentered echom "tabnewentered:match"') + eq('\n"Xtest-tabnewentered" [New File]\ntabnewentered:4:4\ntabnewentered:match', + nvim('command_output', 'tabnew Xtest-tabnewentered')) end) end) describe('with CTRL-W T', function() diff --git a/test/functional/core/job_partial_spec.lua b/test/functional/core/job_partial_spec.lua index b60f239db9..7643b283c4 100644 --- a/test/functional/core/job_partial_spec.lua +++ b/test/functional/core/job_partial_spec.lua @@ -2,13 +2,14 @@ local helpers = require('test.functional.helpers')(after_each) local clear, eq, next_msg, nvim, source = helpers.clear, helpers.eq, helpers.next_message, helpers.nvim, helpers.source -if helpers.pending_win32(pending) then return end - describe('jobs with partials', function() local channel before_each(function() clear() + if helpers.os_name() == 'windows' then + helpers.set_shell_powershell() + end channel = nvim('get_api_info')[1] nvim('set_var', 'channel', channel) end) @@ -16,12 +17,14 @@ describe('jobs with partials', function() it('works correctly', function() source([[ function PrintArgs(a1, a2, id, data, event) - call rpcnotify(g:channel, '1', a:a1, a:a2, a:data, a:event) + " Windows: Remove ^M char. + let normalized = map(a:data, 'substitute(v:val, "\r", "", "g")') + call rpcnotify(g:channel, '1', a:a1, a:a2, normalized, a:event) endfunction let Callback = function('PrintArgs', ["foo", "bar"]) let g:job_opts = {'on_stdout': Callback} - call jobstart(['echo'], g:job_opts) + call jobstart('echo "some text"', g:job_opts) ]]) - eq({'notification', '1', {'foo', 'bar', {'', ''}, 'stdout'}}, next_msg()) + eq({'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}}, next_msg()) end) end) diff --git a/test/functional/eval/server_spec.lua b/test/functional/eval/server_spec.lua index d2c985e894..420aea04aa 100644 --- a/test/functional/eval/server_spec.lua +++ b/test/functional/eval/server_spec.lua @@ -4,8 +4,6 @@ local nvim, eq, neq, eval = helpers.nvim, helpers.eq, helpers.neq, helpers.eval local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths local os_name = helpers.os_name -if helpers.pending_win32(pending) then return end - describe('serverstart(), serverstop()', function() before_each(clear) @@ -42,8 +40,8 @@ describe('serverstart(), serverstop()', function() -- v:servername will take the next available server. local servername = (os_name() == 'windows' - and [[\\.\pipe\Xtest-functional-server-server-pipe]] - or 'Xtest-functional-server-server-socket') + and [[\\.\pipe\Xtest-functional-server-pipe]] + or 'Xtest-functional-server-socket') funcs.serverstart(servername) eq(servername, meths.get_vvar('servername')) end) @@ -63,9 +61,11 @@ describe('serverlist()', function() local n = eval('len(serverlist())') -- Add a few - local servs = {'should-not-exist', 'another-one-that-shouldnt'} + local servs = (os_name() == 'windows' + and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] } + or { [[Xtest-pipe0934]], [[Xtest-pipe4324]] }) for _, s in ipairs(servs) do - eq(s, eval('serverstart("'..s..'")')) + eq(s, eval("serverstart('"..s.."')")) end local new_servs = eval('serverlist()') @@ -75,10 +75,9 @@ describe('serverlist()', function() -- The new servers should be at the end of the list. for i = 1, #servs do eq(servs[i], new_servs[i + n]) - nvim('command', 'call serverstop("'..servs[i]..'")') + nvim('command', "call serverstop('"..servs[i].."')") end - -- After calling serverstop() on the new servers, they should no longer be - -- in the list. + -- After serverstop() the servers should NOT be in the list. eq(n, eval('len(serverlist())')) end) end) diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 5eec3afe65..2939184d2c 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -346,6 +346,14 @@ local function source(code) return fname end +local function set_shell_powershell() + source([[ + set shell=powershell shellquote=\" shellpipe=\| shellredir=> + set shellcmdflag=\ -ExecutionPolicy\ RemoteSigned\ -Command + let &shellxquote=' ' + ]]) +end + local function nvim(method, ...) return request('nvim_'..method, ...) end @@ -590,6 +598,7 @@ return function(after_each) curtabmeths = curtabmeths, pending_win32 = pending_win32, skip_fragile = skip_fragile, + set_shell_powershell = set_shell_powershell, tmpname = tmpname, NIL = mpack.NIL, } -- cgit