--- 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)