summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
authorTJ DeVries <devries.timothyj@gmail.com>2020-09-10 21:21:14 -0400
committerTJ DeVries <devries.timothyj@gmail.com>2020-09-11 00:14:40 -0400
commitfe387d10db66dc9b33388f05fadabbdc9b31c28b (patch)
treee178ea08415c1d0a9387daeb0ee12b5feb10b51c /lua
parent769f5934f00a49097fec227adbdef62a34d71109 (diff)
feat: add top down prompt position
Diffstat (limited to 'lua')
-rw-r--r--lua/telescope/config.lua2
-rw-r--r--lua/telescope/pickers.lua97
-rw-r--r--lua/telescope/pickers/config_collapse.lua51
-rw-r--r--lua/telescope/pickers/layout_strategies.lua15
4 files changed, 145 insertions, 20 deletions
diff --git a/lua/telescope/config.lua b/lua/telescope/config.lua
index 192056d..8704fe2 100644
--- a/lua/telescope/config.lua
+++ b/lua/telescope/config.lua
@@ -35,6 +35,8 @@ function config.set_defaults(defaults)
set("layout_strategy", "horizontal")
set("width", 0.75)
set("winblend", 0)
+ set("prompt_position", "top")
+ set("preview_cutoff", 120)
set("border", {})
set("borderchars", { '─', '│', '─', '│', '╭', '╮', '╯', '╰'})
diff --git a/lua/telescope/pickers.lua b/lua/telescope/pickers.lua
index 87d3145..15910d3 100644
--- a/lua/telescope/pickers.lua
+++ b/lua/telescope/pickers.lua
@@ -100,6 +100,7 @@ function Picker:new(opts)
-- mappings = get_default(opts.mappings, default_mappings),
attach_mappings = opts.attach_mappings,
+ sorting_strategy = 'ascending',
selection_strategy = get_default(opts.selection_strategy, config.values.selection_strategy),
layout_strategy = get_default(opts.layout_strategy, config.values.layout_strategy),
@@ -115,6 +116,8 @@ function Picker:new(opts)
get_preview_width = get_default(opts.preview_width, config.values.get_preview_width),
results_width = get_default(opts.results_width, 0.8),
+ 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),
@@ -123,7 +126,7 @@ function Picker:new(opts)
horizontal_config = get_default(opts.horizontal_config, config.values.horizontal_config),
},
- preview_cutoff = get_default(opts.preview_cutoff, 120),
+ preview_cutoff = get_default(opts.preview_cutoff, config.values.preview_cutoff),
}, Picker)
end
@@ -171,6 +174,69 @@ function Picker:get_window_options(max_columns, max_lines, prompt_title)
return getter(self, max_columns, max_lines, prompt_title)
end
+--- Take a row and get an index
+---@param index number: The row being displayed
+---@return number The row for the picker to display in
+function Picker:get_row(index)
+ if self.sorting_strategy == 'ascending' then
+ return index
+ else
+ return self.max_results - index + 1
+ end
+end
+
+--- Take a row and get an index
+---@param row number: The row being displayed
+---@return number The index in line_manager
+function Picker:get_index(row)
+ if self.sorting_strategy == 'ascending' then
+ return row
+ else
+ return self.max_results - row + 1
+ end
+end
+
+function Picker:get_reset_row()
+ if self.sorting_strategy == 'ascending' then
+ log.info("Setting reset row:", 1)
+ return 1
+ else
+ return self.max_results
+ end
+end
+
+function Picker:clear_extra_rows(results_bufnr)
+ if self.sorting_strategy == 'ascending' then
+ local num_results = self.manager:num_results()
+ local worst_line = self.max_results - num_results
+
+ if worst_line <= 0 then
+ return
+ end
+
+ log.info("start", num_results + 1, "end", self.max_results)
+ vim.api.nvim_buf_set_lines(results_bufnr, num_results + 1, self.max_results, false, {})
+ else
+ local worst_line = self:get_row(self.manager:num_results())
+ if worst_line <= 0 then
+ return
+ end
+
+ local empty_lines = utils.repeated_table(worst_line, "")
+ vim.api.nvim_buf_set_lines(results_bufnr, 0, worst_line, false, empty_lines)
+
+ log.trace("Worst Line after process_complete: %s", worst_line, results_bufnr)
+ end
+end
+
+function Picker:can_select_row(row)
+ if self.sorting_strategy == 'ascending' then
+ return row <= self.manager:num_results()
+ else
+ return row >= self.manager:num_results()
+ end
+end
+
function Picker:find()
self:reset_selection()
@@ -240,12 +306,13 @@ function Picker:find()
self.manager = pickers.entry_manager(
self.max_results,
vim.schedule_wrap(function(index, entry)
- local row = self.max_results - index + 1
+ local row = self:get_row(index)
-- If it's less than 0, then we don't need to show it at all.
if row < 0 then
return
end
+ -- TODO: Do we need to also make sure we don't have something bigger than max results?
local display
if type(entry.display) == 'function' then
@@ -311,25 +378,18 @@ function Picker:find()
local index = self.manager:find_entry(self:get_selection())
if index then
- local follow_row = self.max_results - index + 1
+ local follow_row = self:get_row(index)
self:set_selection(follow_row)
else
- self:set_selection(self.max_results)
+ self:set_selection(self:get_reset_row())
end
+ elseif selection_strategy == 'reset' then
+ self:set_selection(self:get_reset_row())
else
- -- selection_strategy == 'reset'
- self:set_selection(self.max_results)
+ error('Unknown selection strategy: ' .. selection_strategy)
end
- local worst_line = self.max_results - self.manager.num_results() + 1
- if worst_line <= 0 then
- return
- end
-
- local empty_lines = utils.repeated_table(worst_line, "")
- vim.api.nvim_buf_set_lines(results_bufnr, 0, worst_line, false, empty_lines)
-
- log.trace("Worst Line after process_complete: %s", worst_line, results_bufnr)
+ self:clear_extra_rows(results_bufnr)
end)
local ok, msg = pcall(function()
@@ -479,11 +539,14 @@ function Picker:set_selection(row)
-- I have this same thing copied all over the place (and it's not good).
-- Particularly if we're going to do something like make it possible to sort
-- top to bottom, rather than bottom to top.
- if row < (self.max_results - self.manager:num_results() + 1) then
+
+ -- TODO: Is this the right logic here?
+ if not self:can_select_row(row) then
return
end
- local entry = self.manager:get_entry(self.max_results - row + 1)
+ -- local entry = self.manager:get_entry(self.max_results - row + 1)
+ local entry = self.manager:get_entry(self:get_index(row))
local status = state.get_status(self.prompt_bufnr)
local results_bufnr = status.results_bufnr
diff --git a/lua/telescope/pickers/config_collapse.lua b/lua/telescope/pickers/config_collapse.lua
new file mode 100644
index 0000000..286d484
--- /dev/null
+++ b/lua/telescope/pickers/config_collapse.lua
@@ -0,0 +1,51 @@
+
+--[[
+
+Ultimately boils down to getting `height` and `width` for:
+- prompt
+- preview
+- results
+
+No matter what you do, I will not make prompt have more than one line (atm)
+
+Result of `resolve` should be a table with:
+
+{
+ preview = {
+ get_width = function(self, max_columns, max_lines) end
+ get_height = function(self, max_columns, max_lines) end
+ },
+
+ result = {
+ get_width = function(self, max_columns, max_lines) end
+ get_height = function(self, max_columns, max_lines) end
+ },
+
+ prompt = {
+ get_width = function(self, max_columns, max_lines) return 1end
+ get_height = function(self, max_columns, max_lines) end
+ },
+}
+
+--]]
+
+local resolver = {}
+
+local percentage_resolver = function(selector, percentage)
+ assert(percentage <= 1)
+ assert(percentage >= 0)
+
+ return function(...)
+ return percentage * select(selector, ...)
+ end
+end
+
+resolver.resolve_percentage_height = function(percentage)
+ return percentage_resolver(3, percentage)
+end
+
+resolver.resolve_percentage_width = function(percentage)
+ return percentage_resolver(2, percentage)
+end
+
+return resolver
diff --git a/lua/telescope/pickers/layout_strategies.lua b/lua/telescope/pickers/layout_strategies.lua
index f47fb99..77cb3ab 100644
--- a/lua/telescope/pickers/layout_strategies.lua
+++ b/lua/telescope/pickers/layout_strategies.lua
@@ -64,9 +64,18 @@ layout_strategies.horizontal = function(self, max_columns, max_lines, prompt_tit
-- 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 self.window.prompt_position == "top" then
+ prompt.line = max_lines - height_padding
+ results.line = prompt.line + 3
+ preview.line = prompt.line
+ elseif self.window.prompt_position == "bottom" then
+ results.line = max_lines - height_padding
+ prompt.line = results.line + results.height + 2
+ preview.line = results.line
+ else
+ error("Unknown prompt_position: " .. self.window.prompt_position)
+ end
return {
preview = preview.width > 0 and preview,