Skip to content

Commit

Permalink
feat: highlight search matches and search result score
Browse files Browse the repository at this point in the history
  • Loading branch information
willothy committed Dec 21, 2023
1 parent dedcf53 commit 64f45d0
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 32 deletions.
46 changes: 46 additions & 0 deletions lua/hawtkeys/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@ local M = {}
---@field keyboardLayout SupportedKeyboardLayouts
---@field customMaps { [string] : TSKeyMapArgs | WhichKeyMapargs } | nil

---@class HawtKeyHighlights
---@field HawtkeysMatchGreat vim.api.keyset.highlight | nil
---@field HawtkeysMatchGood vim.api.keyset.highlight | nil
---@field HawtkeysMatchOk vim.api.keyset.highlight | nil
---@field HawtkeysMatchBad vim.api.keyset.highlight | nil

---@class HawtKeyPartialConfig
---@field leader string | nil
---@field homerow number | nil
---@field powerFingers number[] | nil
---@field keyboardLayout SupportedKeyboardLayouts | nil
---@field customMaps { [string] : TSKeyMapArgs | WhichKeyMapargs } | nil
---@field highlights HawtKeyHighlights | nil
---

---@type { [string] : TSKeyMapArgs | WhichKeyMapargs }---
Expand Down Expand Up @@ -48,6 +55,45 @@ function M.setup(config)
M.keyboardLayout = config.keyboardLayout or "qwerty"
M.keyMapSet = vim.tbl_extend("force", _defaultSet, config.customMaps or {})

local default_match_great
if not config.highlights or not config.highlights.HawtkeysMatchGreat then
default_match_great = vim.api.nvim_get_hl(0, { name = "DiagnosticOk" })
default_match_great.underline = true
end
M.highlights = vim.tbl_extend("keep", config.highlights or {}, {
HawtkeysMatchGreat = default_match_great,
HawtkeysMatchGood = {
link = "DiagnosticOk",
},
HawtkeysMatchOk = {
link = "DiagnosticWarn",
},
HawtkeysMatchBad = {
link = "DiagnosticError",
},
})

for name, hl in pairs(M.highlights) do
vim.api.nvim_set_hl(0, name, hl)
end

vim.api.nvim_create_autocmd("ColorScheme", {
callback = function()
if default_match_great then
for k, v in
pairs(vim.api.nvim_get_hl(0, { name = "DiagnosticOk" }))
do
default_match_great[k] = v
end
default_match_great.underline = true
end

for name, hl in pairs(M.highlights) do
vim.api.nvim_set_hl(0, name, hl)
end
end,
})

vim.api.nvim_create_user_command(
"Hawtkeys",
"lua require('hawtkeys.ui').show()",
Expand Down
93 changes: 61 additions & 32 deletions lua/hawtkeys/ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ local ResultWin
local ResultBuf
local SearchWin

local prompt_extmark

local function create_win(enter, opts)
opts = opts or {}
local wo = opts.win_options or {}
Expand Down Expand Up @@ -45,30 +47,12 @@ local function create_win(enter, opts)
return win, buf
end

---@param str string
---@param combo string
---@return string
local function highlight_desc(str, combo)
-- returns str with the first unmarked occurrence of each letter of combo surrounded by []
local newStr = str:lower()
local marked = {} -- Keep track of characters already marked
for i = 1, #combo do
local char = combo:sub(i, i)
local pos = marked[char] or 1 -- Start searching from the last marked position or from the beginning
pos = newStr:find(char, pos, true) or 0
if pos then
newStr = newStr:sub(1, pos - 1)
.. "["
.. char
.. "]"
.. newStr:sub(pos + 1)
marked[char] = pos + 2 -- Mark this character's position
end
end
return newStr
end

local prompt_extmark
local search_threshold = {
GREAT = 6,
GOOD = 3,
OK = 1,
BAD = 0,
}

M.search = function(text)
text = text or ""
Expand All @@ -80,15 +64,14 @@ M.search = function(text)
for i = 1, #results do
local data = results[i]
local lines = {}
table.insert(
lines,
"Key: "
.. highlight_desc(text, data.combo)
.. "<leader>"
.. data.combo
.. " - Hawt Score: "
.. data.score
local line = string.format(
"Key: %s <leader>%s - Hawt Score: %d",
text,
data.combo,
data.score
)
table.insert(lines, line)

line_count = line_count + 1
local already_mapped = false
if
Expand Down Expand Up @@ -138,6 +121,52 @@ M.search = function(text)
0,
-1
)
else
local newStr = text:lower()
local marked = {} -- Keep track of characters already marked
for idx = 1, #data.combo do
local char = data.combo:sub(idx, idx)
local pos = marked[char] or 1 -- Start searching from the last marked position or from the beginning
pos = newStr:find(char, pos, true) or 0
if marked[char] and marked[char] == pos then
pos = newStr:find(char, pos + 1, true) or 0
end
if pos then
newStr = newStr:sub(1, pos - 1)
.. char
.. newStr:sub(pos + 1)
local hl_col = pos + 5
vim.api.nvim_buf_add_highlight(
ResultBuf,
-1,
"Function",
line_count - (already_mapped and 3 or 1),
hl_col - 1,
hl_col
)
marked[char] = pos -- Mark this character's position
end
end

local score_offset = #line - #tostring(data.score)
local score_hl
if data.score >= search_threshold.GREAT then
score_hl = "HawtkeysMatchGreat"
elseif data.score >= search_threshold.GOOD then
score_hl = "HawtkeysMatchGood"
elseif data.score >= search_threshold.OK then
score_hl = "HawtkeysMatchOk"
else
score_hl = "HawtkeysMatchBad"
end
vim.api.nvim_buf_add_highlight(
ResultBuf,
-1,
score_hl,
line_count - (already_mapped and 3 or 1),
score_offset,
#line
)
end
end
end
Expand Down

0 comments on commit 64f45d0

Please sign in to comment.