From 863328a96d81d4b93bcfaa0038d429ea24880b0b Mon Sep 17 00:00:00 2001 From: Simon Hauser Date: Mon, 23 Nov 2020 16:11:46 +0100 Subject: [PATCH] feat: Buffers rework (indicators and sorting) (#208) --- README.md | 17 ++++++------ lua/telescope/actions/init.lua | 10 ++++++- lua/telescope/builtin/init.lua | 32 +++++++++++++++++++---- lua/telescope/make_entry.lua | 48 +++++++++++++++++----------------- lua/telescope/pickers.lua | 27 ++++++++++++++----- lua/telescope/previewers.lua | 34 +++--------------------- 6 files changed, 93 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 178d770..c0dc221 100644 --- a/README.md +++ b/README.md @@ -478,14 +478,15 @@ This section is an overview of how custom pickers can be created any configured. ```lua -- lua/telescope/pickers.lua Picker:new{ - prompt_title = "", -- REQUIRED - finder = FUNCTION, -- see lua/telescope/finder.lua - sorter = FUNCTION, -- see lua/telescope/sorter.lua - previewer = FUNCTION, -- see lua/telescope/previewer.lua - selection_strategy = "reset", -- follow, reset, row - border = {}, - borderchars = {"─", "│", "─", "│", "┌", "┐", "┘", "└"}, - preview_cutoff = 120, + prompt_title = "", -- REQUIRED + finder = FUNCTION, -- see lua/telescope/finder.lua + sorter = FUNCTION, -- see lua/telescope/sorter.lua + previewer = FUNCTION, -- see lua/telescope/previewer.lua + selection_strategy = "reset", -- follow, reset, row + border = {}, + borderchars = {"─", "│", "─", "│", "┌", "┐", "┘", "└"}, + preview_cutoff = 120, + default_selection_index = 1, -- Change the index of the initial selection row } ``` diff --git a/lua/telescope/actions/init.lua b/lua/telescope/actions/init.lua index 9dabfcb..527e0b5 100644 --- a/lua/telescope/actions/init.lua +++ b/lua/telescope/actions/init.lua @@ -96,7 +96,15 @@ function actions._goto_file_selection(prompt_bufnr, command) actions.close(prompt_bufnr) if entry_bufnr then - vim.cmd(string.format(":%s #%d", command, entry_bufnr)) + if command == 'edit' then + vim.cmd(string.format(":buffer %d", entry_bufnr)) + elseif command == 'new' then + vim.cmd(string.format(":sbuffer %d", entry_bufnr)) + elseif command == 'vnew' then + vim.cmd(string.format(":vert sbuffer %d", entry_bufnr)) + elseif command == 'tabedit' then + vim.cmd(string.format(":tab sb %d", entry_bufnr)) + end else filename = path.normalize(filename, vim.fn.getcwd()) diff --git a/lua/telescope/builtin/init.lua b/lua/telescope/builtin/init.lua index f1a50b6..9853072 100644 --- a/lua/telescope/builtin/init.lua +++ b/lua/telescope/builtin/init.lua @@ -611,16 +611,38 @@ builtin.fd = builtin.find_files builtin.buffers = function(opts) opts = opts or {} - local buffers = filter(function(b) + local bufnrs = filter(function(b) return (opts.show_all_buffers or vim.api.nvim_buf_is_loaded(b)) and 1 == vim.fn.buflisted(b) - end, vim.api.nvim_list_bufs()) + local buffers = {} + local default_selection_idx = 1 + for _, bufnr in ipairs(bufnrs) do + local flag = bufnr == vim.fn.bufnr('') and '%' or (bufnr == vim.fn.bufnr('#') and '#' or ' ') + + if opts.sort_lastused and flag == "#" then + default_selection_idx = 2 + end + + local element = { + bufnr = bufnr, + flag = flag, + info = vim.fn.getbufinfo(bufnr)[1], + } + + if opts.sort_lastused and (flag == "#" or flag == "%") then + local idx = ((buffers[1] ~= nil and buffers[1].flag == "%") and 2 or 1) + table.insert(buffers, idx, element) + else + table.insert(buffers, element) + end + end + if not opts.bufnr_width then - local max_bufnr = math.max(unpack(buffers)) + local max_bufnr = math.max(unpack(bufnrs)) opts.bufnr_width = #tostring(max_bufnr) end @@ -630,9 +652,9 @@ builtin.buffers = function(opts) results = buffers, entry_maker = make_entry.gen_from_buffer(opts) }, - -- previewer = previewers.vim_buffer.new(opts), - previewer = previewers.vimgrep.new(opts), + previewer = previewers.vim_buffer.new(opts), sorter = conf.generic_sorter(opts), + default_selection_index = default_selection_idx, }):find() end diff --git a/lua/telescope/make_entry.lua b/lua/telescope/make_entry.lua index aa1d3db..fc8b569 100644 --- a/lua/telescope/make_entry.lua +++ b/lua/telescope/make_entry.lua @@ -283,19 +283,17 @@ end function make_entry.gen_from_buffer(opts) opts = opts or {} + local displayer = entry_display.create { + separator = " ", + items = { + { width = opts.bufnr_width }, + { width = 4 }, + { remaining = true }, + }, + } + local cwd = vim.fn.expand(opts.cwd or vim.fn.getcwd()) - local get_position = function(entry) - local tabpage_wins = vim.api.nvim_tabpage_list_wins(0) - for k, v in ipairs(tabpage_wins) do - if entry == vim.api.nvim_win_get_buf(v) then - return vim.api.nvim_win_get_cursor(v) - end - end - - return {} - end - local make_display = function(entry) local display_bufname if opts.shorten_path then @@ -304,33 +302,35 @@ function make_entry.gen_from_buffer(opts) display_bufname = entry.filename end - return string.format("%" .. opts.bufnr_width .. "d : %s", - entry.bufnr, display_bufname) + return displayer { + entry.bufnr, + entry.indicator, + display_bufname .. ":" .. entry.lnum, + } end return function(entry) - local bufnr_str = tostring(entry) - local bufname = path.normalize(vim.api.nvim_buf_get_name(entry), cwd) - + local bufname = entry.info.name ~= "" and entry.info.name or '[No Name]' -- if bufname is inside the cwd, trim that part of the string + bufname = path.normalize(bufname, cwd) - local position = get_position(entry) - - if '' == bufname then - return nil - end + local hidden = entry.info.hidden == 1 and 'h' or 'a' + local readonly = vim.api.nvim_buf_get_option(entry.bufnr, 'readonly') and '=' or ' ' + local changed = entry.info.changed == 1 and '+' or ' ' + local indicator = entry.flag .. hidden .. readonly .. changed return { valid = true, value = bufname, - ordinal = bufnr_str .. " : " .. bufname, + ordinal = entry.bufnr .. " : " .. bufname, display = make_display, - bufnr = entry, + bufnr = entry.bufnr, filename = bufname, - lnum = position[1] or 1, + lnum = entry.info.lnum or 1, + indicator = indicator, } end end diff --git a/lua/telescope/pickers.lua b/lua/telescope/pickers.lua index adc2dca..b066bd6 100644 --- a/lua/telescope/pickers.lua +++ b/lua/telescope/pickers.lua @@ -79,6 +79,7 @@ function Picker:new(opts) finder = opts.finder, sorter = opts.sorter, previewer = opts.previewer, + default_selection_index = opts.default_selection_index, _completion_callbacks = {}, @@ -470,18 +471,30 @@ function Picker:find() -- TODO: We should either: always leave one result or make sure we actually clean up the results when nothing matches if selection_strategy == 'row' then - self:set_selection(self:get_selection_row()) + if self._selection_row == nil and self.default_selection_index ~= nil then + self:set_selection(self:get_row(self.default_selection_index)) + else + self:set_selection(self:get_selection_row()) + end elseif selection_strategy == 'follow' then - local index = self.manager:find_entry(self:get_selection()) + if self._selection_row == nil and self.default_selection_index ~= nil then + self:set_selection(self:get_row(self.default_selection_index)) + else + local index = self.manager:find_entry(self:get_selection()) - if index then - local follow_row = self:get_row(index) - self:set_selection(follow_row) + if index then + local follow_row = self:get_row(index) + self:set_selection(follow_row) + else + self:set_selection(self:get_reset_row()) + end + end + elseif selection_strategy == 'reset' then + if self.default_selection_index ~= nil then + self:set_selection(self:get_row(self.default_selection_index)) else self:set_selection(self:get_reset_row()) end - elseif selection_strategy == 'reset' then - self:set_selection(self:get_reset_row()) else error('Unknown selection strategy: ' .. selection_strategy) end diff --git a/lua/telescope/previewers.lua b/lua/telescope/previewers.lua index 01d8793..ee98f1c 100644 --- a/lua/telescope/previewers.lua +++ b/lua/telescope/previewers.lua @@ -356,53 +356,27 @@ previewers.vim_buffer = defaulter(function(_) end, preview_fn = function(self, entry, status) - -- TODO: Consider using path here? Might not work otherwise. - local filename = entry.filename + local bufnr = tonumber(entry.bufnr) - if filename == nil then - filename = entry.path - end - - if filename == nil then - local value = entry.value - filename = vim.split(value, ":")[1] - end - - if filename == nil then - return - end - - log.info("Previewing File:", filename) - - local bufnr = vim.fn.bufnr(filename) - if bufnr == -1 then - -- TODO: Is this the best way to load the buffer?... I'm not sure tbh - bufnr = vim.fn.bufadd(filename) + if not vim.api.nvim_buf_is_loaded(bufnr) then vim.fn.bufload(bufnr) - - vim.cmd([[doautocmd filetypedetect BufRead ]] .. filename) end self.state.last_set_bufnr = bufnr - -- TODO: We should probably call something like this because we're not always getting highlight and all that stuff. - -- api.nvim_command('doautocmd filetypedetect BufRead ' .. vim.fn.fnameescape(filename)) vim.api.nvim_win_set_buf(status.preview_win, bufnr) vim.api.nvim_win_set_option(status.preview_win, 'wrap', false) vim.api.nvim_win_set_option(status.preview_win, 'winhl', 'Normal:Normal') - -- vim.api.nvim_win_set_option(preview_win, 'winblend', 20) vim.api.nvim_win_set_option(status.preview_win, 'signcolumn', 'no') vim.api.nvim_win_set_option(status.preview_win, 'foldlevel', 100) - if entry.lnum then vim.api.nvim_buf_add_highlight(bufnr, previewer_ns, "Visual", entry.lnum - 1, 0, -1) - vim.api.nvim_win_set_option(status.preview_win, 'scrolloff', 10) + vim.api.nvim_win_set_option(status.preview_win, 'scrolloff', 999) vim.api.nvim_win_set_cursor(status.preview_win, {entry.lnum, 0}) -- print("LNUM:", entry.lnum) end - vim.api.nvim_win_set_option(status.preview_win, 'scrolloff', 999) - log.info("Previewed bufnr", bufnr) + self.state.hl_win = status.preview_win end, } end, {})