shada.lua (2189B)
1 if vim.g.loaded_shada_plugin then 2 return 3 end 4 vim.g.loaded_shada_plugin = 1 5 6 local augroup = vim.api.nvim_create_augroup('nvim.shada', {}) 7 8 ---@type fun(binstrings: string[]): string[] 9 local shada_get_strings = vim.fn['shada#get_strings'] 10 11 ---@type fun(strings: string[]): string[] 12 local shada_get_binstrings = vim.fn['shada#get_binstrings'] 13 14 ---Ensures that pattern and augroup are set correctly. 15 ---@param event string|string[] 16 ---@param opts vim.api.keyset.create_autocmd 17 ---@param fn fun(args: vim.api.keyset.create_autocmd.callback_args): boolean? 18 local function def_autocmd(event, opts, fn) 19 opts = opts or {} 20 opts.group = augroup 21 opts.pattern = { '*.shada', '*.shada.tmp.[a-z]' } 22 opts.callback = function(ev) 23 if vim.v.cmdarg ~= '' then 24 error('++opt not supported') 25 end 26 fn(ev) 27 end 28 vim.api.nvim_create_autocmd(event, opts) 29 end 30 31 ---Read shada strings from file. 32 ---@param file string Filename 33 ---@return string[] # lines from shada file 34 local function read_strings(file) 35 local f = assert(io.open(file, 'rb')) 36 local strings = f:read('*a') 37 f:close() 38 return shada_get_strings(strings) 39 end 40 41 def_autocmd('BufReadCmd', {}, function(ev) 42 local lines = read_strings(ev.file) 43 vim.api.nvim_buf_set_lines(ev.buf, 0, -1, false, lines) 44 vim.bo[ev.buf].filetype = 'shada' 45 end) 46 47 def_autocmd('FileReadCmd', {}, function(ev) 48 local lines = read_strings(ev.file) 49 local lnum = vim.fn.line("'[") 50 vim.api.nvim_buf_set_lines(ev.buf, lnum, lnum, true, lines) 51 end) 52 53 def_autocmd('BufWriteCmd', {}, function(ev) 54 local buflines = vim.api.nvim_buf_get_lines(0, 0, -1, false) 55 local ret = vim.fn.writefile(shada_get_binstrings(buflines), ev.file, 'b') 56 if ret == 0 then 57 vim.bo[ev.buf].modified = false 58 end 59 end) 60 61 def_autocmd({ 'FileWriteCmd', 'FileAppendCmd' }, {}, function(ev) 62 vim.fn.writefile( 63 shada_get_binstrings( 64 vim.fn.getline( 65 math.min(vim.fn.line("'["), vim.fn.line("']")), 66 math.max(vim.fn.line("'["), vim.fn.line("']")) 67 ) --[=[@as string[]]=] 68 ), 69 ev.file, 70 ev.event == 'FileAppendCmd' and 'ab' or 'b' 71 ) 72 end) 73 74 def_autocmd('SourceCmd', {}, function(ev) 75 vim.cmd.rshada(vim.fn.fnameescape(ev.file)) 76 end)