diff --git a/README.md b/README.md index e79b73a..fc390f7 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,6 @@ require("noice").setup({ long_message_to_split = true, -- long messages will be sent to a split inc_rename = false, -- enables an input dialog for inc-rename.nvim lsp_doc_border = false, -- add a border to hover docs and signature help - cmdline_output_to_split = false, -- send the output of a command you executed in the cmdline to a split }, }) ``` @@ -147,6 +146,13 @@ Check the [wiki](https://github.com/folke/noice.nvim/wiki/Configuration-Recipes) -- Icons for completion item kinds (see defaults at noice.config.icons.kinds) kind_icons = {}, -- set to `false` to disable icons }, + -- default options for require('noice').redirect + -- see the section on Command Redirection + ---@type NoiceRouteConfig + redirect = { + view = "popup", + filter = { event = "msg_show" }, + }, -- You can add any custom commands below that will be available with `:Noice command` ---@type table commands = { @@ -286,7 +292,6 @@ Check the [wiki](https://github.com/folke/noice.nvim/wiki/Configuration-Recipes) long_message_to_split = false, -- long messages will be sent to a split inc_rename = false, -- enables an input dialog for inc-rename.nvim lsp_doc_border = false, -- add a border to hover docs and signature help - cmdline_output_to_split = false, -- send the output of a command you executed in the cmdline to a split }, throttle = 1000 / 30, -- how frequently does Noice need to check for ui updates? This has no effect when in blocking mode. ---@type NoiceConfigViews @@ -644,6 +649,33 @@ end) > You can add custom commands with `config.commands` +### ↪️ Command Redirection + +Sometimes it's useful to redirect the messages generated by a command or function +to a different view. That can be easily achieved with command redirection. + +The redirect API can taken an optional `routes` parameter, which defaults to `{config.redirect}`. + +```lua +-- redirect ":hi" +require("noice").redirect("hi") + +-- redirect some function +require("noice").redirect(function() + print("test") +end) +``` + +Adding the following keymap, will redirect the active cmdline when pressing ``. +The cmdline stays open, so you can change the command and execute it again. +When exiting the cmdline, the popup window will be focused. + +```lua +vim.keymap.set("c", "", function() + require("noice").redirect(vim.fn.getcmdline()) + end, { desc = "Redirect Cmdline" }) +``` + ### Lsp Hover Doc Scrolling ```lua diff --git a/lua/noice/config/init.lua b/lua/noice/config/init.lua index efb2c51..2bcf3e1 100644 --- a/lua/noice/config/init.lua +++ b/lua/noice/config/init.lua @@ -48,6 +48,13 @@ function M.defaults() -- Icons for completion item kinds (see defaults at noice.config.icons.kinds) kind_icons = {}, -- set to `false` to disable icons }, + -- default options for require('noice').redirect + -- see the section on Command Redirection + ---@type NoiceRouteConfig + redirect = { + view = "popup", + filter = { event = "msg_show" }, + }, -- You can add any custom commands below that will be available with `:Noice command` ---@type table commands = { diff --git a/lua/noice/init.lua b/lua/noice/init.lua index ed6c52a..caae712 100644 --- a/lua/noice/init.lua +++ b/lua/noice/init.lua @@ -71,6 +71,13 @@ function M.enable() end end +-- Redirect any messages generated by a command or function +---@param cmd string|fun() command or function to execute +---@param routes? NoiceRouteConfig[] custom routes. Defaults to `config.redirect` +function M.redirect(cmd, routes) + return require("noice.message.router").redirect(cmd, routes) +end + ---@param msg string ---@param level number|string ---@param opts? table diff --git a/lua/noice/message/router.lua b/lua/noice/message/router.lua index 0880efd..3f85918 100644 --- a/lua/noice/message/router.lua +++ b/lua/noice/message/router.lua @@ -44,17 +44,59 @@ function M.disable() end ---@param route NoiceRouteConfig -function M.add(route) +---@param pos? number +function M.add(route, pos) local ret = { filter = route.filter, opts = route.opts or {}, view = route.view and View.get_view(route.view, route.opts) or nil, } if ret.view == nil then - ret.view = nil ret.opts.skip = true end - table.insert(M._routes, ret) + if pos then + table.insert(M._routes, pos, ret) + else + table.insert(M._routes, ret) + end + return ret +end + +-- Redirect any messages generated by a command or function +---@param cmd string|fun() command or function to execute +---@param routes? NoiceRouteConfig[] custom routes. Defaults to `config.redirect` +function M.redirect(cmd, routes) + routes = routes or { Config.options.redirect } + if type(cmd) == "string" then + local cmd_str = cmd + cmd = function() + vim.cmd(cmd_str) + end + end + -- process any pending messages + M.update() + + local added = {} + local pos = 1 + -- add temporary routes + for _, route in ipairs(routes) do + table.insert(added, M.add(route, pos)) + pos = pos + 1 + end + + -- execute callback + Util.try(cmd) + + -- force a redraw to make sure we received all msg_show events + vim.cmd.redraw() + + -- process messages + M.update() + + -- remove temporary routes + M._routes = vim.tbl_filter(function(r) + return not vim.tbl_contains(added, r) + end, M._routes) end function M.setup()