aboutsummaryrefslogtreecommitdiff
path: root/lua/extregs/init.lua
blob: b9dcbe11440c10e5fae1baf9155939467db603a3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
local M = {}

M.defaults = {
  file = { path = (vim.env.XDG_RUNTIME_DIR or vim.fn.stdpath('state')) .. '/nvim.regfile' },
  ssh = { host = nil, path = '~/.local/state/nvim/regfile' },
  osc52 = { register = '+' },
  tmux = { buffer = nil },
  timestamp = { format = '%Y-%m-%dT%H:%M:%S%z' },
}

-- name, module, configuration section; registration semantics are (write, read).
local providers = {
  { 'osc52', 'osc52', 'osc52' },
  { 'tmux', 'tmux', 'tmux' },
  { 'buffer', 'buffer' },
  { 'file.basename', 'file_basename' },
  { 'file.stem', 'file_stem' },
  { 'file.dirname', 'file_dirname' },
  { 'file.backed', 'file', 'file' },
  { 'ssh.backed', 'ssh', 'ssh' },
  { 'timestamp', 'timestamp', 'timestamp' },
  { 'uuid', 'uuid' },
}

local function notify(msg, level)
  vim.schedule(function()
    vim.notify('extregs.nvim: ' .. msg, level or vim.log.levels.ERROR)
  end)
end

local function guard(name, fn)
  return function(...)
    local ok, result = pcall(fn, ...)
    if not ok then
      notify(name .. ': ' .. tostring(result))
      return false
    end
    return result
  end
end

local function register(name, provider)
  assert(type(provider.read) == 'function', name .. ': missing read()')
  assert(type(provider.write) == 'function', name .. ': missing write()')
  vim._extregs.register(name,
    guard(name, function(reg)
      if provider.readonly then
        notify(name .. ' is read-only', vim.log.levels.WARN)
        return false
      end
      return provider:write(reg)
    end),
    guard(name, function() return provider:read() end))
end

function M.setup(opts)
  if vim.fn.has('extregs') ~= 1 or not (vim._extregs and vim._extregs.register) then
    notify("requires a Neovim build with has('extregs') and vim._extregs.register")
    return false
  end
  if M._initialized then return true end
  local cfg = vim.tbl_deep_extend('force', vim.deepcopy(M.defaults), opts or {})
  for _, spec in ipairs(providers) do
    local name, module, section = unpack(spec)
    local provider = require('extregs.' .. module).get_provider(cfg[section] or {})
    register(name, provider)
  end
  M._initialized = true
  return true
end

return M