neovim-lastmod.nix (1910B)
1 { lib, vimUtils, writeText, runCommand }: 2 3 let 4 lastmodLua = writeText "lastmod.lua" '' 5 local SEARCH_LINES = 10 6 local TS_FORMAT = "%Y-%m-%dT%H:%M:%S" 7 local TS_PATTERN = "%d%d%d%d%-%d%d%-%d%dT%d%d:%d%d:?%d*" 8 9 local group = vim.api.nvim_create_augroup("LastmodPrompt", { clear = true }) 10 11 vim.api.nvim_create_autocmd("BufWritePre", { 12 group = group, 13 pattern = { "*.md", "*.markdown" }, 14 desc = "Prompt to update lastmod frontmatter field on save", 15 callback = function(args) 16 local buf = args.buf 17 if not vim.bo[buf].modifiable then 18 return 19 end 20 21 local lines = vim.api.nvim_buf_get_lines(buf, 0, SEARCH_LINES, false) 22 23 for i, line in ipairs(lines) do 24 local prefix, old = line:match("^(%s*lastmod:%s*[\"']?)(" .. TS_PATTERN .. ")") 25 if old then 26 local now = os.date(TS_FORMAT) 27 local choice = vim.fn.confirm( 28 ("Update lastmod?\n %s -> %s"):format(old, now), 29 "&Yes\n&No", 30 1 -- defaults to Yes 31 ) 32 if choice == 1 then 33 -- Replace only the timestamp, preserving indentation/quotes/trailing text 34 local new_line = line:gsub(TS_PATTERN, now, 1) 35 vim.api.nvim_buf_set_lines(buf, i - 1, i, false, { new_line }) 36 end 37 return -- only handle the first lastmod field found 38 end 39 end 40 end, 41 }) 42 43 ''; 44 in 45 vimUtils.buildVimPlugin { 46 pname = "lastmod"; 47 version = "1.0.0"; 48 49 # buildVimPlugin expects a source tree laid out the way Neovim's 50 # runtimepath wants it, so wrap the embedded lua string in lua/. 51 src = runCommand "lastmod-src" { } '' 52 mkdir -p $out/lua 53 cp ${lastmodLua} $out/lua/lastmod.lua 54 ''; 55 56 nvimRequireCheck = "lastmod"; 57 58 meta = { 59 description = "Prompts whether Neovim should update the lastmod field in markdown files on save"; 60 license = lib.licenses.mit; 61 platforms = lib.platforms.all; 62 }; 63 }