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://bitbucket.org/sergio/nvim-lua/

Modeline issues

-- https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md#patches
if vim.fn.has('patch-8.1.1366') then
    vim.opt.modelines=5
    vim.opt.modelineexpr = false
    vim.opt.modeline = true
else
    vim.opt.modeline = false
end
Enter fullscreen mode Exit fullscreen mode

First run startup issue:

Many users report a slugish first run, so:

-- IMPROVE NEOVIM STARTUP
-- https://github.com/editorconfig/editorconfig-vim/issues/50
vim.g.loaded_python_provier=1
vim.g.python_host_skip_check = 1
vim.g.python_host_prog='/bin/python2'
vim.g.python3_host_skip_check = 1
vim.g.python3_host_prog='/bin/python3'
vim.opt.pyxversion=3
-- if vim.fn.executable("editorconfig") then
--  vim.g.EditorConfig_exec_path = '/bin/editorconfig'
-- end
vim.g.EditorConfig_core_mode = 'external'
Enter fullscreen mode Exit fullscreen mode

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
local map = require('user.utils').map -- import map helper
local toggle_opt = require('user.utils').vim_opt_toggle 
Enter fullscreen mode Exit fullscreen mode

NOTE: vim.opt is better than 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

-- protected call if the them is not present it just tells you about
local colorscheme = "nordfox"
local status_ok, _ = pcall(vim.cmd, "colorscheme " .. colorscheme)
if not status_ok then
    vim.notify("colorscheme " .. colorscheme .. " not found!")
    return
end


-- https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md#patches
if vim.fn.has('patch-8.1.1366') then
    vim.opt.modelines=5
    vim.opt.modelineexpr = false
    vim.opt.modeline = true
else
    vim.opt.modeline = false
end

-- IMPROVE NEOVIM STARTUP
-- https://github.com/editorconfig/editorconfig-vim/issues/50
vim.g.loaded_python_provier = 0
vim.g.loaded_python3_provider = 0
vim.g.python_host_skip_check = 1
vim.g.python_host_prog='/bin/python2'
vim.g.python3_host_skip_check = 1
vim.g.python3_host_prog='/bin/python3'
vim.opt.pyxversion=3
-- if vim.fn.executable("editorconfig") then
--  vim.g.EditorConfig_exec_path = '/bin/editorconfig'
-- end
vim.g.EditorConfig_core_mode = 'external_command'

-- https://vi.stackexchange.com/a/5318/7339
vim.g.matchparen_timeout = 20
vim.g.matchparen_insert_timeout = 20

-- disable builtins plugins
local disabled_built_ins = {
    "2html_plugin",
    "getscript",
    "getscriptPlugin",
    "gzip",
    "logipat",
    "matchit",
    "netrw",
    "netrwFileHandlers",
    "loaded_remote_plugins",
    "loaded_tutor_mode_plugin",
    "netrwPlugin",
    "netrwSettings",
    "rrhelper",
    "spellfile_plugin",
    "tar",
    "tarPlugin",
    "vimball",
    "vimballPlugin",
    "zip",
    "zipPlugin",
    "matchparen", -- matchparen.nvim disables the default
}

for _, plugin in pairs(disabled_built_ins) do
    vim.g["loaded_" .. plugin] = 1
end

vim.g.do_filetype_lua = 1
vim.g.did_load_filetypes = 0

g.mapleader = ","

--vim.cmd("hi normal guibg=NONE ctermbg=NONE")
-- https://www.codesd.com/item/how-do-i-open-the-quickfix-window-instead-of-displaying-grep-results.html
-- vim.cmd([[command! -bar -nargs=1 Grep silent grep <q-args> | redraw! | cw]])
vim.cmd([[cnoreab cls Cls]])
vim.cmd([[command! Cls lua require("core.utils").preserve('%s/\\s\\+$//ge')]])
vim.cmd([[command! Reindent lua require('core.utils').preserve("sil keepj normal! gg=G")]])
vim.cmd([[command! BufOnly lua require('core.utils').preserve("silent! %bd|e#|bd#")]])
vim.cmd([[cnoreab Bo BufOnly]])
vim.cmd([[cnoreab W w]])
vim.cmd([[cnoreab W! w!]])
vim.cmd([[command! CloneBuffer new | 0put =getbufline('#',1,'$')]])
vim.cmd([[command! Mappings drop ~/.config/nvim/lua/user/mappings.lua]])
vim.cmd([[command! Scratch new | setlocal bt=nofile bh=wipe nobl noswapfile nu]])
vim.cmd([[syntax sync minlines=64]]) --  faster syntax hl

-- save as root, in my case I use the command 'doas'
vim.cmd([[cmap w!! w !doas tee % >/dev/null]])
vim.cmd([[command! SaveAsRoot w !doas tee %]])

-- vim.cmd([[hi ActiveWindow ctermbg=16 | hi InactiveWindow ctermbg=233]])
-- vim.cmd([[set winhighlight=Normal:ActiveWindow,NormalNC:InactiveWindow]])

vim.cmd('command! ReloadConfig lua require("utils").ReloadConfig()')

-- inserts filename and Last Change: date
vim.cmd([[inoreab lc -- File: <c-r>=expand("%:p")<cr><cr>-- Last Change: <c-r>=strftime("%b %d %Y - %H:%M")<cr><cr>]])

vim.cmd([[inoreab Fname <c-r>=expand("%:p")<cr>]])
vim.cmd([[inoreab Iname <c-r>=expand("%:p")<cr>]])
vim.cmd([[inoreab fname <c-r>=expand("%:t")<cr>]])
vim.cmd([[inoreab iname <c-r>=expand("%:t")<cr>]])

vim.cmd([[inoreabbrev idate <C-R>=strftime("%b %d %Y %H:%M")<CR>]])
vim.cmd([[cnoreab cls Cls]])

local options = {
    ssop = vim.opt.ssop - { "blank", "help", "buffers" } + { "terminal" },
    modelines = 5,
    dictionary = vim.opt.dictionary + '~/.dotfiles/nvim/words.txt',   --  " C-x C-k C-n
    modelineexpr = false,
    modeline = true,
    emoji = false, -- CREDIT: https://www.youtube.com/watch?v=F91VWOelFNE
    undofile = true,
    shada = "!,'30,<30,s30,h,:30,%0,/30",
    whichwrap = opt.whichwrap:append "<>[]hl",
    iskeyword = opt.iskeyword:append "-",
    listchars = { eol = "↲", tab = "▶ ", trail = "•", precedes = "«", extends = "»", nbsp = "␣", space = "." },
    --completeopt = "menu,menuone,noselect",
    completeopt = { "menuone", "noselect"},
    encoding = "utf-8",    -- str:  String encoding to use
    fileencoding = "utf8", -- str:  File encoding to use
    syntax = "ON",        -- str:  Allow syntax highlighting
    foldenable = false,
    foldopen = vim.opt.foldopen + "jump", -- when jumping to the line auto-open the folder
    foldmethod = "indent",
    path = vim.opt.path + "~/.config/nvim/lua/user",
    path = vim.opt.path + "**",
    wildignore = { ".git", ".hg", ".svn", "*.pyc", "*.o", "*.out", "*.jpg", "*.jpeg", "*.png", "*.gif", "*.zip" },
    wildignore = vim.opt.wildignore + { "**/node_modules/**", "**/bower_modules/**", "__pycache__", "*~", "*.DS_Store" },
    wildignore = vim.opt.wildignore + { "**/undo/**", "*[Cc]ache/" },
    wildignorecase = true,
    infercase = true,
    lazyredraw = true,
    showmatch = true,
    switchbuf = useopen,
    matchtime = 2,
    synmaxcol = 128, -- avoid slow rendering for long lines
    shell = "/bin/zsh",
    pumheight = 10,
    pumblend = 15,
    wildmode = "longest:full,full",
    timeoutlen = 500,
    ttimeoutlen = 10, -- https://vi.stackexchange.com/a/4471/7339
    hlsearch = true, -- Highlight found searches
    ignorecase = true, -- Ignore case
    inccommand = "nosplit", -- Get a preview of replacements
    incsearch = true, -- Shows the match while typing
    joinspaces = false, -- No double spaces with join
    linebreak = true, -- Stop words being broken on wrap
    list = false, -- Show some invisible characters
    relativenumber = true,
    scrolloff = 2, -- Lines of context
    shiftround = true, -- Round indent
    shiftwidth = 4, -- Size of an indent
    expandtab = true,
    showmode = false, -- Don't display mode
    sidescrolloff = 8, -- Columns of context
    signcolumn = "yes:1", -- always show signcolumns
    smartcase = true, -- Do not ignore case with capitals
    smartindent = true, -- Insert indents automatically
    spelllang = { "en_gb" },
    splitbelow = true, -- Put new windows below current
    splitright = true, -- Put new windows right of current
    tabstop = 4, -- Number of spaces tabs count for
    termguicolors = true, -- You will have bad experience for diagnostic messages when it's default 4000.
    wrap = true,
    mouse = "a",
    undodir = "/tmp",
    undofile = true,
    fillchars = { eob = "~" },
}

for k, v in pairs(options) do
    vim.opt[k] = v
end

if vim.fn.executable("rg") then
    -- if ripgrep installed, use that as a grepper
    vim.opt.grepprg = "rg --vimgrep --no-heading --smart-case"
    vim.opt.grepformat = "%f:%l:%c:%m,%f:%l:%m"
end
--lua require("notify")("install ripgrep!")

if vim.fn.executable("prettier") then
    opt.formatprg = "prettier --stdin-filepath=%"
end
--lua require("notify")("Install prettier formater!")

opt.formatoptions = "l"
opt.formatoptions = opt.formatoptions
    - "a" -- Auto formatting is BAD.
    - "t" -- Don't auto format my code. I got linters for that.
    + "c" -- In general, I like it when comments respect textwidth
    + "q" -- Allow formatting comments w/ gq
    - "o" -- O and o, don't continue comments
    + "r" -- But do continue when pressing enter.
    + "n" -- Indent past the formatlistpat, not underneath it.
    + "j" -- Auto-remove comments if possible.
    - "2" -- I'm not in gradeschool anymore

opt.guicursor = {
    "n-v:block",
    "i-c-ci-ve:ver25",
    "r-cr:hor20",
    "o:hor50",
    "i:blinkwait700-blinkoff400-blinkon250-Cursor/lCursor",
    "sm:block-blinkwait175-blinkoff150-blinkon175",
}

-- window-local options
window_options = {
    numberwidth = 2,
    number = true,
    relativenumber = true,
    linebreak = true,
    cursorline = true,
    foldenable = false,
}

for k, v in pairs(window_options) do
    vim.wo[k] = v
end

-- buffer-local options
buffer_options = {
    expandtab = true,
    softtabstop = 4,
    tabstop = 4,
    shiftwidth = 4,
    smartindent = true,
    suffixesadd = '.lua'
}

for k, v in pairs(buffer_options) do
    vim.bo[k] = v
end

vim.g.nojoinspaces = true
Enter fullscreen mode Exit fullscreen mode

Yet in options we can improve our startup performance disabling some builtin plugins:

-- disable builtins plugins
local disabled_built_ins = {
    "netrw",
    "netrwPlugin",
    "netrwSettings",
    "netrwFileHandlers",
    "gzip",
    "zip",
    "zipPlugin",
    "tar",
    "tarPlugin",
    "getscript",
    "getscriptPlugin",
    "vimball",
    "vimballPlugin",
    "2html_plugin",
    "logipat",
    "rrhelper",
    "spellfile_plugin",
    "matchit"
}

for _, plugin in pairs(disabled_built_ins) do
    vim.g["loaded_" .. plugin] = 1
end
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’.

-- File: /home/sergio/.config/nvim/lua/user/plugins.lua
-- Last Change: Mon, 28 Feb 2022 09:07

local fn = vim.fn

-- Automatically install packer
local install_path = fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim"
if fn.empty(fn.glob(install_path)) > 0 then
    PACKER_BOOTSTRAP = fn.system {
        "git",
        "clone",
        "--depth",
        "1",
        "https://github.com/wbthomason/packer.nvim",
        install_path,
    }
    print "Installing packer close and reopen Neovim..."
    vim.cmd [[packadd packer.nvim]]
end

function get_setup(name)
    return string.format('require("user/%s")', name)
end

-- Autocommand that reloads neovim whenever you save the plugins.lua file
vim.cmd [[
  augroup packer_user_config
  autocmd!
  autocmd BufWritePost plugins.lua source <afile> | PackerSync
  augroup end
]]

-- Use a protected call so we don't error out on first use
local status_ok, packer = pcall(require, "packer")
if not status_ok then
    return
end

-- Have packer use a popup window
packer.init {
    display = {
        open_fn = function()
            return require("packer.util").float { border = "rounded" }
        end,
    },
}

-- Install your plugins here
return packer.startup(function(use)
    -- My plugins here
    use "wbthomason/packer.nvim" -- Have packer manage itself
    use "nvim-lua/popup.nvim" -- An implementation of the Popup API from vim in Neovim
    use "nvim-lua/plenary.nvim" -- Useful lua functions used ny lots of plugins
    use ({"windwp/nvim-autopairs", config = get_setup("autopairs")}) -- Autopairs, integrates with both cmp and treesitter
    use 'rcarriga/nvim-notify'
    use({
        "karb94/neoscroll.nvim",
        --opt = true,
        --event = "WinScrolled",
        config = get_setup("neoscroll"),
    })
    use({ "numToStr/Comment.nvim", config = get_setup("comment"),
        -- opt = true,
        -- keys = { "gc", "gcc", "gbc" }, -- it makes commet plugi lazy load
        requires = {"JoosepAlviste/nvim-ts-context-commentstring"}
    }) -- Easily comment stuff

    use({
        "folke/persistence.nvim",
        event = "BufReadPre", -- this will only start session saving when an actual file was opened
        module = "persistence",
        config = function()
            require("persistence").setup()
        end,
    })

    -- colorschemes
    use 'tanvirtin/monokai.nvim'
    use({"EdenEast/nightfox.nvim"})
    use({"ellisonleao/gruvbox.nvim", requires = { "rktjmp/lush.nvim" } })
    use 'marko-cerovac/material.nvim'
    use("shaunsingh/nord.nvim")
    use({"navarasu/onedark.nvim"})
    use({"cocopon/iceberg.vim"})
    use({"folke/tokyonight.nvim"})
    use({"lunarvim/darkplus.nvim"})
    use("Mofiqul/dracula.nvim")
    use({
    'rose-pine/neovim',
        as = 'rose-pine',
        tag = 'v1.*',
        -- config = function()
        --     vim.cmd('colorscheme rose-pine')
        -- end
    })

    -- Linux users: you must install wmctrl to be able to automatically switch to
    -- the Vim window with the open file. wmctrl is already packaged for most
    -- distributions. (autoswap dependency)
    use({ "gioele/vim-autoswap" })
    use ({"DanilaMihailov/beacon.nvim", config = get_setup("beacon") }) -- show cursor on jumps
    use "kyazdani42/nvim-web-devicons"
    use ({"kyazdani42/nvim-tree.lua", config = get_setup("nvim-tree") })
    use ({"akinsho/bufferline.nvim", config = get_setup("bufferline")})
    use "moll/vim-bbye"
    use ({"nvim-lualine/lualine.nvim", config = get_setup("lualine")})
    use ({"akinsho/toggleterm.nvim", config = get_setup("toggleterm")})
    -- use "ahmedkhalf/project.nvim"
    use ({"lewis6991/impatient.nvim", config = get_setup("impatient")})
    use ({"lukas-reineke/indent-blankline.nvim", config = get_setup("indentline")})
    use ({"goolord/alpha-nvim", config = get_setup("alpha") })
    use "antoinemadec/FixCursorHold.nvim" -- This is needed to fix lsp doc highlight
    use 'tjdevries/nlua.nvim'
    use({ "nathom/filetype.nvim", config = get_setup("filetype") })
    --use "folke/which-key.nvim"

    -- cmp plugins
    use ({"hrsh7th/nvim-cmp", config = get_setup("cmp") }) -- The completion plugin
    use "hrsh7th/cmp-buffer" -- buffer completions
    use "hrsh7th/cmp-path" -- path completions
    use "hrsh7th/cmp-cmdline" -- cmdline completions
    use "saadparwaiz1/cmp_luasnip" -- snippet completions
    use "hrsh7th/cmp-nvim-lsp"

    -- snippets
    use "L3MON4D3/LuaSnip" --snippet engine
    use "rafamadriz/friendly-snippets" -- a bunch of snippets to use

    -- LSP
    use "neovim/nvim-lspconfig" -- enable LSP
    use "williamboman/nvim-lsp-installer" -- simple to use language server installer
    use "tamago324/nlsp-settings.nvim" -- language server settings defined in json for
    use "jose-elias-alvarez/null-ls.nvim" -- for formatters and linters
    use "MunifTanjim/prettier.nvim"

    -- Telescope
    use ({"nvim-telescope/telescope.nvim", config = get_setup("telescope")})

    -- Treesitter
    use {
        "nvim-treesitter/nvim-treesitter",
        run = ":TSUpdate",
        config = get_setup("treesitter"),
    }
    use "JoosepAlviste/nvim-ts-context-commentstring"

    -- Git
    use ({"lewis6991/gitsigns.nvim", config = get_setup("gitsigns")})

    -- Automatically set up your configuration after cloning packer.nvim
    -- Put this at the end after all plugins
    if PACKER_BOOTSTRAP then
        require("packer").sync()
    end
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.

-- this function resides in ~/.config/nvim/lua/user/utils.lua
-- https://blog.devgenius.io/create-custom-keymaps-in-neovim-with-lua-d1167de0f2c2
-- https://oroques.dev/notes/neovim-init/
M.map = function(mode, lhs, rhs, opts)
    local options = { noremap = true }
    if opts then
        options = vim.tbl_extend("force", options, opts)
    end
    vim.keymap.set(mode, lhs, rhs, options)
end

M.vim_opt_toggle = function(opt, on, off, name)
    local message = name
    if vim.opt[opt]:get() == off then
        vim.opt[opt] = on
        message = message .. " Enabled" else
        vim.opt[opt] = off
        message = message .. " Disabled"
    end
        vim.notify(message)
end
Enter fullscreen mode Exit fullscreen mode

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

-- Fname: /home/sergio/.config/nvim/lua/mappings.lua
--  Last Change: Mon, 28 Feb 2022 11:12

local map = require('user.utils').map
local opt_toggle = require('user.utils').vim_opt_toggle

--- Map leader to space
vim.g.mapleader = ","

local s = {silent = true}

-- Modes
--   normal_mode = "n",
--   insert_mode = "i",
--   visual_mode = "v",
--   visual_block_mode = "x",
--   term_mode = "t",
--   command_mode = "c",

-- Normal --
-- Better window navigation
map("n", "<C-h>", "<C-w>h" )
map("n", "<C-j>", "<C-w>j" )
map("n", "<C-k>", "<C-w>k" )
map("n", "<C-l>", "<C-w>l" )

-- vim.keymap.set allows us use lua functions inside our mappings 
map({'n', "i"} , 
'<leader>l', 
function() vim_opt_toggle("list", true, false, "List") 
end,
{ desc = "Toggle list hidden chars"}
)

-- toggle number/relative number
map('n', '<M-n>', '<cmd>let [&nu, &rnu] = [!&rnu, &nu+&rnu==1]<cr>')


-- Resize with arrows
map("n", "<C-Up>", ":resize -2<CR>" )
map("n", "<C-Down>", ":resize +2<CR>" )
map("n", "<C-Left>", ":vertical resize -2<CR>" )
map("n", "<C-Right>", ":vertical resize +2<CR>" )

-- Navigate buffers
map("n", "<M-,>", ":bnext<CR>" )
map("n", "<M-.>", ":bprevious<CR>" )

-- Move text up and down
map("n", "<A-j>", "<Esc>:m .+1<CR>==gi" )
map("n", "<A-k>", "<Esc>:m .-2<CR>==gi" )

-- Visual --
-- Stay in indent mode
map("v", "<", "<gv" )
map("v", ">", ">gv" )

-- Move text up and down
map("v", "<A-j>", ":m .+1<CR>==" )
map("v", "<A-k>", ":m .-2<CR>==" )
-- keymap("v", "p", '"_dP' )

-- Visual Block --
-- Move text up and down
map("x", "J", ":move '>+1<CR>gv-gv" )
map("x", "K", ":move '<-2<CR>gv-gv" )
map("x", "<A-j>", ":move '>+1<CR>gv-gv" )
map("x", "<A-k>", ":move '<-2<CR>gv-gv" )

-- Terminal --
-- Better terminal navigation
-- keymap("t", "<C-h>", "<C-\\><C-N><C-w>h", term_opts)
-- keymap("t", "<C-j>", "<C-\\><C-N><C-w>j", term_opts)
-- keymap("t", "<C-k>", "<C-\\><C-N><C-w>k", term_opts)
-- keymap("t", "<C-l>", "<C-\\><C-N><C-w>l", term_opts)

---- line text-objects (inner and whole line text-objects)
---- I am trying now to create some "inner next object", "around last object" and
---- these mappings conflict with the mappings bellow, so, I am disabling those for a while
map("x", "al", ":<C-u>norm! 0v$<cr>")
map("x", "il", ":<C-u>norm! _vg_<cr>")
map("o", "al", ":norm! val<cr>")
map("o", "il", ":norm! vil<cr>")

-- other interesting text objects
-- reference: https://www.reddit.com/r/vim/comments/adsqnx/comment/edjw792
-- TODO: detect if we are over the first char and jump to the right
local chars = { "_", "-", ".", ":", ",", ";", "<bar>", "/", "<bslash>", "*", "+", "%", "#", "`" }
for k, v in ipairs(chars) do
    map("x", "i" .. v, ":<C-u>norm! T" .. v .. "vt" .. v .. "<CR>")
    map("x", "a" .. v, ":<C-u>norm! F" .. v .. "vf" .. v .. "<CR>")
    map("o", "a" .. v, ":normal! va" .. v .. "<CR>")
    map("o", "i" .. v, ":normal! vi" .. v .. "<CR>")
end

-- charactere under the cursor
--local char = vim.fn.strcharpart(vim.fn.strpart(vim.fn.getline("."), vim.fn.col(".") - 1), 0, 1)
--print(char)

-- for k, v in ipairs(chars) do
--     map("o", "an" .. v, ":norm! f" .. v .. "vf" .. v .. "<CR>")
--     map("o", "in" .. v, ":norm! f" .. v .. "lvt" .. v .. "<CR>")
--     map("o", "al" .. v, ":norm! F" .. v .. "vF" .. v .. "<CR>")
--     map("o", "il" .. v, ":norm! F" .. v .. "hvT" .. v .. "<CR>")
--     map("x", "an" .. v, ":<c-u>norm! f" .. v .. "vf" .. v .. "<CR>")
--     map("x", "in" .. v, ":<c-u>norm! f" .. v .. "lvt" .. v .. "<CR>")
--     map("x", "al" .. v, ":<c-u>norm! F" .. v .. "vF" .. v .. "<CR>")
--     map("x", "il" .. v, ":<c-u>norm! F" .. v .. "hvT" .. v .. "<CR>")
-- end

map("v", "<Leader>y", '"+y')

-- glow (markdow preview)
map('n', '<C-M-g', '<cmd>Glow<CR>')

-- terminal mappings
-- Notice: There are other mappings in the which-key file settings!
--         but they will only work after some delay
--         you can also call "vertical and float" terminals
map("n", "<leader>t", "<cmd>ToggleTerm size=8 direction=horizontal<cr>")

-- copy to the primary selection on mouse release
map("v", "<LeftRelease>", '"*y')

-- jump to the last changed spot
map("n", "gl", "`.")

-- Nvim Tree
-- map("n", "<leader>e", ":PackerLoad nvim-tree.lua | NvimTreeToggle<CR>", { silent = true })
map("n", "<leader>e", ":PackerLoad nvim-tree.lua<cr>:NvimTreeToggle<CR>", { silent = true })
--map("n", "<leader>e", ":NvimTreeToggle<CR>", { silent = true })
map("n", "<F11>", ":NvimTreeFindFile<CR>", { silent = true })

-- two commands at once to load plugin and then use it!
-- map("n", "<F4>", ":PackerLoad undotree<cr>:UndotreeToggle<cr>", { silent = true })

map("n", "<F4>", ":set invpaste paste?<cr>")
map("i", "<F4>", "<c-o>:set invpaste paste?<cr>")

-- Update Plugins
map("n", "<Leader>u", ":PackerSync<CR>")

-- Open nvimrc file
map("n", "<Leader>v", "<cmd>drop $MYVIMRC<CR>")
map("n", "<Leader>z", "<cmd>drop ~/.zshrc<CR>")

-- Source nvimrc file
map("n", "<Leader>sv", ":luafile %<CR>")

-- Quick new file
-- map("n", "<Leader>n", "<cmd>enew<CR>")

-- nvim file
map('n', '<Leader>n', "<cmd>lua require('user.files').nvim_files()<CR>")

-- Make visual yanks place the cursor back where started
-- map("v", "y", "ygv<Esc>")
-- https://ddrscott.github.io/blog/2016/yank-without-jank/
vim.cmd([[vnoremap <expr>y "my\"" . v:register . "y`y"]])

-- Easier file save
map("n", "<Delete>", "<cmd>:update!<CR>")
map("n", "<F9>", "<cmd>update<cr>")
map("i", "<F9>", "<c-o>:update<cr>")

-- Cheatsheet plugin (show your mappings)
map("n", "<F12>", "<cmd>Cheatsheet<cr>")

-- discard buffer
-- fixing a temporary issue: https://github.com/dstein64/nvim-scrollview/issues/10
map("n", "<leader>x", ":wsh | up | sil! bd<cr>", { silent = true })
map("n", "<leader>w", ":bw!<cr>", { silent = true })

-- select last paste in visual mode
map("n", "<leader>p", "'`[' . strpart(getregtype(), 0, 1) . '`]'", { expr = true })

-- It adds motions like 25j and 30k to the jump list, so you can cycle
-- through them with control-o and control-i.
-- source: https://www.vi-improved.org/vim-tips/
map("n", "j", [[v:count ? (v:count > 5 ? "m'" . v:count : '') . 'j' : 'gj']], { expr = true })
map("n", "k", [[v:count ? (v:count > 5 ? "m'" . v:count : '') . 'k' : 'gk']], { expr = true })


-- type c* (perform your substitution Esc) then "n" and "."
map("n", "<leader><leader>", ":b#<cr>")
map("n", "c*", "*<c-o>cgn")
map("n", "c#", "#<c-o>cgn")
-- map("n", "<leader>g", "*<c-o>cgn")

-- avoid clipboard hacking security issue
-- http://thejh.net/misc/website-terminal-copy-paste
-- inoremap <C-R>+ <C-r><C-o>+
map("i", "<C-r>+", "<C-r><C-o>+")
map("i", "<S-Insert>", "<C-r><C-o>+")

-- two clicks in a word makes a count
map("n", "<2-LeftMouse>", [[:lua require('user.utils').CountWordFunction()<cr>]], { silent = true })
map("n", "<RightMouse>", "<cmd>match none<cr>")

-- show current buffer
-- map("n", "<C-m-t>", [[:lua require('notify')(vim.fn.expand('%:p'))<cr>:lua require('user.utils').flash_cursorline()<cr>]])

-- deletes the rest of the line in command mode
map("c", "<c-k>", [[<c-\>egetcmdline()[:getcmdpos()-2]<CR>]])

-- <Tab> to navigate the completion menu
map("i", "<Tab>", 'pumvisible() ? "\\<C-n>" : "\\<Tab>"', { expr = true })
map("i", "<S-Tab>", 'pumvisible() ? "\\<C-p>" : "\\<Tab>"', { expr = true })

-- More molecular undo of text
-- map("i", ",", ",<c-g>u")
map("i", ".", ".<c-g>u")
map("i", "!", "!<c-g>u")
map("i", "?", "?<c-g>u")
map("i", ";", ";<c-g>u")
map("i", ":", ":<c-g>u")
map("i", "]", "]<c-g>u")
map("i", "}", "}<c-g>u")

-- map("n", "<F3>", '<cmd>lua require("harpoon.mark").add_file(vim.fn.expand("%:p"))<cr>')
-- map("n", "<S-F3>", '<cmd>lua require("harpoon.ui").toggle_quick_menu()<cr>')

-- https://stackoverflow.com/a/37897322
-- https://neovim.discourse.group/t/how-to-append-mappings-in-lua/2118
-- use maparg
map('n', 'n', 'n:Beacon<CR>')
map('n', 'N', 'N:Beacon<CR>')
map('n', '*', '*:Beacon<CR>')
map('n', '#', '#:Beacon<CR>')

-- -- Keep search results centred
-- map("n", "n", "nzz")
-- map("n", "N", "Nzz")

map("n", "J", "mzJ`z")
-- map("n", "<c-o>", '<c-o>zv:lua require("user.utils").flash_cursorline()<cr>', { silent = true })
-- map("n", "<c-i>", '<c-i>zv:lua require("user.utils").flash_cursorline()<cr>', { silent = true })
map("n", "<c-o>", '<c-o>zv:Beacon<cr>', { silent = true })
map("n", "<c-i>", '<c-i>zv:Beacon<cr>', { silent = true })

-- better gx mapping
-- https://sbulav.github.io/vim/neovim-opening-urls/
map("", "gx", '<Cmd>call jobstart(["xdg-open", expand("<cfile>")], {"detach": v:true})<CR>', {})

-- quickfix mappings
map('n', '[q', ':cprevious<CR>')
map('n', ']q', ':cnext<CR>')
map('n', ']Q', ':clast<CR>')
map('n', '[Q', ':cfirst<CR>')

-- Reselect visual when indenting
map("x", ">", ">gv")
map("x", "<", "<gv")

-- Selecting your pasted text
-- map gp `[v`]
-- https://www.reddit.com/r/vim/comments/4aab93 ]]
-- map("n", "gV", "`[V`]")
map("n", "gV", [['`[' . strpart(getregtype(), 0, 1) . '`]']], { expr = true })

map(
    "n",
    "<C-l>",
    [[ (&hls && v:hlsearch ? ':nohls' : ':set hls')."\n" <BAR> redraw<CR>]],
    { silent = true, expr = true }
)

-- Make Y yank to end of the line
map("n", "Y", "yg_")

-- shortcuts to jump in the command line
map("c", "<C-a>", "<home>")
map("c", "<C-e>", "<end>")

map("i", "<s-cr>", "<c-o>o")
map("i", "<c-cr>", "<c-o>O")

--nnoremap <expr> oo 'm`' . v:count1 . 'o<Esc>``'
--nnoremap <expr> OO 'm`' . v:count1 . 'O<Esc>``'

map("n", "ç", ":")
map("n", "<space>", "/")

-- Line bubbling
map("n", "<c-j>", "<cmd>m .+1<CR>==", { silent = true }) -- move current line down
map("n", "<c-k>", "<cmd>m .-2<CR>==", { silent = true }) -- move current line up
map("v", "<c-j>", ":m '>+1<CR>==gv=gv", { silent = true }) -- move current line down
map("v", "<c-k>", ":m '<-2<CR>==gv=gv", { silent = true }) -- move current line up

-- Make the dot command work as expected in visual mode (via
-- https://www.reddit.com/r/vim/comments/3y2mgt/
map("v", ".", ":norm .<cr>")

-- close buffer without loosing the opened window
map("n", "<C-c>", ":new|bd #<CR>", { silent = true })

map("n", "<leader>d", '<cmd>lua require("user.utils").squeeze_blank_lines()<cr>')

map("n", "<space>fb", "<cmd>lua require 'telescope'.extensions.file_browser.file_browser()<CR>", { noremap = true })

-- telescope mappings
-- map("n", "<leader>o", ':lua require("telescope.builtin").oldfiles()<cr>') -- already mapped on which-key
map("n", "<C-M-o>", ':lua require("telescope.builtin").oldfiles()<CR>') -- already mapped on which-key
-- cd ~/.dotfiles/wiki | Telescope find_files
--map("n", "<c-p>", [[<cmd>lua require("telescope.builtin").find_files{cwd = "~/.dotfiles"}<cr>]], { silent = true })
map("n", "<c-p>", [[<cmd>lua require('user.files').search_dotfiles()<cr>]], { silent = true })
--map("n", "<F8>", [[<cmd>lua require("telescope.builtin").find_files{cwd = "~/.config"}<cr>]], { silent = true })
map("n", "<F8>", [[<cmd>lua require("user.files").xdg_config()<cr>]], { silent = true })
-- map('n', '<F8>', [[<cmd>lua require("telescope.builtin").find_files{cwd = "~/.config/nvim"}<cr>]], {silent = true})
-- map("n", "<leader>f", [[<cmd>lua require('telescope.builtin').find_files()<cr>]], { silent = true })
-- map("n", "<leader>b", [[<cmd>lua require('telescope.builtin').buffers()<cr>]], { silent = true })
map('n', '<leader>b', [[<Cmd>lua require('user.files').buffers()<CR>]])
-- map(
--     "n",
--     "<leader>b",
--     [[<cmd>lua require('telescope.builtin').buffers(require('telescope.themes').get_dropdown{previewer = false})<cr>")]]
-- )
map("n", "<leader>l", [[<cmd>lua require('telescope.builtin').current_buffer_fuzzy_find()<cr>]], { silent = true })
-- map('n', '<leader>t', [[<cmd>lua require('telescope.builtin').tags()<cr>]], {  silent = true})
map("n", "<leader>?", [[<cmd>lua require('telescope.builtin').oldfiles()<cr>]], { silent = true })
map("n", "<leader>sd", [[<cmd>lua require('telescope.builtin').grep_string()<cr>]], { silent = true })
map(
    "n",
    "<leader>sp",
    [[<cmd>lua require('telescope.builtin').live_grep{cwd = "~/.dotfiles/wiki"}<cr>]],
    { silent = true }
)
-- map('n', '<leader>o', [[<cmd>lua require('telescope.builtin').tags{ only_current_buffer = true }<cr>]], {  silent = true})
map("n", "<leader>gc", [[<cmd>lua require('telescope.builtin').git_commits()<cr>]], { silent = true })
map("n", "<leader>gb", [[<cmd>lua require('telescope.builtin').git_branches()<cr>]], { silent = true })
map("n", "<leader>gs", [[<cmd>lua require('telescope.builtin').git_status()<cr>]], { silent = true })
map("n", "<leader>gp", [[<cmd>lua require('telescope.builtin').git_bcommits()<cr>]], { silent = true })
-- end of telescope mappings

-- gitsigns mappings:
map('n', ']c', "&diff ? ']c' : '<cmd>Gitsigns next_hunk<CR>'", {expr=true})
map('n', '[c', "&diff ? '[c' : '<cmd>Gitsigns prev_hunk<CR>'", {expr=true})

-- reload snippets.lua
map('n', '<leader><leader>s', '<cmd>source ~/.config/nvim/after/plugin/snippets.lua<cr>')

-- avoid entering Ex mode by accident
map('n', 'Q', '<Nop>')

-- mappings for persistence plugin
-- restore the session for the current directory
map("n", "<leader>qs", [[<cmd>lua require("persistence").load()<cr>]])

-- restore the last session
map("n", "<F5>", [[<cmd>lua require("persistence").load({ last = true })<cr>]])

-- stop Persistence => session won't be saved on exit
map("n", "<leader>qd", [[<cmd>lua require("persistence").stop()<cr>]])

-- Easy add date/time
-- map("n", "<Leader>t", "\"=strftime('%c')<CR>Pa", { silent = true })

-- Telescope
map("n", "<Leader>1", ":Telescope sessions [save_current=true]<CR>")
-- map("n", "<leader>p", '<cmd>lua require("telescope.builtin").find_files()<cr>')
map("n", "<leader>p", "<cmd>lua require'telescope.builtin'.find_files({find_command={'fd','--no-ignore-vcs'}})")
map("n", "<leader>r", '<cmd>lua require("telescope.builtin").registers()<cr>')
map("n", "<leader>g", '<cmd>lua require("telescope.builtin").live_grep()<cr>')
-- map("n", "<leader>b", '<cmd>lua require("telescope.builtin").buffers()<cr>')
map("n", "<leader>j", '<cmd>lua require("telescope.builtin").help_tags()<cr>')
map("n", "<leader>h", '<cmd>lua require("telescope.builtin").git_bcommits()<cr>')
-- map("n", "<leader>f", '<cmd>lua require("telescope").extensions.file_browser.file_browser()<CR>')
map("n", "<leader>s", '<cmd>lua require("telescope.builtin").spell_suggest()<cr>')
map("n", "<leader>i", '<cmd>lua require("telescope.builtin").git_status()<cr>')
map("n", "<leader>ca", '<cmd>lua require("telescope.builtin").lsp_code_actions()<cr>')
map("n", "<leader>cs", '<cmd>lua require("telescope.builtin").lsp_document_symbols()<cr>')
map("n", "<leader>cd", '<cmd>lua require("telescope.builtin").lsp_document_diagnostics()<cr>')
map("n", "<leader>cr", '<cmd>lua require("telescope.builtin").lsp_references()<cr>')

map("i", "<F2>", '<cmd>lua require("renamer").rename()<cr>', { noremap = true, silent = true })
map("n", "<leader>cn", '<cmd>lua require("renamer").rename()<cr>', { noremap = true, silent = true })
map("v", "<leader>cn", '<cmd>lua require("renamer").rename()<cr>', { noremap = true, silent = true })

-- change colors
-- map("n", "<F6>", [[<cmd>lua require("user.utils").toggle_colors()<cr>]])
map("n", "<F6>", ":lua require('user.colors').choose_colors()<CR>" )
-- map("n", "<F2>", [[<cmd>lua require("user.utils").toggle_transparency()<cr>]])

-- toggle list
-- set list! | :echo (&list == 1 ? "list enabled" : "list disabled")
map("n", "<c-m-l>", ":set list!<CR>:echo (&list == 1 ? 'list enabled' : 'list disabled')<CR>")
map("i", "<c-m-l>", "<C-o>:set list!<CR><C-o>:echo (&list == 1 ? 'list enabled' : 'list disabled')<CR>")

map("n", "<F7>", "[[:let &background = ( &background == 'dark'? 'light' : 'dark' )<CR>]]", { silent = true })

map("n", "<leader>ci", "<cmd> lua vim.diagnostic.open_float()<cr>")

-- Easier split mappings
map("n", "<Leader><Down>", "<C-W><C-J>", { silent = true })
map("n", "<Leader><Up>", "<C-W><C-K>", { silent = true })
map("n", "<Leader><Right>", "<C-W><C-L>", { silent = true })
map("n", "<Leader><Left>", "<C-W><C-H>", { silent = true })
map("n", "<Leader>;", "<C-W>R", { silent = true })
map("n", "<Leader>[", "<C-W>_", { silent = true })
map("n", "<Leader>]", "<C-W>|", { silent = true })
map("n", "<Leader>=", "<C-W>=", { silent = true })

map('n', '<leader>a', ':Alpha<CR>')

-- -- Hop
-- map("n", "h", "<cmd>lua require'hop'.hint_words()<cr>")
-- map("n", "l", "<cmd>lua require'hop'.hint_lines()<cr>")
-- map("v", "h", "<cmd>lua require'hop'.hint_words()<cr>")
-- map("v", "l", "<cmd>lua require'hop'.hint_lines()<cr>")

-- Symbols outline
-- map("n", "<leader>o", ":SymbolsOutline<cr>")

-- barbar mappings

-- Move to previous/next
map("n", "<A-,>", ":BufferPrevious<CR>")
map("n", "<A-.>", ":BufferNext<CR>")

-- Tab to switch buffers in Normal mode
map("n", "<Tab>", ":bnext<CR>")
map("n", "<S-Tab>", ":bprevious<CR>")

-- -- Move to previous/next (tabline)
-- map("n", "<A-,>", ":TablineBufferNext<CR>")
-- map("n", "<A-.>", ":TablineBufferPrevious<CR>")

-- -- Re-order to previous/next
map("n", "<A-<>", ":BufferMovePrevious<CR>")
map("n", "<A->>", ":BufferMoveNext<CR>")

-- Goto buffer in position...
map("n", "<A-1>", ":BufferGoto 1<CR>")
map("n", "<A-2>", ":BufferGoto 2<CR>")
map("n", "<A-3>", ":BufferGoto 3<CR>")
map("n", "<A-4>", ":BufferGoto 4<CR>")
map("n", "<A-5>", ":BufferGoto 5<CR>")
map("n", "<A-6>", ":BufferGoto 6<CR>")
map("n", "<A-7>", ":BufferGoto 7<CR>")
map("n", "<A-8>", ":BufferGoto 8<CR>")
map("n", "<A-9>", ":BufferLast<CR>")
-- Pin/unpin buffer
map("n", "<A-p>", ":BufferPin<CR>")
-- Close buffer
map("n", "<A-c>", ":BufferPin<CR>")

-- Wipeout buffer
-- :BufferWipeout<CR>
-- Close commands
-- :BufferCloseAllButCurrent<CR>
-- :BufferCloseAllButPinned<CR>
-- :BufferCloseBuffersLeft<CR>
-- :BufferCloseBuffersRight<CR>

-- Magic buffer-picking mode
map("n", "<C-s>", ":BufferPick<CR>")

-- Sort automatically by...
map("n", "<Space>bb", ":BufferOrderByBufferNumber<CR>")
map("n", "<Space>bd", ":BufferOrderByDirectory<CR>")
map("n", "<Space>bl", ":BufferOrderByLanguage<CR>")
map("n", "<Space>bw", ":BufferOrderByWindowNumber<CR>")

-- Other:
-- :BarbarEnable - enables barbar (enabled by default)
-- :BarbarDisable - very bad command, should never be used
Enter fullscreen mode Exit fullscreen mode

Fixing gf command for lua files:

On your ~/.config/nvim/ftplugin/lua.lua file add:

vim.opt_local.suffixesadd:prepend('.lua')
vim.opt_local.suffixesadd:prepend('init.lua')
vim.opt_local.path:prepend(vim.fn.stdpath('config')..'/lua')
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

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 =" };
    };
    -- show trailing spaces only in normal mode
    toggle_search_highlighting = {
        { "InsertEnter", "*", "setlocal nohlsearch" },
        { "InsertEnter", "*", [[call clearmatches()]]},
        { "InsertLeave", "*", [[highlight RedundantSpaces ctermbg=red guibg=red]]},
        { "InsertLeave", "*", [[match RedundantSpaces /\s\+$/]]},
    },
    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)

-- Fname: /home/sergio/.config/nvim/lua/utils.lua
-- Last Change: Sun, 16 Jan 2022 10:51

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 = {}

-- https://blog.devgenius.io/create-custom-keymaps-in-neovim-with-lua-d1167de0f2c2
-- https://oroques.dev/notes/neovim-init/
M.map = function(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

-- References
-- https://bit.ly/3HqvgRT
M.CountWordFunction = function()
    local hlsearch_status = vim.v.hlsearch
    local old_query = vim.fn.getreg("/") -- save search register
    local current_word = vim.fn.expand("<cword>")
    vim.fn.setreg("/", current_word)
    local wordcount = vim.fn.searchcount({ maxcount = 1000, timeout = 500 }).total
    vim.fn.setreg("/", old_query) -- restore search register
    print("Current word found: " .. wordcount .. " times")
    -- Below we are using the nvim-notify plugin to show up the count of words
    vim.cmd([[highlight CurrenWord ctermbg=LightGray ctermfg=Red guibg=LightGray guifg=Black]])
    vim.cmd([[exec 'match CurrenWord /\V\<' . expand('<cword>') . '\>/']])
    -- require("notify")("word '" .. current_word .. "' found " .. wordcount .. " times")
end

local transparency = 0
M.toggle_transparency = function()
    if transparency == 0 then
        vim.cmd("hi Normal guibg=NONE ctermbg=NONE")
        local transparency = 1
    else
        vim.cmd("hi Normal guibg=#111111 ctermbg=black")
        local transparency = 0
    end
end
-- -- map('n', '<c-s-t>', '<cmd>lua require("utils").toggle_transparency()<br>')

M.toggle_colors = function()
    local current_color = vim.g.colors_name
    if current_color == "tokyonight" then
        vim.cmd("colorscheme monokai")
        vim.cmd("colo")
    elseif current_color == "monokai" then
        vim.cmd("colorscheme dawnfox")
        vim.cmd("colo")
    elseif current_color == "dawnfox" then
        vim.cmd("colorscheme onedark")
        vim.cmd("colo")
    elseif current_color == "onedark" then
        vim.cmd("colorscheme iceberg")
        vim.cmd("colo")
    else
        --vim.g.tokyonight_transparent = true
        vim.cmd("colorscheme tokyonight")
        vim.cmd("colo")
    end
end

-- https://vi.stackexchange.com/questions/31206
M.flash_cursorline = function()
    -- local cursorline_state = vim.opt.cursorline:get()
    vim.opt.cursorline = true
    vim.cmd([[hi CursorLine guifg=#FFFFFF guibg=#FF9509]])
    vim.fn.timer_start(200, function()
        vim.cmd([[hi CursorLine guifg=NONE guibg=NONE]])
        vim.opt.cursorline = false
    end)
end

-- https://www.reddit.com/r/neovim/comments/rnevjt/comment/hps3aba/
M.ToggleQuickFix = function()
    if vim.fn.getqflist({ winid = 0 }).winid ~= 0 then
        vim.cmd([[cclose]])
    else
        vim.cmd([[copen]])
    end
end
vim.cmd([[command! -nargs=0 -bar ToggleQuickFix lua require('utils').ToggleQuickFix()]])
vim.cmd([[cnoreab TQ ToggleQuickFix]])
vim.cmd([[cnoreab tq ToggleQuickFix]])

-- dos2unix
M.dosToUnix = function()
    M.preserve("%s/\\%x0D$//e")
    vim.bo.fileformat = "unix"
    vim.bo.bomb = true
    vim.opt.encoding = "utf-8"
    vim.opt.fileencoding = "utf-8"
end
vim.cmd([[command! Dos2unix lua require('utils').dosToUnix()]])

M.squeeze_blank_lines = function()
-- references: https://vi.stackexchange.com/posts/26304/revisions
    if vim.bo.binary == false and vim.opt.filetype:get() ~= "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

-- https://neovim.discourse.group/t/reload-init-lua-and-all-require-d-scripts/971/11
M.ReloadConfig = function()
    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

M.preserve = function(arguments)
    local arguments = string.format("keepjumps keeppatterns execute %q", arguments)
    -- local original_cursor = vim.fn.winsaveview()
    local line, col = unpack(vim.api.nvim_win_get_cursor(0))
    vim.api.nvim_command(arguments)
    local lastline = vim.fn.line("$")
    -- vim.fn.winrestview(original_cursor)
    if line > lastline then
        line = lastline
    end
    vim.api.nvim_win_set_cursor({ 0 }, { line, col })
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
    local bufnr = vim.api.nvim_get_current_buf()
    if not vim.api.nvim_buf_get_option(bufnr, "modifiable") then
        require("notify")("Current file not modifiable!")
        return
    end
    --if not vim.api.nvim_buf_get_option(bufnr, "modified") then
        --require("notify")("Current file has not changed!")
        --return
    --end
    if vim.fn.line("$") >= 7 then
        os.setlocale("en_US.UTF-8") -- show Sun instead of dom (portuguese)
        local time = os.date("%a, %d %b %Y %H:%M")
        M.preserve("sil! keepp keepj 1,7s/\\vlast (modified|change):?\\zs.*/ " .. time .. "/ei")
        require("notify")("Changed file header!")
    end
end

return M

-- vim.api.nvim_set_keymap('n', '<Leader>vs', '<Cmd>lua ReloadConfig()<CR>', { silent = true, noremap = true })
-- vim.cmd('command! ReloadConfig lua ReloadConfig()')
Enter fullscreen mode Exit fullscreen mode

Flash cursorline

-- https://vi.stackexchange.com/questions/31206
-- Every time I jump to a new window my cursor flashes. First the function:
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()]]}
       -- keep cursor consistent with my st (terminal)
       { "VimLeave", "*", "lua vim.opt.guicursor='a:blinkwait700-blinkoff400-blinkon250-Cursor/lCursor,n-v:hor20'"}

    };
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

Write a color picker using telescope

-- File: /home/sergio/.config/nvim/lua/colors.lua 
-- Last Change: Tue, 01 Feb 2022 08:09

-- This code comes from a series of 7 videos on how to use telescope pickers
-- to change colorschemes on neovim, here is the list:

-- video 1: https://youtu.be/vjKEKsQbQMU
-- video 2: https://youtu.be/2LSGlOgI9Cg
-- video 3: https://youtu.be/-SwYCH4Ht2g
-- video 5: https://youtu.be/Wq3wbplnxug
-- video 6: https://youtu.be/BMTXuY640dA
-- video 7: https://youtu.be/zA-VXoZ-Q8E

-- In order to mapp this function you have to map the command below:
-- :lua require('colors').choose_colors()
--
-- Modify the list of colors or uncomment the function that takes all possible colors

local M = {}

M.choose_colors = function()
    local actions = require "telescope.actions"
    local actions_state = require "telescope.actions.state"
    local pickers = require "telescope.pickers"
    local finders = require "telescope.finders"
    local sorters = require "telescope.sorters"
    local dropdown = require "telescope.themes".get_dropdown()

    function enter(prompt_bufnr)
        local selected = actions_state.get_selected_entry()
        local cmd = 'colorscheme ' .. selected[1]
        vim.cmd(cmd)
        actions.close(prompt_bufnr)
    end

    function next_color(prompt_bufnr)
        actions.move_selection_next(prompt_bufnr)
        local selected = actions_state.get_selected_entry()
        local cmd = 'colorscheme ' .. selected[1]
        vim.cmd(cmd)
    end

    function prev_color(prompt_bufnr)
        actions.move_selection_previous(prompt_bufnr)
        local selected = actions_state.get_selected_entry()
        local cmd = 'colorscheme ' .. selected[1]
        vim.cmd(cmd)
    end

    -- local colors = vim.fn.getcompletion("", "color")

    local opts = {

        finder = finders.new_table {"gruvbox", "nordfox", "nightfox", "monokai", "tokyonight"},
        -- finder = finders.new_table(colors),
        sorter = sorters.get_generic_fuzzy_sorter({}),

        attach_mappings = function(prompt_bufnr, map)
            map("i", "<CR>", enter)
            map("i", "<C-j>", next_color)
            map("i", "<C-k>", prev_color)
            return true
        end,

    }

    local colors = pickers.new(dropdown, opts)

    colors:find()
end

return M
Enter fullscreen mode Exit fullscreen mode

References:

Top comments (1)

Collapse
 
voyeg3r profile image
Sérgio Araújo

A function to make your clipboard blockwise, this will allow you paste text not bellow the current one but on its side:

M.blockwise_clipboard = function()
    vim.cmd("call setreg('+', @+, 'b')")
    -- print('set + reg: blockwise!')
    pcall(require("notify")('set + reg: blockwise!'))
end
Enter fullscreen mode Exit fullscreen mode

Advice For Junior Developers

Advice from a career of 15+ years for new and beginner developers just getting started on their journey.