From 3eab38d904631bc82cf29ff969b74c9552afa7c1 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Mon, 18 May 2020 18:22:53 +0300 Subject: [PATCH 1/4] Only update highlights from the first changed line --- lua/commonmarker/init.lua | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lua/commonmarker/init.lua b/lua/commonmarker/init.lua index e235009..8c6bb64 100644 --- a/lua/commonmarker/init.lua +++ b/lua/commonmarker/init.lua @@ -25,7 +25,6 @@ end local function byte2pos (byte) local line = call_function("byte2line", { byte }) - -- local col = byte - vim.api.nvim_buf_get_offset(buffer, line) local col = byte - call_function("line2byte", { line }) return line, col end @@ -36,28 +35,30 @@ local function get_contents (buffer) return table.concat(lines) end -local function highlight (buffer, namespace) +local function highlight (buffer, namespace, firstline) local contents = get_contents(buffer) local events = rust.get_offsets(contents) for _, event in ipairs(events) do - local sline, scol = byte2pos(event.first) - local eline, ecol = byte2pos(event.last) - if sline < eline then - buf_add_highlight(buffer, namespace, event.group, sline - 1, scol, -1) - sline = sline + 1 - while sline < eline do - buf_add_highlight(buffer, namespace, event.group, sline - 1, 0, -1) + repeat -- Allow continue in for loop + local sline, scol = byte2pos(event.first) + if sline < firstline then break end + local eline, ecol = byte2pos(event.last) + if sline < eline then + buf_add_highlight(buffer, namespace, event.group, sline - 1, scol, -1) sline = sline + 1 + while sline < eline do + buf_add_highlight(buffer, namespace, event.group, sline - 1, 0, -1) + sline = sline + 1 + end + buf_add_highlight(buffer, namespace, event.group, sline - 1, 0, ecol) + else + buf_add_highlight(buffer, namespace, event.group, sline - 1, scol, ecol) end - buf_add_highlight(buffer, namespace, event.group, sline - 1, 0, ecol) - else - buf_add_highlight(buffer, namespace, event.group, sline - 1, scol, ecol) - end + until true end end function commonmarker:detach (buffer) - dump(self._attachments) self._attachments[buffer] = nil buf_clear_namespace(buffer, self._namespace, 0, -1) end @@ -65,14 +66,13 @@ end function commonmarker:attach (buffer) if self._attachments[buffer] then return end self._attachments[buffer] = true - highlight(buffer, self._namespace) + highlight(buffer, self._namespace, 0) buf_attach(buffer, false, { - on_lines = function (_, _, _, _, _, _) - dump(self) - buf_clear_namespace(buffer, self._namespace, 0, -1) + on_lines = function (_, _, _, firstline, _, _) + buf_clear_namespace(buffer, self._namespace, firstline, -1) -- Returning true here detaches, we thought we should have been already if not self._attachments[buffer] then return true end - highlight(buffer, self._namespace) + highlight(buffer, self._namespace, firstline) end, on_detach = function (_) self._attachments[buffer] = nil From ab78036fac47f7667c9b7a3a0c9b966dac9bb30e Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Tue, 19 May 2020 01:31:21 +0300 Subject: [PATCH 2/4] Add rudimentry tracking to not return data before the line changed --- lua/commonmarker/init.lua | 3 ++- src/lib.rs | 5 ++++- src/lua.rs | 4 ++-- src/python.rs | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lua/commonmarker/init.lua b/lua/commonmarker/init.lua index 8c6bb64..85c67ce 100644 --- a/lua/commonmarker/init.lua +++ b/lua/commonmarker/init.lua @@ -37,7 +37,8 @@ end local function highlight (buffer, namespace, firstline) local contents = get_contents(buffer) - local events = rust.get_offsets(contents) + local firstbyte = call_function("line2byte", { firstline }) + local events = rust.get_offsets(contents, firstbyte) for _, event in ipairs(events) do repeat -- Allow continue in for loop local sline, scol = byte2pos(event.first) diff --git a/src/lib.rs b/src/lib.rs index e2e9e68..e07f1e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ struct MdTag { type Events = Vec; -fn get_offsets(buffer: String) -> Result { +fn get_offsets(buffer: String, firstbyte: usize) -> Result { let options = Options::all(); let parser = Parser::new_ext(buffer.as_str(), options); let mut events = Events::new(); @@ -35,6 +35,9 @@ fn get_offsets(buffer: String) -> Result { let first = range.start + 1; let last = range.end + 1; let mut lang = None; + if first < firstbyte { + continue; + } let group = match event { Event::Start(tag) => match tag { Tag::Heading(level) => Some(format!("cmarkHeading{}", level)), diff --git a/src/lua.rs b/src/lua.rs index bfc4fce..4066298 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -5,9 +5,9 @@ fn to_html(_: &Lua, buffer: String) -> LuaResult { Ok(super::to_html(buffer).unwrap()) } -fn get_offsets(lua: &Lua, buffer: String) -> LuaResult { +fn get_offsets(lua: &Lua, (buffer, firstbyte): (String, usize)) -> LuaResult { let table = lua.create_table().unwrap(); - let events = super::get_offsets(buffer).unwrap(); + let events = super::get_offsets(buffer, firstbyte).unwrap(); for (i, event) in events.iter().enumerate() { let info = lua.create_table().unwrap(); info.set("group", event.group.as_str()).unwrap(); diff --git a/src/python.rs b/src/python.rs index 5d42f51..7bb23c4 100644 --- a/src/python.rs +++ b/src/python.rs @@ -8,8 +8,8 @@ fn to_html(_py: Python, buffer: String) -> PyResult { } #[pyfunction] -fn get_offsets(_py: Python, buffer: String) -> PyResult<&PyDict> { - let events = super::get_offsets(buffer).unwrap(); +fn get_offsets(_py: Python, buffer: String, firstbyte: usize) -> PyResult<&PyDict> { + let events = super::get_offsets(buffer, firstbyte).unwrap(); let pyevents = PyDict::new(_py); let mut i: u32 = 1; for event in events.iter() { From 4675c1a3747ea2e634bf6e69484f4a4d22479ff3 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Tue, 19 May 2020 01:38:02 +0300 Subject: [PATCH 3/4] Add rudimentry tracking to not return data after the last line changed --- lua/commonmarker/init.lua | 13 +++++++------ src/lib.rs | 4 ++-- src/lua.rs | 7 +++++-- src/python.rs | 9 +++++++-- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lua/commonmarker/init.lua b/lua/commonmarker/init.lua index 85c67ce..04bc568 100644 --- a/lua/commonmarker/init.lua +++ b/lua/commonmarker/init.lua @@ -35,10 +35,11 @@ local function get_contents (buffer) return table.concat(lines) end -local function highlight (buffer, namespace, firstline) +local function highlight (buffer, namespace, firstline, lastline) local contents = get_contents(buffer) local firstbyte = call_function("line2byte", { firstline }) - local events = rust.get_offsets(contents, firstbyte) + local lastbyte = call_function("line2byte", { lastline + 1 }) - 1 + local events = rust.get_offsets(contents, firstbyte, lastbyte) for _, event in ipairs(events) do repeat -- Allow continue in for loop local sline, scol = byte2pos(event.first) @@ -67,13 +68,13 @@ end function commonmarker:attach (buffer) if self._attachments[buffer] then return end self._attachments[buffer] = true - highlight(buffer, self._namespace, 0) + highlight(buffer, self._namespace, 1, call_function("line", { "$" })) buf_attach(buffer, false, { - on_lines = function (_, _, _, firstline, _, _) - buf_clear_namespace(buffer, self._namespace, firstline, -1) + on_lines = function (_, _, _, firstline, lastline, _) + buf_clear_namespace(buffer, self._namespace, firstline, lastline) -- Returning true here detaches, we thought we should have been already if not self._attachments[buffer] then return true end - highlight(buffer, self._namespace, firstline) + highlight(buffer, self._namespace, firstline, lastline) end, on_detach = function (_) self._attachments[buffer] = nil diff --git a/src/lib.rs b/src/lib.rs index e07f1e8..e630d00 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ struct MdTag { type Events = Vec; -fn get_offsets(buffer: String, firstbyte: usize) -> Result { +fn get_offsets(buffer: String, firstbyte: usize, lastbyte: usize) -> Result { let options = Options::all(); let parser = Parser::new_ext(buffer.as_str(), options); let mut events = Events::new(); @@ -35,7 +35,7 @@ fn get_offsets(buffer: String, firstbyte: usize) -> Result { let first = range.start + 1; let last = range.end + 1; let mut lang = None; - if first < firstbyte { + if firstbyte > last || lastbyte < first { continue; } let group = match event { diff --git a/src/lua.rs b/src/lua.rs index 4066298..63444f3 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -5,9 +5,12 @@ fn to_html(_: &Lua, buffer: String) -> LuaResult { Ok(super::to_html(buffer).unwrap()) } -fn get_offsets(lua: &Lua, (buffer, firstbyte): (String, usize)) -> LuaResult { +fn get_offsets( + lua: &Lua, + (buffer, firstbyte, lastbyte): (String, usize, usize), +) -> LuaResult { let table = lua.create_table().unwrap(); - let events = super::get_offsets(buffer, firstbyte).unwrap(); + let events = super::get_offsets(buffer, firstbyte, lastbyte).unwrap(); for (i, event) in events.iter().enumerate() { let info = lua.create_table().unwrap(); info.set("group", event.group.as_str()).unwrap(); diff --git a/src/python.rs b/src/python.rs index 7bb23c4..77f4a6d 100644 --- a/src/python.rs +++ b/src/python.rs @@ -8,8 +8,13 @@ fn to_html(_py: Python, buffer: String) -> PyResult { } #[pyfunction] -fn get_offsets(_py: Python, buffer: String, firstbyte: usize) -> PyResult<&PyDict> { - let events = super::get_offsets(buffer, firstbyte).unwrap(); +fn get_offsets( + _py: Python, + buffer: String, + firstbyte: usize, + lastbyte: usize, +) -> PyResult<&PyDict> { + let events = super::get_offsets(buffer, firstbyte, lastbyte).unwrap(); let pyevents = PyDict::new(_py); let mut i: u32 = 1; for event in events.iter() { From 2ed3aa7d800f3cc5f48115770fcc70908e30d384 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Tue, 19 May 2020 01:39:05 +0300 Subject: [PATCH 4/4] Drop selective highlight filter from Lua, logic moving to Rust --- lua/commonmarker/init.lua | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/lua/commonmarker/init.lua b/lua/commonmarker/init.lua index 04bc568..de2d1a8 100644 --- a/lua/commonmarker/init.lua +++ b/lua/commonmarker/init.lua @@ -41,22 +41,19 @@ local function highlight (buffer, namespace, firstline, lastline) local lastbyte = call_function("line2byte", { lastline + 1 }) - 1 local events = rust.get_offsets(contents, firstbyte, lastbyte) for _, event in ipairs(events) do - repeat -- Allow continue in for loop - local sline, scol = byte2pos(event.first) - if sline < firstline then break end - local eline, ecol = byte2pos(event.last) - if sline < eline then - buf_add_highlight(buffer, namespace, event.group, sline - 1, scol, -1) + local sline, scol = byte2pos(event.first) + local eline, ecol = byte2pos(event.last) + if sline < eline then + buf_add_highlight(buffer, namespace, event.group, sline - 1, scol, -1) + sline = sline + 1 + while sline < eline do + buf_add_highlight(buffer, namespace, event.group, sline - 1, 0, -1) sline = sline + 1 - while sline < eline do - buf_add_highlight(buffer, namespace, event.group, sline - 1, 0, -1) - sline = sline + 1 - end - buf_add_highlight(buffer, namespace, event.group, sline - 1, 0, ecol) - else - buf_add_highlight(buffer, namespace, event.group, sline - 1, scol, ecol) end - until true + buf_add_highlight(buffer, namespace, event.group, sline - 1, 0, ecol) + else + buf_add_highlight(buffer, namespace, event.group, sline - 1, scol, ecol) + end end end