Skip to content

Commit c774321

Browse files
authored
feat(ui): add configurable window position (#26)
Adds `ui.position` option to control where the marks window appears. Defaults to 'center'. Supported values: - top_center: positions the window near the top, centered horizontally - bottom_center: positions it near the bottom - center: keeps the existing centered behavior
1 parent fb75cb9 commit c774321

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ Vim's built-in marks are great, but they're global and get messy fast. Marksman
6161
silent = false,
6262
disable_default_keymaps = false,
6363
debounce_ms = 500,
64+
ui = {
65+
position = "center", -- "center", "top_center", or "bottom_center"
66+
},
6467
},
6568
}
6669
```
@@ -129,6 +132,9 @@ require("marksman").setup({
129132
silent = false, -- Suppress notifications
130133
disable_default_keymaps = false,
131134
debounce_ms = 500, -- Save debounce (100-5000ms)
135+
ui = {
136+
position = "center", -- Window position: "center", "top_center", or "bottom_center"
137+
},
132138
highlights = {
133139
ProjectMarksTitle = { fg = "#61AFEF", bold = true },
134140
ProjectMarksNumber = { fg = "#C678DD" },

lua/marksman/init.lua

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,36 @@ local default_config = {
3434
},
3535
auto_save = true,
3636
max_marks = 100,
37-
search_in_ui = true,
3837
silent = false,
3938
minimal = false,
4039
disable_default_keymaps = false,
4140
debounce_ms = 500, -- Debounce save operations
41+
ui = {
42+
-- Position of the marks window.
43+
-- "center" positions the window in the middle of the editor (default).
44+
-- "top_center" aligns the window at the top of the screen, centered horizontally.
45+
-- "bottom_center" aligns the window at the bottom of the screen, centered horizontally.
46+
position = "center",
47+
},
4248
}
4349

4450
-- Configuration validation schema
4551
local config_schema = {
4652
auto_save = { type = "boolean" },
4753
max_marks = { type = "number", min = 1, max = 1000 },
48-
search_in_ui = { type = "boolean" },
4954
silent = { type = "boolean" },
5055
minimal = { type = "boolean" },
5156
disable_default_keymaps = { type = "boolean" },
5257
debounce_ms = { type = "number", min = 100, max = 5000 },
58+
ui = {
59+
type = "table",
60+
fields = {
61+
position = {
62+
type = "string",
63+
allowed = { "center", "top_center", "bottom_center" },
64+
},
65+
},
66+
},
5367
}
5468

5569
local config = {}

lua/marksman/ui.lua

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,8 +624,43 @@ function M.show_marks_window(marks, project_name, search_query)
624624
pcall(vim.api.nvim_buf_add_highlight, buf, -1, hl.hl_group, hl.line, hl.col, hl.end_col)
625625
end
626626

627-
-- Calculate window position (centered)
628-
local row = math.floor((vim.o.lines - WINDOW_HEIGHT) / 2)
627+
-- Calculate window position based on user configuration. By default the
628+
-- marks window is centered in the editor, but users can override
629+
-- this by specifying ui.position in their plugin configuration. A
630+
-- value of "top_center" positions the window near the top of the
631+
-- screen, while "bottom_center" aligns it near the bottom. Any
632+
-- unrecognised value falls back to the centered position. We also
633+
-- clamp the row so the window never renders outside the visible
634+
-- editor lines. Note: vim.o.lines returns the total number of
635+
-- lines in the UI (not just the buffer), so subtracting the window
636+
-- height ensures the window is fully on screen.
637+
local pos = nil
638+
if config and type(config.ui) == "table" then
639+
pos = config.ui.position
640+
end
641+
local row
642+
if pos == "top_center" then
643+
-- Place the window a couple of lines down to avoid
644+
-- overlapping the very top of the UI. A value of 1 gives
645+
-- a small margin but still keeps the window anchored near
646+
-- the top.
647+
row = 1
648+
elseif pos == "bottom_center" then
649+
-- Place the window a couple of lines above the bottom to
650+
-- leave room for command line and status line. We subtract
651+
-- 2 to account for the border and padding.
652+
row = vim.o.lines - WINDOW_HEIGHT - 2
653+
else
654+
-- Default to center positioning
655+
row = math.floor((vim.o.lines - WINDOW_HEIGHT) / 2)
656+
end
657+
-- Ensure row stays within valid bounds
658+
if row < 0 then
659+
row = 0
660+
elseif row > vim.o.lines - WINDOW_HEIGHT then
661+
row = math.max(vim.o.lines - WINDOW_HEIGHT, 0)
662+
end
663+
-- Always center horizontally
629664
local col = math.floor((vim.o.columns - WINDOW_WIDTH) / 2)
630665

631666
-- Window title
@@ -701,3 +736,4 @@ function M.cleanup()
701736
end
702737

703738
return M
739+

0 commit comments

Comments
 (0)