diff options
-rw-r--r-- | runtime/autoload/man.vim | 5 | ||||
-rw-r--r-- | runtime/autoload/provider/pythonx.vim | 3 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 2 | ||||
-rw-r--r-- | src/nvim/os/time.c | 39 | ||||
-rw-r--r-- | src/nvim/path.c | 47 | ||||
-rw-r--r-- | src/nvim/testdir/test_usercommands.vim | 30 | ||||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | test/unit/path_spec.lua | 11 |
8 files changed, 101 insertions, 38 deletions
diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim index 6fed4a54e3..251e6eee41 100644 --- a/runtime/autoload/man.vim +++ b/runtime/autoload/man.vim @@ -113,10 +113,11 @@ function! s:system(cmd, ...) abort endfunction function! s:get_page(path) abort + " Respect $MANWIDTH or default to window width. + let manwidth = empty($MANWIDTH) ? winwidth(0) : $MANWIDTH " Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db). " http://comments.gmane.org/gmane.editors.vim.devel/29085 - " Respect $MANWIDTH, or default to window width. - return s:system(['env', 'MANPAGER=cat', (empty($MANWIDTH) ? 'MANWIDTH='.winwidth(0) : ''), 'man', a:path]) + return s:system(['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'man', a:path]) endfunction function! s:put_page(page) abort diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim index f46c260fa3..08a0f39b01 100644 --- a/runtime/autoload/provider/pythonx.vim +++ b/runtime/autoload/provider/pythonx.vim @@ -57,7 +57,8 @@ function! provider#pythonx#Detect(major_ver) abort if exists('g:python3_host_prog') return [g:python3_host_prog, ''] else - let progs = ['python3', 'python3.5', 'python3.4', 'python3.3', 'python'] + let progs = ['python3', 'python3.7', 'python3.6', 'python3.5', + \ 'python3.4', 'python3.3', 'python'] endif endif diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 79a0b5849f..2c60cd0189 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1711,7 +1711,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, xfree(p); // If the autocommands did something and didn't cause an error, try // finding the command again. - p = (ret && !aborting()) ? find_command(&ea, NULL) : NULL; + p = (ret && !aborting()) ? find_command(&ea, NULL) : ea.cmd; } if (p == NULL) { diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 2205ad0958..8ce2ecf4f4 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -7,6 +7,7 @@ #include <uv.h> #include "nvim/os/time.h" +#include "nvim/os/input.h" #include "nvim/event/loop.h" #include "nvim/vim.h" #include "nvim/main.h" @@ -34,10 +35,10 @@ uint64_t os_hrtime(void) return uv_hrtime(); } -/// Sleeps for a certain amount of milliseconds +/// Sleeps for a certain amount of milliseconds. /// /// @param milliseconds Number of milliseconds to sleep -/// @param ignoreinput If true, allow a SIGINT to interrupt us +/// @param ignoreinput If true, only SIGINT (CTRL-C) can interrupt. void os_delay(uint64_t milliseconds, bool ignoreinput) { if (ignoreinput) { @@ -46,26 +47,42 @@ void os_delay(uint64_t milliseconds, bool ignoreinput) } LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, (int)milliseconds, got_int); } else { - os_microdelay(milliseconds * 1000); + os_microdelay(milliseconds * 1000u, ignoreinput); } } -/// Sleeps for a certain amount of microseconds +/// Sleeps for a certain amount of microseconds. /// -/// @param microseconds Number of microseconds to sleep -void os_microdelay(uint64_t microseconds) +/// @param ms Number of microseconds to sleep. +/// @param ignoreinput If true, ignore all input (including SIGINT/CTRL-C). +/// If false, waiting is aborted on any input. +void os_microdelay(uint64_t ms, bool ignoreinput) { - uint64_t elapsed = 0; - uint64_t ns = microseconds * 1000; // convert to nanoseconds + uint64_t elapsed = 0u; uint64_t base = uv_hrtime(); + // Convert microseconds to nanoseconds, or UINT64_MAX on overflow. + const uint64_t ns = (ms < UINT64_MAX / 1000u) ? ms * 1000u : UINT64_MAX; uv_mutex_lock(&delay_mutex); while (elapsed < ns) { - if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns - elapsed) - == UV_ETIMEDOUT) + // If ignoring input, we simply wait the full delay. + // Else we check for input in ~100ms intervals. + const uint64_t ns_delta = ignoreinput + ? ns - elapsed + : MIN(ns - elapsed, 100000000u); // 100ms + + const int rv = uv_cond_timedwait(&delay_cond, &delay_mutex, ns_delta); + if (0 != rv && UV_ETIMEDOUT != rv) { + assert(false); + break; + } // Else: Timeout proceeded normally. + + if (!ignoreinput && os_char_avail()) { break; - uint64_t now = uv_hrtime(); + } + + const uint64_t now = uv_hrtime(); elapsed += now - base; base = now; } diff --git a/src/nvim/path.c b/src/nvim/path.c index 6149e1ab99..3d1def8dd4 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -417,15 +417,11 @@ char *FullName_save(char *fname, bool force) } char *buf = xmalloc(MAXPATHL); - char *new_fname = NULL; - if (vim_FullName(fname, buf, MAXPATHL, force) != FAIL) { - new_fname = xstrdup(buf); - } else { - new_fname = xstrdup(fname); + if (vim_FullName(fname, buf, MAXPATHL, force) == FAIL) { + xfree(buf); + return xstrdup(fname); } - xfree(buf); - - return new_fname; + return buf; } /// Saves the absolute path. @@ -1649,30 +1645,37 @@ bool vim_isAbsName(char_u *name) /// Save absolute file name to "buf[len]". /// -/// @param fname is the filename to evaluate -/// @param[out] buf is the buffer for returning the absolute path for `fname` -/// @param len is the length of `buf` -/// @param force is a flag to force expanding even if the path is absolute +/// @param fname filename to evaluate +/// @param[out] buf contains `fname` absolute path, or: +/// - truncated `fname` if longer than `len` +/// - unmodified `fname` if absolute path fails or is a URL +/// @param len length of `buf` +/// @param force flag to force expanding even if the path is absolute /// /// @return FAIL for failure, OK otherwise int vim_FullName(const char *fname, char *buf, size_t len, bool force) FUNC_ATTR_NONNULL_ARG(2) { - int retval = OK; - int url; - *buf = NUL; - if (fname == NULL) + if (fname == NULL) { return FAIL; + } - url = path_with_url(fname); - if (!url) - retval = path_get_absolute_path((char_u *)fname, (char_u *)buf, len, force); - if (url || retval == FAIL) { - /* something failed; use the file name (truncate when too long) */ + if (strlen(fname) > (len - 1)) { + xstrlcpy(buf, fname, len); // truncate + return FAIL; + } + + if (path_with_url(fname)) { xstrlcpy(buf, fname, len); + return OK; } - return retval; + + int rv = path_get_absolute_path((char_u *)fname, (char_u *)buf, len, force); + if (rv == FAIL) { + xstrlcpy(buf, fname, len); // something failed; use the filename + } + return rv; } /// Get the full resolved path for `fname` diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim index f593d16dbf..facd675f88 100644 --- a/src/nvim/testdir/test_usercommands.vim +++ b/src/nvim/testdir/test_usercommands.vim @@ -46,3 +46,33 @@ function Test_cmdmods() delcommand MyQCmd unlet g:mods endfunction + +func Test_Ambiguous() + command Doit let g:didit = 'yes' + command Dothat let g:didthat = 'also' + call assert_fails('Do', 'E464:') + Doit + call assert_equal('yes', g:didit) + Dothat + call assert_equal('also', g:didthat) + unlet g:didit + unlet g:didthat + + delcommand Doit + Do + call assert_equal('also', g:didthat) + delcommand Dothat +endfunc + +func Test_CmdUndefined() + call assert_fails('Doit', 'E492:') + au CmdUndefined Doit :command Doit let g:didit = 'yes' + Doit + call assert_equal('yes', g:didit) + delcommand Doit + + call assert_fails('Dothat', 'E492:') + au CmdUndefined * let g:didnot = 'yes' + call assert_fails('Dothat', 'E492:') + call assert_equal('yes', g:didnot) +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index 8d2c89c950..6ddc0cd77e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -330,7 +330,7 @@ static int included_patches[] = { // 2113, 2112, // 2111, - // 2110, + 2110, 2109, // 2108 NA // 2107, diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua index 9b76834383..ccaf0228ab 100644 --- a/test/unit/path_spec.lua +++ b/test/unit/path_spec.lua @@ -336,6 +336,17 @@ describe('more path function', function() eq(FAIL, result) end) + it('fails safely if given length is wrong #5737', function() + local force_expansion = 1 + local filename = 'foo/bar/bazzzzzzz/buz/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/a' + local too_short_len = 8 + local buf = cstr(too_short_len, '') + local result = path.vim_FullName(filename, buf, too_short_len, force_expansion) + local expected = string.sub(filename, 1, (too_short_len - 1)) + eq(expected, (ffi.string(buf))) + eq(FAIL, result) + end) + it('uses the filename if the filename is a URL', function() local force_expansion = 1 local filename = 'http://www.neovim.org' |