aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/tree_sitter.lua
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2019-06-07 14:21:00 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2019-09-28 14:55:43 +0200
commit005b6d638caa200711bf5960e0c0d70ba5721c94 (patch)
treef8513f54348ab32ba8ef49646c1be0eda251aa24 /runtime/lua/vim/tree_sitter.lua
parentc07e1e8696826579f017c9b401fe264d70384ceb (diff)
downloadrneovim-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.lua47
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
+