aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake.deps/CMakeLists.txt13
-rw-r--r--cmake.deps/cmake/BuildLuajit.cmake6
-rw-r--r--cmake.deps/deps.txt4
-rw-r--r--cmake/FindTreesitter.cmake20
-rw-r--r--runtime/doc/filetype.txt1
-rw-r--r--runtime/doc/lsp.txt12
-rw-r--r--runtime/doc/news.txt4
-rw-r--r--runtime/doc/treesitter.txt7
-rw-r--r--runtime/lua/vim/filetype.lua4
-rw-r--r--runtime/lua/vim/filetype/detect.lua22
-rw-r--r--runtime/lua/vim/lsp.lua4
-rw-r--r--runtime/lua/vim/lsp/_watchfiles.lua10
-rw-r--r--runtime/lua/vim/treesitter/_meta.lua14
-rw-r--r--runtime/lua/vim/treesitter/query.lua8
-rw-r--r--src/nvim/CMakeLists.txt10
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/ex_cmds.c3
-rw-r--r--src/nvim/ex_docmd.c20
-rw-r--r--src/nvim/ex_getln.c2
-rw-r--r--src/nvim/getchar.c11
-rw-r--r--src/nvim/highlight.c9
-rw-r--r--src/nvim/lua/treesitter.c28
-rw-r--r--src/nvim/normal.c2
-rw-r--r--src/nvim/ops.c14
-rw-r--r--src/nvim/ops.h4
-rw-r--r--src/nvim/terminal.c2
-rw-r--r--test/functional/api/keymap_spec.lua45
-rw-r--r--test/functional/plugin/lsp_spec.lua10
-rw-r--r--test/functional/ui/float_spec.lua63
-rw-r--r--test/functional/ui/screen_basic_spec.lua121
-rw-r--r--test/functional/ui/title_spec.lua138
-rw-r--r--test/old/testdir/test_exit.vim12
-rw-r--r--test/old/testdir/test_filetype.vim33
33 files changed, 464 insertions, 194 deletions
diff --git a/cmake.deps/CMakeLists.txt b/cmake.deps/CMakeLists.txt
index 3d835064ba..bb86a671f2 100644
--- a/cmake.deps/CMakeLists.txt
+++ b/cmake.deps/CMakeLists.txt
@@ -133,7 +133,9 @@ if(APPLE)
endif()
include(ExternalProject)
-set_directory_properties(PROPERTIES EP_PREFIX "${DEPS_BUILD_DIR}")
+set_directory_properties(PROPERTIES
+ EP_PREFIX "${DEPS_BUILD_DIR}"
+ CMAKE_CONFIGURE_DEPENDS deps.txt)
file(READ deps.txt DEPENDENCIES)
STRING(REGEX REPLACE "\n" ";" DEPENDENCIES "${DEPENDENCIES}")
@@ -141,16 +143,9 @@ foreach(dep ${DEPENDENCIES})
STRING(REGEX REPLACE " " ";" dep "${dep}")
list(GET dep 0 name)
list(GET dep 1 value)
-
- if(name MATCHES "^.*URL$")
- mark_as_advanced(${name})
- if(NOT USE_EXISTING_SRC_DIR)
- set(${name} ${value} CACHE STRING "")
- endif()
- elseif(name MATCHES "^.*SHA256$")
+ if(NOT ${name})
set(${name} ${value})
endif()
-
endforeach()
if(USE_BUNDLED_UNIBILIUM)
diff --git a/cmake.deps/cmake/BuildLuajit.cmake b/cmake.deps/cmake/BuildLuajit.cmake
index 04696baf9b..cb2e8b9292 100644
--- a/cmake.deps/cmake/BuildLuajit.cmake
+++ b/cmake.deps/cmake/BuildLuajit.cmake
@@ -122,8 +122,7 @@ elseif(MINGW)
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/libluajit.a ${DEPS_LIB_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/include/luajit-2.1
COMMAND ${CMAKE_COMMAND} -DFROM_GLOB=${DEPS_BUILD_DIR}/src/luajit/src/*.h -DTO=${DEPS_INSTALL_DIR}/include/luajit-2.1 -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CopyFilesGlob.cmake
- COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_BIN_DIR}/lua/jit
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${DEPS_BIN_DIR}/lua/jit
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${DEPS_INSTALL_DIR}/share/luajit-2.1.0-beta3/jit
)
elseif(MSVC)
@@ -139,8 +138,7 @@ elseif(MSVC)
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/lua51.lib ${DEPS_LIB_DIR}/luajit.lib
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/include/luajit-2.1
COMMAND ${CMAKE_COMMAND} -DFROM_GLOB=${DEPS_BUILD_DIR}/src/luajit/src/*.h -DTO=${DEPS_INSTALL_DIR}/include/luajit-2.1 -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CopyFilesGlob.cmake
- COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_BIN_DIR}/lua/jit
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${DEPS_BIN_DIR}/lua/jit
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${DEPS_INSTALL_DIR}/share/luajit-2.1.0-beta3/jit
)
else()
message(FATAL_ERROR "Trying to build luajit in an unsupported system ${CMAKE_SYSTEM_NAME}/${CMAKE_C_COMPILER_ID}")
diff --git a/cmake.deps/deps.txt b/cmake.deps/deps.txt
index cd687cf929..6ae3a095e7 100644
--- a/cmake.deps/deps.txt
+++ b/cmake.deps/deps.txt
@@ -1,5 +1,5 @@
-LIBUV_URL https://github.com/libuv/libuv/archive/62c2374a8c005ce9e42088965f8f8af2532c177b.tar.gz
-LIBUV_SHA256 c7e89137da65a1cb550ba96b892dfeeabea982bf33b9237bcf9bbcd90f2e70a1
+LIBUV_URL https://github.com/libuv/libuv/archive/15e81386bf9a285cada688c5faf67b3ed1319dcf.tar.gz
+LIBUV_SHA256 cd97aff8e7073fb128aef7a45e9183264ccaf07945a6cb430053070bd03ff200
MSGPACK_URL https://github.com/msgpack/msgpack-c/releases/download/c-6.0.0/msgpack-c-6.0.0.tar.gz
MSGPACK_SHA256 3654f5e2c652dc52e0a993e270bb57d5702b262703f03771c152bba51602aeba
diff --git a/cmake/FindTreesitter.cmake b/cmake/FindTreesitter.cmake
index ddea35fe66..23214283c0 100644
--- a/cmake/FindTreesitter.cmake
+++ b/cmake/FindTreesitter.cmake
@@ -7,3 +7,23 @@ mark_as_advanced(TREESITTER_LIBRARY TREESITTER_INCLUDE_DIR)
add_library(treesitter INTERFACE)
target_include_directories(treesitter SYSTEM BEFORE INTERFACE ${TREESITTER_INCLUDE_DIR})
target_link_libraries(treesitter INTERFACE ${TREESITTER_LIBRARY})
+
+# TODO(lewis6991): remove when min TS version is 0.20.9
+list(APPEND CMAKE_REQUIRED_INCLUDES "${TREESITTER_INCLUDE_DIR}")
+list(APPEND CMAKE_REQUIRED_LIBRARIES "${TREESITTER_LIBRARY}")
+check_c_source_compiles("
+#include <tree_sitter/api.h>
+int
+main(void)
+{
+ TSQueryCursor *cursor = ts_query_cursor_new();
+ ts_query_cursor_set_max_start_depth(cursor, 32);
+ return 0;
+}
+" TS_HAS_SET_MAX_START_DEPTH)
+list(REMOVE_ITEM CMAKE_REQUIRED_INCLUDES "${TREESITTER_INCLUDE_DIR}")
+list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "${TREESITTER_LIBRARY}")
+
+if(TS_HAS_SET_MAX_START_DEPTH)
+ target_compile_definitions(treesitter INTERFACE NVIM_TS_HAS_SET_MAX_START_DEPTH)
+endif()
diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt
index 175c531950..48d6aed0f2 100644
--- a/runtime/doc/filetype.txt
+++ b/runtime/doc/filetype.txt
@@ -162,6 +162,7 @@ variables can be used to overrule the filetype used for certain extensions:
*.sys g:filetype_sys
*.sh g:bash_is_sh |ft-sh-syntax|
*.tex g:tex_flavor |ft-tex-plugin|
+ *.typ g:filetype_typ
*.w g:filetype_w |ft-cweb-syntax|
For a few filetypes the global variable is used only when the filetype could
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index e07bfc2209..fc365c927b 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -942,12 +942,12 @@ start_client({config}) *vim.lsp.start_client()*
Parameters: ~
• {config} (table) Configuration for the server:
- • cmd: (table|string|fun(dispatchers: table):table) command
- string or list treated like |jobstart()|. The command must
- launch the language server process. `cmd` can also be a
- function that creates an RPC client. The function receives
- a dispatchers table and must return a table with the
- functions `request`, `notify`, `is_closing` and
+ • cmd: (string[]|fun(dispatchers: table):table) command a
+ list of strings treated like |jobstart()|. The command
+ must launch the language server process. `cmd` can also be
+ a function that creates an RPC client. The function
+ receives a dispatchers table and must return a table with
+ the functions `request`, `notify`, `is_closing` and
`terminate` See |vim.lsp.rpc.request()| and
|vim.lsp.rpc.notify()| For TCP there is a built-in rpc
client factory: |vim.lsp.rpc.connect()|
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index bc357ac534..6b1e9112c1 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -29,6 +29,7 @@ The following changes may require adaptations in user config or plugins.
set selectmode=mouse,key
set mousemodel=popup
set keymodel=startsel,stopsel
+<
==============================================================================
ADDED FEATURES *news-added*
@@ -52,6 +53,9 @@ iterators |luaref-in|.
• |'smoothscroll'| option to scroll by screen line rather than by text line
when |'wrap'| is set.
+• |Query:iter_matches()| now has the ability to set the maximum start depth
+ for matches.
+
==============================================================================
CHANGED FEATURES *news-changed*
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt
index 0168b11499..d425c8dace 100644
--- a/runtime/doc/treesitter.txt
+++ b/runtime/doc/treesitter.txt
@@ -939,7 +939,7 @@ Query:iter_captures({self}, {node}, {source}, {start}, {stop})
metadata
*Query:iter_matches()*
-Query:iter_matches({self}, {node}, {source}, {start}, {stop})
+Query:iter_matches({self}, {node}, {source}, {start}, {stop}, {opts})
Iterates the matches of self on a given range.
Iterate over all matches within a {node}. The arguments are the same as
@@ -966,6 +966,11 @@ Query:iter_matches({self}, {node}, {source}, {start}, {stop})
• {source} (integer|string) Source buffer or string to search
• {start} (integer) Starting line for the search
• {stop} (integer) Stopping line for the search (end-exclusive)
+ • {opts} (table|nil) Options:
+ • max_start_depth (integer) if non-zero, sets the maximum
+ start depth for each match. This is used to prevent
+ traversing too deep into a tree. Requires treesitter >=
+ 0.20.9.
• {self}
Return: ~
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index 5c799b23f2..c746eef1bb 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -997,7 +997,9 @@ local extension = {
spi = 'spyce',
spy = 'spyce',
tyc = 'sql',
- typ = 'sql',
+ typ = function(path, bufnr)
+ return require('vim.filetype.detect').typ(bufnr)
+ end,
pkb = 'sql',
tyb = 'sql',
pks = 'sql',
diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua
index 74b01d569c..94106a3547 100644
--- a/runtime/lua/vim/filetype/detect.lua
+++ b/runtime/lua/vim/filetype/detect.lua
@@ -1322,6 +1322,28 @@ function M.txt(bufnr)
end
end
+function M.typ(bufnr)
+ if vim.g.filetype_typ then
+ return vim.g.filetype_typ
+ end
+
+ for _, line in ipairs(getlines(bufnr, 1, 200)) do
+ if
+ findany(line, {
+ '^CASE[%s]?=[%s]?SAME$',
+ '^CASE[%s]?=[%s]?LOWER$',
+ '^CASE[%s]?=[%s]?UPPER$',
+ '^CASE[%s]?=[%s]?OPPOSITE$',
+ '^TYPE%s',
+ })
+ then
+ return 'sql'
+ end
+ end
+
+ return 'typst'
+end
+
-- Determine if a .v file is Verilog, V, or Coq
function M.v(bufnr)
if vim.fn.did_filetype() ~= 0 then
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 5c78bd7580..a724593188 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -901,8 +901,8 @@ end
--- Field `cmd` in {config} is required.
---
---@param config (table) Configuration for the server:
---- - cmd: (table|string|fun(dispatchers: table):table) command string or
---- list treated like |jobstart()|. The command must launch the language server
+--- - cmd: (string[]|fun(dispatchers: table):table) command a list of
+--- strings treated like |jobstart()|. The command must launch the language server
--- process. `cmd` can also be a function that creates an RPC client.
--- The function receives a dispatchers table and must return a table with the
--- functions `request`, `notify`, `is_closing` and `terminate`
diff --git a/runtime/lua/vim/lsp/_watchfiles.lua b/runtime/lua/vim/lsp/_watchfiles.lua
index 533a955925..3a78724d79 100644
--- a/runtime/lua/vim/lsp/_watchfiles.lua
+++ b/runtime/lua/vim/lsp/_watchfiles.lua
@@ -198,16 +198,17 @@ function M.register(reg, ctx)
end
local watch_regs = {}
for _, w in ipairs(reg.registerOptions.watchers) do
+ local relative_pattern = false
local glob_patterns = {}
if type(w.globPattern) == 'string' then
for _, folder in ipairs(client.workspace_folders) do
table.insert(glob_patterns, { baseUri = folder.uri, pattern = w.globPattern })
end
else
+ relative_pattern = true
table.insert(glob_patterns, w.globPattern)
end
for _, glob_pattern in ipairs(glob_patterns) do
- local pattern = parse(glob_pattern.pattern)
local base_dir = nil
if type(glob_pattern.baseUri) == 'string' then
base_dir = glob_pattern.baseUri
@@ -216,9 +217,16 @@ function M.register(reg, ctx)
end
assert(base_dir, "couldn't identify root of watch")
base_dir = vim.uri_to_fname(base_dir)
+
local kind = w.kind
or protocol.WatchKind.Create + protocol.WatchKind.Change + protocol.WatchKind.Delete
+ local pattern = glob_pattern.pattern
+ if relative_pattern then
+ pattern = base_dir .. '/' .. pattern
+ end
+ pattern = parse(pattern)
+
table.insert(watch_regs, {
base_dir = base_dir,
pattern = pattern,
diff --git a/runtime/lua/vim/treesitter/_meta.lua b/runtime/lua/vim/treesitter/_meta.lua
index 4d0f43d030..c1009f5f5d 100644
--- a/runtime/lua/vim/treesitter/_meta.lua
+++ b/runtime/lua/vim/treesitter/_meta.lua
@@ -31,17 +31,19 @@ local TSNode = {}
---@param query userdata
---@param captures true
----@param start integer
----@param end_ integer
+---@param start? integer
+---@param end_? integer
+---@param opts? table
---@return fun(): integer, TSNode, any
-function TSNode:_rawquery(query, captures, start, end_) end
+function TSNode:_rawquery(query, captures, start, end_, opts) end
---@param query userdata
---@param captures false
----@param start integer
----@param end_ integer
+---@param start? integer
+---@param end_? integer
+---@param opts? table
---@return fun(): string, any
-function TSNode:_rawquery(query, captures, start, end_) end
+function TSNode:_rawquery(query, captures, start, end_, opts) end
---@class TSParser
---@field parse fun(self: TSParser, tree: TSTree?, source: integer|string, include_bytes: boolean?): TSTree, integer[]
diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua
index 93841bb31e..e6a117557a 100644
--- a/runtime/lua/vim/treesitter/query.lua
+++ b/runtime/lua/vim/treesitter/query.lua
@@ -686,16 +686,20 @@ end
---@param source (integer|string) Source buffer or string to search
---@param start integer Starting line for the search
---@param stop integer Stopping line for the search (end-exclusive)
+---@param opts table|nil Options:
+--- - max_start_depth (integer) if non-zero, sets the maximum start depth
+--- for each match. This is used to prevent traversing too deep into a tree.
+--- Requires treesitter >= 0.20.9.
---
---@return (fun(): integer, table<integer,TSNode>, table): pattern id, match, metadata
-function Query:iter_matches(node, source, start, stop)
+function Query:iter_matches(node, source, start, stop, opts)
if type(source) == 'number' and source == 0 then
source = api.nvim_get_current_buf()
end
start, stop = value_or_node_range(start, stop, node)
- local raw_iter = node:_rawquery(self.query, false, start, stop)
+ local raw_iter = node:_rawquery(self.query, false, start, stop, opts)
---@cast raw_iter fun(): string, any
local function iter()
local pattern, match = raw_iter()
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index c9a46ecfa1..3bb054946f 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -292,6 +292,7 @@ set(LUA_FILETYPE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/filetype.lu
set(LUA_INIT_PACKAGES_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_init_packages.lua)
set(LUA_KEYMAP_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/keymap.lua)
set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua)
+set(LUAJIT_RUNTIME_DIR ${DEPS_PREFIX}/share/luajit-2.1.0-beta3/jit)
glob_wrapper(UNICODE_FILES ${UNICODE_DIR}/*.txt)
glob_wrapper(API_HEADERS api/*.h)
@@ -798,6 +799,15 @@ install(DIRECTORY ${BINARY_LIB_DIR}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/nvim/
USE_SOURCE_PERMISSIONS)
+if(NOT PREFER_LUA)
+ # install luajit runtime files if bundled
+ if(EXISTS ${LUAJIT_RUNTIME_DIR})
+ install(DIRECTORY ${LUAJIT_RUNTIME_DIR}
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/nvim/runtime/lua
+ USE_SOURCE_PERMISSIONS)
+ endif()
+endif()
+
add_library(libnvim STATIC EXCLUDE_FROM_ALL)
if(MSVC)
set(LIBNVIM_NAME libnvim)
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index c544daee08..8fbc5fb2ab 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -881,7 +881,7 @@ static int insert_handle_key(InsertState *s)
goto check_pum;
case K_LUA:
- map_execute_lua();
+ map_execute_lua(false);
check_pum:
// nvim_select_popupmenu_item() can be called from the handling of
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index dbfd1088d2..9a8dc9899c 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1926,6 +1926,9 @@ void do_wqall(exarg_T *eap)
int save_forceit = eap->forceit;
if (eap->cmdidx == CMD_xall || eap->cmdidx == CMD_wqall) {
+ if (before_quit_all(eap) == FAIL) {
+ return;
+ }
exiting = true;
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index adb17f2cfd..83232d5f17 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -4589,8 +4589,9 @@ static void ex_cquit(exarg_T *eap)
getout(eap->addr_count > 0 ? (int)eap->line2 : EXIT_FAILURE);
}
-/// ":qall": try to quit all windows
-static void ex_quit_all(exarg_T *eap)
+/// Do preparations for "qall" and "wqall".
+/// Returns FAIL when quitting should be aborted.
+int before_quit_all(exarg_T *eap)
{
if (cmdwin_type != 0) {
if (eap->forceit) {
@@ -4598,19 +4599,28 @@ static void ex_quit_all(exarg_T *eap)
} else {
cmdwin_result = K_XF2;
}
- return;
+ return FAIL;
}
// Don't quit while editing the command line.
if (text_locked()) {
text_locked_msg();
- return;
+ return FAIL;
}
if (before_quit_autocmds(curwin, true, eap->forceit)) {
- return;
+ return FAIL;
}
+ return OK;
+}
+
+/// ":qall": try to quit all windows
+static void ex_quit_all(exarg_T *eap)
+{
+ if (before_quit_all(eap) == FAIL) {
+ return;
+ }
exiting = true;
if (eap->forceit || !check_changed_any(false, false)) {
getout(0);
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index af2ec3356f..1345a29a21 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1140,7 +1140,7 @@ static int command_line_execute(VimState *state, int key)
} else if (s->c == K_COMMAND) {
do_cmdline(NULL, getcmdkeycmd, NULL, DOCMD_NOWAIT);
} else {
- map_execute_lua();
+ map_execute_lua(false);
}
// nvim_select_popupmenu_item() can be called from the handling of
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index ca555937ab..5c1366c5b2 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -2986,7 +2986,12 @@ char *getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
return line_ga.ga_data;
}
-bool map_execute_lua(void)
+/// Handle a Lua mapping: get its LuaRef from typeahead and execute it.
+///
+/// @param may_repeat save the LuaRef for redoing with "." later
+///
+/// @return false if getting the LuaRef was aborted, true otherwise
+bool map_execute_lua(bool may_repeat)
{
garray_T line_ga;
int c1 = -1;
@@ -3018,6 +3023,10 @@ bool map_execute_lua(void)
}
LuaRef ref = (LuaRef)atoi(line_ga.ga_data);
+ if (may_repeat) {
+ repeat_luaref = ref;
+ }
+
Error err = ERROR_INIT;
Array args = ARRAY_DICT_INIT;
nlua_call_ref(ref, NULL, args, false, &err);
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index e2f3e2aafa..cc332c530d 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -398,6 +398,15 @@ void update_window_hl(win_T *wp, bool invalid)
} else {
wp->w_hl_attr_normalnc = hl_def[HLF_INACTIVE];
}
+
+ // if blend= attribute is not set, 'winblend' value overrides it.
+ if (wp->w_floating && wp->w_p_winbl > 0) {
+ HlEntry entry = kv_A(attr_entries, wp->w_hl_attr_normalnc);
+ if (entry.attr.hl_blend == -1) {
+ entry.attr.hl_blend = (int)wp->w_p_winbl;
+ wp->w_hl_attr_normalnc = get_attr_entry(entry);
+ }
+ }
}
void update_ns_hl(int ns_id)
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index da64685a40..0c16d09b63 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -1349,6 +1349,11 @@ static int node_rawquery(lua_State *L)
} else {
cursor = ts_query_cursor_new();
}
+
+#ifdef NVIM_TS_HAS_SET_MAX_START_DEPTH
+ // reset the start depth
+ ts_query_cursor_set_max_start_depth(cursor, 0);
+#endif
ts_query_cursor_set_match_limit(cursor, 256);
ts_query_cursor_exec(cursor, query, node);
@@ -1360,6 +1365,29 @@ static int node_rawquery(lua_State *L)
ts_query_cursor_set_point_range(cursor, (TSPoint){ start, 0 }, (TSPoint){ end, 0 });
}
+ if (lua_gettop(L) >= 6 && !lua_isnil(L, 6)) {
+ if (!lua_istable(L, 6)) {
+ return luaL_error(L, "table expected");
+ }
+ lua_pushnil(L);
+ // stack: [dict, ..., nil]
+ while (lua_next(L, 6)) {
+ // stack: [dict, ..., key, value]
+ if (lua_type(L, -2) == LUA_TSTRING) {
+ char *k = (char *)lua_tostring(L, -2);
+ if (strequal("max_start_depth", k)) {
+ // TODO(lewis6991): remove ifdef when min TS version is 0.20.9
+#ifdef NVIM_TS_HAS_SET_MAX_START_DEPTH
+ uint32_t max_start_depth = (uint32_t)lua_tointeger(L, -1);
+ ts_query_cursor_set_max_start_depth(cursor, max_start_depth);
+#endif
+ }
+ }
+ lua_pop(L, 1); // pop the value; lua_next will pop the key.
+ // stack: [dict, ..., key]
+ }
+ }
+
TSLua_cursor *ud = lua_newuserdata(L, sizeof(*ud)); // [udata]
ud->cursor = cursor;
ud->predicated_match = -1;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 890fa0f80a..fa6cdb0ad8 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -3232,7 +3232,7 @@ static void nv_colon(cmdarg_T *cap)
}
if (is_lua) {
- cmd_result = map_execute_lua();
+ cmd_result = map_execute_lua(true);
} else {
// get a command line and execute it
cmd_result = do_cmdline(NULL, is_cmdkey ? getcmdkeycmd : getexline, NULL,
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index c1511ab8da..de77cdd238 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -5777,6 +5777,11 @@ typedef struct {
int rv_arg; ///< extra argument
} redo_VIsual_T;
+static bool is_ex_cmdchar(cmdarg_T *cap)
+{
+ return cap->cmdchar == ':' || cap->cmdchar == K_COMMAND;
+}
+
/// Handle an operator after Visual mode or when the movement is finished.
/// "gui_yank" is true when yanking text for the clipboard.
void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
@@ -5831,7 +5836,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
if ((redo_yank || oap->op_type != OP_YANK)
&& ((!VIsual_active || oap->motion_force)
// Also redo Operator-pending Visual mode mappings.
- || ((cap->cmdchar == ':' || cap->cmdchar == K_COMMAND)
+ || ((is_ex_cmdchar(cap) || cap->cmdchar == K_LUA)
&& oap->op_type != OP_COLON))
&& cap->cmdchar != 'D'
&& oap->op_type != OP_FOLD
@@ -5851,7 +5856,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
AppendToRedobuffLit(cap->searchbuf, -1);
}
AppendToRedobuff(NL_STR);
- } else if (cap->cmdchar == ':' || cap->cmdchar == K_COMMAND) {
+ } else if (is_ex_cmdchar(cap)) {
// do_cmdline() has stored the first typed line in
// "repeat_cmdline". When several lines are typed repeating
// won't be possible.
@@ -5866,6 +5871,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
AppendToRedobuff(NL_STR);
XFREE_CLEAR(repeat_cmdline);
}
+ } else if (cap->cmdchar == K_LUA) {
+ AppendNumberToRedobuff(repeat_luaref);
+ AppendToRedobuff(NL_STR);
}
}
@@ -6021,7 +6029,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
prep_redo(oap->regname, cap->count0,
get_op_char(oap->op_type), get_extra_op_char(oap->op_type),
oap->motion_force, cap->cmdchar, cap->nchar);
- } else if (cap->cmdchar != ':' && cap->cmdchar != K_COMMAND) {
+ } else if (!is_ex_cmdchar(cap) && cap->cmdchar != K_LUA) {
int opchar = get_op_char(oap->op_type);
int extra_opchar = get_extra_op_char(oap->op_type);
int nchar = oap->op_type == OP_REPLACE ? cap->nchar : NUL;
diff --git a/src/nvim/ops.h b/src/nvim/ops.h
index 75ea1853a0..4c5c6bafce 100644
--- a/src/nvim/ops.h
+++ b/src/nvim/ops.h
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include <stddef.h>
+#include "lauxlib.h"
#include "nvim/ascii.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
@@ -126,4 +127,7 @@ static inline int op_reg_index(const int regname)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ops.h.generated.h"
#endif
+
+EXTERN LuaRef repeat_luaref INIT(= LUA_NOREF); ///< LuaRef for "."
+
#endif // NVIM_OPS_H
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 0686305d02..0b0e321d8c 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -596,7 +596,7 @@ static int terminal_execute(VimState *state, int key)
break;
case K_LUA:
- map_execute_lua();
+ map_execute_lua(false);
break;
case Ctrl_N:
diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua
index f2817ff627..e239717d3a 100644
--- a/test/functional/api/keymap_spec.lua
+++ b/test/functional/api/keymap_spec.lua
@@ -813,19 +813,18 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
it('can make lua mappings', function()
eq(0, exec_lua [[
GlobalCount = 0
- vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
+ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
return GlobalCount
]])
feed('asdf\n')
eq(1, exec_lua[[return GlobalCount]])
-
end)
it (':map command shows lua mapping correctly', function()
exec_lua [[
- vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end })
+ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() print('jkl;') end })
]]
assert.truthy(
string.match(
@@ -837,7 +836,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
it ('mapcheck() returns lua mapping correctly', function()
exec_lua [[
- vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end })
+ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() print('jkl;') end })
]]
assert.truthy(string.match(funcs.mapcheck('asdf', 'n'),
"^<Lua %d+>"))
@@ -871,7 +870,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
it('can make lua expr mappings replacing keycodes', function()
exec_lua [[
- vim.api.nvim_set_keymap ('n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true })
+ vim.api.nvim_set_keymap('n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true })
]]
feed('aa')
@@ -881,7 +880,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
it('can make lua expr mappings without replacing keycodes', function()
exec_lua [[
- vim.api.nvim_set_keymap ('i', 'aa', '', {callback = function() return '<space>' end, expr = true })
+ vim.api.nvim_set_keymap('i', 'aa', '', {callback = function() return '<space>' end, expr = true })
]]
feed('iaa<esc>')
@@ -891,7 +890,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
it('lua expr mapping returning nil is equivalent to returning an empty string', function()
exec_lua [[
- vim.api.nvim_set_keymap ('i', 'aa', '', {callback = function() return nil end, expr = true })
+ vim.api.nvim_set_keymap('i', 'aa', '', {callback = function() return nil end, expr = true })
]]
feed('iaa<esc>')
@@ -902,17 +901,29 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
it('does not reset pum in lua mapping', function()
eq(0, exec_lua [[
VisibleCount = 0
- vim.api.nvim_set_keymap ('i', '<F2>', '', {callback = function() VisibleCount = VisibleCount + vim.fn.pumvisible() end})
+ vim.api.nvim_set_keymap('i', '<F2>', '', {callback = function() VisibleCount = VisibleCount + vim.fn.pumvisible() end})
return VisibleCount
]])
feed('i<C-X><C-V><F2><F2><esc>')
eq(2, exec_lua[[return VisibleCount]])
end)
+ it('redo of lua mappings in op-pending mode work', function()
+ eq(0, exec_lua [[
+ OpCount = 0
+ vim.api.nvim_set_keymap('o', '<F2>', '', {callback = function() OpCount = OpCount + 1 end})
+ return OpCount
+ ]])
+ feed('d<F2>')
+ eq(1, exec_lua[[return OpCount]])
+ feed('.')
+ eq(2, exec_lua[[return OpCount]])
+ end)
+
it('can overwrite lua mappings', function()
eq(0, exec_lua [[
GlobalCount = 0
- vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
+ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
return GlobalCount
]])
@@ -921,7 +932,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
eq(1, exec_lua[[return GlobalCount]])
exec_lua [[
- vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end })
+ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end })
]]
feed('asdf\n')
@@ -932,7 +943,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
it('can unmap lua mappings', function()
eq(0, exec_lua [[
GlobalCount = 0
- vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
+ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
return GlobalCount
]])
@@ -1078,7 +1089,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
it('can make lua mappings', function()
eq(0, exec_lua [[
GlobalCount = 0
- vim.api.nvim_buf_set_keymap (0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
+ vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
return GlobalCount
]])
@@ -1089,7 +1100,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
it('can make lua expr mappings replacing keycodes', function()
exec_lua [[
- vim.api.nvim_buf_set_keymap (0, 'n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true })
+ vim.api.nvim_buf_set_keymap(0, 'n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true })
]]
feed('aa')
@@ -1099,7 +1110,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
it('can make lua expr mappings without replacing keycodes', function()
exec_lua [[
- vim.api.nvim_buf_set_keymap (0, 'i', 'aa', '', {callback = function() return '<space>' end, expr = true })
+ vim.api.nvim_buf_set_keymap(0, 'i', 'aa', '', {callback = function() return '<space>' end, expr = true })
]]
feed('iaa<esc>')
@@ -1111,7 +1122,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
it('can overwrite lua mappings', function()
eq(0, exec_lua [[
GlobalCount = 0
- vim.api.nvim_buf_set_keymap (0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
+ vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
return GlobalCount
]])
@@ -1120,7 +1131,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
eq(1, exec_lua[[return GlobalCount]])
exec_lua [[
- vim.api.nvim_buf_set_keymap (0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end })
+ vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end })
]]
feed('asdf\n')
@@ -1131,7 +1142,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
it('can unmap lua mappings', function()
eq(0, exec_lua [[
GlobalCount = 0
- vim.api.nvim_buf_set_keymap (0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
+ vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
return GlobalCount
]])
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 5ba0706208..fc7b2dafb8 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -3855,7 +3855,7 @@ describe('LSP', function()
end)
it('correctly registers and unregisters', function()
- local root_dir = 'some_dir'
+ local root_dir = '/some_dir'
exec_lua(create_server_definition)
local result = exec_lua([[
local root_dir = ...
@@ -4009,10 +4009,9 @@ describe('LSP', function()
local watchers = {}
local max_kind = protocol.WatchKind.Create + protocol.WatchKind.Change + protocol.WatchKind.Delete
for i = 0, max_kind do
- local j = i
table.insert(watchers, {
globPattern = {
- baseUri = vim.uri_from_fname('/dir'..tostring(i)),
+ baseUri = vim.uri_from_fname('/dir'),
pattern = 'watch'..tostring(i),
},
kind = i,
@@ -4031,7 +4030,7 @@ describe('LSP', function()
}, { client_id = client_id })
for i = 0, max_kind do
- local filename = 'watch'..tostring(i)
+ local filename = '/dir/watch' .. tostring(i)
send_event(filename, vim._watch.FileChangeType.Created)
send_event(filename, vim._watch.FileChangeType.Changed)
send_event(filename, vim._watch.FileChangeType.Deleted)
@@ -4045,7 +4044,8 @@ describe('LSP', function()
local function watched_uri(fname)
return exec_lua([[
- return vim.uri_from_fname(...)
+ local fname = ...
+ return vim.uri_from_fname('/dir/' .. fname)
]], fname)
end
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 28c16642f1..46a079d9ff 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -8079,10 +8079,13 @@ describe('float window', function()
[6] = {foreground = tonumber('0x332533'), background = tonumber('0xfff1ff')},
[7] = {background = tonumber('0xffcfff'), bold = true, foreground = tonumber('0x0000d8')},
[8] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1},
- [9] = {background = Screen.colors.LightMagenta, blend=30},
- [10] = {foreground = Screen.colors.Red, background = Screen.colors.LightMagenta, blend=0},
- [11] = {foreground = Screen.colors.Red, background = Screen.colors.LightMagenta, blend=80},
- [12] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1, blend=30},
+ [9] = {background = Screen.colors.LightMagenta, blend = 30},
+ [10] = {foreground = Screen.colors.Red, background = Screen.colors.LightMagenta, blend = 0},
+ [11] = {foreground = Screen.colors.Red, background = Screen.colors.LightMagenta, blend = 80},
+ [12] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1, blend = 30},
+ [13] = {background = Screen.colors.LightGray, blend = 30},
+ [14] = {foreground = Screen.colors.Grey0, background = Screen.colors.Grey88},
+ [15] = {foreground = tonumber('0x939393'), background = Screen.colors.Grey88},
})
insert([[
Lorem ipsum dolor sit amet, consectetur
@@ -8184,6 +8187,58 @@ describe('float window', function()
]])
end
+ -- Check that 'winblend' works with NormalNC highlight
+ meths.set_option_value('winhighlight', 'NormalNC:Visual', {win = win})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:--------------------------------------------------]|
+ [2:--------------------------------------------------]|
+ [2:--------------------------------------------------]|
+ [2:--------------------------------------------------]|
+ [2:--------------------------------------------------]|
+ [2:--------------------------------------------------]|
+ [2:--------------------------------------------------]|
+ [2:--------------------------------------------------]|
+ [3:--------------------------------------------------]|
+ ## grid 2
+ Ut enim ad minim veniam, quis nostrud |
+ exercitation ullamco laboris nisi ut aliquip ex |
+ ea commodo consequat. Duis aute irure dolor in |
+ reprehenderit in voluptate velit esse cillum |
+ dolore eu fugiat nulla pariatur. Excepteur sint |
+ occaecat cupidatat non proident, sunt in culpa |
+ qui officia deserunt mollit anim id est |
+ laborum^. |
+ ## grid 3
+ |
+ ## grid 5
+ {13:test }|
+ {13: }|
+ {13:popup text }|
+ ]], float_pos={
+ [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50};
+ }}
+ else
+ screen:expect([[
+ Ut enim ad minim veniam, quis nostrud |
+ exercitation ullamco laboris nisi ut aliquip ex |
+ ea co{14:test}{15:o consequat}. Duis aute irure dolor in |
+ repre{15:henderit in vol}uptate velit esse cillum |
+ dolor{14:popup}{15:fugi}{14:text}{15:ul}la pariatur. Excepteur sint |
+ occaecat cupidatat non proident, sunt in culpa |
+ qui officia deserunt mollit anim id est |
+ laborum^. |
+ |
+ ]])
+ end
+
+ -- Also test with global NormalNC highlight
+ meths.set_option_value('winhighlight', '', {win = win})
+ command('hi link NormalNC Visual')
+ screen:expect_unchanged(true)
+ command('hi clear NormalNC')
+
command('hi SpecialRegion guifg=Red blend=0')
meths.buf_add_highlight(buf, -1, "SpecialRegion", 2, 0, -1)
if multigrid then
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index 6b05bd01c2..e1ae76badf 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -2,12 +2,10 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local spawn, set_session, clear = helpers.spawn, helpers.set_session, helpers.clear
local feed, command = helpers.feed, helpers.command
-local curwin = helpers.curwin
local insert = helpers.insert
local eq = helpers.eq
local eval = helpers.eval
-local funcs, meths, exec_lua = helpers.funcs, helpers.meths, helpers.exec_lua
-local is_os = helpers.is_os
+local funcs, meths = helpers.funcs, helpers.meths
describe('screen', function()
local screen
@@ -120,123 +118,6 @@ local function screen_tests(linegrid)
eq(expected, screen.title)
end)
end)
-
- it('has correct default title with unnamed file', function()
- local expected = '[No Name] - NVIM'
- command('set title')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
-
- it('has correct default title with named file', function()
- local expected = (is_os('win') and 'myfile (C:\\mydir) - NVIM' or 'myfile (/mydir) - NVIM')
- command('set title')
- command(is_os('win') and 'file C:\\mydir\\myfile' or 'file /mydir/myfile')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
-
- describe('is not changed by', function()
- local file1 = is_os('win') and 'C:\\mydir\\myfile1' or '/mydir/myfile1'
- local file2 = is_os('win') and 'C:\\mydir\\myfile2' or '/mydir/myfile2'
- local expected = (is_os('win') and 'myfile1 (C:\\mydir) - NVIM' or 'myfile1 (/mydir) - NVIM')
- local buf2
-
- before_each(function()
- command('edit '..file1)
- buf2 = funcs.bufadd(file2)
- command('set title')
- end)
-
- it('calling setbufvar() to set an option in a hidden buffer from i_CTRL-R', function()
- command([[inoremap <F2> <C-R>=setbufvar(]]..buf2..[[, '&autoindent', 1) ? '' : ''<CR>]])
- feed('i<F2><Esc>')
- command('redraw!')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
-
- it('an RPC call to nvim_buf_set_option in a hidden buffer', function()
- meths.buf_set_option(buf2, 'autoindent', true)
- command('redraw!')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
-
- it('a Lua callback calling nvim_buf_set_option in a hidden buffer', function()
- exec_lua(string.format([[
- vim.schedule(function()
- vim.api.nvim_buf_set_option(%d, 'autoindent', true)
- end)
- ]], buf2))
- command('redraw!')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
-
- it('a Lua callback calling nvim_buf_call in a hidden buffer', function()
- exec_lua(string.format([[
- vim.schedule(function()
- vim.api.nvim_buf_call(%d, function() end)
- end)
- ]], buf2))
- command('redraw!')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
-
- it('setting the buffer of another window using RPC', function()
- local oldwin = curwin().id
- command('split')
- meths.win_set_buf(oldwin, buf2)
- command('redraw!')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
-
- it('setting the buffer of another window using Lua callback', function()
- local oldwin = curwin().id
- command('split')
- exec_lua(string.format([[
- vim.schedule(function()
- vim.api.nvim_win_set_buf(%d, %d)
- end)
- ]], oldwin, buf2))
- command('redraw!')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
-
- it('creating a floating window using RPC', function()
- meths.open_win(buf2, false, {
- relative = 'editor', width = 5, height = 5, row = 0, col = 0,
- })
- command('redraw!')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
-
- it('creating a floating window using Lua callback', function()
- exec_lua(string.format([[
- vim.api.nvim_open_win(%d, false, {
- relative = 'editor', width = 5, height = 5, row = 0, col = 0,
- })
- ]], buf2))
- command('redraw!')
- screen:expect(function()
- eq(expected, screen.title)
- end)
- end)
- end)
end)
describe(':set icon', function()
diff --git a/test/functional/ui/title_spec.lua b/test/functional/ui/title_spec.lua
new file mode 100644
index 0000000000..75ead49f74
--- /dev/null
+++ b/test/functional/ui/title_spec.lua
@@ -0,0 +1,138 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear = helpers.clear
+local command = helpers.command
+local curwin = helpers.curwin
+local eq = helpers.eq
+local exec_lua = helpers.exec_lua
+local feed = helpers.feed
+local funcs = helpers.funcs
+local meths = helpers.meths
+local is_os = helpers.is_os
+
+describe('title', function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new()
+ screen:attach()
+ end)
+
+ it('has correct default title with unnamed file', function()
+ local expected = '[No Name] - NVIM'
+ command('set title')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+
+ it('has correct default title with named file', function()
+ local expected = (is_os('win') and 'myfile (C:\\mydir) - NVIM' or 'myfile (/mydir) - NVIM')
+ command('set title')
+ command(is_os('win') and 'file C:\\mydir\\myfile' or 'file /mydir/myfile')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+
+ describe('is not changed by', function()
+ local file1 = is_os('win') and 'C:\\mydir\\myfile1' or '/mydir/myfile1'
+ local file2 = is_os('win') and 'C:\\mydir\\myfile2' or '/mydir/myfile2'
+ local expected = (is_os('win') and 'myfile1 (C:\\mydir) - NVIM' or 'myfile1 (/mydir) - NVIM')
+ local buf2
+
+ before_each(function()
+ command('edit '..file1)
+ buf2 = funcs.bufadd(file2)
+ command('set title')
+ end)
+
+ it('calling setbufvar() to set an option in a hidden buffer from i_CTRL-R', function()
+ command([[inoremap <F2> <C-R>=setbufvar(]]..buf2..[[, '&autoindent', 1) ? '' : ''<CR>]])
+ feed('i<F2><Esc>')
+ command('redraw!')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+
+ it('an RPC call to nvim_buf_set_option in a hidden buffer', function()
+ meths.buf_set_option(buf2, 'autoindent', true)
+ command('redraw!')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+
+ it('a Lua callback calling nvim_buf_set_option in a hidden buffer', function()
+ exec_lua(string.format([[
+ vim.schedule(function()
+ vim.api.nvim_buf_set_option(%d, 'autoindent', true)
+ end)
+ ]], buf2))
+ command('redraw!')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+
+ it('a Lua callback calling nvim_buf_call in a hidden buffer', function()
+ exec_lua(string.format([[
+ vim.schedule(function()
+ vim.api.nvim_buf_call(%d, function() end)
+ end)
+ ]], buf2))
+ command('redraw!')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+
+ it('setting the buffer of another window using RPC', function()
+ local oldwin = curwin().id
+ command('split')
+ meths.win_set_buf(oldwin, buf2)
+ command('redraw!')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+
+ it('setting the buffer of another window using Lua callback', function()
+ local oldwin = curwin().id
+ command('split')
+ exec_lua(string.format([[
+ vim.schedule(function()
+ vim.api.nvim_win_set_buf(%d, %d)
+ end)
+ ]], oldwin, buf2))
+ command('redraw!')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+
+ it('creating a floating window using RPC', function()
+ meths.open_win(buf2, false, {
+ relative = 'editor', width = 5, height = 5, row = 0, col = 0,
+ })
+ command('redraw!')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+
+ it('creating a floating window using Lua callback', function()
+ exec_lua(string.format([[
+ vim.api.nvim_open_win(%d, false, {
+ relative = 'editor', width = 5, height = 5, row = 0, col = 0,
+ })
+ ]], buf2))
+ command('redraw!')
+ screen:expect(function()
+ eq(expected, screen.title)
+ end)
+ end)
+ end)
+end)
diff --git a/test/old/testdir/test_exit.vim b/test/old/testdir/test_exit.vim
index 6dbfb7047c..93e55ce575 100644
--- a/test/old/testdir/test_exit.vim
+++ b/test/old/testdir/test_exit.vim
@@ -81,6 +81,18 @@ func Test_exiting()
\ readfile('Xtestout'))
endif
call delete('Xtestout')
+
+ " ExitPre autocommand also executed on :wqall
+ let after =<< trim [CODE]
+ au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")
+ au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")
+ wqall
+ [CODE]
+
+ if RunVim([], after, '')
+ call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
+ endif
+ call delete('Xtestout')
endfunc
" Test for getting the Vim exit code from v:exiting
diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim
index 2d7a24090f..177a8247ac 100644
--- a/test/old/testdir/test_filetype.vim
+++ b/test/old/testdir/test_filetype.vim
@@ -564,7 +564,7 @@ let s:filename_checks = {
\ 'spice': ['file.sp', 'file.spice'],
\ 'spup': ['file.speedup', 'file.spdata', 'file.spd'],
\ 'spyce': ['file.spy', 'file.spi'],
- \ 'sql': ['file.tyb', 'file.typ', 'file.tyc', 'file.pkb', 'file.pks'],
+ \ 'sql': ['file.tyb', 'file.tyc', 'file.pkb', 'file.pks'],
\ 'sqlj': ['file.sqlj'],
\ 'prql': ['file.prql'],
\ 'sqr': ['file.sqr', 'file.sqi'],
@@ -2047,4 +2047,35 @@ func Test_lsl_file()
filetype off
endfunc
+func Test_typ_file()
+ filetype on
+
+ " SQL type file
+
+ call writefile(['CASE = LOWER'], 'Xfile.typ', 'D')
+ split Xfile.typ
+ call assert_equal('sql', &filetype)
+ bwipe!
+
+ call writefile(['TYPE foo'], 'Xfile.typ')
+ split Xfile.typ
+ call assert_equal('sql', &filetype)
+ bwipe!
+
+ " typst document
+
+ call writefile(['this is a fallback'], 'Xfile.typ')
+ split Xfile.typ
+ call assert_equal('typst', &filetype)
+ bwipe!
+
+ let g:filetype_typ = 'typst'
+ split test.typ
+ call assert_equal('typst', &filetype)
+ bwipe!
+ unlet g:filetype_typ
+
+ filetype off
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab