Skip to content

Commit

Permalink
feat: new preserve_win_context option to preserve parent window con…
Browse files Browse the repository at this point in the history
…text
  • Loading branch information
DNLHC committed Dec 22, 2024
1 parent 04f7325 commit 9c7e2ab
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 9 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ glance.setup({
height = 18, -- Height of the window
zindex = 45,

-- By default glance will open preview "embedded" within your active window
-- when `detached` is enabled, glance will render above all existing windows
-- Preserve the parent window context by appending virtual lines underneath the preview window.
-- requires Neovim >= 0.10.0 uses experimental nvim api that may change in the future.
preserve_win_context = true,

-- By default glance will open preview window "embedded" within your active window.
-- When `detached` is enabled glance preview will be rendered above all existing windows
-- and won't be restiricted by the width of your active window
detached = true,

Expand Down
7 changes: 7 additions & 0 deletions lua/glance/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ config.hl_ns = 'Glance'
---@field folds GlanceFoldsOpts
---@field indent_lines GlanceIndentLinesOpts
---@field winbar GlanceWinbarOpts
---@field preserve_win_context boolean

---@param user_config GlanceOpts | nil
---@param actions GlanceActions
function config.setup(user_config, actions)
local defaults = {
height = 18,
zindex = 45,
preserve_win_context = true,
detached = function(winid)
return vim.api.nvim_win_get_width(winid) < 100
end,
Expand Down Expand Up @@ -132,6 +134,7 @@ function config.setup(user_config, actions)

vim.validate({
height = { opts.height, 'n', false },
preserve_win_context = { opts.preserve_win_context, 'b', false },
list = { opts.list, 't', false },
position = utils.valid_enum(opts.list.position, { 'left', 'right' }, false),
width = { opts.list.width, 'n', false },
Expand All @@ -143,6 +146,10 @@ function config.setup(user_config, actions)
),
})

if opts.preserve_win_context and vim.fn.has('nvim-0.10.0') == 0 then
config.options.preserve_win_context = false
end

-- Filter disabled mappings
for _, mappings in pairs(opts.mappings) do
for key, action in pairs(mappings) do
Expand Down
45 changes: 39 additions & 6 deletions lua/glance/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ local glance = {}
Glance.__index = Glance
local initialized = false
local last_session = nil
local layout_ns = vim.api.nvim_create_namespace('GlanceLayout')

---@param opts? GlanceOpts
function Glance.setup(opts)
Expand Down Expand Up @@ -51,10 +52,15 @@ local function is_open()
return list_is_valid and preview_is_valid
end

local function get_preview_win_height(winnr)
local function get_preview_content_height(winnr)
return math.min(vim.fn.winheight(winnr), config.options.height)
end

local function get_preview_layout_height(winnr)
local border_height = config.options.border.enable and 2 or 0
return get_preview_content_height(winnr) + border_height
end

local function is_detached(winnr)
local detached = config.options.detached
if type(detached) == 'function' then
Expand Down Expand Up @@ -85,7 +91,7 @@ local function get_win_opts(winnr, line)
local list_width =
utils.round(win_width * math.min(0.5, math.max(0.1, opts.list.width)))
local preview_width = win_width - list_width
local height = get_preview_win_height(winnr)
local height = get_preview_content_height(winnr)
local list_pos = opts.list.position
local row = line

Expand Down Expand Up @@ -129,6 +135,31 @@ local function get_win_opts(winnr, line)
return list_win_opts, preview_win_opts
end

-- Creates virtual lines in the parent window to reserve space for the float preview.
-- Uses experimental neovim API that may change in the future `nvim__win_add_ns`
-- to set window-local extmarks
local function append_virtual_lines(winnr, start_row)
if not vim.api.nvim__win_add_ns then
return
end

local bufnr = vim.api.nvim_win_get_buf(winnr)
local height = get_preview_layout_height(winnr)

local virt_lines = {}
for _ = 1, height do
table.insert(virt_lines, { { '', 'NonText' } })
end

vim.api.nvim__win_add_ns(winnr, layout_ns)

vim.api.nvim_buf_set_extmark(bufnr, layout_ns, start_row, 0, {
virt_lines = virt_lines,
virt_lines_above = false,
scoped = true,
})
end

local function create(
results,
parent_bufnr,
Expand Down Expand Up @@ -403,6 +434,10 @@ function Glance:create(opts)
local push_tagstack = utils.create_push_tagstack(opts.winnr)
local list_win_opts, preview_win_opts = get_win_opts(opts.winnr, row)

if config.options.preserve_win_context then
append_virtual_lines(opts.winnr, opts.params.position.line)
end

local list = require('glance.list').create({
results = opts.results,
parent_winnr = opts.winnr,
Expand Down Expand Up @@ -454,10 +489,7 @@ function Glance:scroll_into_view(winnr, position)
local win_height = vim.fn.winheight(winnr)
local row = vim.fn.winline()
local bottom_offset = 2
local border_height = config.options.border.enable and 2 or 0
local preview_height = get_preview_win_height(winnr)
+ border_height
+ bottom_offset
local preview_height = get_preview_layout_height(winnr) + bottom_offset

if preview_height >= win_height then
return 0
Expand Down Expand Up @@ -569,6 +601,7 @@ function Glance:close()
end

function Glance:destroy()
vim.api.nvim_buf_clear_namespace(self.parent_bufnr, layout_ns, 0, -1)
self.list:destroy()
self.preview:destroy()
glance = {}
Expand Down
3 changes: 2 additions & 1 deletion lua/glance/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ function utils.get_line_byte_from_position(line, position, offset_encoding)
if ok then
return result
end
ok, result = pcall(vim.str_byteindex, line, col, offset_encoding == 'utf-16')
ok, result =
pcall(vim.str_byteindex, line, col, offset_encoding == 'utf-16')
if ok then
return result
end
Expand Down

0 comments on commit 9c7e2ab

Please sign in to comment.