Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update display config methods #823

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
fa38539
First attempt: add hierarchy and {padding=...} option
l-kershaw May 7, 2021
757fdc2
Update layout strategies to use new method
l-kershaw May 7, 2021
289b894
Update the validate layout_config function for hierarchy
l-kershaw May 7, 2021
b82c743
validate_layout_config: only check the given strategy
l-kershaw May 7, 2021
f558a53
Switch to included version of deepcopy
l-kershaw May 8, 2021
fc485ce
[docgen] Update doc/telescope.txt
May 8, 2021
f6722c1
Add layout_defaults
l-kershaw May 8, 2021
eec0a4d
Merge branch 'display_config' of https://github.com/l-kershaw/telesco…
l-kershaw May 8, 2021
e5a4364
Improve layout diagrams
l-kershaw May 8, 2021
d762448
[docgen] Update doc/telescope.txt
May 8, 2021
e4c797f
Add documentation for size resolver functions
l-kershaw May 8, 2021
0f3c9ee
[docgen] Update doc/telescope.txt
May 8, 2021
9d4fab8
Add resolver functions file to docgen
l-kershaw May 8, 2021
bd40df7
[docgen] Update doc/telescope.txt
May 8, 2021
911003c
Correct links to resolver functions
l-kershaw May 8, 2021
5d29e35
[docgen] Update doc/telescope.txt
May 8, 2021
245be0a
Remove get_width_opt, now handled by validate_layout_config
l-kershaw May 12, 2021
e710e46
Add documentation for defaults affecting layout
l-kershaw May 13, 2021
3256829
[docgen] Update doc/telescope.txt
May 13, 2021
f46d9b2
Rename `layout_defaults` to `layout_config`
l-kershaw May 14, 2021
c651f21
[docgen] Update doc/telescope.txt
May 14, 2021
e269210
Changes suggested by tjdevries
l-kershaw May 16, 2021
a8a97f6
Merge branch 'master' into display_config
l-kershaw May 16, 2021
7ba80ce
Fix typo
l-kershaw May 16, 2021
5b2fdef
Add resolving to `bottom_pane` strategy
l-kershaw May 16, 2021
bec87e3
Improve documentation for `resolve_height` and `resolve_width`
l-kershaw May 16, 2021
87ffc50
Small changes to documentation
l-kershaw May 16, 2021
eddc27b
Attempt to add functionality from PR #773
l-kershaw May 16, 2021
97dd75e
[docgen] Update doc/telescope.txt
May 16, 2021
c9da4d2
Message instead of error when using 'layout_default'
l-kershaw May 17, 2021
2c1d42f
Allow layout_config keys if they are valid for any layout_strategy
l-kershaw May 17, 2021
cc2c8b5
Merge branch 'display_config' of https://github.com/l-kershaw/telesco…
l-kershaw May 17, 2021
ee7e175
[docgen] Update doc/telescope.txt
May 17, 2021
5c45e79
feat: much code
tjdevries May 19, 2021
0cace86
Add layout function descriptions + some small changes
l-kershaw May 19, 2021
450d150
Refactor setting options using `config.set_defaults`
l-kershaw May 20, 2021
6ca31e2
Linting
l-kershaw May 20, 2021
33ce376
First attempt at `layout_default` inheritance tests
l-kershaw May 20, 2021
743601c
Second attempt at `layout_default` inheritance tests
l-kershaw May 20, 2021
904b8eb
Add more `layout_config` inheritance tests
l-kershaw May 21, 2021
557485e
Implements a smarter table extend for `layout_config`
l-kershaw May 24, 2021
9699e68
wip: preview_cutoff and prompt_position
tjdevries May 31, 2021
87b67d3
[WIP]: Wed 09 Jun 2021 08:48:06 AM EDT
tjdevries Jun 9, 2021
617d62e
working on docs and clarifications
tjdevries Jun 9, 2021
28f3b27
[docgen] Update doc/telescope.txt
Jun 9, 2021
3a1ce1f
Resolve `preview_cutoff` (first attempt)
l-kershaw Jun 9, 2021
172bd53
[docgen] Update doc/telescope.txt
Jun 9, 2021
b037cb1
Linting
l-kershaw Jun 9, 2021
dba65d3
Revert "Resolve `preview_cutoff` (first attempt)"
l-kershaw Jun 10, 2021
337c997
Revert "[docgen] Update doc/telescope.txt"
l-kershaw Jun 10, 2021
4935eae
Switch `preview_cutoff` to check lines for `center` and `vertical` st…
l-kershaw Jun 10, 2021
9863e71
[docgen] Update doc/telescope.txt
Jun 10, 2021
8a0d26b
Reduce duplicated layout info in readme
l-kershaw Jun 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lua/telescope/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ function config.set_defaults(defaults)
set("layout_strategy", "horizontal")
set("layout_defaults", {})

set("width", 0.75)
-- set("width", 0.75)
set("winblend", 0)
set("prompt_position", "bottom")
set("preview_cutoff", 120)

set("results_height", 1)
set("results_height", 5)
set("results_width", 0.8)

set("prompt_prefix", "> ", [[
Expand Down
27 changes: 24 additions & 3 deletions lua/telescope/config/resolve.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ height =

3. function(picker, columns, lines)
-> returns one of the above options
return max.min(110, max_rows * .5)
return math.min(110, max_rows * .5)

if columns > 120 then
return 110
Expand Down Expand Up @@ -88,8 +88,7 @@ That's the next step to scrolling.
local get_default = require('telescope.utils').get_default

local resolver = {}

local _resolve_map = {
local _simple_resolve_map = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is probably easier to understand by just doing _resolve_map = {} and then each of the following with _resolve_map[function() ...] = ... etc.

I don't think we need to do the copy thing, right?

Or is this because only some keys are considered "simple"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally, I was getting some issues where the padding case in _resolve_map was referring back to _resolve_map.

I don't seem to be getting those issues now, so I've changed to just using _resolve_map instead of _simple_resolve_map.
I'll keep an eye out for any issues re-emerging.

-- Booleans
[function(val) return val == false end] = function(selector, val)
return function(...)
Expand Down Expand Up @@ -128,6 +127,28 @@ local _resolve_map = {
end,
}

-- Make a copy of the "simple" _resolve_map that we can add to to make the "full" _resolve_map.
local _resolve_map = require('luassert.util').deepcopy(_simple_resolve_map)
l-kershaw marked this conversation as resolved.
Show resolved Hide resolved

-- Add padding option
_resolve_map[function(val) return type(val) == 'table' and val['padding'] ~= nil end] = function(selector, val)
local resolve_pad = function(value)
for k, v in pairs(_simple_resolve_map) do
if k(value) then
return v(selector, value)
end
end

error('invalid configuration option for padding:' .. tostring(value))
end

return function(...)
local selected = select(selector, ...)
local padding = resolve_pad(val['padding'])
return math.floor(selected - 2 * padding(...))
end
end

resolver.resolve_height = function(val)
for k, v in pairs(_resolve_map) do
if k(val) then
Expand Down
7 changes: 4 additions & 3 deletions lua/telescope/pickers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,20 @@ function Picker:new(opts)
layout_strategy = layout_strategy,
layout_config = get_default(
opts.layout_config,
(config.values.layout_defaults or {})[layout_strategy]
config.values.layout_defaults
) or {},

window = {
-- TODO: This won't account for different layouts...
-- TODO: If it's between 0 and 1, it's a percetnage.
-- TODO: If its's a single number, it's always that many columsn
-- TODO: If it's between 0 and 1, it's a percentage.
-- TODO: If it's a single number, it's always that many columns
l-kershaw marked this conversation as resolved.
Show resolved Hide resolved
-- TODO: If it's a list, of length 2, then it's a range of min to max?
height = get_default(opts.height, 0.8),
width = get_default(opts.width, config.values.width),

get_preview_width = get_default(opts.preview_width, config.values.get_preview_width),

-- TODO: figure out the intention of this option. It doesn't currently do anything
l-kershaw marked this conversation as resolved.
Show resolved Hide resolved
results_width = get_default(opts.results_width, config.values.results_width),
results_height = get_default(opts.results_height, config.values.results_height),

Expand Down
191 changes: 128 additions & 63 deletions lua/telescope/pickers/layout_strategies.lua
Original file line number Diff line number Diff line change
Expand Up @@ -94,26 +94,91 @@ local function get_initial_window_options(picker)
}
end

-- Get the width to be used for a given strategy
local function get_width_opt(picker, layout_config, strat)
if picker.window.width ~= nil then
return picker.window.width
elseif layout_config[strat] ~= nil and layout_config[strat].width ~=nil then
return picker.layout_config[strat].width
elseif layout_config.width ~= nil then
return layout_config.width
end

-- TODO: provide more information in this error.
error('Unsupported width options provided.')
end

-- Get the height to be used for a given strategy
local function get_height_opt(picker, layout_config, strat)
if picker.window.width ~= nil then
return picker.window.width
elseif layout_config[strat] ~= nil and layout_config[strat].width ~=nil then
return layout_config[strat].width
elseif layout_config.width ~= nil then
return layout_config.width
end
end

-- Check if there are any borders. Right now it's a little raw as
-- there are a few things that contribute to the border
local is_borderless = function(opts)
return opts.window.border == false
end

-- TODO: make an automatic way to create this list
-- could just use layout_strategies???
local layout_list = {horizontal=1,vertical=1,flex=1,center=1,current_buffer=1}
l-kershaw marked this conversation as resolved.
Show resolved Hide resolved

local function validate_layout_config(strategy, options, values)
local result = {}
-- Define a function to check that the keys in options match those
-- in values or those in layout_list
local function key_check(opts,vals,strat)
for k, _ in pairs(opts) do
if not vals[k] and not layout_list[k] then
if strat == nil then
error(string.format(
"Unsupported layout_config key: %s\n%s",
k,
vim.inspect(vals)
))
else
error(string.format(
"Unsupported layout_config key for the %s strategy: %s\n%s",
strat,
k,
vim.inspect(vals)
))
end
end
end
end

local function validate_layout_config(options, values)
for k, _ in pairs(options) do
if not values[k] then
-- Check that options has the correct form for this strategy
key_check(options,values)
if options[strategy] ~= nil then
if type(options[strategy]) ~= 'table' then
error(string.format(
"Unsupported layout_config key: %s\n%s",
k,
vim.inspect(values)
'Unsupported layout_config for the %s strategy: %s\n%s\nShould be a table',
strategy,
vim.inspect(options[strategy])
))
else
key_check(options[strategy],values)
end
end

-- Create the output table
for k, _ in pairs(values) do
-- Prioritise values that are specific to this strategy
if options[strategy] ~= nil and options[strategy][k] ~= nil then
result[k] = options[strategy][k]
elseif values[k] ~= nil then
result[k] = options[k]
end
end

return options
return result
end

local layout_strategies = {}
Expand All @@ -131,9 +196,9 @@ local layout_strategies = {}
--- +-------------+--------------+
--- </pre>
layout_strategies.horizontal = function(self, max_columns, max_lines)
local layout_config = validate_layout_config(self.layout_config or {}, {
width_padding = "How many cells to pad the width",
height_padding = "How many cells to pad the height",
local layout_config = validate_layout_config('horizontal',self.layout_config or {}, {
width = "How wide the picker is",
height = "How tall the picker is",
preview_width = "(Resolvable): Determine preview width",
mirror = "Flip the location of the results/prompt and preview windows",
scroll_speed = "The speed when scrolling through the previewer",
Expand All @@ -146,25 +211,13 @@ layout_strategies.horizontal = function(self, max_columns, max_lines)

-- TODO: Test with 120 width terminal
-- TODO: Test with self.width
local width_padding = resolve.resolve_width(layout_config.width_padding or function(_, cols)
if cols < self.preview_cutoff then
return 2
elseif cols < 150 then
return 5
else
return 10
end
end)(self, max_columns, max_lines)
local picker_width = max_columns - 2 * width_padding
local width_opt = get_width_opt(self,layout_config,'horizontal')
local picker_width = resolve.resolve_width(width_opt)(self,max_columns,max_lines)
local width_padding = math.floor((max_columns - picker_width)/2)

local height_padding = resolve.resolve_height(layout_config.height_padding or function(_, _, lines)
if lines < 40 then
return 4
else
return math.floor(0.1 * lines)
end
end)(self, max_columns, max_lines)
local picker_height = max_lines - 2 * height_padding
local height_opt = get_height_opt(self,layout_config,'horizontal')
local picker_height = resolve.resolve_height(height_opt)(self,max_columns,max_lines)
local height_padding = math.floor((max_lines - picker_height)/2)

if self.previewer then
preview.width = resolve.resolve_width(layout_config.preview_width or function(_, cols)
Expand Down Expand Up @@ -223,31 +276,45 @@ layout_strategies.horizontal = function(self, max_columns, max_lines)
}
end

--- Centered layout wih smaller default sizes (I think)
--- Centered layout with a combined block of the prompt
--- and results aligned to the middle of the screen.
--- The preview window is then placed in the space above.
---
--- <pre>
--- +--------------+
--- ┌──────────────┐
--- | Preview |
--- +--------------+
--- | Preview |
--- └──────────────┘
--- ┌──────────────┐
--- | Prompt |
--- +--------------+
--- | Result |
--- ├──────────────┤
--- | Result |
--- | Result |
--- +--------------+
--- └──────────────┘
---
---
--- </pre>
layout_strategies.center = function(self, columns, lines)
layout_strategies.center = function(self, max_columns, max_lines)
local layout_config = validate_layout_config('center',self.layout_config or {}, {
width = "How wide the picker is",
preview_height = "(Resolvable): Determine preview height",
mirror = "Flip the locations of the results and prompt windows",
scroll_speed = "The speed when scrolling through the previewer",
})
local initial_options = get_initial_window_options(self)
local preview = initial_options.preview
local results = initial_options.results
local prompt = initial_options.prompt

-- This sets the height/width for the whole layout
local height = resolve.resolve_height(self.window.results_height)(self, columns, lines)
local width = resolve.resolve_width(self.window.width)(self, columns, lines)
-- This sets the width for the whole layout
local width_opt = get_width_opt(self,layout_config,'center')
local width = resolve.resolve_width(width_opt)(self, max_columns, max_lines)

local max_results = (height > lines and lines or height)
local max_width = (width > columns and columns or width)
-- This sets the number of results displayed
local res_height = resolve.resolve_height(self.window.results_height)(self, max_columns, max_lines)

local max_results = (res_height > max_lines and max_lines or res_height)
local max_width = (width > max_columns and max_columns or width)

prompt.height = 1
results.height = max_results
Expand All @@ -262,17 +329,19 @@ layout_strategies.center = function(self, columns, lines)
bs = 0
end

prompt.line = (lines / 2) - ((max_results + (bs * 2)) / 2)
-- Align the prompt and results so halfway up the screen is
-- in the middle of this combined block
prompt.line = (max_lines / 2) - ((max_results + (bs * 2)) / 2)
results.line = prompt.line + 1 + (bs)

preview.line = 1
preview.height = math.floor(prompt.line - (2 + bs))

if not self.previewer or columns < self.preview_cutoff then
if not self.previewer or max_columns < self.preview_cutoff then
preview.height = 0
end

results.col = math.ceil((columns / 2) - (width / 2) - bs)
results.col = math.ceil((max_columns / 2) - (width / 2) - bs)
prompt.col = results.col
preview.col = results.col

Expand All @@ -283,7 +352,7 @@ layout_strategies.center = function(self, columns, lines)
}
end

--- Vertical perviewer stacks the items on top of each other.
--- Vertical previewer stacks the items on top of each other.
---
--- <pre>
--- +-----------------+
Expand All @@ -299,9 +368,9 @@ end
--- +-----------------+
--- </pre>
layout_strategies.vertical = function(self, max_columns, max_lines)
local layout_config = validate_layout_config(self.layout_config or {}, {
width_padding = "How many cells to pad the width",
height_padding = "How many cells to pad the height",
local layout_config = validate_layout_config('vertical',self.layout_config or {}, {
width = "How many cells to pad the width",
height = "How many cells to pad the height",
preview_height = "(Resolvable): Determine preview height",
mirror = "Flip the locations of the results and prompt windows",
scroll_speed = "The speed when scrolling through the previewer",
Expand All @@ -312,31 +381,27 @@ layout_strategies.vertical = function(self, max_columns, max_lines)
local results = initial_options.results
local prompt = initial_options.prompt

local width_padding = resolve.resolve_width(
layout_config.width_padding or math.ceil((1 - self.window.width) * 0.5 * max_columns)
)(self, max_columns, max_lines)
local width_opt = get_width_opt(self,layout_config,'horizontal')
local picker_width = resolve.resolve_width(width_opt)(self,max_columns,max_lines)
local width_padding = math.floor((max_columns - picker_width)/2)

local height_opt = get_height_opt(self,layout_config,'horizontal')
local picker_height = resolve.resolve_height(height_opt)(self,max_columns,max_lines)
local height_padding = math.floor((max_lines - picker_height)/2)

local width = max_columns - width_padding * 2
if not self.previewer then
preview.width = 0
else
preview.width = width
preview.width = picker_width
end
results.width = width
prompt.width = width

-- Height
local height_padding = math.max(
1,
resolve.resolve_height(layout_config.height_padding or 3)(self, max_columns, max_lines)
)
local picker_height = max_lines - 2 * height_padding
results.width = picker_width
prompt.width = picker_width

local preview_total = 0
preview.height = 0
if self.previewer then
preview.height = resolve.resolve_height(
layout_config.preview_height or (max_lines - 15)
layout_config.preview_height or 0.5
)(self, max_columns, picker_height)

preview_total = preview.height + 2
Expand Down Expand Up @@ -392,7 +457,7 @@ layout_strategies.flex = function(self, max_columns, max_lines)
end

layout_strategies.current_buffer = function(self, _, _)
local initial_options = self:_get_initial_window_options()
local initial_options = get_initial_window_options(self)

local window_width = vim.api.nvim_win_get_width(0)
local window_height = vim.api.nvim_win_get_height(0)
Expand Down
Loading