From 1605be38bdaa94bc6891e7d310585a9cb16b9dcb Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Wed, 12 Jun 2024 07:44:00 +0200 Subject: [PATCH] feat: added integrations for fzf-lua --- README.md | 14 ++++- lua/noice/commands.lua | 12 ++++ lua/noice/config/format.lua | 16 +++++ lua/noice/integrations/fzf.lua | 110 +++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 lua/noice/integrations/fzf.lua diff --git a/README.md b/README.md index 87f94f6c..f441780e 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Highly experimental plugin that completely replaces the UI for `messages`, `cmdl - 💻 fully customizable **cmdline** with icons - 💅 **syntax highlighting** for `vim` and `lua` on the **cmdline** - 🚥 **statusline** components -- 🔭 open message history in [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) +- 🔭 open message history in [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) or [fzf-lua](https://github.com/ibhagwan/fzf-lua) ## 🔥 Status @@ -524,6 +524,8 @@ Formatters are used in `format` definitions. **Noice** includes the following bu }, telescope = ..., -- formatter used to display telescope results telescope_preview = ..., -- formatter used to preview telescope results + fzf = ..., -- formatter used to display fzf results + fzf_preview = ..., -- formatter used to preview fzf results lsp_progress = ..., -- formatter used by lsp progress lsp_progress_done = ..., -- formatter used by lsp progress } @@ -634,6 +636,11 @@ require("lualine").setup({ +## 🔭 Pickers + +For convenience, you can do `:Noice pick`, which will open a picker with all the messages in the history, +either with `telescope` or `fzf-lua`. + ## 🔭 Telescope In order to use **Noice** in **Telescope**, you can either do `:Noice telescope`, @@ -644,6 +651,11 @@ The results panel is formatted using `config.format.formatters.telescope`. The p require("telescope").load_extension("noice") ``` +## 🔭 Fzf Lua + +In order to use **Noice** in **FzfLua**, you can do `:Noice fzf`. +The results panel is formatted using `config.format.formatters.fzf`. The preview is formatted with `config.format.formatters.telescope_fzf` + ## 🚀 Usage - `:Noice` or `:Noice history` shows the message history diff --git a/lua/noice/commands.lua b/lua/noice/commands.lua index 6297b4c9..fa3db36f 100644 --- a/lua/noice/commands.lua +++ b/lua/noice/commands.lua @@ -58,6 +58,18 @@ function M.setup() telescope = function() require("telescope").extensions.noice.noice({}) end, + fzf = function() + require("noice.integrations.fzf").open({}) + end, + pick = function() + if pcall(_G.require, "telescope.config") then + require("telescope").extensions.noice.noice({}) + elseif pcall(_G.require, "fzf-lua") then + require("noice.integrations.fzf").open({}) + else + Util.error("No picker available") + end + end, stats = function() Manager.add(Util.stats.message()) end, diff --git a/lua/noice/config/format.lua b/lua/noice/config/format.lua index be13c4c7..d99c0816 100644 --- a/lua/noice/config/format.lua +++ b/lua/noice/config/format.lua @@ -30,6 +30,22 @@ M.builtin = { "\n", "{message}", }, + fzf = { + "{level} ", + "{date} ", + "{title} ", + "{message}", + }, + fzf_preview = { + "{level} ", + "{date} ", + "{event}", + { "{kind}", before = { ".", hl_group = "NoiceFormatKind" } }, + "\n", + "{title}\n", + "\n", + "{message}", + }, lsp_progress = { { "{progress} ", diff --git a/lua/noice/integrations/fzf.lua b/lua/noice/integrations/fzf.lua new file mode 100644 index 00000000..1e1ba261 --- /dev/null +++ b/lua/noice/integrations/fzf.lua @@ -0,0 +1,110 @@ +local require = require("noice.util.lazy") + +local fzf = require("fzf-lua") +local builtin = require("fzf-lua.previewer.builtin") +local Config = require("noice.config") +local Manager = require("noice.message.manager") +local Format = require("noice.text.format") + +local M = {} + +---@alias NoiceEntry {message: NoiceMessage, ordinal: string, display: string} + +---@param message NoiceMessage +---@return NoiceEntry +function M.entry(message) + message = Format.format(message, "fzf") + local line = message._lines[1] + local hl = {} ---@type string[] + for _, text in ipairs(line._texts) do + ---@type string? + local hl_group = text.extmark and text.extmark.hl_group + hl[#hl + 1] = hl_group and fzf.utils.ansi_from_hl(hl_group, text:content()) or text:content() + end + hl[#hl + 1] = fzf.utils.ansi_from_hl("Conceal", " [" .. message.id .. "]") + return { + message = message, + ordinal = message:content(), + display = table.concat(hl, ""), + } +end + +function M.find() + local messages = Manager.get(Config.options.commands.history.filter, { + history = true, + sort = true, + reverse = true, + }) + ---@type table + local ret = {} + + for _, message in ipairs(messages) do + ret[message.id] = M.entry(message) + end + + return ret +end + +---@param messages table +function M.previewer(messages) + local previewer = builtin.buffer_or_file:extend() + + function previewer:new(o, opts, fzf_win) + previewer.super.new(self, o, opts, fzf_win) + self.title = "Noice" + setmetatable(self, previewer) + return self + end + + function previewer:parse_entry(entry_str) + local id = tonumber(entry_str:match("%[(%d+)%]$")) + local entry = messages[id] + assert(entry, "No message found for entry: " .. entry_str) + return entry + end + + function previewer:populate_preview_buf(entry_str) + local buf = self:get_tmp_buffer() + local entry = self:parse_entry(entry_str) + assert(entry, "No message found for entry: " .. entry_str) + + ---@type NoiceMessage + local m = Format.format(entry.message, "fzf_preview") + m:render(buf, Config.ns) + + self:set_preview_buf(buf) + self.win:update_title(" Noice ") + self.win:update_scrollbar() + end + + return previewer +end + +---@param opts? table +function M.open(opts) + local messages = M.find() + opts = vim.tbl_deep_extend("force", opts or {}, { + prompt = false, + winopts = { + title = " Noice ", + title_pos = "center", + preview = { + title = " Noice ", + title_pos = "center", + }, + }, + previewer = M.previewer(messages), + fzf_opts = { + ["--no-multi"] = "", + }, + actions = { + default = function() end, + }, + }) + local lines = vim.tbl_map(function(entry) + return entry.display + end, vim.tbl_values(messages)) + return fzf.fzf_exec(lines, opts) +end + +return M