// lua bindings for treesitter.
// NB: this file mostly contains a generic lua interface for treesitter
// trees and nodes, and could be broken out as a reusable lua package
#include <assert.h>
#include <ctype.h>
#include <lauxlib.h>
#include <limits.h>
#include <lua.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tree_sitter/api.h>
#include <uv.h>
#include "klib/kvec.h"
#include "nvim/api/private/helpers.h"
#include "nvim/buffer_defs.h"
#include "nvim/globals.h"
#include "nvim/lua/treesitter.h"
#include "nvim/macros_defs.h"
#include "nvim/map_defs.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/pos_defs.h"
#include "nvim/strings.h"
#include "nvim/types_defs.h"
#define TS_META_PARSER "treesitter_parser"
#define TS_META_TREE "treesitter_tree"
#define TS_META_NODE "treesitter_node"
#define TS_META_QUERY "treesitter_query"
#define TS_META_QUERYCURSOR "treesitter_querycursor"
#define TS_META_QUERYMATCH "treesitter_querymatch"
#define TS_META_TREECURSOR "treesitter_treecursor"
typedef struct {
LuaRef cb;
lua_State *lstate;
bool lex;
bool parse;
} TSLuaLoggerOpts;
typedef struct {
TSTree *tree;
} TSLuaTree;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "lua/treesitter.c.generated.h"
#endif
static PMap(cstr_t) langs = MAP_INIT;
// TSLanguage
int tslua_has_language(lua_State *L)
{
const char *lang_name = luaL_checkstring(L, 1);
lua_pushboolean(L, map_has(cstr_t, &langs, lang_name));
return 1;
}
static TSLanguage *load_language(lua_State *L, const char *path, const char *lang_name,
const char *symbol)
{
uv_lib_t lib;
if (uv_dlopen(path, &lib)) {
uv_dlclose(&lib);
luaL_error(L, "Failed to load parser for language '%s': uv_dlopen: %s",
lang_name, uv_dlerror(&lib));
}
char symbol_buf[128];
snprintf(symbol_buf, sizeof(symbol_buf), "tree_sitter_%s", symbol);
TSLanguage *(*lang_parser)(void);
if (uv_dlsym(&lib, symbol_buf, (void **)&lang_parser)) {
uv_dlclose(&lib);
luaL_error(L, "Failed to load parser: uv_dlsym: %s
|