fix(treesitter): remove duplicate symbol names in language.inspect()

**Problems:**

- `vim.treesitter.language.inspect()` returns duplicate
  symbol names, sometimes up to 6 of one kind in the case of `markdown`
- The list-like `symbols` table can have holes and is thus not even a
  valid msgpack table anyway, mentioned in a test

**Solution:** Return symbols as a map, rather than a list, where field
names are the names of the symbol. The boolean value associated with the
field encodes whether or not the symbol is named.

Note that anonymous nodes are surrounded with double quotes (`"`) to
prevent potential collisions with named counterparts that have the same
identifier.
This commit is contained in:
Riley Bruins
2024-09-19 13:08:22 -07:00
committed by Christian Clason
parent 267c7525f7
commit d3193afc25
6 changed files with 42 additions and 26 deletions

View File

@@ -271,12 +271,16 @@ int tslua_inspect_lang(lua_State *L)
// not used by the API
continue;
}
lua_createtable(L, 2, 0); // [retval, symbols, elem]
lua_pushstring(L, ts_language_symbol_name(lang, (TSSymbol)i));
lua_rawseti(L, -2, 1);
lua_pushboolean(L, t == TSSymbolTypeRegular);
lua_rawseti(L, -2, 2); // [retval, symbols, elem]
lua_rawseti(L, -2, (int)i); // [retval, symbols]
const char *name = ts_language_symbol_name(lang, (TSSymbol)i);
bool named = t == TSSymbolTypeRegular;
lua_pushboolean(L, named); // [retval, symbols, is_named]
if (!named) {
char buf[256];
snprintf(buf, sizeof(buf), "\"%s\"", name);
lua_setfield(L, -2, buf); // [retval, symbols]
} else {
lua_setfield(L, -2, name); // [retval, symbols]
}
}
lua_setfield(L, -2, "symbols"); // [retval]