diff options
author | Lewis Russell <lewis6991@gmail.com> | 2023-05-17 11:42:18 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-17 11:42:18 +0100 |
commit | 189fb6203262340e7a59e782be970bcd8ae28e61 (patch) | |
tree | 2a672dcc33d1d7525850bb26e88d1758c9987a91 /src/nvim/lua/treesitter.c | |
parent | 6b19170d44ca56cf65542ee184d2bc89c6d622a9 (diff) | |
download | rneovim-189fb6203262340e7a59e782be970bcd8ae28e61.tar.gz rneovim-189fb6203262340e7a59e782be970bcd8ae28e61.tar.bz2 rneovim-189fb6203262340e7a59e782be970bcd8ae28e61.zip |
feat(treesitter): improved logging (#23638)
- Add bindings to Treesitter ts_parser_set_logger and ts_parser_logger
- Add logfile with path STDPATH('log')/treesitter.c
- Rework existing LanguageTree loggin to use logfile
- Begin implementing log levels for vim.g.__ts_debug
Diffstat (limited to 'src/nvim/lua/treesitter.c')
-rw-r--r-- | src/nvim/lua/treesitter.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 0c16d09b63..96e104cd48 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -20,6 +20,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/buffer_defs.h" #include "nvim/globals.h" +#include "nvim/lua/executor.h" #include "nvim/lua/treesitter.h" #include "nvim/macros.h" #include "nvim/map.h" @@ -43,6 +44,13 @@ typedef struct { int max_match_id; } TSLua_cursor; +typedef struct { + LuaRef cb; + lua_State *lstate; + bool lex; + bool parse; +} TSLuaLoggerOpts; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/treesitter.c.generated.h" #endif @@ -56,6 +64,8 @@ static struct luaL_Reg parser_meta[] = { { "included_ranges", parser_get_ranges }, { "set_timeout", parser_set_timeout }, { "timeout", parser_get_timeout }, + { "_set_logger", parser_set_logger }, + { "_logger", parser_get_logger }, { NULL, NULL } }; @@ -322,6 +332,12 @@ static int parser_gc(lua_State *L) return 0; } + TSLogger logger = ts_parser_logger(*p); + if (logger.log) { + TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)logger.payload; + xfree(opts); + } + ts_parser_delete(*p); return 0; } @@ -669,9 +685,82 @@ static int parser_get_timeout(lua_State *L) } lua_pushinteger(L, (long)ts_parser_timeout_micros(*p)); + return 1; +} + +static void logger_cb(void *payload, TSLogType logtype, const char *s) +{ + TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)payload; + if ((!opts->lex && logtype == TSLogTypeLex) + || (!opts->parse && logtype == TSLogTypeParse)) { + return; + } + + lua_State *lstate = opts->lstate; + + nlua_pushref(lstate, opts->cb); + lua_pushstring(lstate, logtype == TSLogTypeParse ? "parse" : "lex"); + lua_pushstring(lstate, s); + if (lua_pcall(lstate, 2, 0, 0)) { + luaL_error(lstate, "Error executing treesitter logger callback"); + } +} + +static int parser_set_logger(lua_State *L) +{ + TSParser **p = parser_check(L, 1); + if (!p) { + return 0; + } + + if (!lua_isboolean(L, 2)) { + return luaL_argerror(L, 2, "boolean expected"); + } + + if (!lua_isboolean(L, 3)) { + return luaL_argerror(L, 3, "boolean expected"); + } + + if (!lua_isfunction(L, 4)) { + return luaL_argerror(L, 4, "function expected"); + } + + TSLuaLoggerOpts *opts = xmalloc(sizeof(TSLuaLoggerOpts)); + + *opts = (TSLuaLoggerOpts){ + .lex = lua_toboolean(L, 2), + .parse = lua_toboolean(L, 3), + .cb = nlua_ref_global(L, 4), + .lstate = L + }; + + TSLogger logger = { + .payload = (void *)opts, + .log = logger_cb + }; + + ts_parser_set_logger(*p, logger); return 0; } +static int parser_get_logger(lua_State *L) +{ + TSParser **p = parser_check(L, 1); + if (!p) { + return 0; + } + + TSLogger logger = ts_parser_logger(*p); + if (logger.log) { + TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)logger.payload; + nlua_pushref(L, opts->cb); + } else { + lua_pushnil(L); + } + + return 1; +} + // Tree methods /// push tree interface on lua stack. |