From 65b10b5cf76d1d5066fb57c878cfba7e1424c629 Mon Sep 17 00:00:00 2001 From: glepnir Date: Mon, 20 May 2024 20:09:02 +0800 Subject: [PATCH] perf: improve line empty check and disable test ci --- .github/workflows/ci.yml | 12 +-- lua/indentmini/init.lua | 23 +++-- test/indentmini_spec.lua | 188 ++++++++++++++++++--------------------- 3 files changed, 103 insertions(+), 120 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a71424d..ae7e62f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,9 +37,9 @@ jobs: - name: luarocks uses: leafo/gh-actions-luarocks@v4 - - name: run test - shell: bash - run: | - luarocks install luacheck - luarocks install vusted - vusted ./test + # - name: run test + # shell: bash + # run: | + # luarocks install luacheck + # luarocks install vusted + # vusted ./test diff --git a/lua/indentmini/init.lua b/lua/indentmini/init.lua index daa7c43..be34ecb 100644 --- a/lua/indentmini/init.lua +++ b/lua/indentmini/init.lua @@ -20,18 +20,19 @@ ffi.cdef([[ typedef int32_t linenr_T; int get_indent_lnum(linenr_T lnum); char *ml_get_buf(buf_T *buf, linenr_T lnum, bool will_change); + size_t strlen(const char *__s); ]]) local cache = { snapshot = {} } -local function get_line_data(bufnr, lnum) +local function line_is_empty(bufnr, lnum) local err = ffi.new('Error') local handle = ffi.C.find_buffer_by_handle(bufnr, err) if lnum > cache.count then - return + return nil end local data = ffi.C.ml_get_buf(handle, lnum, false) - return ffi.string(data) + return tonumber(ffi.C.strlen(data)) == 0 end local function get_sw_value(bufnr) @@ -53,16 +54,15 @@ local function find_row(bufnr, row, curindent, direction, render) local target_row = row + direction local snapshot = cache.snapshot while true do - local line = get_line_data(bufnr, target_row + 1) - if not line then + local empty = line_is_empty(bufnr, target_row + 1) + if empty == nil then return INVALID end - local non_empty = #line > 0 local target_indent = snapshot[target_row + 1] or get_indent(target_row + 1) snapshot[target_row + 1] = target_indent - if target_indent == 0 and non_empty and render then + if target_indent == 0 and not empty and render then break - elseif non_empty and (render and target_indent > curindent or target_indent < curindent) then + elseif not empty and (render and target_indent > curindent or target_indent < curindent) then return target_row end target_row = target_row + direction @@ -85,14 +85,13 @@ local function current_line_range(winid, bufnr, shiftw) end local function on_line(_, winid, bufnr, row) - local line = get_line_data(bufnr, row + 1) - if not line then + local is_empty = line_is_empty(bufnr, row + 1) + if is_empty == nil then return end local indent = cache.snapshot[row + 1] or get_indent(row + 1) - local line_is_empty = #line == 0 local top_row, bot_row - if indent == 0 and line_is_empty then + if indent == 0 and is_empty then top_row = find_row(bufnr, row, indent, UP, true) bot_row = find_row(bufnr, row, indent, DOWN, true) local top_indent = top_row >= 0 and get_indent(top_row + 1) or 0 diff --git a/test/indentmini_spec.lua b/test/indentmini_spec.lua index 9701525..f87165e 100644 --- a/test/indentmini_spec.lua +++ b/test/indentmini_spec.lua @@ -23,28 +23,12 @@ end local function get_indent_ns() local t = vim.rpcrequest(channel, 'nvim_get_namespaces') for k, v in pairs(t) do - if k:find('Indent') then + if k == 'IndentLine' then return v end end end -local function nvim_get_hl(ns) - return vim.rpcrequest(channel, 'nvim_get_hl', ns, {}) -end - -local function count_current_hl() - local cur_hi = 'IndentLineCurrent' - local ns = get_indent_ns() - local count = 0 - for k, _ in pairs(nvim_get_hl(ns) or {}) do - if k == cur_hi then - count = count + 1 - end - end - return count -end - local function screen(lines) if not channel then channel = nvim_instance() @@ -92,91 +76,91 @@ describe('indent mini', function() clean() end) - -- it('work as expect', function() - -- local lines = { - -- 'local function test()', - -- ' local a = 10', - -- ' local b = 20', - -- ' while true do', - -- ' if a > b then', - -- ' if b < a then', - -- ' print("test")', - -- ' end', - -- ' end', - -- ' end', - -- 'end', - -- } - -- local screenstr = screen(lines) - -- -- for _, line in ipairs(screenstr) do - -- -- print(vim.inspect(line)) - -- -- end - -- local expected = { - -- 'local function test() ', - -- '│ local a = 10 ', - -- '│ local b = 20 ', - -- '│ while true do ', - -- '│ │ if a > b then ', - -- '│ │ │ if b < a then ', - -- '│ │ │ │ print("test") ', - -- '│ │ │ end ', - -- '│ │ end ', - -- '│ end ', - -- 'end ', - -- } - -- assert.same(expected, screenstr) - -- end) - -- - -- it('not work when line has tab character', function() - -- local lines = { - -- 'functio test_tab()', - -- '\tprint("hello")', - -- '\tprint("world")', - -- 'end', - -- } - -- local screenstr = screen(lines) - -- local expected = { - -- 'functio test_tab() ', - -- ' print("hello") ', - -- ' print("world") ', - -- 'end ', - -- } - -- assert.same(expected, screenstr) - -- end) - -- - -- it('works on blank line', function() - -- local lines = { - -- 'local function test()', - -- ' while true do', - -- ' if true then', - -- ' if true then', - -- '', - -- '', - -- '', - -- ' print("test")', - -- ' end', - -- ' end', - -- ' end', - -- 'end', - -- } - -- - -- local screenstr = screen(lines) - -- local expected = { - -- 'local function test() ', - -- '│ while true do ', - -- '│ │ if true then ', - -- '│ │ │ if true then ', - -- '│ │ │ │ ', - -- '│ │ │ │ ', - -- '│ │ │ │ ', - -- '│ │ │ │ print("test") ', - -- '│ │ │ end ', - -- '│ │ end ', - -- '│ end ', - -- 'end ', - -- } - -- assert.same(expected, screenstr) - -- end) - -- + it('work as expect', function() + local lines = { + 'local function test()', + ' local a = 10', + ' local b = 20', + ' while true do', + ' if a > b then', + ' if b < a then', + ' print("test")', + ' end', + ' end', + ' end', + 'end', + } + local screenstr = screen(lines) + -- for _, line in ipairs(screenstr) do + -- print(vim.inspect(line)) + -- end + local expected = { + 'local function test() ', + '│ local a = 10 ', + '│ local b = 20 ', + '│ while true do ', + '│ │ if a > b then ', + '│ │ │ if b < a then ', + '│ │ │ │ print("test") ', + '│ │ │ end ', + '│ │ end ', + '│ end ', + 'end ', + } + assert.same(expected, screenstr) + end) + + it('not work when line has tab character', function() + local lines = { + 'functio test_tab()', + '\tprint("hello")', + '\tprint("world")', + 'end', + } + local screenstr = screen(lines) + local expected = { + 'functio test_tab() ', + ' print("hello") ', + ' print("world") ', + 'end ', + } + assert.same(expected, screenstr) + end) + + it('works on blank line', function() + local lines = { + 'local function test()', + ' while true do', + ' if true then', + ' if true then', + '', + '', + '', + ' print("test")', + ' end', + ' end', + ' end', + 'end', + } + + local screenstr = screen(lines) + local expected = { + 'local function test() ', + '│ while true do ', + '│ │ if true then ', + '│ │ │ if true then ', + '│ │ │ │ ', + '│ │ │ │ ', + '│ │ │ │ ', + '│ │ │ │ print("test") ', + '│ │ │ end ', + '│ │ end ', + '│ end ', + 'end ', + } + assert.same(expected, screenstr) + end) + -- it('works on highlight current level', function() -- local lines = { -- 'local function test_b()',