Initial commit

This commit is contained in:
Folkert Kevelam 2025-08-18 23:02:07 +02:00
commit 3b57f9457a
4 changed files with 372 additions and 0 deletions

View 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

View 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

View 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

View 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