new provider: highlights

main
bhagwan 2 years ago
parent 4edaa792ff
commit 835de49506

@ -203,6 +203,7 @@ vim.api.nvim_set_keymap('n', '<c-P>',
| `help_tags` | help tags |
| `man_pages` | man pages |
| `colorschemes` | color schemes |
| `highlights` | highlight groups |
| `commands` | neovim commands |
| `command_history` | command history |
| `search_history` | search history |

@ -239,6 +239,7 @@ MISC *fzf-lua-misc*
| `help_tags` | help tags |
| `man_pages` | man pages |
| `colorschemes` | color schemes |
| `highlights` | highlight groups |
| `commands` | neovim commands |
| `command_history` | command history |
| `search_history` | search history |

@ -419,6 +419,10 @@ M.globals.colorschemes = {
width = 0.50,
},
}
M.globals.highlights = {
prompt = 'highlights> ',
previewer = { _ctor = previewers.builtin.highlights, },
}
M.globals.helptags = {
prompt = 'Help> ',
actions = {

@ -106,6 +106,7 @@ M.blines = require'fzf-lua.providers.buffers'.blines
M.help_tags = require'fzf-lua.providers.helptags'.helptags
M.man_pages = require'fzf-lua.providers.manpages'.manpages
M.colorschemes = require'fzf-lua.providers.colorschemes'.colorschemes
M.highlights = require'fzf-lua.providers.colorschemes'.highlights
M.tags = require'fzf-lua.providers.tags'.tags
M.btags = require'fzf-lua.providers.tags'.btags

@ -854,4 +854,72 @@ function Previewer.tags:set_cursor_hl(entry)
end)
end
Previewer.highlights = Previewer.base:extend()
function Previewer.highlights:should_clear_preview(_)
return false
end
function Previewer.highlights:gen_winopts()
local winopts = {
wrap = self.win.preview_wrap,
number = false
}
return vim.tbl_extend("keep", winopts, self.winopts)
end
function Previewer.highlights:new(o, opts, fzf_win)
Previewer.highlights.super.new(self, o, opts, fzf_win)
self.ns_previewer = vim.api.nvim_create_namespace("fzf-lua.previewer.hl")
return self
end
function Previewer.highlights:close()
Previewer.highlights.super.close(self)
self.tmpbuf = nil
end
function Previewer.highlights:populate_preview_buf(entry_str)
if not self.tmpbuf then
local output = vim.split(vim.fn.execute "highlight", "\n")
local hl_groups = {}
for _, v in ipairs(output) do
if v ~= "" then
if v:sub(1, 1) == " " then
local part_of_old = v:match "%s+(.*)"
hl_groups[#hl_groups] = hl_groups[#hl_groups] .. part_of_old
else
table.insert(hl_groups, v)
end
end
end
self.tmpbuf = self:get_tmp_buffer()
vim.api.nvim_buf_set_lines(self.tmpbuf, 0, -1, false, hl_groups)
for k, v in ipairs(hl_groups) do
local startPos = string.find(v, "xxx", 1, true) - 1
local endPos = startPos + 3
local hlgroup = string.match(v, "([^ ]*)%s+.*")
pcall(vim.api.nvim_buf_add_highlight, self.tmpbuf, 0, hlgroup, k - 1, startPos, endPos)
end
self:set_preview_buf(self.tmpbuf)
end
local selected_hl = utils.strip_ansi_coloring(entry_str)
pcall(vim.api.nvim_buf_clear_namespace, self.tmpbuf, self.ns_previewer, 0, -1)
pcall(api.nvim_win_call, self.win.preview_winid, function()
-- start searching at line 1 in case we
-- didn't reload the buffer (same file)
api.nvim_win_set_cursor(0, {1, 0})
fn.clearmatches()
fn.search(selected_hl.." ", "W")
if self.win.winopts.hl.search then
fn.matchadd(self.win.winopts.hl.search, selected_hl.." ")
end
self.orig_pos = api.nvim_win_get_cursor(0)
utils.zz()
end)
self.win:update_scrollbar()
end
return Previewer

@ -16,5 +16,6 @@ Previewer.builtin.man_pages = function() return require 'fzf-lua.previewer.built
Previewer.builtin.marks = function() return require 'fzf-lua.previewer.builtin'.marks end
Previewer.builtin.jumps = function() return require 'fzf-lua.previewer.builtin'.jumps end
Previewer.builtin.tags = function() return require 'fzf-lua.previewer.builtin'.tags end
Previewer.builtin.highlights = function() return require 'fzf-lua.previewer.builtin'.highlights end
return Previewer

@ -1,4 +1,5 @@
local core = require "fzf-lua.core"
local utils = require "fzf-lua.utils"
local shell = require "fzf-lua.shell"
local config = require "fzf-lua.config"
local actions = require "fzf-lua.actions"
@ -57,4 +58,68 @@ M.colorschemes = function(opts)
end
M.highlights = function(opts)
opts = config.normalize_opts(opts, config.globals.highlights)
if not opts then return end
local contents = function (cb)
local highlights = vim.fn.getcompletion('', 'highlight')
local function add_entry(hl, co)
-- translate the highlight using ansi escape sequences
local x = utils.ansi_from_hl(hl, hl)
cb(x, function(err)
if co then coroutine.resume(co) end
if err then
-- error, close fzf pipe
cb(nil, function() end)
end
end)
if co then coroutine.yield() end
end
local function populate(entries, fn, co)
for _, e in ipairs(entries) do
fn(e, co)
end
cb(nil, function()
if co then coroutine.resume(co) end
end)
end
local coroutinify = (opts.coroutinify==nil) and false or opts.coroutinify
if not coroutinify then
populate(highlights, add_entry)
else
coroutine.wrap(function()
-- Unable to coroutinify, hl functions fail inside coroutines with:
-- E5560: vimL function must not be called in a lua loop callback
-- and using 'vim.schedule'
-- attempt to yield across C-call boundary
populate(highlights,
function(x, co)
vim.schedule(function()
add_entry(x, co)
end)
end,
coroutine.running())
coroutine.yield()
end)()
end
end
opts.fzf_opts['--no-multi'] = ''
core.fzf_wrap(opts, contents, function(selected)
if not selected then return end
actions.act(opts.actions, selected)
end)()
end
return M

@ -300,6 +300,51 @@ for color, escseq in pairs(M.ansi_colors) do
M.add_ansi_code(color, escseq)
end
local function hex2rgb(hexcol)
local r,g,b = hexcol:match('#(..)(..)(..)')
if not r or not g or not b then return end
r, g, b = tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)
return r, g, b
end
local function synIDattr(hl, w)
return vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID(hl)), w)
end
function M.ansi_from_hl(hl, s)
if vim.fn.hlexists(hl) == 1 then
-- https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797#rgb-colors
-- Set foreground color as RGB: 'ESC[38;2;{r};{g};{b}m'
-- Set background color as RGB: 'ESC[48;2;{r};{g};{b}m'
local what = {
['fg'] = { rgb = true, code = 38 },
['bg'] = { rgb = true, code = 48 },
['bold'] = { code = 1 },
['italic'] = { code = 3 },
['underline'] = { code = 4 },
['inverse'] = { code = 7 },
['reverse'] = { code = 7 },
['strikethrough'] = { code = 9 },
}
for w, p in pairs(what) do
if p.rgb then
local hexcol = synIDattr(hl, w)
local r, g, b = hex2rgb(hexcol)
if r and g and b then
local escseq = ('[%d;2;%d;%d;%dm'):format(p.code, r, g, b)
s = ("%s%s%s"):format(escseq, s, M.ansi_colors.clear)
end
else
local value = synIDattr(hl, w)
if value and tonumber(value)==1 then
local escseq = ('[%dm'):format(p.code)
s = ("%s%s%s"):format(escseq, s, M.ansi_colors.clear)
end
end
end
end
return s
end
function M.strip_ansi_coloring(str)
if not str then return str end

Loading…
Cancel
Save