diff options
Diffstat (limited to 'src/nvim/lua')
-rw-r--r-- | src/nvim/lua/executor.c | 20 | ||||
-rw-r--r-- | src/nvim/lua/spell.c | 99 | ||||
-rw-r--r-- | src/nvim/lua/spell.h | 12 | ||||
-rw-r--r-- | src/nvim/lua/stdlib.c | 11 |
4 files changed, 129 insertions, 13 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index b09d133495..107ff22913 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -404,9 +404,9 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { const char *code = (char *)&shared_module[0]; - if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/shared.lua") + if (luaL_loadbuffer(lstate, code, sizeof(shared_module) - 1, "@vim/shared.lua") || nlua_pcall(lstate, 0, 0)) { - nlua_error(lstate, _("E5106: Error while creating shared module: %.*s")); + nlua_error(lstate, _("E5106: Error while creating shared module: %.*s\n")); return 1; } } @@ -416,18 +416,18 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL lua_getfield(lstate, -1, "loaded"); // [package, loaded] const char *code = (char *)&inspect_module[0]; - if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/inspect.lua") + if (luaL_loadbuffer(lstate, code, sizeof(inspect_module) - 1, "@vim/inspect.lua") || nlua_pcall(lstate, 0, 1)) { - nlua_error(lstate, _("E5106: Error while creating inspect module: %.*s")); + nlua_error(lstate, _("E5106: Error while creating inspect module: %.*s\n")); return 1; } // [package, loaded, inspect] lua_setfield(lstate, -2, "vim.inspect"); // [package, loaded] code = (char *)&lua_F_module[0]; - if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/F.lua") + if (luaL_loadbuffer(lstate, code, sizeof(lua_F_module) - 1, "@vim/F.lua") || nlua_pcall(lstate, 0, 1)) { - nlua_error(lstate, _("E5106: Error while creating vim.F module: %.*s")); + nlua_error(lstate, _("E5106: Error while creating vim.F module: %.*s\n")); return 1; } // [package, loaded, module] @@ -438,9 +438,9 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { const char *code = (char *)&vim_module[0]; - if (luaL_loadbuffer(lstate, code, strlen(code), "@vim.lua") + if (luaL_loadbuffer(lstate, code, sizeof(vim_module) - 1, "@vim.lua") || nlua_pcall(lstate, 0, 0)) { - nlua_error(lstate, _("E5106: Error while creating vim module: %.*s")); + nlua_error(lstate, _("E5106: Error while creating vim module: %.*s\n")); return 1; } } @@ -450,9 +450,9 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL lua_getfield(lstate, -1, "loaded"); // [package, loaded] const char *code = (char *)&lua_meta_module[0]; - if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/_meta.lua") + if (luaL_loadbuffer(lstate, code, sizeof(lua_meta_module) - 1, "@vim/_meta.lua") || nlua_pcall(lstate, 0, 1)) { - nlua_error(lstate, _("E5106: Error while creating vim._meta module: %.*s")); + nlua_error(lstate, _("E5106: Error while creating vim._meta module: %.*s\n")); return 1; } // [package, loaded, module] diff --git a/src/nvim/lua/spell.c b/src/nvim/lua/spell.c new file mode 100644 index 0000000000..b84124bc19 --- /dev/null +++ b/src/nvim/lua/spell.c @@ -0,0 +1,99 @@ + +#include <lua.h> +#include <lauxlib.h> + +#include "nvim/spell.h" +#include "nvim/vim.h" +#include "nvim/lua/spell.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "lua/spell.c.generated.h" +#endif + +int nlua_spell_check(lua_State *lstate) +{ + if (lua_gettop(lstate) < 1) { + return luaL_error(lstate, "Expected 1 argument"); + } + + if (lua_type(lstate, 1) != LUA_TSTRING) { + luaL_argerror(lstate, 1, "expected string"); + } + + const char *str = lua_tolstring(lstate, 1, NULL); + + // spell.c requires that 'spell' is enabled, so we need to temporarily enable + // it before we can call spell functions. + const int wo_spell_save = curwin->w_p_spell; + + if (!curwin->w_p_spell) { + did_set_spelllang(curwin); + curwin->w_p_spell = true; + } + + // Check 'spelllang' + if (*curwin->w_s->b_p_spl == NUL) { + emsg(_(e_no_spell)); + curwin->w_p_spell = wo_spell_save; + return 0; + } + + hlf_T attr = HLF_COUNT; + size_t len = 0; + size_t pos = 0; + int capcol = -1; + int no_res = 0; + const char * result; + + lua_createtable(lstate, 0, 0); + + while (*str != NUL) { + attr = HLF_COUNT; + len = spell_check(curwin, (char_u *)str, &attr, &capcol, false); + assert(len <= INT_MAX); + + if (attr != HLF_COUNT) { + lua_createtable(lstate, 3, 0); + + lua_pushlstring(lstate, str, len); + lua_rawseti(lstate, -2, 1); + + result = attr == HLF_SPB ? "bad" : + attr == HLF_SPR ? "rare" : + attr == HLF_SPL ? "local" : + attr == HLF_SPC ? "caps" : + NULL; + + assert(result != NULL); + + lua_pushstring(lstate, result); + lua_rawseti(lstate, -2, 2); + + // +1 for 1-indexing + lua_pushinteger(lstate, (long)pos + 1); + lua_rawseti(lstate, -2, 3); + + lua_rawseti(lstate, -2, ++no_res); + } + + str += len; + pos += len; + capcol -= (int)len; + } + + // Restore 'spell' + curwin->w_p_spell = wo_spell_save; + return 1; +} + +static const luaL_Reg spell_functions[] = { + { "check", nlua_spell_check }, + { NULL , NULL } +}; + +int luaopen_spell(lua_State *L) +{ + lua_newtable(L); + luaL_register(L, NULL, spell_functions); + return 1; +} diff --git a/src/nvim/lua/spell.h b/src/nvim/lua/spell.h new file mode 100644 index 0000000000..8f798a5191 --- /dev/null +++ b/src/nvim/lua/spell.h @@ -0,0 +1,12 @@ +#ifndef NVIM_LUA_SPELL_H +#define NVIM_LUA_SPELL_H + +#include <lauxlib.h> +#include <lua.h> +#include <lualib.h> + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "lua/spell.h.generated.h" +#endif + +#endif // NVIM_LUA_SPELL_H diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index b746e03625..18a579ed0f 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -30,6 +30,7 @@ #include "nvim/lua/stdlib.h" #include "nvim/lua/treesitter.h" #include "nvim/lua/xdiff.h" +#include "nvim/lua/spell.h" #include "nvim/macros.h" #include "nvim/map.h" #include "nvim/memline.h" @@ -230,8 +231,8 @@ static int nlua_str_utf_start(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL if (offset < 0 || offset > (intptr_t)s1_len) { return luaL_error(lstate, "index out of range"); } - int tail_offset = mb_head_off((char_u *)s1, (char_u *)s1 + (char_u)offset - 1); - lua_pushinteger(lstate, tail_offset); + int head_offset = mb_head_off((char_u *)s1, (char_u *)s1 + offset - 1); + lua_pushinteger(lstate, head_offset); return 1; } @@ -250,7 +251,7 @@ static int nlua_str_utf_end(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL if (offset < 0 || offset > (intptr_t)s1_len) { return luaL_error(lstate, "index out of range"); } - int tail_offset = mb_tail_off((char_u *)s1, (char_u *)s1 + (char_u)offset - 1); + int tail_offset = mb_tail_off((char_u *)s1, (char_u *)s1 + offset - 1); lua_pushinteger(lstate, tail_offset); return 1; } @@ -518,6 +519,10 @@ void nlua_state_add_stdlib(lua_State *const lstate) lua_pushcfunction(lstate, &nlua_xdl_diff); lua_setfield(lstate, -2, "diff"); + // vim.spell + luaopen_spell(lstate); + lua_setfield(lstate, -2, "spell"); + lua_cjson_new(lstate); lua_setfield(lstate, -2, "json"); } |