diff --git a/docs/pages/docs/components/buffer.mdx b/docs/pages/docs/components/buffer.mdx new file mode 100644 index 0000000..501fe20 --- /dev/null +++ b/docs/pages/docs/components/buffer.mdx @@ -0,0 +1,100 @@ +import { Callout } from 'nextra/components'; +import { Property } from '../../../components/Property' + +## Buffer + +`Buffer` is a component that handles window layout only and renders the contents of a given buffer. + +![](/gifs/buffer-1.gif) + +### Usage Example + + + The code example is using the [`gen.nvim`](https://github.com/David-Kunz/gen.nvim) plugin. + + +```lua +local renderer = n.create_renderer({ + width = 60, + height = 3, +}) + +local signal = n.create_signal({ + chat = "", + is_preview_visible = false, +}) + +local buf = vim.api.nvim_create_buf(false, true) + +local body = function() + return n.rows( + n.text_input({ + border_label = "Chat", + autofocus = true, + wrap = true, + on_change = function(value) + signal.chat = value + end, + }), + n.buffer({ + id = "preview", + flex = 1, + buf = buf, + autoscroll = true, + border_label = "Preview", + hidden = signal.is_preview_visible:negate(), + }) + ) +end + +renderer:add_mappings({ + { + mode = { "n", "i" }, + key = "", + handler = function() + local gen = require("gen") + local state = signal:get_value() + + renderer:set_size({ height = 20 }) + signal.is_preview_visible = true + + renderer:schedule(function() + gen.float_win = renderer:get_component_by_id("preview").winid + gen.result_buffer = buf + gen.exec({ prompt = state.chat }) + end) + end, + }, +}) + +renderer:render(body) +``` + +### Properties + +#### buf + + + +#### autoscroll + + + +#### filetype + + + +#### linebreak + + diff --git a/docs/public/gifs/buffer-1.gif b/docs/public/gifs/buffer-1.gif new file mode 100644 index 0000000..99f1afb Binary files /dev/null and b/docs/public/gifs/buffer-1.gif differ diff --git a/lua/nui-components/buffer.lua b/lua/nui-components/buffer.lua new file mode 100644 index 0000000..4c7af22 --- /dev/null +++ b/lua/nui-components/buffer.lua @@ -0,0 +1,86 @@ +local Component = require("nui-components.component") +local buf_storage = require("nui.utils.buf_storage") + +local fn = require("nui-components.utils.fn") + +local Buffer = Component:extend("Buffer") + +function Buffer:init(props, popup_options) + Buffer.super.init( + self, + fn.merge({ + buf = nil, + autoscroll = false, + }, props), + fn.deep_merge({ + buf_options = { + filetype = props.filetype or "", + }, + win_options = { + linebreak = fn.default_to(props.linebreak, true), + }, + }, popup_options) + ) +end + +function Buffer:prop_types() + return { + buf = "number", + autoscroll = "boolean", + filetype = { "string", "nil" }, + } +end + +function Buffer:_buf_create() + local props = self:get_props() + + self.bufnr = props.buf + + if props.autoscroll then + self._private.autoscroll_id = vim.api.nvim_create_autocmd("TextChanged", { + buffer = self.bufnr, + callback = function() + if not self.winid or not vim.api.nvim_win_is_valid(self.winid) then + return + end + + if not self.bufnr or not vim.api.nvim_buf_is_valid(self.bufnr) then + return true + end + + vim.api.nvim_win_set_cursor(self.winid, { + vim.api.nvim_buf_line_count(self.bufnr), + 9999, + }) + end, + }) + end +end + +function Buffer:_buf_destroy() + buf_storage.cleanup(self.bufnr) + + if self._private.autoscroll_id then + pcall(vim.api.nvim_del_autocmd, self._private.autoscroll_id) + self._private.autoscroll_id = nil + end + + self.bufnr = nil +end + +function Buffer:on_update() + local props = self:get_props() + + if props.buf and self.bufnr ~= props.buf and self._.layout_ready then + local is_focused = vim.api.nvim_get_current_win() == self.winid + + self:unmount() + self:mount() + + if is_focused then + vim.api.nvim_set_current_win(self.winid) + end + end +end + +return Buffer diff --git a/lua/nui-components/init.lua b/lua/nui-components/init.lua index 8459696..d042365 100644 --- a/lua/nui-components/init.lua +++ b/lua/nui-components/init.lua @@ -66,6 +66,7 @@ M.checkbox = require("nui-components.checkbox") M.paragraph = require("nui-components.paragraph") M.spinner = require("nui-components.spinner") M.animated_text = require("nui-components.animated-text") +M.buffer = require("nui-components.buffer") M.tabs = add_children_prop(Tabs) M.tab = add_children_prop(Tab)