DEV Community

Sérgio Araújo
Sérgio Araújo

Posted on • Updated on

My ever growing neovim init.lua

Intro

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

The full configuration resides now at:
https://github.com/voyeg3r/nvim

Aliases

-- aliases
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
Enter fullscreen mode Exit fullscreen mode

NOTE: vim.opt is better thant vim.o

Now if you want to set any global option you do not have more to type vim.o, just type o.setnumber for example.

My options

-- global options -- i could explain all of these but then again :h var exists...
opt.completeopt = "menuone,noselect"
opt.inccommand = 'nosplit'
opt.swapfile = true
opt.dir = '/tmp'
opt.smartcase = true
opt.laststatus = 2
opt.hlsearch = true
opt.incsearch = true
opt.ignorecase = true
opt.scrolloff = 3
opt.showcmd = true
opt.wildmenu = true
opt.mouse = 'a'
opt.showmatch = true
opt.expandtab = true
opt.ruler = true
opt.incsearch = true
opt.hlsearch = true
opt.showmode = false
opt.tabstop = 4
opt.softtabstop = 4
opt.shiftwidth = 4
opt.shiftround = true
opt.timeout = false
opt.timeoutlen = 10
opt.undofile = true; bo.undofile = true -- persistent undo is a neat feature
opt.title = true
opt.hidden = true
opt.path = vim.opt.path + '.,**'
Enter fullscreen mode Exit fullscreen mode

Leader key

If you don't know what leader key is read this article

g.mapleader = ","
Enter fullscreen mode Exit fullscreen mode

Plugin manager

Once we are using lua for almost everything it is a good idea using a pure lua plugin manager, in our case → ‘packer’.

-- Install packer
local execute = vim.api.nvim_command
local install_path = vim.fn.stdpath('data')..'/site/pack/packer/opt/packer.nvim'

if vim.fn.empty(vim.fn.glob(install_path)) > 0 then
  execute('!git clone https://github.com/wbthomason/packer.nvim '..install_path)
end

vim.cmd [[packadd packer.nvim]]
vim.api.nvim_exec([[
  augroup Packer
    autocmd!
    autocmd BufWritePost plugins.lua PackerCompile
  augroup end
]], false)

local use = require('packer').use
require('packer').startup(function()
  use {'wbthomason/packer.nvim', opt = true}
  use 'kana/vim-smartinput' -- auto close delimiters
  use 'tpope/vim-commentary'
  use {'nvim-telescope/telescope.nvim', requires = {{'nvim-lua/popup.nvim'}, {'nvim-lua/plenary.nvim'}} }
  use 'joshdick/onedark.vim'
  use 'itchyny/lightline.vim'
  -- use { 'lukas-reineke/indent-blankline.nvim', branch="master" }
  use 'neovim/nvim-lspconfig'
  use 'hrsh7th/nvim-compe'
  -- snippets -- why should you type when you can get your minions to do it for you?
   use 'sirver/ultisnips' -- the engine 
   use 'honza/vim-snippets' -- the coal (the actuall snippets)
end)
Enter fullscreen mode Exit fullscreen mode

Mappings

It is cool having a mapper function in order to make things easier, so I have found a nice wrapper to make easier to write my mappings.

-- map helper
local function map(mode, lhs, rhs, opts)
  local options = {noremap = true}
  if opts then options = vim.tbl_extend('force', options, opts) end
  vim.api.nvim_set_keymap(mode, lhs, rhs, options)
end
Enter fullscreen mode Exit fullscreen mode

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

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-o>', '<c-o>zz')
map('n', '<c-i>', '<c-i>zz')
map{'n', '<C-l>', ':set hls!<cr>'}
map{n', '<leader>r', ':registers<cr>}'

map{'v', 'al', ':norm!0v$', noremap = true, silent = true}
map{'v', 'il', ':norm!vg', noremap = true, silent = true}
map{'o', 'al', ':norm val', noremap = true, silent = true}
map{'o', 'il', ':norm vil', noremap = true, silent = true}

-- shortcuts to jump in the command line
map('c', '<C-a>', '<home>', options)
map('c', '<C-e>', '<end>', options)
map('n', '<leader>b', ':buffers<cr>:b<space>')
Enter fullscreen mode Exit fullscreen mode

UltiSnips config

-- ultisnips (snippets)
g.completion_enable_snippet = 'UltiSnips'
g.ultisnipssnippetsdir = '~/.dotfiles/nvim/snips/'
g.ultisnipssnippetdirectories = 'snips'
g.UltiSnipsExpandTrigger = '<C-j>'
g.UltiSnipsJumpForwardTrigger = '<C-j>'
g.UltiSnipsJumpBackwardTrigger = '<C-k>'
g.UltiSnipsEditSplit = 'vertical'
g.UltiSnipsListSnippets = '<C-Space>'

g.UltiSnipsExpandTrigger="<tab>"
g.UltiSnipsJumpForwardTrigger="<c-n>"
g.UltiSnipsJumpBackwardTrigger="<c-p>"

-- snippets variables
g.snips_author = 'Sergio Araujo'
g.snips_site = 'https://dev.to/voyeg3r'
g.snips_email = '<voyeg3r ✉ gmail.com>'
g.snips_github = 'https://github.com/voyeg3r'
g.snips_twitter = '@voyeg3r'
g.UltiSnipsEditSplit = 'horizontal'

map ('n', '<leader>u', ':UltiSnipsEdit<cr>', options)
Enter fullscreen mode Exit fullscreen mode

Reload config function

-- 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
Enter fullscreen mode Exit fullscreen mode

My new "utils.lua" file

Now I have just added a function called "flash_cursorline", every time I jump to a new window my cursor flashes. First the function:

-- https://vi.stackexchange.com/questions/31206
M.flash_cursorline = function()
    vim.opt.cursorline = true
    vim.cmd([[hi CursorLine guifg=#000000 guibg=#ffffff]])
    vim.fn.timer_start(200, function()
        vim.cmd([[hi CursorLine guifg=NONE guibg=NONE]])
        vim.opt.cursorline = false
    end)
end
Enter fullscreen mode Exit fullscreen mode

Now I have just to add a new autocommand at the "autocommands" section:

-- add to the autocmd section below
flash_cursor_line = {
    { "WinEnter", "*", [[lua require('utils').flash_cursorline()]]}
};
Enter fullscreen mode Exit fullscreen mode

Auto command section

It uses some functions in utils.lua (see it below)

-- 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
Enter fullscreen mode Exit fullscreen mode

utils.lua (old name tools)

-- utils.lua
-- Last Change: dom, 22 ago 2021 11:10
-- author: Sergio Araujo
-- site: https://dev.to/voyeg3r

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

local M = {}

M.squeeze_blank_lines = function()
    -- references: https://vi.stackexchange.com/posts/26304/revisions
    if (vim.bo.filetype ~= 'binary') or (vim.bo.filetype ~= 'diff') then
        local old_query = vim.fn.getreg('/')    -- save search register
        M.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))
        M.preserve('sil! keepp keepj %s/^\\n\\{2,}/\\r/ge')
        M.preserve('sil! keepp keepj %s/\\v($\\n\\s*)+%$/\\r/e')
        if result > 0 then
            vim.api.nvim_win_set_cursor({0}, {(line - result), col})
        end
        vim.fn.setreg('/', old_query)           -- restore search register
    end
end


--> :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()
    -- We only can run this function if the file is modifiable
    if not vim.api.nvim_buf_get_option(vim.api.nvim_get_current_buf(), "modifiable") then
        return
    end
    if (vim.fn.line('$') >= 7) then
        os.setlocale("en_US.UTF-8") -- show Sun instead of dom (portuguese)
        time = os.date("%a, %d %b %Y %H:%M")
        M.preserve('sil! keepp keepj 1,7s/\\vlast (modified|change):\\zs.*/ ' .. time .. '/ei')
    end
end


return M
Enter fullscreen mode Exit fullscreen mode

Flash cursorline

-- https://vi.stackexchange.com/questions/31206
M.flash_cursorline = function()
    vim.opt.cursorline = true
    vim.cmd([[hi CursorLine guifg=#000000 guibg=#ffffff]])
    vim.fn.timer_start(200, function()
        vim.cmd([[hi CursorLine guifg=NONE guibg=NONE]])
        vim.opt.cursorline = false
    end)
end
Enter fullscreen mode Exit fullscreen mode

Now my functions are in the utils.lua, so I have added these lines on my autocmd.lua

    flash_cursor_line = {
       { "WinEnter", "*", [[lua require('utils').flash_cursorline()]]}
    };
Enter fullscreen mode Exit fullscreen mode

My ReloadConfig function is now called as autocommand like this:

        {"BufWritePre", "$MYVIMRC", "lua require('utils').ReloadConfig()"};
Enter fullscreen mode Exit fullscreen mode

References:

Discussion (0)