|
|
|
@@ -4,9 +4,10 @@ local F = require("core.functions")
|
|
|
|
|
|
|
|
|
|
local M = {}
|
|
|
|
|
|
|
|
|
|
-- Buffer table structure:
|
|
|
|
|
-- Buffers, categorized into groups
|
|
|
|
|
-- {
|
|
|
|
|
-- "Group" = { "buffer1", "buffer2", active_index = 1 }
|
|
|
|
|
-- { group = "Project", buffers = { "buffer1", "buffer2" }, active_index = 1 },
|
|
|
|
|
-- { group = "Other", buffers = { "buffer3", "buffer4" }, active_index = 1 },
|
|
|
|
|
-- }
|
|
|
|
|
M.buffers = {}
|
|
|
|
|
|
|
|
|
@@ -42,19 +43,32 @@ M.add_buffer = function()
|
|
|
|
|
-- Add if buffer does not exist yet
|
|
|
|
|
local add = function(config_group)
|
|
|
|
|
local group = eval_group(config_group)
|
|
|
|
|
if not M.buffers[group] then M.buffers[group] = {} end
|
|
|
|
|
for i, buffer in ipairs(M.buffers[group]) do
|
|
|
|
|
|
|
|
|
|
local index
|
|
|
|
|
for i, buffer_group in ipairs(M.buffers) do
|
|
|
|
|
if buffer_group.group == group then index = i end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Group is new entirely, so we only have 1 buffer
|
|
|
|
|
if not index then
|
|
|
|
|
table.insert(M.buffers, { group = group, buffers = { buffer_name }, active_index = 1 })
|
|
|
|
|
return #M.buffers, 1 -- group index, buffer index
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Buffer previously added, set active
|
|
|
|
|
for i, buffer in ipairs(M.buffers[index].buffers) do
|
|
|
|
|
if buffer == buffer_name then
|
|
|
|
|
M.buffers[group]["active_index"] = i
|
|
|
|
|
return group, i
|
|
|
|
|
M.buffers[index].active_index = i
|
|
|
|
|
return index, i -- group index, buffer index
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
table.insert(M.buffers[group], buffer_name)
|
|
|
|
|
local count = #M.buffers[group]
|
|
|
|
|
M.buffers[group]["active_index"] = count
|
|
|
|
|
-- Buffer is new, add it to the list
|
|
|
|
|
table.insert(M.buffers[index].buffers, buffer_name)
|
|
|
|
|
local count = #M.buffers[index].buffers
|
|
|
|
|
M.buffers[index].active_index = count
|
|
|
|
|
|
|
|
|
|
return group, count
|
|
|
|
|
return index, count -- group index, buffer index
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Walk matcher configuration
|
|
|
|
@@ -82,34 +96,74 @@ M.add_buffer = function()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local get_group_from_buffer = function(buffer_name)
|
|
|
|
|
for group, buffers in pairs(M.buffers) do
|
|
|
|
|
for i, buffer in ipairs(buffers) do
|
|
|
|
|
if buffer == buffer_name then return group, i end
|
|
|
|
|
for i, buffer_group in ipairs(M.buffers) do
|
|
|
|
|
for j, buffer in ipairs(buffer_group.buffers) do
|
|
|
|
|
if buffer == buffer_name then
|
|
|
|
|
return i, j -- group index, buffer index
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local focus_buffer = function(new_buffer_name)
|
|
|
|
|
for _, buffer in ipairs(vim.api.nvim_list_bufs()) do
|
|
|
|
|
if vim.api.nvim_buf_get_name(buffer) == new_buffer_name then
|
|
|
|
|
vim.api.nvim_set_current_buf(buffer)
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
M.remove_buffer = function(buffer_name)
|
|
|
|
|
if not buffer_name or buffer_name == "" then return end
|
|
|
|
|
|
|
|
|
|
local group_index, buffer_index = get_group_from_buffer(buffer_name)
|
|
|
|
|
if not group_index or not buffer_index then return end
|
|
|
|
|
|
|
|
|
|
local buffer_group = M.buffers[group_index]
|
|
|
|
|
|
|
|
|
|
-- Remove the buffer and decrease active index
|
|
|
|
|
table.remove(buffer_group.buffers, buffer_index)
|
|
|
|
|
buffer_group.active_index = math.max(buffer_group.active_index - 1, 1)
|
|
|
|
|
local new_buffer_name = buffer_group.buffers[buffer_group.active_index]
|
|
|
|
|
|
|
|
|
|
-- If there are now no buffers in the group, delete the group
|
|
|
|
|
if #buffer_group.buffers == 0 then
|
|
|
|
|
table.remove(M.buffers, group_index)
|
|
|
|
|
if #M.buffers == 0 then return end
|
|
|
|
|
if #M.buffers < group_index then group_index = group_index - 1 end
|
|
|
|
|
new_buffer_name = M.buffers[group_index].buffers[M.buffers[group_index].active_index]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Make the new index the active buffer
|
|
|
|
|
focus_buffer(new_buffer_name)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local buffer_action_in_active_group = function(action, direction)
|
|
|
|
|
local buffer_name = get_buffer_name()
|
|
|
|
|
if not buffer_name then return end
|
|
|
|
|
|
|
|
|
|
local group, index = get_group_from_buffer(buffer_name)
|
|
|
|
|
if not group then group, index = M.add_buffer() end
|
|
|
|
|
-- Get active group from the current buffer
|
|
|
|
|
local group_index, buffer_index = get_group_from_buffer(buffer_name)
|
|
|
|
|
if not group_index then group_index, buffer_index = M.add_buffer() end
|
|
|
|
|
|
|
|
|
|
local buffers = M.buffers[group]
|
|
|
|
|
-- Get buffer set
|
|
|
|
|
local buffers = M.buffers[group_index].buffers
|
|
|
|
|
if #buffers < 2 then return end
|
|
|
|
|
|
|
|
|
|
-- Determine the other index
|
|
|
|
|
local other_index = index + direction
|
|
|
|
|
if index == 1 and direction == -1 then
|
|
|
|
|
local other_index = buffer_index + direction
|
|
|
|
|
if buffer_index == 1 and direction == -1 then
|
|
|
|
|
other_index = #buffers
|
|
|
|
|
elseif index == #buffers and direction == 1 then
|
|
|
|
|
elseif buffer_index == #buffers and direction == 1 then
|
|
|
|
|
other_index = 1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if action == "move" then
|
|
|
|
|
for _, buffer in ipairs(vim.api.nvim_list_bufs()) do
|
|
|
|
|
-- TODO: Probably not needed if the other autocommands are implemented
|
|
|
|
|
-- Remove inactive buffers
|
|
|
|
|
if not vim.api.nvim_buf_is_loaded(buffer) then
|
|
|
|
|
for i, group_buffer in ipairs(buffers) do
|
|
|
|
@@ -127,7 +181,7 @@ local buffer_action_in_active_group = function(action, direction)
|
|
|
|
|
-- Make buffer active
|
|
|
|
|
if vim.api.nvim_buf_get_name(buffer) == buffers[other_index] then
|
|
|
|
|
vim.api.nvim_set_current_buf(buffer)
|
|
|
|
|
buffers.active_index = other_index
|
|
|
|
|
M.buffers[group_index].active_index = other_index
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -135,11 +189,11 @@ local buffer_action_in_active_group = function(action, direction)
|
|
|
|
|
end
|
|
|
|
|
elseif action == "swap" then
|
|
|
|
|
local tmp = buffers[other_index]
|
|
|
|
|
buffers[other_index] = buffers[index]
|
|
|
|
|
buffers[index] = tmp
|
|
|
|
|
buffers[other_index] = buffers[buffer_index]
|
|
|
|
|
buffers[buffer_index] = tmp
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
M.buffers[group] = buffers
|
|
|
|
|
M.buffers[group_index].buffers = buffers
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
M.buffer_move_left = function()
|
|
|
|
@@ -165,13 +219,28 @@ local buffer_group_move = function(direction)
|
|
|
|
|
local buffer_name = get_buffer_name()
|
|
|
|
|
if not buffer_name then return end
|
|
|
|
|
|
|
|
|
|
-- TODO: How to get groups deterministically?
|
|
|
|
|
|
|
|
|
|
-- Get active group from the current buffer
|
|
|
|
|
local group_index, _ = get_group_from_buffer(buffer_name)
|
|
|
|
|
if not group_index then group_index, _ = M.add_buffer() end
|
|
|
|
|
|
|
|
|
|
-- Check groups bounds
|
|
|
|
|
if #M.buffers < 2 then return end
|
|
|
|
|
|
|
|
|
|
-- Change active group
|
|
|
|
|
-- Determine the other index
|
|
|
|
|
local other_index = group_index + direction
|
|
|
|
|
if group_index == 1 and direction == -1 then
|
|
|
|
|
other_index = #M.buffers
|
|
|
|
|
elseif group_index == #M.buffers and direction == 1 then
|
|
|
|
|
other_index = 1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Get active index from other group
|
|
|
|
|
local other_active_index = M.buffers[other_index].active_index
|
|
|
|
|
|
|
|
|
|
-- Make buffer active
|
|
|
|
|
-- TODO: What do if this buffer no longer exists?
|
|
|
|
|
local other_buffer = M.buffers[other_index].buffers[other_active_index]
|
|
|
|
|
focus_buffer(other_buffer)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
M.buffer_group_move_up = function()
|
|
|
|
@@ -182,32 +251,97 @@ M.buffer_group_move_down = function()
|
|
|
|
|
buffer_group_move(1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- TODO: functions that can
|
|
|
|
|
-- v Navigate buffer left
|
|
|
|
|
-- v Navigate buffer right
|
|
|
|
|
-- - Navigate group up (use active_index when swapping)
|
|
|
|
|
-- - Navigate group down
|
|
|
|
|
-- v Move buffer left
|
|
|
|
|
-- v Move buffer right
|
|
|
|
|
-- - Remove buffer from currently active group (decrease active_index)
|
|
|
|
|
--------------------------------------------
|
|
|
|
|
-- Telescope functionss
|
|
|
|
|
|
|
|
|
|
local pick = function(title, items, entry_maker, action)
|
|
|
|
|
local actions = require("telescope.actions")
|
|
|
|
|
local action_state = require("telescope.actions.state")
|
|
|
|
|
local conf = require("telescope.config").values
|
|
|
|
|
local finders = require("telescope.finders")
|
|
|
|
|
local pickers = require("telescope.pickers")
|
|
|
|
|
|
|
|
|
|
pickers.new({}, {
|
|
|
|
|
prompt_title = title,
|
|
|
|
|
finder = finders.new_table {
|
|
|
|
|
results = items,
|
|
|
|
|
entry_maker = entry_maker,
|
|
|
|
|
},
|
|
|
|
|
previewer = false,
|
|
|
|
|
sorter = conf.generic_sorter({}),
|
|
|
|
|
attach_mappings = function(prompt_bufnr)
|
|
|
|
|
actions.select_default:replace(function()
|
|
|
|
|
actions.close(prompt_bufnr)
|
|
|
|
|
|
|
|
|
|
local selection = action_state.get_selected_entry()
|
|
|
|
|
action(selection)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
end,
|
|
|
|
|
}):find()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
M.buffer_pick_buffer = function()
|
|
|
|
|
local buffer_name = get_buffer_name()
|
|
|
|
|
if not buffer_name then return end
|
|
|
|
|
|
|
|
|
|
-- Get active group from the current buffer
|
|
|
|
|
local group_index, _ = get_group_from_buffer(buffer_name)
|
|
|
|
|
if not group_index then group_index, _ = M.add_buffer() end
|
|
|
|
|
|
|
|
|
|
-- Get all buffers from the active group
|
|
|
|
|
local buffers = {}
|
|
|
|
|
for i, buffer in ipairs(M.buffers[group_index].buffers) do
|
|
|
|
|
table.insert(buffers, { key = buffer, value = tostring(i) })
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
pick("Group buffers",
|
|
|
|
|
buffers,
|
|
|
|
|
function(buffer)
|
|
|
|
|
-- Only show last part of the path
|
|
|
|
|
local display = buffer.key:match("^.+/(.+)$") or buffer.key
|
|
|
|
|
return {
|
|
|
|
|
display = display, -- shown in the picker
|
|
|
|
|
ordinal = buffer.value, -- used for sorting/filtering
|
|
|
|
|
value = buffer.value, -- actual value
|
|
|
|
|
}
|
|
|
|
|
end,
|
|
|
|
|
function(selection)
|
|
|
|
|
local new_buffer_name = M.buffers[group_index].buffers[tonumber(selection.value)]
|
|
|
|
|
|
|
|
|
|
-- Make new buffer active
|
|
|
|
|
focus_buffer(new_buffer_name)
|
|
|
|
|
end
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
M.buffer_pick_group = function()
|
|
|
|
|
-- Get all groups
|
|
|
|
|
local groups = {}
|
|
|
|
|
for i, buffer_group in ipairs(M.buffers) do
|
|
|
|
|
table.insert(groups, { key = buffer_group.group, value = tostring(i) })
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
pick("Groups",
|
|
|
|
|
groups,
|
|
|
|
|
function(group)
|
|
|
|
|
-- Only show last part of the path
|
|
|
|
|
local display = group.key:match("^.+/(.+)$") or group.key
|
|
|
|
|
return {
|
|
|
|
|
display = display, -- shown in the picker
|
|
|
|
|
ordinal = group.value, -- used for sorting/filtering
|
|
|
|
|
value = group.value, -- actual value
|
|
|
|
|
}
|
|
|
|
|
end,
|
|
|
|
|
function(selection)
|
|
|
|
|
local buffer_group = M.buffers[tonumber(selection.value)]
|
|
|
|
|
local new_buffer_name = buffer_group.buffers[buffer_group.active_index]
|
|
|
|
|
|
|
|
|
|
-- Make new buffer active
|
|
|
|
|
focus_buffer(new_buffer_name)
|
|
|
|
|
end
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return M
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- (cond
|
|
|
|
|
-- ((string-equal "*" (substring (buffer-name) 0 1)) "Emacs")
|
|
|
|
|
-- ((or (memq major-mode '(magit-process-mode
|
|
|
|
|
-- magit-status-mode
|
|
|
|
|
-- magit-diff-mode
|
|
|
|
|
-- magit-log-mode
|
|
|
|
|
-- magit-file-mode
|
|
|
|
|
-- magit-blob-mode
|
|
|
|
|
-- magit-blame-mode))
|
|
|
|
|
-- (string= (buffer-name) "COMMIT_EDITMSG")) "Magit")
|
|
|
|
|
-- ((project-current) (dot/project-project-name))
|
|
|
|
|
-- ((memq major-mode '(org-mode
|
|
|
|
|
-- emacs-lisp-mode)) "Org Mode")
|
|
|
|
|
-- ((derived-mode-p 'dired-mode) "Dired")
|
|
|
|
|
-- ((derived-mode-p 'prog-mode
|
|
|
|
|
-- 'text-mode) "Editing")
|
|
|
|
|
-- (t "Other")))))
|
|
|
|
|