Skip to content

Commit b2e0d0c

Browse files
authored
feat: add percent-based current-line positioning
Adds a new option to place the current line based on its progress through the file, instead of keeping it fixed at the viewport middle. Config: - `current_line_position = "percent"` (new) - `current_line_position = "center"` (default/unchanged)
1 parent b225230 commit b2e0d0c

File tree

5 files changed

+44
-3
lines changed

5 files changed

+44
-3
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,14 @@ vim.g.neominimap = {
225225
-- How many rows a dot should span
226226
y_multiplier = 1, ---@type integer
227227

228+
---@alias Neominimap.Config.CurrentLinePosition "center" | "percent"
229+
230+
-- How the minimap places the current line vertically.
231+
-- `"center"` -> pins the line to the viewport middle (window-relative).
232+
-- `"percent"` -> maps line index / total lines to minimap height (file-relative).
233+
-- Note: here "center" means the middle of the **minimap window**, not "center of the file".
234+
current_line_position = "center", ---@type Neominimap.Config.CurrentLinePosition
235+
228236
buffer = {
229237
-- When true, the minimap will be recreated when you delete the buffer.
230238
-- When false, the minimap will be disabled for the current buffer when you delete the minimap buffer.
@@ -405,7 +413,7 @@ vim.g.neominimap = {
405413
signcolumn = "auto",
406414
number = false,
407415
relativenumber = false,
408-
scrolloff = 99999, -- To center minimap
416+
scrolloff = config.current_line_position == "center" and 99999 or 0,
409417
sidescrolloff = 0,
410418
winblend = 0,
411419
cursorline = true,

lua/neominimap/config/internal.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ local M = {
5353
-- How many rows a dot should span
5454
y_multiplier = 1, ---@type integer
5555

56+
---@alias Neominimap.Config.CurrentLinePosition "center" | "percent"
57+
58+
--- How the minimap places the current line vertically.
59+
--- `"center"` -> pins the line to the viewport middle (window-relative).
60+
--- `"percent"` -> maps line index / total lines to minimap height (file-relative).
61+
--- Note: here "center" means the middle of the **minimap window**, not "center of the file".
62+
current_line_position = "center", ---@type Neominimap.Config.CurrentLinePosition
63+
5664
buffer = {
5765
-- When true, the minimap will be recreated when you delete the buffer.
5866
-- When false, the minimap will be disabled for the current buffer when you delete the minimap buffer.

lua/neominimap/config/meta.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ local M = {}
1313
---@field x_multiplier? integer
1414
---@field y_multiplier? integer
1515
---@field sync_cursor? boolean
16+
---@field current_line_position? Neominimap.Config.CurrentLinePosition
1617
---@field buffer? Neominimap.BufferConfig
1718
---@field layout? Neominimap.Config.LayoutType
1819
---@field float? Neominimap.FloatConfig

lua/neominimap/config/validator.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ M.validate_config = function(cfg)
9393
tab_filter = { cfg.tab_filter, "function" },
9494
x_multiplier = { cfg.x_multiplier, "number" },
9595
y_multiplier = { cfg.y_multiplier, "number" },
96+
current_line_position = { cfg.current_line_position, "string" },
9697
sync_cursor = { cfg.sync_cursor, "boolean" },
9798
delay = { cfg.delay, "number" },
9899

lua/neominimap/window/util.lua

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ local default_winopt = {
6060
signcolumn = "auto",
6161
number = false,
6262
relativenumber = false,
63-
scrolloff = 99999, -- To center minimap
63+
scrolloff = config.current_line_position == "center" and 99999 or 0,
6464
sidescrolloff = 0,
6565
winblend = 0,
6666
cursorline = true,
@@ -79,6 +79,23 @@ M.set_winopt = function(opt, winid)
7979
config.winopt(opt, winid)
8080
end
8181

82+
---@param winid integer
83+
---@param row integer
84+
local function set_current_line_by_percentage(winid, row)
85+
local win_h = M.win_get_true_height(winid)
86+
local bufnr = api.nvim_win_get_buf(winid)
87+
local line_cnt = api.nvim_buf_line_count(bufnr)
88+
local topline = math.floor(row - (row * win_h) / line_cnt)
89+
row = math.max(1, math.min(row, line_cnt))
90+
topline = math.max(1, math.min(topline, line_cnt))
91+
return function()
92+
local view = vim.fn.winsaveview()
93+
view.topline = topline
94+
view.lnum = row - 1
95+
vim.fn.winrestview(view)
96+
end
97+
end
98+
8299
---@param swinid integer
83100
---@param mwinid integer
84101
M.sync_to_minimap = function(swinid, mwinid)
@@ -139,7 +156,13 @@ M.sync_to_source = function(swinid, mwinid)
139156
if row <= line_cnt then
140157
local util = require("neominimap.util")
141158
vim.schedule(function()
142-
local ok = util.noautocmd(pcall)(vim.api.nvim_win_set_cursor, mwinid, { row, 0 })
159+
local ok = util.noautocmd(pcall)((function()
160+
if config.current_line_position == "center" then
161+
return vim.api.nvim_win_set_cursor, mwinid, { row, 0 }
162+
else
163+
return api.nvim_win_call, mwinid, set_current_line_by_percentage(mwinid, row)
164+
end
165+
end)())
143166
if not ok then
144167
logger.log.error("Failed to set cursor")
145168
end

0 commit comments

Comments
 (0)