local function map(mode, l, r, desc) vim.keymap.set(mode, l, r, { desc = desc }) end local function cmd(mode, l, r, desc) map(mode, l, "" .. r .. "", desc) end local function cmdi(mode, l, r, desc) map(mode, l, ":" .. r, desc) end local function nmap(l, r, desc) map("n", l, r, desc) end local function vmap(l, r, desc) map("v", l, r, desc) end local function nvmap(l, r, desc) map({ "n", "v" }, l, r, desc) end local function ncmd(l, r, desc) cmd("n", l, r, desc) end local function ncmdi(l, r, desc) cmdi("n", l, r, desc) end local function vcmdi(l, r, desc) cmdi("v", l, r, desc) end ncmd("", "nohlsearch") -- highlight last inserted text nmap("gV", "`[v`]") nmap("", "") nmap("", "") -- paste over selection without clobbering registers vmap("p", '"_dP') -- Find and Replace binds ncmdi("s", "%s/") vcmdi("s", "s/") ncmd("x", "wall") ncmd("z", "wqall") ncmd("q", "quitall") vim.keymap.set( "t", "", "", { silent = true, noremap = true, desc = "Exit terminal mode" } ) nmap("[w", function() vim.diagnostic.jump({ count = -vim.v.count1, severity = { min = vim.diagnostic.severity.WARN }, }) end) nmap("]w", function() vim.diagnostic.jump({ count = vim.v.count1, severity = { min = vim.diagnostic.severity.WARN }, }) end) nmap("[e", function() vim.diagnostic.jump({ count = -vim.v.count1, severity = vim.diagnostic.severity.ERROR, }) end) nmap("]e", function() vim.diagnostic.jump({ count = vim.v.count1, severity = vim.diagnostic.severity.ERROR, }) end) nmap("yp", function() vim.fn.setreg("+", vim.fn.expand("%")) end, "[Y]ank [P]ath") local doas_exec = function(_cmd) vim.fn.inputsave() local password = vim.fn.inputsecret("Password: ") vim.fn.inputrestore() if not password or #password == 0 then vim.notify("Invalid password, doas aborted", vim.log.levels.WARN) return false end local out = vim.fn.system(string.format("doas -S %s", _cmd), password .. "\n") if vim.v.shell_error ~= 0 then print("\r\n") vim.notify(out, vim.log.levels.ERROR) return false end return true end vim.api.nvim_create_user_command("DoasWrite", function(opts) local tmpfile = vim.fn.tempname() local filepath if #opts.fargs == 1 then filepath = opts.fargs[1] else filepath = vim.fn.expand("%") end if not filepath or #filepath == 0 then vim.notify("E32: No file name", vim.log.levels.ERROR) return end -- `bs=1048576` is equivalent to `bs=1M` for GNU dd or `bs=1m` for BSD dd -- Both `bs=1M` and `bs=1m` are non-POSIX local _cmd = string.format( "dd if=%s of=%s bs=1048576", vim.fn.shellescape(tmpfile), vim.fn.shellescape(filepath) ) -- no need to check error as this fails the entire function vim.api.nvim_exec2(string.format("write! %s", tmpfile), { output = true }) if doas_exec(_cmd) then -- refreshes the buffer and prints the "written" message vim.cmd.checktime() -- exit command mode vim.api.nvim_feedkeys( vim.api.nvim_replace_termcodes("", true, false, true), "n", true ) end vim.fn.delete(tmpfile) end, { nargs = "?", desc = "Write using doas permissions", })