-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat:
ibhagwan/fzf-lua
support (#150)
* feat: `ibhagwan/fzf-lua` support * feat(picker): close buffer * fix: telescope lang picker * feat: adjust picker sizes * docs: `picker.provider` config * feat: picker provider resolver
- Loading branch information
Showing
17 changed files
with
669 additions
and
425 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
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
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
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
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,93 @@ | ||
local log = require("leetcode.logger") | ||
local config = require("leetcode.config") | ||
|
||
---@return "fzf" | "telescope" | ||
local function resolve_provider() | ||
---@type string | ||
local provider = config.user.picker.provider | ||
|
||
if provider == nil then | ||
local fzf_ok = pcall(require, "fzf-lua") | ||
if fzf_ok then | ||
return "fzf" | ||
end | ||
local telescope_ok = pcall(require, "telescope") | ||
if telescope_ok then | ||
return "telescope" | ||
end | ||
error("no supported picker provider found") | ||
else | ||
local provider_ok = pcall(require, provider) | ||
assert(provider_ok, ("specified picker provider not found: `%s`"):format(provider)) | ||
return provider == "fzf-lua" and "fzf" or provider | ||
end | ||
end | ||
|
||
---@class leet.Picker | ||
local P = {} | ||
P.provider = resolve_provider() | ||
|
||
function P.hl_to_ansi(hl_group) | ||
local color = vim.api.nvim_get_hl(0, { name = hl_group }) | ||
if color and color.fg then | ||
return string.format( | ||
"\x1b[38;2;%d;%d;%dm", | ||
bit.rshift(color.fg, 16), | ||
bit.band(bit.rshift(color.fg, 8), 0xFF), | ||
bit.band(color.fg, 0xFF) | ||
) | ||
end | ||
return "" | ||
end | ||
|
||
function P.apply_hl(text, hl_group) | ||
if not hl_group then | ||
return text | ||
end | ||
return P.hl_to_ansi(hl_group) .. text .. "\x1b[0m" | ||
end | ||
|
||
function P.normalize(items) | ||
return vim.tbl_map(function(item) | ||
return table.concat( | ||
vim.tbl_map(function(col) | ||
if type(col) == "table" then | ||
return P.apply_hl(col[1], col[2]) | ||
else | ||
return col | ||
end | ||
end, item.entry), | ||
" " | ||
) | ||
end, items) | ||
end | ||
|
||
function P.pick(path, ...) | ||
local rpath = table.concat({ "leetcode.picker", path, P.provider }, ".") | ||
return require(rpath)(...) | ||
end | ||
|
||
function P.language(...) | ||
P.pick("language", ...) | ||
end | ||
|
||
function P.question(...) | ||
P.pick("question", ...) | ||
end | ||
|
||
function P.tabs() | ||
local utils = require("leetcode.utils") | ||
local tabs = utils.question_tabs() | ||
|
||
if vim.tbl_isempty(tabs) then | ||
return log.warn("No questions opened") | ||
end | ||
|
||
P.pick("tabs", tabs) | ||
end | ||
|
||
function P.hidden_field(text, deli) | ||
return text:match(("([^%s]+)$"):format(deli)) | ||
end | ||
|
||
return P |
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,35 @@ | ||
local fzf = require("fzf-lua") | ||
local t = require("leetcode.translator") | ||
local language_picker = require("leetcode.picker.language") | ||
local Picker = require("leetcode.picker") | ||
|
||
local deli = "\t" | ||
|
||
return function(question, cb) | ||
local items = language_picker.items(question.q.code_snippets) | ||
|
||
for i, item in ipairs(items) do | ||
local md = vim.inspect({ slug = item.value.t.slug, lang = item.value.t.lang }) | ||
:gsub("\n", "") | ||
items[i] = table.concat({ Picker.normalize({ item })[1], md }, deli) | ||
end | ||
|
||
fzf.fzf_exec(items, { | ||
prompt = t("Available Languages") .. "> ", | ||
winopts = { | ||
win_height = language_picker.height, | ||
win_width = language_picker.width, | ||
}, | ||
fzf_opts = { | ||
["--delimiter"] = deli, | ||
["--nth"] = "1", | ||
["--with-nth"] = "1", | ||
}, | ||
actions = { | ||
["default"] = function(selected) | ||
local md = Picker.hidden_field(selected[1], deli) | ||
language_picker.select(load("return " .. md)(), question, cb) | ||
end, | ||
}, | ||
}) | ||
end |
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,64 @@ | ||
local log = require("leetcode.logger") | ||
local t = require("leetcode.translator") | ||
local config = require("leetcode.config") | ||
local utils = require("leetcode.utils") | ||
|
||
local L = {} | ||
|
||
L.width = 80 | ||
L.height = 15 | ||
|
||
---@param snippet lc.QuestionCodeSnippet | ||
local function dislay_icon(snippet) | ||
local hl = "leetcode_lang_" .. snippet.t.slug | ||
vim.api.nvim_set_hl(0, hl, { fg = snippet.t.color }) | ||
|
||
return { snippet.t.icon, hl } | ||
end | ||
|
||
---@param snippet lc.QuestionCodeSnippet | ||
local function display_lang(snippet) | ||
return { snippet.lang } | ||
end | ||
|
||
function L.entry(item) | ||
return { | ||
dislay_icon(item), | ||
display_lang(item), | ||
} | ||
end | ||
|
||
---@param item lc.QuestionCodeSnippet | ||
function L.ordinal(item) | ||
return ("%s %s"):format(item.t.lang, item.t.slug) | ||
end | ||
|
||
function L.items(content) | ||
return vim.tbl_map(function(item) | ||
---@type lc.language | ||
item.t = utils.get_lang(item.lang_slug) | ||
if not item.t then | ||
return | ||
end | ||
return { entry = L.entry(item), value = item } | ||
end, content) | ||
end | ||
|
||
function L.select(selection, question, cb, close) | ||
if question.lang == selection.slug then | ||
return log.warn(("%s: %s"):format(t("Language already set to"), selection.lang)) | ||
end | ||
|
||
config.lang = selection.slug | ||
if close then | ||
close() | ||
end | ||
|
||
if cb then | ||
cb(selection.slug) | ||
else | ||
question:change_lang(selection.slug) | ||
end | ||
end | ||
|
||
return L |
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,67 @@ | ||
local log = require("leetcode.logger") | ||
local t = require("leetcode.translator") | ||
|
||
local pickers = require("telescope.pickers") | ||
local finders = require("telescope.finders") | ||
local conf = require("telescope.config").values | ||
local config = require("leetcode.config") | ||
|
||
local entry_display = require("telescope.pickers.entry_display") | ||
local actions = require("telescope.actions") | ||
local action_state = require("telescope.actions.state") | ||
local language_picker = require("leetcode.picker.language") | ||
|
||
local displayer = entry_display.create({ | ||
separator = " ", | ||
items = { | ||
{ width = 1 }, | ||
{ remaining = true }, | ||
}, | ||
}) | ||
|
||
local function entry_maker(item) | ||
return { | ||
value = item.value, | ||
display = function() | ||
return displayer(item.entry) | ||
end, | ||
ordinal = language_picker.ordinal(item.value), | ||
} | ||
end | ||
|
||
local opts = require("telescope.themes").get_dropdown({ | ||
layout_config = { | ||
width = language_picker.width, | ||
height = language_picker.height, | ||
}, | ||
}) | ||
|
||
---@param question lc.ui.Question | ||
return function(question, cb) | ||
local items = language_picker.items(question.q.code_snippets) | ||
|
||
pickers | ||
.new(opts, { | ||
prompt_title = t("Available Languages"), | ||
finder = finders.new_table({ | ||
results = items, | ||
entry_maker = entry_maker, | ||
}), | ||
sorter = conf.generic_sorter(opts), | ||
attach_mappings = function(prompt_bufnr) | ||
actions.select_default:replace(function() | ||
local selection = action_state.get_selected_entry() | ||
if not selection then | ||
log.warn("No selection") | ||
return | ||
end | ||
language_picker.select(selection.value.t, question, cb, function() | ||
actions.close(prompt_bufnr) | ||
end) | ||
end) | ||
|
||
return true | ||
end, | ||
}) | ||
:find() | ||
end |
Oops, something went wrong.