diff options
Diffstat (limited to 'lua/vim/userregs/impl/fileregister.lua')
-rw-r--r-- | lua/vim/userregs/impl/fileregister.lua | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/lua/vim/userregs/impl/fileregister.lua b/lua/vim/userregs/impl/fileregister.lua new file mode 100644 index 0000000..0ec1715 --- /dev/null +++ b/lua/vim/userregs/impl/fileregister.lua @@ -0,0 +1,73 @@ +--- Fileregister: maps the '&' register to an external file. +--- +--- This register reads from or writes to a file defined by `g:fileregister_filename` +--- or defaults to `${RUN_DIRECTORY}/fileregister`. +--- +--- On yank, the content is saved as JSON. +--- On put, the content is decoded from JSON (if valid) or interpreted as raw lines. + +local userregs = require("vim.userregs") +local api = vim.api + +local handler = {} + +--- Get the filename used for this register. +--- Defaults to /tmp/.vim.$USER.fileregister +---@return string +local function get_file_name() + return vim.g.fileregister_filename + or (vim.fn.stdpath("run") .. "/fileregister") +end + +--- Write the yanked content into the fileregister as JSON. +---@param _ string register name (ignored) +---@param content table content from 'userregfunc' +function handler.yank(_, content) + local filename = get_file_name() + local ok, encoded = pcall(vim.json.encode, content) + if not ok then + vim.notify("[fileregister] Failed to encode content to JSON", vim.log.levels.ERROR) + return + end + + local f = io.open(filename, "w") + if not f then + vim.notify("[fileregister] Could not open file for writing: " .. filename, vim.log.levels.ERROR) + return + end + + f:write(encoded) + f:close() +end + +--- Read from the file. If it's valid JSON, decode as register content. +--- Otherwise, interpret it as a list of lines. +---@param _ string register name (ignored) +---@return table|string +function handler.put(_) + local filename = get_file_name() + local f = io.open(filename, "r") + + if not f then + return {} + end + + local content = f:read("*a") + f:close() + + if content:sub(1, 1) == "{" then + local ok, decoded = pcall(vim.json.decode, content) + if ok then return decoded end + end + + local lines = {} + for line in content:gmatch("[^\r\n]+") do + table.insert(lines, line) + end + return lines +end + +-- Register the '&' fileregister +userregs.register_handler('&', handler) + +return {} |