@@ -115,34 +115,110 @@ local function compute_layout(config)
115115 local width = math.floor (terminal_width * width_ratio )
116116 local height = math.floor (terminal_height * height_ratio )
117117
118- local col_ratio_default = 0.5 - (width_ratio / 2 )
119- local col_ratio = col_ratio_default
118+ -- Account for chrome (statusline, tabline, cmdheight) for edge-anchored positions
119+ local has_tabline = vim .o .showtabline == 2 or (vim .o .showtabline == 1 and # vim .api .nvim_list_tabpages () > 1 )
120+ local has_statusline = vim .o .laststatus > 0
121+ local top_edge = has_tabline and 1 or 0
122+ local bottom_edge = terminal_height - vim .o .cmdheight - (has_statusline and 1 or 0 )
123+ local usable_height = bottom_edge - top_edge
124+ height = math.min (height , usable_height )
125+
126+ -- Anchor controls default placement; manual col/row overrides still work
127+ local anchor = utils .resolve_config_value (
128+ config .layout .anchor ,
129+ terminal_width ,
130+ terminal_height ,
131+ function (v )
132+ return utils .is_one_of (v , {
133+ ' center' ,
134+ ' top_left' ,
135+ ' top' ,
136+ ' top_right' ,
137+ ' left' ,
138+ ' right' ,
139+ ' bottom_left' ,
140+ ' bottom' ,
141+ ' bottom_right' ,
142+ })
143+ end ,
144+ ' center' ,
145+ ' layout.anchor'
146+ )
147+
148+ -- Compute default positions as direct pixel values.
149+ -- Edge-flush anchors compensate for offsets added by calculate_layout_dimensions:
150+ -- col: -1 for left (internal +1 on list_col makes it flush)
151+ -- -2 for right (internal +1 plus the preview window's independent right border)
152+ -- row: -1 for top/bottom (internal +1 on rows; bottom also accounts for chrome via bottom_edge)
153+ local center_col = math.floor ((terminal_width - width ) / 2 )
154+ local center_row = top_edge + math.floor ((usable_height - height ) / 2 )
155+ local anchor_positions = {
156+ center = {
157+ col = center_col ,
158+ row = center_row ,
159+ },
160+ top_left = {
161+ col = - 1 ,
162+ row = top_edge - 1 ,
163+ },
164+ top = {
165+ col = center_col ,
166+ row = top_edge - 1 ,
167+ },
168+ top_right = {
169+ col = terminal_width - width - 2 ,
170+ row = top_edge - 1 ,
171+ },
172+ left = {
173+ col = - 1 ,
174+ row = center_row ,
175+ },
176+ right = {
177+ col = terminal_width - width - 2 ,
178+ row = center_row ,
179+ },
180+ bottom_left = {
181+ col = - 1 ,
182+ row = bottom_edge - height - 1 ,
183+ },
184+ bottom = {
185+ col = center_col ,
186+ row = bottom_edge - height - 1 ,
187+ },
188+ bottom_right = {
189+ col = terminal_width - width - 2 ,
190+ row = bottom_edge - height - 1 ,
191+ },
192+ }
193+
194+ local pos = anchor_positions [anchor ] or anchor_positions .center
195+ local col = pos .col
196+ local row = pos .row
197+
198+ -- Allow manual ratio overrides (backwards compat)
120199 if config .layout .col ~= nil then
121- col_ratio = utils .resolve_config_value (
200+ local col_ratio = utils .resolve_config_value (
122201 config .layout .col ,
123202 terminal_width ,
124203 terminal_height ,
125204 utils .is_valid_ratio ,
126- col_ratio_default ,
205+ col / terminal_width ,
127206 ' layout.col'
128207 )
208+ col = math.floor (terminal_width * col_ratio )
129209 end
130- local row_ratio_default = 0.5 - (height_ratio / 2 )
131- local row_ratio = row_ratio_default
132210 if config .layout .row ~= nil then
133- row_ratio = utils .resolve_config_value (
211+ local row_ratio = utils .resolve_config_value (
134212 config .layout .row ,
135213 terminal_width ,
136214 terminal_height ,
137215 utils .is_valid_ratio ,
138- row_ratio_default ,
216+ row / terminal_height ,
139217 ' layout.row'
140218 )
219+ row = math.floor (terminal_height * row_ratio )
141220 end
142221
143- local col = math.floor (terminal_width * col_ratio )
144- local row = math.floor (terminal_height * row_ratio )
145-
146222 local prompt_position = get_prompt_position ()
147223 local preview_position = get_preview_position ()
148224
0 commit comments