My ever growing neovim init.lua 
Tags: neovim, lua
Published: 2021-08-15 20:29:21

---
title: My ever growing neovim init.lua 
published: true
description: What I have learning about neovim init.lua
tags: neovim, lua
//cover_image: https://direct_url_to_image.jpg
---

# Intro
Since I have now neovim 0.5 installed and know it can run faster with init.lua I started to gradually annotate and copying pieces of others [neo]vimmers to reproduce my old environment.

## Aliases

```lua
-- aliases
local execute = vim.api.nvim_command
local vim = vim
local opt  = vim.opt   -- global
local g  = vim.g     -- global for let options
local wo = vim.wo    -- window local
local bo = vim.bo    -- buffer local
local fn = vim.fn    -- access vim functions
local cmd = vim.cmd  -- vim commands
local api = vim.api  -- access vim api
```

## A function to reaload vim (useful when you change your config)

```lua 
-- https://neovim.discourse.group/t/reload-init-lua-and-all-require-d-scripts/971/11
function _G.ReloadConfig()
    local hls_status = vim.v.hlsearch
    for name,_ in pairs(package.loaded) do
        if name:match('^cnull') then
            package.loaded[name] = nil
        end
    end
    dofile(vim.env.MYVIMRC)
    if hls_status == 0 then
        vim.opt.hlsearch = false
    end
end
```

## Mappings
It is cool having a mapper function in order to make things easier, so:

```lua
-- map helper
local map = function(key)
    -- get the extra options
    local opts = {noremap = true}
    for i, v in pairs(key) do
        if type(i) == 'string' then opts[i] = v end
    end

    -- basic support for buffer-scoped keybindings
    local buffer = opts.buffer
    opts.buffer = nil

    if buffer then
        vim.api.nvim_buf_set_keymap(0, key[1], key[2], key[3], opts)
    else
        vim.api.nvim_set_keymap(key[1], key[2], key[3], opts)
    end
end
```

Once you have a mapper tool you can add mappings like these:

```lua
map{'n', '<space>', '/'}
map{'n', '<F9>', ':update<cr>'}
map{'n', '<leader>v', ':e $MYVIMRC<cr>'}
map{'n', '<F4>', ':set invpaste paste?<cr>'}
map{'i', '<S-insert>', '<C-r><C-o>+'}
map{'n', 'n', 'nzz'}
map{'n', 'N', 'Nzz'}
map{'n', '<C-l>', ':set hls!<cr>'}

-- line text-objects
map{'v', 'al', ':<c-u>norm!0v$<cr>', {noremap = true, silent = true}}
map{'v', 'il', ':<c-u>norm!_vg_<cr>', {noremap = true, silent = true}}
map{'o', 'al', ':norm val<cr>', {noremap = true, silent = true}}
map{'o', 'il', ':norm vil<cr>', {noremap = true, silent = true}}
```

## Some useful functions
First I have a global function called **preserve**, we can change some stuff in the file
without making the cursor jumping around. 

```lua
-- -- https://bit.ly/3g6vYIW
function _G.preserve(cmd)
        local cmd = string.format('keepjumps keeppatterns execute %q', cmd)
        local original_cursor = vim.fn.winsaveview()
        vim.api.nvim_command(cmd)
        vim.fn.winrestview(original_cursor)
end
```

Once you have this function you can reindent your file with a new command

```lua
vim.cmd([[command! Reindent lua preserve("sil keepj normal! gg=G")]])
```

In the `~/.config/nvim/lua` I have a function to squeeze blank lines

```lua
M = {}

M.squeeze_blank_lines = function()
    -- references: https://vi.stackexchange.com/posts/26304/revisions
    local old_query = vim.fn.getreg('/')    -- save search register
    preserve('sil! 1,.s/^\\n\\{2,}/\\r/gn') -- set current search count number
    local result = vim.fn.searchcount({maxcount = 1000, timeout = 500}).current
    local line, col = unpack(vim.api.nvim_win_get_cursor(0))
    preserve('sil! keepp keepj %s/^\\n\\{2,}/\\r/ge')
    preserve('sil! keepp keepj %s/\\v($\\n\\s*)+%$/\\r/e')
    vim.api.nvim_win_set_cursor({0}, {(line - result), col})
    vim.fn.setreg('/', old_query)           -- restore search register
end

return M
```

Also in the tools.lua I have a function to change the file header, where we can read: "Last Change: ..."

```lua
--> :lua changeheader()
-- This function is called with the BufWritePre event (autocmd)
-- and when I want to save a file I use ":update" which
-- only writes a buffer if it was modified
M.changeheader = function()
    if (vim.fn.line('$') >= 7) then
        time = os.date("%a, %m %Y %H:%M")
        preserve('sil! keepp keepj 1,7s/\\vlast (modified|change):\\zs.*/ ' .. time .. '/ei') 
    end
end
```

Here my autocommands:

```lua
-- autocommands
--- This function is taken from https://github.com/norcalli/nvim_utils
function nvim_create_augroups(definitions)
    for group_name, definition in pairs(definitions) do
        api.nvim_command('augroup '..group_name)
        api.nvim_command('autocmd!')
        for _, def in ipairs(definition) do
            local command = table.concat(vim.tbl_flatten{'autocmd', def}, ' ')
            api.nvim_command(command)
        end
        api.nvim_command('augroup END')
    end
end

local autocmds = {
        reload_vimrc = {
        -- Reload vim config automatically
        -- {"BufWritePost",[[$VIM_PATH/{*.vim,*.yaml,vimrc} nested source $MYVIMRC | redraw]]};
        {"BufWritePre", "$MYVIMRC", "lua ReloadConfig()"};
    };

    change_header = {
            {"BufWritePre", "*", "lua require('tools').changeheader()"}
        };
    packer = {
        { "BufWritePost", "plugins.lua", "PackerCompile" };
    };
    terminal_job = {
        { "TermOpen", "*", [[tnoremap <buffer> <Esc> <c-\><c-n>]] };
        { "TermOpen", "*", "startinsert" };
        { "TermOpen", "*", "setlocal listchars= nonumber norelativenumber" };
    };
    restore_cursor = {
        { 'BufRead', '*', [[call setpos(".", getpos("'\""))]] };
    };
    save_shada = {
        {"VimLeave", "*", "wshada!"};
    };
    resize_windows_proportionally = {
        { "VimResized", "*", ":wincmd =" };
    };
    toggle_search_highlighting = {
        { "InsertEnter", "*", "setlocal nohlsearch" };
    };
    lua_highlight = {
        { "TextYankPost", "*", [[silent! lua vim.highlight.on_yank() {higroup="IncSearch", timeout=400}]] };
    };
    ansi_esc_log = {
        { "BufEnter", "*.log", ":AnsiEsc" };
    };
}

nvim_create_augroups(autocmds)
-- autocommands END
```