aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml1
-rw-r--r--CMakeLists.txt34
-rw-r--r--ci/build.ps11
-rwxr-xr-xci/install.sh1
-rw-r--r--cmake/FindLibIntl.cmake12
-rw-r--r--cmake/FindLibUV.cmake6
-rw-r--r--makedeps.bat18
-rw-r--r--runtime/doc/eval.txt10
-rw-r--r--runtime/doc/pattern.txt43
-rw-r--r--runtime/mswin.vim45
-rw-r--r--src/nvim/CMakeLists.txt6
-rw-r--r--src/nvim/api/private/dispatch.c2
-rw-r--r--src/nvim/api/ui.c7
-rw-r--r--src/nvim/api/ui_events.in.h2
-rw-r--r--src/nvim/api/vim.c14
-rw-r--r--src/nvim/buffer.c2
-rw-r--r--src/nvim/buffer_updates.c5
-rw-r--r--src/nvim/channel.c1
-rw-r--r--src/nvim/charset.c4
-rw-r--r--src/nvim/eval.c71
-rw-r--r--src/nvim/ex_cmds.lua4
-rw-r--r--src/nvim/ex_docmd.c1
-rw-r--r--src/nvim/ex_getln.c9
-rw-r--r--src/nvim/fold.c16
-rw-r--r--src/nvim/globals.h8
-rw-r--r--src/nvim/mark.c49
-rw-r--r--src/nvim/mbyte.c48
-rw-r--r--src/nvim/misc1.c3
-rw-r--r--src/nvim/move.c9
-rw-r--r--src/nvim/msgpack_rpc/channel.c18
-rw-r--r--src/nvim/msgpack_rpc/helpers.c3
-rw-r--r--src/nvim/option.c7
-rw-r--r--src/nvim/options.lua2
-rw-r--r--src/nvim/os/users.c2
-rw-r--r--src/nvim/os/win_defs.h1
-rw-r--r--src/nvim/path.c17
-rw-r--r--src/nvim/po/CMakeLists.txt2
-rw-r--r--src/nvim/regexp.c23
-rw-r--r--src/nvim/regexp_nfa.c11
-rw-r--r--src/nvim/screen.c6
-rw-r--r--src/nvim/search.c88
-rw-r--r--src/nvim/tag.c11
-rw-r--r--src/nvim/terminal.c18
-rw-r--r--src/nvim/testdir/Makefile2
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_cmdline.vim4
-rw-r--r--src/nvim/testdir/test_fold.vim57
-rw-r--r--src/nvim/testdir/test_functions.vim415
-rw-r--r--src/nvim/testdir/test_listlbr_utf8.vim15
-rw-r--r--src/nvim/testdir/test_mapping.vim27
-rw-r--r--src/nvim/testdir/test_marks.vim44
-rw-r--r--src/nvim/testdir/test_normal.vim56
-rw-r--r--src/nvim/testdir/test_options.vim7
-rw-r--r--src/nvim/testdir/test_python2.vim24
-rw-r--r--src/nvim/testdir/test_python3.vim24
-rw-r--r--src/nvim/testdir/test_quotestar.vim17
-rw-r--r--src/nvim/testdir/test_regexp_utf8.vim82
-rw-r--r--src/nvim/testdir/test_scroll_opt.vim36
-rw-r--r--src/nvim/testdir/test_smartindent.vim27
-rw-r--r--src/nvim/testdir/test_startup.vim11
-rw-r--r--src/nvim/testdir/test_syntax.vim59
-rw-r--r--src/nvim/tui/tui.c6
-rw-r--r--src/nvim/ui.c16
-rw-r--r--src/nvim/ui.h1
-rw-r--r--src/nvim/ui_bridge.c25
-rw-r--r--src/nvim/undo.c6
-rw-r--r--src/nvim/version.c120
-rw-r--r--test/functional/api/buffer_updates_spec.lua79
-rw-r--r--test/functional/api/highlight_spec.lua2
-rw-r--r--test/functional/api/rpc_fixture.lua2
-rw-r--r--test/functional/api/server_requests_spec.lua2
-rw-r--r--test/functional/api/vim_spec.lua17
-rw-r--r--test/functional/eval/setpos_spec.lua3
-rw-r--r--test/functional/ex_cmds/debug_spec.lua110
-rw-r--r--test/functional/ex_cmds/write_spec.lua20
-rw-r--r--test/functional/ex_cmds/wviminfo_spec.lua18
-rw-r--r--test/functional/legacy/011_autocommands_spec.lua5
-rw-r--r--test/functional/legacy/097_glob_path_spec.lua2
-rw-r--r--test/functional/legacy/assert_spec.lua15
-rw-r--r--test/functional/legacy/delete_spec.lua6
-rw-r--r--test/functional/provider/nodejs_spec.lua12
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua10
-rw-r--r--test/functional/terminal/tui_spec.lua13
-rw-r--r--test/functional/ui/cmdline_spec.lua101
-rw-r--r--test/functional/ui/wildmode_spec.lua23
-rw-r--r--test/helpers.lua2
-rw-r--r--third-party/CMakeLists.txt24
-rw-r--r--third-party/cmake/BuildLibtermkey.cmake1
-rw-r--r--third-party/cmake/BuildLibuv.cmake33
-rw-r--r--third-party/cmake/BuildLibvterm.cmake3
-rw-r--r--third-party/cmake/BuildLuajit.cmake10
-rw-r--r--third-party/cmake/BuildLuarocks.cmake17
-rw-r--r--third-party/cmake/BuildLuv.cmake6
-rw-r--r--third-party/cmake/LibuvCMakeLists.txt15
-rw-r--r--third-party/patches/libtermkey-Fix-escape-sequences-for-MSVC.patch189
-rw-r--r--third-party/patches/libvterm-Fix-escape-sequences-for-MSVC.patch53
-rw-r--r--third-party/patches/luarocks-Change-default-downloader-to-curl.patch24
98 files changed, 2020 insertions, 522 deletions
diff --git a/.gitignore b/.gitignore
index 85b371b926..cf0a11804d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
# Tools
.ropeproject/
+# Visual Studio
+/.vs/
# Build/deps dir
/build/
diff --git a/.travis.yml b/.travis.yml
index b275a5262d..fa884bd021 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -53,6 +53,7 @@ jobs:
compiler: clang
env: >
CLANG_SANITIZER=ASAN_UBSAN
+ # Use Lua so that ASAN can test our embedded Lua support. 8fec4d53d0f6
CMAKE_FLAGS="$CMAKE_FLAGS -DPREFER_LUA=ON"
sudo: true
- os: linux
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4cafdef73f..9660fae527 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,9 +13,9 @@ include(PreventInTreeBuilds)
# Prefer our bundled versions of dependencies.
if(DEFINED ENV{DEPS_BUILD_DIR})
-set(DEPS_PREFIX "$ENV{DEPS_BUILD_DIR}/usr" CACHE PATH "Path prefix for finding dependencies")
+ set(DEPS_PREFIX "$ENV{DEPS_BUILD_DIR}/usr" CACHE PATH "Path prefix for finding dependencies")
else()
-set(DEPS_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/.deps/usr" CACHE PATH "Path prefix for finding dependencies")
+ set(DEPS_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/.deps/usr" CACHE PATH "Path prefix for finding dependencies")
endif()
if(CMAKE_CROSSCOMPILING AND NOT UNIX)
list(INSERT CMAKE_FIND_ROOT_PATH 0 ${DEPS_PREFIX})
@@ -53,6 +53,14 @@ if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(USE_FNAME_CASE TRUE)
endif()
+option(ENABLE_LIBINTL "enable libintl" ON)
+if(MSVC)
+ add_definitions(-DDYNAMIC_ICONV)
+ option(ENABLE_LIBICONV "enable libiconv" OFF)
+else()
+ option(ENABLE_LIBICONV "enable libiconv" ON)
+endif()
+
# Set default build type.
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "CMAKE_BUILD_TYPE not given, defaulting to 'Debug'.")
@@ -331,6 +339,7 @@ if(PREFER_LUA)
find_package(Lua REQUIRED)
set(LUA_PREFERRED_INCLUDE_DIRS ${LUA_INCLUDE_DIR})
set(LUA_PREFERRED_LIBRARIES ${LUA_LIBRARIES})
+ # Passive (not REQUIRED): if LUAJIT_FOUND is not set, nvim-test is skipped.
find_package(LuaJit)
else()
find_package(LuaJit REQUIRED)
@@ -399,31 +408,30 @@ if((CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) AND NOT CMAKE_C_COMPILER_ID MA
message(FATAL_ERROR "Sanitizers are only supported for Clang.")
endif()
-if(CMAKE_SYSTEM_NAME MATCHES "OpenBSD|FreeBSD")
- message(STATUS "detected OpenBSD/FreeBSD; disabled jemalloc. #5318")
+if(CMAKE_SYSTEM_NAME MATCHES "OpenBSD|FreeBSD|Windows") # see #5318
+ message(STATUS "skipping jemalloc on this system: ${CMAKE_SYSTEM_NAME}")
option(ENABLE_JEMALLOC "enable jemalloc" OFF)
else()
option(ENABLE_JEMALLOC "enable jemalloc" ON)
endif()
-if (ENABLE_JEMALLOC)
+if(ENABLE_JEMALLOC)
if(CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN)
message(STATUS "Sanitizers have been enabled; don't use jemalloc.")
else()
- find_package(JeMalloc)
- if(JEMALLOC_FOUND)
- include_directories(SYSTEM ${JEMALLOC_INCLUDE_DIRS})
- endif()
+ find_package(JeMalloc REQUIRED)
+ include_directories(SYSTEM ${JEMALLOC_INCLUDE_DIRS})
endif()
endif()
-find_package(LibIntl)
-if(LibIntl_FOUND)
+if(ENABLE_LIBINTL)
+ # LibIntl (not Intl) selects our FindLibIntl.cmake script. #8464
+ find_package(LibIntl REQUIRED)
include_directories(SYSTEM ${LibIntl_INCLUDE_DIRS})
endif()
-find_package(Iconv)
-if(Iconv_FOUND)
+if(ENABLE_LIBICONV)
+ find_package(Iconv REQUIRED)
include_directories(SYSTEM ${Iconv_INCLUDE_DIRS})
endif()
diff --git a/ci/build.ps1 b/ci/build.ps1
index 8eb237ccd1..7e686f3464 100644
--- a/ci/build.ps1
+++ b/ci/build.ps1
@@ -77,6 +77,7 @@ where.exe neovim-ruby-host.bat ; exitIfFailed
cmd /c npm.cmd install -g neovim ; exitIfFailed
where.exe neovim-node-host.cmd ; exitIfFailed
+cmd /c npm link neovim
function convertToCmakeArgs($vars) {
return $vars.GetEnumerator() | foreach { "-D$($_.Key)=$($_.Value)" }
diff --git a/ci/install.sh b/ci/install.sh
index 50f3490b63..e95e2f29c1 100755
--- a/ci/install.sh
+++ b/ci/install.sh
@@ -33,3 +33,4 @@ fi
echo "Install neovim npm package"
npm install -g neovim
+npm link neovim
diff --git a/cmake/FindLibIntl.cmake b/cmake/FindLibIntl.cmake
index f8442566a9..738ae39983 100644
--- a/cmake/FindLibIntl.cmake
+++ b/cmake/FindLibIntl.cmake
@@ -34,9 +34,8 @@ if (LibIntl_INCLUDE_DIR)
set(CMAKE_REQUIRED_INCLUDES "${LibIntl_INCLUDE_DIR}")
endif()
-# This is required because some operating systems don't have a separate
-# libintl--it is built into glibc. So we only need to specify the library
-# if one was actually found.
+# On some systems (linux+glibc) libintl is passively available.
+# So only specify the library if one was found.
if (LibIntl_LIBRARY)
set(CMAKE_REQUIRED_LIBRARIES "${LibIntl_LIBRARY}")
endif()
@@ -53,6 +52,13 @@ int main(int argc, char** argv) {
}" HAVE_WORKING_LIBINTL)
if (HAVE_WORKING_LIBINTL)
+ # On some systems (linux+glibc) libintl is passively available.
+ # If HAVE_WORKING_LIBINTL then we consider the requirement satisfied.
+ # Unset REQUIRED so that libfind_process(LibIntl) can proceed.
+ if(LibIntl_FIND_REQUIRED)
+ unset(LibIntl_FIND_REQUIRED)
+ endif()
+
check_variable_exists(_nl_msg_cat_cntr HAVE_NL_MSG_CAT_CNTR)
endif()
diff --git a/cmake/FindLibUV.cmake b/cmake/FindLibUV.cmake
index 3a60a831ea..29eaf15b8e 100644
--- a/cmake/FindLibUV.cmake
+++ b/cmake/FindLibUV.cmake
@@ -31,11 +31,7 @@ if(LIBUV_USE_STATIC)
"${CMAKE_STATIC_LIBRARY_PREFIX}uv${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif(LIBUV_USE_STATIC)
-if(MSVC)
- list(APPEND LIBUV_NAMES libuv)
-else()
- list(APPEND LIBUV_NAMES uv)
-endif()
+list(APPEND LIBUV_NAMES uv)
find_library(LIBUV_LIBRARY NAMES ${LIBUV_NAMES}
HINTS ${PC_LIBUV_LIBDIR} ${PC_LIBUV_LIBRARY_DIRS}
diff --git a/makedeps.bat b/makedeps.bat
new file mode 100644
index 0000000000..a614885568
--- /dev/null
+++ b/makedeps.bat
@@ -0,0 +1,18 @@
+echo off
+
+if not defined VS150COMNTOOLS (
+ echo error: missing VS150COMNTOOLS environment variable.
+ echo Run this script from the 'Developer Command Prompt'.
+ exit /b 1
+)
+
+echo on
+
+set CMAKE=%VS150COMNTOOLS%\..\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe
+
+mkdir .deps
+cd .deps
+"%CMAKE%" -G "Visual Studio 15 2017" "-DCMAKE_BUILD_TYPE=RelWithDebInfo" ..\third-party\
+"%CMAKE%" --build . --config RelWithDebInfo -- "/verbosity:normal"
+cd ..
+
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index fffdcef8d9..f404192abb 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -6789,10 +6789,12 @@ setpos({expr}, {list})
[bufnum, lnum, col, off, curswant]
"bufnum" is the buffer number. Zero can be used for the
- current buffer. Setting the cursor is only possible for
- the current buffer. To set a mark in another buffer you can
- use the |bufnr()| function to turn a file name into a buffer
- number.
+ current buffer. When setting an uppercase mark "bufnum" is
+ used for the mark position. For other marks it specifies the
+ buffer to set the mark in. You can use the |bufnr()| function
+ to turn a file name into a buffer number.
+ For setting the cursor and the ' mark "bufnum" is ignored,
+ since these are associated with a window, not a buffer.
Does not change the jumplist.
"lnum" and "col" are the position in the buffer. The first
diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt
index ab78b8b71c..cc485b655d 100644
--- a/runtime/doc/pattern.txt
+++ b/runtime/doc/pattern.txt
@@ -1071,25 +1071,27 @@ x A single character, with no special meaning, matches itself
- A character class expression is evaluated to the set of characters
belonging to that character class. The following character classes
are supported:
- Name Contents ~
-*[:alnum:]* [:alnum:] ASCII letters and digits
-*[:alpha:]* [:alpha:] ASCII letters
-*[:blank:]* [:blank:] space and tab characters
-*[:cntrl:]* [:cntrl:] control characters
-*[:digit:]* [:digit:] decimal digits
-*[:graph:]* [:graph:] printable characters excluding space
-*[:lower:]* [:lower:] lowercase letters (all letters when
+ Name Func Contents ~
+*[:alnum:]* [:alnum:] isalnum ASCII letters and digits
+*[:alpha:]* [:alpha:] isalpha ASCII letters
+*[:blank:]* [:blank:] space and tab
+*[:cntrl:]* [:cntrl:] iscntrl ASCII control characters
+*[:digit:]* [:digit:] decimal digits '0' to '9'
+*[:graph:]* [:graph:] isgraph ASCII printable characters excluding
+ space
+*[:lower:]* [:lower:] (1) lowercase letters (all letters when
'ignorecase' is used)
-*[:print:]* [:print:] printable characters including space
-*[:punct:]* [:punct:] ASCII punctuation characters
-*[:space:]* [:space:] whitespace characters
-*[:upper:]* [:upper:] uppercase letters (all letters when
+*[:print:]* [:print:] (2) printable characters including space
+*[:punct:]* [:punct:] ispunct ASCII punctuation characters
+*[:space:]* [:space:] whitespace characters: space, tab, CR,
+ NL, vertical tab, form feed
+*[:upper:]* [:upper:] (3) uppercase letters (all letters when
'ignorecase' is used)
-*[:xdigit:]* [:xdigit:] hexadecimal digits
-*[:return:]* [:return:] the <CR> character
-*[:tab:]* [:tab:] the <Tab> character
-*[:escape:]* [:escape:] the <Esc> character
-*[:backspace:]* [:backspace:] the <BS> character
+*[:xdigit:]* [:xdigit:] hexadecimal digits: 0-9, a-f, A-F
+*[:return:]* [:return:] the <CR> character
+*[:tab:]* [:tab:] the <Tab> character
+*[:escape:]* [:escape:] the <Esc> character
+*[:backspace:]* [:backspace:] the <BS> character
The brackets in character class expressions are additional to the
brackets delimiting a collection. For example, the following is a
plausible pattern for a Unix filename: "[-./[:alnum:]_~]\+" That is,
@@ -1100,6 +1102,13 @@ x A single character, with no special meaning, matches itself
regexp engine. See |two-engines|. In the future these items may
work for multi-byte characters. For now, to get all "alpha"
characters you can use: [[:lower:][:upper:]].
+
+ The "Func" column shows what library function is used. The
+ implementation depends on the system. Otherwise:
+ (1) Uses islower() for ASCII and Vim builtin rules for other
+ characters when built with the |+multi_byte| feature.
+ (2) Uses Vim builtin rules
+ (3) As with (1) but using isupper()
*/[[=* *[==]*
- An equivalence class. This means that characters are matched that
have almost the same meaning, e.g., when ignoring accents. This
diff --git a/runtime/mswin.vim b/runtime/mswin.vim
index ca280d227c..da869a9fc7 100644
--- a/runtime/mswin.vim
+++ b/runtime/mswin.vim
@@ -1,7 +1,7 @@
" Set options and add mapping such that Vim behaves a lot like MS-Windows
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last change: 2012 Jul 25
+" Last change: 2017 Oct 28
" bail out if this isn't wanted (mrsvim.vim uses this).
if exists("g:skip_loading_mswin") && g:skip_loading_mswin
@@ -23,20 +23,22 @@ set backspace=indent,eol,start whichwrap+=<,>,[,]
" backspace in Visual mode deletes selection
vnoremap <BS> d
-" CTRL-X and SHIFT-Del are Cut
-vnoremap <C-X> "+x
-vnoremap <S-Del> "+x
+if has("clipboard")
+ " CTRL-X and SHIFT-Del are Cut
+ vnoremap <C-X> "+x
+ vnoremap <S-Del> "+x
-" CTRL-C and CTRL-Insert are Copy
-vnoremap <C-C> "+y
-vnoremap <C-Insert> "+y
+ " CTRL-C and CTRL-Insert are Copy
+ vnoremap <C-C> "+y
+ vnoremap <C-Insert> "+y
-" CTRL-V and SHIFT-Insert are Paste
-map <C-V> "+gP
-map <S-Insert> "+gP
+ " CTRL-V and SHIFT-Insert are Paste
+ map <C-V> "+gP
+ map <S-Insert> "+gP
-cmap <C-V> <C-R>+
-cmap <S-Insert> <C-R>+
+ cmap <C-V> <C-R>+
+ cmap <S-Insert> <C-R>+
+endif
" Pasting blockwise and linewise selections is not possible in Insert and
" Visual mode without the +virtualedit feature. They are pasted as if they
@@ -44,8 +46,10 @@ cmap <S-Insert> <C-R>+
" Uses the paste.vim autoload script.
" Use CTRL-G u to have CTRL-Z only undo the paste.
-exe 'inoremap <script> <C-V> <C-G>u' . paste#paste_cmd['i']
-exe 'vnoremap <script> <C-V> ' . paste#paste_cmd['v']
+if 1
+ exe 'inoremap <script> <C-V> <C-G>u' . paste#paste_cmd['i']
+ exe 'vnoremap <script> <C-V> ' . paste#paste_cmd['v']
+endif
imap <S-Insert> <C-V>
vmap <S-Insert> <C-V>
@@ -99,6 +103,19 @@ inoremap <C-F4> <C-O><C-W>c
cnoremap <C-F4> <C-C><C-W>c
onoremap <C-F4> <C-C><C-W>c
+if has("gui")
+ " CTRL-F is the search dialog
+ noremap <expr> <C-F> has("gui_running") ? ":promptfind\<CR>" : "/"
+ inoremap <expr> <C-F> has("gui_running") ? "\<C-\>\<C-O>:promptfind\<CR>" : "\<C-\>\<C-O>/"
+ cnoremap <expr> <C-F> has("gui_running") ? "\<C-\>\<C-C>:promptfind\<CR>" : "\<C-\>\<C-O>/"
+
+ " CTRL-H is the replace dialog,
+ " but in console, it might be backspace, so don't map it there
+ nnoremap <expr> <C-H> has("gui_running") ? ":promptrepl\<CR>" : "\<C-H>"
+ inoremap <expr> <C-H> has("gui_running") ? "\<C-\>\<C-O>:promptrepl\<CR>" : "\<C-H>"
+ cnoremap <expr> <C-H> has("gui_running") ? "\<C-\>\<C-C>:promptrepl\<CR>" : "\<C-H>"
+endif
+
" restore 'cpoptions'
set cpo&
if 1
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 2d803792c8..65c3c6bbb9 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -457,6 +457,8 @@ if(WIN32)
COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Widgets.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/winpty.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/libiconv-2.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+
COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/platforms/qwindows.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/platforms/
)
add_dependencies(nvim_runtime_deps external_blobs)
@@ -484,7 +486,9 @@ set_property(
APPEND_STRING PROPERTY COMPILE_FLAGS " -DMAKE_LIB "
)
-if(LUAJIT_FOUND)
+if(NOT LUAJIT_FOUND)
+ message(STATUS "luajit not found, skipping nvim-test (unit tests) target")
+else()
set(NVIM_TEST_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES} ${LUAJIT_LIBRARIES})
add_library(
nvim-test
diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c
index f8eebcdb10..5207a57b88 100644
--- a/src/nvim/api/private/dispatch.c
+++ b/src/nvim/api/private/dispatch.c
@@ -29,6 +29,8 @@ static void msgpack_rpc_add_method_handler(String method,
map_put(String, MsgpackRpcRequestHandler)(methods, method, handler);
}
+/// @param name API method name
+/// @param name_len name size (includes terminating NUL)
MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
size_t name_len)
{
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 4cd2657561..b6e0b9a566 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -97,6 +97,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
ui->set_icon = remote_ui_set_icon;
ui->option_set = remote_ui_option_set;
ui->event = remote_ui_event;
+ ui->inspect = remote_ui_inspect;
memset(ui->ui_ext, 0, sizeof(ui->ui_ext));
@@ -275,3 +276,9 @@ static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed)
}
push_call(ui, name, my_args);
}
+
+static void remote_ui_inspect(UI *ui, Dictionary *info)
+{
+ UIData *data = ui->data;
+ PUT(*info, "chan", INTEGER_OBJ((Integer)data->channel_id));
+}
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
index 96d494460b..3ef16a7ac3 100644
--- a/src/nvim/api/ui_events.in.h
+++ b/src/nvim/api/ui_events.in.h
@@ -62,7 +62,7 @@ void set_title(String title)
void set_icon(String icon)
FUNC_API_SINCE(3);
void option_set(String name, Object value)
- FUNC_API_SINCE(4);
+ FUNC_API_SINCE(4) FUNC_API_BRIDGE_IMPL;
void popupmenu_show(Array items, Integer selected, Integer row, Integer col)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index f587948cf0..b3ae52602b 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -16,6 +16,7 @@
#include "nvim/api/private/dispatch.h"
#include "nvim/api/buffer.h"
#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/lua/executor.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
@@ -1163,6 +1164,11 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
MsgpackRpcRequestHandler handler = msgpack_rpc_get_handler_for(name.data,
name.size);
+ if (handler.fn == msgpack_rpc_handle_missing_method) {
+ api_set_error(&nested_error, kErrorTypeException, "Invalid method: %s",
+ name.size > 0 ? name.data : "<empty>");
+ break;
+ }
Object result = handler.fn(channel_id, args, &nested_error);
if (ERROR_SET(&nested_error)) {
// error handled after loop
@@ -1747,6 +1753,14 @@ Dictionary nvim__stats(void)
/// Gets a list of dictionaries representing attached UIs.
///
/// @return Array of UI dictionaries
+///
+/// Each dictionary has the following keys:
+/// - "height" requested height of the UI
+/// - "width" requested width of the UI
+/// - "rgb" whether the UI uses rgb colors (false implies cterm colors)
+/// - "ext_..." Requested UI extensions, see |ui-options|
+/// - "chan" Channel id of remote UI (not present for TUI)
+///
Array nvim_list_uis(void)
FUNC_API_SINCE(4)
{
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index af77a9891b..838f267dcd 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -575,7 +575,7 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
/* Change directories when the 'acd' option is set. */
do_autochdir();
- // disable live updates for the current buffer
+ // disable buffer updates for the current buffer
buf_updates_unregister_all(buf);
/*
diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c
index 4774b969c4..157f80e55a 100644
--- a/src/nvim/buffer_updates.c
+++ b/src/nvim/buffer_updates.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include "nvim/buffer_updates.h"
#include "nvim/memline.h"
#include "nvim/api/private/helpers.h"
@@ -199,7 +202,7 @@ void buf_updates_send_changes(buf_T *buf,
// change notifications are so frequent that many dead channels will be
// cleared up quickly.
if (badchannelid != 0) {
- ELOG("Disabling live updates for dead channel %llu", badchannelid);
+ ELOG("Disabling buffer updates for dead channel %llu", badchannelid);
buf_updates_unregister(buf, badchannelid);
}
}
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 64d743891b..6ad64bbb85 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -602,6 +602,7 @@ static void on_channel_output(Stream *stream, Channel *chan, RBuffer *buf,
// process_channel_event will modify the read buffer(convert NULs into NLs)
if (chan->term) {
terminal_receive(chan->term, ptr, count);
+ terminal_flush_output(chan->term);
}
rbuffer_consumed(buf, count);
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 7d5f80c531..4f70bcc41a 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1018,7 +1018,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
// needs a break here
if (wp->w_p_lbr
&& vim_isbreak(c)
- && !vim_isbreak(s[1])
+ && !vim_isbreak((int)s[1])
&& wp->w_p_wrap
&& (wp->w_width != 0)) {
// Count all characters from first non-blank after a blank up to next
@@ -1042,7 +1042,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
c = *s;
if (!(c != NUL
- && (vim_isbreak(c) || col2 == col || !vim_isbreak(*ps)))) {
+ && (vim_isbreak(c) || col2 == col || !vim_isbreak((int)(*ps))))) {
break;
}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index ffea88aa83..9c29f18c0c 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -6742,36 +6742,39 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv,
char_u *tofree;
if (opt_msg_tv->v_type != VAR_UNKNOWN) {
- tofree = (char_u *) encode_tv2string(opt_msg_tv, NULL);
+ tofree = (char_u *)encode_tv2echo(opt_msg_tv, NULL);
ga_concat(gap, tofree);
xfree(tofree);
+ ga_concat(gap, (char_u *)": ");
+ }
+
+ if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH) {
+ ga_concat(gap, (char_u *)"Pattern ");
+ } else if (atype == ASSERT_NOTEQUAL) {
+ ga_concat(gap, (char_u *)"Expected not equal to ");
} else {
- if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH) {
- ga_concat(gap, (char_u *)"Pattern ");
- } else if (atype == ASSERT_NOTEQUAL) {
- ga_concat(gap, (char_u *)"Expected not equal to ");
- } else {
- ga_concat(gap, (char_u *)"Expected ");
- }
- if (exp_str == NULL) {
- tofree = (char_u *)encode_tv2string(exp_tv, NULL);
- ga_concat_esc(gap, tofree);
- xfree(tofree);
+ ga_concat(gap, (char_u *)"Expected ");
+ }
+
+ if (exp_str == NULL) {
+ tofree = (char_u *)encode_tv2string(exp_tv, NULL);
+ ga_concat_esc(gap, tofree);
+ xfree(tofree);
+ } else {
+ ga_concat_esc(gap, exp_str);
+ }
+
+ if (atype != ASSERT_NOTEQUAL) {
+ if (atype == ASSERT_MATCH) {
+ ga_concat(gap, (char_u *)" does not match ");
+ } else if (atype == ASSERT_NOTMATCH) {
+ ga_concat(gap, (char_u *)" does match ");
} else {
- ga_concat_esc(gap, exp_str);
- }
- if (atype != ASSERT_NOTEQUAL) {
- if (atype == ASSERT_MATCH) {
- ga_concat(gap, (char_u *)" does not match ");
- } else if (atype == ASSERT_NOTMATCH) {
- ga_concat(gap, (char_u *)" does match ");
- } else {
- ga_concat(gap, (char_u *)" but got ");
- }
- tofree = (char_u *)encode_tv2string(got_tv, NULL);
- ga_concat_esc(gap, tofree);
- xfree(tofree);
+ ga_concat(gap, (char_u *)" but got ");
}
+ tofree = (char_u *)encode_tv2string(got_tv, NULL);
+ ga_concat_esc(gap, tofree);
+ xfree(tofree);
}
}
@@ -14806,18 +14809,14 @@ static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
pos.col = 0;
}
if (name[0] == '.' && name[1] == NUL) {
- // set cursor
- if (fnum == curbuf->b_fnum) {
- curwin->w_cursor = pos;
- if (curswant >= 0) {
- curwin->w_curswant = curswant - 1;
- curwin->w_set_curswant = false;
- }
- check_cursor();
- rettv->vval.v_number = 0;
- } else {
- EMSG(_(e_invarg));
+ // set cursor; "fnum" is ignored
+ curwin->w_cursor = pos;
+ if (curswant >= 0) {
+ curwin->w_curswant = curswant - 1;
+ curwin->w_set_curswant = false;
}
+ check_cursor();
+ rettv->vval.v_number = 0;
} else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
// set mark
if (setmark_pos((uint8_t)name[1], &pos, fnum) == OK) {
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index ce02808ad3..c87e3d4c66 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -698,7 +698,7 @@ return {
},
{
command='delfunction',
- flags=bit.bor(NEEDARG, WORD1, CMDWIN),
+ flags=bit.bor(BANG, NEEDARG, WORD1, CMDWIN),
addr_type=ADDR_LINES,
func='ex_delfunction',
},
@@ -3082,7 +3082,7 @@ return {
},
{
command='windo',
- flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL),
+ flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL),
addr_type=ADDR_WINDOWS,
func='ex_listdo',
},
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 52b810085c..e1efd5710d 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -8104,6 +8104,7 @@ static void ex_normal(exarg_T *eap)
if (eap->addr_count != 0) {
curwin->w_cursor.lnum = eap->line1++;
curwin->w_cursor.col = 0;
+ check_cursor_moved(curwin);
}
exec_normal_cmd(
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 96388a2a9d..2c828be083 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -295,10 +295,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
redir_off = true; // don't redirect the typed command
if (!cmd_silent) {
- s->i = msg_scrolled;
- msg_scrolled = 0; // avoid wait_return message
gotocmdline(true);
- msg_scrolled += s->i;
redrawcmdprompt(); // draw prompt or indent
set_cmdspos();
}
@@ -349,7 +346,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
// redraw the statusline for statuslines that display the current mode
// using the mode() function.
- if (KeyTyped) {
+ if (KeyTyped && msg_scrolled == 0) {
curwin->w_redr_status = true;
redraw_statuslines();
}
@@ -629,6 +626,7 @@ static int command_line_execute(VimState *state, int key)
// Entered command line, move it up
cmdline_row--;
redrawcmd();
+ wild_menu_showing = 0;
} else if (save_p_ls != -1) {
// restore 'laststatus' and 'winminheight'
p_ls = save_p_ls;
@@ -639,12 +637,13 @@ static int command_line_execute(VimState *state, int key)
restore_cmdline(&s->save_ccline);
redrawcmd();
save_p_ls = -1;
+ wild_menu_showing = 0;
} else {
win_redraw_last_status(topframe);
+ wild_menu_showing = 0; // must be before redraw_statuslines #8385
redraw_statuslines();
}
KeyTyped = skt;
- wild_menu_showing = 0;
if (ccline.input_fn) {
RedrawingDisabled = old_RedrawingDisabled;
}
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index b8ace511e8..52ed2fe3dc 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -2464,27 +2464,27 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
flp->lnum - 1 - fp->fd_top);
if (lvl < level) {
- /* End of fold found, update the length when it got shorter. */
+ // End of fold found, update the length when it got shorter.
if (fp->fd_len != flp->lnum - fp->fd_top) {
- if (fp->fd_top + fp->fd_len > bot + 1) {
- /* fold continued below bot */
+ if (fp->fd_top + fp->fd_len - 1 > bot) {
+ // fold continued below bot
if (getlevel == foldlevelMarker
|| getlevel == foldlevelExpr
|| getlevel == foldlevelSyntax) {
- /* marker method: truncate the fold and make sure the
- * previously included lines are processed again */
+ // marker method: truncate the fold and make sure the
+ // previously included lines are processed again
bot = fp->fd_top + fp->fd_len - 1;
fp->fd_len = flp->lnum - fp->fd_top;
} else {
- /* indent or expr method: split fold to create a new one
- * below bot */
+ // indent or expr method: split fold to create a new one
+ // below bot
i = (int)(fp - (fold_T *)gap->ga_data);
foldSplit(gap, i, flp->lnum, bot);
fp = (fold_T *)gap->ga_data + i;
}
} else
fp->fd_len = flp->lnum - fp->fd_top;
- fold_changed = TRUE;
+ fold_changed = true;
}
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 4aa0ef7def..2860817f79 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -745,11 +745,9 @@ EXTERN int State INIT(= NORMAL); /* This is the current state of the
EXTERN bool finish_op INIT(= false); // true while an operator is pending
EXTERN long opcount INIT(= 0); // count for pending operator
-/*
- * ex mode (Q) state
- */
-EXTERN int exmode_active INIT(= 0); /* zero, EXMODE_NORMAL or EXMODE_VIM */
-EXTERN int ex_no_reprint INIT(= FALSE); /* no need to print after z or p */
+// Ex Mode (Q) state
+EXTERN int exmode_active INIT(= 0); // zero, EXMODE_NORMAL or EXMODE_VIM
+EXTERN int ex_no_reprint INIT(= false); // no need to print after z or p
EXTERN int Recording INIT(= FALSE); /* TRUE when recording into a reg. */
EXTERN int Exec_reg INIT(= FALSE); /* TRUE when executing a register */
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 3cd26a5bf7..bcd9cf2090 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -106,39 +106,41 @@ int setmark_pos(int c, pos_T *pos, int fnum)
return OK;
}
+ // Can't set a mark in a non-existant buffer.
+ buf_T *buf = buflist_findnr(fnum);
+ if (buf == NULL) {
+ return FAIL;
+ }
+
if (c == '"') {
- RESET_FMARK(&curbuf->b_last_cursor, *pos, curbuf->b_fnum);
+ RESET_FMARK(&buf->b_last_cursor, *pos, buf->b_fnum);
return OK;
}
/* Allow setting '[ and '] for an autocommand that simulates reading a
* file. */
if (c == '[') {
- curbuf->b_op_start = *pos;
+ buf->b_op_start = *pos;
return OK;
}
if (c == ']') {
- curbuf->b_op_end = *pos;
+ buf->b_op_end = *pos;
return OK;
}
if (c == '<' || c == '>') {
- if (c == '<')
- curbuf->b_visual.vi_start = *pos;
- else
- curbuf->b_visual.vi_end = *pos;
- if (curbuf->b_visual.vi_mode == NUL)
- /* Visual_mode has not yet been set, use a sane default. */
- curbuf->b_visual.vi_mode = 'v';
+ if (c == '<') {
+ buf->b_visual.vi_start = *pos;
+ } else {
+ buf->b_visual.vi_end = *pos;
+ }
+ if (buf->b_visual.vi_mode == NUL) {
+ // Visual_mode has not yet been set, use a sane default.
+ buf->b_visual.vi_mode = 'v';
+ }
return OK;
}
- buf_T *buf = buflist_findnr(fnum);
- // Can't set a mark in a non-existant buffer.
- if (buf == NULL) {
- return FAIL;
- }
-
if (ASCII_ISLOWER(c)) {
i = c - 'a';
RESET_FMARK(buf->b_namedm + i, *pos, fnum);
@@ -358,13 +360,14 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, int changefile, int *fnum)
} else if (c == '<' || c == '>') { /* start/end of visual area */
startp = &buf->b_visual.vi_start;
endp = &buf->b_visual.vi_end;
- if ((c == '<') == lt(*startp, *endp))
+ if (((c == '<') == lt(*startp, *endp) || endp->lnum == 0)
+ && startp->lnum != 0) {
posp = startp;
- else
+ } else {
posp = endp;
- /*
- * For Visual line mode, set mark at begin or end of line
- */
+ }
+
+ // For Visual line mode, set mark at begin or end of line
if (buf->b_visual.vi_mode == 'V') {
pos_copy = *posp;
posp = &pos_copy;
@@ -647,8 +650,8 @@ void do_marks(exarg_T *eap)
show_one_mark(-1, arg, NULL, NULL, false);
}
-static void
-show_one_mark (
+static void
+show_one_mark(
int c,
char_u *arg,
pos_T *p,
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index a52ab9f5d3..05e326104b 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -37,6 +37,8 @@
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
+#include "nvim/eval.h"
+#include "nvim/path.h"
#include "nvim/iconv.h"
#include "nvim/mbyte.h"
#include "nvim/charset.h"
@@ -72,6 +74,9 @@ struct interval {
# include "unicode_tables.generated.h"
#endif
+char_u e_loadlib[] = "E370: Could not load library %s";
+char_u e_loadfunc[] = "E448: Could not load library function %s";
+
// To speed up BYTELEN(); keep a lookup table to quickly get the length in
// bytes of a UTF-8 character from the first byte of a UTF-8 string. Bytes
// which are illegal when used as the first byte have a 1. The NUL byte has
@@ -2038,9 +2043,10 @@ void * my_iconv_open(char_u *to, char_u *from)
return (void *)-1; /* detected a broken iconv() previously */
#ifdef DYNAMIC_ICONV
- /* Check if the iconv.dll can be found. */
- if (!iconv_enabled(true))
+ // Check if the iconv.dll can be found.
+ if (!iconv_enabled(true)) {
return (void *)-1;
+ }
#endif
fd = iconv_open((char *)enc_skip(to), (char *)enc_skip(from));
@@ -2162,7 +2168,7 @@ static HINSTANCE hMsvcrtDLL = 0;
# ifndef DYNAMIC_ICONV_DLL
# define DYNAMIC_ICONV_DLL "iconv.dll"
-# define DYNAMIC_ICONV_DLL_ALT "libiconv.dll"
+# define DYNAMIC_ICONV_DLL_ALT "libiconv-2.dll"
# endif
# ifndef DYNAMIC_MSVCRT_DLL
# define DYNAMIC_MSVCRT_DLL "msvcrt.dll"
@@ -2208,6 +2214,35 @@ static void * get_iconv_import_func(HINSTANCE hInst,
return NULL;
}
+// Load library "name".
+HINSTANCE vimLoadLib(char *name)
+{
+ HINSTANCE dll = NULL;
+
+ // NOTE: Do not use mch_dirname() and mch_chdir() here, they may call
+ // vimLoadLib() recursively, which causes a stack overflow.
+ WCHAR old_dirw[MAXPATHL];
+
+ // Path to exe dir.
+ char *buf = xstrdup((char *)get_vim_var_str(VV_PROGPATH));
+ // ptrdiff_t len = ;
+ // assert(len > 0);
+ buf[path_tail_with_sep(buf) - buf] = '\0';
+
+ if (GetCurrentDirectoryW(MAXPATHL, old_dirw) != 0) {
+ // Change directory to where the executable is, both to make
+ // sure we find a .dll there and to avoid looking for a .dll
+ // in the current directory.
+ SetCurrentDirectory((LPCSTR)buf);
+ // TODO(justinmk): use uv_dlopen instead. see os_libcall
+ dll = LoadLibrary(name);
+ SetCurrentDirectoryW(old_dirw);
+ }
+
+ return dll;
+}
+
+
/*
* Try opening the iconv.dll and return TRUE if iconv() can be used.
*/
@@ -2255,10 +2290,13 @@ bool iconv_enabled(bool verbose)
void iconv_end(void)
{
- if (hIconvDLL != 0)
+ if (hIconvDLL != 0) {
+ // TODO(justinmk): use uv_dlclose instead.
FreeLibrary(hIconvDLL);
- if (hMsvcrtDLL != 0)
+ }
+ if (hMsvcrtDLL != 0) {
FreeLibrary(hMsvcrtDLL);
+ }
hIconvDLL = 0;
hMsvcrtDLL = 0;
}
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 6c5c47b91f..70733e5564 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -107,7 +107,8 @@ open_line (
char_u *p;
char_u saved_char = NUL; // init for GCC
pos_T *pos;
- bool do_si = (!p_paste && curbuf->b_p_si && !curbuf->b_p_cin);
+ bool do_si = (!p_paste && curbuf->b_p_si && !curbuf->b_p_cin
+ && *curbuf->b_p_inde == NUL);
bool no_si = false; // reset did_si afterwards
int first_char = NUL; // init for GCC
int vreplace_mode;
diff --git a/src/nvim/move.c b/src/nvim/move.c
index cb13a9e207..41859a489f 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -132,11 +132,9 @@ void update_topline(void)
bool check_botline = false;
long save_so = p_so;
- if (!screen_valid(true))
- return;
-
- // If the window height is zero, just use the cursor line.
- if (curwin->w_height == 0) {
+ // If there is no valid screen and when the window height is zero just use
+ // the cursor line.
+ if (!screen_valid(true) || curwin->w_height == 0) {
curwin->w_topline = curwin->w_cursor.lnum;
curwin->w_botline = curwin->w_topline;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
@@ -1979,6 +1977,7 @@ void halfpage(bool flag, linenr_T Prenum)
int n = curwin->w_p_scr <= curwin->w_height ? (int)curwin->w_p_scr
: curwin->w_height;
+ update_topline();
validate_botline();
int room = curwin->w_empty_rows + curwin->w_filler_rows;
if (flag) {
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 26b84b7cc7..6d0c270a51 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -312,24 +312,30 @@ static void handle_request(Channel *channel, msgpack_object *request)
api_clear_error(&error);
return;
}
+
// Retrieve the request handler
MsgpackRpcRequestHandler handler;
+ Array args = ARRAY_DICT_INIT;
msgpack_object *method = msgpack_rpc_method(request);
if (method) {
handler = msgpack_rpc_get_handler_for(method->via.bin.ptr,
method->via.bin.size);
+ if (handler.fn == msgpack_rpc_handle_missing_method) {
+ String m = method->via.bin.size > 0
+ ? cbuf_to_string(method->via.bin.ptr, method->via.bin.size)
+ : cstr_to_string("<empty>");
+ ADD(args, STRING_OBJ(m));
+ handler.async = true;
+ } else if (!msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) {
+ handler.fn = msgpack_rpc_handle_invalid_arguments;
+ handler.async = true;
+ }
} else {
handler.fn = msgpack_rpc_handle_missing_method;
handler.async = true;
}
- Array args = ARRAY_DICT_INIT;
- if (!msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) {
- handler.fn = msgpack_rpc_handle_invalid_arguments;
- handler.async = true;
- }
-
RequestEvent *evdata = xmalloc(sizeof(RequestEvent));
evdata->channel = channel;
evdata->handler = handler;
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index fecae11d45..e18c4472b5 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -493,7 +493,8 @@ Object msgpack_rpc_handle_missing_method(uint64_t channel_id,
Array args,
Error *error)
{
- api_set_error(error, kErrorTypeException, "Invalid method name");
+ api_set_error(error, kErrorTypeException, "Invalid method: %s",
+ args.size > 0 ? args.items[0].data.string.data : "?");
return NIL;
}
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 88c458b597..26fc164c6c 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -939,11 +939,8 @@ void set_init_2(bool headless)
{
int idx;
- /*
- * 'scroll' defaults to half the window height. Note that this default is
- * wrong when the window height changes.
- */
- set_number_default("scroll", Rows / 2);
+ // 'scroll' defaults to half the window height. The stored default is zero,
+ // which results in the actual value computed from the window height.
idx = findoption("scroll");
if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
set_option_default(idx, OPT_LOCAL, p_cp);
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index f1f559fff0..47c9f5aa78 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -1922,7 +1922,7 @@ return {
no_mkrc=true,
vi_def=true,
pv_name='p_scroll',
- defaults={if_true={vi=12}}
+ defaults={if_true={vi=0}}
},
{
full_name='scrollback', abbreviation='scbk',
diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c
index 82bb918f70..7c48ac6e5e 100644
--- a/src/nvim/os/users.c
+++ b/src/nvim/os/users.c
@@ -76,7 +76,7 @@ char *os_get_user_directory(const char *name)
{
#if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
struct passwd *pw;
- if (name == NULL) {
+ if (name == NULL || *name == NUL) {
return NULL;
}
pw = getpwnam(name); // NOLINT(runtime/threadsafe_fn)
diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h
index db93f016bf..356094baa1 100644
--- a/src/nvim/os/win_defs.h
+++ b/src/nvim/os/win_defs.h
@@ -59,7 +59,6 @@
#define BACKSLASH_IN_FILENAME
#ifdef _MSC_VER
-typedef SSIZE_T ssize_t;
typedef int mode_t;
#endif
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 4f3f7c0661..61cfaea84a 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -1097,17 +1097,18 @@ static bool has_env_var(char_u *p)
}
#ifdef SPECIAL_WILDCHAR
-/*
- * Return TRUE if "p" contains a special wildcard character.
- * Allowing for escaping.
- */
+
+// Return TRUE if "p" contains a special wildcard character, one that Vim
+// cannot expand, requires using a shell.
static bool has_special_wildchar(char_u *p)
{
for (; *p; mb_ptr_adv(p)) {
- if (*p == '\\' && p[1] != NUL)
- ++p;
- else if (vim_strchr((char_u *)SPECIAL_WILDCHAR, *p) != NULL)
+ // Allow for escaping
+ if (*p == '\\' && p[1] != NUL) {
+ p++;
+ } else if (vim_strchr((char_u *)SPECIAL_WILDCHAR, *p) != NULL) {
return true;
+ }
}
return false;
}
@@ -2033,7 +2034,7 @@ int expand_wildcards(int num_pat, char_u **pat, int *num_files, char_u ***files,
break;
}
if (match_file_list(p_wig, (*files)[i], ffname)) {
- // remove this matching files from the list
+ // remove this matching file from the list
xfree((*files)[i]);
for (j = i; j + 1 < *num_files; j++) {
(*files)[j] = (*files)[j + 1];
diff --git a/src/nvim/po/CMakeLists.txt b/src/nvim/po/CMakeLists.txt
index 94cc63baea..a7b910f0eb 100644
--- a/src/nvim/po/CMakeLists.txt
+++ b/src/nvim/po/CMakeLists.txt
@@ -1,4 +1,4 @@
-find_package(Gettext)
+find_package(Gettext REQUIRED)
find_program(XGETTEXT_PRG xgettext)
find_program(ICONV_PRG iconv)
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index e4de43b49e..c4af7d9e4a 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -479,6 +479,8 @@ static char_u *regprop(char_u *);
#endif
static char_u e_missingbracket[] = N_("E769: Missing ] after %s[");
+static char_u e_reverse_range[] = N_("E944: Reverse range in character class");
+static char_u e_large_class[] = N_("E945: Range too large in character class");
static char_u e_unmatchedpp[] = N_("E53: Unmatched %s%%(");
static char_u e_unmatchedp[] = N_("E54: Unmatched %s(");
static char_u e_unmatchedpar[] = N_("E55: Unmatched %s)");
@@ -2232,15 +2234,18 @@ collection:
if (endc == '\\' && !reg_cpo_lit)
endc = coll_get_char();
- if (startc > endc)
- EMSG_RET_NULL(_(e_invrange));
+ if (startc > endc) {
+ EMSG_RET_NULL(_(e_reverse_range));
+ }
if (has_mbyte && ((*mb_char2len)(startc) > 1
|| (*mb_char2len)(endc) > 1)) {
- /* Limit to a range of 256 chars */
- if (endc > startc + 256)
- EMSG_RET_NULL(_(e_invrange));
- while (++startc <= endc)
+ // Limit to a range of 256 chars
+ if (endc > startc + 256) {
+ EMSG_RET_NULL(_(e_large_class));
+ }
+ while (++startc <= endc) {
regmbc(startc);
+ }
} else {
while (++startc <= endc)
regc(startc);
@@ -2328,21 +2333,21 @@ collection:
regc('\t');
break;
case CLASS_CNTRL:
- for (cu = 1; cu <= 255; cu++) {
+ for (cu = 1; cu <= 127; cu++) {
if (iscntrl(cu)) {
regmbc(cu);
}
}
break;
case CLASS_DIGIT:
- for (cu = 1; cu <= 255; cu++) {
+ for (cu = 1; cu <= 127; cu++) {
if (ascii_isdigit(cu)) {
regmbc(cu);
}
}
break;
case CLASS_GRAPH:
- for (cu = 1; cu <= 255; cu++) {
+ for (cu = 1; cu <= 127; cu++) {
if (isgraph(cu)) {
regmbc(cu);
}
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 98fae858f6..334539b228 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -1711,8 +1711,9 @@ collection:
if (emit_range) {
endc = startc;
startc = oldstartc;
- if (startc > endc)
- EMSG_RET_FAIL(_(e_invrange));
+ if (startc > endc) {
+ EMSG_RET_FAIL(_(e_reverse_range));
+ }
if (endc > startc + 2) {
/* Emit a range instead of the sequence of
@@ -4358,16 +4359,18 @@ static int check_char_class(int class, int c)
return OK;
break;
case NFA_CLASS_CNTRL:
- if (c >= 1 && c <= 255 && iscntrl(c))
+ if (c >= 1 && c <= 127 && iscntrl(c)) {
return OK;
+ }
break;
case NFA_CLASS_DIGIT:
if (ascii_isdigit(c))
return OK;
break;
case NFA_CLASS_GRAPH:
- if (c >= 1 && c <= 255 && isgraph(c))
+ if (c >= 1 && c <= 127 && isgraph(c)) {
return OK;
+ }
break;
case NFA_CLASS_LOWER:
if (mb_islower(c) && c != 170 && c != 186) {
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index f15afa619f..b0bf3a7d5f 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -3454,7 +3454,8 @@ win_line (
}
// Found last space before word: check for line break.
- if (wp->w_p_lbr && c0 == c && vim_isbreak(c) && !vim_isbreak(*ptr)) {
+ if (wp->w_p_lbr && c0 == c && vim_isbreak(c)
+ && !vim_isbreak((int)(*ptr))) {
int mb_off = has_mbyte ? (*mb_head_off)(line, ptr - 1) : 0;
char_u *p = ptr - (mb_off + 1);
// TODO: is passing p for start of the line OK?
@@ -4060,7 +4061,8 @@ win_line (
* Also highlight the 'colorcolumn' if it is different than
* 'cursorcolumn' */
vcol_save_attr = -1;
- if (draw_state == WL_LINE && !lnum_in_visual_area) {
+ if (draw_state == WL_LINE && !lnum_in_visual_area
+ && search_attr == 0 && area_attr == 0) {
if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol
&& lnum != wp->w_cursor.lnum) {
vcol_save_attr = char_attr;
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 84782497a0..14a7d41300 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -130,8 +130,8 @@ typedef struct SearchedFile {
*
* returns FAIL if failed, OK otherwise.
*/
-int
-search_regcomp (
+int
+search_regcomp(
char_u *pat,
int pat_save,
int pat_use,
@@ -2121,9 +2121,9 @@ static int check_linecomment(char_u *line)
* Show the match only if it is visible on the screen.
* If there isn't a match, then beep.
*/
-void
-showmatch (
- int c /* char to show match for */
+void
+showmatch(
+ int c // char to show match for
)
{
pos_T *lpos, save_cursor;
@@ -2377,8 +2377,14 @@ findpar (
++curr;
curwin->w_cursor.lnum = curr;
if (curr == curbuf->b_ml.ml_line_count && what != '}') {
- if ((curwin->w_cursor.col = (colnr_T)STRLEN(ml_get(curr))) != 0) {
- --curwin->w_cursor.col;
+ char_u *line = ml_get(curr);
+
+ // Put the cursor on the last character in the last line and make the
+ // motion inclusive.
+ if ((curwin->w_cursor.col = (colnr_T)STRLEN(line)) != 0) {
+ curwin->w_cursor.col--;
+ curwin->w_cursor.col -=
+ (*mb_head_off)(line, line + curwin->w_cursor.col);
*pincl = true;
}
} else
@@ -2483,8 +2489,8 @@ static int cls(void)
* Returns FAIL if the cursor was already at the end of the file.
* If eol is TRUE, last word stops at end of line (for operators).
*/
-int
-fwd_word (
+int
+fwd_word(
long count,
int bigword, /* "W", "E" or "B" */
int eol
@@ -2666,8 +2672,8 @@ finished:
*
* Returns FAIL if start of the file was reached.
*/
-int
-bckend_word (
+int
+bckend_word(
long count,
int bigword, /* TRUE for "B" */
int eol /* TRUE: stop at end of line. */
@@ -2756,8 +2762,8 @@ static void find_first_blank(pos_T *posp)
/*
* Skip count/2 sentences and count/2 separating white spaces.
*/
-static void
-findsent_forward (
+static void
+findsent_forward(
long count,
int at_start_sent /* cursor is at start of sentence */
)
@@ -2776,8 +2782,8 @@ findsent_forward (
* Find word under cursor, cursor at end.
* Used while an operator is pending, and in Visual mode.
*/
-int
-current_word (
+int
+current_word(
oparg_T *oap,
long count,
int include, /* TRUE: include word and white space */
@@ -3084,8 +3090,8 @@ extend:
* Find block under the cursor, cursor at end.
* "what" and "other" are two matching parenthesis/brace/etc.
*/
-int
-current_block (
+int
+current_block(
oparg_T *oap,
long count,
int include, /* TRUE == include white space */
@@ -3282,8 +3288,8 @@ static int in_html_tag(int end_tag)
/*
* Find tag block under the cursor, cursor at end.
*/
-int
-current_tagblock (
+int
+current_tagblock(
oparg_T *oap,
long count_arg,
int include /* TRUE == include white space */
@@ -3465,8 +3471,8 @@ theend:
return retval;
}
-int
-current_par (
+int
+current_par(
oparg_T *oap,
long count,
int include, /* TRUE == include white space */
@@ -3632,8 +3638,8 @@ extend:
* as a quote.
* Returns column number of "quotechar" or -1 when not found.
*/
-static int
-find_next_quote (
+static int
+find_next_quote(
char_u *line,
int col,
int quotechar,
@@ -3664,8 +3670,8 @@ find_next_quote (
* as a quote.
* Return the found column or zero.
*/
-static int
-find_prev_quote (
+static int
+find_prev_quote(
char_u *line,
int col_start,
int quotechar,
@@ -3694,8 +3700,8 @@ find_prev_quote (
* Find quote under the cursor, cursor at end.
* Returns TRUE if found, else FALSE.
*/
-int
-current_quote (
+int
+current_quote(
oparg_T *oap,
long count,
int include, /* TRUE == include quote char */
@@ -3920,8 +3926,8 @@ current_quote (
* Find next search match under cursor, cursor at end.
* Used while an operator is pending, and in Visual mode.
*/
-int
-current_search (
+int
+current_search(
long count,
int forward /* move forward or backwards */
)
@@ -4116,19 +4122,19 @@ int linewhite(linenr_T lnum)
* Find identifiers or defines in included files.
* If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase.
*/
-void
-find_pattern_in_path (
- char_u *ptr, /* pointer to search pattern */
- int dir, /* direction of expansion */
- size_t len, /* length of search pattern */
- int whole, /* match whole words only */
- int skip_comments, /* don't match inside comments */
- int type, /* Type of search; are we looking for a type?
- a macro? */
+void
+find_pattern_in_path(
+ char_u *ptr, // pointer to search pattern
+ int dir, // direction of expansion
+ size_t len, // length of search pattern
+ int whole, // match whole words only
+ int skip_comments, // don't match inside comments
+ int type, // Type of search; are we looking for a type?
+ // a macro?
long count,
- int action, /* What to do when we find it */
- linenr_T start_lnum, /* first line to start searching */
- linenr_T end_lnum /* last line for searching */
+ int action, // What to do when we find it
+ linenr_T start_lnum, // first line to start searching
+ linenr_T end_lnum // last line for searching
)
{
SearchedFile *files; /* Stack of included files */
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index ba2727f0d7..d7bdf97c48 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -2404,11 +2404,14 @@ jumpto_tag (
}
}
- /* If it was a CTRL-W CTRL-] command split window now. For ":tab tag"
- * open a new tab page. */
+ // If it was a CTRL-W CTRL-] command split window now. For ":tab tag"
+ // open a new tab page.
if (postponed_split || cmdmod.tab != 0) {
- (void)win_split(postponed_split > 0 ? postponed_split : 0,
- postponed_split_flags);
+ if (win_split(postponed_split > 0 ? postponed_split : 0,
+ postponed_split_flags) == FAIL) {
+ RedrawingDisabled--;
+ goto erret;
+ }
RESET_BINDING(curwin);
}
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index c29f0b3927..c2370de0f8 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -528,6 +528,13 @@ void terminal_send(Terminal *term, char *data, size_t size)
term->opts.write_cb(data, size, term->opts.data);
}
+void terminal_flush_output(Terminal *term)
+{
+ size_t len = vterm_output_read(term->vt, term->textbuf,
+ sizeof(term->textbuf));
+ terminal_send(term, term->textbuf, len);
+}
+
void terminal_send_key(Terminal *term, int c)
{
VTermModifier mod = VTERM_MOD_NONE;
@@ -545,9 +552,7 @@ void terminal_send_key(Terminal *term, int c)
vterm_keyboard_unichar(term->vt, (uint32_t)c, mod);
}
- size_t len = vterm_output_read(term->vt, term->textbuf,
- sizeof(term->textbuf));
- terminal_send(term, term->textbuf, (size_t)len);
+ terminal_flush_output(term);
}
void terminal_receive(Terminal *term, char *data, size_t len)
@@ -982,7 +987,7 @@ static bool send_mouse_event(Terminal *term, int c)
mouse_action(term, button, row, col, drag, 0);
size_t len = vterm_output_read(term->vt, term->textbuf,
- sizeof(term->textbuf));
+ sizeof(term->textbuf));
terminal_send(term, term->textbuf, (size_t)len);
return false;
}
@@ -1234,8 +1239,9 @@ static void refresh_screen(Terminal *term, buf_T *buf)
int change_start = row_to_linenr(term, term->invalid_start);
int change_end = change_start + changed;
- // Note: don't send nvim_buf_lines_event event for a :terminal buffer
- changed_lines(change_start, 0, change_end, added, false);
+ changed_lines(change_start, 0, change_end, added,
+ // Don't send nvim_buf_lines_event for :terminal buffer.
+ false);
term->invalid_start = INT_MAX;
term->invalid_end = -1;
}
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index c1ede08c31..a161f14bc8 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -88,6 +88,8 @@ NEW_TESTS ?= \
test_options.res \
test_profile.res \
test_put.res \
+ test_python2.res \
+ test_python3.res \
test_quickfix.res \
test_quotestar.res \
test_recover.res \
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index b4baf7a8d7..c4b4a43ad4 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -27,6 +27,7 @@ source test_popup.vim
source test_put.vim
source test_recover.vim
source test_regexp_utf8.vim
+source test_scroll_opt.vim
source test_source_utf8.vim
source test_sha256.vim
source test_statusline.vim
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index be68e9ff9d..8139f00f0e 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -64,6 +64,10 @@ func Test_highlight_completion()
hi Aardig ctermfg=green
call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt')
call assert_equal('"hi Aardig', getreg(':'))
+ call feedkeys(":hi default \<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"hi default Aardig', getreg(':'))
+ call feedkeys(":hi clear Aa\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"hi clear Aardig', getreg(':'))
call feedkeys(":hi li\<S-Tab>\<Home>\"\<CR>", 'xt')
call assert_equal('"hi link', getreg(':'))
call feedkeys(":hi d\<S-Tab>\<Home>\"\<CR>", 'xt')
diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim
index 7c6d38d7ec..0c2ec08af3 100644
--- a/src/nvim/testdir/test_fold.vim
+++ b/src/nvim/testdir/test_fold.vim
@@ -9,8 +9,8 @@ func! Test_address_fold()
call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
\ 'after fold 1', 'after fold 2', 'after fold 3'])
setl fen fdm=marker
- " The next ccommands should all copy the same part of the buffer,
- " regardless of the adressing type, since the part to be copied
+ " The next commands should all copy the same part of the buffer,
+ " regardless of the addressing type, since the part to be copied
" is folded away
:1y
call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
@@ -381,3 +381,56 @@ func Test_foldopen_exception()
endtry
call assert_match('E492:', a)
endfunc
+
+func Test_folddoopen_folddoclosed()
+ new
+ call setline(1, range(1, 9))
+ set foldmethod=manual
+ 1,3 fold
+ 6,8 fold
+
+ " Test without range.
+ folddoopen s/$/o/
+ folddoclosed s/$/c/
+ call assert_equal(['1c', '2c', '3c',
+ \ '4o', '5o',
+ \ '6c', '7c', '8c',
+ \ '9o'], getline(1, '$'))
+
+ " Test with range.
+ call setline(1, range(1, 9))
+ 1,8 folddoopen s/$/o/
+ 4,$ folddoclosed s/$/c/
+ call assert_equal(['1', '2', '3',
+ \ '4o', '5o',
+ \ '6c', '7c', '8c',
+ \ '9'], getline(1, '$'))
+
+ set foldmethod&
+ bw!
+endfunc
+
+func Test_fold_error()
+ new
+ call setline(1, [1, 2])
+
+ for fm in ['indent', 'expr', 'syntax', 'diff']
+ exe 'set foldmethod=' . fm
+ call assert_fails('norm zf', 'E350:')
+ call assert_fails('norm zd', 'E351:')
+ call assert_fails('norm zE', 'E352:')
+ endfor
+
+ set foldmethod=manual
+ call assert_fails('norm zd', 'E490:')
+ call assert_fails('norm zo', 'E490:')
+ call assert_fails('3fold', 'E16:')
+
+ set foldmethod=marker
+ set nomodifiable
+ call assert_fails('1,2fold', 'E21:')
+
+ set modifiable&
+ set foldmethod&
+ bw!
+endfunc
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 398e9ab331..8a82493ab6 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -1,5 +1,101 @@
" Tests for various functions.
+" Must be done first, since the alternate buffer must be unset.
+func Test_00_bufexists()
+ call assert_equal(0, bufexists('does_not_exist'))
+ call assert_equal(1, bufexists(bufnr('%')))
+ call assert_equal(0, bufexists(0))
+ new Xfoo
+ let bn = bufnr('%')
+ call assert_equal(1, bufexists(bn))
+ call assert_equal(1, bufexists('Xfoo'))
+ call assert_equal(1, bufexists(getcwd() . '/Xfoo'))
+ call assert_equal(1, bufexists(0))
+ bw
+ call assert_equal(0, bufexists(bn))
+ call assert_equal(0, bufexists('Xfoo'))
+endfunc
+
+func Test_empty()
+ call assert_equal(1, empty(''))
+ call assert_equal(0, empty('a'))
+
+ call assert_equal(1, empty(0))
+ call assert_equal(1, empty(-0))
+ call assert_equal(0, empty(1))
+ call assert_equal(0, empty(-1))
+
+ call assert_equal(1, empty(0.0))
+ call assert_equal(1, empty(-0.0))
+ call assert_equal(0, empty(1.0))
+ call assert_equal(0, empty(-1.0))
+ call assert_equal(0, empty(1.0/0.0))
+ call assert_equal(0, empty(0.0/0.0))
+
+ call assert_equal(1, empty([]))
+ call assert_equal(0, empty(['a']))
+
+ call assert_equal(1, empty({}))
+ call assert_equal(0, empty({'a':1}))
+
+ call assert_equal(1, empty(v:null))
+ " call assert_equal(1, empty(v:none))
+ call assert_equal(1, empty(v:false))
+ call assert_equal(0, empty(v:true))
+
+ if has('channel')
+ call assert_equal(1, empty(test_null_channel()))
+ endif
+ if has('job')
+ call assert_equal(1, empty(test_null_job()))
+ endif
+
+ call assert_equal(0, empty(function('Test_empty')))
+endfunc
+
+func Test_len()
+ call assert_equal(1, len(0))
+ call assert_equal(2, len(12))
+
+ call assert_equal(0, len(''))
+ call assert_equal(2, len('ab'))
+
+ call assert_equal(0, len([]))
+ call assert_equal(2, len([2, 1]))
+
+ call assert_equal(0, len({}))
+ call assert_equal(2, len({'a': 1, 'b': 2}))
+
+ " call assert_fails('call len(v:none)', 'E701:')
+ call assert_fails('call len({-> 0})', 'E701:')
+endfunc
+
+func Test_max()
+ call assert_equal(0, max([]))
+ call assert_equal(2, max([2]))
+ call assert_equal(2, max([1, 2]))
+ call assert_equal(2, max([1, 2, v:null]))
+
+ call assert_equal(0, max({}))
+ call assert_equal(2, max({'a':1, 'b':2}))
+
+ call assert_fails('call max(1)', 'E712:')
+ " call assert_fails('call max(v:none)', 'E712:')
+endfunc
+
+func Test_min()
+ call assert_equal(0, min([]))
+ call assert_equal(2, min([2]))
+ call assert_equal(1, min([1, 2]))
+ call assert_equal(0, min([1, 2, v:null]))
+
+ call assert_equal(0, min({}))
+ call assert_equal(1, min({'a':1, 'b':2}))
+
+ call assert_fails('call min(1)', 'E712:')
+ " call assert_fails('call min(v:none)', 'E712:')
+endfunc
+
func Test_str2nr()
call assert_equal(0, str2nr(''))
call assert_equal(1, str2nr('1'))
@@ -15,6 +111,77 @@ func Test_str2nr()
call assert_equal(123456789, str2nr('123456789'))
call assert_equal(-123456789, str2nr('-123456789'))
+
+ call assert_equal(5, str2nr('101', 2))
+ call assert_equal(5, str2nr('0b101', 2))
+ call assert_equal(5, str2nr('0B101', 2))
+ call assert_equal(-5, str2nr('-101', 2))
+ call assert_equal(-5, str2nr('-0b101', 2))
+ call assert_equal(-5, str2nr('-0B101', 2))
+
+ call assert_equal(65, str2nr('101', 8))
+ call assert_equal(65, str2nr('0101', 8))
+ call assert_equal(-65, str2nr('-101', 8))
+ call assert_equal(-65, str2nr('-0101', 8))
+
+ call assert_equal(11259375, str2nr('abcdef', 16))
+ call assert_equal(11259375, str2nr('ABCDEF', 16))
+ call assert_equal(-11259375, str2nr('-ABCDEF', 16))
+ call assert_equal(11259375, str2nr('0xabcdef', 16))
+ call assert_equal(11259375, str2nr('0Xabcdef', 16))
+ call assert_equal(11259375, str2nr('0XABCDEF', 16))
+ call assert_equal(-11259375, str2nr('-0xABCDEF', 16))
+
+ call assert_equal(0, str2nr('0x10'))
+ call assert_equal(0, str2nr('0b10'))
+ call assert_equal(1, str2nr('12', 2))
+ call assert_equal(1, str2nr('18', 8))
+ call assert_equal(1, str2nr('1g', 16))
+
+ call assert_equal(0, str2nr(v:null))
+ " call assert_equal(0, str2nr(v:none))
+
+ call assert_fails('call str2nr([])', 'E730:')
+ call assert_fails('call str2nr({->2})', 'E729:')
+ call assert_fails('call str2nr(1.2)', 'E806:')
+ call assert_fails('call str2nr(10, [])', 'E474:')
+endfunc
+
+func Test_strftime()
+ if !exists('*strftime')
+ return
+ endif
+ " Format of strftime() depends on system. We assume
+ " that basic formats tested here are available and
+ " identical on all systems which support strftime().
+ "
+ " The 2nd parameter of strftime() is a local time, so the output day
+ " of strftime() can be 17 or 18, depending on timezone.
+ call assert_match('^2017-01-1[78]$', strftime('%Y-%m-%d', 1484695512))
+ "
+ call assert_match('^\d\d\d\d-\(0\d\|1[012]\)-\([012]\d\|3[01]\) \([01]\d\|2[0-3]\):[0-5]\d:\([0-5]\d\|60\)$', strftime('%Y-%m-%d %H:%M:%S'))
+
+ call assert_fails('call strftime([])', 'E730:')
+ call assert_fails('call strftime("%Y", [])', 'E745:')
+endfunc
+
+func Test_simplify()
+ call assert_equal('', simplify(''))
+ call assert_equal('/', simplify('/'))
+ call assert_equal('/', simplify('/.'))
+ call assert_equal('/', simplify('/..'))
+ call assert_equal('/...', simplify('/...'))
+ call assert_equal('./dir/file', simplify('./dir/file'))
+ call assert_equal('./dir/file', simplify('.///dir//file'))
+ call assert_equal('./dir/file', simplify('./dir/./file'))
+ call assert_equal('./file', simplify('./dir/../file'))
+ call assert_equal('../dir/file', simplify('dir/../../dir/file'))
+ call assert_equal('./file', simplify('dir/.././file'))
+
+ call assert_fails('call simplify({->0})', 'E729:')
+ call assert_fails('call simplify([])', 'E730:')
+ call assert_fails('call simplify({})', 'E731:')
+ call assert_fails('call simplify(1.2)', 'E806:')
endfunc
func Test_setbufvar_options()
@@ -48,6 +215,19 @@ func Test_setbufvar_options()
bwipe!
endfunc
+func Test_strpart()
+ call assert_equal('de', strpart('abcdefg', 3, 2))
+ call assert_equal('ab', strpart('abcdefg', -2, 4))
+ call assert_equal('abcdefg', strpart('abcdefg', -2))
+ call assert_equal('fg', strpart('abcdefg', 5, 4))
+ call assert_equal('defg', strpart('abcdefg', 3))
+
+ if has('multi_byte')
+ call assert_equal('lép', strpart('éléphant', 2, 4))
+ call assert_equal('léphant', strpart('éléphant', 2))
+ endif
+endfunc
+
func Test_tolower()
call assert_equal("", tolower(""))
@@ -188,7 +368,7 @@ func Test_toupper()
call assert_equal("YÝŶŸẎỲỶỸ", toupper("YÝŶŸẎỲỶỸ"))
call assert_equal("ZŹŻŽƵẐẔ", toupper("ZŹŻŽƵẐẔ"))
- call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
+ call assert_equal("Ⱥ Ⱦ", toupper("ⱥ ⱦ"))
endfunc
" Tests for the mode() function
@@ -353,3 +533,236 @@ func Test_getbufvar()
set fileformats&
endfunc
+
+func Test_last_buffer_nr()
+ call assert_equal(bufnr('$'), last_buffer_nr())
+endfunc
+
+func Test_stridx()
+ call assert_equal(-1, stridx('', 'l'))
+ call assert_equal(0, stridx('', ''))
+ call assert_equal(0, stridx('hello', ''))
+ call assert_equal(-1, stridx('hello', 'L'))
+ call assert_equal(2, stridx('hello', 'l', -1))
+ call assert_equal(2, stridx('hello', 'l', 0))
+ call assert_equal(2, stridx('hello', 'l', 1))
+ call assert_equal(3, stridx('hello', 'l', 3))
+ call assert_equal(-1, stridx('hello', 'l', 4))
+ call assert_equal(-1, stridx('hello', 'l', 10))
+ call assert_equal(2, stridx('hello', 'll'))
+ call assert_equal(-1, stridx('hello', 'hello world'))
+endfunc
+
+func Test_strridx()
+ call assert_equal(-1, strridx('', 'l'))
+ call assert_equal(0, strridx('', ''))
+ call assert_equal(5, strridx('hello', ''))
+ call assert_equal(-1, strridx('hello', 'L'))
+ call assert_equal(3, strridx('hello', 'l'))
+ call assert_equal(3, strridx('hello', 'l', 10))
+ call assert_equal(3, strridx('hello', 'l', 3))
+ call assert_equal(2, strridx('hello', 'l', 2))
+ call assert_equal(-1, strridx('hello', 'l', 1))
+ call assert_equal(-1, strridx('hello', 'l', 0))
+ call assert_equal(-1, strridx('hello', 'l', -1))
+ call assert_equal(2, strridx('hello', 'll'))
+ call assert_equal(-1, strridx('hello', 'hello world'))
+endfunc
+
+func Test_matchend()
+ call assert_equal(7, matchend('testing', 'ing'))
+ call assert_equal(7, matchend('testing', 'ing', 2))
+ call assert_equal(-1, matchend('testing', 'ing', 5))
+endfunc
+
+func Test_nextnonblank_prevnonblank()
+ new
+insert
+This
+
+
+is
+
+a
+Test
+.
+ call assert_equal(0, nextnonblank(-1))
+ call assert_equal(0, nextnonblank(0))
+ call assert_equal(1, nextnonblank(1))
+ call assert_equal(4, nextnonblank(2))
+ call assert_equal(4, nextnonblank(3))
+ call assert_equal(4, nextnonblank(4))
+ call assert_equal(6, nextnonblank(5))
+ call assert_equal(6, nextnonblank(6))
+ call assert_equal(7, nextnonblank(7))
+ call assert_equal(0, nextnonblank(8))
+
+ call assert_equal(0, prevnonblank(-1))
+ call assert_equal(0, prevnonblank(0))
+ call assert_equal(1, prevnonblank(1))
+ call assert_equal(1, prevnonblank(2))
+ call assert_equal(1, prevnonblank(3))
+ call assert_equal(4, prevnonblank(4))
+ call assert_equal(4, prevnonblank(5))
+ call assert_equal(6, prevnonblank(6))
+ call assert_equal(7, prevnonblank(7))
+ call assert_equal(0, prevnonblank(8))
+ bw!
+endfunc
+
+func Test_byte2line_line2byte()
+ new
+ call setline(1, ['a', 'bc', 'd'])
+
+ set fileformat=unix
+ call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
+ \ map(range(-1, 8), 'byte2line(v:val)'))
+ call assert_equal([-1, -1, 1, 3, 6, 8, -1],
+ \ map(range(-1, 5), 'line2byte(v:val)'))
+
+ set fileformat=mac
+ call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
+ \ map(range(-1, 8), 'byte2line(v:val)'))
+ call assert_equal([-1, -1, 1, 3, 6, 8, -1],
+ \ map(range(-1, 5), 'line2byte(v:val)'))
+
+ set fileformat=dos
+ call assert_equal([-1, -1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, -1],
+ \ map(range(-1, 11), 'byte2line(v:val)'))
+ call assert_equal([-1, -1, 1, 4, 8, 11, -1],
+ \ map(range(-1, 5), 'line2byte(v:val)'))
+
+ set fileformat&
+ bw!
+endfunc
+
+func Test_count()
+ let l = ['a', 'a', 'A', 'b']
+ call assert_equal(2, count(l, 'a'))
+ call assert_equal(1, count(l, 'A'))
+ call assert_equal(1, count(l, 'b'))
+ call assert_equal(0, count(l, 'B'))
+
+ call assert_equal(2, count(l, 'a', 0))
+ call assert_equal(1, count(l, 'A', 0))
+ call assert_equal(1, count(l, 'b', 0))
+ call assert_equal(0, count(l, 'B', 0))
+
+ call assert_equal(3, count(l, 'a', 1))
+ call assert_equal(3, count(l, 'A', 1))
+ call assert_equal(1, count(l, 'b', 1))
+ call assert_equal(1, count(l, 'B', 1))
+ call assert_equal(0, count(l, 'c', 1))
+
+ call assert_equal(1, count(l, 'a', 0, 1))
+ call assert_equal(2, count(l, 'a', 1, 1))
+ call assert_fails('call count(l, "a", 0, 10)', 'E684:')
+
+ let d = {1: 'a', 2: 'a', 3: 'A', 4: 'b'}
+ call assert_equal(2, count(d, 'a'))
+ call assert_equal(1, count(d, 'A'))
+ call assert_equal(1, count(d, 'b'))
+ call assert_equal(0, count(d, 'B'))
+
+ call assert_equal(2, count(d, 'a', 0))
+ call assert_equal(1, count(d, 'A', 0))
+ call assert_equal(1, count(d, 'b', 0))
+ call assert_equal(0, count(d, 'B', 0))
+
+ call assert_equal(3, count(d, 'a', 1))
+ call assert_equal(3, count(d, 'A', 1))
+ call assert_equal(1, count(d, 'b', 1))
+ call assert_equal(1, count(d, 'B', 1))
+ call assert_equal(0, count(d, 'c', 1))
+
+ call assert_fails('call count(d, "a", 0, 1)', 'E474:')
+ call assert_fails('call count("a", "a")', 'E712:')
+endfunc
+
+func Test_changenr()
+ new Xchangenr
+ call assert_equal(0, changenr())
+ norm ifoo
+ call assert_equal(1, changenr())
+ set undolevels=10
+ norm Sbar
+ call assert_equal(2, changenr())
+ undo
+ call assert_equal(1, changenr())
+ redo
+ call assert_equal(2, changenr())
+ bw!
+ set undolevels&
+endfunc
+
+func Test_filewritable()
+ new Xfilewritable
+ write!
+ call assert_equal(1, filewritable('Xfilewritable'))
+
+ call assert_notequal(0, setfperm('Xfilewritable', 'r--r-----'))
+ call assert_equal(0, filewritable('Xfilewritable'))
+
+ call assert_notequal(0, setfperm('Xfilewritable', 'rw-r-----'))
+ call assert_equal(1, filewritable('Xfilewritable'))
+
+ call assert_equal(0, filewritable('doesnotexist'))
+
+ call delete('Xfilewritable')
+ bw!
+endfunc
+
+func Test_hostname()
+ let hostname_vim = hostname()
+ if has('unix')
+ let hostname_system = systemlist('uname -n')[0]
+ call assert_equal(hostname_vim, hostname_system)
+ endif
+endfunc
+
+func Test_getpid()
+ " getpid() always returns the same value within a vim instance.
+ call assert_equal(getpid(), getpid())
+ if has('unix')
+ call assert_equal(systemlist('echo $PPID')[0], string(getpid()))
+ endif
+endfunc
+
+func Test_hlexists()
+ call assert_equal(0, hlexists('does_not_exist'))
+ " call assert_equal(0, hlexists('Number'))
+ call assert_equal(0, highlight_exists('does_not_exist'))
+ " call assert_equal(0, highlight_exists('Number'))
+ syntax on
+ call assert_equal(0, hlexists('does_not_exist'))
+ " call assert_equal(1, hlexists('Number'))
+ call assert_equal(0, highlight_exists('does_not_exist'))
+ " call assert_equal(1, highlight_exists('Number'))
+ syntax off
+endfunc
+
+func Test_col()
+ new
+ call setline(1, 'abcdef')
+ norm gg4|mx6|mY2|
+ call assert_equal(2, col('.'))
+ call assert_equal(7, col('$'))
+ call assert_equal(4, col("'x"))
+ call assert_equal(6, col("'Y"))
+ call assert_equal(2, col([1, 2]))
+ call assert_equal(7, col([1, '$']))
+
+ call assert_equal(0, col(''))
+ call assert_equal(0, col('x'))
+ call assert_equal(0, col([2, '$']))
+ call assert_equal(0, col([1, 100]))
+ call assert_equal(0, col([1]))
+ bw!
+endfunc
+
+func Test_balloon_show()
+ if has('balloon_eval')
+ " This won't do anything but must not crash either.
+ call balloon_show('hi!')
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_listlbr_utf8.vim b/src/nvim/testdir/test_listlbr_utf8.vim
index 56a4cc9b31..b648a3361b 100644
--- a/src/nvim/testdir/test_listlbr_utf8.vim
+++ b/src/nvim/testdir/test_listlbr_utf8.vim
@@ -194,6 +194,21 @@ func Test_multibyte_sign_and_colorcolumn()
call s:close_windows()
endfunc
+func Test_colorcolumn_priority()
+ call s:test_windows('setl cc=4 cuc hls')
+ call setline(1, ["xxyy", ""])
+ norm! gg
+ exe "normal! /xxyy\<CR>"
+ norm! G
+ redraw!
+ let line_attr = s:screen_attr(1, [1, &cc])
+ " Search wins over CursorColumn
+ call assert_equal(line_attr[1], line_attr[0])
+ " Search wins over Colorcolumn
+ call assert_equal(line_attr[2], line_attr[3])
+ call s:close_windows('setl hls&vim')
+endfunc
+
func Test_illegal_byte_and_breakat()
call s:test_windows("setl sbr= brk+=<")
vert resize 18
diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim
index f5e4c4b90c..0a198763bb 100644
--- a/src/nvim/testdir/test_mapping.vim
+++ b/src/nvim/testdir/test_mapping.vim
@@ -160,3 +160,30 @@ func Test_map_meta_quotes()
set nomodified
iunmap <M-">
endfunc
+
+func Test_map_timeout()
+ nnoremap aaaa :let got_aaaa = 1<CR>
+ nnoremap bb :let got_bb = 1<CR>
+ nmap b aaa
+ new
+ func ExitInsert(timer)
+ let g:line = getline(1)
+ call feedkeys("\<Esc>", "t")
+ endfunc
+ set timeout timeoutlen=200
+ call timer_start(300, 'ExitInsert')
+ " After the 'b' Vim waits for another character to see if it matches 'bb'.
+ " When it times out it is expanded to "aaa", but there is no wait for
+ " "aaaa". Can't check that reliably though.
+ call feedkeys("b", "xt!")
+ call assert_equal("aa", g:line)
+ call assert_false(exists('got_aaa'))
+ call assert_false(exists('got_bb'))
+
+ bwipe!
+ nunmap aaaa
+ nunmap bb
+ nunmap b
+ set timeoutlen&
+ delfunc ExitInsert
+endfunc
diff --git a/src/nvim/testdir/test_marks.vim b/src/nvim/testdir/test_marks.vim
index d00b1ddc88..18a0c71aab 100644
--- a/src/nvim/testdir/test_marks.vim
+++ b/src/nvim/testdir/test_marks.vim
@@ -24,3 +24,47 @@ function! Test_Incr_Marks()
call assert_equal("XXX 123 123", getline(3))
enew!
endfunction
+
+func Test_setpos()
+ new one
+ let onebuf = bufnr('%')
+ let onewin = win_getid()
+ call setline(1, ['aaa', 'bbb', 'ccc'])
+ new two
+ let twobuf = bufnr('%')
+ let twowin = win_getid()
+ call setline(1, ['aaa', 'bbb', 'ccc'])
+
+ " for the cursor the buffer number is ignored
+ call setpos(".", [0, 2, 1, 0])
+ call assert_equal([0, 2, 1, 0], getpos("."))
+ call setpos(".", [onebuf, 3, 3, 0])
+ call assert_equal([0, 3, 3, 0], getpos("."))
+
+ call setpos("''", [0, 1, 3, 0])
+ call assert_equal([0, 1, 3, 0], getpos("''"))
+ call setpos("''", [onebuf, 2, 2, 0])
+ call assert_equal([0, 2, 2, 0], getpos("''"))
+
+ " buffer-local marks
+ for mark in ["'a", "'\"", "'[", "']", "'<", "'>"]
+ call win_gotoid(twowin)
+ call setpos(mark, [0, 2, 1, 0])
+ call assert_equal([0, 2, 1, 0], getpos(mark), "for mark " . mark)
+ call setpos(mark, [onebuf, 1, 3, 0])
+ call win_gotoid(onewin)
+ call assert_equal([0, 1, 3, 0], getpos(mark), "for mark " . mark)
+ endfor
+
+ " global marks
+ call win_gotoid(twowin)
+ call setpos("'N", [0, 2, 1, 0])
+ call assert_equal([twobuf, 2, 1, 0], getpos("'N"))
+ call setpos("'N", [onebuf, 1, 3, 0])
+ call assert_equal([onebuf, 1, 3, 0], getpos("'N"))
+
+ call win_gotoid(onewin)
+ bwipe!
+ call win_gotoid(twowin)
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
index 1d15c7f83d..27ac084ef0 100644
--- a/src/nvim/testdir/test_normal.vim
+++ b/src/nvim/testdir/test_normal.vim
@@ -2314,28 +2314,36 @@ func! Test_normal53_digraph()
bw!
endfunc
-func! Test_normal54_Ctrl_bsl()
- new
- call setline(1, 'abcdefghijklmn')
- exe "norm! df\<c-\>\<c-n>"
- call assert_equal(['abcdefghijklmn'], getline(1,'$'))
- exe "norm! df\<c-\>\<c-g>"
- call assert_equal(['abcdefghijklmn'], getline(1,'$'))
- exe "norm! df\<c-\>m"
- call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+func Test_normal54_Ctrl_bsl()
+ new
+ call setline(1, 'abcdefghijklmn')
+ exe "norm! df\<c-\>\<c-n>"
+ call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+ exe "norm! df\<c-\>\<c-g>"
+ call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+ exe "norm! df\<c-\>m"
+ call assert_equal(['abcdefghijklmn'], getline(1,'$'))
if !has("multi_byte")
return
endif
- call setline(2, 'abcdefghijklmnāf')
- norm! 2gg0
- exe "norm! df\<Char-0x101>"
- call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
- norm! 1gg0
- exe "norm! df\<esc>"
- call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
+ call setline(2, 'abcdefghijklmnāf')
+ norm! 2gg0
+ exe "norm! df\<Char-0x101>"
+ call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
+ norm! 1gg0
+ exe "norm! df\<esc>"
+ call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
- " clean up
- bw!
+ " clean up
+ bw!
+endfunc
+
+func Test_normal_large_count()
+ " This may fail with 32bit long, how do we detect that?
+ new
+ normal o
+ normal 6666666666dL
+ bwipe!
endfunc
" Test for the gr (virtual replace) command
@@ -2379,3 +2387,15 @@ func Test_changelist()
%bwipe!
let &ul = save_ul
endfunc
+
+func Test_delete_until_paragraph()
+ if !has('multi_byte')
+ return
+ endif
+ new
+ normal grádv}
+ call assert_equal('á', getline(1))
+ normal grád}
+ call assert_equal('', getline(1))
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index eb42e35bd3..5ae8528ee9 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -22,6 +22,13 @@ function! Test_whichwrap()
set whichwrap&
endfunction
+function! Test_isfname()
+ " This used to cause Vim to access uninitialized memory.
+ set isfname=
+ call assert_equal("~X", expand("~X"))
+ set isfname&
+endfunction
+
function! Test_options()
let caught = 'ok'
try
diff --git a/src/nvim/testdir/test_python2.vim b/src/nvim/testdir/test_python2.vim
new file mode 100644
index 0000000000..fb98c1eda7
--- /dev/null
+++ b/src/nvim/testdir/test_python2.vim
@@ -0,0 +1,24 @@
+" Test for python 2 commands.
+" TODO: move tests from test87.in here.
+
+if !has('python')
+ finish
+endif
+
+func Test_pydo()
+ " Check deleting lines does not trigger ml_get error.
+ py import vim
+ new
+ call setline(1, ['one', 'two', 'three'])
+ pydo vim.command("%d_")
+ bwipe!
+
+ " Check switching to another buffer does not trigger ml_get error.
+ new
+ let wincount = winnr('$')
+ call setline(1, ['one', 'two', 'three'])
+ pydo vim.command("new")
+ call assert_equal(wincount + 1, winnr('$'))
+ bwipe!
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_python3.vim b/src/nvim/testdir/test_python3.vim
new file mode 100644
index 0000000000..bb241dacb1
--- /dev/null
+++ b/src/nvim/testdir/test_python3.vim
@@ -0,0 +1,24 @@
+" Test for python 2 commands.
+" TODO: move tests from test88.in here.
+
+if !has('python3')
+ finish
+endif
+
+func Test_py3do()
+ " Check deleting lines does not trigger an ml_get error.
+ py3 import vim
+ new
+ call setline(1, ['one', 'two', 'three'])
+ py3do vim.command("%d_")
+ bwipe!
+
+ " Check switching to another buffer does not trigger an ml_get error.
+ new
+ let wincount = winnr('$')
+ call setline(1, ['one', 'two', 'three'])
+ py3do vim.command("new")
+ call assert_equal(wincount + 1, winnr('$'))
+ bwipe!
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_quotestar.vim b/src/nvim/testdir/test_quotestar.vim
index d0dd04f91d..37e3a10ed1 100644
--- a/src/nvim/testdir/test_quotestar.vim
+++ b/src/nvim/testdir/test_quotestar.vim
@@ -39,6 +39,15 @@ func Do_test_quotestar_for_x11()
if cmd == ''
return 'GetVimCommand() failed'
endif
+ try
+ call remote_send('xxx', '')
+ catch
+ if v:exception =~ 'E240:'
+ " No connection to the X server, give up.
+ return
+ endif
+ " ignore other errors
+ endtry
let name = 'XVIMCLIPBOARD'
let cmd .= ' --servername ' . name
@@ -109,8 +118,12 @@ func Test_quotestar()
if has('macunix')
let skipped = Do_test_quotestar_for_macunix()
- elseif !empty("$DISPLAY")
- let skipped = Do_test_quotestar_for_x11()
+ elseif has('x11')
+ if empty($DISPLAY)
+ let skipped = "Test can only run when $DISPLAY is set."
+ else
+ let skipped = Do_test_quotestar_for_x11()
+ endif
else
let skipped = "Test is not implemented yet for this platform."
endif
diff --git a/src/nvim/testdir/test_regexp_utf8.vim b/src/nvim/testdir/test_regexp_utf8.vim
index a2f4286d4f..97638e9aac 100644
--- a/src/nvim/testdir/test_regexp_utf8.vim
+++ b/src/nvim/testdir/test_regexp_utf8.vim
@@ -35,12 +35,21 @@ func s:classes_test()
set isprint=@,161-255
call assert_equal('Motörhead', matchstr('Motörhead', '[[:print:]]\+'))
+ let alnumchars = ''
let alphachars = ''
+ let backspacechar = ''
+ let blankchars = ''
+ let cntrlchars = ''
+ let digitchars = ''
+ let escapechar = ''
+ let graphchars = ''
let lowerchars = ''
- let upperchars = ''
- let alnumchars = ''
let printchars = ''
let punctchars = ''
+ let returnchar = ''
+ let spacechars = ''
+ let tabchar = ''
+ let upperchars = ''
let xdigitchars = ''
let i = 1
while i <= 255
@@ -48,21 +57,48 @@ func s:classes_test()
if c =~ '[[:alpha:]]'
let alphachars .= c
endif
- if c =~ '[[:lower:]]'
- let lowerchars .= c
- endif
- if c =~ '[[:upper:]]'
- let upperchars .= c
- endif
if c =~ '[[:alnum:]]'
let alnumchars .= c
endif
+ if c =~ '[[:backspace:]]'
+ let backspacechar .= c
+ endif
+ if c =~ '[[:blank:]]'
+ let blankchars .= c
+ endif
+ if c =~ '[[:cntrl:]]'
+ let cntrlchars .= c
+ endif
+ if c =~ '[[:digit:]]'
+ let digitchars .= c
+ endif
+ if c =~ '[[:escape:]]'
+ let escapechar .= c
+ endif
+ if c =~ '[[:graph:]]'
+ let graphchars .= c
+ endif
+ if c =~ '[[:lower:]]'
+ let lowerchars .= c
+ endif
if c =~ '[[:print:]]'
let printchars .= c
endif
if c =~ '[[:punct:]]'
let punctchars .= c
endif
+ if c =~ '[[:return:]]'
+ let returnchar .= c
+ endif
+ if c =~ '[[:space:]]'
+ let spacechars .= c
+ endif
+ if c =~ '[[:tab:]]'
+ let tabchar .= c
+ endif
+ if c =~ '[[:upper:]]'
+ let upperchars .= c
+ endif
if c =~ '[[:xdigit:]]'
let xdigitchars .= c
endif
@@ -70,11 +106,20 @@ func s:classes_test()
endwhile
call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alphachars)
- call assert_equal('abcdefghijklmnopqrstuvwxyzµßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', lowerchars)
- call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ', upperchars)
call assert_equal('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alnumchars)
+ call assert_equal("\b", backspacechar)
+ call assert_equal("\t ", blankchars)
+ call assert_equal("\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0b\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\e\x1c\x1d\x1e\x1f\x7f", cntrlchars)
+ call assert_equal("0123456789", digitchars)
+ call assert_equal("\<Esc>", escapechar)
+ call assert_equal('!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~', graphchars)
+ call assert_equal('abcdefghijklmnopqrstuvwxyzµßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', lowerchars)
call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ', printchars)
call assert_equal('!"#$%&''()*+,-./:;<=>?@[\]^_`{|}~', punctchars)
+ call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ', upperchars)
+ call assert_equal("\r", returnchar)
+ call assert_equal("\t\n\x0b\f\r ", spacechars)
+ call assert_equal("\t", tabchar)
call assert_equal('0123456789ABCDEFabcdef', xdigitchars)
endfunc
@@ -121,3 +166,20 @@ func Test_eow_with_optional()
call assert_equal(expected, actual)
endfor
endfunc
+
+func Test_reversed_range()
+ for re in range(0, 2)
+ exe 'set re=' . re
+ call assert_fails('call match("abc def", "[c-a]")', 'E944:')
+ endfor
+ set re=0
+endfunc
+
+func Test_large_class()
+ set re=1
+ call assert_fails('call match("abc def", "[\u3000-\u4000]")', 'E945:')
+ set re=2
+ call assert_equal(0, 'abc def' =~# '[\u3000-\u4000]')
+ call assert_equal(1, "\u3042" =~# '[\u3000-\u4000]')
+ set re=0
+endfunc
diff --git a/src/nvim/testdir/test_scroll_opt.vim b/src/nvim/testdir/test_scroll_opt.vim
new file mode 100644
index 0000000000..77920eb8b0
--- /dev/null
+++ b/src/nvim/testdir/test_scroll_opt.vim
@@ -0,0 +1,36 @@
+" Test for reset 'scroll'
+"
+
+func Test_reset_scroll()
+ let scr = &l:scroll
+
+ setlocal scroll=1
+ setlocal scroll&
+ call assert_equal(scr, &l:scroll)
+
+ setlocal scroll=1
+ setlocal scroll=0
+ call assert_equal(scr, &l:scroll)
+
+ try
+ execute 'setlocal scroll=' . (winheight(0) + 1)
+ " not reached
+ call assert_false(1)
+ catch
+ call assert_exception('E49:')
+ endtry
+
+ split
+
+ let scr = &l:scroll
+
+ setlocal scroll=1
+ setlocal scroll&
+ call assert_equal(scr, &l:scroll)
+
+ setlocal scroll=1
+ setlocal scroll=0
+ call assert_equal(scr, &l:scroll)
+
+ quit!
+endfunc
diff --git a/src/nvim/testdir/test_smartindent.vim b/src/nvim/testdir/test_smartindent.vim
index d00eac9798..9e93a55eb0 100644
--- a/src/nvim/testdir/test_smartindent.vim
+++ b/src/nvim/testdir/test_smartindent.vim
@@ -1,3 +1,4 @@
+" Tests for smartindent
" Tests for not doing smart indenting when it isn't set.
function! Test_nosmartindent()
@@ -12,3 +13,29 @@ function! Test_nosmartindent()
call assert_equal(" #test", getline(1))
enew! | close
endfunction
+
+function MyIndent()
+endfunction
+
+" When 'indentexpr' is set, setting 'si' has no effect.
+function Test_smartindent_has_no_effect()
+ new
+ exe "normal! i\<Tab>one\<Esc>"
+ set noautoindent
+ set smartindent
+ set indentexpr=
+ exe "normal! Gotwo\<Esc>"
+ call assert_equal("\ttwo", getline("$"))
+
+ set indentexpr=MyIndent
+ exe "normal! Gothree\<Esc>"
+ call assert_equal("three", getline("$"))
+
+ delfunction! MyIndent
+ set autoindent&
+ set smartindent&
+ set indentexpr&
+ bwipe!
+endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
index 11e26d03aa..495c561991 100644
--- a/src/nvim/testdir/test_startup.vim
+++ b/src/nvim/testdir/test_startup.vim
@@ -240,3 +240,14 @@ func Test_progpath()
" Only expect "vim" to appear in v:progname.
call assert_match('vim\c', v:progname)
endfunc
+
+func Test_silent_ex_mode()
+ if !has('unix') || has('gui_running')
+ " can't get output of Vim.
+ return
+ endif
+
+ " This caused an ml_get error.
+ let out = system(GetVimCommand() . '-u NONE -es -c''set verbose=1|h|exe "%norm\<c-y>\<c-d>"'' -c cq')
+ call assert_notmatch('E315:', out)
+endfunc
diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim
index 8465fe7d45..ebdfc250aa 100644
--- a/src/nvim/testdir/test_syntax.vim
+++ b/src/nvim/testdir/test_syntax.vim
@@ -301,11 +301,19 @@ func Test_syntax_arg_skipped()
syn clear
endfunc
-
-func Test_invalid_arg()
+
+func Test_syntax_invalid_arg()
call assert_fails('syntax case asdf', 'E390:')
- call assert_fails('syntax conceal asdf', 'E390:')
+ if has('conceal')
+ call assert_fails('syntax conceal asdf', 'E390:')
+ endif
call assert_fails('syntax spell asdf', 'E390:')
+ call assert_fails('syntax clear @ABCD', 'E391:')
+ call assert_fails('syntax include @Xxx', 'E397:')
+ call assert_fails('syntax region X start="{"', 'E399:')
+ call assert_fails('syntax sync x', 'E404:')
+ call assert_fails('syntax keyword Abc a[', 'E789:')
+ call assert_fails('syntax keyword Abc a[bc]d', 'E890:')
endfunc
func Test_syn_sync()
@@ -346,6 +354,50 @@ func Test_invalid_name()
hi clear @Wrong
endfunc
+func Test_ownsyntax()
+ new Xfoo
+ call setline(1, '#define FOO')
+ syntax on
+ set filetype=c
+ ownsyntax perl
+ call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name'))
+ call assert_equal('c', b:current_syntax)
+ call assert_equal('perl', w:current_syntax)
+
+ " A new split window should have the original syntax.
+ split
+ call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name'))
+ call assert_equal('c', b:current_syntax)
+ call assert_equal(0, exists('w:current_syntax'))
+
+ wincmd x
+ call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name"))
+
+ syntax off
+ set filetype&
+ %bw!
+endfunc
+
+func Test_ownsyntax_completion()
+ call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"ownsyntax java javacc javascript', @:)
+endfunc
+
+func Test_highlight_invalid_arg()
+ if has('gui_running')
+ call assert_fails('hi XXX guifg=xxx', 'E254:')
+ endif
+ call assert_fails('hi DoesNotExist', 'E411:')
+ call assert_fails('hi link', 'E412:')
+ call assert_fails('hi link a', 'E412:')
+ call assert_fails('hi link a b c', 'E413:')
+ call assert_fails('hi XXX =', 'E415:')
+ call assert_fails('hi XXX cterm', 'E416:')
+ call assert_fails('hi XXX cterm=', 'E417:')
+ call assert_fails('hi XXX cterm=DoesNotExist', 'E418:')
+ call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:')
+ call assert_fails('hi XXX xxx=White', 'E423:')
+endfunc
func Test_conceal()
if !has('conceal')
@@ -382,3 +434,4 @@ func Test_conceal()
set conceallevel&
bw!
endfunc
+
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 65957626cb..25c39587f4 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -405,6 +405,10 @@ static void sigwinch_cb(SignalWatcher *watcher, int signum, void *data)
{
got_winch = true;
UI *ui = data;
+ if (tui_is_stopped(ui)) {
+ return;
+ }
+
update_size(ui);
ui_schedule_refresh();
}
@@ -845,7 +849,7 @@ CursorShape tui_cursor_decode_shape(const char *shape_str)
static cursorentry_T decode_cursor_entry(Dictionary args)
{
- cursorentry_T r;
+ cursorentry_T r = shape_table[0];
for (size_t i = 0; i < args.size; i++) {
char *key = args.items[i].key.data;
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 42366fdb76..21dd6ec0dd 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -535,14 +535,18 @@ Array ui_array(void)
{
Array all_uis = ARRAY_DICT_INIT;
for (size_t i = 0; i < ui_count; i++) {
- Dictionary dic = ARRAY_DICT_INIT;
- PUT(dic, "width", INTEGER_OBJ(uis[i]->width));
- PUT(dic, "height", INTEGER_OBJ(uis[i]->height));
- PUT(dic, "rgb", BOOLEAN_OBJ(uis[i]->rgb));
+ UI *ui = uis[i];
+ Dictionary info = ARRAY_DICT_INIT;
+ PUT(info, "width", INTEGER_OBJ(ui->width));
+ PUT(info, "height", INTEGER_OBJ(ui->height));
+ PUT(info, "rgb", BOOLEAN_OBJ(ui->rgb));
for (UIExtension j = 0; j < kUIExtCount; j++) {
- PUT(dic, ui_ext_names[j], BOOLEAN_OBJ(uis[i]->ui_ext[j]));
+ PUT(info, ui_ext_names[j], BOOLEAN_OBJ(ui->ui_ext[j]));
+ }
+ if (ui->inspect) {
+ ui->inspect(ui, &info);
}
- ADD(all_uis, DICTIONARY_OBJ(dic));
+ ADD(all_uis, DICTIONARY_OBJ(info));
}
return all_uis;
}
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index 48896a6a3f..6b04e9c67a 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -36,6 +36,7 @@ struct ui_t {
#endif
void (*event)(UI *ui, char *name, Array args, bool *args_consumed);
void (*stop)(UI *ui);
+ void (*inspect)(UI *ui, Dictionary *info);
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index a8bbeea035..56db124a46 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -163,3 +163,28 @@ static void ui_bridge_suspend_event(void **argv)
UI *ui = UI(argv[0]);
ui->suspend(ui);
}
+
+static void ui_bridge_option_set(UI *ui, String name, Object value)
+{
+ String copy_name = copy_string(name);
+ Object *copy_value = xmalloc(sizeof(Object));
+ *copy_value = copy_object(value);
+ UI_BRIDGE_CALL(ui, option_set, 4, ui, copy_name.data,
+ INT2PTR(copy_name.size), copy_value);
+ // TODO(bfredl): when/if TUI/bridge teardown is refactored to use events, the
+ // commit that introduced this special case can be reverted.
+ // For now this is needed for nvim_list_uis().
+ if (strequal(name.data, "termguicolors")) {
+ ui->rgb = value.data.boolean;
+ }
+}
+static void ui_bridge_option_set_event(void **argv)
+{
+ UI *ui = UI(argv[0]);
+ String name = (String){ .data = argv[1], .size = (size_t)argv[2] };
+ Object value = *(Object *)argv[3];
+ ui->option_set(ui, name, value);
+ api_free_string(name);
+ api_free_object(value);
+ xfree(argv[3]);
+}
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 44bcefb332..8b290edd1f 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -1698,9 +1698,9 @@ bool u_undo_and_forget(int count)
count = 1;
}
undo_undoes = true;
- // don't send a nvim_buf_lines_event for this undo is part of 'inccommand'
- // playing with buffer contents
- u_doit(count, true, false);
+ u_doit(count, true,
+ // Don't send nvim_buf_lines_event for u_undo_and_forget().
+ false);
if (curbuf->b_u_curhead == NULL) {
// nothing was undone.
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 17f89a25d2..be160e678e 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -145,7 +145,7 @@ static const int included_patches[] = {
// 1497,
// 1496,
// 1495,
- // 1494,
+ 1494,
1493,
// 1492,
// 1491,
@@ -167,7 +167,7 @@ static const int included_patches[] = {
1475,
// 1474,
// 1473,
- // 1472,
+ 1472,
// 1471,
// 1470,
// 1469,
@@ -328,7 +328,7 @@ static const int included_patches[] = {
// 1314,
// 1313,
// 1312,
- // 1311,
+ 1311,
// 1310,
// 1309,
// 1308,
@@ -405,9 +405,9 @@ static const int included_patches[] = {
// 1237,
// 1236,
// 1235,
- // 1234,
+ 1234,
// 1233,
- // 1232,
+ 1232,
// 1231,
1230,
1229,
@@ -442,13 +442,13 @@ static const int included_patches[] = {
1200,
// 1199,
// 1198,
- // 1197,
+ 1197,
// 1196,
// 1195,
// 1194,
// 1193,
// 1192,
- // 1191,
+ 1191,
// 1190,
1189,
1188,
@@ -458,8 +458,8 @@ static const int included_patches[] = {
// 1184,
// 1183,
// 1182,
- // 1181,
- // 1180,
+ 1181,
+ 1180,
// 1179,
// 1178,
// 1177,
@@ -489,7 +489,7 @@ static const int included_patches[] = {
// 1153,
// 1152,
// 1151,
- // 1150,
+ 1150,
// 1149,
// 1148,
// 1147,
@@ -498,7 +498,7 @@ static const int included_patches[] = {
// 1144,
// 1143,
// 1142,
- // 1141,
+ 1141,
// 1140,
// 1139,
// 1138,
@@ -518,7 +518,7 @@ static const int included_patches[] = {
// 1124,
// 1123,
// 1122,
- // 1121,
+ 1121,
// 1120,
// 1119,
// 1118,
@@ -714,7 +714,7 @@ static const int included_patches[] = {
// 928,
// 927,
// 926,
- // 925,
+ 925,
// 924,
// 923,
// 922,
@@ -758,7 +758,7 @@ static const int included_patches[] = {
// 884,
// 883,
// 882,
- // 881,
+ 881,
// 880,
// 879,
// 878,
@@ -1077,11 +1077,11 @@ static const int included_patches[] = {
565,
564,
// 563,
- // 562,
+ 562,
561,
// 560,
- // 559,
- // 558,
+ 559,
+ 558,
// 557,
// 556,
555,
@@ -1120,30 +1120,30 @@ static const int included_patches[] = {
// 522,
// 521,
// 520,
- // 519,
+ 519,
518,
517,
- // 516,
- // 515,
+ 516,
+ 515,
// 514,
513,
// 512,
- // 511,
+ 511,
// 510,
// 509,
// 508,
- // 507,
+ 507,
// 506,
- // 505,
+ 505,
// 504,
- // 503,
+ 503,
502,
// 501,
500,
499,
498,
- // 497,
- // 496,
+ 497,
+ 496,
495,
// 494,
// 493,
@@ -1175,36 +1175,36 @@ static const int included_patches[] = {
// 467,
// 466,
465,
- // 464,
- // 463,
+ 464,
+ 463,
// 462,
461,
- // 460,
+ 460,
459,
458,
457,
- // 456,
+ 456,
// 455,
- // 454,
+ 454,
453,
// 452,
// 451,
- // 450,
+ 450,
// 449,
448,
- // 447,
+ 447,
446,
// 445,
444,
443,
442,
- // 441,
+ 441,
440,
439,
- // 438,
+ 438,
437,
// 436,
- // 435,
+ 435,
434,
433,
// 432,
@@ -1220,23 +1220,23 @@ static const int included_patches[] = {
// 422,
421,
420,
- // 419,
+ 419,
// 418,
417,
- // 416,
- // 415,
+ 416,
+ 415,
// 414,
// 413,
// 412,
// 411,
// 410,
- // 409,
+ 409,
408,
407,
406,
405,
404,
- // 403,
+ 403,
402,
// 401,
400,
@@ -1255,20 +1255,20 @@ static const int included_patches[] = {
387,
// 386,
385,
- // 384,
- // 383,
- // 382,
+ 384,
+ 383,
+ 382,
381,
380,
379,
378,
377,
376,
- // 375,
+ 375,
374,
// 373,
// 372,
- // 371,
+ 371,
// 370,
// 369,
// 368,
@@ -1277,27 +1277,27 @@ static const int included_patches[] = {
// 365,
364,
// 363,
- // 362,
+ 362,
// 361,
360,
359,
358,
357,
- // 356,
+ 356,
// 355,
- // 354,
+ 354,
353,
352,
351,
// 350,
// 349,
- // 348,
+ 348,
347,
// 346,
345,
344,
343,
- // 342,
+ 342,
341,
// 340,
339,
@@ -1307,10 +1307,10 @@ static const int included_patches[] = {
335,
334,
333,
- // 332,
+ 332,
331,
330,
- // 329,
+ 329,
328,
327,
326,
@@ -1318,16 +1318,16 @@ static const int included_patches[] = {
324,
323,
322,
- // 321,
+ 321,
320,
319,
- // 318,
- // 317,
+ 318,
+ 317,
316,
315,
314,
- // 313,
- // 312,
+ 313,
+ 312,
311,
310,
309,
@@ -1335,7 +1335,7 @@ static const int included_patches[] = {
307,
306,
305,
- // 304,
+ 304,
// 303,
302,
301,
@@ -1378,7 +1378,7 @@ static const int included_patches[] = {
// 264,
263,
262,
- // 261,
+ 261,
260,
259,
258,
diff --git a/test/functional/api/buffer_updates_spec.lua b/test/functional/api/buffer_updates_spec.lua
index 00409c1528..6da790b871 100644
--- a/test/functional/api/buffer_updates_spec.lua
+++ b/test/functional/api/buffer_updates_spec.lua
@@ -3,6 +3,7 @@ local eq, ok = helpers.eq, helpers.ok
local buffer, command, eval, nvim, next_msg = helpers.buffer,
helpers.command, helpers.eval, helpers.nvim, helpers.next_msg
local expect_err = helpers.expect_err
+local write_file = helpers.write_file
local origlines = {"original line 1",
"original line 2",
@@ -18,7 +19,7 @@ end
local function sendkeys(keys)
nvim('input', keys)
- -- give neovim some time to process msgpack requests before possibly sending
+ -- give nvim some time to process msgpack requests before possibly sending
-- more key presses - otherwise they all pile up in the queue and get
-- processed at once
local ntime = os.clock() + 0.1
@@ -27,14 +28,14 @@ end
local function open(activate, lines)
local filename = helpers.tmpname()
- helpers.write_file(filename, table.concat(lines, "\n").."\n", true)
+ write_file(filename, table.concat(lines, "\n").."\n", true)
command('edit ' .. filename)
local b = nvim('get_current_buf')
-- what is the value of b:changedtick?
local tick = eval('b:changedtick')
- -- turn on live updates, ensure that the nvim_buf_lines_event messages
- -- arrive as expectected
+ -- Enable buffer events, ensure that the nvim_buf_lines_event messages
+ -- arrive as expected
if activate then
local firstline = 0
ok(buffer('attach', b, true, {}))
@@ -91,8 +92,8 @@ local function reopenwithfolds(b)
return tick
end
-describe('buffer events', function()
- it('when you add line to a buffer', function()
+describe('API: buffer events:', function()
+ it('when lines are added', function()
local b, tick = editoriginal(true)
-- add a new line at the start of the buffer
@@ -156,7 +157,7 @@ describe('buffer events', function()
expectn('nvim_buf_lines_event', {b, tick, 29, 29, firstfour, false})
-- create a new empty buffer and wipe out the old one ... this will
- -- turn off live updates
+ -- turn off buffer events
command('enew!')
expectn('nvim_buf_detach_event', {b})
@@ -170,7 +171,7 @@ describe('buffer events', function()
tick = tick + 1
expectn('nvim_buf_lines_event', {b2, tick, 0, 0, {'new line 1'}, false})
- -- turn off live updates manually
+ -- turn off buffer events manually
buffer('detach', b2)
expectn('nvim_buf_detach_event', {b2})
@@ -192,7 +193,7 @@ describe('buffer events', function()
expectn('nvim_buf_lines_event', {b3, tick, 0, 0, {"New First Line"}, false})
end)
- it('knows when you remove lines from a buffer', function()
+ it('when lines are removed', function()
local b, tick = editoriginal(true)
-- remove one line from start of file
@@ -231,7 +232,7 @@ describe('buffer events', function()
expectn('nvim_buf_lines_event', {b, tick, 4, 6, {}, false})
end)
- it('knows when you modify lines of text', function()
+ it('when text is changed', function()
local b, tick = editoriginal(true)
-- some normal text editing
@@ -286,7 +287,7 @@ describe('buffer events', function()
expectn('nvim_buf_lines_event', {bnew, tick + 7, 1, 2, {'world'}, false})
end)
- it('knows when you replace lines', function()
+ it('when lines are replaced', function()
local b, tick = editoriginal(true)
-- blast away parts of some lines with visual mode
@@ -311,7 +312,7 @@ describe('buffer events', function()
expectn('nvim_buf_lines_event', {b, tick, 3, 4, {}, false})
end)
- it('knows when you filter lines', function()
+ it('when lines are filtered', function()
-- Test filtering lines with !cat
local b, tick = editoriginal(true, {"A", "C", "E", "B", "D", "F"})
@@ -325,7 +326,7 @@ describe('buffer events', function()
expectn('nvim_buf_lines_event', {b, tick, 1, 5, {}, false})
end)
- it('sends a sensible event when you use "o"', function()
+ it('when you use "o"', function()
local b, tick = editoriginal(true, {'AAA', 'BBB'})
command('set noautoindent nosmartindent')
@@ -365,7 +366,7 @@ describe('buffer events', function()
expectn('nvim_buf_lines_event', {b, tick, 0, 1, {"\tmmm"}, false})
end)
- it('deactivates when your buffer changes outside vim', function()
+ it('deactivates if the buffer is changed externally', function()
-- Test changing file from outside vim and reloading using :edit
local lines = {"Line 1", "Line 2"};
local b, tick, filename = editoriginal(true, lines)
@@ -380,17 +381,14 @@ describe('buffer events', function()
expectn('nvim_buf_changedtick_event', {b, tick})
-- change the file directly
- local f = io.open(filename, 'a')
- f:write("another line\n")
- f:flush()
- f:close()
+ write_file(filename, "another line\n", true, true)
- -- reopen the file and watch live updates shut down
+ -- reopen the file and watch buffer events shut down
command('edit')
expectn('nvim_buf_detach_event', {b})
end)
- it('allows a channel to watch multiple buffers at once', function()
+ it('channel can watch many buffers at once', function()
-- edit 3 buffers, make sure they all have windows visible so that when we
-- move between buffers, none of them are unloaded
local b1, tick1 = editoriginal(true, {'A1', 'A2'})
@@ -436,12 +434,12 @@ describe('buffer events', function()
expectn('nvim_buf_changedtick_event', {b3, tick3})
end)
- it('doesn\'t get confused when you turn watching on/off many times',
+ it('does not get confused if enabled/disabled many times',
function()
local channel = nvim('get_api_info')[1]
local b, tick = editoriginal(false)
- -- turn on live updates many times
+ -- Enable buffer events many times.
ok(buffer('attach', b, true, {}))
ok(buffer('attach', b, true, {}))
ok(buffer('attach', b, true, {}))
@@ -451,7 +449,7 @@ describe('buffer events', function()
eval('rpcnotify('..channel..', "Hello There")')
expectn('Hello There', {})
- -- turn live updates off many times
+ -- Disable buffer events many times.
ok(buffer('detach', b))
ok(buffer('detach', b))
ok(buffer('detach', b))
@@ -462,7 +460,7 @@ describe('buffer events', function()
expectn('Hello Again', {})
end)
- it('is able to notify several channels at once', function()
+ it('can notify several channels at once', function()
helpers.clear()
-- create several new sessions, in addition to our main API
@@ -486,11 +484,11 @@ describe('buffer events', function()
eq({'notification', name, args}, session:next_message())
end
- -- edit a new file, but don't turn on live updates
+ -- Edit a new file, but don't enable buffer events.
local lines = {'AAA', 'BBB'}
local b, tick = open(false, lines)
- -- turn on live updates for sessions 1, 2 and 3
+ -- Enable buffer events for sessions 1, 2 and 3.
ok(request(1, 'nvim_buf_attach', b, true, {}))
ok(request(2, 'nvim_buf_attach', b, true, {}))
ok(request(3, 'nvim_buf_attach', b, true, {}))
@@ -498,18 +496,18 @@ describe('buffer events', function()
wantn(2, 'nvim_buf_lines_event', {b, tick, 0, -1, lines, false})
wantn(3, 'nvim_buf_lines_event', {b, tick, 0, -1, lines, false})
- -- make a change to the buffer
+ -- Change the buffer.
command('normal! x')
tick = tick + 1
wantn(1, 'nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false})
wantn(2, 'nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false})
wantn(3, 'nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false})
- -- stop watching on channel 1
+ -- Stop watching on channel 1.
ok(request(1, 'nvim_buf_detach', b))
wantn(1, 'nvim_buf_detach_event', {b})
- -- undo the change to buffer 1
+ -- Undo the change to buffer 1.
command('undo')
tick = tick + 1
wantn(2, 'nvim_buf_lines_event', {b, tick, 0, 1, {'AAA'}, false})
@@ -612,7 +610,7 @@ describe('buffer events', function()
expectn('nvim_buf_lines_event', {b, tick, 5, 7, {}, false})
end)
- it('sends sensible events when you manually add/remove folds', function()
+ it('when you manually add/remove folds', function()
local b = editoriginal(true)
local tick = reopenwithfolds(b)
@@ -656,11 +654,11 @@ describe('buffer events', function()
'original line 6'}, false})
end)
- it('turns off updates when a buffer is closed', function()
+ it('detaches if the buffer is closed', function()
local b, tick = editoriginal(true, {'AAA'})
local channel = nvim('get_api_info')[1]
- -- test live updates are working
+ -- Test that buffer events are working.
command('normal! x')
tick = tick + 1
expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false})
@@ -674,7 +672,7 @@ describe('buffer events', function()
command('enew')
expectn('nvim_buf_detach_event', {b})
- -- reopen the original buffer, make sure there are no Live Updates sent
+ -- Reopen the original buffer, make sure there are no buffer events sent.
command('b1')
command('normal! x')
@@ -682,12 +680,11 @@ describe('buffer events', function()
expectn('Hello There', {})
end)
- -- test what happens when a buffer is hidden
- it('keeps updates turned on if the buffer is hidden', function()
+ it('stays attached if the buffer is hidden', function()
local b, tick = editoriginal(true, {'AAA'})
local channel = nvim('get_api_info')[1]
- -- test live updates are working
+ -- Test that buffer events are working.
command('normal! x')
tick = tick + 1
expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false})
@@ -697,22 +694,22 @@ describe('buffer events', function()
tick = tick + 1
expectn('nvim_buf_changedtick_event', {b, tick})
- -- close our buffer by creating a new one
+ -- Close our buffer by creating a new one.
command('set hidden')
command('enew')
- -- note that no nvim_buf_detach_event is sent
+ -- Assert that no nvim_buf_detach_event is sent.
eval('rpcnotify('..channel..', "Hello There")')
expectn('Hello There', {})
- -- reopen the original buffer, make sure Live Updates are still active
+ -- Reopen the original buffer, assert that buffer events are still active.
command('b1')
command('normal! x')
tick = tick + 1
expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false})
end)
- it('turns off live updates when a buffer is unloaded, deleted, or wiped',
+ it('detaches if the buffer is unloaded/deleted/wiped',
function()
-- start with a blank nvim
helpers.clear()
@@ -730,7 +727,7 @@ describe('buffer events', function()
end
end)
- it('doesn\'t send the buffer\'s content when not requested', function()
+ it('does not send the buffer content if not requested', function()
helpers.clear()
local b, tick = editoriginal(false)
ok(buffer('attach', b, false, {}))
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
index fed53a3dfd..76bf338d97 100644
--- a/test/functional/api/highlight_spec.lua
+++ b/test/functional/api/highlight_spec.lua
@@ -5,7 +5,7 @@ local eq, eval = helpers.eq, helpers.eval
local command = helpers.command
local meths = helpers.meths
-describe('highlight api',function()
+describe('API: highlight',function()
local expected_rgb = {
background = Screen.colors.Yellow,
foreground = Screen.colors.Red,
diff --git a/test/functional/api/rpc_fixture.lua b/test/functional/api/rpc_fixture.lua
index 423864740f..e885a525af 100644
--- a/test/functional/api/rpc_fixture.lua
+++ b/test/functional/api/rpc_fixture.lua
@@ -31,7 +31,7 @@ end
local function on_notification(event, args)
if event == 'ping' and #args == 0 then
- session:notify("vim_eval", "rpcnotify(g:channel, 'pong')")
+ session:notify("nvim_eval", "rpcnotify(g:channel, 'pong')")
end
end
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index e79a60fb10..856e5ca4d2 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -222,7 +222,7 @@ describe('server -> client', function()
end)
it('returns an error if the request failed', function()
- expect_err('Vim:Invalid method name',
+ expect_err('Vim:Invalid method: does%-not%-exist',
eval, "rpcrequest(vim, 'does-not-exist')")
end)
end)
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 1e910b6aa7..e4b343c123 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -20,9 +20,20 @@ local format_string = global_helpers.format_string
local intchar2lua = global_helpers.intchar2lua
local mergedicts_copy = global_helpers.mergedicts_copy
-describe('api', function()
+describe('API', function()
before_each(clear)
+ it('validates requests', function()
+ expect_err('Invalid method: bogus',
+ request, 'bogus')
+ expect_err('Invalid method: … の り 。…',
+ request, '… の り 。…')
+ expect_err('Invalid method: <empty>',
+ request, '')
+ expect_err("can't serialize object",
+ request, nil)
+ end)
+
describe('nvim_command', function()
it('works', function()
local fname = helpers.tmpname()
@@ -924,7 +935,7 @@ describe('api', function()
{'i_am_not_a_method', {'xx'}},
{'nvim_set_var', {'avar', 10}},
}
- eq({{}, {0, error_types.Exception.id, 'Invalid method name'}},
+ eq({{}, {0, error_types.Exception.id, 'Invalid method: i_am_not_a_method'}},
meths.call_atomic(req))
eq(5, meths.get_var('avar'))
end)
@@ -1226,6 +1237,7 @@ describe('api', function()
screen:attach()
local expected = {
{
+ chan = 1,
ext_cmdline = false,
ext_popupmenu = false,
ext_tabline = false,
@@ -1242,6 +1254,7 @@ describe('api', function()
screen:attach({ rgb = false })
expected = {
{
+ chan = 1,
ext_cmdline = false,
ext_popupmenu = false,
ext_tabline = false,
diff --git a/test/functional/eval/setpos_spec.lua b/test/functional/eval/setpos_spec.lua
index 6a8b3a8732..935f387bcc 100644
--- a/test/functional/eval/setpos_spec.lua
+++ b/test/functional/eval/setpos_spec.lua
@@ -27,9 +27,8 @@ describe('setpos() function', function()
eq(getpos("."), {0, 2, 1, 0})
setpos(".", {2, 1, 1, 0})
eq(getpos("."), {0, 1, 1, 0})
- -- Ensure get an error attempting to set position to another buffer
local ret = exc_exec('call setpos(".", [1, 1, 1, 0])')
- eq('Vim(call):E474: Invalid argument', ret)
+ eq(0, ret)
end)
it('can set lowercase marks in the current buffer', function()
setpos("'d", {0, 2, 1, 0})
diff --git a/test/functional/ex_cmds/debug_spec.lua b/test/functional/ex_cmds/debug_spec.lua
new file mode 100644
index 0000000000..5dad8098ea
--- /dev/null
+++ b/test/functional/ex_cmds/debug_spec.lua
@@ -0,0 +1,110 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local feed = helpers.feed
+local clear = helpers.clear
+
+describe(':debug', function()
+ local screen
+ before_each(function()
+ clear()
+ screen = Screen.new(50, 14)
+ screen:set_default_attr_ids({
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [2] = {bold = true, reverse = true},
+ [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ [4] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ })
+ screen:attach()
+ end)
+ it('scrolls messages correctly', function()
+ feed(':echoerr bork<cr>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {2: }|
+ {3:E121: Undefined variable: bork} |
+ {3:E15: Invalid expression: bork} |
+ {4:Press ENTER or type command to continue}^ |
+ ]])
+
+ feed(':debug echo "aa"| echo "bb"<cr>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {2: }|
+ {3:E121: Undefined variable: bork} |
+ {3:E15: Invalid expression: bork} |
+ Entering Debug mode. Type "cont" to continue. |
+ cmd: echo "aa"| echo "bb" |
+ >^ |
+ ]])
+
+ feed('step<cr>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {2: }|
+ {3:E121: Undefined variable: bork} |
+ {3:E15: Invalid expression: bork} |
+ Entering Debug mode. Type "cont" to continue. |
+ cmd: echo "aa"| echo "bb" |
+ >step |
+ aa |
+ cmd: echo "bb" |
+ >^ |
+ ]])
+
+ feed('step<cr>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {2: }|
+ {3:E121: Undefined variable: bork} |
+ {3:E15: Invalid expression: bork} |
+ Entering Debug mode. Type "cont" to continue. |
+ cmd: echo "aa"| echo "bb" |
+ >step |
+ aa |
+ cmd: echo "bb" |
+ >step |
+ bb |
+ {4:Press ENTER or type command to continue}^ |
+ ]])
+
+ feed('<cr>')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+ end)
+end)
diff --git a/test/functional/ex_cmds/write_spec.lua b/test/functional/ex_cmds/write_spec.lua
index bcf83698bb..3f54ff6f41 100644
--- a/test/functional/ex_cmds/write_spec.lua
+++ b/test/functional/ex_cmds/write_spec.lua
@@ -9,6 +9,7 @@ local command = helpers.command
local feed_command = helpers.feed_command
local funcs = helpers.funcs
local meths = helpers.meths
+local iswin = helpers.iswin
local fname = 'Xtest-functional-ex_cmds-write'
local fname_bak = fname .. '~'
@@ -34,11 +35,14 @@ describe(':write', function()
it('&backupcopy=auto preserves symlinks', function()
command('set backupcopy=auto')
write_file('test_bkc_file.txt', 'content0')
- if helpers.iswin() then
+ if iswin() then
command("silent !mklink test_bkc_link.txt test_bkc_file.txt")
else
command("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
end
+ if eval('v:shell_error') ~= 0 then
+ pending('Cannot create symlink', function()end)
+ end
source([[
edit test_bkc_link.txt
call setline(1, ['content1'])
@@ -51,11 +55,14 @@ describe(':write', function()
it('&backupcopy=no replaces symlink with new file', function()
command('set backupcopy=no')
write_file('test_bkc_file.txt', 'content0')
- if helpers.iswin() then
+ if iswin() then
command("silent !mklink test_bkc_link.txt test_bkc_file.txt")
else
command("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
end
+ if eval('v:shell_error') ~= 0 then
+ pending('Cannot create symlink', function()end)
+ end
source([[
edit test_bkc_link.txt
call setline(1, ['content1'])
@@ -66,7 +73,8 @@ describe(':write', function()
end)
it("appends FIFO file", function()
- if eval("executable('mkfifo')") == 0 then
+ -- mkfifo creates read-only .lnk files on Windows
+ if iswin() or eval("executable('mkfifo')") == 0 then
pending('missing "mkfifo" command', function()end)
return
end
@@ -88,7 +96,7 @@ describe(':write', function()
command('let $HOME=""')
eq(funcs.fnamemodify('.', ':p:h'), funcs.fnamemodify('.', ':p:h:~'))
-- Message from check_overwrite
- if not helpers.iswin() then
+ if not iswin() then
eq(('\nE17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'),
redir_exec('write .'))
end
@@ -108,7 +116,7 @@ describe(':write', function()
funcs.setfperm(fname, 'r--------')
eq('Vim(write):E505: "Xtest-functional-ex_cmds-write" is read-only (add ! to override)',
exc_exec('write'))
- if helpers.iswin() then
+ if iswin() then
eq(0, os.execute('del /q/f ' .. fname))
eq(0, os.execute('rd /q/s ' .. fname_bak))
else
@@ -117,7 +125,7 @@ describe(':write', function()
end
write_file(fname_bak, 'TTYX')
-- FIXME: exc_exec('write!') outputs 0 in Windows
- if helpers.iswin() then return end
+ if iswin() then return end
lfs.link(fname_bak .. ('/xxxxx'):rep(20), fname, true)
eq('Vim(write):E166: Can\'t open linked file for writing',
exc_exec('write!'))
diff --git a/test/functional/ex_cmds/wviminfo_spec.lua b/test/functional/ex_cmds/wviminfo_spec.lua
index eebbd70f2b..df0b9df5dd 100644
--- a/test/functional/ex_cmds/wviminfo_spec.lua
+++ b/test/functional/ex_cmds/wviminfo_spec.lua
@@ -3,21 +3,21 @@ local lfs = require('lfs')
local command, eq, neq, spawn, nvim_prog, set_session, write_file =
helpers.command, helpers.eq, helpers.neq, helpers.spawn,
helpers.nvim_prog, helpers.set_session, helpers.write_file
+local iswin = helpers.iswin
+local read_file = helpers.read_file
describe(':wshada', function()
local shada_file = 'wshada_test'
local session
before_each(function()
- if session then
- session:close()
- end
-
-- Override the default session because we need 'swapfile' for these tests.
- session = spawn({nvim_prog, '-u', 'NONE', '-i', '/dev/null', '--embed',
+ session = spawn({nvim_prog, '-u', 'NONE', '-i', iswin() and 'nul' or '/dev/null', '--embed',
'--cmd', 'set swapfile'})
set_session(session)
-
+ end)
+ after_each(function ()
+ session:close()
os.remove(shada_file)
end)
@@ -36,7 +36,7 @@ describe(':wshada', function()
write_file(shada_file, text)
-- sanity check
- eq(text, io.open(shada_file):read())
+ eq(text, read_file(shada_file))
neq(nil, lfs.attributes(shada_file))
command('wsh! '..shada_file)
@@ -49,8 +49,4 @@ describe(':wshada', function()
assert(char1:byte() == 0x01,
shada_file..' should be a shada file')
end)
-
- teardown(function()
- os.remove(shada_file)
- end)
end)
diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua
index c2667d28d2..379646b2ba 100644
--- a/test/functional/legacy/011_autocommands_spec.lua
+++ b/test/functional/legacy/011_autocommands_spec.lua
@@ -17,9 +17,10 @@ local lfs = require('lfs')
local clear, feed_command, expect, eq, neq, dedent, write_file, feed =
helpers.clear, helpers.feed_command, helpers.expect, helpers.eq, helpers.neq,
helpers.dedent, helpers.write_file, helpers.feed
+local iswin = helpers.iswin
local function has_gzip()
- local null = helpers.iswin() and 'nul' or '/dev/null'
+ local null = iswin() and 'nul' or '/dev/null'
return os.execute('gzip --help >' .. null .. ' 2>&1') == 0
end
@@ -59,7 +60,7 @@ describe('file reading, writing and bufnew and filter autocommands', function()
os.remove('test.out')
end)
- if not has_gzip() then
+ if iswin() or not has_gzip() then
pending('skipped (missing `gzip` utility)', function() end)
else
diff --git a/test/functional/legacy/097_glob_path_spec.lua b/test/functional/legacy/097_glob_path_spec.lua
index 907f0665ae..ccd93fed60 100644
--- a/test/functional/legacy/097_glob_path_spec.lua
+++ b/test/functional/legacy/097_glob_path_spec.lua
@@ -74,7 +74,7 @@ describe('glob() and globpath()', function()
teardown(function()
if helpers.iswin() then
os.execute('del /q/f Xxx{ Xxx$')
- os.execute('rd /q sautest')
+ os.execute('rd /q /s sautest')
else
os.execute("rm -rf sautest Xxx{ Xxx$")
end
diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua
index 381461dc4f..10703465aa 100644
--- a/test/functional/legacy/assert_spec.lua
+++ b/test/functional/legacy/assert_spec.lua
@@ -77,6 +77,11 @@ describe('assert function:', function()
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
exc_exec('call CheckAssert()'))
end)
+
+ it('can specify a message and get a message about what failed', function()
+ call('assert_equal', 'foo', 'bar', 'testing')
+ expected_errors({"testing: Expected 'foo' but got 'bar'"})
+ end)
end)
-- assert_notequal({expected}, {actual}[, {msg}])
@@ -164,10 +169,10 @@ describe('assert function:', function()
call assert_true('', 'file two')
]])
expected_errors({
- tmpname_one .. " line 1: 'equal assertion failed'",
- tmpname_one .. " line 2: 'true assertion failed'",
- tmpname_one .. " line 3: 'false assertion failed'",
- tmpname_two .. " line 1: 'file two'",
+ tmpname_one .. " line 1: equal assertion failed: Expected 1 but got 100",
+ tmpname_one .. " line 2: true assertion failed: Expected False but got 'true'",
+ tmpname_one .. " line 3: false assertion failed: Expected True but got 'false'",
+ tmpname_two .. " line 1: file two: Expected True but got ''",
})
end)
@@ -198,7 +203,7 @@ describe('assert function:', function()
it('should set v:errors to msg when given and match fails', function()
call('assert_match', 'bar.*foo', 'foobar', 'wrong')
- expected_errors({"'wrong'"})
+ expected_errors({"wrong: Pattern 'bar.*foo' does not match 'foobar'"})
end)
end)
diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua
index 5ef456bfe3..9ea3269828 100644
--- a/test/functional/legacy/delete_spec.lua
+++ b/test/functional/legacy/delete_spec.lua
@@ -4,6 +4,9 @@ local eq, eval, command = helpers.eq, helpers.eval, helpers.command
describe('Test for delete()', function()
before_each(clear)
+ after_each(function()
+ os.remove('Xfile')
+ end)
it('file delete', function()
command('split Xfile')
@@ -52,6 +55,9 @@ describe('Test for delete()', function()
silent !ln -s Xfile Xlink
endif
]])
+ if eval('v:shell_error') ~= 0 then
+ pending('Cannot create symlink', function()end)
+ end
-- Delete the link, not the file
eq(0, eval("delete('Xlink')"))
eq(-1, eval("delete('Xlink')"))
diff --git a/test/functional/provider/nodejs_spec.lua b/test/functional/provider/nodejs_spec.lua
index f69c3e7c78..07a00f8a8c 100644
--- a/test/functional/provider/nodejs_spec.lua
+++ b/test/functional/provider/nodejs_spec.lua
@@ -16,7 +16,6 @@ end
before_each(function()
clear()
- command([[let $NODE_PATH = get(split(system('npm root -g'), "\n"), 0, '')]])
end)
describe('nodejs host', function()
@@ -28,21 +27,18 @@ describe('nodejs host', function()
it('works', function()
local fname = 'Xtest-nodejs-hello.js'
write_file(fname, [[
- const socket = process.env.NVIM_LISTEN_ADDRESS;
const neovim = require('neovim');
- const nvim = neovim.attach({socket: socket});
+ const nvim = neovim.attach({socket: process.env.NVIM_LISTEN_ADDRESS});
nvim.command('let g:job_out = "hello"');
- nvim.command('call jobstop(g:job_id)');
]])
command('let g:job_id = jobstart(["node", "'..fname..'"])')
- retry(nil, 2000, function() eq('hello', eval('g:job_out')) end)
+ retry(nil, 3000, function() eq('hello', eval('g:job_out')) end)
end)
it('plugin works', function()
local fname = 'Xtest-nodejs-hello-plugin.js'
write_file(fname, [[
- const socket = process.env.NVIM_LISTEN_ADDRESS;
const neovim = require('neovim');
- const nvim = neovim.attach({socket: socket});
+ const nvim = neovim.attach({socket: process.env.NVIM_LISTEN_ADDRESS});
class TestPlugin {
hello() {
@@ -54,6 +50,6 @@ describe('nodejs host', function()
plugin.instance.hello();
]])
command('let g:job_id = jobstart(["node", "'..fname..'"])')
- retry(nil, 2000, function() eq('hello-plugin', eval('g:job_out')) end)
+ retry(nil, 3000, function() eq('hello-plugin', eval('g:job_out')) end)
end)
end)
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index 4f22f7385d..f98add41a0 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -47,6 +47,16 @@ describe(':terminal', function()
]])
end)
+ it("reads output buffer on terminal reporting #4151", function()
+ if helpers.pending_win32(pending) then return end
+ if iswin() then
+ feed_command([[terminal powershell -NoProfile -NoLogo -Command Write-Host -NoNewline "\"$([char]27)[6n\""; Start-Sleep -Milliseconds 500 ]])
+ else
+ feed_command([[terminal printf '\e[6n'; sleep 0.5 ]])
+ end
+ screen:expect('%^%[%[1;1R', nil, nil, nil, true)
+ end)
+
it("in normal-mode :split does not move cursor", function()
if iswin() then
feed_command([[terminal for /L \\%I in (1,0,2) do ( echo foo & ping -w 100 -n 1 127.0.0.1 > nul )]])
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 0ae5802a01..5603224975 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -253,6 +253,19 @@ describe('tui', function()
{4:-- TERMINAL --} |
]])
end)
+
+ it('shows up in nvim_list_uis', function()
+ feed_data(':echo map(nvim_list_uis(), {k,v -> sort(items(v))})\013')
+ screen:expect([=[
+ {5: }|
+ [[['ext_cmdline', v:false], ['ext_popupmenu', v:fa|
+ lse], ['ext_tabline', v:false], ['ext_wildmenu', v|
+ :false], ['height', 6], ['rgb', v:false], ['width'|
+ , 50]]] |
+ {10:Press ENTER or type command to continue}{1: } |
+ {3:-- TERMINAL --} |
+ ]=])
+ end)
end)
describe('tui with non-tty file descriptors', function()
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index 41c290a462..5ce49822e5 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -22,6 +22,8 @@ describe('external cmdline', function()
[1] = {bold = true, foreground = Screen.colors.Blue1},
[2] = {reverse = true},
[3] = {bold = true, reverse = true},
+ [4] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ [5] = {bold = true, foreground = Screen.colors.SeaGreen4},
})
screen:set_on_event_handler(function(name, data)
if name == "cmdline_show" then
@@ -157,24 +159,87 @@ describe('external cmdline', function()
end)
end)
- it("redraws statusline on entering", function()
- command('set laststatus=2')
- command('set statusline=%{mode()}')
- feed(':')
- screen:expect([[
- |
- {1:~ }|
- {1:~ }|
- {3:c^ }|
- |
- ]], nil, nil, function()
- eq({{
- content = { { {}, "" } },
- firstc = ":",
- indent = 0,
- pos = 0,
- prompt = ""
- }}, cmdline)
+ describe("redraws statusline on entering", function()
+ before_each(function()
+ command('set laststatus=2')
+ command('set statusline=%{mode()}')
+ end)
+
+ it('from normal mode', function()
+ feed(':')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {3:c^ }|
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "" } },
+ firstc = ":",
+ indent = 0,
+ pos = 0,
+ prompt = ""
+ }}, cmdline)
+ end)
+ end)
+
+ it('but not with scrolled messages', function()
+ screen:try_resize(50,10)
+ feed(':echoerr doesnotexist<cr>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3: }|
+ {4:E121: Undefined variable: doesnotexist} |
+ {4:E15: Invalid expression: doesnotexist} |
+ {5:Press ENTER or type command to continue}^ |
+ ]])
+ feed(':echoerr doesnotexist<cr>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3: }|
+ {4:E121: Undefined variable: doesnotexist} |
+ {4:E15: Invalid expression: doesnotexist} |
+ {4:E121: Undefined variable: doesnotexist} |
+ {4:E15: Invalid expression: doesnotexist} |
+ {5:Press ENTER or type command to continue}^ |
+ ]])
+
+ feed(':echoerr doesnotexist<cr>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {3: }|
+ {4:E121: Undefined variable: doesnotexist} |
+ {4:E15: Invalid expression: doesnotexist} |
+ {4:E121: Undefined variable: doesnotexist} |
+ {4:E15: Invalid expression: doesnotexist} |
+ {4:E121: Undefined variable: doesnotexist} |
+ {4:E15: Invalid expression: doesnotexist} |
+ {5:Press ENTER or type command to continue}^ |
+ ]])
+
+ feed('<cr>')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3:n }|
+ |
+ ]])
end)
end)
diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua
index c6ddc78618..b60d520ca0 100644
--- a/test/functional/ui/wildmode_spec.lua
+++ b/test/functional/ui/wildmode_spec.lua
@@ -31,6 +31,29 @@ describe("'wildmenu'", function()
]])
end)
+ it(':sign <tab> <space> hides wildmenu #8453', function()
+ command('set wildmode=full')
+ -- only a regression if status-line open
+ command('set laststatus=2')
+ command('set wildmenu')
+ feed(':sign <tab>')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ define jump list > |
+ :sign define^ |
+ ]])
+ feed('<space>')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ [No Name] |
+ :sign define ^ |
+ ]])
+ end)
+
it('does not crash after cycling back to original text', function()
command('set wildmode=full')
feed(':j<Tab><Tab><Tab>')
diff --git a/test/helpers.lua b/test/helpers.lua
index 0d3fe1316b..a774a67df3 100644
--- a/test/helpers.lua
+++ b/test/helpers.lua
@@ -259,7 +259,7 @@ local function check_cores(app, force)
else
initial_path = '.'
re = '/core[^/]*$'
- exc_re = { '^/%.deps$', local_tmpdir }
+ exc_re = { '^/%.deps$', local_tmpdir, '^/%node_modules$' }
db_cmd = gdb_db_cmd
random_skip = true
end
diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt
index 654cc5846f..adb3d73293 100644
--- a/third-party/CMakeLists.txt
+++ b/third-party/CMakeLists.txt
@@ -81,6 +81,15 @@ if(CMAKE_GENERATOR MATCHES "Makefiles")
set(MAKE_PRG "$(MAKE)")
endif()
+if(MINGW AND CMAKE_GENERATOR MATCHES "Ninja")
+ find_program(MAKE_PRG NAMES mingw32-make)
+ if(NOT MAKE_PRG)
+ message(FATAL_ERROR "GNU Make for mingw32 is required to build the dependecies.")
+ else()
+ message(STATUS "Found GNU Make for mingw32 at ${MAKE_PRG}")
+ endif()
+endif()
+
if(CMAKE_C_COMPILER_ARG1)
set(DEPS_C_COMPILER "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}")
else()
@@ -118,8 +127,8 @@ set(LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz)
set(LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333)
# NOTE: Version must match LUAROCKS_VERSION in third-party/cmake/BuildLuarocks.cmake
-set(LUAROCKS_URL https://github.com/luarocks/luarocks/archive/v2.4.3.tar.gz)
-set(LUAROCKS_SHA256 ea1881d6954f2a98c34f93674571c8f0cbdbc28dedb3fa3cb56b6a91886d1a99)
+set(LUAROCKS_URL https://github.com/luarocks/luarocks/archive/v2.4.4.tar.gz)
+set(LUAROCKS_SHA256 9eb3d0738fd02ad8bf39bcedccac4e83e9b5fff2bcca247c3584b925b2075d9c)
set(UNIBILIUM_URL https://github.com/mauke/unibilium/archive/v2.0.0.tar.gz)
set(UNIBILIUM_SHA256 78997d38d4c8177c60d3d0c1aa8c53fd0806eb21825b7b335b1768d7116bc1c1)
@@ -148,16 +157,22 @@ set(WINGUI_SHA256 260efc686423e2529360b6a45c8e241fbbf276c8de6b04d44f45ab5b6fe8df
set(WIN32YANK_X86_URL https://github.com/equalsraf/win32yank/releases/download/v0.0.4/win32yank-x86.zip)
set(WIN32YANK_X86_SHA256 62f34e5a46c5d4a7b3f3b512e1ff7b77fedd432f42581cbe825233a996eed62c)
-
set(WIN32YANK_X86_64_URL https://github.com/equalsraf/win32yank/releases/download/v0.0.4/win32yank-x64.zip)
set(WIN32YANK_X86_64_SHA256 33a747a92da60fb65e668edbf7661d3d902411a2d545fe9dc08623cecd142a20)
set(WINPTY_URL https://github.com/rprichard/winpty/releases/download/0.4.3/winpty-0.4.3-msvc2015.zip)
set(WINPTY_SHA256 35a48ece2ff4acdcbc8299d4920de53eb86b1fb41e64d2fe5ae7898931bcee89)
+# gettext source (for building/linking, does NOT provide tools like msgmerge.exe)
set(GETTEXT_URL https://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.8.1.tar.gz)
set(GETTEXT_SHA256 ff942af0e438ced4a8b0ea4b0b6e0d6d657157c5e2364de57baa279c1c125c43)
+# gettext binary (for tools like msgmerge.exe)
+set(GETTEXT_X86_URL https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.19.8.1-v1.15/gettext0.19.8.1-iconv1.15-shared-32.zip)
+set(GETTEXT_X86_SHA256 b7d8fe2d038950bc0447d664db614ebfc3100a1ba962a959d78e41bc708a2140)
+set(GETTEXT_X86_64_URL https://github.com/mlocati/gettext-iconv-windows/releases/download/v0.19.8.1-v1.15/gettext0.19.8.1-iconv1.15-shared-64.zip)
+set(GETTEXT_X86_64_SHA256 c8ed2897438efc0a511892c2b38b623ef0c9092aced2acbd3f3daf2f12ba70b4)
+
if(USE_BUNDLED_UNIBILIUM)
include(BuildUnibilium)
endif()
@@ -220,6 +235,9 @@ if(WIN32)
GetBinaryDep(TARGET "win32yank_${TARGET_ARCH}"
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy win32yank.exe ${DEPS_INSTALL_DIR}/bin)
+ GetBinaryDep(TARGET "gettext_${TARGET_ARCH}"
+ INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory bin ${DEPS_INSTALL_DIR}/bin)
+
if("${TARGET_ARCH}" STREQUAL "X86_64")
set(TARGET_ARCH x64)
elseif(TARGET_ARCH STREQUAL "X86")
diff --git a/third-party/cmake/BuildLibtermkey.cmake b/third-party/cmake/BuildLibtermkey.cmake
index 8147c47e1e..0b56674ad2 100644
--- a/third-party/cmake/BuildLibtermkey.cmake
+++ b/third-party/cmake/BuildLibtermkey.cmake
@@ -14,6 +14,7 @@ ExternalProject_Add(libtermkey
PATCH_COMMAND ${GIT_EXECUTABLE} -C ${DEPS_BUILD_DIR}/src/libtermkey init
COMMAND ${GIT_EXECUTABLE} -C ${DEPS_BUILD_DIR}/src/libtermkey apply --ignore-whitespace
${CMAKE_CURRENT_SOURCE_DIR}/patches/libtermkey-Add-support-for-Windows.patch
+ ${CMAKE_CURRENT_SOURCE_DIR}/patches/libtermkey-Fix-escape-sequences-for-MSVC.patch
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/cmake/libtermkeyCMakeLists.txt
${DEPS_BUILD_DIR}/src/libtermkey/CMakeLists.txt
diff --git a/third-party/cmake/BuildLibuv.cmake b/third-party/cmake/BuildLibuv.cmake
index 084e707f92..e1aecdc43c 100644
--- a/third-party/cmake/BuildLibuv.cmake
+++ b/third-party/cmake/BuildLibuv.cmake
@@ -44,7 +44,7 @@ set(UNIX_CFGCMD sh ${DEPS_BUILD_DIR}/src/libuv/autogen.sh &&
set(LIBUV_PATCH_COMMAND
${GIT_EXECUTABLE} -C ${DEPS_BUILD_DIR}/src/libuv init
- COMMAND ${GIT_EXECUTABLE} -C ${DEPS_BUILD_DIR}/src/libuv apply
+ COMMAND ${GIT_EXECUTABLE} -C ${DEPS_BUILD_DIR}/src/libuv apply --ignore-whitespace
${CMAKE_CURRENT_SOURCE_DIR}/patches/libuv-overlapped.patch)
if(UNIX)
@@ -64,21 +64,16 @@ elseif(MINGW AND CMAKE_CROSSCOMPILING)
CONFIGURE_COMMAND ${UNIX_CFGCMD} --host=${CROSS_TARGET}
INSTALL_COMMAND ${MAKE_PRG} V=1 install)
-elseif(MINGW)
-
- # Native MinGW
- BuildLibUv(BUILD_IN_SOURCE
- PATCH_COMMAND ${LIBUV_PATCH_COMMAND}
- BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} -f Makefile.mingw
- INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/lib
- COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/libuv/libuv.a ${DEPS_INSTALL_DIR}/lib
- COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/include
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/libuv/include ${DEPS_INSTALL_DIR}/include
- )
-
-elseif(WIN32 AND MSVC)
+elseif(WIN32)
set(UV_OUTPUT_DIR ${DEPS_BUILD_DIR}/src/libuv/${CMAKE_BUILD_TYPE})
+ if(MSVC)
+ set(BUILD_SHARED ON)
+ elseif(MINGW)
+ set(BUILD_SHARED OFF)
+ else()
+ message(FATAL_ERROR "Trying to build libuv in an unsupported system ${CMAKE_SYSTEM_NAME}/${CMAKE_C_COMPILER_ID}")
+ endif()
BuildLibUv(BUILD_IN_SOURCE
PATCH_COMMAND ${LIBUV_PATCH_COMMAND}
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy
@@ -88,16 +83,10 @@ elseif(WIN32 AND MSVC)
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
- -DBUILD_SHARED_LIBS=ON
+ -DBUILD_SHARED_LIBS=${BUILD_SHARED}
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR}
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE}
- INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${CMAKE_BUILD_TYPE}
- # Some applications (lua-client/luarocks) look for uv.lib instead of libuv.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${UV_OUTPUT_DIR}/libuv.lib ${DEPS_INSTALL_DIR}/lib/uv.lib
- COMMAND ${CMAKE_COMMAND} -E copy ${UV_OUTPUT_DIR}/libuv.dll ${DEPS_INSTALL_DIR}/bin/
- COMMAND ${CMAKE_COMMAND} -E copy ${UV_OUTPUT_DIR}/libuv.dll ${DEPS_INSTALL_DIR}/bin/uv.dll
- COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/include
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/libuv/include ${DEPS_INSTALL_DIR}/include)
+ INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${CMAKE_BUILD_TYPE})
else()
message(FATAL_ERROR "Trying to build libuv in an unsupported system ${CMAKE_SYSTEM_NAME}/${CMAKE_C_COMPILER_ID}")
diff --git a/third-party/cmake/BuildLibvterm.cmake b/third-party/cmake/BuildLibvterm.cmake
index e4649986af..4720581e52 100644
--- a/third-party/cmake/BuildLibvterm.cmake
+++ b/third-party/cmake/BuildLibvterm.cmake
@@ -39,7 +39,8 @@ if(WIN32)
set(LIBVTERM_PATCH_COMMAND
${GIT_EXECUTABLE} -C ${DEPS_BUILD_DIR}/src/libvterm init
COMMAND ${GIT_EXECUTABLE} -C ${DEPS_BUILD_DIR}/src/libvterm apply --ignore-whitespace
- ${CMAKE_CURRENT_SOURCE_DIR}/patches/libvterm-Remove-VLAs-for-MSVC.patch)
+ ${CMAKE_CURRENT_SOURCE_DIR}/patches/libvterm-Remove-VLAs-for-MSVC.patch
+ ${CMAKE_CURRENT_SOURCE_DIR}/patches/libvterm-Fix-escape-sequences-for-MSVC.patch)
endif()
set(LIBVTERM_CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibvtermCMakeLists.txt
diff --git a/third-party/cmake/BuildLuajit.cmake b/third-party/cmake/BuildLuajit.cmake
index 2fda221b12..721bca9f63 100644
--- a/third-party/cmake/BuildLuajit.cmake
+++ b/third-party/cmake/BuildLuajit.cmake
@@ -78,8 +78,12 @@ elseif(MINGW AND CMAKE_CROSSCOMPILING)
elseif(MINGW)
-
- BuildLuaJit(BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} CC=${DEPS_C_COMPILER}
+ if(CMAKE_GENERATOR MATCHES "Ninja")
+ set(LUAJIT_MAKE_PRG ${MAKE_PRG})
+ else()
+ set(LUAJIT_MAKE_PRG ${CMAKE_MAKE_PROGRAM})
+ endif()
+ BuildLuaJit(BUILD_COMMAND ${LUAJIT_MAKE_PRG} CC=${DEPS_C_COMPILER}
PREFIX=${DEPS_INSTALL_DIR}
CFLAGS+=-DLUAJIT_DISABLE_JIT
CFLAGS+=-DLUA_USE_APICHECK
@@ -87,7 +91,7 @@ elseif(MINGW)
CCDEBUG+=-g
BUILDMODE=static
# Build a DLL too
- COMMAND ${CMAKE_MAKE_PROGRAM} CC=${DEPS_C_COMPILER} BUILDMODE=dynamic
+ COMMAND ${LUAJIT_MAKE_PRG} CC=${DEPS_C_COMPILER} BUILDMODE=dynamic
INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/bin
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/luajit.exe ${DEPS_INSTALL_DIR}/bin
diff --git a/third-party/cmake/BuildLuarocks.cmake b/third-party/cmake/BuildLuarocks.cmake
index b5fcf7f3e5..e0ea670be1 100644
--- a/third-party/cmake/BuildLuarocks.cmake
+++ b/third-party/cmake/BuildLuarocks.cmake
@@ -12,7 +12,7 @@ function(BuildLuarocks)
cmake_parse_arguments(_luarocks
""
""
- "PATCH_COMMAND;CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND"
+ "CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND"
${ARGN})
if(NOT _luarocks_CONFIGURE_COMMAND AND NOT _luarocks_BUILD_COMMAND
@@ -32,7 +32,6 @@ function(BuildLuarocks)
-DTARGET=luarocks
-DUSE_EXISTING_SRC_DIR=${USE_EXISTING_SRC_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DownloadAndExtractFile.cmake
- PATCH_COMMAND "${_luarocks_PATCH_COMMAND}"
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND "${_luarocks_CONFIGURE_COMMAND}"
BUILD_COMMAND "${_luarocks_BUILD_COMMAND}"
@@ -51,11 +50,6 @@ if(NOT MSVC)
# version already knows, and passing them here breaks the build
set(LUAROCKS_BUILDARGS CC=${HOSTDEPS_C_COMPILER} LD=${HOSTDEPS_C_COMPILER})
endif()
-if(WIN32)
- # Use our bundled curl.exe for downloading packages
- set(LUAROCKS_BUILDARGS ${LUAROCKS_BUILDARGS} CURL=${DEPS_BIN_DIR}/curl.exe)
-endif()
-
if(UNIX OR (MINGW AND CMAKE_CROSSCOMPILING))
@@ -82,12 +76,7 @@ elseif(MSVC OR MINGW)
endif()
# Ignore USE_BUNDLED_LUAJIT - always ON for native Win32
- BuildLuarocks(
- PATCH_COMMAND
- ${GIT_EXECUTABLE} -C ${DEPS_BUILD_DIR}/src/luarocks init
- COMMAND ${GIT_EXECUTABLE} -C ${DEPS_BUILD_DIR}/src/luarocks apply --ignore-whitespace
- ${CMAKE_CURRENT_SOURCE_DIR}/patches/luarocks-Change-default-downloader-to-curl.patch
- INSTALL_COMMAND install.bat /FORCECONFIG /NOREG /NOADMIN /Q /F
+ BuildLuarocks(INSTALL_COMMAND install.bat /FORCECONFIG /NOREG /NOADMIN /Q /F
/LUA ${DEPS_INSTALL_DIR}
/LIB ${DEPS_LIB_DIR}
/BIN ${DEPS_BIN_DIR}
@@ -99,8 +88,6 @@ elseif(MSVC OR MINGW)
/LUAMOD ${DEPS_BIN_DIR}/lua)
set(LUAROCKS_BINARY ${DEPS_INSTALL_DIR}/${LUAROCKS_VERSION}/luarocks.bat)
- add_dependencies(luarocks wintools)
-
else()
message(FATAL_ERROR "Trying to build luarocks in an unsupported system ${CMAKE_SYSTEM_NAME}/${CMAKE_C_COMPILER_ID}")
endif()
diff --git a/third-party/cmake/BuildLuv.cmake b/third-party/cmake/BuildLuv.cmake
index 339264746c..a62ee72f91 100644
--- a/third-party/cmake/BuildLuv.cmake
+++ b/third-party/cmake/BuildLuv.cmake
@@ -58,6 +58,12 @@ set(LUV_CONFIGURE_COMMAND_COMMON
-DBUILD_SHARED_LIBS=OFF
-DBUILD_MODULE=OFF)
+if(USE_BUNDLED_LIBUV)
+ set(LUV_CONFIGURE_COMMAND_COMMON
+ ${LUV_CONFIGURE_COMMAND_COMMON}
+ -DCMAKE_PREFIX_PATH=${DEPS_INSTALL_DIR})
+endif()
+
if(MINGW AND CMAKE_CROSSCOMPILING)
get_filename_component(TOOLCHAIN ${CMAKE_TOOLCHAIN_FILE} REALPATH)
set(LUV_CONFIGURE_COMMAND
diff --git a/third-party/cmake/LibuvCMakeLists.txt b/third-party/cmake/LibuvCMakeLists.txt
index 063e4291f2..8b51a101c6 100644
--- a/third-party/cmake/LibuvCMakeLists.txt
+++ b/third-party/cmake/LibuvCMakeLists.txt
@@ -4,11 +4,13 @@ project(libuv LANGUAGES C)
file(GLOB UV_SOURCES_COMMON src/*.c)
file(GLOB UV_SOURCES_WIN src/win/*.c)
-add_library(libuv ${UV_SOURCES_COMMON} ${UV_SOURCES_WIN})
-target_compile_definitions(libuv PRIVATE WIN32_LEAN_AND_MEAN "_WIN32_WINNT=0x0600")
-target_link_libraries(libuv iphlpapi psapi shell32 userenv ws2_32)
-target_include_directories(libuv PUBLIC ./include PRIVATE ./src)
-set_target_properties(libuv PROPERTIES DEFINE_SYMBOL BUILDING_UV_SHARED)
+add_library(uv ${UV_SOURCES_COMMON} ${UV_SOURCES_WIN})
+target_compile_definitions(uv PRIVATE WIN32_LEAN_AND_MEAN "_WIN32_WINNT=0x0600")
+target_link_libraries(uv iphlpapi psapi shell32 userenv ws2_32)
+target_include_directories(uv PUBLIC ./include PRIVATE ./src)
+if(BUILD_SHARED_LIBS)
+ set_target_properties(uv PROPERTIES DEFINE_SYMBOL BUILDING_UV_SHARED)
+endif()
install(FILES
include/tree.h
@@ -20,8 +22,9 @@ install(FILES
DESTINATION include)
include(GNUInstallDirs)
-install(TARGETS libuv
+install(TARGETS uv
PUBLIC_HEADER
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
diff --git a/third-party/patches/libtermkey-Fix-escape-sequences-for-MSVC.patch b/third-party/patches/libtermkey-Fix-escape-sequences-for-MSVC.patch
new file mode 100644
index 0000000000..c1099bd3c4
--- /dev/null
+++ b/third-party/patches/libtermkey-Fix-escape-sequences-for-MSVC.patch
@@ -0,0 +1,189 @@
+diff --git a/t/30mouse.c b/t/30mouse.c
+--- a/t/30mouse.c
++++ b/t/30mouse.c
+@@ -14,7 +14,7 @@ int main(int argc, char *argv[])
+
+ tk = termkey_new_abstract("vt100", 0);
+
+- termkey_push_bytes(tk, "\e[M !!", 6);
++ termkey_push_bytes(tk, "\x1b[M !!", 6);
+
+ key.type = -1;
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse press");
+@@ -38,7 +38,7 @@ int main(int argc, char *argv[])
+ is_int(len, 21, "string length for press");
+ is_str(buffer, "MousePress(1) @ (1,1)", "string buffer for press");
+
+- termkey_push_bytes(tk, "\e[M@\"!", 6);
++ termkey_push_bytes(tk, "\x1b[M@\"!", 6);
+
+ key.type = -1;
+ ev = -1; button = -1; line = -1; col = -1;
+@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
+ is_int(col, 2, "mouse column for drag");
+ is_int(key.modifiers, 0, "modifiers for press");
+
+- termkey_push_bytes(tk, "\e[M##!", 6);
++ termkey_push_bytes(tk, "\x1b[M##!", 6);
+
+ key.type = -1;
+ ev = -1; button = -1; line = -1; col = -1;
+@@ -63,7 +63,7 @@ int main(int argc, char *argv[])
+ is_int(col, 3, "mouse column for release");
+ is_int(key.modifiers, 0, "modifiers for press");
+
+- termkey_push_bytes(tk, "\e[M0++", 6);
++ termkey_push_bytes(tk, "\x1b[M0++", 6);
+
+ key.type = -1;
+ ev = -1; button = -1; line = -1; col = -1;
+@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
+ is_str(buffer, "C-MousePress(1)", "string buffer for Ctrl-press");
+
+ // rxvt protocol
+- termkey_push_bytes(tk, "\e[0;20;20M", 10);
++ termkey_push_bytes(tk, "\x1b[0;20;20M", 10);
+
+ key.type = -1;
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse press rxvt protocol");
+@@ -96,7 +96,7 @@ int main(int argc, char *argv[])
+ is_int(col, 20, "mouse column for press rxvt protocol");
+ is_int(key.modifiers, 0, "modifiers for press rxvt protocol");
+
+- termkey_push_bytes(tk, "\e[3;20;20M", 10);
++ termkey_push_bytes(tk, "\x1b[3;20;20M", 10);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse release rxvt protocol");
+
+@@ -111,7 +111,7 @@ int main(int argc, char *argv[])
+ is_int(key.modifiers, 0, "modifiers for release rxvt protocol");
+
+ // SGR protocol
+- termkey_push_bytes(tk, "\e[<0;30;30M", 11);
++ termkey_push_bytes(tk, "\x1b[<0;30;30M", 11);
+
+ key.type = -1;
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse press SGR encoding");
+@@ -127,7 +127,7 @@ int main(int argc, char *argv[])
+ is_int(col, 30, "mouse column for press SGR");
+ is_int(key.modifiers, 0, "modifiers for press SGR");
+
+- termkey_push_bytes(tk, "\e[<0;30;30m", 11);
++ termkey_push_bytes(tk, "\x1b[<0;30;30m", 11);
+
+ key.type = -1;
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse release SGR encoding");
+@@ -139,7 +139,7 @@ int main(int argc, char *argv[])
+
+ is_int(ev, TERMKEY_MOUSE_RELEASE, "mouse event for release SGR");
+
+- termkey_push_bytes(tk, "\e[<0;500;300M", 13);
++ termkey_push_bytes(tk, "\x1b[<0;500;300M", 13);
+
+ key.type = -1;
+ ev = -1; button = -1; line = -1; col = -1;
+diff --git a/t/31position.c b/t/31position.c
+index 1748211..86ad1bc 100644
+--- a/t/31position.c
++++ b/t/31position.c
+@@ -11,7 +11,7 @@ int main(int argc, char *argv[])
+
+ tk = termkey_new_abstract("vt100", 0);
+
+- termkey_push_bytes(tk, "\e[?15;7R", 8);
++ termkey_push_bytes(tk, "\x1b[?15;7R", 8);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for position report");
+
+@@ -25,7 +25,7 @@ int main(int argc, char *argv[])
+ /* A plain CSI R is likely to be <F3> though.
+ * This is tricky :/
+ */
+- termkey_push_bytes(tk, "\e[R", 3);
++ termkey_push_bytes(tk, "\x1b[R", 3);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for <F3>");
+
+diff --git a/t/32modereport.c b/t/32modereport.c
+index 31de400..5e49705 100644
+--- a/t/32modereport.c
++++ b/t/32modereport.c
+@@ -11,7 +11,7 @@ int main(int argc, char *argv[])
+
+ tk = termkey_new_abstract("vt100", 0);
+
+- termkey_push_bytes(tk, "\e[?1;2$y", 8);
++ termkey_push_bytes(tk, "\x1b[?1;2$y", 8);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mode report");
+
+@@ -23,7 +23,7 @@ int main(int argc, char *argv[])
+ is_int(mode, 1, "mode number from mode report");
+ is_int(value, 2, "mode value from mode report");
+
+- termkey_push_bytes(tk, "\e[4;1$y", 7);
++ termkey_push_bytes(tk, "\x1b[4;1$y", 7);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mode report");
+
+diff --git a/t/38csi.c b/t/38csi.c
+index 9d186f6..fd592d5 100644
+--- a/t/38csi.c
++++ b/t/38csi.c
+@@ -13,7 +13,7 @@ int main(int argc, char *argv[])
+
+ tk = termkey_new_abstract("vt100", 0);
+
+- termkey_push_bytes(tk, "\e[5;25v", 7);
++ termkey_push_bytes(tk, "\x1b[5;25v", 7);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for CSI v");
+
+@@ -26,14 +26,14 @@ int main(int argc, char *argv[])
+ is_int(args[1], 25, "args[1] for unknown CSI");
+ is_int(command, 'v', "command for unknown CSI");
+
+- termkey_push_bytes(tk, "\e[?w", 4);
++ termkey_push_bytes(tk, "\x1b[?w", 4);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for CSI ? w");
+ is_int(key.type, TERMKEY_TYPE_UNKNOWN_CSI, "key.type for unknown CSI");
+ is_int(termkey_interpret_csi(tk, &key, args, &nargs, &command), TERMKEY_RES_KEY, "interpret_csi yields RES_KEY");
+ is_int(command, '?'<<8 | 'w', "command for unknown CSI");
+
+- termkey_push_bytes(tk, "\e[?$x", 5);
++ termkey_push_bytes(tk, "\x1b[?$x", 5);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for CSI ? $x");
+ is_int(key.type, TERMKEY_TYPE_UNKNOWN_CSI, "key.type for unknown CSI");
+diff --git a/t/39dcs.c b/t/39dcs.c
+index c517411..f065477 100644
+--- a/t/39dcs.c
++++ b/t/39dcs.c
+@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
+ tk = termkey_new_abstract("xterm", 0);
+
+ // 7bit DCS
+- termkey_push_bytes(tk, "\eP1$r1 q\e\\", 10);
++ termkey_push_bytes(tk, "\x1bP1$r1 q\x1b\\", 10);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for DCS");
+
+@@ -38,7 +38,7 @@ int main(int argc, char *argv[])
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_NONE, "getkey again yields RES_NONE");
+
+ // 7bit OSC
+- termkey_push_bytes(tk, "\e]15;abc\e\\", 10);
++ termkey_push_bytes(tk, "\x1b]15;abc\x1b\\", 10);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for OSC");
+
+@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_NONE, "getkey again yields RES_NONE");
+
+ // False alarm
+- termkey_push_bytes(tk, "\eP", 2);
++ termkey_push_bytes(tk, "\x1bP", 2);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_AGAIN, "getkey yields RES_AGAIN for false alarm");
+
diff --git a/third-party/patches/libvterm-Fix-escape-sequences-for-MSVC.patch b/third-party/patches/libvterm-Fix-escape-sequences-for-MSVC.patch
new file mode 100644
index 0000000000..b2f0809544
--- /dev/null
+++ b/third-party/patches/libvterm-Fix-escape-sequences-for-MSVC.patch
@@ -0,0 +1,53 @@
+diff --git a/src/keyboard.c b/src/keyboard.c
+index bc1299b..5f368f4 100644
+--- a/src/keyboard.c
++++ b/src/keyboard.c
+@@ -48,7 +48,7 @@ void vterm_keyboard_unichar(VTerm *vt, uint32_t c, VTermModifier mod)
+ if(mod & VTERM_MOD_CTRL)
+ c &= 0x1f;
+
+- vterm_push_output_sprintf(vt, "%s%c", mod & VTERM_MOD_ALT ? "\e" : "", c);
++ vterm_push_output_sprintf(vt, "%s%c", mod & VTERM_MOD_ALT ? "\x1b" : "", c);
+ }
+
+ typedef struct {
+@@ -73,7 +73,7 @@ static keycodes_s keycodes[] = {
+ { KEYCODE_ENTER, '\r' }, // ENTER
+ { KEYCODE_TAB, '\t' }, // TAB
+ { KEYCODE_LITERAL, '\x7f' }, // BACKSPACE == ASCII DEL
+- { KEYCODE_LITERAL, '\e' }, // ESCAPE
++ { KEYCODE_LITERAL, '\x1b' }, // ESCAPE
+
+ { KEYCODE_CSI_CURSOR, 'A' }, // UP
+ { KEYCODE_CSI_CURSOR, 'B' }, // DOWN
+@@ -173,7 +173,7 @@ void vterm_keyboard_key(VTerm *vt, VTermKey key, VTermModifier mod)
+ if(mod & (VTERM_MOD_SHIFT|VTERM_MOD_CTRL))
+ vterm_push_output_sprintf_ctrl(vt, C1_CSI, "%d;%du", k.literal, mod+1);
+ else
+- vterm_push_output_sprintf(vt, mod & VTERM_MOD_ALT ? "\e%c" : "%c", k.literal);
++ vterm_push_output_sprintf(vt, mod & VTERM_MOD_ALT ? "\x1b%c" : "%c", k.literal);
+ break;
+
+ case KEYCODE_SS3: case_SS3:
+diff --git a/src/vterm.c b/src/vterm.c
+index 826df93..262b3fc 100644
+--- a/src/vterm.c
++++ b/src/vterm.c
+@@ -158,7 +158,7 @@ INTERNAL void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, cons
+ size_t orig_cur = vt->outbuffer_cur;
+
+ if(ctrl >= 0x80 && !vt->mode.ctrl8bit)
+- vterm_push_output_sprintf(vt, "\e%c", ctrl - 0x40);
++ vterm_push_output_sprintf(vt, "\x1b%c", ctrl - 0x40);
+ else
+ vterm_push_output_sprintf(vt, "%c", ctrl);
+
+@@ -176,7 +176,7 @@ INTERNAL void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...)
+ size_t orig_cur = vt->outbuffer_cur;
+
+ if(!vt->mode.ctrl8bit)
+- vterm_push_output_sprintf(vt, "\e%c", C1_DCS - 0x40);
++ vterm_push_output_sprintf(vt, "\x1b%c", C1_DCS - 0x40);
+ else
+ vterm_push_output_sprintf(vt, "%c", C1_DCS);
+
diff --git a/third-party/patches/luarocks-Change-default-downloader-to-curl.patch b/third-party/patches/luarocks-Change-default-downloader-to-curl.patch
deleted file mode 100644
index b7109a3b53..0000000000
--- a/third-party/patches/luarocks-Change-default-downloader-to-curl.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 69313032fad04743c96bc8f2a029b691857488f9 Mon Sep 17 00:00:00 2001
-Date: Thu, 1 Mar 2018 21:41:29 -0600
-Subject: [PATCH] Change default downloader to curl
-
----
- install.bat | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/install.bat b/install.bat
-index 09cf9aa..76e4059 100644
---- a/install.bat
-+++ b/install.bat
-@@ -1037,7 +1037,7 @@ f:write(S[=[
- site_config.LUAROCKS_UNAME_M=[[$UNAME_M]]
- site_config.LUAROCKS_ROCKS_TREE=[[$TREE_ROOT]]
- site_config.LUAROCKS_PREFIX=[[$PREFIX]]
--site_config.LUAROCKS_DOWNLOADER=[[wget]]
-+site_config.LUAROCKS_DOWNLOADER=[[curl]]
- site_config.LUAROCKS_MD5CHECKER=[[md5sum]]
- ]=])
- if FORCE_CONFIG then
---
-2.16.1.windows.4
-