My lazy neovim config
Tags: nvim, lua, dev, programming
Published: 2023-06-29 13:31:33

# [Intro](url)

The [lazy nvim plugin manager](https://github.com/folke/lazy.nvim.git) 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.

```sh
mv ~/.config/nvim{,-backup} 
git clone https://sergio@bitbucket.org/sergio/mylazy-nvim.git ~/.config.nvim
```

## python env

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

in your options.lua:

```lua
-- main editor configs
vim.g.python3_host_prog = vim.loop.os_homedir() .. "/.virtualenvs/neovim/bin/python"
```

## The structure

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

```

## 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":

```sh
# 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)}'
```

In my case I have another vim config whit no plugins

```sh
# 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
```

```sh
git clone https://sergio@bitbucket.org/sergio/mylazy-nvim.git ~/.config/lv
```

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`

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

## options

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

-- Compile lua to bytecode if the nvim version supports it.
-- https://github.com/armyers/NormalNvim
-- if vim.loader and vim.fn.has "nvim-0.9.1" == 1 then vim.loader.enable() end

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

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

vim.g.markdown_fenced_languages = {
  "html",
  "javascript",
  "typescript",
  "css",
  "scss",
  "lua",
  "vim",
  "sh",
}

vim.diagnostic.config {
  float = { border = "rounded" }, -- add border to diagnostic popups
}

local options = {
  --keywordprg = ':help',
  equalalways = true,
  winbar = '%=%m %F',
  nrformats = { "alpha", "octal", "hex" },
  virtualedit = "block",
  modelines = 5,
  modelineexpr = false,
  modeline = true,
  cursorline = false,
  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 + "**",
  isfname = vim.opt.isfname:append("@-@"),
  autochdir = true,
  relativenumber = true,
  numberwidth = 2,
  shada = "!,'50,<50,s10,h,r/tmp",
  expandtab = true,
  smarttab = true,
  smartindent = true,
  shiftround = true,
  shiftwidth = 2,
  tabstop = 2,
  foldenable = false,
  foldlevel = 99,
  foldlevelstart = 99,
  foldcolumn = '1',
  foldmethod = "expr",
  foldexpr = "nvim_treesitter#foldexpr()",
  undodir = os.getenv("HOME") .. "/.vim/undodir",
  undofile = true,
  showtabline = 0,
  mouse = 'a',
  mousescroll = "ver:2,hor:6",
  scrolloff = 3,
  sidescrolloff = 3,
  wrap = true,
  list = true,
  -- listchars = { leadmultispace = "│ ", multispace = "│ ", tab = "│ ", },
  --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

if vim.fn.has("nvim-0.10") == 1 then
  opt.smoothscroll = true
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 = false,
  foldenable = false,
}

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

## utils

```lua
-- 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 user_cmd = vim.api.nvim_create_user_command
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 = {}

-- Todo: test this function
M.is_loaded = function(plugin_name)
  return package.loaded["plugin_name"] ~= nil
  -- return require("lazy.core.config").plugins[plugin_name]._.loaded
end

--@ rturns true or false
M.is_recording = function()
  return vim.fn.reg_recording() ~= nil
end

-- @param name module
M.safeRequire = function(module)
  local success, loadedModule = pcall(require, module)
  if success then return loadedModule end
  print("Error loading " .. module)
end

-- toggle_autopairs() -- <leader>tp -- toggle autopairs
M.toggle_autopairs = function()
  local ok, autopairs = pcall(require, "nvim-autopairs")
  if ok then
    -- if autopairs.state.disabled then
    if MPairs.state.disabled then
      autopairs.enable()
      vim.notify("autopairs on")
    else
      autopairs.disable()
      vim.notify("autopairs off")
    end
  else
    vim.notifylrrr("autopairs not available")
  end
end

M.toggleInlayHints = function()
  vim.lsp.inlay_hint.enable(0, not vim.lsp.inlay_hint.is_enabled())
end

--that pressing `.` will repeat the action.
--Example: `vim.keymap.set('n', 'ct', dot_repeat(function() print(os.clock()) end), { expr = true })`
--Setting expr = true in the keymap is required for this function to make the keymap repeatable
--based on gist: https://gist.github.com/kylechui/a5c1258cd2d86755f97b10fc921315c3
M.dot_repeat = function(
  callback --[[Function]]
)
  return function()
    _G.dot_repeat_callback = callback
    vim.go.operatorfunc = 'v:lua.dot_repeat_callback'
    return 'g@l'
  end
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

-- 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)
  vim.keymap.set(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.toggle_spell = function()
  vim.wo.spell = not vim.wo.spell
end

M.ToggleConcealLevel = function()
  vim.o.conceallevel = (vim.o.conceallevel == 0) and 2 or 0
  vim.notify("ConcealLevel set to: " .. vim.o.conceallevel, vim.log.levels.INFO)
end

M.edit_snippets = function()
  local status_ok, luasnip = pcall(require, "luasnip")
  if status_ok then
    -- require("luasnip.loaders.from_lua").edit_snippet_files()
    require("luasnip.loaders").edit_snippet_files()
  end
end

M.toggle_background = function()
  local current_bg = vim.opt.background:get()
  vim.opt.background = (current_bg == 'light') and 'dark' or 'light'
end

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

-- this helps us paste a line from the clipboard that
-- has a new line
M.linewise_clipboard = function()
  vim.cmd("call setreg('+', @+, 'l')")
  print('set + reg: linewise!')
end

-- 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 ayu-mirage')
    vim.cmd('colo')
    vim.cmd('redraw')
  elseif current_color == 'ayu' then
    vim.cmd('colorscheme catppuccin')
    vim.cmd('colo')
    vim.cmd('redraw')
  elseif current_color == 'catppuccin-mocha' 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
  cursor_pos = vim.fn.getpos('.')
  vim.cmd([[hi CursorLine guifg=#FFFFFF guibg=#FF9509]])
  vim.fn.timer_start(200, function()
    vim.cmd([[hi CursorLine guifg=NONE guibg=NONE]])
    vim.fn.setpos('.', cursor_pos)
    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()]])

-- vim.diagnostic.goto_prev,
-- vim.diagnostic.open_float
-- vim.diagnostic.setloclist
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')
    vim.notify('Removed duplicated blank ines')
    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

M.is_executable = function()
  local file = vim.fn.expand("%:p")
  local type = vim.fn.getftype(file)
  if type == "file" then
    local perm = vim.fn.getfperm(file)
    if string.match(perm, 'x', 3) then
      return true
    else
      return false
    end
  end
end

M.increment = function(par, inc)
  return par + (inc or 1)
end

-- M.is_file = function()
--   local file = vim.fn.expand('<cfile>')
--   if vim.fs.isfile(file) == true then
--     return true
--   else
--     return 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
```

## autocommands

```lua
-- File: ~/.config/nvim/lua/hore/autocommands.lua
-- Last Change: Mon, 10 Jul 2023 07:13:37

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

-- rewrite all augroups using tis function
local function augroup(name)
  return vim.api.nvim_create_augroup('sergio-lazyvim_' .. name, { clear = true })
end

-- augroup('buf_empty', { clear = true })
autocmd({ 'BufEnter' }, {
  group = augroup('buf_enter'),
  pattern = { '' },
  callback = function()
    local buf_ft = vim.bo.filetype
    if buf_ft == '' or buf_ft == nil then
      vim.keymap.set('n', '<leader>q', '<cmd>close<cr>', { buffer = true, silent = true })
    end
  end,
})

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

autocmd('BufEnter', {
  group = augroup('lsp_disable_diagnostic'),
  pattern = '*',
  command = 'lua vim.diagnostic.disable()',
  desc = 'Disable diagnostic for a while',
})

-- augroup('formatonsave', { clear = true })
autocmd('BufWritePost', {
  group = augroup('formatonsave'),
  desc = 'Trigger format on save',
  pattern = { '*.lua', '*.py', '*.rb', '*.rs', '*.ts', '*.tsx', '*.sh', '*.md' },
  callback = function()
    vim.lsp.buf.format()
    vim.cmd('normal zz')
  end,
})

autocmd('VimLeave', {
  pattern = "*",
  group = augroup("WriteShada"),
  command = 'wshada',
  desc = "Save registers jumps marks and more",
})

-- autocmd('InsertLeave', {
--   pattern = '*',
--   group = augroup('MatchRedundantSpaces'),
--   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', {
--   group = augroup('clear_matches'),
--   pattern = '*',
--   callback = function()
--     vim.cmd([[call clearmatches()]])
--     vim.cmd([[highlight RedundantSpaces ctermbg=red guibg=red]])
--     vim.cmd([[set nohls]])
--   end,
--   desc = 'Do not show extra spaces during typing',
-- })

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

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

autocmd({ 'VimResized' }, {
  group = augroup('vimresized'),
  pattern = '*',
  callback = function()
    vim.schedule(function()
      vim.cmd('tabdo wincmd =')
    end)
  end,
  desc = 'wondows in equal size',
})

autocmd({ 'CursorHold' }, {
  group = augroup('start_luasnip'),
  callback = function()
    local status_ok, luasnip = pcall(require, 'luasnip')
    if not status_ok then
      return
    end
    if luasnip.expand_or_jumpable() then
      -- ask maintainer for option to make this silent
      -- luasnip.unlink_current()
      vim.cmd([[silent! lua require("luasnip").unlink_current()]])
    end
  end,
  desc = "Start luasnip"
})

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

autocmd('BufWritePre', {
  group = augroup('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,
  desc = "Create dir during file save",
})

-- Check for spelling in text filetypes and enable wrapping, and set gj and gk keymaps
autocmd('FileType', {
  group = augroup('set_wrap'),
  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,
})

autocmd('BufReadPost', {
  group = augroup('restore_position'),
  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)
      vim.api.nvim_feedkeys('zz', 'n', true)
    end
  end,
  desc = 'Go to the last loc when opening a buffer',
})

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

autocmd({
  'BufEnter',
  'FocusGained',
  'InsertLeave',
  'CmdlineLeave',
  'WinEnter',
}, {
  pattern = '*',
  group = augroup('EnableRelativenumber'),
  callback = function()
    if vim.o.nu and vim.api.nvim_get_mode().mode ~= "i" then
      vim.opt.relativenumber = true
    end
  end,
  desc = 'Enable relative number in normal mode'
})

autocmd({
    "BufLeave",
    'FocusLost',
    'InsertEnter',
    'CmdlineEnter',
    'WinLeave',
  },
  {
    pattern = '*',
    group = augroup('DisableRelativenumber'),
    callback = function()
      if vim.o.nu then
        vim.opt.relativenumber = false
        vim.cmd('redraw')
      end
    end,
    desc = 'Disable relative number in insert mode'
  })

autocmd('RecordingEnter', {
  group = augroup('record_action'),
  pattern = "*",
  command = 'lua vim.opt_local.cmdheight = 1',
  desc = "Show recording status",
})

autocmd('RecordingLeave', {
  group = augroup('record_leave'),
  pattern = "*",
  command = 'lua vim.opt_local.cmdheight = 0',
  desc = "Show recording status",
})

autocmd('BufWritePost', {
  group = augroup('make-executable'),
  pattern = { '*.sh', '*.zsh', '*.py' },
  -- command = [[!chmod +x %]],
  callback = function()
    local file = vim.fn.expand("%p")
    local status = require('core.utils').is_executable()
    if status ~= true then
      vim.fn.setfperm(file, "rwxr-x---")
    end
  end,
  desc = 'Make files ended with *.sh, *.py executable',
})
```

## commands

```lua
-- Filename: ~/.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:

local user_cmd = vim.api.nvim_create_user_command

user_cmd(
  'LspSignatre',
  'lua vim.lsp.buf.signature_help()',
  {
    nargs = '+',
  }
)

user_cmd(
  'LspHover',
  'lua vim.lsp.buf.hover()',
  {
    nargs = "+",
  }
)

user_cmd(
  'LineWiseClipboard',
  'lua require("core.utils").linewise_clipboard()',
  {
    nargs = 0,
  }
)

user_cmd(
  'BlokwiseClipboard',
  'lua require("core.utils").blockwise_clipboard()',
  {
    nargs = 0,
  }
)

-- vim.cmd("command! -nargs=1 SubstituteAndSet lua substituteAndSet(<f-args>)")

user_cmd(
  'RenameIdentifier',
  function() vim.lsp.buf.rename() end,
  { desc = 'Lsp rename' }
)

-- commands and abbreviations
user_cmd(
  'ClearBuffer',
  'enew | bd! #',
  {
    nargs = 0,
    bang = true,
  }
)
user_cmd(
  'CopyUrl',
  'let @+=expand("<cfile>")',
  { nargs = 0, bang = true }
)

user_cmd(
  'CopyBuffer',
  '%y+',
  { nargs = 0, bang = true }
)

user_cmd(
  'HarponDel',
  'lua require("harpoon.mark").rm_file()',
  {
    nargs = 0,
    bang = true,
  }
)

user_cmd(
  'BlockwiseZero',
  'lua require("core.utils").blockwise_register("0")<CR>',
  {
    nargs = '?',
    bang = false,
  }
)

user_cmd(
  'BlockwisePlus',
  'lua require("core.utils").blockwise_register("+")<CR>',
  {
    nargs = '?',
    bang = false,
  }
)

user_cmd(
  '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]])

user_cmd(
  'Dos2unix',
  'lua require("core.utils").dosToUnix()<CR>',
  {
    nargs = 0,
    bang = true,
    desc = 'Convert dos 2 unix'
  }
)

user_cmd(
  'ToggleBackground',
  'lua require("core.utils").toggle_background()<cr>',
  {
    nargs = 0,
  }
)

user_cmd(
  'SwitchColor',
  'lua require("core.utils").toggle_colors()<cr>',
  {
    nargs = 0,
    desc = 'Change color',
  }
)
-- lua require("core.utils").toggle_colors()

user_cmd(
  'TogglePairs',
  'lua require("core.utils").toggle_autopairs()<cr>',
  {
    nargs = 0,
    desc = 'Toggle autopairs',
  }
)

user_cmd(
  'ToggleSpell',
  'lua require("core.utils").toggle_spell()<cr>',
  {
    nargs = 0,
    desc = 'Toggle spell',
  }
)

user_cmd(
  'ToggleDiagnostics',
  function()
    require('core.utils').toggle_diagnostics()
  end,
  {
    desc = 'Toggle lsp diagnostic',
    nargs = 0,
    bang = true
  }
)

user_cmd(
  'Transparency',
  function()
    require('core.utils').toggle_transparency()
  end,
  {
    desc = 'Toggle transparency',
    nargs = 0,
    bang = true,
  }
)

user_cmd(
  'Wiki',
  'lua require("core.files").wiki()<CR>',
  {
    desc = 'Search on my wiki',
  }
)

user_cmd(
  "UpdateAll",
  function()
    vim.cmd([[TSUpdateSync]])
    vim.cmd([[MasonUpdate]])
  end,
  {
    desc = "Update treesitter and mason",
  }
)

user_cmd(
  "LuaSnipEdit",
  function()
    require("core.utils").edit_snippets()
  end,
  {
    desc = 'Edit your snippets',
  }
)

user_cmd(
  "Cor",
  "lua print(vim.g.colors_name)<cr>",
  {
    desc = "show current colorscheme",
  }
)

user_cmd(
  'SnipList',
  function()
    pcall(function()
      require('core.utils').list_snips()
    end)
  end,
  { desc = 'List avaiable snippets' }
)

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")]])

user_cmd(
  'Format',
  'lua vim.lsp.buf.format()<cr>',
  {
    desc = 'Format buffer',
    nargs = 0,
  }
)

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#")]])

user_cmd(
  'BufOnly',
  function()
    pcall(function()
      require('core.utils').preserve('silent! up|%bd|e#|bd#')
    end)
  end,
  { desc = 'Close every other buffer' }
)

vim.cmd([[cnoreab Bo BufOnly]])
vim.cmd([[cnoreab W w]])
vim.cmd([[cnoreab W! w!]])

-- vim.cmd([[command! CloneBuffer new | 0put =getbufline('#',1,'$')]])

user_cmd(
  '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

user_cmd(
  'Delblank',
  function()
    require('core.utils').squeeze_blank_lines()
  end,
  {
    desc = 'Squeeze blank lines',
    nargs = 0,
    bang = true,
  })

user_cmd(
  'Old',
  'Telescope oldfiles',
  {
    desc = 'List oldfiles (open)',
  }
)

user_cmd(
  '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]])

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

user_cmd(
  '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,
  })
```

## keymaps

```lua
-- Filename: ~/.config/nvim/lua/core/keymaps.lua
-- Last Change: Tue, 11 Jul 2023 - 16:00

local map = require('core.utils').map
local mapfile = " "

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

map(
  'n',
  '<c-k>',
  function()
    local word = vim.fn.expand("<cword>")
    vim.cmd('help ' .. word)
  end,
  {
    desc = mapfile .. 'help for current word',
  }
)

-- -- ref: https://ofirgall.github.io/learn-nvim/chapters/08-advanced-config.html
-- map(
--   'n',
--   '<c-k>',
--   function()
--     local ft = vim.api.nvim_buf_get_option(0, 'filetype')
--     if ft == 'man' then
--       vim.api.nvim_command(':Man ' .. vim.fn.expand('<cWORD>'))
--     elseif ft == 'help' then
--       vim.api.nvim_command(':help ' .. vim.fn.expand('<cword>'))
--     else
--       require('telescope.builtin').lsp_definitions()
--     end
--   end,
--   { desc = "Go to definition" }
-- )

-- https://codeberg.org/blau_araujo/vim-keys/issues/12

-- (neo)vim overrides mouse selection in terminals (so you don't end up copying line numbers and stuff) so you have to manually set this keybind up. one way is:
-- map('v', '<LeftRelease>', '"*ygv')

-- vim.keymap.set("n", "<Leader>c", [[:%s/<C-r><C-w>//g<Left><Left>]])

map(
  'n',
  '<leader>bu',
  function()
    vim.cmd('Cls') -- personal command
    vim.cmd('update')
  end,
  {
    desc = mapfile .. 'Buffer :update',
    silent = true,
  }
)

map(
  'n',
  '<c-s>',
  function()
    vim.cmd('Cls') -- personal command
    vim.cmd('update')
  end,
  {
    desc = mapfile .. 'Buffer :update',
    silent = true,
  }
)

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

-- map(
--   'n',
--   '<leader>bw',
--   ':bw!<cr>',
--   {
--     silent = true,
--     desc = 'Buffer wipe',
--   }
-- )

map(
  'n',
  '<leader>by',
  '<cmd>%y+<cr>',
  {
    desc = mapfile .. 'Buffer to clipboard',
    silent = true,
  }
)

map(
  'n',
  '<leader>bc',
  '<cmd>%d<cr>',
  { desc = mapfile .. 'Erase buffer content!' }
)

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

map(
  'v',
  '<',
  '<gv',
  {
    desc = mapfile .. 'Reselect after < on visual mode',
  })

map(
  'v',
  '>',
  '>gv',
  {
    desc = mapfile .. 'Reselect after > on visual mode'
  }
)

map(
  'n',
  '<leader>ud',
  '<cmd>ToggleDiagnostics<cr>',
  {
    desc = mapfile .. 'Toggle diagnostcs',
    silent = true,
  }
)

map(
  'n',
  '<leader>um',
  function()
    if package.loaded["noice.lua"] ~= nil then
      vim.cmd("Noice")
    else
      vim.cmd('messages')
    end
  end,
  {
    desc = mapfile .. 'Show messages',
    silent = true,
  }
)

map(
  'n',
  '<leader>ui',
  '<cmd>lua require("core.utils").toggleInlayHints<cr>',
  {
    desc = mapfile .. 'Toggle inlay hints',
    silent = true,
  }
)

map(
  'n',
  '<leader>cd',
  '<cmd>ToggleDiagnostics<cr>',
  {
    desc = mapfile .. 'Diagnostic toggle',
    silent = true,
  }
)

map(
  'n',
  '<leader>ce',
  vim.diagnostic.enable,
  {
    desc = mapfile .. 'Diagnostic enable',
    silent = true,
  }
)

map(
  'n',
  '<leader>uu',
  '<cmd>SwitchColor<cr>',
  {
    desc = mapfile .. 'Switch color',
    silent = true,
  }
)

map(
  'n',
  '<leader>cf',
  vim.diagnostic.open_float,
  {
    desc = mapfile .. 'Diagnostic open float',
    silent = true,
  }
)

map(
  'n',
  '<leader>cn',
  vim.diagnostic.goto_next,
  {
    desc = mapfile .. 'Diagnostic next',
    silent = true,
  }
)

map(
  'n',
  '<leader>cp',
  vim.diagnostic.goto_prev,
  {
    desc = mapfile .. 'Diagnostic prev',
    silent = true,
  }
)

map(
  'n',
  '<leader>cl',
  vim.diagnostic.setloclist,
  {
    desc = mapfile .. 'Diagnostic list',
    silent = true,
  }
)

map(
  'n',
  '<leader>bs',
  '<cmd>Delblank<cr>',
  {
    desc = mapfile .. 'Squeeze blank lines',
  }
)

-- map(
--   'n',
--   '<leader>sw',
--   function()
--     vim.cmd('NoiseDisable')
--     vim.cmd('%s/<C-r><C-w>//g<Left><Left>')
--     vim.cmd('NoiseEnable')
--   end,
--   { desc = 'Substitute current word', silent = true }
-- )

map(
  "n",
  "<leader>nl",
  function()
    require("noice").cmd("last")
  end,
  {
    desc = mapfile .. 'Show last noice message',
  }
)

-- map(
--   'n',
--   '<leader>a',
--   '<cmd>Alpha<cr>',
--   {
--     desc =  mapfile .. 'Show alpha',
--     silent = true,
--   }
-- )

map(
  'n',
  '<m-s>',
  '<cmd>Delblank<cr>',
  {
    desc = mapfile .. 'Squeeze blank lines',
  }
)

map(
  'n',
  '[q',
  ':cprevious<CR>',
  {
    desc = mapfile .. "Jump to the previous quickfix",
  }
)

map(
  'n',
  ']q',
  ':cnext<CR>',
  {
    desc = mapfile .. "Next quickfix"
  }
)

map(
  'n',
  ']Q',
  ':clast<CR>',
  {
    desc = mapfile .. "Last quickfix"
  }
)

map(
  'n',
  '[Q',
  ':cfirst<CR>',
  {
    desc = mapfile .. "First quickfix"
  }
)

map(
  'n',
  '[b',
  ':bprevious<CR>',
  {
    desc = mapfile .. 'Next buffer',
  }
)

map(
  'n',
  ']b',
  ':bnext<CR>',
  {
    desc = mapfile .. 'Prev buffer',
  }
)

map(
  'n',
  ']l',
  ':lnext<cr>',
  {
    silent = true,
    desc = mapfile .. 'Next loclist'
  }
)

map(
  'n',
  '[l',
  ':lprev<cr>',
  {
    silent = true,
    desc = mapfile .. 'Previous loclist'
  }
)

map(
  'n',
  '<leader>bn',
  ':bnext<CR>',
  {
    desc = mapfile .. 'Next buffer',
  }
)

map(
  'n',
  '<leader>bp',
  ':bprevious<CR>',
  {
    desc = mapfile .. 'Previous buffer',
  }
)

map(
  'n',
  '<leader>br',
  function()
    return require('telescope.builtin').oldfiles()
  end,
  {
    desc = mapfile .. 'Recent files',
    silent = true,
  }
)

map(
  'n',
  '<leader>nd',
  function()
    return require('core.files').search_dotfiles()
  end,
  {
    desc = mapfile .. 'Search dotfiles',
    silent = true,
  }
)

map(
  'n',
  '<leader>cb',
  '<cmd>BiPolar<cr>',
  {
    desc = mapfile .. 'Toggle boolean',
    silent = true,
  }
)

map(
  'n',
  'Y',
  'yg_',
  {
    desc = mapfile .. '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 = mapfile .. 'Repeat normal command in visual' }
)

map( -- Line bubbling
  'x',
  'K',
  ":move '<-2<CR>gv-gv",
  {
    noremap = true,
    silent = true,
    desc = mapfile .. 'Up visual line',
  }
)

map(
  'x',
  'J',
  ":move '>+1<CR>gv-gv",
  {
    noremap = true,
    silent = true,
    desc = mapfile .. 'Down visual line',
  }
)

map(
  'n',
  '<leader>cr',
  '<cmd>lua vim.lsp.buf.rename()<cr>',
  {
    desc = mapfile .. 'LSP identifier rename',
  }
)

map(
  'n',
  'dd',
  function()
    local empty_line = vim.api.nvim_get_current_line():match('^%s*$')
    return (empty_line and '"_dd' or 'dd')
  end,
  {
    expr = true,
    desc = mapfile .. "delete blank lines to black hole register",
  }
)

map(
  'n',
  '<leader>x',
  '<cmd>bd<CR>',
  { desc = mapfile .. 'Delete buffer' }
)

-- vim.keymap.set('n', '<leader>x', 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('Bdelete')
--   else
--     vim.cmd('quit')
--   end
-- end, { silent = false, desc = 'bd or quit' })

map(
  'n',
  '<bs>',
  '<c-^>\'"zz',
  {
    silent = true,
    noremap = true,
    desc = 'Jump to alternate buffer',
  }
)

map(
  'n',
  '<leader>un',
  '<cmd>let [&nu, &rnu] = [!&rnu, &nu+&rnu==1]<cr>',
  { desc = 'Toggle number and relative number' }
)

-- 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,
    desc = mapfile .. 'Operstor pending a line',
  }
)

map(
  'v',
  'al',
  [[v:count==0 ? ":<c-u>normal! 0V$h<cr>" : ":<c-u>normal! V" . (v:count) . "jk<cr>" ]],
  {
    expr = true,
    desc = mapfile .. 'Visual a line',
  }
)

map(
  'o',
  'il',
  [[v:count==0 ? ":<c-u>normal! ^vg_<cr>" : ":<c-u>normal! ^v" . (v:count) . "jkg_<cr>"]],
  {
    expr = true,
    desc = mapfile .. 'Operstor pending inner line',
  }
)

map(
  'v',
  'il',
  [[v:count==0 ? ":<c-u>normal! ^vg_<cr>" : ":<c-u>normal! ^v" . (v:count) . "jkg_<cr>"]],
  {
    expr = true,
    desc = mapfile .. 'Visual inner line',
  }
)

-- cnoremap <expr> <c-n> wildmenumode() ? "\<c-n>" : "\<down>"
-- cnoremap <expr> <c-p> wildmenumode() ? "\<c-p>" : "\<up>"
map(
  'c',
  '<c-j>',
  [[wildmenumode() ? "\<c-j>" : "\<down>"]],
  { expr = true }
)
map(
  'c',
  '<c-k>',
  [[wildmenumode() ? "\<c-k>" : "\<up>"]],
  { expr = true }
)

map(
  'n',
  '<leader>uc',
  '<cmd>lua require("core.utils").ToggleConcealLevel()<cr>',
  { desc = mapfile .."Toggle conceal level" }
)

-- -- 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,
    desc = mapfile .. 'Add j jumps to the jumplist'
  }
)

map('n',
  'k',
  [[v:count ? (v:count > 5 ? "m'" . v:count : '') . 'k' : 'gk']],
  {
    expr = true,
    desc = mapfile .. 'Add k jumps to the jumplist'
  }
)

-- map(
--   'n',
--   '<leader>cd',
--   '<cmd> lua vim.diagnostic.open_float()<cr>',
--   { desc = 'Open diagnostic float' }
-- )

map(
  'n',
  '<Leader>nf',
  "<cmd>lua require('core.files').nvim_files()<CR>",
  { desc = mapfile .. 'Edit nvim files' }
)

map(
  'n',
  '<Leader>np',
  "<cmd>lua require('core.files').nvim_plugins()<CR>",
  { desc = mapfile .. 'Edit nvim plugins' }
)

map(
  'n',
  '<Leader>nc',
  "<cmd>lua require('core.files').nvim_core()<CR>",
  { desc = mapfile .. 'Edit nvim core' }
)

map(
  'n',
  '<leader>uC',
  "<cmd>lua require('core.colors').choose_colors()<cr>",
  { desc = mapfile .. 'Choose colorScheme' }
)

-- map(
--   'n',
--   '<leader>*',
--   '*<c-o>cgn',
--   { desc = 'Change cursor word' }
-- )
-- map(
--   'n',
--   '<leader>#',
--   '#<c-o>cgn',
--   { desc = 'Change cursor word' }
-- )

map(
  'n',
  'gl',
  '`.',
  { desc = mapfile .. 'Last change location' }
)

map(
  'n',
  '<leader>c=',
  '<cmd>Reindent<cr>',
  {
    desc = mapfile .. 'Code Reindent',
  }
)

map(
  'n',
  '<Leader>v',
  function()
    local myvimrc = vim.env.MYVIMRC
    vim.cmd('drop ' .. myvimrc)
  end,
  {
    desc = mapfile .. 'edit init.lua',
  }
)

map(
  'n',
  '<Leader>ze',
  function()
    local zshrc = vim.env.ZDOTDIR .. "/.zshrc"
    vim.cmd('drop ' .. zshrc)
  end,
  { desc = mapfile .. 'Edit zshrc' }
)

map( -- the actual command is defined in commands.
  'n',
  '<leader>us',
  '<cmd>ToggleSpell<cr>',
  {
    desc = mapfile .. 'Toggle spell',
  }
)

map(
  'n',
  '<Leader>za',
  function()
    local zshaliases = vim.env.ZDOTDIR .. "/zsh-aliases"
    vim.cmd('drop ' .. zshaliases)
  end,
  {
    desc = mapfile .. 'Edit zsh aliases',
  }
)

map(
  'n',
  '<Leader>zf',
  '<cmd>lua require("core.files").nvim_zshfiles()<CR>',
  {
    desc = mapfile .. 'Edit zsh files',
  }
)

map(
  'i',
  '<C-r>0',
  '<C-r><C-p>0',
  {
    desc = mapfile .. 'Insert 0 keeping indentation',
  }
)

map(
  'i',
  '<C-r>+',
  '<C-r><C-p>+',
  {
    desc = mapfile .. 'Insert clipboard keeping indentation',
  }
)

map(
  'i',
  '<C-r>*',
  '<C-r><C-o>*',
  {
    desc = mapfile .. 'Insert primary clipboard keeping indentation',
  }
)
map(
  'i',
  '<S-Insert>',
  '<C-r><C-o>*',
  {
    desc = mapfile .. 'Insert reg* keep inden',
  }
)
map(
  'i',
  '<leader>+',
  '<C-r><C-o>+',
  {
    desc = mapfile .. 'Insert reg+ keep indent',
  }
)

-- vim.keymap.set("n", "sx", "<cmd>lua require('substitute.exchange').operator({motion = 'iw'})<cr>", { noremap = true })
-- vim.keymap.set("n", "sxx", "<cmd>lua require('substitute.exchange').line<cr>", { noremap = true })
-- vim.keymap.set("x", "X", "<cmd>lua require('substitute.exchange').visual<cr>", { noremap = true })
-- vim.keymap.set("n", "sxc", "<cmd>lua require('substitute.exchange').cancel<cr>", { noremap = true })

map(
  'n',
  ']p',
  ':pu<cr>',
  {
    desc = 'Paste line bellow',
    silent = true,
  }
)

map(
  'n',
  '[p',
  ':pu!<cr>',
  {
    desc = mapfile .. 'Paste line bellow',
    silent = true,
  }
)

map(
  'n',
  '<leader>ub',
  '<cmd>ToggleBackground<cr>',
  {
    desc = mapfile .. "toggle backgroud",
  }
)

map(
  'n',
  '<M-p>',
  -- '"+gP',
  '"+]p',
  {
    desc = mapfile .. 'Paste clipboard',
  }
)

map(
  'v',
  '<M-p>',
  -- '"+gP',
  '"+]p',
  { desc = mapfile .. 'Paste clipboard' }
)

map(
  'i',
  '<M-p>',
  '<C-r><C-p>+',
  {
    desc = mapfile .. 'Paste clipboard',
  }
)

map(
  'v',
  '<leader>y',
  '"+y',
  {
    desc = mapfile .. 'Selection to clipboard',
  }
)

map(
  'n',
  '<leader>bo',
  '<cmd>BufOnly<cr>',
  {
    desc = mapfile .. 'Keep just current buffer',
    silent = true,
  }
)

map(
  'n',
  '<leader>cF',
  '<cmd>Format<cr>',
  {
    desc = mapfile .. 'Format buffer code',
  }
)

map(
  "x",
  "<leader>p",
  '"_dP',
  {
    desc = mapfile .. "Paste without losing buffer",
  }
)

map(
  'i',
  '.',
  '.<c-g>u',
  {
    desc = mapfile .. 'Dot Undo break',
  }
)
map(
  'i',
  '!',
  '!<c-g>u',
  { desc = mapfile .. 'Exclamation Undo break' }
)
map(
  'i',
  '?',
  '?<c-g>u',
  { desc = mapfile .. 'Undo break' }
)
map('i', ';', ';<c-g>u', {
  desc = mapfile .. 'Undo break',
})
map(
  'i',
  ':',
  ':<c-g>u',
  { desc = mapfile .. 'Undo break' }
)
map(
  'i',
  ']',
  ']<c-g>u',
  { desc = mapfile .. 'Undo break' }
)
map(
  'i',
  '}',
  '}<c-g>u',
  { desc = mapfile .. 'Undo break' }
)

-- -- Surround visual selection
-- vim.keymap.set('v', '(', 'c()<esc>P<right>%', { desc = "surround selection" })
-- vim.keymap.set('v', '[', 'c[]<esc>P<right>%', { desc = "surround selection" })
-- vim.keymap.set('v', '{', 'c{}<esc>P<right>%', { desc = "surround selection" })
-- vim.keymap.set('v', "'", "c''<esc>P<right>%", { desc = "surround selection" })
-- vim.keymap.set('v', '"', 'c""<esc>P<right>%', { desc = "surround selection" })

map(
  'n',
  '<c-e>',
  '3<c-e>',
  { desc = mapfile .. 'Faster scrolling' }
)

map(
  'n',
  '<c-y>',
  '3<c-y>',
  { desc = mapfile .. 'Faster scrolling' }
)

map(
  'n',
  'n',
  'n:lua require("core.utils").flash_cursorline()<CR><CR>'
)
map(
  'n',
  'N',
  'N:lua require("core.utils").flash_cursorline()<CR><CR>'
)
map(
  'n',
  'n',
  'n:lua require("neoscroll").zz(300)<cr>',
  { desc = mapfile .. "middle of screen" }
)
map(
  'n',
  'N',
  'N:lua require("neoscroll").zz(300)<cr>',
  { desc = "middle of screen" }
)

map(
  'n',
  '<tab>',
  '<cmd>bnext<cr>',
  {
    desc = mapfile .. 'Next buffer',
    silent = true,
  }
)

map(
  'n',
  '<s-tab>',
  '<cmd>bprevious<cr>',
  {
    desc = mapfile .. 'Next buffer',
    silent = true,
  }
)

-- map(
--   'n',
--   '*',
--   '*:lua require("core.utils").flash_cursorline()<CR><CR>'
-- )

-- map(
--   'n',
--   '#',
--   '#:lua require("core.utils").flash_cursorline()<CR><CR>'
-- )

-- map(
--   'n',
--   'n',
--   "n<cmd>lua require('core.utils').flash_cursorline()<cr><cr>",
--   { desc = 'center the next match', silent = true }
-- )
--
-- map(
--   'n',
--   'N',
--   "N<cmd>:lua require('core.utils').flash_cursorline()<cr><cr>",
--   { desc = 'center the next match', silent = true }
-- )

-- -- Consistent n/N search navigation
-- map('n', 'n', "'Nn'[v:searchforward]", { expr = true, desc = 'Next search result' })
-- map('x', 'n', "'Nn'[v:searchforward]", { expr = true, desc = 'Next search result' })
-- map('o', 'n', "'Nn'[v:searchforward]", { expr = true, desc = 'Next search result' })
-- map('n', 'N', "'nN'[v:searchforward]", { expr = true, desc = 'Prev search result' })
-- map('x', 'N', "'nN'[v:searchforward]", { expr = true, desc = 'Prev search result' })
-- map('o', 'N', "'nN'[v:searchforward]", { expr = true, desc = 'Prev search result' })

map(
  'n',
  'J',
  'mzJ`z',
  {
    desc = mapfile .. 'Join lines keep position',
  }
)

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

map('c',
  '<C-a>',
  '<home>', {
    desc = mapfile .. 'Beginning of command',
  })

map(
  'c',
  '<C-e>',
  '<end>',
  {
    desc = mapfile .. 'End of command',
  }
)

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

map(
  'n',
  '<leader>w',
  '<cmd>bw!<CR>',
  { desc = mapfile .. 'Buffer wipe' }
)

map(
  'n',
  '<leader>nr',
  ':lua require("core.files").search_oldfiles()<cr>',
  {
    desc = mapfile .. 'Recent files',
  }
)

-- map("n", "<c-p>", [[<cmd>lua require("telescope.builtin").find_files{cwd = "~/.dotfiles/wiki"}<cr>]], { silent = true })

map(
  'n',
  '<c-p>',
  function()
    return require('core.files').search_dotfiles()
  end,
  { silent = true }
)
--map("n", "<leader>b", [[<cmd>lua require('telescope.builtin').buffers()<cr>]], { silent = true })

map(
  "n",
  "<leader>bb",
  ":lua require('telescope.builtin').buffers()<cr>",
  {
    desc = mapfile .. "Swich buffers",
    silent = true,
  }
)

-- nnoremap <F5> :buffers<CR>:buffer<Space>

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

local open_command = (vim.fn.has('mac') == 1 and 'open') or 'xdg-open'

local function url_repo()
  local cursorword = vim.fn.expand('<cfile>')
  if string.find(cursorword, '^[a-zA-Z0-9-_.]*/[a-zA-Z0-9-_.]*$') then
    cursorword = 'https://github.com/' .. cursorword
  end
  return cursorword or ''
end

map(
  'n',
  'gx',
  function()
    vim.fn.jobstart({ open_command, url_repo() }, { detach = true })
  end,
  {
    silent = true,
    desc = 'xdg open link',
  }
)

-- vim.keymap.set("n", "<cr>", function()
--   local path = vim.fn.expand("<cfile>")
--   local buf = vim.api.nvim_get_current_buf()
--   local cwd = vim.api.nvim_buf_get_name(buf):match("(.*/)")
--
--   local handler = io.open(cwd .. path)
--   if handler == nil then
--     return "<cr>"
--   end
--
--   handler:close()
--   return "gf"
-- end, { expr = true})

vim.keymap.set("n", "<cr>", function()
  local path = vim.fn.expand("<cfile>")
  local ok, result = pcall(vim.cmd, 'gf ' .. path)
  if not ok then
    return "<cr>"
  end
  -- If 'gf' succeeded, return an empty string to prevent further actions
  return "gf"
end, { expr = true })

map(
  'n',
  '<leader>cR',
  '<cmd>lua require("luasnip.loaders.from_lua").load({paths = "~/.config/nvim/luasnip/"})<cr>',
  {
    desc = mapfile .. 'reload snippets',
    silent = false,
  }
)

-- -- Insert 'n' lines below current line staying in normal mode (e.g. use 5<leader>o)
-- vim.keymap.set("n", "<m-o>", function()
--   return "m`" .. vim.v.count .. "o<Esc>``"
-- end, { expr = true })

-- -- Insert 'n' lines above current line staying in normal mode (e.g. use 5<leader>O)
-- vim.keymap.set("n", "<m-O>", function()
--   return "m`" .. vim.v.count .. "O<Esc>``"
-- end, { expr = true })

-- map('n', '<leftmose>', '<cmd>normal gf<cr>', { desc = "go to file"})

map(
  "n",
  "<m-o>",
  "<cmd>Telescope oldfiles<cr>",
  { desc = "telescope oldfiles" }
)
-- map("n", "<leader>b", "<cmd>Telescope buffers<cr>", { desc = "telescope buffers" })

map(
  'n',
  '<leader>cs',
  '<cmd>LuaSnipEdit<cr>',
  { desc = mapfile .. 'Edit snippets' }
)

-- map(
--   'n',
--   '<Leader><CR>',
--   '<cmd>drop ~/.config/nvim/luasnip/snippets.lua<cr>',
--   { silent = true, noremap = true, desc = 'Edit lua snippets' }
-- )

map('i', 'jk', '<Esc>', {
  desc = 'Exit insert mode',
})

map('i', 'kj', '<Esc>', {
  desc = 'Exit insert mode',
})

map(
  'n',
  '<leader>ll',
  function()
    return require('lazy').home()
  end,
  { desc = 'Lazy home' }
)

map('n',
  '<leader>lu',
  function() return require('lazy').update() end,
  { desc = 'Lazy update' }
)

map('n',
  '<leader>ls',
  function()
    return require('lazy').sync()
  end,
  {
    desc = 'Lazy sync',
  }
)

map('n',
  '<leader>lL',
  function()
    return require('lazy').log()
  end,
  { desc = 'Lazy log' }
)

map('n',
  '<leader>lc',
  function()
    return require('lazy').clean()
  end,
  { desc = 'Lazy clean' }
)

map('n',
  '<leader>lp',
  function()
    return require('lazy').profile()
  end,
  { desc = 'Lazy profile' }
)
```

## files (for telescope)

```lua
-- 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 files on ~/.config
M.wiki = function()
  require("telescope.builtin").find_files({
    prompt_title = "Search wiki",
    previewer = false,
    find_command = { 'fd', '--no-ignore-vcs' },
    sorting_strategy = "ascending",
    -- file_ignore_patterns = { "lua-language-server", "chromium" },
    layout_config = { width = 0.7 },
    cwd = "~/.dotfiles/wiki/",
    -- 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


local NVIMHOME = vim.env.NVIM_APPNAME or nvim
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

M.nvim_plugins = function()
  require("telescope.builtin").find_files({
    prompt_title = "NVIM PLUGINS",
    previewer = false,
    find_command = { 'fd', '--no-ignore-vcs' },
    sorting_strategy = "ascending",
    file_ignore_patterns = { ".git" },
    cwd = "~/.config/nvim/lua/plugins",
    hidden = true,
  })
end

M.nvim_core = function()
  require("telescope.builtin").find_files({
    prompt_title = "NVIM CORE",
    previewer = false,
    find_command = { 'fd', '--no-ignore-vcs' },
    sorting_strategy = "ascending",
    file_ignore_patterns = { ".git" },
    cwd = "~/.config/nvim/lua/core",
    hidden = true,
  })
end

M.nvim_zshfiles = function()
  require("telescope.builtin").find_files({
    prompt_title = "NVIM ZSHFILES",
    previewer = false,
    find_command = { 'fd', '--no-ignore-vcs' },
    sorting_strategy = "ascending",
    file_ignore_patterns = { ".git" },
    cwd = vim.env.ZDOTDIR,
    hidden = true,
  })
end

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

M.search_oldfiles = function()
  require("telescope.builtin").oldfiles({
    prompt_title = "OLDFILES",
    previewer = true,
    shorten_path = true,
    sorting_strategy = "ascending",
    -- cwd = vim.env.DOTFILES,
    hidden = true,
    layout_config = { height = 0.3 },
    layout_config = { width = 0.8 },
  })
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
```

## init.lua

```lua
-- Filename: ~/.config/nvim/init.lua
-- Last Change: Mon, 06 Nov 2023 - 15:08

-- @param name module
local function safeRequire(module)
  local success, loadedModule = pcall(require, module)
  if success then return loadedModule end
  print("Error loading " .. module)
end

safeRequire('core.options')
safeRequire('core.filetype')
safeRequire('core.keymaps')
safeRequire('core.autocommands')
safeRequire('core.bootstrap')
safeRequire('core.commands')
safeRequire('core.theme')
safeRequire('core.winbar')
-- safeRequire('core.files')
```