repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
neovim/lua/bugabinga/sessions.lua
Rawlocal map = require 'std.map'
local auto = require 'std.auto'
local table = require 'std.table'
local sessions = vim.fs.normalize( vim.fn.stdpath 'data' .. '/sessions' )
vim.fn.mkdir( sessions, 'p' )
local file_exists = function ( path )
local stat = vim.uv.fs_stat( path )
---@diagnostic disable-next-line: undefined-field
return stat ~= nil and stat.type ~= nil
end
local encode = function ( data )
vim.validate('data', data, 'string')
-- replace some chars in base64, that are not allowed in file names.
return vim.base64.encode( data ):gsub( '%+', '-' ):gsub( '%/', '.' ):gsub( '%=', '_' )
end
local decode = function ( data )
vim.validate('data', data, 'string')
return vim.base64.decode( data:gsub( '%-', '+' ):gsub( '%.', '/' ):gsub( '%_', '=' )
)
end
local to_session_path = function ( path )
local encoded = sessions .. '/' .. encode( path )
local session_save_path = vim.fs.normalize( encoded )
return session_save_path
end
local save_session_for_cwd = function ()
local cwd = vim.uv.cwd()
local session_save_path = to_session_path( cwd )
vim.cmd.mksession { session_save_path, bang = true }
end
local load_session = function ( session )
local session_path = vim.fs.normalize( sessions .. '/' .. session )
if file_exists( session_path ) then
vim.cmd.source { session_path }
else
vim.notify( 'No session `' .. session .. '` found!' )
end
end
local load_current_session = function ()
local cwd = vim.uv.cwd()
local session = encode( cwd )
load_session( session )
end
local load_any_session = function ()
local all_sessions = {}
for session, type in vim.fs.dir( sessions ) do
if type == 'file' then
table.insert( all_sessions, session )
end
end
table.sort( all_sessions, function ( a, b )
a = vim.fs.normalize( sessions .. '/' .. a )
b = vim.fs.normalize( sessions .. '/' .. b )
return vim.uv.fs_stat( a ).mtime.sec > vim.uv.fs_stat( b ).mtime.sec
end )
vim.ui.select(
all_sessions,
{
prompt = 'Select a session to load: ',
format_item = function ( encoded_session_path )
local session_name = vim.fs.basename( encoded_session_path )
session_name = decode( session_name )
session_name = vim.fn.fnamemodify( session_name, ':~' )
return ' ' .. session_name
end,
},
function ( session )
if session then load_session( session ) end
end )
end
map.normal {
description = 'Load for cwd, if available.',
category = 'session',
keys = '<leader>ss',
command = load_current_session,
}
map.normal {
description = 'Load any.',
category = 'session',
keys = '<leader>sa',
command = load_any_session,
}
auto 'save_session_on_exit' {
description = 'Save current session for cwd, when leaving vim',
events = 'VimLeavePre',
command = save_session_for_cwd,
}