Skip to content

Commit

Permalink
feat: add command :SosBufToggle to toggle buffers
Browse files Browse the repository at this point in the history
This command allows for ignoring individual buffers so that they do not
get autosaved. It accepts an optional `[bufname]` argument to specify a
buffer other than the current one. Deleting a buffer (e.g. `:bdelete`)
resets its ignored status. Ignore status is stored in the buffer
variable `b:sos_ignore`.

Also add dedicated API functions for this, as well as functions to
enable or disable the entire plugin. These can all be found in the
`require('sos')` module table.

Also do some refactoring/cleanup:

- Rename `lua/bufevents.lua` -> `lua/observer.lua`
- Remove `lua/plugin.lua` (require main module instead)
- Main module `require('sos')` is now the entry point (incl. when the
  plugin is sourced by nvim at startup) and also holds most of the
  plugin's state
- Make all config fields optional (in the class/type)
- Update `init.lua` to handle module reloading (UNFINISHED)
- Update `util.lua` with new utility functions and error handling
- Improve benchmark interface
  • Loading branch information
tmillr committed Sep 12, 2024
1 parent 0351264 commit 1530899
Show file tree
Hide file tree
Showing 17 changed files with 863 additions and 398 deletions.
56 changes: 56 additions & 0 deletions lua/sos/_test/action.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
local util = require 'sos._test.util'
local api = vim.api
local M = { buf = {} }

-- api.nvim_feedkeys(
-- api.nvim_replace_termcodes(':new<CR>', true, true, true),
-- 'L',
-- -- 'mtx',
-- false
-- )

function M.input(keys)
assert.equals('n', api.nvim_get_mode().mode, 'not in normal mode')
assert.is_false(api.nvim_get_mode().blocking)
api.nvim_feedkeys(
api.nvim_replace_termcodes(keys, true, true, true),
-- 'L',
'mtx',
false
)

util.await_schedule()
end

function M.cmd(cmd)
assert.equals('n', api.nvim_get_mode().mode, 'not in normal mode')
assert.is_false(api.nvim_get_mode().blocking)
M.input(':' .. cmd .. '<CR>')
assert.equals('n', api.nvim_get_mode().mode, 'not in normal mode')
assert.is_false(api.nvim_get_mode().blocking)
end

---NOTE: May change the current buffer!
function M.trigger_save(buf)
assert.equals('n', api.nvim_get_mode().mode, 'not in normal mode')
assert.is_false(api.nvim_get_mode().blocking)

if buf and buf ~= 0 and buf ~= api.nvim_get_current_buf() then
assert(api.nvim_buf_is_valid(buf), 'invalid buffer number: ' .. buf)
local ei = vim.o.ei
vim.o.ei = 'all'
api.nvim_set_current_buf(buf)
vim.o.ei = ei
end

M.cmd 'tabnew'
-- util.await_schedule()
end

function M.buf.modify()
assert.is_false(vim.bo.mod, 'buffer is modified prior to modification')
M.input 'ochanges<Esc>'
assert.is_true(vim.bo.mod, 'unable to modify buffer')
end

return M
38 changes: 38 additions & 0 deletions lua/sos/_test/assert.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
local api = vim.api
local M = {}

function M.all_bufs_saved()
assert.same(
{},
vim.fn.getbufinfo { bufmodified = 1 },
'all buffers should be saved, and none modified'
)
end

---@param buf number
function M.saved(buf)
vim.validate { buf = { buf, { 'number' }, false } }
local file = api.nvim_buf_get_name(buf)
assert.is_false(vim.bo[buf].mod, 'buffer is still modified')
assert.same(
api.nvim_buf_get_lines(file, 0, -1, true),
vim.fn.readfile(file),
"buffer wasn't saved"
)
end

---@param buf number
function M.unsaved(buf)
vim.validate { buf = { buf, { 'number' }, false } }
local file = api.nvim_buf_get_name(buf)
assert.is_true(vim.bo[buf].mod, "buffer shouldn't have been saved")
local ok, content = pcall(vim.fn.readfile, file)
if not ok then return end
assert.not_same(
api.nvim_buf_get_lines(file, 0, -1, true),
content,
"buffer shouldn't have been saved"
)
end

return M
47 changes: 30 additions & 17 deletions lua/sos/_test/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,31 @@

local M = {}
local api = vim.api
local uv = vim.loop
local uv = vim.uv or vim.loop
local sleep = uv.sleep
local co = coroutine
local tmpfiles

---@param schedwrap boolean
function M.coroutine_resumer(schedwrap)
local curr_co = co.running()

if schedwrap then
return vim.schedule_wrap(function(...) co.resume(curr_co, ...) end)
end

return function(...) co.resume(curr_co, ...) end
local function resume(...) assert(co.resume(curr_co, ...)) end
return schedwrap and vim.schedule_wrap(resume) or resume
end

---@return nil
function M.await_schedule()
local curr_co = co.running()

local timeout = M.set_timeout(
5000,
function()
co.resume(curr_co, false, 'timed out waiting for vim.schedule() callback')
assert(
co.resume(
curr_co,
false,
'timed out waiting for vim.schedule() callback'
)
)
end
)

Expand All @@ -39,6 +40,13 @@ function M.await_schedule()
assert(co.yield())
end

---Sleep/wait by yielding the current coroutine.
---@param ms integer
function M.wait(ms)
vim.defer_fn(M.coroutine_resumer(false), ms)
co.yield()
end

---@async
function M.setup_plugin(...)
-- require("sos").setup(nil, true)
Expand All @@ -47,6 +55,7 @@ function M.setup_plugin(...)
else
require('sos').setup { enabled = true }
end

M.await_vim_enter()
end

Expand Down Expand Up @@ -74,18 +83,20 @@ function M.bufwritemock(onwrite)
})
end

---@return integer bufnr
---@return string output
---@overload fun(nvim: table, file?: string): string
---@overload fun(file?: string): string
---@overload fun(nvim: table, file?: string)
---@overload fun(file?: string)
function M.silent_edit(...)
local external_nvim_or_api, file = M.nvim_recv_or_api(...)

return external_nvim_or_api.nvim_cmd({
local out = external_nvim_or_api.nvim_cmd({
cmd = 'edit',
args = { file },
magic = { file = false, bar = false },
mods = { silent = true },
}, { output = true })

return api.nvim_get_current_buf(), out
end

---@param keys string
Expand Down Expand Up @@ -363,7 +374,9 @@ function M.autocmd(autocmd, opts)

local timer = M.set_timeout(
1e4,
function() co.resume(co, false, 'timed out waiting for autocmd') end
function()
assert(co.resume(curr_co, false, 'timed out waiting for autocmd'))
end
)

local result = { co.yield() }
Expand All @@ -380,13 +393,13 @@ end
function M.await_vim_enter()
if vim.v.vim_did_enter == 1 or vim.v.vim_did_enter == true then return end
M.autocmd('VimEnter', { once = true }):await()
M.await_schedule()
M.wait(100)
end

---@param fn function
---@return number ns
function M.time_it_once(fn)
local hrtime = vim.loop.hrtime
local hrtime = uv.hrtime
local start = hrtime()
fn()
return hrtime() - start
Expand Down Expand Up @@ -427,7 +440,7 @@ end
---@param cb function
---@return unknown
function M.set_timeout(ms, cb)
local timer = vim.loop.new_timer()
local timer = uv.new_timer()

timer:start(ms, 0, function()
timer:stop()
Expand Down
1 change: 0 additions & 1 deletion lua/sos/autocmds.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
local M = {}
local commands = require 'sos.commands'
local impl = require 'sos.impl'
local api = vim.api
local augroup = 'sos-autosaver'
Expand Down
Loading

0 comments on commit 1530899

Please sign in to comment.