forked from folke/which-key.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 970e79f
Showing
8 changed files
with
362 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# https://github.com/Koihik/LuaFormatter/blob/master/docs/Style-Config.md | ||
column_limit: 100 | ||
indent_width: 2 | ||
continuation_indent_width: 2 | ||
use_tab: false | ||
chop_down_parameter: true | ||
chop_down_table: true | ||
chop_down_kv_table: true | ||
single_quote_to_double_quote: true | ||
spaces_inside_table_braces: true | ||
align_parameter: true | ||
keep_simple_control_block_one_line: true | ||
extra_sep_at_table_end: true |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
local M = {} | ||
|
||
local links = { | ||
[""] = "Function", | ||
Seperator = "DiffAdded", | ||
Group = "Keyword", | ||
Desc = "Identifier", | ||
WhichKeyFloating = "NormalFloat", | ||
} | ||
|
||
function M.setup() | ||
for k, v in pairs(links) do vim.api.nvim_command("hi def link WhichKey" .. k .. " " .. v) end | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
local M = {} | ||
|
||
M.namespace = vim.api.nvim_create_namespace("WhichKey") | ||
|
||
---@class Options | ||
local defaults = {} | ||
|
||
---@type Options | ||
M.options = {} | ||
|
||
---@return Options | ||
function M.setup(options) M.options = vim.tbl_deep_extend("force", {}, defaults, options or {}) end | ||
|
||
M.setup() | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
local Keys = require("which-key.keys") | ||
local config = require("which-key.config") | ||
require("which-key.colors").setup() | ||
|
||
local M = {} | ||
|
||
function M.setup(options) config.setup(options) end | ||
|
||
M.register = Keys.register | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
local M = {} | ||
|
||
function M.t(str) return vim.api.nvim_replace_termcodes(str, true, true, true) end | ||
|
||
function M.parse_keys(keystr) | ||
local keys = {} | ||
local special = nil | ||
for i = 1, #keystr, 1 do | ||
local c = keystr:sub(i, i) | ||
if c == "<" then | ||
special = "<" | ||
elseif c == ">" and special then | ||
table.insert(keys, special .. ">") | ||
special = nil | ||
elseif special then | ||
special = special .. c | ||
else | ||
table.insert(keys, c) | ||
end | ||
end | ||
local ret = { keys = M.t(keystr), term = {}, nvim = {} } | ||
for i, key in pairs(keys) do | ||
if key == " " then key = "<space>" end | ||
if i == 1 and vim.g.mapleader and M.t(key) == M.t(vim.g.mapleader) then key = "<leader>" end | ||
table.insert(ret.term, M.t(key)) | ||
table.insert(ret.nvim, key) | ||
end | ||
return ret | ||
end | ||
|
||
function M.get_keymap(mode, prefix, buf) | ||
local mappings = {} | ||
|
||
local map = function(keymap) | ||
prefix = M.t(prefix) | ||
for _, mapping in pairs(keymap) do | ||
local id = M.t(mapping.lhs) | ||
if id:sub(1, #prefix) == prefix then | ||
mapping.id = id | ||
local idx = M.get_idx(mode, mapping.id) | ||
local buf_idx = M.get_idx(mode, mapping.id, buf) | ||
mapping.keys = M.parse_keys(mapping.lhs) | ||
mapping = vim.tbl_deep_extend("force", {}, mapping, M.mappings[idx] or {}, | ||
M.mappings[buf_idx] or {}, mapping) | ||
mappings[id] = mapping | ||
end | ||
end | ||
end | ||
|
||
-- global mappings | ||
map(vim.api.nvim_get_keymap(mode)) | ||
-- buffer local mappings | ||
if buf then map(vim.api.nvim_buf_get_keymap(buf, mode)) end | ||
|
||
return mappings | ||
end | ||
|
||
function M.parse_mappings(ret, value, prefix) | ||
prefix = prefix or "" | ||
if type(value) == "string" then | ||
table.insert(ret, { prefix = prefix, label = value }) | ||
elseif type(value) == "table" then | ||
if #value == 0 then | ||
-- key group | ||
for k, v in pairs(value) do if k ~= "name" then M.parse_mappings(ret, v, prefix .. k) end end | ||
if prefix ~= "" then | ||
table.insert(ret, { prefix = prefix, label = value.name or "+prefix", group = true }) | ||
end | ||
else | ||
-- key mapping | ||
local mapping = { prefix = prefix, opts = {} } | ||
for k, v in pairs(value) do | ||
if k == 1 then | ||
mapping.label = v | ||
elseif k == 2 then | ||
mapping.cmd = mapping.label | ||
mapping.label = v | ||
elseif k == "noremap" then | ||
mapping.opts.noremap = v | ||
elseif k == "silent" then | ||
mapping.opts.silent = v | ||
elseif k == "bufnr" then | ||
mapping.opts.bufnr = v | ||
else | ||
error("Invalid key mapping: " .. vim.inspect(value)) | ||
end | ||
end | ||
table.insert(ret, mapping) | ||
end | ||
else | ||
error("Invalid mapping " .. vim.inspect(value)) | ||
end | ||
return ret | ||
end | ||
|
||
M.mappings = {} | ||
|
||
function M.register(mappings, opts) | ||
opts = opts or {} | ||
|
||
local prefix = opts.prefix or "" | ||
opts.prefix = nil | ||
|
||
local mode = opts.mode or "n" | ||
opts.mode = nil | ||
|
||
mappings = M.parse_mappings({}, mappings, prefix) | ||
|
||
for _, mapping in pairs(mappings) do | ||
mapping.id = M.t(mapping.prefix) | ||
mapping.opts = vim.tbl_deep_extend("force", { silent = true, noremap = true }, opts, | ||
mapping.opts or {}) | ||
local cmd = mapping.cmd | ||
if mapping.group then | ||
mapping.opts.noremap = false | ||
cmd = string.format([[<cmd>lua require("which-key.view").on_keys(%q)<cr>]], mapping.prefix) | ||
end | ||
|
||
if cmd then | ||
if mapping.opts.bufnr ~= nil then | ||
local buf = mapping.opts.bufnr | ||
mapping.opts.bufnr = nil | ||
vim.api.nvim_buf_set_keymap(buf, mode, mapping.prefix, cmd, mapping.opts) | ||
mapping.opts.bufnr = buf | ||
else | ||
vim.api.nvim_set_keymap(mode, mapping.prefix, cmd, mapping.opts) | ||
end | ||
end | ||
local idx = M.get_idx(mode, mapping.id, mapping.opts.bufnr) | ||
M.mappings[idx] = vim.tbl_deep_extend("force", M.mappings[idx] or {}, mapping) | ||
end | ||
end | ||
|
||
function M.get_idx(mode, keyid, buf) | ||
local ret = mode .. ":" .. keyid | ||
if buf then ret = ":" .. buf end | ||
return ret | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
---@class Text | ||
---@field lines string[] | ||
---@field hl Highlight[] | ||
---@field lineNr number | ||
---@field current string | ||
local Text = {} | ||
Text.__index = Text | ||
|
||
function Text:new() | ||
local this = { lines = {}, hl = {}, lineNr = 0, current = "" } | ||
setmetatable(this, self) | ||
return this | ||
end | ||
|
||
function Text:nl() | ||
table.insert(self.lines, self.current) | ||
self.current = "" | ||
self.lineNr = self.lineNr + 1 | ||
end | ||
|
||
function Text:render(str, group, opts) | ||
if type(opts) == "string" then opts = { append = opts } end | ||
opts = opts or {} | ||
|
||
if group then | ||
if opts.exact ~= true then group = "WhichKey" .. group end | ||
local from = string.len(self.current) | ||
---@class Highlight | ||
local hl | ||
hl = { line = self.lineNr, from = from, to = from + string.len(str), group = group } | ||
table.insert(self.hl, hl) | ||
end | ||
self.current = self.current .. str | ||
if opts.append then self.current = self.current .. opts.append end | ||
if opts.nl then self:nl() end | ||
end | ||
|
||
return Text |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
local Keys = require("which-key.keys") | ||
local config = require("which-key.config") | ||
local Text = require("which-key.text") | ||
|
||
local highlight = vim.api.nvim_buf_add_highlight | ||
|
||
---@class View | ||
local M = {} | ||
|
||
M.keys = "" | ||
M.buf = nil | ||
M.win = nil | ||
|
||
function M.is_valid() | ||
return M.buf and vim.api.nvim_buf_is_valid(M.buf) and vim.api.nvim_buf_is_loaded(M.buf) and | ||
vim.api.nvim_win_is_valid(M.win) | ||
|
||
end | ||
|
||
function M.show() | ||
if M.is_valid() then return end | ||
M.buf = vim.api.nvim_create_buf(false, true) | ||
M.win = vim.api.nvim_open_win(M.buf, false, { | ||
relative = "editor", | ||
width = vim.o.columns, | ||
height = 10, | ||
focusable = false, | ||
anchor = "SW", | ||
row = vim.o.lines - 2, | ||
col = 0, | ||
style = "minimal", | ||
}) | ||
vim.api.nvim_win_set_option(M.win, "winhighlight", "NormalFloat:WhichKeyFloating") | ||
vim.cmd [[autocmd! WinClosed <buffer> lua require("which-key.view").on_close()]] | ||
end | ||
|
||
function M.eat(wait) | ||
while true do | ||
local n = wait and vim.fn.getchar() or vim.fn.getchar(0) | ||
if n == 0 then return end | ||
if n == 27 then -- <esc> key | ||
M.on_close() | ||
return | ||
end | ||
M.keys = M.keys .. (type(n) == "number" and vim.fn.nr2char(n) or n) | ||
if wait then | ||
vim.defer_fn(function() M.on_keys(M.keys) end, 0) | ||
return | ||
end | ||
end | ||
end | ||
|
||
function M.on_close() | ||
print(M.keys) | ||
M.hide() | ||
end | ||
|
||
function M.hide() | ||
if M.buf and vim.api.nvim_buf_is_valid(M.buf) then | ||
vim.api.nvim_buf_delete(M.buf, { force = true }) | ||
M.buf = nil | ||
end | ||
if M.win and vim.api.nvim_win_is_valid(M.win) then | ||
vim.api.nvim_win_close(M.win, { force = true }) | ||
M.win = nil | ||
end | ||
end | ||
|
||
---@param text Text | ||
function M.render_mapping(text, mapping) | ||
text:render(mapping.lhs, "") | ||
text:render("->", "Seperator") | ||
if mapping.group == true then | ||
text:render(mapping.label or mapping.rhs or "", "Group") | ||
else | ||
text:render(mapping.label or mapping.rhs or "", "Desc") | ||
end | ||
text:nl() | ||
end | ||
|
||
function M.on_keys(keys) | ||
M.keys = keys or "" | ||
-- eat queued characters | ||
M.eat(false) | ||
|
||
local mappings = Keys.get_keymap(vim.api.nvim_get_mode().mode, M.keys, | ||
vim.api.nvim_get_current_buf()) | ||
|
||
local text = Text:new() | ||
for _, mapping in pairs(mappings) do | ||
-- Exact match found, trigger keymapping | ||
if mapping.id == Keys.t(M.keys) then | ||
if mapping.group ~= true then | ||
M.hide() | ||
vim.api.nvim_feedkeys(M.keys, "m", true) | ||
return | ||
else -- skip this exact prefix group | ||
end | ||
end | ||
M.render_mapping(text, mapping) | ||
end | ||
|
||
if #text.lines == 0 then | ||
-- no mappings found. Feed back the keys | ||
M.hide() | ||
vim.api.nvim_feedkeys(M.keys, "n", true) | ||
return | ||
end | ||
|
||
if not M.is_valid() then M.show() end | ||
|
||
M.render(text) | ||
|
||
-- defer further eating on the main loop | ||
vim.defer_fn(function() M.eat(true) end, 0) | ||
end | ||
|
||
---@param text Text | ||
function M.render(text) | ||
vim.api.nvim_buf_set_lines(M.buf, 0, -1, false, text.lines) | ||
if vim.api.nvim_buf_is_valid(M.buf) then | ||
vim.api.nvim_buf_clear_namespace(M.buf, config.namespace, 0, -1) | ||
end | ||
for _, data in ipairs(text.hl) do | ||
highlight(M.buf, config.namespace, data.group, data.line, data.from, data.to) | ||
end | ||
end | ||
|
||
return M |