neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 1d4a5cd18537d054a564ff19b9361120597d9dd7
parent e69834744ba550100778890d0b4ecfc3c469af15
Author: Raphael <glephunter@gmail.com>
Date:   Tue, 12 Dec 2023 19:06:22 +0800

feat(eval): exists() function supports checking v:lua functions (#26485)

Problem:  Vimscript function exists() can't check v:lua functions.
Solution: Add support for v:lua functions to exists().
Diffstat:
Mruntime/doc/news.txt | 2++
Msrc/nvim/eval/funcs.c | 2++
Msrc/nvim/lua/executor.c | 18++++++++++++++++++
Mtest/functional/lua/vim_spec.lua | 27+++++++++++++++++++++++++++
4 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt @@ -339,6 +339,8 @@ The following changes to existing APIs or features add new behavior. • |vim.wait()| is no longer allowed to be called in |api-fast|. +• Vimscript function |exists()| supports checking |v:lua| functions. + ============================================================================== REMOVED FEATURES *news-removed* diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c @@ -1716,6 +1716,8 @@ static void f_exists(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } else { n = au_exists(p + 1); } + } else if (strncmp(p, "v:lua.", 6) == 0 && nlua_func_exists(p + 6)) { + n = true; } else { // Internal variable. n = var_exists(p); } diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c @@ -2313,3 +2313,21 @@ void nlua_init_defaults(void) os_errmsg("\n"); } } + +/// check lua function exist +bool nlua_func_exists(const char *lua_funcname) +{ + MAXSIZE_TEMP_ARRAY(args, 1); + size_t length = strlen(lua_funcname) + 8; + char *str = xmalloc(length); + vim_snprintf(str, length, "return %s", lua_funcname); + ADD_C(args, CSTR_AS_OBJ(str)); + Error err = ERROR_INIT; + Object result = NLUA_EXEC_STATIC("return type(loadstring(...)()) =='function'", args, &err); + xfree(str); + + if (result.type != kObjectTypeBoolean) { + return false; + } + return result.data.boolean; +} diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua @@ -3352,4 +3352,31 @@ describe('vim.keymap', function() eq(1, exec_lua[[return GlobalCount]]) end) + it('exists() can check a lua function', function() + eq(true, exec_lua[[ + _G.test = function() print("hello") end + return vim.fn.exists('v:lua.test') == 1 + ]]) + + eq(true, exec_lua[[ + return vim.fn.exists('v:lua.require("mpack").decode') == 1 + ]]) + + eq(true, exec_lua[[ + return vim.fn.exists("v:lua.require('vim.lsp').start") == 1 + ]]) + + eq(true, exec_lua[[ + return vim.fn.exists('v:lua.require"vim.lsp".start') == 1 + ]]) + + eq(true, exec_lua[[ + return vim.fn.exists("v:lua.require'vim.lsp'.start") == 1 + ]]) + + eq(false, exec_lua[[ + return vim.fn.exists("v:lua.require'vim.lsp'.unknown") == 1 + ]]) + end) + end)