Skip to content

Commit

Permalink
feat(pickers): fully customizable layout (#2572)
Browse files Browse the repository at this point in the history
  • Loading branch information
MunifTanjim authored Sep 27, 2023
1 parent 5c91b85 commit 84d53df
Show file tree
Hide file tree
Showing 15 changed files with 649 additions and 202 deletions.
156 changes: 156 additions & 0 deletions doc/telescope.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ telescope.setup({opts}) *telescope.setup()*

Default: 'horizontal'

*telescope.defaults.create_layout*
create_layout: ~
Configure the layout of Telescope pickers.
See |telescope.pickers.layout| for details.

Default: 'nil'

*telescope.defaults.layout_config*
layout_config: ~
Determines the default configuration values for layout strategies.
Expand Down Expand Up @@ -1947,6 +1954,155 @@ ordered from the lowest priority to the highest priority.
<


================================================================================
LAYOUT *telescope.pickers.layout*

The telescope pickers layout can be configured using the
|telescope.defaults.create_layout| option.

Parameters: ~
- picker : A Picker object.

Return: ~
- layout : instance of `TelescopeLayout` class.

Example: ~
>
local Layout = require "telescope.pickers.layout"

require("telescope").setup {
create_layout = function(picker)
local function create_window(enter, width, height, row, col, title)
local bufnr = vim.api.nvim_create_buf(false, true)
local winid = vim.api.nvim_open_win(bufnr, enter, {
style = "minimal",
relative = "editor",
width = width,
height = height,
row = row,
col = col,
border = "single",
title = title,
})

vim.wo[winid].winhighlight = "Normal:Normal"

return Layout.Window {
bufnr = bufnr,
winid = winid,
}
end

local function destory_window(window)
if window then
if vim.api.nvim_win_is_valid(window.winid) then
vim.api.nvim_win_close(window.winid, true)
end
if vim.api.nvim_buf_is_valid(window.bufnr) then
vim.api.nvim_buf_delete(window.bufnr, { force = true })
end
end
end

local layout = Layout {
picker = picker,
mount = function(self)
self.results = create_window(false, 40, 20, 0, 0, "Results")
self.preview = create_window(false, 40, 23, 0, 42, "Preview")
self.prompt = create_window(true, 40, 1, 22, 0, "Prompt")
end,
unmount = function(self)
destory_window(self.results)
destory_window(self.preview)
destory_window(self.prompt)
end,
update = function(self) end,
}

return layout
end,
}
<

TelescopeWindowBorder.config *TelescopeWindowBorder.config*


Fields: ~
{bufnr} (integer)
{winid} (integer|nil)
{change_title} (nil|function) (self: TelescopeWindowBorder, title:
string, pos?:
"NW"|"N"|"NE"|"SW"|"S"|"SE"):nil


TelescopeWindowBorder *TelescopeWindowBorder*


Fields: ~
{bufnr} (integer|nil)
{winid} (integer|nil)


TelescopeWindow.config *TelescopeWindow.config*


Fields: ~
{bufnr} (integer)
{winid} (integer|nil)
{border} (TelescopeWindowBorder.config|nil)


TelescopeWindow *TelescopeWindow*


Fields: ~
{border} (TelescopeWindowBorder)
{bufnr} (integer)
{winid} (integer)


TelescopeLayout.config *TelescopeLayout.config*


Fields: ~
{mount} (function) (self: TelescopeLayout):nil
{unmount} (function) (self: TelescopeLayout):nil
{update} (function) (self: TelescopeLayout):nil
{prompt} (TelescopeWindow|nil)
{results} (TelescopeWindow|nil)
{preview} (TelescopeWindow|nil)


TelescopeLayout *TelescopeLayout*


Fields: ~
{prompt} (TelescopeWindow)
{results} (TelescopeWindow)
{preview} (TelescopeWindow|nil)


Layout:mount() *telescope.pickers.layout:mount()*
Create the layout. This needs to ensure the required properties are
populated.



Layout:unmount() *telescope.pickers.layout:unmount()*
Destroy the layout. This is responsible for performing clean-up, for
example:
- deleting buffers
- closing windows
- clearing autocmds



Layout:update() *telescope.pickers.layout:update()*
Refresh the layout. This is called when, for example, vim is resized.




================================================================================
LAYOUT *telescope.layout*

Expand Down
8 changes: 4 additions & 4 deletions lua/telescope/actions/generate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ action_generate.refine = function(prompt_bufnr, opts)
end

-- title
if opts.prompt_title and current_picker.prompt_border then
current_picker.prompt_border:change_title(opts.prompt_title)
if opts.prompt_title and current_picker.layout.prompt.border then
current_picker.layout.prompt.border:change_title(opts.prompt_title)
end

if opts.results_title and current_picker.results_border then
current_picker.results_border:change_title(opts.results_title)
if opts.results_title and current_picker.layout.results.border then
current_picker.layout.results.border:change_title(opts.results_title)
end

local results = {}
Expand Down
5 changes: 3 additions & 2 deletions lua/telescope/actions/layout.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ action_layout.toggle_preview = function(prompt_bufnr)
local picker = action_state.get_current_picker(prompt_bufnr)
local status = state.get_status(picker.prompt_bufnr)

if picker.previewer and status.preview_win then
local preview_winid = status.layout.preview and status.layout.preview.winid
if picker.previewer and preview_winid then
picker.hidden_previewer = picker.previewer
picker.previewer = nil
elseif picker.hidden_previewer and not status.preview_win then
elseif picker.hidden_previewer and not preview_winid then
picker.previewer = picker.hidden_previewer
picker.hidden_previewer = nil
else
Expand Down
9 changes: 5 additions & 4 deletions lua/telescope/actions/set.lua
Original file line number Diff line number Diff line change
Expand Up @@ -230,12 +230,13 @@ action_set.scroll_previewer = function(prompt_bufnr, direction)
local previewer = action_state.get_current_picker(prompt_bufnr).previewer
local status = state.get_status(prompt_bufnr)

local preview_winid = status.layout.preview and status.layout.preview.winid
-- Check if we actually have a previewer and a preview window
if type(previewer) ~= "table" or previewer.scroll_fn == nil or status.preview_win == nil then
if type(previewer) ~= "table" or previewer.scroll_fn == nil or preview_winid == nil then
return
end

local default_speed = vim.api.nvim_win_get_height(status.preview_win) / 2
local default_speed = vim.api.nvim_win_get_height(status.layout.preview.winid) / 2
local speed = status.picker.layout_config.scroll_speed or default_speed

previewer:scroll_fn(math.floor(speed * direction))
Expand Down Expand Up @@ -270,12 +271,12 @@ end
-- Valid directions include: "1", "-1"
action_set.scroll_results = function(prompt_bufnr, direction)
local status = state.get_status(prompt_bufnr)
local default_speed = vim.api.nvim_win_get_height(status.results_win) / 2
local default_speed = vim.api.nvim_win_get_height(status.layout.results.winid) / 2
local speed = status.picker.layout_config.scroll_speed or default_speed

local input = direction > 0 and [[]] or [[]]

vim.api.nvim_win_call(status.results_win, function()
vim.api.nvim_win_call(status.layout.results.winid, function()
vim.cmd([[normal! ]] .. math.floor(speed) .. input)
end)

Expand Down
6 changes: 4 additions & 2 deletions lua/telescope/builtin/__internal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -991,8 +991,10 @@ internal.colorscheme = function(opts)
preview_fn = function(_, entry, status)
if not deleted then
deleted = true
del_win(status.preview_win)
del_win(status.preview_border_win)
if status.layout.preview then
del_win(status.layout.preview.winid)
del_win(status.layout.preview.border.winid)
end
end
vim.cmd("colorscheme " .. entry.value)
end,
Expand Down
10 changes: 10 additions & 0 deletions lua/telescope/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,16 @@ append(
Default: 'horizontal']]
)

append(
"create_layout",
nil,
[[
Configure the layout of Telescope pickers.
See |telescope.pickers.layout| for details.
Default: 'nil']]
)

append("layout_config", layout_config_defaults, layout_config_description)

append(
Expand Down
Loading

0 comments on commit 84d53df

Please sign in to comment.