summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
authorTJ DeVries <devries.timothyj@gmail.com>2020-09-04 00:36:28 -0400
committerTJ DeVries <devries.timothyj@gmail.com>2020-09-04 00:36:28 -0400
commit996f69465ed51856aa18093d88795fae2b8565f4 (patch)
treefee85048ce993d62e4d961bef632a96cfdeea463 /lua
parent839f57efb37cba7a9542b67b31370e1babaf194a (diff)
feat: vertical layouts. see 'layout_strategy'
Diffstat (limited to 'lua')
-rw-r--r--lua/telescope/builtin.lua1
-rw-r--r--lua/telescope/config.lua25
-rw-r--r--lua/telescope/pickers.lua77
-rw-r--r--lua/telescope/pickers/layout_strategies.lua121
4 files changed, 176 insertions, 48 deletions
diff --git a/lua/telescope/builtin.lua b/lua/telescope/builtin.lua
index 0430d09..7f4c72d 100644
--- a/lua/telescope/builtin.lua
+++ b/lua/telescope/builtin.lua
@@ -200,6 +200,7 @@ end
builtin.grep_string = function(opts)
opts = opts or {}
+ -- TODO: This should probably check your visual selection as well, if you've got one
local search = opts.search or vim.fn.expand("<cword>")
pickers.new(opts, {
diff --git a/lua/telescope/config.lua b/lua/telescope/config.lua
new file mode 100644
index 0000000..6139d36
--- /dev/null
+++ b/lua/telescope/config.lua
@@ -0,0 +1,25 @@
+local get_default = require('telescope.utils').get_default
+
+
+-- TODO: Add other major configuration points here.
+-- border
+-- borderchars
+-- selection_strategy
+
+-- TODO: use `require('telescope').setup { }`
+
+_TelescopeConfigurationValues = _TelescopeConfigurationValues or {}
+
+_TelescopeConfigurationValues.default_layout_strategy = get_default(
+ _TelescopeConfigurationValues.default_layout_strategy,
+ 'horizontal'
+)
+
+-- TODO: this should probably be more complicated than just a number.
+-- If you're going to allow a bunch of layout strats, they should have nested info or something
+_TelescopeConfigurationValues.default_window_width = get_default(
+ _TelescopeConfigurationValues.default_window_width,
+ 0.75
+)
+
+return _TelescopeConfigurationValues
diff --git a/lua/telescope/pickers.lua b/lua/telescope/pickers.lua
index f109db7..c747927 100644
--- a/lua/telescope/pickers.lua
+++ b/lua/telescope/pickers.lua
@@ -2,6 +2,8 @@ local a = vim.api
local popup = require('popup')
local actions = require('telescope.actions')
+local config = require('telescope.config')
+local layout_strategies = require('telescope.pickers.layout_strategies')
local log = require('telescope.log')
local mappings = require('telescope.mappings')
local state = require('telescope.state')
@@ -66,6 +68,10 @@ Picker.__index = Picker
function Picker:new(opts)
opts = opts or {}
+ if opts.layout_strategy and opts.get_window_options then
+ error("layout_strategy and get_window_options are not compatible keys")
+ end
+
return setmetatable({
prompt = opts.prompt,
default_text = opts.default_text,
@@ -88,12 +94,17 @@ function Picker:new(opts)
-- mappings = get_default(opts.mappings, default_mappings),
attach_mappings = opts.attach_mappings,
+ layout_strategy = opts.layout_strategy,
get_window_options = opts.get_window_options,
selection_strategy = opts.selection_strategy,
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.default_window_width),
preview_width = get_default(opts.preview_width, 0.8),
results_width = get_default(opts.results_width, 0.8),
@@ -106,7 +117,7 @@ function Picker:new(opts)
}, Picker)
end
-function Picker:get_window_options(max_columns, max_lines, prompt_title)
+function Picker:_get_initial_window_options(prompt_title)
local popup_border = self.window.border
local popup_borderchars = self.window.borderchars
@@ -130,58 +141,26 @@ function Picker:get_window_options(max_columns, max_lines, prompt_title)
enter = true
}
- -- TODO: Test with 120 width terminal
-
- local width_padding = 10
- if not self.previewer or max_columns < self.preview_cutoff then
- width_padding = 2
- preview.width = 0
- elseif max_columns < 150 then
- width_padding = 5
- preview.width = math.floor(max_columns * 0.4)
- elseif max_columns < 200 then
- preview.width = 80
- else
- preview.width = 120
- end
-
- local other_width = max_columns - preview.width - (2 * width_padding)
- results.width = other_width
- prompt.width = other_width
+ return {
+ preview = preview,
+ results = results,
+ prompt = prompt,
+ }
+end
- local base_height
- if max_lines < 40 then
- base_height = math.min(math.floor(max_lines * 0.8), max_lines - 8)
- else
- base_height = math.floor(max_lines * 0.8)
- end
- results.height = base_height
- results.minheight = results.height
- prompt.height = 1
- prompt.minheight = prompt.height
-
- if self.previewer then
- preview.height = results.height + prompt.height + 2
- preview.minheight = preview.height
- else
- preview.height = 0
+function Picker:get_window_options(max_columns, max_lines, prompt_title)
+ local layout_strategy = self.layout_strategy
+ if not layout_strategy then
+ layout_strategy = config.default_layout_strategy
end
- results.col = width_padding
- prompt.col = width_padding
- preview.col = results.col + results.width + 2
+ local getter = layout_strategies[layout_strategy]
- -- TODO: Center this in the page a bit better.
- local height_padding = math.max(math.floor(0.95 * max_lines), 2)
- results.line = max_lines - height_padding
- prompt.line = results.line + results.height + 2
- preview.line = results.line
+ if not getter then
+ error("Not a valid layout strategy: ", layout_strategy)
+ end
- return {
- preview = preview.width > 0 and preview,
- results = results,
- prompt = prompt,
- }
+ return getter(self, max_columns, max_lines, prompt_title)
end
function Picker:find()
@@ -651,5 +630,7 @@ function pickers.on_close_prompt(prompt_bufnr)
end
end
+pickers._Picker = Picker
+
return pickers
diff --git a/lua/telescope/pickers/layout_strategies.lua b/lua/telescope/pickers/layout_strategies.lua
new file mode 100644
index 0000000..10c9613
--- /dev/null
+++ b/lua/telescope/pickers/layout_strategies.lua
@@ -0,0 +1,121 @@
+
+local layout_strategies = {}
+
+layout_strategies.horizontal = function(self, max_columns, max_lines, prompt_title)
+ local initial_options = self:_get_initial_window_options(prompt_title)
+ 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 = 10
+ if not self.previewer or max_columns < self.preview_cutoff then
+ width_padding = 2
+ preview.width = 0
+ elseif max_columns < 150 then
+ width_padding = 5
+ preview.width = math.floor(max_columns * 0.4)
+ elseif max_columns < 200 then
+ preview.width = 80
+ else
+ preview.width = 120
+ end
+
+ local other_width = max_columns - preview.width - (2 * width_padding)
+ results.width = other_width
+ prompt.width = other_width
+
+ local base_height
+ if max_lines < 40 then
+ base_height = math.min(math.floor(max_lines * 0.8), max_lines - 8)
+ else
+ base_height = math.floor(max_lines * 0.8)
+ end
+ results.height = base_height
+ results.minheight = results.height
+ prompt.height = 1
+ prompt.minheight = prompt.height
+
+ if self.previewer then
+ preview.height = results.height + prompt.height + 2
+ preview.minheight = preview.height
+ else
+ preview.height = 0
+ end
+
+ results.col = width_padding
+ prompt.col = width_padding
+ preview.col = results.col + results.width + 2
+
+ -- TODO: Center this in the page a bit better.
+ local height_padding = math.max(math.floor(0.95 * max_lines), 2)
+ results.line = max_lines - height_padding
+ prompt.line = results.line + results.height + 2
+ preview.line = results.line
+
+ return {
+ preview = preview.width > 0 and preview,
+ results = results,
+ prompt = prompt,
+ }
+end
+
+layout_strategies.vertical = function(self, max_columns, max_lines, prompt_title)
+ local initial_options = self:_get_initial_window_options(prompt_title)
+
+ local preview = initial_options.preview
+ local results = initial_options.results
+ local prompt = initial_options.prompt
+
+ local width_padding = math.ceil((1 - self.window.width) * 0.5 * max_columns)
+ local width = max_columns - width_padding * 2
+ if not self.previewer then
+ preview.width = 0
+ else
+ preview.width = width
+ end
+ results.width = width
+ prompt.width = width
+
+ -- Height
+ local height_padding = 3
+
+ results.height = 10
+ results.minheight = 10
+ prompt.height = 1
+ prompt.minheight = 1
+
+ -- The last 2 * 2 is for the extra borders
+ if self.previewer then
+ preview.height = max_lines - results.height - prompt.height - 2 * 2 - height_padding * 2
+ preview.minheight = preview.height
+ else
+ results.height = max_lines - prompt.height - 2 - height_padding * 2
+ results.minheight = results.height
+ end
+
+ results.col, preview.col, prompt.col = width_padding, width_padding, width_padding
+
+ if self.previewer then
+ preview.line = height_padding
+ results.line = preview.line + preview.height + 2
+ prompt.line = results.line + results.height + 2
+ else
+ results.line = height_padding
+ prompt.line = results.line + results.height + 2
+ end
+
+ return {
+ preview = preview.width > 0 and preview,
+ results = results,
+ prompt = prompt
+ }
+end
+
+-- TODO: Add "flex"
+-- If you don't have enough width, use the height one
+-- etc.
+
+return layout_strategies