diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 68a40e5..3f93c6e 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -1,5 +1,6 @@ local MAP = vim.keymap.set local AUTOCMD = vim.api.nvim_create_autocmd +local NEWCMD = vim.api.nvim_create_user_command vim.cmd("colorscheme scheme") vim.cmd("filetype indent on") @@ -247,6 +248,103 @@ local function MakeScratch() end end +local function AlignEq() + if vim.fn.mode():lower() == "v" then + -- Feed an escape to leave visual mode, this updates the '< and '> marks + local keys = vim.api.nvim_replace_termcodes('', true, false, true) + vim.api.nvim_feedkeys(keys, 'x', true) + end + + local st = vim.fn.getpos("'<")[2] - 1 + local ed = vim.fn.getpos("'>")[2] + + local max = 0 + + local lines = vim.api.nvim_buf_get_lines(0, st, ed, true) + local aligned = {} + + for _, line in ipairs(lines) do + local pos = line:find('=', 1, true) + if pos then + local trimmed = line:sub(1, pos - 1):gsub("%s+$", "") + max = math.max(#trimmed, max) + end + end + + for _, line in ipairs(lines) do + local text = line + local pos = line:find('=', 1, true) + if pos then + local before = line:sub(1, pos - 1):gsub("%s+$", "") + local after = line:sub(pos + 1):gsub("^%s+", "") + + text = before .. string.rep(" ", max - #before + 1) .. "= " .. after + end + + table.insert(aligned, text) + end + + vim.api.nvim_buf_set_lines(0, st, ed, true, aligned) +end + +local _comment_leaders = { + lua = '--', + vim = '"', + sh = "#", + python = "#", + conf = "#", + yaml = "#", + gdscript = "#", + make = "#" +} + +local function BlockComment() + local leader = _comment_leaders[vim.o.filetype] or '//' + + local st = vim.api.nvim_win_get_cursor(0)[1] - 1 + local ed = st + 1 + + if vim.fn.mode():lower() == "v" then + -- Feed keys to leave visual mode, this updates the '< and '> marks + local keys = vim.api.nvim_replace_termcodes('', true, false, true) + vim.api.nvim_feedkeys(keys, 'x', true) + + st = vim.fn.getpos("'<")[2] - 1 + ed = vim.fn.getpos("'>")[2] + end + + local lines = vim.api.nvim_buf_get_lines(0, st, ed, true) + local comment = false + + for _, line in ipairs(lines) do + local pos = line:find("%S") + if #line > 0 and line:byte(pos) ~= leader:byte(1) then + comment = true + break + end + end + + local adjusted = {} + + for _, line in ipairs(lines) do + local text = "" + if #line > 0 then + if comment then + text = leader .. " " .. line + else + local s, e = line:find(leader, 1, true) + + if line:byte(e + 1) == 0x20 then e = e + 1 end + text = line:sub(1, s - 1) .. line:sub(e + 1) + end + end + + table.insert(adjusted, text) + end + + vim.api.nvim_buf_set_lines(0, st, ed, true, adjusted) +end + -- Windowing local _is_help = { help = true, man = true, qf = true } @@ -338,6 +436,9 @@ MAP("i", "", BufferComplete, { expr = true }) MAP("n", "s", ManageSplit) MAP("n", "f", ProjectSearch) MAP("n", "m", PromptBuild) +MAP("v", "/", BlockComment) +MAP("n", "/", BlockComment) +MAP("v", "=", AlignEq) -------------------------------------------------------------------------------- -- Autocommands @@ -353,3 +454,44 @@ AUTOCMD('BufWinEnter', { callback = LayoutHelp, pattern = "*" }) AUTOCMD('WinEnter', { callback = ExpandHelp, pattern = "*" }) AUTOCMD('WinLeave', { callback = ExpandHelp, pattern = "*" }) AUTOCMD('BufRead', { callback = LoadDiagnostics, pattern = "*" }) + +-------------------------------------------------------------------------------- +-- Custom commands +-------------------------------------------------------------------------------- + +local function Tabber(a) + local count = tonumber(a.fargs[1]) + + if count == nil then + vim.notify("[Error] :: Expected number", vim.log.levels.ERROR) + else + local opts = { ts = vim.o.tabstop, et = vim.o.expandtab } + + vim.o.tabstop = count + + if a.bang then + vim.o.expandtab = true + vim.cmd("silent retab") + else + local pos = { + view = vim.fn.winsaveview(), + vstart = vim.fn.getpos("'<"), + vend = vim.fn.getpos("'>") + } + + -- gg=G doesn't work in some niche cases so we do a full buffer select, indent and then + -- unindent. With expandtab disabled converts leading spaces to tabs + vim.o.expandtab = false + vim.cmd("silent normal! ggVG>VG<") + + vim.fn.winrestview(pos.view) + vim.fn.setpos("'<", pos.vstart) + vim.fn.setpos("'>", pos.vend) + end + + vim.o.tabstop = opts.ts + vim.o.expandtab = opts.et + end +end + +NEWCMD('Tabber', Tabber, { nargs = 1, bang = true }) diff --git a/install b/dots similarity index 93% rename from install rename to dots index 4a5e428..6304c15 100755 --- a/install +++ b/dots @@ -3,7 +3,7 @@ set -e pushd "$(dirname $0)" > /dev/null -Push() { +Install() { # Installs current dotfiles onto the system # echo "[Info] :: Installing dotfiles into $1" @@ -27,8 +27,8 @@ ACTION=$1 [[ -z $INSTALL_DIR ]] && echo "[Error] :: Installation directory not set" && exit 1 case $ACTION in - push) - Push $INSTALL_DIR + install) + Install $INSTALL_DIR ;; pull) Pull $INSTALL_DIR