DEV Community

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

Posted on • Updated on

My lazy neovim config

Intro

The lazy nvim plugin manager caught my attention because everybody says it is incredibly fast.

As someone who likes innovation and challenges I have created a new repo for this new nvim config:

The backup part could be avoided or not needed if you use the tip about runtimepath in the next section.

mv ~/.config/nvim{,-backup} 
git clone https://sergio@bitbucket.org/sergio/mylazy-nvim.git ~/.config.nvim
Enter fullscreen mode Exit fullscreen mode

python env

# my neovim config uses a python virtual environment
# The line bellow is in my ~/.zshenv file
[ ! -d ~/.virtualenvs/neovim ] && python -m ~/.virtualenvs/neovim
Enter fullscreen mode Exit fullscreen mode

in your options.lua:

-- main editor configs
vim.g.python3_host_prog = vim.loop.os_homedir() .. "/.virtualenvs/neovim/bin/python"
Enter fullscreen mode Exit fullscreen mode

The structure

 ~/.config/nvim
    ├── README.md
    ├── after
    │   └── ftplugin
    ├── init.lua
    ├── lazy-lock.json
    └── lua
        ├── core       -->    options, some keymaps, bootstrap
        └── plugins

Enter fullscreen mode Exit fullscreen mode

Installing in a different path so you can keep your regular nvim without worring so mutch.

The neovim developpers ended up creating an environment variable to deal with "runtimepath":

# you can also clone to another place and keep 
# another vim configuration
alias lv='(){(export NVIM_APPNAME=lv;export MYVIMRC=~/.config/lv/init.lua;nvim)}'
Enter fullscreen mode Exit fullscreen mode

In my case I have another vim config whit no plugins

# https://gitlab.com/linuxdabbler/dotfiles/.config/nvim
# ln -sfvn ~/.dotfiles/vinone ~/.config
if [[ -d "$HOME/.config/vinone" ]]; then
    [[ ! `readlink "$HOME/.config/vinone"` =~ '.*dotfiles.vinone$' ]] && ln -sfvn ~/.dotfiles/vinone ~/.config
    alias vinone='(){(export NVIM_APPNAME=vinone;export MYVIMRC=~/.config/vinone/init.lua;nvim $@)}'
else
    alias vinone="nvim -u NONE -U NONE -N -i NONE -c 'set mouse=a| syntax on| set nu'"
fi
Enter fullscreen mode Exit fullscreen mode
git clone https://sergio@bitbucket.org/sergio/mylazy-nvim.git ~/.config/lv
Enter fullscreen mode Exit fullscreen mode

Every time you want to load this version you should use the lv alias.

Issues:

For now I have a huge problem, I cannot install clangd because my voidlinux(musl).

Some mappings still need to be fixed bu it works.
I will come back on this article latter to continue with the documentation.

Bootstrap

The bootstrap file ensures I are going to have the lazy.nvim installed properly ~/.config/nvim/lua/core/bootstrap.lua

-- Install lazy.nvim automatically
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
    vim.fn.system {
        'git',
        'clone',
        '--filter=blob:none',
        'https://github.com/folke/lazy.nvim.git',
        '--branch=stable', -- latest stable release
        lazypath,
    }
end
vim.opt.rtp:prepend(lazypath)

local opts = {
    git = { log = { '--since=3 days ago' } },
    ui = { custom_keys = { false } },
    install = { colorscheme = { 'tokyonight' } },
    performance = {
        rtp = {
            disabled_plugins = {
                'gzip',
                'netrwPlugin',
                'tarPlugin',
                'tohtml',
                'tutor',
                'zipPlugin',
                'rplugin',
                'editorconfig',
                'matchparen',
                'matchit',
            },
        },
    },
checker = { enabled = false },
}

-- Load the plugins and options
require('lazy').setup('plugins', opts)
Enter fullscreen mode Exit fullscreen mode

options

-- Filename: options.lua
-- Last Change: Tue, 11 Jul 2023 - 16:23

local opt = vim.opt
local g = vim.g

-- IMPROVE NEOVIM STARTUP
-- https://github.com/editorconfig/editorconfig-vim/issues/50
-- vim.g.loaded_python_provier = 0
-- vim.g.loaded_python3_provider = 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
-- 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
vim.g.python3_host_prog = vim.loop.os_homedir() .. "/.virtualenvs/neovim/bin/python3"

local options = {
  modelines = 5,
  modelineexpr = false,
  modeline = true,
  cursorline = true,
  cursorcolumn = false,
  splitright = true,
  splitbelow = true,
  smartcase = true,
  hlsearch = true,
  ignorecase = true,
  incsearch = true,
  inccommand = "nosplit",
  hidden = true,
  autoindent = true,
  termguicolors = true,
  showmode = false,
  showmatch = true,
  matchtime = 2,
  wildmode = "longest:full,full",
  number = true,
  linebreak = true,
  joinspaces = false,
  timeoutlen = 500,
  ttimeoutlen = 10, -- https://vi.stackexchange.com/a/4471/7339
  path = vim.opt.path + "**",
  autochdir = true,
  relativenumber = true,
  numberwidth = 2,
  expandtab = true,
  smarttab = true,
  smartindent = true,
  shiftround = true,
  shiftwidth = 2,
  tabstop = 2,
  foldenable = false,
  foldlevel = 99,
  foldlevelstart = 99,
  foldcolumn = '1',
  undofile = true,
  showtabline = 0,
  mouse = 'a',
  scrolloff = 3,
  sidescrolloff = 3,
  wrap = true,
  list = true,
  --lazyredraw = true,
  updatetime = 250,
  laststatus = 3,
  confirm = false,
  conceallevel = 3,
  cmdheight = 0,
  -- filetype = 'on', -- handled by filetypefiletype = 'on' --lugin
}

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

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

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

utils

-- Fname: /home/sergio/.config/nvim/lua/utils.lua
-- Last Change: Wed, 01 Jun 2022 08:19
-- https://github.com/ibhagwan/nvim-lua/blob/main/lua/utils.lua

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

function _G.reload(package)
  package.loaded[package] = nil
  return require(package)
end

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

M.toggle_quicklist = function()
  if fn.empty(fn.filter(fn.getwininfo(), 'v:val.quickfix')) == 1 then
    vim.cmd('copen')
  else
    vim.cmd('cclose')
  end
end

M.blockwise_clipboard = function()
  vim.cmd("call setreg('+', @+, 'b')")
  print('set + reg: blockwise!')
end

---- The function  below still does not work but I will keep it
-- M.toggle_boolean_value_on_line = function()
--   local values = {
--     ["true"] = "false",
--     ["false"] = "true",
--     ["on"] = "off",
--     ["off"] = "on",
--     ["yes"] = "no",
--     ["no"] = "yes",
--     ["1"] = "0",
--     ["0"] = "1",
--     ["enable"] = "disable",
--     ["disable"] = "enable",
--     ["enabled"] = "disabled",
--     ["disabled"] = "enabled",
--     ["before"] = "after",
--     ["after"] = "before",
--     ["first"] = "last",
--     ["last"] = "first",
--     ["up"] = "down",
--     ["down"] = "up",
--   }
--
--   local function toggle_bool_value(word)
--     local toggleWord = values[word:sub(1, -2)]
--     if toggleWord == nil then
--       -- Check if the word ends with a comma
--       local wordWithoutComma = word:match("^(.-),$")
--       if wordWithoutComma and values[wordWithoutComma] then
--         return values[wordWithoutComma] .. ","
--       end
--       return word
--     end
--     return toggleWord
--   end
--
--   local current_line = vim.api.nvim_get_current_line()
--   local indent = current_line:match("^%s*") -- Get the leading whitespace
--   local line_words = {}
--   local bool_count = 0
--
--   for word in current_line:gmatch("[%w_'\"]+(?:=|,)?[%w_'\"]+") do
--     if values[word:sub(1, -2)] ~= nil then
--       bool_count = bool_count + 1
--     end
--     table.insert(line_words, word)
--   end
--
--   local cursor_word = vim.fn.expand("<cword>")
--
--   if bool_count == 1 then
--     for i, word in ipairs(line_words) do
--       if values[word:sub(1, -2)] ~= nil or word:match("^.+,$") then
--         line_words[i] = toggle_bool_value(word)
--       end
--     end
--   else
--     for i, word in ipairs(line_words) do
--       if word == cursor_word or word:match("^.+,$") then
--         line_words[i] = toggle_bool_value(word)
--         break
--       end
--     end
--   end
--
--   local new_line = indent .. table.concat(line_words, " ")
--   vim.api.nvim_replace_current_line(new_line)
-- end

-- vim.keymap.set("n", "<Leader>tb", toggle_boolean, {buffer = true})

-- source: https://www.reddit.com/r/neovim/comments/109018y/comment/j3vdaux/
M.list_snips = function()
  local ft_list = require("luasnip").available()[vim.o.filetype]
  local ft_snips = {}
  for _, item in pairs(ft_list) do
    ft_snips[item.trigger] = item.name
  end
  print(vim.inspect(ft_snips))
end

vim.api.nvim_create_user_command("SnipList", M.list_snips, {})

-- that's a false mistake
-- source: https://github.com/sagarrakshe/toggle-bool/blob/master/plugin/toggle_bool.py

-- https://www.reddit.com/r/vim/comments/p7xcpo/comment/h9nw69j/
--M.MarkdownHeaders = function()
--   local filename = vim.fn.expand("%")
--   local lines = vim.fn.getbufline('%', 0, '$')
--   local lines = vim.fn.map(lines, {index, value -> {"lnum": index + 1, "text": value, "filename": filename}})
--   local vim.fn.filter(lines, {_, value -> value.text =~# '^#\+ .*$'})
--   vim.cmd("call setqflist(lines)")
--   vim.cmd("copen")
--end
-- nmap <M-h> :cp<CR>
-- nmap <M-l> :cn<CR>

-- 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
  local current_word_number = vim.fn.searchcount({ maxcount = 1000, timeout = 500 }).current
  vim.fn.setreg("/", old_query) -- restore search register
  print( "[" .. current_word_number .. '/' .. wordcount .. "]" )
  -- 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("core.utils").toggle_transparency()<br>')

-- TODO: change colors forward and backward
M.toggle_colors = function()
  local current_color = vim.g.colors_name
  if current_color == "gruvbox" then
    -- gruvbox light is very cool
    vim.cmd("colorscheme dawnfox")
    vim.cmd("colo")
    vim.cmd("redraw")
  elseif current_color == "dawnfox" then
    vim.cmd("colorscheme catppuccin")
    vim.cmd("colo")
    vim.cmd("redraw")
  elseif current_color == "catppuccin" then
    vim.cmd("colorscheme material")
    vim.cmd("colo")
    vim.cmd("redraw")
  elseif current_color == "material" then
    vim.cmd("colorscheme rose-pine")
    vim.cmd("colo")
    vim.cmd("redraw")
  elseif current_color == "rose-pine" then
    vim.cmd("colorscheme nordfox")
    vim.cmd("colo")
    vim.cmd("redraw")
  elseif current_color == "nordfox" then
    vim.cmd("colorscheme monokai")
    vim.cmd("colo")
    vim.cmd("redraw")
  elseif current_color == "monokai" then
    vim.cmd("colorscheme tokyonight")
    vim.cmd("colo")
    vim.cmd("redraw")
  else
    --vim.g.tokyonight_transparent = true
    vim.cmd("colorscheme gruvbox")
    vim.cmd("colo")
    vim.cmd("redraw")
  end
end

-- https://vi.stackexchange.com/questions/31206
-- https://vi.stackexchange.com/a/36950/7339
M.flash_cursorline = function()
  local cursorline_state = lua print(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]])
    if cursorline_state == false then
      vim.opt.cursorline = false
    end
  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('core.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('core.utils').dosToUnix()]])

M.toggle_diagnostics = function()
  if vim.diagnostic.is_disabled() then
    vim.diagnostic.enable()
    vim.notify("Diagnostic enabled")
  else
    vim.diagnostic.disable()
    vim.notify("Diagnostic disabled")
  end
end

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/^\\s\\+$/\\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.reload_module = function(...)
  return require("plenary.reload").reload_module(...)
end

M.rerequire_module = function(name)
  M.reload_module(name)
  return require(name)
end

M.preserve = function(arguments)
  local arguments = string.format("keepjumps keeppatterns execute %q", arguments)
  local line, col = unpack(vim.api.nvim_win_get_cursor(0))
  vim.api.nvim_command(arguments)
  local lastline = vim.fn.line("$")
  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
  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

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", "catppuccin", "material", "rose-pine", "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)
      map("i", "<C-n>", next_color)
      map("i", "<C-p>", prev_color)
      return true
    end,

  }

  local colors = pickers.new(dropdown, opts)

  colors:find()
end

return M
Enter fullscreen mode Exit fullscreen mode

autocommands

-- ~/.config/nvim/lua/core/autocommands.lua
-- Mon, 10 Jul 2023 07:13:37

-- Define local variables
local augroup = vim.api.nvim_create_augroup
local autocmd = vim.api.nvim_create_autocmd

augroup('write_pre', { clear = true})
autocmd('BufWritePre', {
  callback = function()
    local cursor_pos = vim.fn.getpos('.')
    vim.cmd('%s/\\s\\+$//e')
    vim.fn.setpos('.', cursor_pos)
  end,
  group = 'write_pre',
  desc = "Remove trailing whitespaces",
})

-- Highlight text on yank
augroup('YankHighlight', { clear = true })
autocmd('TextYankPost', {
  group = 'YankHighlight',
  callback = function()
    vim.highlight.on_yank { higroup = 'IncSearch', timeout = '700' }
  end,
  desc = "Highlight yanked text",
})

-- -- augroup('auto_working_dir', { clear = true})
-- -- autocmd('BufEnter', {
-- --   pattern = "*",
-- --   group = "auto_working_dir",
-- --   command = "silent! lcd %:p:h",
-- --   desc = "Automatically sets working dir"
-- -- })
-- --
-- augroup("lsp_disable_diagnostic", { clear = true})
-- autocmd('BufEnter', {
--   group = 'lsp_disable_diagnostic',
--   pattern = "*",
--   command = "lua vim.diagnostic.disable()",
--   desc = "Disable diagnostic for a while"
-- })

augroup("MatchRedundantSpaces", { clear = true})
autocmd("InsertLeave", {
  pattern = "*",
  callback = function()
    vim.cmd([[highlight RedundantSpaces ctermbg=red guibg=red]])
    vim.cmd([[match RedundantSpaces /\s\+$/]])
  end,
  desc = "Higlight extra spaces",
})

augroup("clear_matches", { clear = true})
autocmd("InsertEnter", {
  pattern = "*",
  callback = function()
    vim.cmd([[call clearmatches()]])
    vim.cmd([[highlight RedundantSpaces ctermbg=red guibg=red]])
  end,
  desc = "Do not show extra spaces during typing",
})

augroup('yankpost', { clear = true })
autocmd({ "VimEnter", "CursorMoved" }, {
  group = 'yankpost',
  pattern = "*",
  callback = function()
    cursor_pos = vim.fn.getpos('.')
  end,
  desc = "Stores cursor position",
})

autocmd("TextYankPost", {
  pattern = "*",
  group = 'yankpost',
  callback = function()
    if vim.v.event.operator == 'y' then
      vim.fn.setpos('.', cursor_pos)
    end
  end,
})

-- Automatically rebalance windows on vim resize
autocmd('VimResized', {
  callback = function()
    vim.cmd('tabdo wincmd =')
  end,
  desc = "Auto resize windows when size changes",
})

-- -- Never insert line as a comment when using 'o' to enter insert mode
-- autocmd('BufWinEnter', {
--   callback = function()
--     vim.cmd('setlocal formatoptions-=o')
--   end,
-- })

-- Close man and help with just <q>
autocmd('FileType', {
  pattern = {
    'help',
    'man',
    'lspinfo',
    'checkhealth',
  },
  callback = function(event)
    vim.bo[event.buf].buflisted = false
    vim.keymap.set('n', 'q', '<cmd>q<cr>', { buffer = event.buf, silent = true })
  end,
})

-- Auto create dir when saving a file where some intermediate directory does not exist
autocmd('BufWritePre', {
  group = 'write_pre',
  callback = function(event)
    if event.match:match('^%w%w+://') then
      return
    end
    local file = vim.loop.fs_realpath(event.match) or event.match
    vim.fn.mkdir(vim.fn.fnamemodify(file, ':p:h'), 'p')
  end,
})

-- Check for spelling in text filetypes and enable wrapping, and set gj and gk keymaps
autocmd('FileType', {
  pattern = {
    'gitcommit',
    'markdown',
    'text',
  },
  callback = function()
    local opts = { noremap = true, silent = true }
    vim.opt_local.spell = true
    vim.opt_local.wrap = true
    vim.api.nvim_buf_set_keymap(0, 'n', 'j', 'gj', opts)
    vim.api.nvim_buf_set_keymap(0, 'n', 'k', 'gk', opts)
  end,
})

-- Go to the last loc when opening a buffer
augroup('bufcheck', { clear = true })
autocmd('BufReadPost', {
  group = 'bufcheck',
  callback = function()
    local exclude = { "gitcommit" }
    local buf = vim.api.nvim_get_current_buf()
    if vim.tbl_contains(exclude, vim.bo[buf].filetype) then
      return
    end
    local mark = vim.api.nvim_buf_get_mark(0, '"')
    local lcount = vim.api.nvim_buf_line_count(0)
    if mark[1] > 0 and mark[1] <= lcount then
      pcall(vim.api.nvim_win_set_cursor, 0, mark)
    end
  end,
})

-- Check if the file needs to be reloaded when it's changed
augroup('userconf', {clear = true})
autocmd({ 'FocusGained', 'TermClose', 'TermLeave' }, {
  command = 'checktime',
  group = 'userconf',
})

-- Toggle relative numbers based on certain events
augroup('GainFocus', { clear = true })
autocmd({ 'BufEnter', 'FocusGained', 'InsertLeave', 'CmdlineLeave', 'WinEnter' }, {
  pattern = '*',
  group = 'GainFocus',
  callback = function()
    if vim.o.nu and vim.api.nvim_get_mode().mode ~= 'i' then
      vim.opt.relativenumber = true
    end
  end,
})

autocmd({ 'BufLeave', 'FocusLost', 'InsertEnter', 'CmdlineEnter', 'WinLeave' }, {
  pattern = '*',
  group = 'GainFocus',
  callback = function()
    if vim.o.nu then
      vim.opt.relativenumber = false
      vim.cmd('redraw')
    end
  end,
})

-- Set cmdheight to 1 when recording, and put it back to normal when it stops
augroup('record_action', { clear = true })
autocmd('RecordingEnter', {
  callback = function()
    vim.opt_local.cmdheight = 1
  end,
  group = 'record_action',
})

autocmd('RecordingLeave', {
  callback = function()
    vim.opt_local.cmdheight = 0
  end,
  group = 'record_action',
})
Enter fullscreen mode Exit fullscreen mode

commands

-- Filename: /home/sergio/.config/nvim/lua/core/commands.lua
-- Last Change: Fri, 09 Dec 2022 - 19:18
-- vim:set ft=lua nolist softtabstop=2 shiftwidth=2 tabstop=2 expandtab:

-- commands and abbreviations
vim.api.nvim_create_user_command('ClearBuffer', 'enew | bd! #', { nargs = 0, bang = true})
vim.api.nvim_create_user_command('CopyUrl', 'let @+=expand("<cfile>")', { nargs = 0, bang = true})
vim.api.nvim_create_user_command('HarponDel', ':lua require("harpoon.mark").rm_file()', { nargs = 0, bang = true})
vim.api.nvim_create_user_command('BlockwiseZero', ':lua require("core.utils").blockwise_register("0")<CR>', { nargs = '?', bang = false})
vim.api.nvim_create_user_command('BlockwisePlus', ':lua require("core.utils").blockwise_register("+")<CR>', { nargs = '?', bang = false})
vim.api.nvim_create_user_command('BlockwisePrimary', ':lua require("core.utils").blockwise_register("*")<CR>', { nargs = '?', bang = false})
vim.cmd([[cnoreab Bz BlockwiseZero]])
vim.cmd([[cnoreab B+ BlockwisePlus]])
vim.cmd([[cnoreab B* BlockwisePrimary]])

vim.api.nvim_create_user_command("OpenGithubRepo", function(_)
  local ghpath = vim.api.nvim_eval("shellescape(expand('<cfile>'))")
  local formatpath = ghpath:sub(2, #ghpath - 1)
  local repourl = "https://www.github.com/" .. formatpath
  vim.fn.system({ "xdg-open", repourl })
end, {
desc = "Open Github Repo",
force = true,
})

vim.cmd([[command! Dos2unix lua require('core.utils').dosToUnix()]])

vim.cmd([[cnoreab Cb ClearBuffer]])
vim.cmd([[cabbrev vb vert sb]]) --vertical split buffer :vb <buffer>
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([[highlight MinhasNotas ctermbg=Yellow ctermfg=red guibg=Yellow guifg=red]])
vim.cmd([[match MinhasNotas /NOTE:/]])

-- vim.cmd([[command! BufOnly lua require('core.utils').preserve("silent! %bd|e#|bd#")]])
vim.api.nvim_create_user_command('BufOnly',function()
  pcall(function()
    -- vim.fn.Preserve("exec '%bd|e#|bd#'")
    require('core.utils').preserve("silent! up|%bd|e#|bd#")
  end)
end,{})

vim.cmd([[cnoreab Bo BufOnly]])
vim.cmd([[cnoreab W w]])
vim.cmd([[cnoreab W! w!]])
vim.cmd([[command! CloneBuffer new | 0put =getbufline('#',1,'$')]])
vim.api.nvim_create_user_command('CloneBuffer', "new | 0put =getbufline('#',', '$')", { nargs = 0, bang = true} )
-- 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
-- vim.cmd([[command! Blockwise lua require('core.utils').blockwise_clipboard()]])
vim.api.nvim_create_user_command('Blockwise', function()
  require'core.utils'.blockwise_clipboard()
end,
{ desc = "Make + register blockwise", nargs = 0, bang = true}
)
vim.cmd([[cnoreab Bw Blockwise]])

-- Use ':Grep' or ':LGrep' to grep into quickfix|loclist
-- without output or jumping to first match
-- Use ':Grep <pattern> %' to search only current file
-- Use ':Grep <pattern> %:h' to search the current file dir
vim.cmd("command! -nargs=+ -complete=file Grep noautocmd grep! <args> | redraw! | copen")
vim.cmd("command! -nargs=+ -complete=file LGrep noautocmd lgrep! <args> | redraw! | lopen")

-- 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()')
vim.cmd('command! ReloadConfig lua require("core.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('inoreabbrev Fname <c-r>=expand("%:p")<cr>')
vim.cmd('inoreabbrev Iname <c-r>=expand("%:p")<cr>')
vim.cmd('inoreabbrev fname <c-r>=expand("%:t")<cr>')
vim.cmd('inoreabbrev iname <c-r>=expand("%:t")<cr>')

vim.cmd('inoreabbrev idate <c-r>=strftime("%a, %d %b %Y %T")<cr>')
vim.cmd([[cnoreab cls Cls]])

vim.api.nvim_create_user_command("BiPolar", function(_)
  local moods_table = {
    ["true"] = "false",
    ["false"] = "true",
    ["on"] = "off",
    ["off"] = "on",
    ["Up"] = "Down",
    ["Down"] = "Up",
    ["up"] = "down",
    ["down"] = "up",
    ["enable"] = "disable",
    ["disable"] = "enable",
    ["no"] = "yes",
    ["yes"] = "no",
  }
  local cursor_word = vim.api.nvim_eval("expand('<cword>')")
  if moods_table[cursor_word] then
    vim.cmd("normal ciw" .. moods_table[cursor_word] .. "")
  end
end, { desc = "Switch Moody Words", force = true })
Enter fullscreen mode Exit fullscreen mode

keymaps

-- Filename: keymaps.lua
-- Last Change: Tue, 11 Jul 2023 - 16:00

local map = require('core.utils').map

-- Set space as my leader key
map('', '<Space>', '<Nop>')
vim.g.mapleader = ' '
vim.g.maplocalleader = ' '

--{ silent = false, noremap = true, desc = 'toggles diagnostic'})
map("n", "<leader>l", "<cmd>Lazy<cr>", { desc = "Lazy" })

map('n',  'gl',  '`.', { desc = "Jump to the last changeoint" })

map('n',  '>',  '>>', { desc = "faster indent unindent" } )
map('n',  '<',  '<<', { desc = "faster indent unindent" } )
map("v", "<", "<gv" , { desc = "Reselect after < on visual mode" } )
map("v", ">", ">gv" , { desc = "Reselect after > on visual mode" } )

map('n', '<leader>d', '<cmd>lua require("core.utils").toggle_diagnostics()<cr>', { desc = 'enable/disable diagnostcs', silent = true })

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

map("n", "Y", "yg_", { desc = "Copy until the end of line"})

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

-- Line bubbling
-- Move selected line / block of text in visual mode
map("x", "K", ":move '<-2<CR>gv-gv", { noremap = true, silent = true })
map("x", "J", ":move '>+1<CR>gv-gv", { noremap = true, silent = true })

map("n", "'", "`")
map("n", "`", "'")

map('n', '<m-d>', '<cmd>lua require("core.utils").squeeze_blank_lines()<cr>' , { desc = "remove consecutive blank lines"})

-- empty lines go to black hole register
vim.keymap.set('n', 'dd', function()
  if vim.api.nvim_get_current_line():match('^%s*$') then
    vim.api.nvim_feedkeys('"_dd', 'n', false)
  else
    vim.api.nvim_feedkeys('dd', 'n', false)
  end
end)

vim.keymap.set('n', '<M-5>', function ()
-- https://stackoverflow.com/a/47074633
-- https://codereview.stackexchange.com/a/282183

  local results = {}
  local buffers = vim.api.nvim_list_bufs()

  for _, buffer in ipairs(buffers) do
    if vim.api.nvim_buf_is_loaded(buffer) then
      local filename = vim.api.nvim_buf_get_name(buffer)
      if filename ~= "" then
        table.insert(results, filename)
      end
    end
  end
  curr_buf = vim.api.nvim_buf_get_name(0)
  if (#results > 1 or curr_buf == "") then
    vim.cmd("bd")
  else
    vim.cmd("quit")
  end
end, { silent = false, desc = "bd or quit"})

-- alternate file mapping (add silent true)
map('n', '<bs>',
    [[:<c-u>exe v:count ? v:count . 'b' : 'b' . (bufloaded(0) ? '#' : 'n')<cr>]],
    { silent = true, noremap = true } )

map('n', '<cr>', 'gf', { desc = 'Open file under cursor'})

map("n", "<M-,>", "<cmd>BufferLineCyclePrev<cr>", { desc = "Prev buffer" })
map("n", "<M-.>", "<cmd>BufferLineCycleNext<cr>", { desc = "Next buffer" })

-- line text-objects
-- https://vimrcfu.com/snippet/269
map('o', 'al', [[v:count==0 ? ":<c-u>normal! 0V$h<cr>" : ":<c-u>normal! V" . (v:count) . "jk<cr>" ]],  { expr = true } )
map('v', 'al', [[v:count==0 ? ":<c-u>normal! 0V$h<cr>" : ":<c-u>normal! V" . (v:count) . "jk<cr>" ]],  { expr = true } )
map('o', 'il', [[v:count==0 ? ":<c-u>normal! ^vg_<cr>" : ":<c-u>normal! ^v" . (v:count) . "jkg_<cr>"]], { expr = true })
map('v', 'il', [[v:count==0 ? ":<c-u>normal! ^vg_<cr>" : ":<c-u>normal! ^v" . (v:count) . "jkg_<cr>"]], { expr = true })

-- cnoremap <expr> <c-n> wildmenumode() ? "\<c-n>" : "\<down>"
-- cnoremap <expr> <c-p> wildmenumode() ? "\<c-p>" : "\<up>"
map('c', '<c-n>', [[wildmenumode() ? "\<c-n>" : "\<down>"]], { expr = true} )
map('c', '<c-p>', [[wildmenumode() ? "\<c-p>" : "\<up>"]], { 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 })

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

map("n", "gl", "`.")
map("n", "gh", "<cmd>OpenGithubRepo<cr>", { desc = "Open github repo"})

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

map("i", "<C-r>+", "<C-r><C-o>+", { desc = 'Insert clipboard keeping indentation' })
map("i", "<S-Insert>", "<C-r><C-o>*", { desc = 'Insert clipboard keeping indentation' })
map("i", "<leader>+", "<C-r><C-o>+", { desc = 'Insert clipboard keeping indentation' })
map("i", "<S-Insert>", "<C-r><C-o>*", { desc = 'Insert clipboard keeping indentation' })

map('n', '<leader>p', '"+p' )
map('i', '<leader>p', '<c-r><c-o>+' )
map('v', '<leader>y', '"+y')

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', 'n', 'nzzzv')
-- map('n', 'N', 'Nzzzv')
map('n', 'n', 'n:lua require("neoscroll").zz(300)<cr>', { desc = "middle of screen"})
map('n', 'N', 'N:lua require("neoscroll").zz(300)<cr>', { desc = "middle of screen"})
map('n', '*', '*:lua require("core.utils").flash_cursorline()<CR><CR>')
map('n', '#', '#:lua require("core.utils").flash_cursorline()<CR><CR>')

map("n", "J", "mzJ`z")

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

map("c", "<C-a>", "<home>")
map("c", "<C-e>", "<end>")

map("n", "<F8>", [[<cmd>lua require("core.files").xdg_config()<cr>]], { silent = true })

-- -- Quit neovim
-- map('n', '<leader>Q', '<cmd>qa<CR>')
-- map('n', '<leader>q', '<cmd>q<CR>')

-- Quick write
map('n', '<leader>w', '<cmd>up<CR>', { silent = false, noremap = true, desc = 'save file'})
-- map('n', '<leader>d', '<cmd>bd<CR>')

map("n", "<M-o>", ':lua require("telescope.builtin").oldfiles()<cr>') -- already mapped on which-key
map("n", "<c-p>", [[<cmd>lua require("telescope.builtin").find_files{cwd = "~/.config/nvim"}<cr>]], { silent = true })
map("n", "<leader>b", [[<cmd>lua require('telescope.builtin').buffers()<cr>]], { silent = true })

-- Resize splits with arrow keys
map('n', '<C-Up>', '<cmd>resize +2<CR>')
map('n', '<C-Down>', '<cmd>resize -2<CR>')
map('n', '<C-Left>', '<cmd>vertical resize -2<CR>')
map('n', '<C-Right>', '<cmd>vertical resize +2<CR>')

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

map('n', '<leader>t', '<cmd>lua require("core.utils").toggle_boolean_value_on_line()<cr>',
{ desc = "toggle boolean on line"})

vim.keymap.set('n', '<leader>ll', function()
  return require('lazy').home()
end)
vim.keymap.set('n', '<leader>lu', function()
  return require('lazy').update()
end)
vim.keymap.set('n', '<leader>ls', function()
  return require('lazy').sync()
end)
vim.keymap.set('n', '<leader>lL', function()
  return require('lazy').log()
end)
vim.keymap.set('n', '<leader>lc', function()
  return require('lazy').clean()
end)
vim.keymap.set('n', '<leader>lp', function()
  return require('lazy').profile()
end)
Enter fullscreen mode Exit fullscreen mode

files (for telescope)

-- File: /home/sergio/.config/nvim/lua/files.lua
-- Last Change: Thu, 17 Mar 2022 15:05
-- https://github.com/nvim-telescope/telescope.nvim/wiki/Configuration-Recipes
-- https://youtu.be/Ua8FkgTL-94

local status_ok, telescope = pcall(require, "telescope")
if not status_ok then
  return
end

local M = {}

-- copied from https://github.com/nvim-telescope/telescope.nvim/wiki/Gallery
-- :Telescope find_files previewer=false theme=get_dropdown
local dropdown_theme = require('telescope.themes').get_dropdown({
  results_height = 20,
  -- winblend = 20;
  width = 0.6,
  prompt_title = '',
  prompt_prefix = 'Files> ',
  previewer = false,
  borderchars = {
    { '─', '│', '─', '│', '╭', '╮', '╯', '╰' },
    preview = { '─', '│', '─', '│', '╭', '╮', '╯', '╰' },
  },
})

-- searches files on ~/.config
M.xdg_config = function()
  require("telescope.builtin").find_files({
    prompt_title = "XDG-CONFIG",
    previewer = false,
    find_command={'fd','--no-ignore-vcs'},
    sorting_strategy = "ascending",
    file_ignore_patterns = { "lua-language-server", "chromium" },
    layout_config = { width = 0.7 },
    cwd = "~/.config",
    -- width = 0.6,
    layout_config = { height = 0.3 },
    layout_config = { width = 0.5 },
    results_height = 20,
    hidden = true,
    previewer = false,
    borderchars = {
      { '─', '│', '─', '│', '╭', '╮', '╯', '╰' },
      preview = { '─', '│', '─', '│', '╭', '╮', '╯', '╰' },
    },
  })
end
-- mapped to F8

-- searches opened buffers
M.buffers = function()
  require("telescope.builtin").buffers({
    prompt_title = "BUFFERS",
    sorting_strategy = "ascending",
    file_ignore_patterns = { "lua-language-server", "chromium" },
    -- cwd = "~/.config",
    previewer = false,
    layout_config = { height = 0.3 },
    layout_config = { width = 0.5 },
    hidden = true,
  })
end
-- mapped to <leader>b

M.nvim_files = function()
  require("telescope.builtin").find_files({
    prompt_title = "NVIM FILES",
    previewer = false,
    find_command={'fd','--no-ignore-vcs'},
    sorting_strategy = "ascending",
    file_ignore_patterns = { ".git" },
    cwd = "~/.config/nvim",
    hidden = true,
  })
end
-- mapped to <leader>n

-- searches on ~/.dotfiles
M.search_dotfiles = function()
  require("telescope.builtin").find_files({
    prompt_title = "DOTFILES",
    find_command={'fd','--no-ignore-vcs'},
    shorten_path = true,
    sorting_strategy = "ascending",
    cwd = vim.env.DOTFILES,
    hidden = true,
    previewer = false,
    layout_config = { height = 0.3 },
    layout_config = { width = 0.5 },
  })
end
-- mapped to Ctrl-p

-- searches on ~/.dotfiles
M.search_oldfiles = function()
  require("telescope.builtin").oldfiles({
    prompt_title = "OLDFILES",
    previewer = false,
    shorten_path = true,
    sorting_strategy = "ascending",
    -- cwd = vim.env.DOTFILES,
    hidden = true,
    layout_config = { height = 0.3 },
    layout_config = { width = 0.5 },
  })
end
-- mapped to Ctrl-Alt-o

-- searches on ~/.dotfiles
M.grep_dotfiles = function()
  require("telescope.builtin").live_grep({
    prompt_title = "GREP DOTFILES",
    shorten_path = true,
    sorting_strategy = "ascending",
    cwd = vim.env.DOTFILES,
    hidden = true,
  })
end
-- mapped to

M.grep_wiki = function()
  local opts = {}
  opts.hidden = true
  opts.search_dirs = {
    "~/.dotfiles/wiki",
  }
  opts.prompt_prefix = ">"
  opts.prompt_title = "Grep Wiki"
  opts.path_display = { "smart" }
  require("telescope.builtin").live_grep(opts)
end

return M
Enter fullscreen mode Exit fullscreen mode

init.lua

require('core.options')
require('core.keymaps')
require('core.autocommands')
require('core.bootstrap')
require('core.commands')
Enter fullscreen mode Exit fullscreen mode

Top comments (0)