feat(query): save last query based on filename

master
Steven Sojka 4 years ago
parent b073cc461a
commit 08057ffaf5

@ -4,10 +4,20 @@ local printer = require 'nvim-treesitter-playground.printer'
local utils = require 'nvim-treesitter-playground.utils'
local ts_query = require 'nvim-treesitter.query'
local pl_query = require 'nvim-treesitter-playground.query'
local Promise = require 'nvim-treesitter-playground.promise'
local api = vim.api
local luv = vim.loop
local M = {}
local fs_mkdir = Promise.promisify(luv.fs_mkdir)
local fs_open = Promise.promisify(luv.fs_open)
local fs_write = Promise.promisify(luv.fs_write)
local fs_close = Promise.promisify(luv.fs_close)
local fs_stat = Promise.promisify(luv.fs_stat)
local fs_fstat = Promise.promisify(luv.fs_fstat)
local fs_read = Promise.promisify(luv.fs_read)
M._entries = setmetatable({}, {
__index = function(tbl, key)
local entry = rawget(tbl, key)
@ -125,9 +135,51 @@ local function setup_query_editor(bufnr)
on_lines = utils.debounce(function() M.update_query(bufnr, buf) end, 1000)
})
M.read_saved_query(bufnr):then_(vim.schedule_wrap(function(lines)
if #lines > 0 then
api.nvim_buf_set_lines(buf, 0, -1, false, lines)
end
end))
return buf
end
local function get_cache_path()
return vim.fn.stdpath('cache') .. '/nvim_treesitter_playground'
end
local function get_filename(bufnr)
return vim.fn.fnamemodify(vim.fn.bufname(bufnr), ':t')
end
function M.save_query_file(bufnr, query)
local cache_path = get_cache_path()
local filename = get_filename(bufnr)
fs_stat(cache_path)
:catch(function() return fs_mkdir(cache_path, 775) end)
:then_(function() return fs_open(cache_path .. '/' .. filename .. '~', 'w', 444) end)
:then_(function(fd)
return fs_write(fd, query, -1):then_(function() return fd end)
end)
:then_(function(fd) return fs_close(fd) end)
:catch(function(err) print(err) end)
end
function M.read_saved_query(bufnr)
local cache_path = get_cache_path()
local filename = get_filename(bufnr)
local query_path = cache_path .. '/' .. filename .. '~'
return fs_open(query_path, 'r', 438)
:then_(function(fd) return fs_fstat(fd)
:then_(function(stat) return fs_read(fd, stat.size, 0) end)
:then_(function(data) return fs_close(fd)
:then_(function() return vim.split(data, '\n') end) end)
end)
:catch(function(err) return {} end)
end
function M.highlight_playground_nodes(bufnr, nodes)
local entry = M._entries[bufnr]
local results = entry.results
@ -214,6 +266,7 @@ function M.update_query(bufnr, query_bufnr)
local capture_by_color = {}
local index = 1
M.save_query_file(bufnr, query)
M._entries[bufnr].query_results = matches
M._entries[bufnr].captures = {}
M.clear_highlights(query_bufnr, query_hl_ns)

@ -0,0 +1,138 @@
local M = {}
local luv = vim.loop
function M.promisify(fn)
return function(...)
local args = {...}
return M.new(function(resolve, reject)
table.insert(args, function(err, v)
if err then return reject(err) end
resolve(v)
end)
fn(unpack(args))
end)
end
end
local function set_timeout(timeout, fn)
local timer = luv.new_timer()
timer:start(timeout, 0, function()
timer:stop()
timer:close()
fn()
end)
return timer
end
local function exec_fn(fn)
set_timeout(fn)
end
function M.new(sink)
local p = setmetatable({
result = nil,
is_resolved = false,
is_errored = false,
cbs = {},
err_cbs = {},
}, { __index = M })
p._resolve = function(v) p:_set_result(v, false) end
p._reject = function(err) p:_set_result(err, true) end
local success, err = pcall(function()
sink(p._resolve, p._reject)
end)
if not success then p._reject(err) end
return p
end
function M:then_(on_success, on_error)
local p = self
return M.new(function(resolve, reject)
table.insert(p.cbs, function(result)
if not on_success then
return resolve(result)
end
local success, res = pcall(function() resolve(on_success(result)) end)
if not success then reject(res) end
return res
end)
table.insert(p.err_cbs, function(result)
if not on_error then
return reject(result)
end
local success, res = pcall(function() resolve(on_error(result)) end)
if not success then reject(res) end
return res
end)
p:_exec_handlers()
end)
end
function M:catch(on_error)
return self:then_(nil, on_error)
end
function M:_exec_handlers()
if self.is_resolved then
for _, cb in ipairs(self.cbs) do
cb(self.result)
end
self.cbs = {}
self.err_cbs = {}
elseif self.is_errored then
for _, cb in ipairs(self.err_cbs) do
cb(self.result)
end
self.cbs = {}
self.err_cbs = {}
end
end
function M:_set_result(result, errored)
local p = self
set_timeout(0, function()
if p.is_resolved or p.is_errored then
return
end
if M.is_promise(result) then
return result:then_(p._resolve, p._reject)
end
p.result = result
if errored then
p.is_errored = true
else
p.is_resolved = true
end
p:_exec_handlers()
end)
end
function M.is_promise(v)
return type(v) == 'table' and type(v.then_) == 'function'
end
return M
Loading…
Cancel
Save