mirror of
https://github.com/zoriya/telescope.nvim.git
synced 2025-12-06 06:46:10 +00:00
feat: Consistent and sensible layout_config (#922)
* feat: Consistent and sensible layout_config * [docgen] Update doc/telescope.txt skip-checks: true * [WIP]: Thu 17 Jun 2021 03:36:44 PM EDT * [WIP]: Thu 17 Jun 2021 03:38:11 PM EDT * layout_default -> layout_defaults * remove options from bug repot * Conni2461 suggestions: part 1 * [docgen] Update doc/telescope.txt skip-checks: true * Conni2461 suggestions: part 2 * [docgen] Update doc/telescope.txt skip-checks: true * Linting * Improve deprecation checks - Move `layout_defaults` handling to `deprecated.lua` - Check for "layout keys" outside of `layout_config` on `setup` * fixup: Just add a few more words Co-authored-by: Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> Co-authored-by: Github Actions <actions@github>
This commit is contained in:
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -88,37 +88,5 @@ Plug 'nvim-telescope/telescope.nvim'
|
||||
call plug#end()
|
||||
|
||||
autocmd VimEnter * PlugClean! | PlugUpdate --sync | close
|
||||
lua << EOF
|
||||
|
||||
require('telescope').setup{
|
||||
defaults = {
|
||||
vimgrep_arguments = {
|
||||
'rg',
|
||||
'--color=never',
|
||||
'--no-heading',
|
||||
'--with-filename',
|
||||
'--line-number',
|
||||
'--column',
|
||||
'--smart-case'
|
||||
},
|
||||
prompt_position = "bottom",
|
||||
prompt_prefix = ">",
|
||||
selection_strategy = "reset",
|
||||
sorting_strategy = "descending",
|
||||
layout_strategy = "horizontal",
|
||||
layout_defaults = {},
|
||||
file_ignore_patterns = {},
|
||||
shorten_path = true,
|
||||
winblend = 0,
|
||||
width = 0.75,
|
||||
preview_cutoff = 120,
|
||||
results_height = 1,
|
||||
results_width = 0.8,
|
||||
border = {},
|
||||
borderchars = { '─', '│', '─', '│', '╭', '╮', '╯', '╰'},
|
||||
color_devicons = true,
|
||||
use_less = true,
|
||||
}
|
||||
}
|
||||
EOF
|
||||
lua require('telescope').setup()
|
||||
```
|
||||
|
||||
70
README.md
70
README.md
@@ -138,7 +138,6 @@ require('telescope').setup{
|
||||
'--column',
|
||||
'--smart-case'
|
||||
},
|
||||
prompt_position = "bottom",
|
||||
prompt_prefix = "> ",
|
||||
selection_caret = "> ",
|
||||
entry_prefix = " ",
|
||||
@@ -146,7 +145,7 @@ require('telescope').setup{
|
||||
selection_strategy = "reset",
|
||||
sorting_strategy = "descending",
|
||||
layout_strategy = "horizontal",
|
||||
layout_defaults = {
|
||||
layout_config = {
|
||||
horizontal = {
|
||||
mirror = false,
|
||||
},
|
||||
@@ -159,10 +158,6 @@ require('telescope').setup{
|
||||
generic_sorter = require'telescope.sorters'.get_generic_fuzzy_sorter,
|
||||
shorten_path = true,
|
||||
winblend = 0,
|
||||
width = 0.75,
|
||||
preview_cutoff = 120,
|
||||
results_height = 1,
|
||||
results_width = 0.8,
|
||||
border = {},
|
||||
borderchars = { '─', '│', '─', '│', '╭', '╮', '╯', '╰' },
|
||||
color_devicons = true,
|
||||
@@ -196,24 +191,19 @@ EOF
|
||||
|
||||
| Keys | Description | Options |
|
||||
|------------------------|-------------------------------------------------------|----------------------------|
|
||||
| `prompt_position` | Where the prompt should be located. | top/bottom |
|
||||
| `prompt_prefix` | What should the prompt prefix be. | string |
|
||||
| `selection_caret` | What should the selection caret be. | string |
|
||||
| `entry_prefix` | What should be shown in front of every entry. (current selection excluded) | string|
|
||||
| `initial_mode` | The initial mode when a prompt is opened. | insert/normal |
|
||||
| `sorting_strategy` | Where first selection should be located. | descending/ascending |
|
||||
| `layout_strategy` | How the telescope is drawn. | [supported layouts](https://github.com/nvim-telescope/telescope.nvim/wiki/Layouts) |
|
||||
| `winblend` | How transparent is the telescope window should be. | NUM |
|
||||
| `layout_defaults` | Extra settings for fine-tuning how your layout looks | [supported settings](https://github.com/nvim-telescope/telescope.nvim/wiki/Layouts#layout-defaults) |
|
||||
| `width` | TODO | NUM |
|
||||
| `preview_cutoff` | TODO | NUM |
|
||||
| `results_height` | TODO | NUM |
|
||||
| `results_width` | TODO | NUM |
|
||||
| `layout_config` | Extra settings for fine-tuning how your layout looks | [supported settings](https://github.com/nvim-telescope/telescope.nvim/wiki/Layouts#layout-defaults) |
|
||||
| `sorting_strategy` | Where first selection should be located. | descending/ascending |
|
||||
| `scroll_strategy` | How to behave when the when there are no more item next/prev | cycle, nil |
|
||||
| `winblend` | How transparent is the telescope window should be. | number |
|
||||
| `borderchars` | The border chars, it gives border telescope window | dict |
|
||||
| `color_devicons` | Whether to color devicons or not | boolean |
|
||||
| `use_less` | Whether to use less with bat or less/cat if bat not installed | boolean |
|
||||
| `set_env` | Set environment variables for previewer | dict |
|
||||
| `scroll_strategy` | How to behave when the when there are no more item next/prev | cycle, nil |
|
||||
| `file_previewer` | What telescope previewer to use for files. | [Previewers](#previewers) |
|
||||
| `grep_previewer` | What telescope previewer to use for grep and similar | [Previewers](#previewers) |
|
||||
| `qflist_previewer` | What telescope previewer to use for qflist | [Previewers](#previewers) |
|
||||
@@ -446,7 +436,7 @@ Built-in functions. Ready to be bound to any key you like. :smile:
|
||||
| `builtin.current_buffer_fuzzy_find` | Live fuzzy search inside of the currently open buffer |
|
||||
| `builtin.current_buffer_tags` | Lists all of the tags for the currently open buffer, with a preview |
|
||||
|
||||
### LSP Pickers
|
||||
### Neovim LSP Pickers
|
||||
|
||||
| Functions | Description |
|
||||
|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
@@ -644,7 +634,6 @@ Picker:new{
|
||||
selection_strategy = "reset", -- follow, reset, row
|
||||
border = {},
|
||||
borderchars = {"─", "│", "─", "│", "┌", "┐", "┘", "└"},
|
||||
preview_cutoff = 120,
|
||||
default_selection_index = 1, -- Change the index of the initial selection row
|
||||
}
|
||||
```
|
||||
@@ -677,24 +666,37 @@ end
|
||||
### Layout (display)
|
||||
<!-- TODO need some work -->
|
||||
|
||||
`Resolvable`:
|
||||
1. 0 <= number < 1:
|
||||
- This means total height as a percentage
|
||||
2. 1 <= number:
|
||||
- This means total height as a fixed number
|
||||
3. function(picker, columns, lines):
|
||||
- returns one of the above options
|
||||
- `return max.min(110, max_rows * .5)`
|
||||
Layout can be configured by choosing a specific `layout_strategy` and
|
||||
specifying a particular `layout_config` for that strategy.
|
||||
For more details on available strategies and configuration options,
|
||||
see `:help telescope.layout`.
|
||||
|
||||
```lua
|
||||
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",
|
||||
preview_width = "(Resolvable): Determine preview width",
|
||||
})
|
||||
...
|
||||
end
|
||||
Some options for configuring sizes in layouts are "resolvable".
|
||||
This means that they can take different forms, and will be interpreted differently according to which form they take.
|
||||
For example, if we wanted to set the `width` of a picker using the `vertical`
|
||||
layout strategy to 50% of the screen width, we would specify that width
|
||||
as `0.5`, but if we wanted to specify the `width` to be exactly 80
|
||||
characters wide, we would specify it as `80`.
|
||||
For more details on resolving sizes, see `:help telescope.resolve`.
|
||||
|
||||
As an example, if we wanted to specify the layout strategy and width,
|
||||
but only for this instance, we could do something like:
|
||||
```
|
||||
:lua require('telescope.builtin').find_files({layout_strategy='vertical',layout_config={width=0.5}})
|
||||
```
|
||||
or if we wanted to change the width for every time we use the `vertical`
|
||||
layout strategy, we could add the following to our `setup()` call:
|
||||
```
|
||||
require('telescope').setup({
|
||||
defaults = {
|
||||
layout_config = {
|
||||
vertical = { width = 0.5 }
|
||||
-- other layout configuration here
|
||||
},
|
||||
-- other defaults configuration here
|
||||
},
|
||||
-- other configuration values here
|
||||
})
|
||||
```
|
||||
|
||||
## Vim Commands
|
||||
|
||||
@@ -19,13 +19,27 @@ telescope.setup({opts}) *telescope.setup()*
|
||||
|
||||
Valid keys for {opts.defaults}
|
||||
|
||||
*telescope.defaults.border*
|
||||
border: ~
|
||||
Boolean defining if borders are added to Telescope windows.
|
||||
|
||||
Default: true
|
||||
|
||||
*telescope.defaults.default_mappings*
|
||||
default_mappings: ~
|
||||
Not recommended to use except for advanced users.
|
||||
|
||||
Will allow you to completely remove all of telescope's default maps
|
||||
and use your own.
|
||||
|
||||
|
||||
*telescope.defaults.dynamic_preview_title*
|
||||
dynamic_preview_title: ~
|
||||
Will change the title of the preview window dynamically, where it
|
||||
is supported. Means the preview window will for example show the
|
||||
full filename.
|
||||
Will change the title of the preview window dynamically, where it
|
||||
is supported. Means the preview window will for example show the
|
||||
full filename.
|
||||
|
||||
Default: false
|
||||
Default: false
|
||||
|
||||
|
||||
*telescope.defaults.entry_prefix*
|
||||
@@ -34,6 +48,94 @@ telescope.setup({opts}) *telescope.setup()*
|
||||
|
||||
Default: ' '
|
||||
|
||||
*telescope.defaults.layout_config*
|
||||
layout_config: ~
|
||||
Determines the default configuration values for layout strategies.
|
||||
See |telescope.layout| for details of the configurations options for
|
||||
each strategy.
|
||||
|
||||
Allows setting defaults for all strategies as top level options and
|
||||
for overriding for specific options.
|
||||
For example, the default values below set the default width to 80% of
|
||||
the screen width for all strategies except 'center', which has width
|
||||
of 50% of the screen width.
|
||||
|
||||
Default: {
|
||||
center = {
|
||||
preview_cutoff = 40
|
||||
},
|
||||
height = 0.9,
|
||||
horizontal = {
|
||||
preview_cutoff = 120,
|
||||
prompt_position = "bottom"
|
||||
},
|
||||
vertical = {
|
||||
preview_cutoff = 40
|
||||
},
|
||||
width = 0.8
|
||||
}
|
||||
|
||||
|
||||
*telescope.defaults.layout_strategy*
|
||||
layout_strategy: ~
|
||||
Determines the default layout of Telescope pickers.
|
||||
See |telescope.layout| for details of the available strategies.
|
||||
|
||||
Default: 'horizontal'
|
||||
|
||||
*telescope.defaults.mappings*
|
||||
mappings: ~
|
||||
Your mappings to override telescope's default mappings.
|
||||
|
||||
Format is:
|
||||
{
|
||||
mode = { ..keys }
|
||||
}
|
||||
|
||||
where {mode} is the one character letter for a mode
|
||||
('i' for insert, 'n' for normal).
|
||||
|
||||
For example:
|
||||
|
||||
mappings = {
|
||||
i = {
|
||||
["<esc>"] = require('telescope.actions').close,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
To disable a keymap, put [map] = false
|
||||
So, to not map "<C-n>", just put
|
||||
|
||||
...,
|
||||
["<C-n>"] = false,
|
||||
...,
|
||||
|
||||
Into your config.
|
||||
|
||||
|
||||
otherwise, just set the mapping to the function that you want it to be.
|
||||
|
||||
...,
|
||||
["<C-i>"] = require('telescope.actions').select_default,
|
||||
...,
|
||||
|
||||
If the function you want is part of `telescope.actions`, then you can simply give a string.
|
||||
For example, the previous option is equivalent to:
|
||||
|
||||
...,
|
||||
["<C-i>"] = "select_default",
|
||||
...,
|
||||
|
||||
You can also add other mappings using tables with `type = "command"`.
|
||||
For example:
|
||||
|
||||
...,
|
||||
["jj"] = { "<esc>", type = "command" },
|
||||
["kk"] = { "<cmd>echo \"Hello, World!\"<cr>", type = "command" },)
|
||||
...,
|
||||
|
||||
|
||||
*telescope.defaults.prompt_prefix*
|
||||
prompt_prefix: ~
|
||||
Will be shown in front of the prompt.
|
||||
@@ -478,7 +580,7 @@ require("telescope").setup {
|
||||
mappings = {
|
||||
i = {
|
||||
["<c-d>"] = require("telescope.actions").delete_buffer,
|
||||
-- or right hand side can also be a the name of the action as string
|
||||
-- or right hand side can also be the name of the action as string
|
||||
["<c-d>"] = "delete_buffer",
|
||||
},
|
||||
n = {
|
||||
@@ -1118,6 +1220,52 @@ action_state.get_current_picker({prompt_bufnr})*action_state.get_current_picker(
|
||||
|
||||
|
||||
|
||||
================================================================================
|
||||
*telescope.resolve*
|
||||
|
||||
Provides "resolver functions" to allow more customisable inputs for options.
|
||||
|
||||
resolver.resolve_height() *resolver.resolve_height()*
|
||||
Converts input to a function that returns the height. The input must take
|
||||
one of four forms:
|
||||
1. 0 <= number < 1
|
||||
This means total height as a percentage.
|
||||
2. 1 <= number
|
||||
This means total height as a fixed number.
|
||||
3. function
|
||||
Must have signature: function(self, max_columns, max_lines): number
|
||||
4. table of the form: {padding = `foo`}
|
||||
where `foo` has one of the previous three forms.
|
||||
The height is then set to be the remaining space after padding. For
|
||||
example, if the window has height 50, and the input is {padding = 5},
|
||||
the height returned will be `40 = 50 - 2*5`
|
||||
|
||||
The returned function will have signature: function(self, max_columns,
|
||||
max_lines): number
|
||||
|
||||
|
||||
|
||||
resolver.resolve_width() *resolver.resolve_width()*
|
||||
Converts input to a function that returns the width. The input must take
|
||||
one of four forms:
|
||||
1. 0 <= number < 1
|
||||
This means total width as a percentage.
|
||||
2. 1 <= number
|
||||
This means total width as a fixed number.
|
||||
3. function
|
||||
Must have signature: function(self, max_columns, max_lines): number
|
||||
4. table of the form: {padding = `foo`}
|
||||
where `foo` has one of the previous three forms.
|
||||
The width is then set to be the remaining space after padding. For
|
||||
example, if the window has width 100, and the input is {padding = 5},
|
||||
the width returned will be `90 = 100 - 2*5`
|
||||
|
||||
The returned function will have signature: function(self, max_columns,
|
||||
max_lines): number
|
||||
|
||||
|
||||
|
||||
|
||||
================================================================================
|
||||
*telescope.previewers*
|
||||
|
||||
@@ -1450,7 +1598,7 @@ Layout strategies are different functions to position telescope.
|
||||
|
||||
All layout strategies are functions with the following signature:
|
||||
|
||||
function(picker, columns, lines)
|
||||
function(picker, columns, lines, layout_config)
|
||||
-- Do some calculations here...
|
||||
return {
|
||||
preview = preview_configuration
|
||||
@@ -1460,99 +1608,167 @@ All layout strategies are functions with the following signature:
|
||||
end
|
||||
|
||||
Parameters: ~
|
||||
- picker : A Picker object. (docs coming soon)
|
||||
- columns : number Columns in the vim window
|
||||
- lines : number Lines in the vim window
|
||||
- picker : A Picker object. (docs coming soon)
|
||||
- columns : (number) Columns in the vim window
|
||||
- lines : (number) Lines in the vim window
|
||||
- layout_config : (table) The configuration values specific to the picker.
|
||||
|
||||
|
||||
TODO: I would like to make these link to `telescope.layout_strategies.*`, but
|
||||
it's not yet possible.
|
||||
This means you can create your own layout strategy if you want! Just be aware
|
||||
for now that we may change some APIs or interfaces, so they may break if you
|
||||
create your own.
|
||||
|
||||
Available layout strategies include:
|
||||
- horizontal:
|
||||
- See |layout_strategies.horizontal|
|
||||
A good method for creating your own would be to copy one of the strategies that
|
||||
most resembles what you want from
|
||||
"./lua/telescope/pickers/layout_strategies.lua" in the telescope repo.
|
||||
|
||||
- vertical:
|
||||
- See |layout_strategies.vertical|
|
||||
|
||||
- flex:
|
||||
- See |layout_strategies.flex|
|
||||
|
||||
Available tweaks to the settings in layout defaults include (can be applied to
|
||||
horizontal and vertical layouts):
|
||||
- mirror (default is `false`):
|
||||
- Flip the view of the current layout:
|
||||
- If using horizontal: if `true`, swaps the location of the
|
||||
results/prompt window and preview window
|
||||
- If using vertical: if `true`, swaps the location of the results and
|
||||
prompt windows
|
||||
|
||||
- width_padding:
|
||||
- How many cells to pad the width of Telescope's layout window
|
||||
|
||||
- height_padding:
|
||||
- How many cells to pad the height of Telescope's layout window
|
||||
|
||||
- preview_width:
|
||||
- Change the width of Telescope's preview window
|
||||
|
||||
- scroll_speed:
|
||||
- Change the scrolling speed of the previewer
|
||||
|
||||
layout_strategies.horizontal() *layout_strategies.horizontal()*
|
||||
Horizontal previewer
|
||||
Horizontal layout has two columns, one for the preview and one for the
|
||||
prompt and results.
|
||||
|
||||
+-------------+--------------+
|
||||
| | |
|
||||
| Results | |
|
||||
| | Preview |
|
||||
| | |
|
||||
+-------------| |
|
||||
| Prompt | |
|
||||
+-------------+--------------+
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ ┌───────────────────┐┌───────────────────┐ │
|
||||
│ │ ││ │ │
|
||||
│ │ ││ │ │
|
||||
│ │ ││ │ │
|
||||
│ │ Results ││ │ │
|
||||
│ │ ││ Preview │ │
|
||||
│ │ ││ │ │
|
||||
│ │ ││ │ │
|
||||
│ └───────────────────┘│ │ │
|
||||
│ ┌───────────────────┐│ │ │
|
||||
│ │ Prompt ││ │ │
|
||||
│ └───────────────────┘└───────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────┘
|
||||
|
||||
`picker.layout_config` shared options:
|
||||
- height:
|
||||
- How tall to make Telescope's entire layout
|
||||
- See |resolver.resolve_height()|
|
||||
- mirror: Flip the location of the results/prompt and preview windows
|
||||
- scroll_speed: The number of lines to scroll through the previewer
|
||||
- width:
|
||||
- How wide to make Telescope's entire layout
|
||||
- See |resolver.resolve_width()|
|
||||
|
||||
`picker.layout_config` unique options:
|
||||
- preview_cutoff: When columns are less than this value, the preview will be disabled
|
||||
- preview_width:
|
||||
- Change the width of Telescope's preview window
|
||||
- See |resolver.resolve_width()|
|
||||
- prompt_position:
|
||||
- Where to place prompt window.
|
||||
- Available Values: 'bottom', 'top'
|
||||
|
||||
|
||||
layout_strategies.center() *layout_strategies.center()*
|
||||
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
|
||||
remaining space above. Particularly useful for creating dropdown menus (see
|
||||
|telescope.themes| and |themes.get_dropdown()|`).
|
||||
|
||||
+--------------+
|
||||
| Preview |
|
||||
+--------------+
|
||||
| Prompt |
|
||||
+--------------+
|
||||
| Result |
|
||||
| Result |
|
||||
| Result |
|
||||
+--------------+
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ | Preview | │
|
||||
│ | Preview | │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ | Prompt | │
|
||||
│ ├────────────────────────────────────────┤ │
|
||||
│ | Result | │
|
||||
│ | Result | │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────┘
|
||||
|
||||
`picker.layout_config` shared options:
|
||||
- height:
|
||||
- How tall to make Telescope's entire layout
|
||||
- See |resolver.resolve_height()|
|
||||
- mirror: Flip the location of the results/prompt and preview windows
|
||||
- scroll_speed: The number of lines to scroll through the previewer
|
||||
- width:
|
||||
- How wide to make Telescope's entire layout
|
||||
- See |resolver.resolve_width()|
|
||||
|
||||
`picker.layout_config` unique options:
|
||||
- preview_cutoff: When lines are less than this value, the preview will be disabled
|
||||
|
||||
|
||||
layout_strategies.vertical() *layout_strategies.vertical()*
|
||||
Vertical perviewer stacks the items on top of each other.
|
||||
Vertical layout stacks the items on top of each other. Particularly useful
|
||||
with thinner windows.
|
||||
|
||||
+-----------------+
|
||||
| Previewer |
|
||||
| Previewer |
|
||||
| Previewer |
|
||||
+-----------------+
|
||||
| Result |
|
||||
| Result |
|
||||
| Result |
|
||||
+-----------------+
|
||||
| Prompt |
|
||||
+-----------------+
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ | Preview | │
|
||||
│ | Preview | │
|
||||
│ | Preview | │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ | Result | │
|
||||
│ | Result | │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ | Prompt | │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────┘
|
||||
|
||||
`picker.layout_config` shared options:
|
||||
- height:
|
||||
- How tall to make Telescope's entire layout
|
||||
- See |resolver.resolve_height()|
|
||||
- mirror: Flip the location of the results/prompt and preview windows
|
||||
- scroll_speed: The number of lines to scroll through the previewer
|
||||
- width:
|
||||
- How wide to make Telescope's entire layout
|
||||
- See |resolver.resolve_width()|
|
||||
|
||||
`picker.layout_config` unique options:
|
||||
- preview_cutoff: When lines are less than this value, the preview will be disabled
|
||||
- preview_height:
|
||||
- Change the height of Telescope's preview window
|
||||
- See |resolver.resolve_height()|
|
||||
- prompt_position:
|
||||
- (unimplemented, but we plan on supporting)
|
||||
|
||||
|
||||
layout_strategies.flex() *layout_strategies.flex()*
|
||||
Swap between `horizontal` and `vertical` strategies based on the window
|
||||
width
|
||||
- Supports `vertical` or `horizontal` features
|
||||
Flex layout swaps between `horizontal` and `vertical` strategies based on
|
||||
the window width
|
||||
- Supports |layout_strategies.vertical| or |layout_strategies.horizontal|
|
||||
features
|
||||
|
||||
Uses:
|
||||
- flip_columns
|
||||
- flip_lines
|
||||
|
||||
`picker.layout_config` shared options:
|
||||
- height:
|
||||
- How tall to make Telescope's entire layout
|
||||
- See |resolver.resolve_height()|
|
||||
- mirror: Flip the location of the results/prompt and preview windows
|
||||
- scroll_speed: The number of lines to scroll through the previewer
|
||||
- width:
|
||||
- How wide to make Telescope's entire layout
|
||||
- See |resolver.resolve_width()|
|
||||
|
||||
`picker.layout_config` unique options:
|
||||
- flip_columns: The number of columns required to move to horizontal mode
|
||||
- flip_lines: The number of lines required to move to horizontal mode
|
||||
- horizontal: Options to pass when switching to horizontal layout
|
||||
- vertical: Options to pass when switching to vertical layout
|
||||
|
||||
|
||||
layout_strategies.bottom_pane() *layout_strategies.bottom_pane()*
|
||||
Bottom pane can be used to create layouts similar to "ivy".
|
||||
|
||||
For an easy ivy configuration, see |themes.get_ivy()|
|
||||
|
||||
|
||||
|
||||
|
||||
51
doc/telescope_changelog.txt
Normal file
51
doc/telescope_changelog.txt
Normal file
@@ -0,0 +1,51 @@
|
||||
================================================================================
|
||||
*telescope.changelog*
|
||||
|
||||
# Changelog
|
||||
|
||||
*telescope.changelog-922*
|
||||
|
||||
Date: May 17, 2021
|
||||
PR: https://github.com/nvim-telescope/telescope.nvim/pull/922
|
||||
|
||||
This is one of our largest breaking changes thus far, so I (TJ) am adding some
|
||||
information here so that you can more easily update (without having to track
|
||||
down the commit, etc.).
|
||||
|
||||
The goal of these breaking changes is to greatly simplify the way
|
||||
configuration for layouts happen. This should make it much easier to configure
|
||||
each picker, layout_strategy, and more. Please report any bugs or behavior
|
||||
that is broken / confusing upstream and we can try and make the configuration
|
||||
better.
|
||||
|
||||
|telescope.setup()| has changed `layout_defaults` -> `layout_config`.
|
||||
This makes it so that the setup and the pickers share the same key,
|
||||
otherwise it is too confusing which key is for which.
|
||||
|
||||
|
||||
`picker:find()` now has different values available for configuring the UI.
|
||||
All configuration for the layout must be passed in the key:
|
||||
`layout_config`.
|
||||
|
||||
Previously, these keys were passed via `picker:find(opts)`, but should be
|
||||
passed via `opts.layout_config` now.
|
||||
- {height}
|
||||
- {width}
|
||||
- {prompt_position}
|
||||
- {preview_cutoff}
|
||||
|
||||
These keys are removed:
|
||||
- {results_height}: This key is no longer valid. Instead, use `height`
|
||||
and the corresponding `preview_*` options for the layout strategy to
|
||||
get the correct results height. This simplifies the configuration
|
||||
for many of the existing strategies.
|
||||
|
||||
- {results_width}: This key actually never did anything. It was
|
||||
leftover from some hacking that I had attempted before. Instead you
|
||||
should be using something like the `preview_width` configuration
|
||||
option for |layout_strategies.horizontal()|
|
||||
|
||||
You should get error messages when you try and use any of the above keys now.
|
||||
|
||||
|
||||
vim:tw=78:ts=8:ft=help:norl:
|
||||
@@ -37,7 +37,7 @@
|
||||
--- mappings = {
|
||||
--- i = {
|
||||
--- ["<c-d>"] = require("telescope.actions").delete_buffer,
|
||||
--- -- or right hand side can also be a the name of the action as string
|
||||
--- -- or right hand side can also be the name of the action as string
|
||||
--- ["<c-d>"] = "delete_buffer",
|
||||
--- },
|
||||
--- n = {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
local strings = require('plenary.strings')
|
||||
local strings = require "plenary.strings"
|
||||
local deprecated = require "telescope.deprecated"
|
||||
local sorters = require "telescope.sorters"
|
||||
local if_nil = vim.F.if_nil
|
||||
|
||||
-- Keep the values around between reloads
|
||||
_TelescopeConfigurationValues = _TelescopeConfigurationValues or {}
|
||||
_TelescopeConfigurationPickers = _TelescopeConfigurationPickers or {}
|
||||
|
||||
local function first_non_null(...)
|
||||
local n = select('#', ...)
|
||||
local n = select("#", ...)
|
||||
for i = 1, n do
|
||||
local value = select(i, ...)
|
||||
|
||||
@@ -15,7 +18,26 @@ local function first_non_null(...)
|
||||
end
|
||||
end
|
||||
|
||||
local sorters = require('telescope.sorters')
|
||||
-- A function that creates an amended copy of the `base` table,
|
||||
-- by replacing keys at "level 2" that match keys in "level 1" in `priority`,
|
||||
-- and then performs a deep_extend.
|
||||
-- May give unexpected results if used with tables of "depth"
|
||||
-- greater than 2.
|
||||
local smarter_depth_2_extend = function(priority, base)
|
||||
local result = {}
|
||||
for key, val in pairs(base) do
|
||||
if type(val) ~= "table" then
|
||||
result[key] = first_non_null(priority[key], val)
|
||||
else
|
||||
result[key] = {}
|
||||
for k, v in pairs(val) do
|
||||
result[key][k] = first_non_null(priority[k], v)
|
||||
end
|
||||
end
|
||||
end
|
||||
result = vim.tbl_deep_extend("keep", priority, result)
|
||||
return result
|
||||
end
|
||||
|
||||
-- TODO: Add other major configuration points here.
|
||||
-- selection_strategy
|
||||
@@ -27,18 +49,279 @@ config.descriptions = {}
|
||||
config.pickers = _TelescopeConfigurationPickers
|
||||
|
||||
function config.set_pickers(pickers)
|
||||
pickers = pickers or {}
|
||||
pickers = if_nil(pickers, {})
|
||||
|
||||
for k, v in pairs(pickers) do
|
||||
config.pickers[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
function config.set_defaults(defaults)
|
||||
defaults = defaults or {}
|
||||
local layout_config_defaults = {
|
||||
width = 0.8,
|
||||
height = 0.9,
|
||||
|
||||
horizontal = {
|
||||
prompt_position = "bottom",
|
||||
preview_cutoff = 120,
|
||||
},
|
||||
|
||||
vertical = {
|
||||
preview_cutoff = 40,
|
||||
},
|
||||
|
||||
center = {
|
||||
preview_cutoff = 40,
|
||||
},
|
||||
}
|
||||
|
||||
local layout_config_description = string.format([[
|
||||
Determines the default configuration values for layout strategies.
|
||||
See |telescope.layout| for details of the configurations options for
|
||||
each strategy.
|
||||
|
||||
Allows setting defaults for all strategies as top level options and
|
||||
for overriding for specific options.
|
||||
For example, the default values below set the default width to 80%% of
|
||||
the screen width for all strategies except 'center', which has width
|
||||
of 50%% of the screen width.
|
||||
|
||||
Default: %s
|
||||
]], vim.inspect(
|
||||
layout_config_defaults,
|
||||
{ newline = "\n ", indent = " " }
|
||||
))
|
||||
|
||||
-- A table of all the usual defaults for telescope.
|
||||
-- Keys will be the name of the default,
|
||||
-- values will be a list where:
|
||||
-- - first entry is the value
|
||||
-- - second entry is the description of the option
|
||||
|
||||
local telescope_defaults = {
|
||||
|
||||
sorting_strategy = {
|
||||
"descending",
|
||||
[[
|
||||
Determines the direction "better" results are sorted towards.
|
||||
|
||||
Available options are:
|
||||
- "descending" (default)
|
||||
- "ascending"]],
|
||||
},
|
||||
|
||||
selection_strategy = {
|
||||
"reset",
|
||||
[[
|
||||
Determines how the cursor acts after each sort iteration.
|
||||
|
||||
Available options are:
|
||||
- "reset" (default)
|
||||
- "follow"
|
||||
- "row"]],
|
||||
},
|
||||
|
||||
scroll_strategy = {
|
||||
"cycle",
|
||||
[[
|
||||
Determines what happens you try to scroll past view of the picker.
|
||||
|
||||
Available options are:
|
||||
- "cycle" (default)
|
||||
- "limit"]],
|
||||
},
|
||||
|
||||
layout_strategy = {
|
||||
"horizontal",
|
||||
[[
|
||||
Determines the default layout of Telescope pickers.
|
||||
See |telescope.layout| for details of the available strategies.
|
||||
|
||||
Default: 'horizontal']],
|
||||
},
|
||||
|
||||
layout_config = { layout_config_defaults, layout_config_description },
|
||||
|
||||
winblend = { 0 },
|
||||
|
||||
prompt_prefix = { "> ", [[
|
||||
Will be shown in front of the prompt.
|
||||
|
||||
Default: '> ']]
|
||||
},
|
||||
|
||||
selection_caret = { "> ", [[
|
||||
Will be shown in front of the selection.
|
||||
|
||||
Default: '> ']]
|
||||
},
|
||||
|
||||
entry_prefix = { " ", [[
|
||||
Prefix in front of each result entry. Current selection not included.
|
||||
|
||||
Default: ' ']]
|
||||
},
|
||||
|
||||
initial_mode = { "insert" },
|
||||
|
||||
border = { true, [[
|
||||
Boolean defining if borders are added to Telescope windows.
|
||||
|
||||
Default: true]]
|
||||
},
|
||||
|
||||
borderchars = { { "─", "│", "─", "│", "╭", "╮", "╯", "╰" } },
|
||||
|
||||
get_status_text = {
|
||||
function(self)
|
||||
local xx = (self.stats.processed or 0) - (self.stats.filtered or 0)
|
||||
local yy = self.stats.processed or 0
|
||||
if xx == 0 and yy == 0 then
|
||||
return ""
|
||||
end
|
||||
|
||||
return string.format("%s / %s", xx, yy)
|
||||
end,
|
||||
},
|
||||
|
||||
dynamic_preview_title = {
|
||||
false,
|
||||
[[
|
||||
Will change the title of the preview window dynamically, where it
|
||||
is supported. Means the preview window will for example show the
|
||||
full filename.
|
||||
|
||||
Default: false
|
||||
]],
|
||||
},
|
||||
|
||||
-- Builtin configuration
|
||||
|
||||
-- List that will be executed.
|
||||
-- Last argument will be the search term (passed in during execution)
|
||||
vimgrep_arguments = {
|
||||
{ "rg", "--color=never", "--no-heading", "--with-filename", "--line-number", "--column", "--smart-case" },
|
||||
},
|
||||
|
||||
use_less = { true },
|
||||
|
||||
color_devicons = { true },
|
||||
|
||||
set_env = { nil },
|
||||
|
||||
mappings = {
|
||||
{}, [[
|
||||
Your mappings to override telescope's default mappings.
|
||||
|
||||
Format is:
|
||||
{
|
||||
mode = { ..keys }
|
||||
}
|
||||
|
||||
where {mode} is the one character letter for a mode
|
||||
('i' for insert, 'n' for normal).
|
||||
|
||||
For example:
|
||||
|
||||
mappings = {
|
||||
i = {
|
||||
["<esc>"] = require('telescope.actions').close,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
To disable a keymap, put [map] = false
|
||||
So, to not map "<C-n>", just put
|
||||
|
||||
...,
|
||||
["<C-n>"] = false,
|
||||
...,
|
||||
|
||||
Into your config.
|
||||
|
||||
|
||||
otherwise, just set the mapping to the function that you want it to be.
|
||||
|
||||
...,
|
||||
["<C-i>"] = require('telescope.actions').select_default,
|
||||
...,
|
||||
|
||||
If the function you want is part of `telescope.actions`, then you can simply give a string.
|
||||
For example, the previous option is equivalent to:
|
||||
|
||||
...,
|
||||
["<C-i>"] = "select_default",
|
||||
...,
|
||||
|
||||
You can also add other mappings using tables with `type = "command"`.
|
||||
For example:
|
||||
|
||||
...,
|
||||
["jj"] = { "<esc>", type = "command" },
|
||||
["kk"] = { "<cmd>echo \"Hello, World!\"<cr>", type = "command" },)
|
||||
...,
|
||||
]],
|
||||
},
|
||||
|
||||
default_mappings = {
|
||||
nil,
|
||||
[[
|
||||
Not recommended to use except for advanced users.
|
||||
|
||||
Will allow you to completely remove all of telescope's default maps
|
||||
and use your own.
|
||||
]],
|
||||
},
|
||||
|
||||
generic_sorter = { sorters.get_generic_fuzzy_sorter },
|
||||
prefilter_sorter = { sorters.prefilter },
|
||||
file_sorter = { sorters.get_fuzzy_file },
|
||||
|
||||
file_ignore_patterns = { nil },
|
||||
|
||||
file_previewer = {
|
||||
function(...)
|
||||
return require("telescope.previewers").vim_buffer_cat.new(...)
|
||||
end,
|
||||
},
|
||||
grep_previewer = {
|
||||
function(...)
|
||||
return require("telescope.previewers").vim_buffer_vimgrep.new(...)
|
||||
end,
|
||||
},
|
||||
qflist_previewer = {
|
||||
function(...)
|
||||
return require("telescope.previewers").vim_buffer_qflist.new(...)
|
||||
end,
|
||||
},
|
||||
buffer_previewer_maker = {
|
||||
function(...)
|
||||
return require("telescope.previewers").buffer_previewer_maker(...)
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
-- @param user_defaults table: a table where keys are the names of options,
|
||||
-- and values are the ones the user wants
|
||||
-- @param tele_defaults table: (optional) a table containing all of the defaults
|
||||
-- for telescope [defaults to `telescope_defaults`]
|
||||
function config.set_defaults(user_defaults, tele_defaults)
|
||||
user_defaults = if_nil(user_defaults, {})
|
||||
tele_defaults = if_nil(tele_defaults, telescope_defaults)
|
||||
|
||||
-- Check if using layout keywords outside of `layout_config`
|
||||
deprecated.picker_window_options(user_defaults)
|
||||
|
||||
-- Check if using `layout_defaults` instead of `layout_config`
|
||||
user_defaults = deprecated.layout_configuration(user_defaults)
|
||||
|
||||
local function get(name, default_val)
|
||||
return first_non_null(defaults[name], config.values[name], default_val)
|
||||
if name == "layout_config" then
|
||||
return smarter_depth_2_extend(
|
||||
if_nil(user_defaults[name], {}),
|
||||
vim.tbl_deep_extend("keep", if_nil(config.values[name], {}), if_nil(default_val, {}))
|
||||
)
|
||||
end
|
||||
return first_non_null(user_defaults[name], config.values[name], default_val)
|
||||
end
|
||||
|
||||
local function set(name, default_val, description)
|
||||
@@ -51,114 +334,13 @@ function config.set_defaults(defaults)
|
||||
end
|
||||
end
|
||||
|
||||
set("sorting_strategy", "descending", [[
|
||||
Determines the direction "better" results are sorted towards.
|
||||
for key, info in pairs(tele_defaults) do
|
||||
set(key, info[1], info[2])
|
||||
end
|
||||
|
||||
Available options are:
|
||||
- "descending" (default)
|
||||
- "ascending"]])
|
||||
|
||||
set("selection_strategy", "reset", [[
|
||||
Determines how the cursor acts after each sort iteration.
|
||||
|
||||
Available options are:
|
||||
- "reset" (default)
|
||||
- "follow"
|
||||
- "row"]])
|
||||
|
||||
set("scroll_strategy", "cycle", [[
|
||||
Determines what happens you try to scroll past view of the picker.
|
||||
|
||||
Available options are:
|
||||
- "cycle" (default)
|
||||
- "limit"]])
|
||||
|
||||
set("layout_strategy", "horizontal")
|
||||
set("layout_defaults", {})
|
||||
|
||||
set("width", 0.75)
|
||||
set("winblend", 0)
|
||||
set("prompt_position", "bottom")
|
||||
set("preview_cutoff", 120)
|
||||
|
||||
set("results_height", 1)
|
||||
set("results_width", 0.8)
|
||||
|
||||
set("prompt_prefix", "> ", [[
|
||||
Will be shown in front of the prompt.
|
||||
|
||||
Default: '> ']])
|
||||
set("selection_caret", "> ", [[
|
||||
Will be shown in front of the selection.
|
||||
|
||||
Default: '> ']])
|
||||
set("entry_prefix", " ", [[
|
||||
Prefix in front of each result entry. Current selection not included.
|
||||
|
||||
Default: ' ']])
|
||||
set("initial_mode", "insert")
|
||||
|
||||
set("border", {})
|
||||
set("borderchars", { '─', '│', '─', '│', '╭', '╮', '╯', '╰'})
|
||||
|
||||
set("get_status_text", function(self)
|
||||
local xx = (self.stats.processed or 0) - (self.stats.filtered or 0)
|
||||
local yy = self.stats.processed or 0
|
||||
if xx == 0 and yy == 0 then return "" end
|
||||
|
||||
return string.format("%s / %s", xx, yy)
|
||||
end)
|
||||
|
||||
-- Builtin configuration
|
||||
|
||||
-- List that will be executed.
|
||||
-- Last argument will be the search term (passed in during execution)
|
||||
set("vimgrep_arguments",
|
||||
{'rg', '--color=never', '--no-heading', '--with-filename', '--line-number', '--column', '--smart-case'}
|
||||
)
|
||||
set("use_less", true)
|
||||
set("color_devicons", true)
|
||||
|
||||
set("set_env", nil)
|
||||
|
||||
-- TODO: Add motions to keybindings
|
||||
|
||||
-- To disable a keymap, put [map] = false
|
||||
-- So, to not map "<C-n>", just put
|
||||
--
|
||||
-- ...,
|
||||
-- ["<C-n>"] = false,
|
||||
-- ...,
|
||||
--
|
||||
-- Into your config.
|
||||
--
|
||||
-- Otherwise, just set the mapping to the function that you want it to be.
|
||||
--
|
||||
-- ...,
|
||||
-- ["<C-i>"] = actions.select_default
|
||||
-- ...,
|
||||
--
|
||||
set("mappings", {})
|
||||
set("default_mappings", nil)
|
||||
|
||||
set("generic_sorter", sorters.get_generic_fuzzy_sorter)
|
||||
set("prefilter_sorter", sorters.prefilter)
|
||||
set("file_sorter", sorters.get_fuzzy_file)
|
||||
|
||||
set("file_ignore_patterns", nil)
|
||||
|
||||
set("dynamic_preview_title", false, [[
|
||||
Will change the title of the preview window dynamically, where it
|
||||
is supported. Means the preview window will for example show the
|
||||
full filename.
|
||||
|
||||
Default: false
|
||||
]])
|
||||
|
||||
set("file_previewer", function(...) return require('telescope.previewers').vim_buffer_cat.new(...) end)
|
||||
set("grep_previewer", function(...) return require('telescope.previewers').vim_buffer_vimgrep.new(...) end)
|
||||
set("qflist_previewer", function(...) return require('telescope.previewers').vim_buffer_qflist.new(...) end)
|
||||
set("buffer_previewer_maker", function(...) return require('telescope.previewers').buffer_previewer_maker(...) end)
|
||||
local M = {}
|
||||
M.get = get
|
||||
return M
|
||||
end
|
||||
|
||||
function config.clear_defaults()
|
||||
@@ -169,5 +351,4 @@ end
|
||||
|
||||
config.set_defaults()
|
||||
|
||||
|
||||
return config
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---@tag telescope.resolve
|
||||
|
||||
---@brief [[
|
||||
--- Provides "resolver functions" to allow more customisable inputs for options.
|
||||
---@brief ]]
|
||||
|
||||
--[[
|
||||
|
||||
@@ -40,7 +45,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
|
||||
@@ -88,46 +93,80 @@ That's the next step to scrolling.
|
||||
local get_default = require('telescope.utils').get_default
|
||||
|
||||
local resolver = {}
|
||||
local _resolve_map = {}
|
||||
|
||||
local _resolve_map = {
|
||||
-- Booleans
|
||||
[function(val) return val == false end] = function(selector, val)
|
||||
return function(...)
|
||||
return val
|
||||
end
|
||||
end,
|
||||
|
||||
-- Percentages
|
||||
[function(val) return type(val) == 'number' and val >= 0 and val < 1 end] = function(selector, val)
|
||||
return function(...)
|
||||
local selected = select(selector, ...)
|
||||
return math.floor(val * selected)
|
||||
end
|
||||
end,
|
||||
|
||||
-- Numbers
|
||||
[function(val) return type(val) == 'number' and val >= 1 end] = function(selector, val)
|
||||
return function(...)
|
||||
local selected = select(selector, ...)
|
||||
return math.min(val, selected)
|
||||
end
|
||||
end,
|
||||
|
||||
|
||||
-- Tables TODO:
|
||||
-- ... {70, max}
|
||||
|
||||
|
||||
-- function:
|
||||
-- Function must have same signature as get_window_layout
|
||||
-- function(self, max_columns, max_lines): number
|
||||
--
|
||||
-- Resulting number is used for this configuration value.
|
||||
[function(val) return type(val) == 'function' end] = function(selector, val)
|
||||
-- Booleans
|
||||
_resolve_map[function(val) return val == false end] = function(_, val)
|
||||
return function(...)
|
||||
return val
|
||||
end,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- Percentages
|
||||
_resolve_map[function(val) return type(val) == 'number' and val >= 0 and val < 1 end] = function(selector, val)
|
||||
return function(...)
|
||||
local selected = select(selector, ...)
|
||||
return math.floor(val * selected)
|
||||
end
|
||||
end
|
||||
|
||||
-- Numbers
|
||||
_resolve_map[function(val) return type(val) == 'number' and val >= 1 end] = function(selector, val)
|
||||
return function(...)
|
||||
local selected = select(selector, ...)
|
||||
return math.min(val, selected)
|
||||
end
|
||||
end
|
||||
|
||||
-- Tables TODO:
|
||||
-- ... {70, max}
|
||||
|
||||
-- function:
|
||||
-- Function must have same signature as get_window_layout
|
||||
-- function(self, max_columns, max_lines): number
|
||||
--
|
||||
-- Resulting number is used for this configuration value.
|
||||
_resolve_map[function(val) return type(val) == 'function' end] = function(_, val)
|
||||
return val
|
||||
end
|
||||
|
||||
-- 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(_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
|
||||
|
||||
|
||||
--- Converts input to a function that returns the height.
|
||||
--- The input must take one of four forms:
|
||||
--- 1. 0 <= number < 1 <br>
|
||||
--- This means total height as a percentage.
|
||||
--- 2. 1 <= number <br>
|
||||
--- This means total height as a fixed number.
|
||||
--- 3. function <br>
|
||||
--- Must have signature:
|
||||
--- function(self, max_columns, max_lines): number
|
||||
--- 4. table of the form: {padding = `foo`} <br>
|
||||
--- where `foo` has one of the previous three forms. <br>
|
||||
--- The height is then set to be the remaining space after padding.
|
||||
--- For example, if the window has height 50, and the input is {padding = 5},
|
||||
--- the height returned will be `40 = 50 - 2*5`
|
||||
---
|
||||
--- The returned function will have signature:
|
||||
--- function(self, max_columns, max_lines): number
|
||||
resolver.resolve_height = function(val)
|
||||
for k, v in pairs(_resolve_map) do
|
||||
if k(val) then
|
||||
@@ -138,6 +177,23 @@ resolver.resolve_height = function(val)
|
||||
error('invalid configuration option for height:' .. tostring(val))
|
||||
end
|
||||
|
||||
--- Converts input to a function that returns the width.
|
||||
--- The input must take one of four forms:
|
||||
--- 1. 0 <= number < 1 <br>
|
||||
--- This means total width as a percentage.
|
||||
--- 2. 1 <= number <br>
|
||||
--- This means total width as a fixed number.
|
||||
--- 3. function <br>
|
||||
--- Must have signature:
|
||||
--- function(self, max_columns, max_lines): number
|
||||
--- 4. table of the form: {padding = `foo`} <br>
|
||||
--- where `foo` has one of the previous three forms. <br>
|
||||
--- The width is then set to be the remaining space after padding.
|
||||
--- For example, if the window has width 100, and the input is {padding = 5},
|
||||
--- the width returned will be `90 = 100 - 2*5`
|
||||
---
|
||||
--- The returned function will have signature:
|
||||
--- function(self, max_columns, max_lines): number
|
||||
resolver.resolve_width = function(val)
|
||||
for k, v in pairs(_resolve_map) do
|
||||
if k(val) then
|
||||
@@ -148,8 +204,8 @@ resolver.resolve_width = function(val)
|
||||
error('invalid configuration option for width:' .. tostring(val))
|
||||
end
|
||||
|
||||
--- Win option always returns a table with preview, results, and prompt.
|
||||
--- It handles many different ways. Some examples are as follows:
|
||||
-- Win option always returns a table with preview, results, and prompt.
|
||||
-- It handles many different ways. Some examples are as follows:
|
||||
--
|
||||
-- -- Disable
|
||||
-- borderschars = false
|
||||
|
||||
59
lua/telescope/deprecated.lua
Normal file
59
lua/telescope/deprecated.lua
Normal file
@@ -0,0 +1,59 @@
|
||||
local log = require "telescope.log"
|
||||
|
||||
local deprecated = {}
|
||||
|
||||
deprecated.picker_window_options = function(opts)
|
||||
local messages = {}
|
||||
|
||||
-- Deprecated: PR:922, 2021/06/25
|
||||
-- Can be removed in a few weeks.
|
||||
|
||||
if opts.width then
|
||||
table.insert(messages, "'opts.width' is no longer valid. Please use 'layout_config.width' instead")
|
||||
end
|
||||
|
||||
if opts.height then
|
||||
table.insert(messages, "'opts.height' is no longer valid. Please use 'layout_config.height' instead")
|
||||
end
|
||||
|
||||
if opts.results_height then
|
||||
table.insert(messages, "'opts.results_height' is no longer valid. Please see ':help telescope.changelog-922'")
|
||||
end
|
||||
|
||||
if opts.results_width then
|
||||
table.insert(messages,
|
||||
"'opts.results_width' actually didn't do anything. Please see ':help telescope.changelog-922'"
|
||||
)
|
||||
end
|
||||
|
||||
if opts.prompt_position then
|
||||
table.insert(messages,
|
||||
"'opts.prompt_position' is no longer valid. Please use 'layout_config.prompt_position' instead."
|
||||
)
|
||||
end
|
||||
|
||||
if opts.preview_cutoff then
|
||||
table.insert(messages,
|
||||
"'opts.preview_cutoff' is no longer valid. Please use 'layout_config.preview_cutoff' instead."
|
||||
)
|
||||
end
|
||||
|
||||
if #messages > 0 then
|
||||
table.insert(messages, 1, "Deprecated window options. Please see ':help telescope.changelog'")
|
||||
vim.api.nvim_err_write(table.concat(messages, "\n \n ") .. "\n \nPress <Enter> to continue\n")
|
||||
end
|
||||
end
|
||||
|
||||
deprecated.layout_configuration = function(user_defaults)
|
||||
if user_defaults.layout_defaults then
|
||||
if user_defaults.layout_config == nil then
|
||||
log.warn "Using 'layout_defaults' in setup() is deprecated. Use 'layout_config' instead."
|
||||
user_defaults.layout_config = user_defaults.layout_defaults
|
||||
else
|
||||
error "Using 'layout_defaults' in setup() is deprecated. Remove this key and use 'layout_config' instead."
|
||||
end
|
||||
end
|
||||
return user_defaults
|
||||
end
|
||||
|
||||
return deprecated
|
||||
@@ -249,6 +249,8 @@ function make_entry.gen_from_git_stash()
|
||||
end
|
||||
|
||||
function make_entry.gen_from_git_commits(opts)
|
||||
opts = opts or {}
|
||||
|
||||
local displayer = entry_display.create {
|
||||
separator = " ",
|
||||
items = {
|
||||
|
||||
@@ -14,6 +14,7 @@ local actions = require('telescope.actions')
|
||||
local action_set = require('telescope.actions.set')
|
||||
local config = require('telescope.config')
|
||||
local debounce = require('telescope.debounce')
|
||||
local deprecated = require('telescope.deprecated')
|
||||
local log = require('telescope.log')
|
||||
local mappings = require('telescope.mappings')
|
||||
local state = require('telescope.state')
|
||||
@@ -56,6 +57,8 @@ function Picker:new(opts)
|
||||
actions._clear()
|
||||
action_set._clear()
|
||||
|
||||
deprecated.picker_window_options(opts)
|
||||
|
||||
local layout_strategy = get_default(opts.layout_strategy, config.values.layout_strategy)
|
||||
|
||||
local obj = setmetatable({
|
||||
@@ -96,33 +99,13 @@ function Picker:new(opts)
|
||||
selection_strategy = get_default(opts.selection_strategy, config.values.selection_strategy),
|
||||
|
||||
layout_strategy = layout_strategy,
|
||||
layout_config = get_default(
|
||||
opts.layout_config,
|
||||
(config.values.layout_defaults or {})[layout_strategy]
|
||||
) or {},
|
||||
layout_config = vim.tbl_deep_extend("keep", opts.layout_config or {}, config.values.layout_config 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 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),
|
||||
|
||||
results_width = get_default(opts.results_width, config.values.results_width),
|
||||
results_height = get_default(opts.results_height, config.values.results_height),
|
||||
|
||||
winblend = get_default(opts.winblend, config.values.winblend),
|
||||
prompt_position = get_default(opts.prompt_position, config.values.prompt_position),
|
||||
|
||||
-- Border config
|
||||
border = get_default(opts.border, config.values.border),
|
||||
borderchars = get_default(opts.borderchars, config.values.borderchars),
|
||||
},
|
||||
|
||||
preview_cutoff = get_default(opts.preview_cutoff, config.values.preview_cutoff),
|
||||
}, self)
|
||||
|
||||
obj.get_window_options = opts.get_window_options or p_window.get_window_options
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
--- All layout strategies are functions with the following signature:
|
||||
---
|
||||
--- <pre>
|
||||
--- function(picker, columns, lines)
|
||||
--- function(picker, columns, lines, layout_config)
|
||||
--- -- Do some calculations here...
|
||||
--- return {
|
||||
--- preview = preview_configuration
|
||||
@@ -17,136 +17,257 @@
|
||||
--- end
|
||||
---
|
||||
--- Parameters: ~
|
||||
--- - picker : A Picker object. (docs coming soon)
|
||||
--- - columns : number Columns in the vim window
|
||||
--- - lines : number Lines in the vim window
|
||||
--- - picker : A Picker object. (docs coming soon)
|
||||
--- - columns : (number) Columns in the vim window
|
||||
--- - lines : (number) Lines in the vim window
|
||||
--- - layout_config : (table) The configuration values specific to the picker.
|
||||
---
|
||||
--- </pre>
|
||||
---
|
||||
--- TODO: I would like to make these link to `telescope.layout_strategies.*`,
|
||||
--- but it's not yet possible.
|
||||
--- This means you can create your own layout strategy if you want! Just be aware
|
||||
--- for now that we may change some APIs or interfaces, so they may break if you create
|
||||
--- your own.
|
||||
---
|
||||
--- Available layout strategies include:
|
||||
--- - horizontal:
|
||||
--- - See |layout_strategies.horizontal|
|
||||
--- A good method for creating your own would be to copy one of the strategies that most
|
||||
--- resembles what you want from "./lua/telescope/pickers/layout_strategies.lua" in the
|
||||
--- telescope repo.
|
||||
---
|
||||
--- - vertical:
|
||||
--- - See |layout_strategies.vertical|
|
||||
---
|
||||
--- - flex:
|
||||
--- - See |layout_strategies.flex|
|
||||
---
|
||||
--- Available tweaks to the settings in layout defaults include
|
||||
--- (can be applied to horizontal and vertical layouts):
|
||||
--- - mirror (default is `false`):
|
||||
--- - Flip the view of the current layout:
|
||||
--- - If using horizontal: if `true`, swaps the location of the
|
||||
--- results/prompt window and preview window
|
||||
--- - If using vertical: if `true`, swaps the location of the results and
|
||||
--- prompt windows
|
||||
---
|
||||
--- - width_padding:
|
||||
--- - How many cells to pad the width of Telescope's layout window
|
||||
---
|
||||
--- - height_padding:
|
||||
--- - How many cells to pad the height of Telescope's layout window
|
||||
---
|
||||
--- - preview_width:
|
||||
--- - Change the width of Telescope's preview window
|
||||
---
|
||||
--- - scroll_speed:
|
||||
--- - Change the scrolling speed of the previewer
|
||||
---@brief ]]
|
||||
|
||||
local config = require('telescope.config')
|
||||
local resolve = require("telescope.config.resolve")
|
||||
|
||||
local resolve = require('telescope.config.resolve')
|
||||
local p_window = require('telescope.pickers.window')
|
||||
local if_nil = vim.F.if_nil
|
||||
|
||||
|
||||
-- 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
|
||||
|
||||
|
||||
local function validate_layout_config(options, values)
|
||||
for k, _ in pairs(options) do
|
||||
if not values[k] then
|
||||
error(string.format(
|
||||
"Unsupported layout_config key: %s\n%s",
|
||||
k,
|
||||
vim.inspect(values)
|
||||
))
|
||||
end
|
||||
local get_border_size = function(opts)
|
||||
if opts.window.border == false then
|
||||
return 0
|
||||
end
|
||||
|
||||
return options
|
||||
return 1
|
||||
end
|
||||
|
||||
local layout_strategies = {}
|
||||
layout_strategies._configurations = {}
|
||||
|
||||
--- Horizontal previewer
|
||||
--@param strategy_config table: table with keys for each option for a strategy
|
||||
--@return table: table with keys for each option (for this strategy) and with keys for each layout_strategy
|
||||
local get_valid_configuration_keys = function(strategy_config)
|
||||
local valid_configuration_keys = {
|
||||
-- TEMP: There are a few keys we should say are valid to start with.
|
||||
preview_cutoff = true,
|
||||
prompt_position = true,
|
||||
}
|
||||
|
||||
for key in pairs(strategy_config) do
|
||||
valid_configuration_keys[key] = true
|
||||
end
|
||||
|
||||
for name in pairs(layout_strategies) do
|
||||
valid_configuration_keys[name] = true
|
||||
end
|
||||
|
||||
return valid_configuration_keys
|
||||
end
|
||||
|
||||
--@param strategy_name string: the name of the layout_strategy we are validating for
|
||||
--@param configuration table: table with keys for each option available
|
||||
--@param values table: table containing all of the non-default options we want to set
|
||||
--@param default_layout_config table: table with the default values to configure layouts
|
||||
--@return table: table containing the combined options (defaults and non-defaults)
|
||||
local function validate_layout_config(strategy_name, configuration, values, default_layout_config)
|
||||
assert(strategy_name, "It is required to have a strategy name for validation.")
|
||||
local valid_configuration_keys = get_valid_configuration_keys(configuration)
|
||||
|
||||
-- If no default_layout_config provided, check Telescope's config values
|
||||
default_layout_config = if_nil(default_layout_config, require('telescope.config').values.layout_config)
|
||||
|
||||
local result = {}
|
||||
local get_value = function(k)
|
||||
-- skip "private" items
|
||||
if string.sub(k, 1, 1) == "_" then return end
|
||||
|
||||
local val
|
||||
-- Prioritise options that are specific to this strategy
|
||||
if values[strategy_name] ~= nil and values[strategy_name][k] ~= nil then
|
||||
val = values[strategy_name][k]
|
||||
end
|
||||
|
||||
-- Handle nested layout config values
|
||||
if layout_strategies[k]
|
||||
and strategy_name ~= k
|
||||
and type(val) == 'table' then
|
||||
val = vim.tbl_deep_extend("force", default_layout_config[k], val)
|
||||
end
|
||||
|
||||
if val == nil and values[k] ~= nil then
|
||||
val = values[k]
|
||||
end
|
||||
|
||||
if val == nil then
|
||||
if default_layout_config[strategy_name] ~= nil
|
||||
and default_layout_config[strategy_name][k] ~= nil then
|
||||
val = default_layout_config[strategy_name][k]
|
||||
else
|
||||
val = default_layout_config[k]
|
||||
end
|
||||
end
|
||||
|
||||
return val
|
||||
end
|
||||
|
||||
-- Always set the values passed first.
|
||||
for k in pairs(values) do
|
||||
if not valid_configuration_keys[k] then
|
||||
-- TODO: At some point we'll move to error here,
|
||||
-- but it's a bit annoying to just straight up crash everyone's stuff.
|
||||
vim.api.nvim_err_writeln(string.format(
|
||||
"Unsupported layout_config key for the %s strategy: %s\n%s",
|
||||
strategy_name, k, vim.inspect(values)
|
||||
))
|
||||
end
|
||||
|
||||
result[k] = get_value(k)
|
||||
end
|
||||
|
||||
-- And then set other valid keys via "inheritance" style extension
|
||||
for k in pairs(valid_configuration_keys) do
|
||||
if result[k] == nil then
|
||||
result[k] = get_value(k)
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
-- List of options that are shared by more than one layout.
|
||||
local shared_options = {
|
||||
width = { "How wide to make Telescope's entire layout", "See |resolver.resolve_width()|" },
|
||||
height = { "How tall to make Telescope's entire layout", "See |resolver.resolve_height()|" },
|
||||
mirror = "Flip the location of the results/prompt and preview windows",
|
||||
scroll_speed = "The number of lines to scroll through the previewer",
|
||||
}
|
||||
|
||||
-- Used for generating vim help documentation.
|
||||
layout_strategies._format = function(name)
|
||||
local strategy_config = layout_strategies._configurations[name]
|
||||
if vim.tbl_isempty(strategy_config) then
|
||||
return {}
|
||||
end
|
||||
|
||||
local results = {"<pre>", "`picker.layout_config` shared options:"}
|
||||
|
||||
local strategy_keys = vim.tbl_keys(strategy_config)
|
||||
table.sort(strategy_keys, function(a, b)
|
||||
return a < b
|
||||
end)
|
||||
|
||||
local add_value = function(k, val)
|
||||
if type(val) == 'string' then
|
||||
table.insert(results, string.format(' - %s: %s', k, val))
|
||||
elseif type(val) == 'table' then
|
||||
table.insert(results, string.format(' - %s:', k))
|
||||
for _, line in ipairs(val) do
|
||||
table.insert(results, string.format(' - %s', line))
|
||||
end
|
||||
else
|
||||
error("Unknown type:" .. type(val))
|
||||
end
|
||||
end
|
||||
|
||||
for _, k in ipairs(strategy_keys) do
|
||||
if shared_options[k] then
|
||||
add_value(k, strategy_config[k])
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(results, "")
|
||||
table.insert(results, "`picker.layout_config` unique options:")
|
||||
|
||||
for _, k in ipairs(strategy_keys) do
|
||||
if not shared_options[k] then
|
||||
add_value(k, strategy_config[k])
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(results, "</pre>")
|
||||
return results
|
||||
end
|
||||
|
||||
--@param name string: the name to be assigned to the layout
|
||||
--@param layout_config table: table where keys are the available options for the layout
|
||||
--@param layout function: function with signature
|
||||
-- function(self, max_columns, max_lines, layout_config): table
|
||||
-- the returned table is the sizing and location information for the parts of the picker
|
||||
--@retun function: wrapped function that inputs a validated layout_config into the `layout` function
|
||||
local function make_documented_layout(name, layout_config, layout)
|
||||
-- Save configuration data to be used by documentation
|
||||
layout_strategies._configurations[name] = layout_config
|
||||
|
||||
-- Return new function that always validates configuration
|
||||
return function(self, max_columns, max_lines, override_layout)
|
||||
return layout(
|
||||
self,
|
||||
max_columns,
|
||||
max_lines,
|
||||
validate_layout_config(
|
||||
name, layout_config, vim.tbl_deep_extend("keep", if_nil(override_layout, {}), if_nil(self.layout_config, {}))
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Horizontal layout has two columns, one for the preview
|
||||
--- and one for the prompt and results.
|
||||
---
|
||||
--- <pre>
|
||||
--- +-------------+--------------+
|
||||
--- | | |
|
||||
--- | Results | |
|
||||
--- | | Preview |
|
||||
--- | | |
|
||||
--- +-------------| |
|
||||
--- | Prompt | |
|
||||
--- +-------------+--------------+
|
||||
--- ┌──────────────────────────────────────────────────┐
|
||||
--- │ │
|
||||
--- │ ┌───────────────────┐┌───────────────────┐ │
|
||||
--- │ │ ││ │ │
|
||||
--- │ │ ││ │ │
|
||||
--- │ │ ││ │ │
|
||||
--- │ │ Results ││ │ │
|
||||
--- │ │ ││ Preview │ │
|
||||
--- │ │ ││ │ │
|
||||
--- │ │ ││ │ │
|
||||
--- │ └───────────────────┘│ │ │
|
||||
--- │ ┌───────────────────┐│ │ │
|
||||
--- │ │ Prompt ││ │ │
|
||||
--- │ └───────────────────┘└───────────────────┘ │
|
||||
--- │ │
|
||||
--- └──────────────────────────────────────────────────┘
|
||||
--- </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",
|
||||
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",
|
||||
})
|
||||
|
||||
---@eval { ["description"] = require('telescope.pickers.layout_strategies')._format("horizontal") }
|
||||
---
|
||||
layout_strategies.horizontal = make_documented_layout('horizontal', vim.tbl_extend("error", shared_options, {
|
||||
preview_width = { "Change the width of Telescope's preview window", "See |resolver.resolve_width()|", },
|
||||
preview_cutoff = "When columns are less than this value, the preview will be disabled",
|
||||
prompt_position = { "Where to place prompt window.", "Available Values: 'bottom', 'top'" },
|
||||
}), function(self, max_columns, max_lines, layout_config)
|
||||
local initial_options = p_window.get_initial_window_options(self)
|
||||
local preview = initial_options.preview
|
||||
local results = initial_options.results
|
||||
local prompt = initial_options.prompt
|
||||
|
||||
-- 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 = layout_config.width
|
||||
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 = layout_config.height
|
||||
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)
|
||||
if not self.previewer or cols < self.preview_cutoff then
|
||||
return 0
|
||||
elseif cols < 150 then
|
||||
if self.previewer and max_columns >= layout_config.preview_cutoff then
|
||||
preview.width = resolve.resolve_width(if_nil(layout_config.preview_width, function(_, cols)
|
||||
if cols < 150 then
|
||||
return math.floor(cols * 0.4)
|
||||
elseif cols < 200 then
|
||||
return 80
|
||||
else
|
||||
return 120
|
||||
end
|
||||
end)(self, picker_width, max_lines)
|
||||
end))(self, picker_width, max_lines)
|
||||
else
|
||||
preview.width = 0
|
||||
end
|
||||
@@ -175,14 +296,14 @@ layout_strategies.horizontal = function(self, max_columns, max_lines)
|
||||
end
|
||||
|
||||
preview.line = height_padding
|
||||
if self.window.prompt_position == "top" then
|
||||
if layout_config.prompt_position == "top" then
|
||||
prompt.line = height_padding
|
||||
results.line = prompt.line + prompt.height + 2
|
||||
elseif self.window.prompt_position == "bottom" then
|
||||
elseif layout_config.prompt_position == "bottom" then
|
||||
results.line = height_padding
|
||||
prompt.line = results.line + results.height + 2
|
||||
else
|
||||
error("Unknown prompt_position: " .. self.window.prompt_position)
|
||||
error("Unknown prompt_position: " .. tostring(self.window.prompt_position) .. "\n" .. vim.inspect(layout_config))
|
||||
end
|
||||
|
||||
return {
|
||||
@@ -190,33 +311,54 @@ layout_strategies.horizontal = function(self, max_columns, max_lines)
|
||||
results = results,
|
||||
prompt = prompt
|
||||
}
|
||||
end
|
||||
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 remaining space above.
|
||||
--- Particularly useful for creating dropdown menus
|
||||
--- (see |telescope.themes| and |themes.get_dropdown()|`).
|
||||
---
|
||||
--- <pre>
|
||||
--- +--------------+
|
||||
--- | Preview |
|
||||
--- +--------------+
|
||||
--- | Prompt |
|
||||
--- +--------------+
|
||||
--- | Result |
|
||||
--- | Result |
|
||||
--- | Result |
|
||||
--- +--------------+
|
||||
--- ┌──────────────────────────────────────────────────┐
|
||||
--- │ ┌────────────────────────────────────────┐ │
|
||||
--- │ | Preview | │
|
||||
--- │ | Preview | │
|
||||
--- │ └────────────────────────────────────────┘ │
|
||||
--- │ ┌────────────────────────────────────────┐ │
|
||||
--- │ | Prompt | │
|
||||
--- │ ├────────────────────────────────────────┤ │
|
||||
--- │ | Result | │
|
||||
--- │ | Result | │
|
||||
--- │ └────────────────────────────────────────┘ │
|
||||
--- │ │
|
||||
--- │ │
|
||||
--- │ │
|
||||
--- │ │
|
||||
--- └──────────────────────────────────────────────────┘
|
||||
--- </pre>
|
||||
layout_strategies.center = function(self, columns, lines)
|
||||
---@eval { ["description"] = require("telescope.pickers.layout_strategies")._format("center") }
|
||||
---
|
||||
layout_strategies.center = make_documented_layout("center", vim.tbl_extend("error", shared_options, {
|
||||
preview_cutoff = "When lines are less than this value, the preview will be disabled",
|
||||
}), function(self, max_columns, max_lines,layout_config)
|
||||
local initial_options = p_window.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 = layout_config.width
|
||||
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_opt = layout_config.height
|
||||
local res_height = resolve.resolve_height(res_height_opt)(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)
|
||||
|
||||
local bs = get_border_size(self)
|
||||
|
||||
prompt.height = 1
|
||||
results.height = max_results
|
||||
@@ -225,87 +367,84 @@ layout_strategies.center = function(self, columns, lines)
|
||||
results.width = max_width
|
||||
preview.width = max_width
|
||||
|
||||
-- border size
|
||||
local bs = 1
|
||||
if is_borderless(self) then
|
||||
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 self.previewer and max_lines >= layout_config.preview_cutoff then
|
||||
preview.height = math.floor(prompt.line - (2 + bs))
|
||||
else
|
||||
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
|
||||
|
||||
return {
|
||||
preview = self.previewer and preview.width > 0 and preview,
|
||||
preview = self.previewer and preview.height > 0 and preview,
|
||||
results = results,
|
||||
prompt = prompt
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
--- Vertical perviewer stacks the items on top of each other.
|
||||
--- Vertical layout stacks the items on top of each other.
|
||||
--- Particularly useful with thinner windows.
|
||||
---
|
||||
--- <pre>
|
||||
--- +-----------------+
|
||||
--- | Previewer |
|
||||
--- | Previewer |
|
||||
--- | Previewer |
|
||||
--- +-----------------+
|
||||
--- | Result |
|
||||
--- | Result |
|
||||
--- | Result |
|
||||
--- +-----------------+
|
||||
--- | Prompt |
|
||||
--- +-----------------+
|
||||
--- ┌──────────────────────────────────────────────────┐
|
||||
--- │ │
|
||||
--- │ ┌────────────────────────────────────────┐ │
|
||||
--- │ | Preview | │
|
||||
--- │ | Preview | │
|
||||
--- │ | Preview | │
|
||||
--- │ └────────────────────────────────────────┘ │
|
||||
--- │ ┌────────────────────────────────────────┐ │
|
||||
--- │ | Result | │
|
||||
--- │ | Result | │
|
||||
--- │ └────────────────────────────────────────┘ │
|
||||
--- │ ┌────────────────────────────────────────┐ │
|
||||
--- │ | Prompt | │
|
||||
--- │ └────────────────────────────────────────┘ │
|
||||
--- │ │
|
||||
--- └──────────────────────────────────────────────────┘
|
||||
--- </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",
|
||||
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",
|
||||
})
|
||||
|
||||
---@eval { ["description"] = require("telescope.pickers.layout_strategies")._format("vertical") }
|
||||
---
|
||||
layout_strategies.vertical = make_documented_layout("vertical", vim.tbl_extend("error", shared_options, {
|
||||
preview_cutoff = "When lines are less than this value, the preview will be disabled",
|
||||
preview_height = { "Change the height of Telescope's preview window", "See |resolver.resolve_height()|" },
|
||||
prompt_position = { "(unimplemented, but we plan on supporting)" },
|
||||
}), function(self, max_columns, max_lines, layout_config)
|
||||
local initial_options = p_window.get_initial_window_options(self)
|
||||
local preview = initial_options.preview
|
||||
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 = layout_config.width
|
||||
local picker_width = resolve.resolve_width(width_opt)(self,max_columns,max_lines)
|
||||
local width_padding = math.floor((max_columns - picker_width)/2)
|
||||
|
||||
local width = max_columns - width_padding * 2
|
||||
if not self.previewer then
|
||||
preview.width = 0
|
||||
local height_opt = layout_config.height
|
||||
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 and max_lines >= layout_config.preview_cutoff then
|
||||
preview.width = picker_width
|
||||
else
|
||||
preview.width = width
|
||||
preview.width = 0
|
||||
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
|
||||
if self.previewer and max_lines >= layout_config.preview_cutoff then
|
||||
preview.height = resolve.resolve_height(
|
||||
layout_config.preview_height or (max_lines - 15)
|
||||
if_nil(layout_config.preview_height, 0.5)
|
||||
)(self, max_columns, picker_height)
|
||||
|
||||
preview_total = preview.height + 2
|
||||
@@ -332,36 +471,38 @@ layout_strategies.vertical = function(self, max_columns, max_lines)
|
||||
end
|
||||
|
||||
return {
|
||||
preview = self.previewer and preview.width > 0 and preview,
|
||||
preview = self.previewer and preview.height > 0 and preview,
|
||||
results = results,
|
||||
prompt = prompt
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
--- Swap between `horizontal` and `vertical` strategies based on the window width
|
||||
--- - Supports `vertical` or `horizontal` features
|
||||
--- Flex layout swaps between `horizontal` and `vertical` strategies based on the window width
|
||||
--- - Supports |layout_strategies.vertical| or |layout_strategies.horizontal| features
|
||||
---
|
||||
--- Uses:
|
||||
--- - flip_columns
|
||||
--- - flip_lines
|
||||
layout_strategies.flex = function(self, max_columns, max_lines)
|
||||
local layout_config = self.layout_config or {}
|
||||
|
||||
local flip_columns = layout_config.flip_columns or 100
|
||||
local flip_lines = layout_config.flip_lines or 20
|
||||
---@eval { ["description"] = require("telescope.pickers.layout_strategies")._format("flex") }
|
||||
---
|
||||
layout_strategies.flex = make_documented_layout('flex', vim.tbl_extend("error", shared_options, {
|
||||
flip_columns = "The number of columns required to move to horizontal mode",
|
||||
flip_lines = "The number of lines required to move to horizontal mode",
|
||||
vertical = "Options to pass when switching to vertical layout",
|
||||
horizontal = "Options to pass when switching to horizontal layout",
|
||||
}), function(self, max_columns, max_lines, layout_config)
|
||||
local flip_columns = if_nil(layout_config.flip_columns, 100)
|
||||
local flip_lines = if_nil(layout_config.flip_lines, 20)
|
||||
|
||||
if max_columns < flip_columns and max_lines > flip_lines then
|
||||
-- TODO: This feels a bit like a hack.... cause you wouldn't be able to pass this to flex easily.
|
||||
self.layout_config = (config.values.layout_defaults or {})['vertical']
|
||||
return layout_strategies.vertical(self, max_columns, max_lines)
|
||||
return layout_strategies.vertical(self, max_columns, max_lines, layout_config.vertical)
|
||||
else
|
||||
self.layout_config = (config.values.layout_defaults or {})['horizontal']
|
||||
return layout_strategies.horizontal(self, max_columns, max_lines)
|
||||
return layout_strategies.horizontal(self, max_columns, max_lines, layout_config.horizontal)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
layout_strategies.current_buffer = function(self, _, _)
|
||||
local initial_options = self:_get_initial_window_options()
|
||||
layout_strategies.current_buffer = make_documented_layout('current_buffer', {
|
||||
-- No custom options.
|
||||
-- height, width ignored
|
||||
}, function(self, _, _, _)
|
||||
local initial_options = p_window.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)
|
||||
@@ -414,19 +555,20 @@ layout_strategies.current_buffer = function(self, _, _)
|
||||
results = results,
|
||||
prompt = prompt,
|
||||
}
|
||||
end
|
||||
|
||||
layout_strategies.bottom_pane = function(self, max_columns, max_lines)
|
||||
local layout_config = validate_layout_config(self.layout_config or {}, {
|
||||
height = "The height of the layout",
|
||||
})
|
||||
end)
|
||||
|
||||
--- Bottom pane can be used to create layouts similar to "ivy".
|
||||
---
|
||||
--- For an easy ivy configuration, see |themes.get_ivy()|
|
||||
layout_strategies.bottom_pane = make_documented_layout('bottom_pane', vim.tbl_extend("error", shared_options, {
|
||||
-- No custom options...
|
||||
}), function(self, max_columns, max_lines, layout_config)
|
||||
local initial_options = p_window.get_initial_window_options(self)
|
||||
local results = initial_options.results
|
||||
local prompt = initial_options.prompt
|
||||
local preview = initial_options.preview
|
||||
|
||||
local result_height = layout_config.height or 25
|
||||
local result_height = if_nil(resolve.resolve_height(layout_config.height)(self,max_columns,max_lines), 25)
|
||||
|
||||
local prompt_width = max_columns
|
||||
local col = 0
|
||||
@@ -477,6 +619,8 @@ layout_strategies.bottom_pane = function(self, max_columns, max_lines)
|
||||
width = result_width,
|
||||
}),
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
layout_strategies._validate_layout_config = validate_layout_config
|
||||
|
||||
return layout_strategies
|
||||
|
||||
@@ -302,7 +302,6 @@ previewers.git_commit_message = buffer_previewer.git_commit_message
|
||||
--- The run command is `git --no-pager diff $FILE`
|
||||
previewers.git_file_diff = buffer_previewer.git_file_diff
|
||||
|
||||
|
||||
previewers.ctags = buffer_previewer.ctags
|
||||
previewers.builtin = buffer_previewer.builtin
|
||||
previewers.help = buffer_previewer.help
|
||||
|
||||
@@ -27,16 +27,26 @@ function themes.get_dropdown(opts)
|
||||
opts = opts or {}
|
||||
|
||||
local theme_opts = {
|
||||
-- WIP: Decide on keeping these names or not.
|
||||
theme = "dropdown",
|
||||
|
||||
results_title = false,
|
||||
preview_title = "Preview",
|
||||
|
||||
sorting_strategy = "ascending",
|
||||
layout_strategy = "center",
|
||||
results_title = false,
|
||||
preview_title = "Preview",
|
||||
preview_cutoff = 1, -- Preview should always show (unless previewer = false)
|
||||
width = 80,
|
||||
results_height = 15,
|
||||
layout_config = {
|
||||
preview_cutoff = 1, -- Preview should always show (unless previewer = false)
|
||||
|
||||
width = function(_, max_columns, _)
|
||||
return math.min(max_columns - 3, 80)
|
||||
end,
|
||||
|
||||
height = function(_, _, max_lines)
|
||||
return math.min(max_lines - 4, 15)
|
||||
end,
|
||||
},
|
||||
|
||||
border = true,
|
||||
borderchars = {
|
||||
{ "─", "│", "─", "│", "╭", "╮", "╯", "╰"},
|
||||
prompt = {"─", "│", " ", "│", "╭", "╮", "│", "│"},
|
||||
|
||||
92
lua/tests/automated/layout_strategies_spec.lua
Normal file
92
lua/tests/automated/layout_strategies_spec.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
-- local tester = require('telescope.pickers._test')
|
||||
local config = require('telescope.config')
|
||||
local resolve = require('telescope.config.resolve')
|
||||
local layout_strats = require('telescope.pickers.layout_strategies')
|
||||
|
||||
local validate_layout_config = layout_strats._validate_layout_config
|
||||
|
||||
local eq = assert.are.same
|
||||
|
||||
describe('layout_strategies', function()
|
||||
it('should have validator', function()
|
||||
assert(validate_layout_config, "Has validator")
|
||||
end)
|
||||
|
||||
local test_height = function(should, output, input, opts)
|
||||
opts = opts or {}
|
||||
|
||||
local max_columns, max_lines = opts.max_columns or 100, opts.max_lines or 100
|
||||
it(should, function()
|
||||
local layout_config = validate_layout_config("horizontal", { height = true }, { height = input })
|
||||
|
||||
eq(output, resolve.resolve_height(layout_config.height)({}, max_columns, max_lines))
|
||||
end)
|
||||
end
|
||||
|
||||
test_height('should handle numbers', 10, 10)
|
||||
|
||||
test_height('should handle percentage: 100', 10, 0.1, { max_lines = 100 })
|
||||
test_height('should handle percentage: 110', 11, 0.1, { max_lines = 110 })
|
||||
|
||||
test_height('should call functions: simple', 5, function() return 5 end)
|
||||
test_height('should call functions: percentage', 15, function(_, _, lines) return 0.1 * lines end, { max_lines = 150 })
|
||||
|
||||
local test_defaults_key = function(should, key, strat, output, ours, theirs, override)
|
||||
ours = ours or {}
|
||||
theirs = theirs or {}
|
||||
override = override or {}
|
||||
|
||||
it(should, function()
|
||||
config.clear_defaults()
|
||||
config.set_defaults({layout_config=theirs}, {layout_config={ours,'description'}})
|
||||
local layout_config = validate_layout_config(strat, layout_strats._configurations[strat], override)
|
||||
eq(output, layout_config[key])
|
||||
end)
|
||||
end
|
||||
|
||||
test_defaults_key("should use ours if theirs and override don't give the key",
|
||||
'height','horizontal',50,
|
||||
{height=50}, {width=100}, {width=120}
|
||||
)
|
||||
|
||||
test_defaults_key("should use ours if theirs and override don't give the key for this strategy",
|
||||
'height','horizontal',50,
|
||||
{height=50}, {vertical={height=100}}, {vertical={height=120}}
|
||||
)
|
||||
|
||||
test_defaults_key("should use theirs if override doesn't give the key",
|
||||
'height','horizontal',100,
|
||||
{height=50}, {height=100}, {width=120}
|
||||
)
|
||||
|
||||
test_defaults_key("should use override if key given",
|
||||
'height','horizontal',120,
|
||||
{height=50}, {height=100}, {height=120}
|
||||
)
|
||||
|
||||
test_defaults_key("should use override if key given for this strategy",
|
||||
'height','horizontal',120,
|
||||
{height=50}, {height=100}, {horizontal={height=120}}
|
||||
)
|
||||
|
||||
test_defaults_key("should use theirs if override doesn't give key (even if ours has strategy specific)",
|
||||
'height','horizontal',100,
|
||||
{horizontal={height=50}}, {height=100}, {width=120}
|
||||
)
|
||||
|
||||
test_defaults_key("should use override (even if ours has strategy specific)",
|
||||
'height','horizontal',120,
|
||||
{horizontal={height=50}}, {height=100}, {height=120}
|
||||
)
|
||||
|
||||
test_defaults_key("should use override (even if theirs has strategy specific)",
|
||||
'height','horizontal',120,
|
||||
{height=50}, {horizontal={height=100}}, {height=120}
|
||||
)
|
||||
|
||||
test_defaults_key("should use override (even if ours and theirs have strategy specific)",
|
||||
'height','horizontal',120,
|
||||
{horizontal={height=50}}, {horizontal={height=100}}, {height=120}
|
||||
)
|
||||
|
||||
end)
|
||||
@@ -35,8 +35,11 @@ describe('builtin.find_files', function()
|
||||
}, vim.tbl_extend("force", {
|
||||
disable_devicons = true,
|
||||
sorter = require('telescope.sorters').get_fzy_sorter(),
|
||||
results_height = max_results,
|
||||
layout_strategy = 'center',
|
||||
layout_config = {
|
||||
height = max_results,
|
||||
width = 0.9,
|
||||
},
|
||||
}, vim.fn.json_decode([==[%s]==])))
|
||||
]], vim.fn.json_encode(configuration)))
|
||||
end)
|
||||
@@ -57,8 +60,11 @@ describe('builtin.find_files', function()
|
||||
}, vim.tbl_extend("force", {
|
||||
disable_devicons = true,
|
||||
sorter = require('telescope.sorters').get_fzy_sorter(),
|
||||
results_height = 5,
|
||||
layout_strategy = 'center',
|
||||
layout_config = {
|
||||
height = max_results,
|
||||
width = 0.9,
|
||||
},
|
||||
}, vim.fn.json_decode([==[%s]==])))
|
||||
]], expected, vim.fn.json_encode(configuration)))
|
||||
end)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
-- Setup telescope with defaults
|
||||
if RELOAD then RELOAD('telescope') end
|
||||
require('telescope').setup()
|
||||
|
||||
local docgen = require('docgen')
|
||||
@@ -15,6 +16,7 @@ docs.test = function()
|
||||
"./lua/telescope/actions/state.lua",
|
||||
"./lua/telescope/actions/set.lua",
|
||||
"./lua/telescope/previewers/init.lua",
|
||||
"./lua/telescope/config/resolve.lua",
|
||||
"./lua/telescope/themes.lua",
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user