diff options
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 |