diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2025-04-10 00:20:28 -0600 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2025-04-10 00:20:28 -0600 |
commit | d2325e040e2a4c2ea9d0d8c57af57bc13f7aeae7 (patch) | |
tree | 42cdc551faf3b3abbeb998166f00f937747fa6b1 /lua/vim/userregs/impl | |
parent | b3b09ff479510abc51ffb88743bb353bcc15e165 (diff) | |
download | rneovim-userregs-main.tar.gz rneovim-userregs-main.tar.bz2 rneovim-userregs-main.zip |
"| - file contents register
" - visual selection register
" - timestamp register
" - uuid register
" - dirname register
Diffstat (limited to 'lua/vim/userregs/impl')
-rw-r--r-- | lua/vim/userregs/impl/basename.lua | 28 | ||||
-rw-r--r-- | lua/vim/userregs/impl/buffercontents.lua | 39 | ||||
-rw-r--r-- | lua/vim/userregs/impl/dirname.lua | 27 | ||||
-rw-r--r-- | lua/vim/userregs/impl/fileregister.lua | 73 | ||||
-rw-r--r-- | lua/vim/userregs/impl/timestamp.lua | 22 | ||||
-rw-r--r-- | lua/vim/userregs/impl/uuid_register.lua | 18 | ||||
-rw-r--r-- | lua/vim/userregs/impl/visualselection.lua | 51 |
7 files changed, 258 insertions, 0 deletions
diff --git a/lua/vim/userregs/impl/basename.lua b/lua/vim/userregs/impl/basename.lua new file mode 100644 index 0000000..a46a381 --- /dev/null +++ b/lua/vim/userregs/impl/basename.lua @@ -0,0 +1,28 @@ +--- Basename Register: returns the current filename without path and extension. +--- +--- This is similar to the "%" register (full filename), but returns only +--- the basename with one extension removed. Useful, for example, when referencing +--- Java class names based on the file name. +--- +--- This register is read-only and assigned to the character '$'. + +local userregs = require("vim.userregs") +local api = vim.api + +---@type table<string, fun(regname: string): any> +local handler = {} + +--- Return the current buffer's basename without extension. +--- Equivalent to `expand('%:t:r')` +function handler.put(regname) + return vim.fn.expand('%:t:r') +end + +-- Make this register read-only by omitting the yank handler. +handler.yank = nil + +-- Register this handler under the user register '$'. +userregs.register_handler('$', handler) + + +return {} diff --git a/lua/vim/userregs/impl/buffercontents.lua b/lua/vim/userregs/impl/buffercontents.lua new file mode 100644 index 0000000..016b4e5 --- /dev/null +++ b/lua/vim/userregs/impl/buffercontents.lua @@ -0,0 +1,39 @@ +local userregs = require("vim.userregs") + +-- Register name: "|" +-- This register represents the full contents of the current buffer. +-- Yank into it → saves the buffer. +-- Put from it → replaces the buffer contents. + +local regname = "|" + +--- Reads the full contents of the current buffer as a list of lines. +--- This is returned in the format expected by 'userregfunc'. +--- @return table a 'put' dictionary with `lines`, `type`, and `additional_data` +local function read_current_buffer() + local bufnr = vim.api.nvim_get_current_buf() + local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) + + return { + lines = lines, + type = "V", -- linewise register + additional_data = {}, + } +end + +--- Replaces the entire contents of the current buffer with the given content. +--- Used when yanking into the "|" register. +--- @param _ string -- register name (ignored here) +--- @param content table -- dictionary with `lines` from yankreg_T +local function write_current_buffer(_, content) + local bufnr = vim.api.nvim_get_current_buf() + + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, content.lines or {}) +end + +-- Register the "|" register with the userregs framework +userregs.register_handler(regname, { + put = function(_) return read_current_buffer() end, + yank = write_current_buffer, +}) + diff --git a/lua/vim/userregs/impl/dirname.lua b/lua/vim/userregs/impl/dirname.lua new file mode 100644 index 0000000..503601d --- /dev/null +++ b/lua/vim/userregs/impl/dirname.lua @@ -0,0 +1,27 @@ +--- Dirname Register: returns the direction for the filename. +--- +--- This is similar to the "%" register (full filename), but returns only +--- the the directory. +--- +--- This register is read-only and assigned to the character '<C-d>'. + +local userregs = require("vim.userregs") +local api = vim.api + +---@type table<string, fun(regname: string): any> +local handler = {} + +--- Return the current buffer's basename without extension. +--- Equivalent to `expand('%:t:r')` +function handler.put(regname) + return vim.fn.expand('%:p:h') .. '/' +end + +-- Make this register read-only by omitting the yank handler. +handler.yank = nil + +-- Register this handler under the user register '<C-d>'. +userregs.register_handler('\4', handler) + + +return {} 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 {} diff --git a/lua/vim/userregs/impl/timestamp.lua b/lua/vim/userregs/impl/timestamp.lua new file mode 100644 index 0000000..517dd43 --- /dev/null +++ b/lua/vim/userregs/impl/timestamp.lua @@ -0,0 +1,22 @@ +local userregs = require("vim.userregs") + +-- Get format from g:timestamp_register_format or use fallback +local function get_timestamp_format() + return vim.g.timestamp_register_format or "%Y-%m-%d %H:%M:%S" +end + +local function generate_timestamp() + local ok, result = pcall(os.date, get_timestamp_format()) + if not ok then + vim.notify("[userregs] Invalid timestamp format", vim.log.levels.WARN) + return os.date("%Y-%m-%d %H:%M:%S") + end + return result +end + +userregs.register_handler('\20', { + put = function() + return generate_timestamp() + end, + yank = nil, -- read-only +}) diff --git a/lua/vim/userregs/impl/uuid_register.lua b/lua/vim/userregs/impl/uuid_register.lua new file mode 100644 index 0000000..de45de1 --- /dev/null +++ b/lua/vim/userregs/impl/uuid_register.lua @@ -0,0 +1,18 @@ +local userregs = require("vim.userregs") + +local function generate_uuid() + local random = math.random + local template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx" + return string.gsub(template, "[xy]", function(c) + local v = (c == "x") and random(0, 0xf) or random(8, 0xb) + return string.format("%x", v) + end) +end + +userregs.register_handler("\21", { -- Ctrl+U + put = function() + return generate_uuid() + end, + yank = nil, -- read-only +}) + diff --git a/lua/vim/userregs/impl/visualselection.lua b/lua/vim/userregs/impl/visualselection.lua new file mode 100644 index 0000000..93cb370 --- /dev/null +++ b/lua/vim/userregs/impl/visualselection.lua @@ -0,0 +1,51 @@ +local userregs = require("vim.userregs") + +-- ASCII-safe register name +local regname = "\22" + +-- Return the contents of the last visual selection +local function read_last_visual() + local bufnr = vim.api.nvim_get_current_buf() + + local start_pos = vim.fn.getpos("'<") + local end_pos = vim.fn.getpos("'>") + + if not start_pos or not end_pos then + vim.notify("[userregs] No visual selection", vim.log.levels.WARN) + return { lines = {}, type = "V" } + end + + local start_lnum = start_pos[2] - 1 -- 0-indexed + local end_lnum = end_pos[2] -- end line is exclusive + + local lines = vim.api.nvim_buf_get_lines(bufnr, start_lnum, end_lnum, false) + return { + lines = lines, + type = "V", -- Assume linewise for now + additional_data = {}, + } +end + +-- Replace the last visual selection with new content +local function write_last_visual(_, content) + local bufnr = vim.api.nvim_get_current_buf() + + local start_pos = vim.fn.getpos("'<") + local end_pos = vim.fn.getpos("'>") + + if not start_pos or not end_pos then + vim.notify("[userregs] No visual selection to write into", vim.log.levels.ERROR) + return + end + + local start_lnum = start_pos[2] - 1 + local end_lnum = end_pos[2] + + -- Replace the range with the new content + vim.api.nvim_buf_set_lines(bufnr, start_lnum, end_lnum, false, content.lines or {}) +end + +userregs.register_handler(regname, { + put = function() return read_last_visual() end, + yank = write_last_visual, +}) |