馃尡 tiny neovim plugin keeping your session safe
1if vim.g.loaded_session then
2 return
3end
4
5vim.g.loaded_session = true
6
7local session = {}
8
9---@private
10session.stdin = false
11
12function session.get_uri()
13 return string.gsub(vim.fn.getcwd(), '[^a-zA-Z0-9_.-]', function(s)
14 return '<' .. vim.fn.char2nr(s)
15 end)
16end
17
18---@param name? string
19function session.get_path(name)
20 local sessiondir = require('nivvie.config').get().session_dir
21 return vim.fs.joinpath(sessiondir, (name or session.get_uri()) .. '.vim')
22end
23
24---@param name? string
25function session.save(name)
26 local session_file = session.get_path(name)
27
28 local sessiondir = require('nivvie.config').get().session_dir
29 vim.fn.mkdir(sessiondir, 'p')
30
31 vim.api.nvim_cmd({
32 cmd = 'mksession',
33 bang = true,
34 args = { session_file },
35 }, {})
36end
37
38function session.clean()
39 vim.iter(ipairs(vim.api.nvim_list_bufs())):each(function(_, bufnr)
40 if vim.bo[bufnr].buftype ~= '' then
41 vim.api.nvim_buf_delete(bufnr, { force = true })
42 end
43 end)
44end
45
46---@param name? string
47function session.restore(name)
48 local path = session.get_path(name)
49 if vim.uv.fs_stat(path) then
50 vim.api.nvim_cmd({
51 cmd = 'source',
52 args = { path },
53 }, {})
54 vim.api.nvim_exec_autocmds('SessionLoadPost', {})
55 end
56end
57
58----
59
60function session.isemptysession()
61 if session.stdin then
62 return false
63 end
64
65 if vim.fn.argc() > 0 then
66 return false
67 end
68
69 local bufs = vim.api.nvim_list_bufs()
70 bufs = vim
71 .iter(bufs)
72 :filter(function(buf)
73 return vim.api.nvim_buf_is_valid(buf) and vim.bo[buf].buftype == ''
74 end)
75 :totable()
76
77 return #bufs == 0
78end
79
80--- only restore if necessary
81function session.autorestore()
82 if not require('nivvie.config').get().autorestore then
83 return
84 end
85
86 if not session.isemptysession() then
87 return
88 end
89
90 session.restore()
91end
92
93local group = vim.api.nvim_create_augroup('nivvie', { clear = true })
94
95vim.api.nvim_create_autocmd({ 'VimLeavePre' }, {
96 group = group,
97 callback = function()
98 if not require('nivvie.config').get().autosave then
99 return
100 end
101 session.clean()
102 session.save()
103 end,
104})
105
106vim.api.nvim_create_autocmd({ 'StdinReadPost' }, {
107 group = group,
108 callback = function()
109 session.stdin = true
110 end,
111})
112
113vim.schedule(function()
114 vim.api.nvim_create_user_command('Nivvie', function(args)
115 if args.fargs[1] == 'save' then
116 session.save(args.fargs[2])
117 return
118 elseif args.fargs[1] == 'restore' then
119 session.restore(args.fargs[2])
120 return
121 elseif args.fargs[1] == 'delete' then
122 local path = session.get_path(args.fargs[2])
123 if vim.uv.fs_stat(path) then
124 vim.uv.fs_unlink(path)
125 end
126 end
127 end, {
128 nargs = '+',
129 complete = function()
130 return {
131 'save',
132 'restore',
133 'delete',
134 }
135 end,
136 })
137end)
138
139----
140
141if vim.v.vim_did_enter > 0 then
142 vim.schedule(function()
143 session.autorestore()
144 end)
145 return
146end
147
148vim.api.nvim_create_autocmd({ 'VimEnter' }, {
149 group = group,
150 callback = function()
151 vim.schedule(function()
152 session.autorestore()
153 end)
154 end,
155})
156
157return