From 8a570bb4081649aba6222af3d67f31142aa57935 Mon Sep 17 00:00:00 2001 From: Joshua Cold Date: Mon, 25 Aug 2025 20:23:21 -0600 Subject: [PATCH 1/2] feat: get started on replacing nui.popup --- lua/python/ui/init.lua | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/lua/python/ui/init.lua b/lua/python/ui/init.lua index 30f482c..484bbde 100644 --- a/lua/python/ui/init.lua +++ b/lua/python/ui/init.lua @@ -1,8 +1,43 @@ local config = require('python.config') local Popup = require("nui.popup") + +---@class Popup +---@field border string +---@field +local Popup = {} + +function Popup:new(o) + o = o or {} + setmetatable(o, self) + self.__index = self + return o +end + +function Popup:mount() + local buf = vim.api.nvim_create_buf(false, true) + + local win_opts = { + relative = "editor", + width = 60, + height = 10, + row = math.floor((vim.o.lines - 10) / 2), -- Center vertically + col = math.floor((vim.o.columns - 60) / 2), -- Center horizontally + border = "rounded", + focusable = true, + } + + local win = vim.api.nvim_open_win(buf, true, win_opts) + + vim.api.nvim_buf_set_lines(buf, 0, -1, false, { + "This is a custom Neovim UI window!", + "", + "Press to close.", + }) +end + local empty_system_ui = { - ---@type NuiPopup|NuiPopup.constructor + ---@type Popup ui = nil, line_count = 0, } From cc4027747981545209b53c5b3f54dda58b3ff058 Mon Sep 17 00:00:00 2001 From: Joshua Cold Date: Mon, 25 Aug 2025 22:45:07 -0600 Subject: [PATCH 2/2] feat: replace nui dependency with built-in commands Replace Popup from nui with our own classes to remove a dependency on the plugin --- README.md | 3 -- lazy.lua | 1 - lua/python/config.lua | 30 ++++++++++--- lua/python/ui/init.lua | 95 ++++++++++++++++++++++-------------------- 4 files changed, 74 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 54ab6bc..1e3a346 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ return { { "mfussenegger/nvim-dap" }, { "mfussenegger/nvim-dap-python" }, { "neovim/nvim-lspconfig" }, - { "MunifTanjim/nui.nvim" }, { "L3MON4D3/LuaSnip" }, { "nvim-neotest/neotest" }, { "nvim-neotest/neotest-python" }, @@ -47,7 +46,6 @@ return { { "mfussenegger/nvim-dap" }, { "mfussenegger/nvim-dap-python" }, { "neovim/nvim-lspconfig" }, - { "MunifTanjim/nui.nvim" }, { "L3MON4D3/LuaSnip" }, { "nvim-neotest/neotest" }, { "nvim-neotest/neotest-python" }, @@ -72,7 +70,6 @@ vim.pack.add("https://github.com/joshzcold/python.nvim") vim.pack.add("https://github.com/mfussenegger/nvim-dap") vim.pack.add("https://github.com/mfussenegger/nvim-dap-python") vim.pack.add("https://github.com/neovim/nvim-lspconfig") -vim.pack.add("https://github.com/MunifTanjim/nui.nvim") vim.pack.add("https://github.com/L3MON4D3/LuaSnip") vim.pack.add("https://github.com/nvim-neotest/neotest") vim.pack.add("https://github.com/nvim-neotest/neotest-python") diff --git a/lazy.lua b/lazy.lua index 112c369..17bbac3 100644 --- a/lazy.lua +++ b/lazy.lua @@ -4,7 +4,6 @@ return { { "mfussenegger/nvim-dap" }, { "mfussenegger/nvim-dap-python" }, { "neovim/nvim-lspconfig" }, - { "MunifTanjim/nui.nvim" }, { "L3MON4D3/LuaSnip" }, { "nvim-neotest/neotest" }, { "nvim-neotest/neotest-python" }, diff --git a/lua/python/config.lua b/lua/python/config.lua index 40f017a..313a51b 100644 --- a/lua/python/config.lua +++ b/lua/python/config.lua @@ -90,15 +90,33 @@ local defaults = { ui = { -- Amount of time to pause closing of ui after a finished task ui_close_timeout = 5000, - -- zindex of new ui elements. - zindex = 999, + -- Default ui style for interfaces created by python.nvim - ---@alias python_ui_default_style "'popup'|nil" + ---@alias python_ui_default_style "'popup'|'split'|nil" default_ui_style = "popup", + + -- Customize the position and behavior of the ui style popup = { - demensions = { - width = "60", - height = "25" + win_opts = { + -- border = "rounded", + -- relative = "win", + -- focusable = true, + -- title = "python.nvim", + -- anchor = "SE", + -- zindex = 999, + -- width = 40, + -- height = 20, + -- row = vim.o.lines - 3, + -- col = vim.o.columns -2, + } + }, + split = { + win_opts = { + -- split = 'below', + -- win = 0, + -- width = 40, + -- height = 10, + -- focusable = true, } } }, diff --git a/lua/python/ui/init.lua b/lua/python/ui/init.lua index 484bbde..68457be 100644 --- a/lua/python/ui/init.lua +++ b/lua/python/ui/init.lua @@ -1,43 +1,56 @@ local config = require('python.config') -local Popup = require("nui.popup") +-- local Popup = require("nui.popup") + +local split_default_style = { + split = 'below', + win = 0, + width = 40, + height = 10, + focusable = true, +} +local popup_default_style = { + border = "rounded", + relative = "win", + focusable = true, + title = "python.nvim", + anchor = "SE", + zindex = 999, + width = 40, + height = 20, + row = vim.o.lines - 3, + col = vim.o.columns - 2, + style = "minimal" +} ----@class Popup ----@field border string ----@field -local Popup = {} +---@class UI +---@field win_opts table +---@field win number | nil +---@field buf number | nil +local UI = { + win_opts = {}, + win = nil, + buf = nil, +} -function Popup:new(o) +function UI:new(o) o = o or {} setmetatable(o, self) self.__index = self return o end -function Popup:mount() - local buf = vim.api.nvim_create_buf(false, true) - - local win_opts = { - relative = "editor", - width = 60, - height = 10, - row = math.floor((vim.o.lines - 10) / 2), -- Center vertically - col = math.floor((vim.o.columns - 60) / 2), -- Center horizontally - border = "rounded", - focusable = true, - } - - local win = vim.api.nvim_open_win(buf, true, win_opts) - - vim.api.nvim_buf_set_lines(buf, 0, -1, false, { - "This is a custom Neovim UI window!", - "", - "Press to close.", - }) +function UI:mount() + self.buf = vim.api.nvim_create_buf(false, true) + self.win = vim.api.nvim_open_win(self.buf, false, self.win_opts) +end + +function UI:unmount() + vim.api.nvim_win_close(self.win, true) end local empty_system_ui = { - ---@type Popup + ---@type UI ui = nil, line_count = 0, } @@ -74,20 +87,12 @@ function M.activate_system_call_ui() M.deactivate_system_call_ui(0) local ui = nil if config.ui.default_ui_style == "popup" then - ui = Popup({ - border = 'single', - anchor = "NE", - relative = "win", - zindex = config.ui.zindex, - position = { - row = 1, - col = vim.api.nvim_win_get_width(0) - 3, - }, - size = { - width = config.ui.popup.demensions.width, - height = config.ui.popup.demensions.height, - } - }) + local win_opts = vim.tbl_deep_extend('keep', config.ui.popup.win_opts or {}, popup_default_style) + ui = UI:new({ win_opts = win_opts }) + end + if config.ui.default_ui_style == "split" then + local win_opts = vim.tbl_deep_extend('keep', config.ui.split.win_opts or {}, split_default_style) + ui = UI:new({ win_opts = win_opts }) end if ui then -- mount/open the component @@ -119,18 +124,18 @@ function M.show_system_call_progress(err, data, flush, callback) local _, line_count = out:gsub('\n', '\n') if flush then M.system_ui.line_count = 0 - pcall(vim.api.nvim_buf_set_text, M.system_ui.ui.bufnr, 0, 0, 0, 0, {}) + pcall(vim.api.nvim_buf_set_text, M.system_ui.ui.buf, 0, 0, 0, 0, {}) end local row = M.system_ui.line_count local increase = row + line_count - if not M.system_ui.ui.bufnr then + if not M.system_ui.ui.buf then return end -- Don't throw errors if we can't set the text on the next line for something reason - pcall(vim.api.nvim_buf_set_text, M.system_ui.ui.bufnr, row, 0, row, 0, vim.fn.split(out .. "\n", "\n")) - pcall(vim.api.nvim_win_set_cursor, M.system_ui.ui.winid, { row, 0 }) + pcall(vim.api.nvim_buf_set_text, M.system_ui.ui.buf, row, 0, row, 0, vim.fn.split(out .. "\n", "\n")) + pcall(vim.api.nvim_win_set_cursor, M.system_ui.ui.win, { row, 0 }) M.system_ui.line_count = increase if callback then