From 776c98086a4807623a3bbff374a6a165310b9f68 Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Wed, 29 May 2024 21:22:41 +1200 Subject: [PATCH 01/12] feat: support "prio" priorty value for gutter marks --- lua/precognition/init.lua | 58 +++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/lua/precognition/init.lua b/lua/precognition/init.lua index 234370c..1340bc5 100644 --- a/lua/precognition/init.lua +++ b/lua/precognition/init.lua @@ -180,31 +180,47 @@ local function apply_gutter_hints(gutter_hints, bufnr) if utils.is_blacklisted_buffer(bufnr) then return end + + local line_table = {} for hint, loc in pairs(gutter_hints) do - if config.gutterHints[hint] and loc ~= 0 and loc ~= nil then - if gutter_signs_cache[hint] then - vim.fn.sign_unplace(gutter_group, { id = gutter_signs_cache[hint].id }) - gutter_signs_cache[hint] = nil - end - vim.fn.sign_define(gutter_name_prefix .. hint, { - text = config.gutterHints[hint].text, - texthl = "PrecognitionHighlight", - }) - local ok, res = pcall(vim.fn.sign_place, 0, gutter_group, gutter_name_prefix .. hint, bufnr, { - lnum = loc, - priority = 100, - }) - if ok then - gutter_signs_cache[hint] = { line = loc, id = res } - end - if not ok and loc ~= 0 then - vim.notify_once( - "Failed to place sign: " .. hint .. " at line " .. loc .. vim.inspect(res), - vim.log.levels.WARN - ) + if gutter_signs_cache[hint] then + vim.fn.sign_unplace(gutter_group, { id = gutter_signs_cache[hint].id }) + gutter_signs_cache[hint] = nil + end + + local prio = config.gutterHints[hint].prio + + -- Build table of valid and priorised gutter hints. + if loc ~= 0 and loc ~= nil and prio > 0 then + local existing = line_table[loc] + if not existing or existing.prio < prio then + line_table[loc] = { hint = hint, prio = prio } end end end + + -- Only render valid and prioritised gutter hints. + for loc, data in pairs(line_table) do + local hint = data.hint + local sign_name = gutter_name_prefix .. hint + vim.fn.sign_define(sign_name, { + text = config.gutterHints[hint].text, + texthl = "PrecognitionHighlight", + }) + local ok, res = pcall(vim.fn.sign_place, 0, gutter_group, sign_name, bufnr, { + lnum = loc, + priority = 100, + }) + if ok then + gutter_signs_cache[hint] = { line = loc, id = res } + end + if not ok and loc ~= 0 then + vim.notify_once( + "Failed to place sign: " .. hint .. " at line " .. loc .. vim.inspect(res), + vim.log.levels.WARN + ) + end + end end local function display_marks() From 912ccf3dfbb2108b05c3feb95c5853b69db88ab2 Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Wed, 29 May 2024 21:29:10 +1200 Subject: [PATCH 02/12] Update docs. --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 06bf475..ae60eea 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ return { -- E = { text = "E", prio = 5 }, -- }, -- gutterHints = { - -- -- prio is not currently used for gutter hints -- G = { text = "G", prio = 1 }, -- gg = { text = "gg", prio = 1 }, -- PrevParagraph = { text = "{", prio = 1 }, @@ -47,11 +46,11 @@ return { ## ⚙️ Config -- Items can be hidden by settings their priority to 0, if you want to hide the - entire virtual line. Set all elements to `prio = 0` in combination with the - below. +- Items can be hidden by setting their priority to 0. If you want to hide the + entire virtual line, set all elements to `prio = 0` in combination with the + below. Gutter marks can also be hidden by setting `prio = 0`. - `showBlankVirtLine = false` - Setting this option will mean that if a Virtual Line would be blank it wont be + Setting this option will mean that if a Virtual Line would be blank it won't be rendered - highlightColor can be set in two ways: From 108b9d4577a9f353b3ab69766ea3970ec519862a Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Thu, 30 May 2024 18:26:44 +1200 Subject: [PATCH 03/12] Address code review issues. --- README.md | 3 ++- lua/precognition/init.lua | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ae60eea..f2f2cd2 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,8 @@ return { - Items can be hidden by setting their priority to 0. If you want to hide the entire virtual line, set all elements to `prio = 0` in combination with the - below. Gutter marks can also be hidden by setting `prio = 0`. + below. +- Gutter marks can also be hidden by setting `prio = 0`. - `showBlankVirtLine = false` Setting this option will mean that if a Virtual Line would be blank it won't be rendered diff --git a/lua/precognition/init.lua b/lua/precognition/init.lua index 1340bc5..e7479e3 100644 --- a/lua/precognition/init.lua +++ b/lua/precognition/init.lua @@ -181,7 +181,7 @@ local function apply_gutter_hints(gutter_hints, bufnr) return end - local line_table = {} + local gutter_table = {} for hint, loc in pairs(gutter_hints) do if gutter_signs_cache[hint] then vim.fn.sign_unplace(gutter_group, { id = gutter_signs_cache[hint].id }) @@ -192,15 +192,15 @@ local function apply_gutter_hints(gutter_hints, bufnr) -- Build table of valid and priorised gutter hints. if loc ~= 0 and loc ~= nil and prio > 0 then - local existing = line_table[loc] + local existing = gutter_table[loc] if not existing or existing.prio < prio then - line_table[loc] = { hint = hint, prio = prio } + gutter_table[loc] = { hint = hint, prio = prio } end end end -- Only render valid and prioritised gutter hints. - for loc, data in pairs(line_table) do + for loc, data in pairs(gutter_table) do local hint = data.hint local sign_name = gutter_name_prefix .. hint vim.fn.sign_define(sign_name, { From 26129cc80430f126f91ec4e55d6bcf00993c6ae1 Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Thu, 30 May 2024 18:29:02 +1200 Subject: [PATCH 04/12] Improve docs. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f2f2cd2..c6bc6e2 100644 --- a/README.md +++ b/README.md @@ -46,14 +46,14 @@ return { ## ⚙️ Config -- Items can be hidden by setting their priority to 0. If you want to hide the +- `hints` can be hidden by setting their priority to 0. If you want to hide the entire virtual line, set all elements to `prio = 0` in combination with the below. -- Gutter marks can also be hidden by setting `prio = 0`. - `showBlankVirtLine = false` Setting this option will mean that if a Virtual Line would be blank it won't be rendered -- highlightColor can be set in two ways: +- `gutterHints` can be hidden by setting their priority to 0. +- `highlightColor` can be set in two ways: 1. As a table containing a link property pointing to an existing highlight group (see `:highlight` for valid options). 2. As a table specifying custom highlight values, such as foreground and background colors. ([more info]()) From b4a70a9e969c96f93dfdbc2d70be130d5d153bf9 Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Thu, 30 May 2024 18:41:05 +1200 Subject: [PATCH 05/12] Adjust default gutter hint priorities. --- README.md | 8 ++++---- lua/precognition/init.lua | 9 ++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c6bc6e2..c766d59 100644 --- a/README.md +++ b/README.md @@ -35,10 +35,10 @@ return { -- E = { text = "E", prio = 5 }, -- }, -- gutterHints = { - -- G = { text = "G", prio = 1 }, - -- gg = { text = "gg", prio = 1 }, - -- PrevParagraph = { text = "{", prio = 1 }, - -- NextParagraph = { text = "}", prio = 1 }, + -- G = { text = "G", prio = 10 }, + -- gg = { text = "gg", prio = 9 }, + -- PrevParagraph = { text = "{", prio = 8 }, + -- NextParagraph = { text = "}", prio = 8 }, -- }, }, } diff --git a/lua/precognition/init.lua b/lua/precognition/init.lua index e7479e3..2f0c9db 100644 --- a/lua/precognition/init.lua +++ b/lua/precognition/init.lua @@ -79,11 +79,10 @@ local default = { highlightColor = { link = "Comment" }, hints = defaultHintConfig, gutterHints = { - --prio is not currentlt used for gutter hints - G = { text = "G", prio = 1 }, - gg = { text = "gg", prio = 1 }, - PrevParagraph = { text = "{", prio = 1 }, - NextParagraph = { text = "}", prio = 1 }, + G = { text = "G", prio = 10 }, + gg = { text = "gg", prio = 9 }, + PrevParagraph = { text = "{", prio = 8 }, + NextParagraph = { text = "}", prio = 8 }, }, } From fdaa5feecdd0c155b99fa7bde305e6341777178a Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Thu, 30 May 2024 20:17:28 +1200 Subject: [PATCH 06/12] Failed attempt a a gutter hint priority test. --- lua/precognition/init.lua | 3 ++ tests/precognition/gutter_hints_spec.lua | 67 ++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/lua/precognition/init.lua b/lua/precognition/init.lua index 2f0c9db..b72f75f 100644 --- a/lua/precognition/init.lua +++ b/lua/precognition/init.lua @@ -410,6 +410,9 @@ local state = { build_gutter_hints = function() return build_gutter_hints end, + apply_gutter_hints = function() + return apply_gutter_hints + end, on_cursor_moved = function() return on_cursor_moved end, diff --git a/tests/precognition/gutter_hints_spec.lua b/tests/precognition/gutter_hints_spec.lua index 5db1f0c..9b5b259 100644 --- a/tests/precognition/gutter_hints_spec.lua +++ b/tests/precognition/gutter_hints_spec.lua @@ -140,3 +140,70 @@ describe("Gutter hints table", function() }, hints) end) end) + +local function dump(o) + if type(o) == 'table' then + local s = '{ ' + for k,v in pairs(o) do + if type(k) ~= 'number' then k = '"'..k..'"' end + s = s .. '['..k..'] = ' .. dump(v) .. ',' + end + return s .. '} ' + else + return tostring(o) + end +end + +describe("Priority", function() + it("0 priority item is not added", function() + precognition.setup({ + ---@diagnostic disable-next-line: missing-fields + gutterHints = { + G = { text = "G", prio = 0 }, + gg = { text = "gg", prio = 9 }, + PrevParagraph = { text = "{", prio = 8 }, + NextParagraph = { text = "}", prio = 8 }, + } + }) + + local testBuf = vim.api.nvim_create_buf(true, true) + vim.api.nvim_buf_set_name(testBuf, "foo") + + vim.api.nvim_buf_set_lines(testBuf, 0, -1, false, { + "ABC", + "DEF", + "", + "GHI", + "", + "JKL", + "", + "MNO", + }) + + local hints = precognition.build_gutter_hints(testBuf) + precognition.apply_gutter_hints(hints, testBuf) + + local def = vim.fn.sign_getdefined("precognition_gutter_PrevParagraph") + print("def") + print(dump(def)) + + local gutter_group = "precognition_gutter" + local buf_name = vim.fn.bufname(testBuf) + print("buf name " .. buf_name) + local placed = vim.fn.sign_getplaced("foo", { group = "*" }) + + print("placed") + print(dump(placed)) + print(placed[1].signs[1]) + for _, g in ipairs(placed[1].signs) do + print(g.name) + end + -- print("hints g is `" .. precognition.gutter_signs_cache["G"] .. "`") + -- eq({ + -- ["gg"] = 1, + -- PrevParagraph = 3, + -- NextParagraph = 5, + -- ["G"] = 8, + -- }, hints) + end) +end) From 7d0a1a0461a81422da5fd9fcbc6574c37d00d175 Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Thu, 30 May 2024 20:21:27 +1200 Subject: [PATCH 07/12] Fix style formatting. --- lua/precognition/init.lua | 2 +- tests/precognition/gutter_hints_spec.lua | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lua/precognition/init.lua b/lua/precognition/init.lua index b72f75f..6bd248e 100644 --- a/lua/precognition/init.lua +++ b/lua/precognition/init.lua @@ -411,7 +411,7 @@ local state = { return build_gutter_hints end, apply_gutter_hints = function() - return apply_gutter_hints + return apply_gutter_hints end, on_cursor_moved = function() return on_cursor_moved diff --git a/tests/precognition/gutter_hints_spec.lua b/tests/precognition/gutter_hints_spec.lua index 9b5b259..cc6d2b3 100644 --- a/tests/precognition/gutter_hints_spec.lua +++ b/tests/precognition/gutter_hints_spec.lua @@ -142,16 +142,16 @@ describe("Gutter hints table", function() end) local function dump(o) - if type(o) == 'table' then - local s = '{ ' - for k,v in pairs(o) do - if type(k) ~= 'number' then k = '"'..k..'"' end - s = s .. '['..k..'] = ' .. dump(v) .. ',' - end - return s .. '} ' - else - return tostring(o) - end + if type(o) == 'table' then + local s = '{ ' + for k,v in pairs(o) do + if type(k) ~= 'number' then k = '"'..k..'"' end + s = s .. '['..k..'] = ' .. dump(v) .. ',' + end + return s .. '} ' + else + return tostring(o) + end end describe("Priority", function() From f1580812165be605716c57b8d3c77e77d43be23b Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Thu, 30 May 2024 20:24:48 +1200 Subject: [PATCH 08/12] Fix style formatting. --- tests/precognition/gutter_hints_spec.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/precognition/gutter_hints_spec.lua b/tests/precognition/gutter_hints_spec.lua index cc6d2b3..95d1207 100644 --- a/tests/precognition/gutter_hints_spec.lua +++ b/tests/precognition/gutter_hints_spec.lua @@ -144,10 +144,10 @@ end) local function dump(o) if type(o) == 'table' then local s = '{ ' - for k,v in pairs(o) do - if type(k) ~= 'number' then k = '"'..k..'"' end - s = s .. '['..k..'] = ' .. dump(v) .. ',' - end + for k,v in pairs(o) do + if type(k) ~= 'number' then k = '"'..k..'"' end + s = s .. '['..k..'] = ' .. dump(v) .. ',' + end return s .. '} ' else return tostring(o) From 5068348c2018ebd5288bcfd1985a1167ec586bec Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Thu, 30 May 2024 20:30:19 +1200 Subject: [PATCH 09/12] Get stylua working. --- tests/precognition/gutter_hints_spec.lua | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/precognition/gutter_hints_spec.lua b/tests/precognition/gutter_hints_spec.lua index 95d1207..20d9a1a 100644 --- a/tests/precognition/gutter_hints_spec.lua +++ b/tests/precognition/gutter_hints_spec.lua @@ -142,13 +142,15 @@ describe("Gutter hints table", function() end) local function dump(o) - if type(o) == 'table' then - local s = '{ ' - for k,v in pairs(o) do - if type(k) ~= 'number' then k = '"'..k..'"' end - s = s .. '['..k..'] = ' .. dump(v) .. ',' + if type(o) == "table" then + local s = "{ " + for k, v in pairs(o) do + if type(k) ~= "number" then + k = '"' .. k .. '"' + end + s = s .. "[" .. k .. "] = " .. dump(v) .. "," end - return s .. '} ' + return s .. "} " else return tostring(o) end @@ -163,7 +165,7 @@ describe("Priority", function() gg = { text = "gg", prio = 9 }, PrevParagraph = { text = "{", prio = 8 }, NextParagraph = { text = "}", prio = 8 }, - } + }, }) local testBuf = vim.api.nvim_create_buf(true, true) From bd13fd9ea22d9e61aada1a00eab90faef068856f Mon Sep 17 00:00:00 2001 From: tris203 Date: Thu, 30 May 2024 15:52:35 +0100 Subject: [PATCH 10/12] tests: add tests --- tests/precognition/e2e_spec.lua | 62 ++++++++++++++++++++++++ tests/precognition/gutter_hints_spec.lua | 54 --------------------- 2 files changed, 62 insertions(+), 54 deletions(-) diff --git a/tests/precognition/e2e_spec.lua b/tests/precognition/e2e_spec.lua index dec6d34..242839e 100644 --- a/tests/precognition/e2e_spec.lua +++ b/tests/precognition/e2e_spec.lua @@ -248,3 +248,65 @@ describe("e2e tests", function() eq(customMark, vim.api.nvim_get_hl(0, { name = extmarks[3].virt_lines[1][1][2] })) end) end) + +describe("Gutter Priority", function() + it("0 priority item is not added", function() + precognition.setup({ + ---@diagnostic disable-next-line: missing-fields + gutterHints = { + G = { text = "G", prio = 0 }, + }, + }) + + local testBuf = vim.api.nvim_create_buf(true, false) + + vim.api.nvim_buf_set_lines(testBuf, 0, -1, false, { + "ABC", + "DEF", + "", + "GHI", + "", + "JKL", + "", + "MNO", + }) + vim.api.nvim_set_current_buf(testBuf) + vim.api.nvim_win_set_cursor(0, { 4, 0 }) + + precognition.on_cursor_moved() + + local gutter_extmarks = get_gutter_extmarks(testBuf) + + for _, extmark in pairs(gutter_extmarks) do + eq(true, extmark[4].sign_text ~= "G ") + eq(true, extmark[4].sign_name ~= "precognition_gutter_G") + end + end) + + it("higher priority item replaces", function() + precognition.setup({ + ---@diagnostic disable-next-line: missing-fields + gutterHints = { + G = { text = "G", prio = 3 }, + gg = { text = "gg", prio = 100 }, + NextParagraph = { text = "}", prio = 2 }, + PrevParagraph = { text = "{", prio = 1 }, + }, + }) + + local testBuf = vim.api.nvim_create_buf(true, false) + + vim.api.nvim_buf_set_lines(testBuf, 0, -1, false, { + "ABC", + }) + vim.api.nvim_set_current_buf(testBuf) + vim.api.nvim_win_set_cursor(0, { 1, 0 }) + + precognition.on_cursor_moved() + + local gutter_extmarks = get_gutter_extmarks(testBuf) + + eq(1, vim.tbl_count(gutter_extmarks)) + eq("gg", gutter_extmarks[1][4].sign_text) + end) +end) diff --git a/tests/precognition/gutter_hints_spec.lua b/tests/precognition/gutter_hints_spec.lua index 20d9a1a..3344045 100644 --- a/tests/precognition/gutter_hints_spec.lua +++ b/tests/precognition/gutter_hints_spec.lua @@ -155,57 +155,3 @@ local function dump(o) return tostring(o) end end - -describe("Priority", function() - it("0 priority item is not added", function() - precognition.setup({ - ---@diagnostic disable-next-line: missing-fields - gutterHints = { - G = { text = "G", prio = 0 }, - gg = { text = "gg", prio = 9 }, - PrevParagraph = { text = "{", prio = 8 }, - NextParagraph = { text = "}", prio = 8 }, - }, - }) - - local testBuf = vim.api.nvim_create_buf(true, true) - vim.api.nvim_buf_set_name(testBuf, "foo") - - vim.api.nvim_buf_set_lines(testBuf, 0, -1, false, { - "ABC", - "DEF", - "", - "GHI", - "", - "JKL", - "", - "MNO", - }) - - local hints = precognition.build_gutter_hints(testBuf) - precognition.apply_gutter_hints(hints, testBuf) - - local def = vim.fn.sign_getdefined("precognition_gutter_PrevParagraph") - print("def") - print(dump(def)) - - local gutter_group = "precognition_gutter" - local buf_name = vim.fn.bufname(testBuf) - print("buf name " .. buf_name) - local placed = vim.fn.sign_getplaced("foo", { group = "*" }) - - print("placed") - print(dump(placed)) - print(placed[1].signs[1]) - for _, g in ipairs(placed[1].signs) do - print(g.name) - end - -- print("hints g is `" .. precognition.gutter_signs_cache["G"] .. "`") - -- eq({ - -- ["gg"] = 1, - -- PrevParagraph = 3, - -- NextParagraph = 5, - -- ["G"] = 8, - -- }, hints) - end) -end) From 6e7eb55cf9eec4b042f7ff80d8ab16a3c251a54f Mon Sep 17 00:00:00 2001 From: tris203 Date: Thu, 30 May 2024 15:56:08 +0100 Subject: [PATCH 11/12] refactor: remove unused code --- lua/precognition/init.lua | 3 --- tests/precognition/gutter_hints_spec.lua | 15 --------------- 2 files changed, 18 deletions(-) diff --git a/lua/precognition/init.lua b/lua/precognition/init.lua index 6bd248e..2f0c9db 100644 --- a/lua/precognition/init.lua +++ b/lua/precognition/init.lua @@ -410,9 +410,6 @@ local state = { build_gutter_hints = function() return build_gutter_hints end, - apply_gutter_hints = function() - return apply_gutter_hints - end, on_cursor_moved = function() return on_cursor_moved end, diff --git a/tests/precognition/gutter_hints_spec.lua b/tests/precognition/gutter_hints_spec.lua index 3344045..5db1f0c 100644 --- a/tests/precognition/gutter_hints_spec.lua +++ b/tests/precognition/gutter_hints_spec.lua @@ -140,18 +140,3 @@ describe("Gutter hints table", function() }, hints) end) end) - -local function dump(o) - if type(o) == "table" then - local s = "{ " - for k, v in pairs(o) do - if type(k) ~= "number" then - k = '"' .. k .. '"' - end - s = s .. "[" .. k .. "] = " .. dump(v) .. "," - end - return s .. "} " - else - return tostring(o) - end -end From 210b217ff68eb96ec2ea1fa3df96f89a892889a7 Mon Sep 17 00:00:00 2001 From: Joshua Wood Date: Sun, 2 Jun 2024 11:24:53 +1200 Subject: [PATCH 12/12] docs: add note about unique hint priorities. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index c766d59..8097d42 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,10 @@ return { 1. As a table containing a link property pointing to an existing highlight group (see `:highlight` for valid options). 2. As a table specifying custom highlight values, such as foreground and background colors. ([more info]()) +### Hint priorities + +Any hints that could appear in the same place as others should have unique priorities to avoid conflicts. + ## ❔Usage ### Toggling