Skip to content

Commit

Permalink
feat: support "prio" priority value for gutter marks (#43)
Browse files Browse the repository at this point in the history
Co-authored-by: tris203 <[email protected]>
  • Loading branch information
josh-nz and tris203 authored Jun 2, 2024
1 parent dbf9a68 commit cab9d0a
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 35 deletions.
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,33 @@ 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 },
-- NextParagraph = { text = "}", prio = 1 },
-- G = { text = "G", prio = 10 },
-- gg = { text = "gg", prio = 9 },
-- PrevParagraph = { text = "{", prio = 8 },
-- NextParagraph = { text = "}", prio = 8 },
-- },
},
}
```

## ⚙️ 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
- `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.
- `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:
- `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](<https://neovim.io/doc/user/api.html#nvim_set_hl()>))

### Hint priorities

Any hints that could appear in the same place as others should have unique priorities to avoid conflicts.

## ❔Usage

### Toggling
Expand Down
67 changes: 41 additions & 26 deletions lua/precognition/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
},
}

Expand Down Expand Up @@ -180,31 +179,47 @@ local function apply_gutter_hints(gutter_hints, bufnr)
if utils.is_blacklisted_buffer(bufnr) then
return
end

local gutter_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 = gutter_table[loc]
if not existing or existing.prio < prio then
gutter_table[loc] = { hint = hint, prio = prio }
end
end
end

-- Only render valid and prioritised gutter hints.
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, {
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()
Expand Down
62 changes: 62 additions & 0 deletions tests/precognition/e2e_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit cab9d0a

Please sign in to comment.