diff options
-rw-r--r-- | plugin/basename.lua | 34 | ||||
-rw-r--r-- | plugin/fileregister.lua | 98 | ||||
-rw-r--r-- | plugin/mark.lua | 75 |
3 files changed, 73 insertions, 134 deletions
diff --git a/plugin/basename.lua b/plugin/basename.lua index 8b875d1..84d2991 100644 --- a/plugin/basename.lua +++ b/plugin/basename.lua @@ -1,24 +1,26 @@ --- Implementation of the basename register. --- --- The basename register is like the filename register ("%), but instead of --- returning the whole filename, it will return just the basename with one --- extension removed. --- --- Useful for Java when needing to reference the class. --- --- This register is assigned to the character '$' +--- 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 userreg = require("vim.userreg") +local userregs = require("vim.userregs") local api = vim.api +---@type table<string, fun(regname: string): any> local handler = {} -function handler.do_yank(self, content) - return -1 -- Read-only register. -end - -function handler.do_put() +--- Return the current buffer's basename without extension. +--- Equivalent to `expand('%:t:r')` +function handler.put(regname) return vim.fn.expand('%:t:r') end -userreg.register_handler('$', handler) +-- Make this register read-only by omitting the yank handler. +handler.yank = nil + +-- Register this handler under the user register '$'. +userregs.register_handler('$', handler) + diff --git a/plugin/fileregister.lua b/plugin/fileregister.lua index 856149a..08bdc5a 100644 --- a/plugin/fileregister.lua +++ b/plugin/fileregister.lua @@ -1,59 +1,71 @@ --- Implementation for the "fileregister" ("&). The fileregister is a user --- register that reads the register data from a specific file --- (g:fileregister_filename). --- --- If the data is encoded in JSON, it is read as 'content' (see :help urf), --- otherwise the file is interpreted as lines (useful when writing to the file --- from an external program). --- --- requires 'json-lua' - -local userreg = require("vim.userreg") +--- 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 = {} --- Retruns the filename to read/write to. Defaults to --- /tmp/.vim.$USER.fileregister, but uses g:fileregister_filename if set. -function handler.get_file_name() - return vim.g.fileregister_filename or - '/tmp/.vim.' .. os.getenv("USER") .. ".fileregister" +--- 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 --- Stores the yanked text into the fileregister as JSON. -function handler.do_yank(self, content) - local json = require('JSON') - local file = self.get_file_name(); - string = json:encode(content) +--- 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 - file = io.open(file, "w") - file:write(string) - file:close() -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 --- Reads the text from the file register and returns it. -function handler.do_put(self) - local file = self.get_file_name(); - local json = require('JSON') + f:write(encoded) + f:close() +end - file = io.open(file, "r") +--- 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 file then + if not f then return {} end - content = file:read "*a" - file:close(); - - if content:sub(1, 1) == '{' then - return json:decode(content) - else - ret = {} - for s in content:gmatch("[^\r\n]+") do - table.insert(ret, s) - end - return ret + 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 -userreg.register_handler('&', handler) +-- Register the '&' fileregister +userregs.register_handler('&', handler) diff --git a/plugin/mark.lua b/plugin/mark.lua deleted file mode 100644 index ccc6374..0000000 --- a/plugin/mark.lua +++ /dev/null @@ -1,75 +0,0 @@ --- Implementation of middle mark. This mark is always in the middle of the --- viewport. - -local api = vim.api - --- Compatibility check. -if not api.nvim_call_function('has', {'usermarks'}) then - return nil -end - -local usermark = require("vim.usermark") - --- The middle mark is on the middle of the screen. -local middle_mark = {} -function middle_mark.get(self) - local topline = vim.api.nvim_call_function('line', {'w0'}) - local bottomline = vim.api.nvim_call_function('line', {'w$'}) - - return math.floor((topline + bottomline) / 2) -end - --- Setting the middle mark sets the current cusor line to the middle of the --- window. Principally this is the same as z. -function middle_mark.set(self) - api.nvim_command('norm z.') -end - --- The top mark is the first line on the window. This does respect scrolloff. -local top_mark = {} -function top_mark.get(self) - return vim.api.nvim_call_function('line', {'w0'}) + vim.o.scrolloff -end --- Setting the top mark move the current line to the top. Principally this is --- the same mas z<cr> -function top_mark.set(self) - api.nvim_command('norm z<cr>') -end - --- Setting the bottom mark moves the current line to the bottom. Principally --- this is the same as z- -local bottom_mark = {} -function bottom_mark.get(self) - return vim.api.nvim_call_function('line', {'w$'}) - vim.o.scrolloff -end --- Setting the bottom mark doesn't do anything. -function bottom_mark.set(self) - api.nvim_command('norm z-') -end - --- Mark that's like the expression register, but for a mark. -local expr_mark = {} -function expr_mark.get(self) - local mode = vim.api.nvim_call_function('mode', {}) - - if mode == "c" then - -- Avoid recurring asking for a value while in command mode. - return nil - end - - local expr = vim.api.nvim_call_function('input', {'='}) - if expr ~= "" then - return vim.api.nvim_eval(expr) - end - - return nil -end - --- Setting the expr_mark does'nt do anything -function expr_mark.set(self) end - --- Register all the marks with their respective characters. -usermark.register_handler('-', middle_mark) -usermark.register_handler('+', top_mark) -usermark.register_handler('_', bottom_mark) -usermark.register_handler('=', expr_mark) |