diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2019-06-07 14:21:00 +0200 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2019-09-28 14:55:43 +0200 |
commit | 005b6d638caa200711bf5960e0c0d70ba5721c94 (patch) | |
tree | f8513f54348ab32ba8ef49646c1be0eda251aa24 /runtime/lua/vim/tree_sitter.lua | |
parent | c07e1e8696826579f017c9b401fe264d70384ceb (diff) | |
download | rneovim-005b6d638caa200711bf5960e0c0d70ba5721c94.tar.gz rneovim-005b6d638caa200711bf5960e0c0d70ba5721c94.tar.bz2 rneovim-005b6d638caa200711bf5960e0c0d70ba5721c94.zip |
tree-sitter: split tree-sitter lua interface from demo code
Diffstat (limited to 'runtime/lua/vim/tree_sitter.lua')
-rw-r--r-- | runtime/lua/vim/tree_sitter.lua | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/runtime/lua/vim/tree_sitter.lua b/runtime/lua/vim/tree_sitter.lua new file mode 100644 index 0000000000..a4cb3f3db6 --- /dev/null +++ b/runtime/lua/vim/tree_sitter.lua @@ -0,0 +1,47 @@ +local a = vim.api + +function parse_tree(tsstate, force) + if tsstate.valid and not force then + return tsstate.tree + end + tsstate.tree = tsstate.parser:parse_buf(tsstate.bufnr) + tsstate.valid = true + return tsstate.tree +end + +local function change_cb(tsstate, ev, bufnr, tick, start_row, oldstopline, stop_row) + local start_byte = a.nvim_buf_get_offset(bufnr,start_row) + -- a bit messy, should we expose edited but not reparsed tree? + -- are multiple edits safe in general? + local root = tsstate.parser:tree():root() + -- TODO: add proper lookup function! + local inode = root:descendant_for_point_range(oldstopline+9000,0, oldstopline,0) + if inode == nil then + local stop_byte = a.nvim_buf_get_offset(bufnr,stop_row) + tsstate.parser:edit(start_byte,stop_byte,stop_byte,start_row,0,stop_row,0,stop_row,0) + else + local fakeoldstoprow, fakeoldstopcol, fakebyteoldstop = inode:start() + local fake_rows = fakeoldstoprow-oldstopline + local fakestop = stop_row+fake_rows + local fakebytestop = a.nvim_buf_get_offset(bufnr,fakestop)+fakeoldstopcol + tsstate.parser:edit(start_byte,fakebyteoldstop,fakebytestop,start_row,0,fakeoldstoprow,fakeoldstopcol,fakestop,fakeoldstopcol) + end + tsstate.valid = false +end + +function create_parser(bufnr) + if bufnr == 0 then + bufnr = a.nvim_get_current_buf() + end + local ft = a.nvim_buf_get_option(bufnr, "filetype") + local tsstate = {} + tsstate.bufnr = bufnr + tsstate.parser = vim.ts_parser(ft.."_parser.so", ft) + parse_tree(tsstate) + local function cb(ev, ...) + return change_cb(tsstate, ev, ...) + end + a.nvim_buf_attach(tsstate.bufnr, false, {on_lines=cb}) + return tsstate +end + |