Neovim: Finish buffer navigation, add keybinds

This commit is contained in:
Riyyi
2025-04-11 22:57:42 +02:00
parent a2148c1e19
commit 855732f3c1
8 changed files with 278 additions and 83 deletions
+9 -3
View File
@@ -42,12 +42,18 @@ vim.api.nvim_create_autocmd("User", {
end,
})
-- Create an autocommand for full window buffers
vim.api.nvim_create_autocmd("BufWinEnter", {
-- callback = require("core.buffers").add_buffer
callback = function()
-- Buffer tracking
require("core.buffers").add_buffer()
LOG(require("core.buffers").buffers)
end,
desc = "Track all full window buffers visited",
})
vim.api.nvim_create_autocmd({ "BufDelete", "BufWipeout" }, {
callback = function(opts)
-- Buffer tracking
require("core.buffers").remove_buffer(opts.match)
end,
desc = "Track all full window buffers killed",
})
+187 -53
View File
@@ -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")))))
+18
View File
@@ -0,0 +1,18 @@
local F = require("core.functions")
local create_command = function(name, command)
if not name or type(name) ~= "string" then return end
vim.api.nvim_create_user_command(name, function()
local cmd = type(command) == "function" and command() or command
F.execute_command(cmd)
end, {})
end
create_command("RunScript", "ls")
create_command("ScanScript", function()
local file_path = vim.fn.expand("%:p")
LOG(file_path)
return "ls"
end)
+5
View File
@@ -0,0 +1,5 @@
vim.filetype.add({
extension = {
flw = "lua",
},
})
+16
View File
@@ -1,5 +1,21 @@
local M = {}
M.execute_command = function(command)
if not command then return end
local job = require("plenary.job")
job:new({
command = command,
on_exit = function(j, _)
vim.schedule(function()
vim.api.nvim_echo({
{ table.concat(j:result(), "\n"), "Normal" }
}, false, {})
end)
end,
}):start()
end
M.is_buffer_a_file = function()
local buffer_name = vim.fn.bufname()