diff options
| author | Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> | 2021-11-15 21:32:02 +0000 |
|---|---|---|
| committer | Luke Kershaw <35707277+l-kershaw@users.noreply.github.com> | 2021-11-18 19:44:12 +0000 |
| commit | edcf07cf885f86c08c5b15f333b7c82b15c3527b (patch) | |
| tree | 4d2638cfb6f401660ab5317f535ceb274cd60e7f /lua/telescope/actions/layout.lua | |
| parent | b952c2f852de1ec5ce7306ccd9262c97e27902d2 (diff) | |
feat: layout actions (#1383)
Co-authored-by: johnybx <johnybx@users.noreply.github.com>
Diffstat (limited to 'lua/telescope/actions/layout.lua')
| -rw-r--r-- | lua/telescope/actions/layout.lua | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/lua/telescope/actions/layout.lua b/lua/telescope/actions/layout.lua new file mode 100644 index 0000000..f40151f --- /dev/null +++ b/lua/telescope/actions/layout.lua @@ -0,0 +1,140 @@ +---@tag telescope.actions.layout + +---@brief [[ +--- The layout actions are actions to be used to change the layout of a picker. +---@brief ]] + +local action_state = require "telescope.actions.state" +local state = require "telescope.state" +local layout_strats = require "telescope.pickers.layout_strategies" + +local action_layout = {} + +--- Toggle preview window. +--- - Note: preview window can be toggled even if preview is set to false. +--- +--- This action is not mapped by default. +---@param prompt_bufnr number: The prompt bufnr +action_layout.toggle_preview = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + local status = state.get_status(picker.prompt_bufnr) + + if picker.previewer and status.preview_win then + picker.hidden_previewer = picker.previewer + picker.previewer = nil + elseif picker.hidden_previewer and not status.preview_win then + picker.previewer = picker.hidden_previewer + picker.hidden_previewer = nil + else + return + end + picker:full_layout_update() +end + +-- TODO IMPLEMENT (mentored project available, contact @l-kershaw) +action_layout.toggle_padding = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + -- if padding ~= 0 + -- 1. Save `height` and `width` of picker + -- 2. Set both to `{padding = 0}` + -- else + -- 1. Lookup previous `height` and `width` of picker + -- 2. Set both to previous values + picker:full_layout_update() +end + +--- Toggles the `prompt_position` option between "top" and "bottom". +--- Checks if `prompt_position` is an option for the current layout. +--- +--- This action is not mapped by default. +---@param prompt_bufnr number: The prompt bufnr +action_layout.toggle_prompt_position = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + picker.layout_config = picker.layout_config or {} + picker.layout_config[picker.layout_strategy] = picker.layout_config[picker.layout_strategy] or {} + -- flex layout is weird and needs handling separately + if picker.layout_strategy == "flex" then + picker.layout_config.flex.horizontal = picker.layout_config.flex.horizontal or {} + picker.layout_config.flex.vertical = picker.layout_config.flex.vertical or {} + local old_pos = picker.layout_config.flex[picker.__flex_strategy].prompt_position + local new_pos = old_pos == "top" and "bottom" or "top" + picker.layout_config[picker.__flex_strategy].prompt_position = new_pos + picker.layout_config.flex[picker.__flex_strategy].prompt_position = new_pos + picker:full_layout_update() + elseif layout_strats._configurations[picker.layout_strategy].prompt_position then + if picker.layout_config.prompt_position == "top" then + picker.layout_config.prompt_position = "bottom" + picker.layout_config[picker.layout_strategy].prompt_position = "bottom" + else + picker.layout_config.prompt_position = "top" + picker.layout_config[picker.layout_strategy].prompt_position = "top" + end + picker:full_layout_update() + end +end + +--- Toggles the `mirror` option between `true` and `false`. +--- Checks if `mirror` is an option for the current layout. +--- +--- This action is not mapped by default. +---@param prompt_bufnr number: The prompt bufnr +action_layout.toggle_mirror = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + -- flex layout is weird and needs handling separately + if picker.layout_strategy == "flex" then + picker.layout_config.flex.horizontal = picker.layout_config.flex.horizontal or {} + picker.layout_config.flex.vertical = picker.layout_config.flex.vertical or {} + local new_mirror = not picker.layout_config.flex[picker.__flex_strategy].mirror + picker.layout_config[picker.__flex_strategy].mirror = new_mirror + picker.layout_config.flex[picker.__flex_strategy].mirror = new_mirror + picker:full_layout_update() + elseif layout_strats._configurations[picker.layout_strategy].mirror then + picker.layout_config = picker.layout_config or {} + local new_mirror = not picker.layout_config.mirror + picker.layout_config.mirror = new_mirror + picker.layout_config[picker.layout_strategy] = picker.layout_config[picker.layout_strategy] or {} + picker.layout_config[picker.layout_strategy].mirror = new_mirror + picker:full_layout_update() + end +end + +-- Helper function for `cycle_layout_next` and `cycle_layout_prev`. +local get_cycle_layout = function(dir) + return function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + if picker.__layout_index then + picker.__layout_index = ((picker.__layout_index + dir - 1) % #picker.__cycle_layout_list) + 1 + else + picker.__layout_index = 1 + end + local new_layout = picker.__cycle_layout_list[picker.__layout_index] + if type(new_layout) == "string" then + picker.layout_strategy = new_layout + picker.layout_config = nil + picker.previewer = picker.all_previewers and picker.all_previewers[1] or nil + elseif type(new_layout) == "table" then + picker.layout_strategy = new_layout.layout_strategy + picker.layout_config = new_layout.layout_config + picker.previewer = (new_layout.previewer == nil and picker.all_previewers[picker.current_previewer_index]) + or new_layout.previewer + else + error("Not a valid layout setup: " .. vim.inspect(new_layout) .. "\nShould be a string or a table") + end + + picker:full_layout_update() + end +end + +--- Cycles to the next layout in `cycle_layout_list`. +--- +--- This action is not mapped by default. +---@param prompt_bufnr number: The prompt bufnr +action_layout.cycle_layout_next = get_cycle_layout(1) + +--- Cycles to the previous layout in `cycle_layout_list`. +--- +--- This action is not mapped by default. +---@param prompt_bufnr number: The prompt bufnr +action_layout.cycle_layout_prev = get_cycle_layout(-1) + +return action_layout |
