Skip to content

Commit

Permalink
WIP: Buffers rework, show indicator in table view and default selection
Browse files Browse the repository at this point in the history
  • Loading branch information
Conni2461 committed Oct 31, 2020
1 parent 37c4f1b commit fbe13e5
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 44 deletions.
42 changes: 33 additions & 9 deletions lua/telescope/builtin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -581,17 +581,40 @@ builtin.fd = builtin.find_files
builtin.buffers = function(opts)
opts = opts or {}

local buffers = filter(function(b)
return
(opts.show_all_buffers
or vim.api.nvim_buf_is_loaded(b))
and 1 == vim.fn.buflisted(b)
local buffers_list = vim.split(vim.fn.execute('buffers'), "\n")

local buffers = {}
local last_used_buffernr
opts.bufnr_width = 0
for i = 2, #buffers_list do
-- Currently we don't get buffername over the buffers command, this is because :buffers shows
-- me the fullfilepath, like this '~/.config/nvim/plugged/lua/telescope/builtin.lua'.
-- This is not really useful for us.
-- TODO(conni2461): Thats wrong, what about readonly buffers
local bufnr, indicator, lnum = string.match(
buffers_list[i], '(%d+)%s*([%%# ]?[ah ]?[-=RF? ]?[+x ]?).*line (%d+)'
)

if indicator:sub(1, 1) == "#" then
last_used_buffernr = bufnr
end

if not opts.show_all_buffers and not vim.api.nvim_buf_is_loaded(tonumber(bufnr)) then
goto continue
end

end, vim.api.nvim_list_bufs())
table.insert(buffers, {
bufnr = bufnr,
indicator = indicator,
lnum = lnum,
})

-- Determine the max_width for bufnr
if opts.bufnr_width < #bufnr then
opts.bufnr_width = #bufnr
end

if not opts.bufnr_width then
local max_bufnr = math.max(unpack(buffers))
opts.bufnr_width = #tostring(max_bufnr)
::continue::
end

pickers.new(opts, {
Expand All @@ -603,6 +626,7 @@ builtin.buffers = function(opts)
-- previewer = previewers.vim_buffer.new(opts),
previewer = previewers.vimgrep.new(opts),
sorter = conf.generic_sorter(opts),
default_selection = last_used_buffernr,
}):find()
end

Expand Down
19 changes: 18 additions & 1 deletion lua/telescope/entry_manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,23 @@ function EntryManager:new(max_results, set_entry, info)
return nil
end,

find_ordinal_starts_with_str = function(_, str)
if str == nil then
return nil
end

for k, v in ipairs(entry_state) do
local existing_entry = v.entry.ordinal:sub(1, #str)

-- FIXME: This has the problem of assuming that display will not be the same for two different entries.
if existing_entry == str then
return k
end
end

return nil
end,

_get_state = function()
return entry_state
end,
Expand Down Expand Up @@ -110,7 +127,7 @@ function EntryManager:insert(picker, index, entry)
-- and then shift all the corresponding items one place.
local next_entry, last_score
repeat
self.info.inserted = self.info.inserted + 1
self.info.inserted = self.info.inserted + 1
next_entry = self.entry_state[index]

self.set_entry(picker, index, entry.entry, entry.score)
Expand Down
34 changes: 12 additions & 22 deletions lua/telescope/make_entry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ do
end

local execute_keys = {
path = function(t)
path = function(t)
return t.cwd .. path.separator .. t.filename, false
end,

Expand Down Expand Up @@ -262,17 +262,6 @@ function make_entry.gen_from_buffer(opts)

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
Expand All @@ -281,17 +270,17 @@ 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 utils.table_format({
[1] = {entry.bufnr, opts.bufnr_width},
[2] = {entry.indicator, 4},
[3] = {display_bufname, 0},
[4] = {entry.lnum, 0},
}, { " ", " ", ":" })
end

return function(entry)
local bufnr_str = tostring(entry)
local bufname = path.normalize(vim.api.nvim_buf_get_name(entry), cwd)

-- if bufname is inside the cwd, trim that part of the string

local position = get_position(entry)
local bufname = path.normalize(vim.api.nvim_buf_get_name(entry.bufnr), cwd)

if '' == bufname then
return nil
Expand All @@ -301,13 +290,14 @@ function make_entry.gen_from_buffer(opts)
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.lnum or 1,
indicator = entry.indicator,
}
end
end
Expand Down
30 changes: 18 additions & 12 deletions lua/telescope/pickers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function Picker:new(opts)
finder = opts.finder,
sorter = opts.sorter,
previewer = opts.previewer,
default_selection = opts.default_selection,

_completion_callbacks = {},

Expand Down Expand Up @@ -452,21 +453,26 @@ function Picker:find()

local process_complete = function()
-- 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())
elseif selection_strategy == 'follow' then
local index = self.manager:find_entry(self:get_selection())

if index then
local follow_row = self:get_row(index)
self:set_selection(follow_row)
else
if self.default_selection == nil then
if selection_strategy == 'row' then
self:set_selection(self:get_selection_row())
elseif selection_strategy == 'follow' then
local index = self.manager:find_entry(self:get_selection())

if index then
local follow_row = self:get_row(index)
self:set_selection(follow_row)
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
elseif selection_strategy == 'reset' then
self:set_selection(self:get_reset_row())
else
error('Unknown selection strategy: ' .. selection_strategy)
local idx = self.manager:find_ordinal_starts_with_str(self.default_selection) - 1
self:set_selection(self:get_reset_row() - idx)
end

self:clear_extra_rows(results_bufnr)
Expand Down
27 changes: 27 additions & 0 deletions lua/telescope/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,31 @@ function utils.max_split(s, pattern, maxsplit)
return t
end

-- index are used to determine the correct order
-- elements = {
-- [1] = { element, max width }, -- max width should be greater than 0
-- [2] = { a, 0 } -- Use 0 to disable max width
-- [3] = { b, 0 } -- If b is nil, skip this column, should skip column for all rows
-- },
-- separator = " " -- either arbitrary string, when you wanna use the same separator between all elements
-- separator = { " ", ":" } -- or table, where [1] is separator between elements[1] and elements[2], etc
function utils.table_format(elements, separator)
local output = ""
for k, v in ipairs(elements) do
local text = v[1]
local width = v[2]
if text ~= nil then
if k > 1 then
output = output .. (type(separator) == "table" and separator[k - 1] or separator)
end
if width == 0 then
output = output .. string.format("%s", text)
else
output = output .. string.format("%" .. width .."s", text)
end
end
end
return output
end

return utils

0 comments on commit fbe13e5

Please sign in to comment.