diff options
| author | TJ DeVries <devries.timothyj@gmail.com> | 2020-07-31 00:05:22 -0400 |
|---|---|---|
| committer | TJ DeVries <devries.timothyj@gmail.com> | 2020-07-31 00:05:22 -0400 |
| commit | fa0382d93e73b66e7ec769cec27b9fbb21020641 (patch) | |
| tree | 624d5dc3de80426956a1c46447f1f26443a87a64 /lua/telescope | |
| parent | ababfbfd88334ca6d94d5d0a8b6324dd6600d602 (diff) | |
Streamed some refactoring. More work to do
Diffstat (limited to 'lua/telescope')
| -rw-r--r-- | lua/telescope/finders.lua | 3 | ||||
| -rw-r--r-- | lua/telescope/mappings.lua | 61 | ||||
| -rw-r--r-- | lua/telescope/pickers.lua | 191 | ||||
| -rw-r--r-- | lua/telescope/previewers.lua | 5 | ||||
| -rw-r--r-- | lua/telescope/sorters.lua | 2 |
5 files changed, 160 insertions, 102 deletions
diff --git a/lua/telescope/finders.lua b/lua/telescope/finders.lua index 0b7e185..518dfc1 100644 --- a/lua/telescope/finders.lua +++ b/lua/telescope/finders.lua @@ -10,7 +10,8 @@ Finder.__call = function(t, ... ) return t:_find(...) end --- Create a new finder command --- ---@param fn_command function The function to call +---@param opts table Keys: +-- fn_command function The function to call function Finder:new(opts) opts = opts or {} diff --git a/lua/telescope/mappings.lua b/lua/telescope/mappings.lua index 3c6de18..a3704a6 100644 --- a/lua/telescope/mappings.lua +++ b/lua/telescope/mappings.lua @@ -1,12 +1,10 @@ -- TODO: Customize keymap local a = vim.api -local ns_telescope_selection = a.nvim_create_namespace('telescope_selection') local state = require('telescope.state') local mappings = {} local keymap = {} -local telescope_selections = {} mappings.set_keymap = function(prompt_bufnr, results_bufnr) local function default_mapper(map_key, table_key) @@ -31,31 +29,8 @@ mappings.set_keymap = function(prompt_bufnr, results_bufnr) default_mapper('<CR>', 'enter') end -local function update_current_selection(prompt_bufnr, results_bufnr, row) - local status = state.get_status(prompt_bufnr) - - a.nvim_buf_clear_namespace(results_bufnr, ns_telescope_selection, 0, -1) - a.nvim_buf_add_highlight( - results_bufnr, - ns_telescope_selection, - 'Error', - row, - 0, - -1 - ) - - telescope_selections[prompt_bufnr] = row - - if status.previewer then - vim.g.got_here = true - - status.previewer:preview( - status.preview_win, - status.preview_bufnr, - status.results_bufnr, - row - ) - end +local function update_current_selection(prompt_bufnr, change) + state.get_status(prompt_bufnr).picker:move_selection(change) end @@ -68,34 +43,16 @@ end -- TODO: Refactor this to use shared code. -- TODO: Move from top to bottom, etc. -- TODO: It seems like doing this brings us back to the beginning of the prompt, which is not great. -keymap["control-n"] = function(prompt_bufnr, results_bufnr) - if telescope_selections[prompt_bufnr] == nil then - telescope_selections[prompt_bufnr] = 0 - end - - local row = telescope_selections[prompt_bufnr] + 1 - update_current_selection(prompt_bufnr, results_bufnr, row) +keymap["control-n"] = function(prompt_bufnr, _) + update_current_selection(prompt_bufnr, 1) end -keymap["control-p"] = function(prompt_bufnr, results_bufnr) - if telescope_selections[prompt_bufnr] == nil then - telescope_selections[prompt_bufnr] = 0 - end - - local row = telescope_selections[prompt_bufnr] - 1 - update_current_selection(prompt_bufnr, results_bufnr, row) +keymap["control-p"] = function(prompt_bufnr, _) + update_current_selection(prompt_bufnr, -1) end keymap["enter"] = function(prompt_bufnr, results_bufnr) - local extmark = a.nvim_buf_get_extmarks( - results_bufnr, - ns_telescope_selection, - 0, - -1, - {} - ) - - local row = extmark[1][2] + local row = state.get_status(prompt_bufnr).picker:get_selection() if row == nil then print("Could not do anything...") return @@ -117,7 +74,9 @@ keymap["enter"] = function(prompt_bufnr, results_bufnr) local bufnr = vim.fn.bufnr(filename, true) a.nvim_set_current_buf(bufnr) a.nvim_buf_set_option(bufnr, 'buflisted', true) - a.nvim_win_set_cursor(0, {row, col}) + if row and col then + a.nvim_win_set_cursor(0, {row, col}) + end end end diff --git a/lua/telescope/pickers.lua b/lua/telescope/pickers.lua index f9f64df..5b4485d 100644 --- a/lua/telescope/pickers.lua +++ b/lua/telescope/pickers.lua @@ -10,8 +10,21 @@ local pickers = {} local Picker = {} Picker.__index = Picker + +local Sorter = require('telescope.sorters').Sorter +local Previewer = require('telescope.previewers').Previewer + +assert(Sorter) +assert(Previewer) + +---@class PickOpts +---@field filter Sorter +---@field maps table +---@field unseen string + +--- Create new picker +--- @param opts PickOpts function Picker:new(opts) - opts = opts or {} return setmetatable({ filter = opts.filter, previewer = opts.previewer, @@ -19,6 +32,56 @@ function Picker:new(opts) }, Picker) end +function Picker._get_window_options(max_columns, max_lines, prompt_title) + local preview = { + border = {}, + enter = false, + highlight = false + } + local results = { + border = {}, + enter = false, + } + local prompt = { + title = prompt_title, + border = {}, + enter = true + } + + local width_padding = 10 + if 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 + + results.height = 25 + results.minheight = results.height + prompt.height = 1 + prompt.minheight = prompt.height + + preview.height = results.height + prompt.height + 2 + preview.minheight = preview.height + + results.col = width_padding + prompt.col = width_padding + preview.col = results.col + results.width + 2 + + local height_padding = math.floor(0.95 * max_lines) + results.line = max_lines - height_padding + prompt.line = results.line + results.height + 2 + preview.line = results.line + + return { + preview = preview, + results = results, + prompt = prompt, + } +end function Picker:find(opts) opts = opts or {} @@ -29,64 +92,41 @@ function Picker:find(opts) local sorter = opts.sorter local prompt_string = opts.prompt + -- Create three windows: -- 1. Prompt window -- 2. Options window -- 3. Preview window - - local width = 100 - local col = 10 - local prompt_line = 50 - - local result_height = 25 - local prompt_height = 1 + local popup_opts = Picker._get_window_options(vim.o.columns, vim.o.lines, prompt_string) -- TODO: Add back the borders after fixing some stuff in popup.nvim - local results_win, results_opts = popup.create('', { - height = result_height, - minheight = result_height, - width = width, - line = prompt_line - 2 - result_height, - col = col, - border = {}, - enter = false, - }) + local results_win, results_opts = popup.create('', popup_opts.results) local results_bufnr = a.nvim_win_get_buf(results_win) - local preview_win, preview_opts = popup.create('', { - height = result_height + prompt_height + 2, - minheight = result_height + prompt_height + 2, - width = 100, - line = prompt_line - 2 - result_height, - col = col + width + 2, - border = {}, - enter = false, - highlight = false, - }) + local preview_win, preview_opts = popup.create('', popup_opts.preview) local preview_bufnr = a.nvim_win_get_buf(preview_win) -- TODO: For some reason, highlighting is kind of weird on these windows. -- It may actually be my colorscheme tho... a.nvim_win_set_option(preview_win, 'winhl', 'Normal:Normal') + a.nvim_win_set_option(preview_win, 'winblend', 1) -- TODO: We need to center this and make it prettier... - local prompt_win, prompt_opts = popup.create('', { - height = prompt_height, - width = width, - line = prompt_line, - col = col, - border = {}, - title = prompt_string - }) + local prompt_win, prompt_opts = popup.create('', popup_opts.prompt) local prompt_bufnr = a.nvim_win_get_buf(prompt_win) -- a.nvim_buf_set_option(prompt_bufnr, 'buftype', 'prompt') -- vim.fn.prompt_setprompt(prompt_bufnr, prompt_string) + -- First thing we want to do is set all the lines to blank. + local max_results = popup_opts.results.height + local initial_lines = {} + for _ = 1, max_results do table.insert(initial_lines, "") end + vim.api.nvim_buf_set_lines(results_bufnr, 0, max_results, false, initial_lines) + local on_lines = function(_, _, _, first_line, last_line) local prompt = vim.api.nvim_buf_get_lines(prompt_bufnr, first_line, last_line, false)[1] - vim.api.nvim_buf_set_lines(results_bufnr, 0, -1, false, {}) -- Create a closure that has all the data we need -- We pass a function called "newResult" to get_results @@ -94,13 +134,21 @@ function Picker:find(opts) -- picker then (if available) calls sorter -- and then appropriately places new result in the buffer. - local line_scores = {} + + -- Sorted table by scores. + -- Lowest score gets lowest index. + self.line_scores = {} -- TODO: We need to fix the sorting -- TODO: We should provide a simple fuzzy matcher in Lua for people -- TODO: We should get all the stuff on the bottom line directly, not floating around -- TODO: We need to handle huge lists in a good way, cause currently we'll just put too much stuff in the buffer -- TODO: Stop having things crash if we have an error. + + local replace_line = function(row, line) + vim.api.nvim_buf_set_lines(results_bufnr, row, row + 1, false, {line}) + end + finder(prompt, function(line) if sorter then local sort_score = sorter:score(prompt, line) @@ -110,24 +158,30 @@ function Picker:find(opts) -- { 7, 3, 1, 1 } -- 2 - for row, row_score in utils.reversed_ipairs(line_scores) do + for row, row_score in utils.reversed_ipairs(self.line_scores) do if row_score > sort_score then -- Insert line at row - vim.api.nvim_buf_set_lines(results_bufnr, row, row, false, { - string.format("%s // %s %s", line, sort_score, row) - }) + replace_line(max_results - row, line) -- Insert current score in the table - table.insert(line_scores, row + 1, sort_score) + table.insert(self.line_scores, row + 1, sort_score) -- All done :) return end + + -- Don't keep inserting stuff + if row > max_results then + return + end end -- Worst score so far, so add to end - vim.api.nvim_buf_set_lines(results_bufnr, -1, -1, false, {line}) - table.insert(line_scores, sort_score) + + -- example: 5 max results, 8 + local worst_line = max_results - #self.line_scores + replace_line(worst_line, line) + table.insert(self.line_scores, sort_score) else -- Just always append to the end of the buffer if this is all you got. vim.api.nvim_buf_set_lines(results_bufnr, -1, -1, false, {line}) @@ -159,6 +213,8 @@ function Picker:find(opts) vim.cmd( on_buf_leave) vim.cmd([[augroup END]]) + self.prompt_bufnr = prompt_bufnr + state.set_status(prompt_bufnr, { prompt_bufnr = prompt_bufnr, prompt_win = prompt_win, @@ -196,12 +252,12 @@ function Picker:close_windows(status) local preview_border_win = status.preview_border_win local function del_win(name, win_id, force) - local file = io.open("/home/tj/test.txt", "a") - file:write(string.format("Closing.... %s %s\n", name, win_id)) + -- local file = io.open("/home/tj/test.txt", "a") + -- file:write(string.format("Closing.... %s %s\n", name, win_id)) local ok = pcall(vim.api.nvim_win_close, win_id, force) - file:write(string.format("OK: %s\n", ok)) - file:write("...Done\n\n") - file:close() + -- file:write(string.format("OK: %s\n", ok)) + -- file:write("...Done\n\n") + -- file:close() end del_win("prompt_win", prompt_win, true) @@ -224,7 +280,44 @@ function Picker:close_windows(status) state.clear_status(status.prompt_bufnr) end +local ns_telescope_selection = a.nvim_create_namespace('telescope_selection') +function Picker:get_selection() + return self.selection or #(self.line_scores or {}) +end + +function Picker:move_selection(change) + self:set_selection(self:get_selection() + change) +end + +function Picker:set_selection(row) + local status = state.get_status(self.prompt_bufnr) + + a.nvim_buf_clear_namespace(status.results_bufnr, ns_telescope_selection, 0, -1) + a.nvim_buf_add_highlight( + status.results_bufnr, + ns_telescope_selection, + 'Error', + row, + 0, + -1 + ) + + -- TODO: Don't let you go over / under the buffer limits + -- TODO: Make sure you start exactly at the bottom selected + + -- TODO: Get row & text in the same obj + self.selection = row + + if self.previewer then + self.previewer:preview( + status.preview_win, + status.preview_bufnr, + status.results_bufnr, + row + ) + end +end pickers.new = function(...) return Picker:new(...) diff --git a/lua/telescope/previewers.lua b/lua/telescope/previewers.lua index ccbd7db..5b686b7 100644 --- a/lua/telescope/previewers.lua +++ b/lua/telescope/previewers.lua @@ -38,10 +38,13 @@ previewers.vim_buffer = previewers.new { vim.api.nvim_win_set_buf(preview_win, bufnr) vim.api.nvim_win_set_option(preview_win, 'wrap', false) vim.api.nvim_win_set_option(preview_win, 'winhl', 'Normal:Normal') - vim.api.nvim_win_set_option(preview_win, 'winblend', 20) + -- vim.api.nvim_win_set_option(preview_win, 'winblend', 20) vim.api.nvim_win_set_option(preview_win, 'signcolumn', 'no') vim.api.nvim_win_set_option(preview_win, 'foldlevel', 100) end, } + +previewers.Previewer = Previewer + return previewers diff --git a/lua/telescope/sorters.lua b/lua/telescope/sorters.lua index d5fb6f9..a648007 100644 --- a/lua/telescope/sorters.lua +++ b/lua/telescope/sorters.lua @@ -29,4 +29,6 @@ function sorters.new(...) return Sorter:new(...) end +sorters.Sorter = Sorter + return sorters |
