mirror of
https://github.com/taigrr/glaze.nvim.git
synced 2026-04-02 03:09:10 -07:00
initial commit
This commit is contained in:
190
lua/glaze/float.lua
Normal file
190
lua/glaze/float.lua
Normal file
@@ -0,0 +1,190 @@
|
||||
---@brief [[
|
||||
--- glaze.nvim floating window (based on lazy.nvim)
|
||||
--- Creates centered floating window with backdrop
|
||||
---@brief ]]
|
||||
|
||||
local M = {}
|
||||
|
||||
---@class GlazeFloatOptions
|
||||
---@field size? { width: number, height: number }
|
||||
---@field border? string
|
||||
---@field title? string
|
||||
---@field zindex? number
|
||||
|
||||
---@class GlazeFloat
|
||||
---@field buf number
|
||||
---@field win number
|
||||
---@field opts GlazeFloatOptions
|
||||
---@field win_opts table
|
||||
---@field backdrop_buf? number
|
||||
---@field backdrop_win? number
|
||||
local Float = {}
|
||||
|
||||
local _id = 0
|
||||
|
||||
---@param opts? GlazeFloatOptions
|
||||
---@return GlazeFloat
|
||||
function Float.new(opts)
|
||||
local self = setmetatable({}, { __index = Float })
|
||||
return self:init(opts)
|
||||
end
|
||||
|
||||
---@param opts? GlazeFloatOptions
|
||||
function Float:init(opts)
|
||||
require("glaze.colors").setup()
|
||||
|
||||
_id = _id + 1
|
||||
self.id = _id
|
||||
|
||||
local config = require("glaze").config
|
||||
self.opts = vim.tbl_deep_extend("force", {
|
||||
size = config.ui.size,
|
||||
border = config.ui.border,
|
||||
zindex = 50,
|
||||
}, opts or {})
|
||||
|
||||
self.win_opts = {
|
||||
relative = "editor",
|
||||
style = "minimal",
|
||||
border = self.opts.border,
|
||||
zindex = self.opts.zindex,
|
||||
title = self.opts.title,
|
||||
title_pos = self.opts.title and "center" or nil,
|
||||
}
|
||||
|
||||
self:mount()
|
||||
return self
|
||||
end
|
||||
|
||||
function Float:layout()
|
||||
local function size(max, value)
|
||||
return value > 1 and math.min(value, max) or math.floor(max * value)
|
||||
end
|
||||
|
||||
self.win_opts.width = size(vim.o.columns, self.opts.size.width)
|
||||
self.win_opts.height = size(vim.o.lines - 4, self.opts.size.height)
|
||||
self.win_opts.row = math.floor((vim.o.lines - self.win_opts.height) / 2)
|
||||
self.win_opts.col = math.floor((vim.o.columns - self.win_opts.width) / 2)
|
||||
|
||||
if self.opts.border ~= "none" then
|
||||
self.win_opts.row = self.win_opts.row - 1
|
||||
self.win_opts.col = self.win_opts.col - 1
|
||||
end
|
||||
end
|
||||
|
||||
function Float:mount()
|
||||
self.buf = vim.api.nvim_create_buf(false, true)
|
||||
|
||||
-- Create backdrop
|
||||
local normal = vim.api.nvim_get_hl(0, { name = "Normal" })
|
||||
if normal.bg and vim.o.termguicolors then
|
||||
self.backdrop_buf = vim.api.nvim_create_buf(false, true)
|
||||
self.backdrop_win = vim.api.nvim_open_win(self.backdrop_buf, false, {
|
||||
relative = "editor",
|
||||
width = vim.o.columns,
|
||||
height = vim.o.lines,
|
||||
row = 0,
|
||||
col = 0,
|
||||
style = "minimal",
|
||||
focusable = false,
|
||||
zindex = self.opts.zindex - 1,
|
||||
})
|
||||
vim.api.nvim_set_hl(0, "GlazeBackdrop", { bg = "#000000", default = true })
|
||||
vim.wo[self.backdrop_win].winhighlight = "Normal:GlazeBackdrop"
|
||||
vim.wo[self.backdrop_win].winblend = 60
|
||||
vim.bo[self.backdrop_buf].buftype = "nofile"
|
||||
end
|
||||
|
||||
self:layout()
|
||||
self.win = vim.api.nvim_open_win(self.buf, true, self.win_opts)
|
||||
|
||||
-- Buffer settings
|
||||
vim.bo[self.buf].buftype = "nofile"
|
||||
vim.bo[self.buf].bufhidden = "wipe"
|
||||
vim.bo[self.buf].filetype = "glaze"
|
||||
|
||||
-- Window settings
|
||||
vim.wo[self.win].conceallevel = 3
|
||||
vim.wo[self.win].foldenable = false
|
||||
vim.wo[self.win].spell = false
|
||||
vim.wo[self.win].wrap = true
|
||||
vim.wo[self.win].winhighlight = "Normal:GlazeNormal,FloatBorder:GlazeBorder"
|
||||
vim.wo[self.win].cursorline = true
|
||||
|
||||
-- Keymaps
|
||||
self:map("q", function()
|
||||
self:close()
|
||||
end, "Close")
|
||||
self:map("<Esc>", function()
|
||||
self:close()
|
||||
end, "Close")
|
||||
|
||||
-- Auto-close on WinClosed
|
||||
vim.api.nvim_create_autocmd("WinClosed", {
|
||||
pattern = tostring(self.win),
|
||||
once = true,
|
||||
callback = function()
|
||||
self:close()
|
||||
end,
|
||||
})
|
||||
|
||||
-- Handle resize
|
||||
vim.api.nvim_create_autocmd("VimResized", {
|
||||
callback = function()
|
||||
if not self:valid() then
|
||||
return true
|
||||
end
|
||||
self:layout()
|
||||
vim.api.nvim_win_set_config(self.win, {
|
||||
relative = "editor",
|
||||
width = self.win_opts.width,
|
||||
height = self.win_opts.height,
|
||||
row = self.win_opts.row,
|
||||
col = self.win_opts.col,
|
||||
})
|
||||
if self.backdrop_win and vim.api.nvim_win_is_valid(self.backdrop_win) then
|
||||
vim.api.nvim_win_set_config(self.backdrop_win, {
|
||||
width = vim.o.columns,
|
||||
height = vim.o.lines,
|
||||
})
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
---@param key string
|
||||
---@param fn function
|
||||
---@param desc string
|
||||
function Float:map(key, fn, desc)
|
||||
vim.keymap.set("n", key, fn, { buffer = self.buf, nowait = true, desc = desc })
|
||||
end
|
||||
|
||||
function Float:valid()
|
||||
return self.win and vim.api.nvim_win_is_valid(self.win)
|
||||
end
|
||||
|
||||
function Float:close()
|
||||
vim.schedule(function()
|
||||
if self.backdrop_win and vim.api.nvim_win_is_valid(self.backdrop_win) then
|
||||
vim.api.nvim_win_close(self.backdrop_win, true)
|
||||
end
|
||||
if self.backdrop_buf and vim.api.nvim_buf_is_valid(self.backdrop_buf) then
|
||||
vim.api.nvim_buf_delete(self.backdrop_buf, { force = true })
|
||||
end
|
||||
if self.win and vim.api.nvim_win_is_valid(self.win) then
|
||||
vim.api.nvim_win_close(self.win, true)
|
||||
end
|
||||
if self.buf and vim.api.nvim_buf_is_valid(self.buf) then
|
||||
vim.api.nvim_buf_delete(self.buf, { force = true })
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
---@return number
|
||||
function Float:width()
|
||||
return self.win_opts.width
|
||||
end
|
||||
|
||||
M.Float = Float
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user