Initial commit
This commit is contained in:
commit
3b57f9457a
88
lua/MarkdownPreviewer/app.lua
Normal file
88
lua/MarkdownPreviewer/app.lua
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
local msgpack = require"MarkdownPreviewer.msgpack"
|
||||
chansend = vim.fn.chansend
|
||||
|
||||
module = {}
|
||||
|
||||
local function ToUint32(data)
|
||||
local len = data
|
||||
t = {}
|
||||
for i=4,1,-1 do
|
||||
t[i] = math.fmod(len, 256)
|
||||
len = math.floor(len / 256)
|
||||
end
|
||||
return string.char(unpack(t))
|
||||
end
|
||||
|
||||
local function Message(data)
|
||||
local internal = msgpack.ToMsgPack(data)
|
||||
return ToUint32(#internal) .. internal
|
||||
end
|
||||
|
||||
app = {
|
||||
cmd = nil,
|
||||
channel = nil
|
||||
}
|
||||
|
||||
function app:init(on_exit)
|
||||
if self.channel then
|
||||
return
|
||||
end
|
||||
|
||||
local cwd = debug.getinfo(1, 'S').source:sub(2):match('(.*[/\\])')
|
||||
self.channel = vim.fn.jobstart(self.cmd, {
|
||||
cwd = cwd,
|
||||
stderr_buffered = true,
|
||||
on_exit = function()
|
||||
vim.fn.chanclose(self.channel)
|
||||
self.channel = nil
|
||||
on_exit()
|
||||
end,
|
||||
on_stderr = function(channel, data, name)
|
||||
print(vim.inspect(data))
|
||||
end,
|
||||
on_stdout = function(channel, data, name)
|
||||
print(vim.inspect(data))
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
function app:show(content)
|
||||
if self.channel == nil then
|
||||
return
|
||||
end
|
||||
|
||||
chansend(self.channel, Message({show = content}))
|
||||
end
|
||||
|
||||
function app:scroll(content)
|
||||
if self.channel == nil then
|
||||
return
|
||||
end
|
||||
|
||||
chansend(self.channel, Message({scroll = content}))
|
||||
end
|
||||
|
||||
|
||||
function app:stop()
|
||||
if self.channel then
|
||||
vim.fn.jobstop(self.channel)
|
||||
end
|
||||
end
|
||||
|
||||
function module.setup()
|
||||
o = {}
|
||||
|
||||
setmetatable(o, app)
|
||||
app.__index = app
|
||||
|
||||
o.cmd = {
|
||||
"../../Server/run.sh",
|
||||
"../../Server/venv",
|
||||
'python3',
|
||||
'../../Server/server.py'
|
||||
}
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
return module
|
||||
70
lua/MarkdownPreviewer/init.lua
Normal file
70
lua/MarkdownPreviewer/init.lua
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
local client = require"MarkdownPreviewer.app"
|
||||
local throttle = require"MarkdownPreviewer.throttle"
|
||||
|
||||
local nvim_buf_get_lines = vim.api.nvim_buf_get_lines
|
||||
local nvim_create_augroup = vim.api.nvim_create_augroup
|
||||
local nvim_create_autocmd = vim.api.nvim_create_autocmd
|
||||
local nvim_del_augroup_by_id = vim.api.nvim_del_augroup_by_id
|
||||
local concat = table.concat
|
||||
|
||||
local function get_buf_content(bufnr)
|
||||
local data = concat(nvim_buf_get_lines(bufnr, 0, -1, false), '\n'):gsub('%s*$', '')
|
||||
return data
|
||||
end
|
||||
|
||||
module = {}
|
||||
|
||||
local server_connection
|
||||
|
||||
function module.setup()
|
||||
server_connection = client.setup()
|
||||
end
|
||||
|
||||
function module.open()
|
||||
augroup = nvim_create_augroup("MarkdownPreviewActiveAugroup", {clear = true})
|
||||
|
||||
server_connection:init(function()
|
||||
augroup = nvim_del_augroup_by_id(augroup)
|
||||
end)
|
||||
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
server_connection:show(get_buf_content(bufnr))
|
||||
server_connection:scroll(vim.fn.line('.'))
|
||||
|
||||
nvim_create_autocmd("BufWritePost", {
|
||||
group = augroup,
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
server_connection:show(get_buf_content(bufnr))
|
||||
end,
|
||||
})
|
||||
|
||||
nvim_create_autocmd({"CursorMoved", "CursorMovedI"}, {
|
||||
group = augroup,
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
server_connection:scroll(vim.fn.line('.'))
|
||||
end,
|
||||
})
|
||||
|
||||
local function show()
|
||||
server_connection:show(get_buf_content(bufnr))
|
||||
end
|
||||
|
||||
nvim_create_autocmd({"TextChanged", "TextChangedI", "TextChangedP" }, {
|
||||
group = augroup,
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
throttle.run_fn(show)
|
||||
end,
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
function module.close()
|
||||
if server_connection then
|
||||
server_connection:stop()
|
||||
end
|
||||
end
|
||||
|
||||
return module
|
||||
183
lua/MarkdownPreviewer/msgpack.lua
Normal file
183
lua/MarkdownPreviewer/msgpack.lua
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
module = {}
|
||||
|
||||
local bit8 = 256
|
||||
local bit16 = 65535
|
||||
local bit32 = 4294967295
|
||||
local bit64 = 18446744070000001024
|
||||
|
||||
local function ToUint16(length)
|
||||
local len = length
|
||||
t = {}
|
||||
for i=2,1,-1 do
|
||||
t[i] = math.fmod(len,256)
|
||||
len = math.floor(len / 256)
|
||||
end
|
||||
return string.char(unpack(t))
|
||||
end
|
||||
|
||||
local function ToUint32(length)
|
||||
local len = length
|
||||
t = {}
|
||||
for i=4,1,-1 do
|
||||
t[i] = math.fmod(len,256)
|
||||
len = math.floor(len / 256)
|
||||
end
|
||||
return string.char(unpack(t))
|
||||
end
|
||||
|
||||
local function ToUint64(length)
|
||||
local len = length
|
||||
t = {}
|
||||
for i=8,1,-1 do
|
||||
t[i] = math.fmod(len,256)
|
||||
len = math.floor(len / 256)
|
||||
end
|
||||
return string.char(unpack(t))
|
||||
end
|
||||
|
||||
local function is_array(t)
|
||||
return type(t) == 'table' and (#t > 0 or next(t) == nil)
|
||||
end
|
||||
|
||||
local function NilToMsgPack()
|
||||
return string.char(0xc0)
|
||||
end
|
||||
|
||||
local function StringToMsgPack(operand)
|
||||
local str_len = #operand
|
||||
|
||||
if str_len <= 31 then
|
||||
local header = string.char(0xa0 + str_len)
|
||||
return header .. operand
|
||||
elseif str_len <= bit8 - 1 then
|
||||
local header = string.char(0xd9)
|
||||
return header .. string.char(str_len) .. operand
|
||||
elseif str_len <= bit16 - 1 then
|
||||
local header = string.char(0xda)
|
||||
return header .. ToUint16(str_len) .. operand
|
||||
elseif str_len <= bit32 - 1 then
|
||||
local header = string.char(0xdb)
|
||||
return header .. ToUint32(str_len) .. operand
|
||||
else
|
||||
print("String too large")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local function NumberToMsgPack(operand)
|
||||
if operand > 0 then
|
||||
if operand <= 127 then
|
||||
return string.char(operand)
|
||||
elseif operand <= bit8 - 1 then
|
||||
return string.char(0xcc) .. string.char(operand)
|
||||
elseif operand <= bit16 - 1 then
|
||||
return string.char(0xcd) .. ToUint16(operand)
|
||||
elseif operand <= bit32 - 1 then
|
||||
return string.char(0xce) .. ToUint32(operand)
|
||||
elseif operand <= bit64 - 1 then
|
||||
return string.char(0xcf) .. ToUint64(operand)
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local function ArrayToMsgPack(operand)
|
||||
local len = #operand
|
||||
|
||||
local data = ""
|
||||
|
||||
if len <= 15 then
|
||||
data = data .. string.char(0x90 + len)
|
||||
elseif len <= bit16 - 1 then
|
||||
data = data .. string.char(0xdc) .. ToUint16(len)
|
||||
elseif len <= bit32 - 1 then
|
||||
data = data .. string.char(0xdd) .. ToUint32(len)
|
||||
end
|
||||
|
||||
for i=1,len do
|
||||
local element = operand[i]
|
||||
if type(element) == 'nil' then
|
||||
data = data .. NilToMsgPack()
|
||||
elseif type(element) == 'number' then
|
||||
data = data .. NumberToMsgPack(element)
|
||||
elseif type(element) == 'string' then
|
||||
data = data .. StringToMsgPack(element)
|
||||
elseif type(element) == 'table' then
|
||||
if is_array(element) then
|
||||
data = data .. ArrayToMsgPack(element)
|
||||
else
|
||||
data = data .. TableToMsgPack(element)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
local function TableToMsgPack(operand)
|
||||
local len = 0
|
||||
for _,v in pairs(operand) do
|
||||
len = len + 1
|
||||
end
|
||||
|
||||
local data = ""
|
||||
|
||||
if len <= 15 then
|
||||
data = data .. string.char(0x80 + len)
|
||||
elseif len <= bit16 - 1 then
|
||||
data = data .. string.char(0xde) .. ToUint16(len)
|
||||
elseif len <= bit32 - 1 then
|
||||
data = data .. string.char(0xdf) .. ToUint32(len)
|
||||
end
|
||||
|
||||
for k,v in pairs(operand) do
|
||||
if type(k) == 'nil' then
|
||||
data = data .. NilToMsgPack()
|
||||
elseif type(k) == 'number' then
|
||||
data = data .. NumberToMsgPack(k)
|
||||
elseif type(k) == 'string' then
|
||||
data = data .. StringToMsgPack(k)
|
||||
elseif type(k) == 'table' then
|
||||
if is_array(k) then
|
||||
data = data .. ArrayToMsgPack(k)
|
||||
else
|
||||
data = data .. TableToMsgPack(k)
|
||||
end
|
||||
end
|
||||
|
||||
if type(v) == 'nil' then
|
||||
data = data .. NilToMsgPack()
|
||||
elseif type(v) == 'number' then
|
||||
data = data .. NumberToMsgPack(v)
|
||||
elseif type(v) == 'string' then
|
||||
data = data .. StringToMsgPack(v)
|
||||
elseif type(v) == 'table' then
|
||||
if is_array(v) then
|
||||
data = data .. ArrayToMsgPack(v)
|
||||
else
|
||||
data = data .. TableToMsgPack(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
function module.ToMsgPack(operand)
|
||||
if type(operand) == 'nil' then
|
||||
return NilToMsgPack()
|
||||
elseif type(operand) == 'number' then
|
||||
return NumberToMsgPack()
|
||||
elseif type(operand) == 'string' then
|
||||
return StringToMsgPack()
|
||||
elseif type(operand) == 'table' then
|
||||
if is_array(operand) then
|
||||
return ArrayToMsgPack(operand)
|
||||
else
|
||||
return TableToMsgPack(operand)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return module
|
||||
31
lua/MarkdownPreviewer/throttle.lua
Normal file
31
lua/MarkdownPreviewer/throttle.lua
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
local module = {}
|
||||
|
||||
local defer = 1000
|
||||
local throttled = false
|
||||
local fn_to_run = nil
|
||||
|
||||
local function throttle()
|
||||
if fn_to_run then
|
||||
fn_to_run()
|
||||
fn_to_run = nil
|
||||
vim.defer_fn(throttle, defer)
|
||||
else
|
||||
throttled = false
|
||||
end
|
||||
end
|
||||
|
||||
function module.run_fn(fn, args)
|
||||
if throttled == true then
|
||||
local function func()
|
||||
fn(args)
|
||||
end
|
||||
|
||||
fn_to_run = func
|
||||
else
|
||||
fn(args)
|
||||
throttled = true
|
||||
vim.defer_fn(throttle, defer)
|
||||
end
|
||||
end
|
||||
|
||||
return module
|
||||
Loading…
Reference in New Issue
Block a user