Skip to content

simonhughxyz/NeovimConfig

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

title description author categories tangle created updated version
Neovim Config
My personal neovim config
Simon H Moore
config
neovim
lua
languages
lua
./lua/config.lua
2024-03-06 23:01:44 +0100
2025-08-23 13:47:38 +0100
1.1.1

INSTALL INSTRUCTIONS

All of my main config is contained in this file config.norg, to be able to use this config you have to first tangle the file to generate the config.lua file.


  1. Create lua directory. A lua directory is needed so that the config.lua file can be crated inside of it. Run the below command inside of your shell at the root of this config:
mkdir lua
  1. Open Neovim to bootstrap the config. A. Because the Lazy.nvim package manager and Neorg plugin is required to tangle the config, you have to bootstrap the config for the first time. Don't worry this happens automatically, you just have to open Neovim by running:
nvim

You will see some errors pop up, don't worry about them this just happens because Neovim expects there to be a config which is not there yet.

B. After this is done, close Neovim again by running the below command:

:qa
  1. Tangle the config.norg file. A. Last, we need to tangle the config.norg file, to do so open the file with Neovim by running the following command:
nvim config.norg

B. After the config.norg file is opened in Neovim, run the following command inside Neovim:

:Neorg tangle

Neovim will ask you which file to tangle, select config.norg

  1. Reopen Neovim and enjoy Close and reopen Neovim and the Lazy plugin manager will install everything needed. You might have to reopen Neovim a few times to make sure everything is installed.

SETUP VARIABLES AND FUNCTIONS

Leader keys

Used by many plugins for keybindings, need to be set early as plugins can be dependant on it.


vim.g.mapleader = ' '
vim.g.maplocalleader = '  '

API Variables

Declare common API variables, will be used throughout the config.


| Variable | Value | Descriptions | |----------+---------+------------------------| | o | vim.opt | Inbuilt vim options | | g | vim.g | Inbuilt global options | | cmd | vim.cmd | Run vim ex commands |

local o = vim.opt
local g = vim.g
local cmd = vim.cmd

Global Print Table Function

The P() function can be used globally to print a lua table for inspection.


P = function(v)
  print(vim.inspect(v))
  return v
end

Lazy Helper Function

The plug() function is used to add plugins to the plugins table. The plugins table will be used by lazy to install and load plugins.


local plugins = {}

function plug(plugin)
  plugins[#plugins +1] = plugin
end

OPTIONS

Configure inbuilt Neovim options.


o.autowrite = true           -- Enable auto write
o.clipboard = "unnamedplus"  -- Sync with system clipboard
o.completeopt = "menu,menuone,noselect" -- Completion options for better experience
o.conceallevel = 3           -- Hide * markup for bold and italic
o.confirm = true             -- Confirm to save changes before exiting modified buffer
o.cursorline = true          -- Enable highlighting of the current line
o.breakindent = true         -- Every wrapped line will honor indent
o.expandtab = true           -- Use spaces instead of tabs
o.formatoptions = "jcroqlnt" -- Format options for automatic formatting
o.grepformat = "%f:%l:%c:%m" -- Format for grep output
o.grepprg = "rg --vimgrep"   -- Use ripgrep for grep command
o.ignorecase = true          -- Ignore case in search patterns
o.inccommand = "nosplit"     -- Preview incremental substitute
o.laststatus = 0             -- Never show status line
o.list = true                -- Show some invisible characters (tabs, trailing spaces)
o.mouse = "a"                -- Enable mouse mode
o.number = true              -- Print line number
o.pumblend = 10              -- Popup blend transparency
o.pumheight = 10             -- Maximum number of entries in a popup
o.relativenumber = true      -- Relative line numbers
o.scrolloff = 4              -- Lines of context around cursor
o.sessionoptions = { "buffers", "curdir", "tabpages", "winsize" } -- Session save options
o.shiftround = true          -- Round indent to multiple of shiftwidth
o.shiftwidth = 2             -- Size of an indent
o.shortmess:append({ W = true, I = true, c = true }) -- Reduce message verbosity
o.showmode = false           -- Don't show mode since we have a statusline
o.sidescrolloff = 8          -- Columns of context around cursor
o.signcolumn = "yes"         -- Always show the signcolumn, otherwise it would shift the text each time
o.smartcase = true           -- Don't ignore case with capitals
o.smartindent = true         -- Insert indents automatically
o.spelllang = { "en" }       -- Spell checking language
o.splitbelow = true          -- Put new windows below current
o.splitright = true          -- Put new windows right of current
o.tabstop = 2                -- Number of spaces tabs count for
o.termguicolors = true       -- True color support
o.timeoutlen = 300           -- Time to wait for a mapped sequence to complete
o.undofile = true            -- Save undo history to file
o.undolevels = 10000         -- Maximum number of changes that can be undone
o.updatetime = 200           -- Save swap file and trigger CursorHold
o.wildmode = "longest:full,full" -- Command-line completion mode
o.winminwidth = 5            -- Minimum window width
o.wrap = false               -- Disable line wrap
o.foldlevelstart = 0         -- Enable foldlevel when opening file
o.foldnestmax = 2            -- Set max nested foldlevel
vim.opt.foldenable = true    -- Enable folding
vim.opt.foldmethod = "expr"  -- Use expression for folding
vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()" -- Use treesitter for fold expression
vim.o.foldtext = ''          -- Use default fold text
vim.o.fillchars = 'fold: '   -- Characters to fill folds

if vim.fn.has("nvim-0.9.0") == 1 then
  o.splitkeep = "screen"
  o.shortmess:append({ C = true })
end

-- use powershell on windows
if vim.fn.has("win32") == 1 then
  o.shell = vim.fn.executable "pwsh" == 1 and "pwsh" or "powershell"
  o.shellcmdflag =
  "-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command [Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;"
  o.shellredir = "-RedirectStandardOutput %s -NoNewWindow -Wait"
  o.shellpipe = "2>&1 | Out-File -Encoding UTF8 %s; exit LastExitCode"
  o.shellquote = ""
  o.shellxquote = ""
end

-- if in a wsl environment WSL_DISTRO_NAME should be set
local in_wsl = os.getenv('WSL_DISTRO_NAME') ~= nil

if in_wsl then
  -- Need to install win32yank in windows
  -- see https://mitchellt.com/2022/05/15/WSL-Neovim-Lua-and-the-Windows-Clipboard.html
  vim.g.clipboard = {
    name = "win32yank-wsl",
    copy = {
      ["+"] = "win32yank.exe -i --crlf",
      ["*"] = "win32yank.exe -i --crlf",
    },
    paste = {
      ["+"] = "win32yank.exe -o --lf",
      ["*"] = "win32yank.exe -o --lf",
    },
    cache_enabled = true,
  }
end

SYNTAX HIGHLIGHTS & COLOR

Here I set up the color and syntax used in Neovim buffers.


Options

Enable true color support:


o.termguicolors = true

Gruvebox Colorscheme

A retro groove color scheme with warm, earthy tones designed for comfortable long coding sessions. Gruvbox provides excellent contrast and readability while being easy on the eyes.

This colorscheme implementation offers:

  • Warm color palette: Carefully selected browns, oranges, and muted colors that reduce eye strain

  • Treesitter integration: Full support for modern syntax highlighting with semantic tokens

  • Transparency support: Optional transparent background for terminal integration

  • Comprehensive language support: Optimized colors for all major programming languages

  • Dark and light variants: Multiple contrast levels to suit different lighting conditions

  • Accessibility focused: High contrast ratios and colorblind-friendly palette choices

    Usage: The colorscheme is automatically applied on startup. The configuration includes transparency mode and custom overrides for better markdown and code block visibility.

    Help: The theme provides consistent highlighting across all file types while maintaining the distinctive Gruvbox aesthetic that has made it popular among developers worldwide.

    For example, comments appear in a muted gray-brown, strings in warm green, and keywords in bright orange, creating a cohesive and pleasant coding environment.


GitHub

plug({
 "ellisonleao/gruvbox.nvim",
 enabled = true,
 lazy = false,
 priority = 10000,
 config = function()
   require("gruvbox").setup({
     transparent_mode = true,
     terminal_colors = false, -- disable gruvbox in terminal
     overrides = {
       Folded = { bg = "#202020" },
       -- fix markdown todo colors
       ["@lsp.type.class.markdown"] = { fg = "#000000" },
       ["@neorg.tags.ranged_verbatim.code_block"] = { bg = "#222222" },
     }
   })
   o.background = "dark"
   g.gruvbox_italic = true
   g.gruvbox_bold = false
   g.gruvbox_transparent_bg = true
   g.gruvbox_constrast_dark = "hard"
   g.gruvbox_improved_strings = false
   cmd([[colorscheme gruvbox]])
 end,
 })

Colorizer

A high-performance color highlighter that displays colors directly in your code for better visual feedback. Colorizer automatically detects and highlights color codes, making it easier to work with CSS, web development, and any files containing color values.

This plugin provides:

  • Real-time color preview: See actual colors rendered inline for hex codes, RGB values, and named colors

  • Multiple format support: Handles #RGB, #RRGGBB, #RRGGBBAA, rgb(), hsl(), and CSS color names

  • Performance optimized: Fast highlighting that doesn't slow down your editor

  • Customizable display: Choose between background highlighting, foreground text, or virtual text display

  • Wide language support: Works with CSS, HTML, JavaScript, Lua, and many other file types

  • Non-intrusive: Only highlights valid color codes without interfering with syntax highlighting

    Usage: Colors are automatically highlighted when you open supported files. The plugin runs in the background and updates highlights as you type.

    Help: The colorizer makes it instantly clear what colors your code represents, eliminating guesswork when working with color values in web development, theming, or configuration files.

    For example, #ff0000 will show with a red background, rgb(0, 255, 0) with green, and blue with the corresponding blue color.


GitHub

plug({
  "norcalli/nvim-colorizer.lua",
  enabled = true,
  event = { "BufReadPost", "BufNewFile" },
  opts = {
    default_options = {
      RGB = true,
      RRGGBB = true,
      names = true,
      RRGGBBAA = true,
      rgb_fn = true,
      hsl_fn = true,
      css = true,
      css_fn = true,
      mode = "background",
    },
    "*", -- highlight all files
  },
})

Rainbow

A Neovim plugin that provides rainbow parentheses highlighting using Tree-sitter for enhanced code readability. Rainbow colorizes matching brackets, parentheses, and delimiters with different colors to make nested code structures easier to navigate and understand.

This plugin offers:

  • Tree-sitter integration: Uses modern Tree-sitter parsing for accurate bracket detection and highlighting

  • Multiple delimiter support: Highlights parentheses, brackets, braces, and other delimiters with distinct colors

  • Extended mode: Optional highlighting of non-bracket delimiters like HTML tags and language-specific constructs

  • Performance optimized: Efficient highlighting that works smoothly even with large files

  • Customizable colors: Configure your own color schemes or use the default rainbow palette

  • Language awareness: Intelligent highlighting that respects language syntax and context

    Usage: Rainbow highlighting is automatically applied when you open supported files. The plugin cycles through colors for each nesting level, making it easy to match opening and closing delimiters.

    Help: The rainbow colors help reduce visual confusion when working with deeply nested code structures, making it easier to spot mismatched brackets and understand code hierarchy at a glance.

    For example, in nested function calls like func(array[index(key)]), each level of brackets will appear in a different color, making the structure immediately clear.


GitHub

plug({
  "p00f/nvim-ts-rainbow",
  event = { "BufReadPost", "BufNewFile" },
  main = 'nvim-treesitter.configs',
  opts = {
    -- for nvim-ts-rainbow plugin
    rainbow = {
      enable = true,
      extended_mode = true,   -- Also highlight non-bracket delimiters like html tags, boolean or table: lang -> boolean
      max_file_lines = 10000, -- Do not enable for files with more than 10000 lines, int
      -- colors = {}, -- table of hex strings
      -- termcolors = {} -- table of colour name strings
    },
  }
})

Sentiment

A modern and enhanced replacement for Neovim's built-in matchparen functionality that provides intelligent bracket and delimiter highlighting. Sentiment offers superior performance and visual feedback for matching pairs in your code.

This plugin enhances code navigation by:

  • Smart pair detection: Accurately highlights matching brackets, parentheses, braces, and other delimiters

  • Performance optimized: Faster and more efficient than the default matchparen plugin

  • Visual clarity: Clear highlighting that makes it easy to identify matching pairs at a glance

  • Customizable appearance: Configure colors and styles to match your preferred theme

  • Language awareness: Intelligent handling of different programming language syntaxes

  • Non-intrusive design: Subtle highlighting that doesn't interfere with your workflow

    Usage: Matching pairs are automatically highlighted when your cursor is positioned on or near brackets, parentheses, or other delimiters. The plugin works seamlessly in the background.

    Help: The highlighting helps you quickly identify the scope of code blocks, function calls, and nested structures, reducing errors and improving code comprehension.

    For example, when your cursor is on an opening [, the corresponding closing ](, the corresponding closing ) will be highlighted, making it easy to see the extent of code blocks and nested structures.


GitHub

plug({
  "utilyre/sentiment.nvim",
  version = "*",
  event = "VeryLazy", -- keep for lazy loading
  opts = {
    -- config
  },
  init = function()
    -- `matchparen.vim` needs to be disabled manually in case of lazy loading
    vim.g.loaded_matchparen = 1
  end,
})

Headlines

This plugin adds highlights for text filetypes, like markdown, orgmode, and neorg.


GitHub

plug({
  "lukas-reineke/headlines.nvim",
  dependencies = "nvim-treesitter/nvim-treesitter",
  config = function()

    vim.cmd [[highlight Headline1 guibg=#1e2718]]
    vim.cmd [[highlight Headline2 guibg=#21262d]]
    vim.cmd [[highlight CodeBlock guibg=#1c1c1c]]
    vim.cmd [[highlight Dash guibg=#D19A66 gui=bold]]
    require("headlines").setup {
      norg = {
        query = vim.treesitter.query.parse(
                "norg",
                [[
                    [
                        (heading1_prefix)
                        (heading2_prefix)
                        (heading3_prefix)
                        (heading4_prefix)
                        (heading5_prefix)
                        (heading6_prefix)
                    ] @headline

                    (weak_paragraph_delimiter) @dash
                    (strong_paragraph_delimiter) @doubledash

                    ([(ranged_tag
                        name: (tag_name) @_name
                        (#eq? @_name "code")
                    )
                    (ranged_verbatim_tag
                        name: (tag_name) @_name
                        (#eq? @_name "code")
                    )] @codeblock (#offset! @codeblock 0 0 1 0))

                    (quote1_prefix) @quote
                ]]
            ),
        headline_highlights = { "Headline1", "Headline2" },
            bullet_highlights = {
                "@neorg.headings.1.prefix",
                "@neorg.headings.2.prefix",
                "@neorg.headings.3.prefix",
                "@neorg.headings.4.prefix",
                "@neorg.headings.5.prefix",
                "@neorg.headings.6.prefix",
            },
            bullets = { "", "", "", "" },
            codeblock_highlight = false,
            dash_highlight = "Dash",
            dash_string = "-",
            doubledash_highlight = "DoubleDash",
            doubledash_string = "=",
            quote_highlight = "Quote",
            quote_string = "",
            fat_headlines = true,
            fat_headline_upper_string = "",
            fat_headline_lower_string = "",
        },
    }

  end,
})

UI

Here we configure the user interface for Neovim.


Lualine

A blazing fast and highly customizable statusline plugin for Neovim written in pure Lua. Lualine provides a beautiful and informative status bar that displays essential information about your editing session while maintaining excellent performance.

This statusline implementation offers:

  • Lightning-fast performance: Written in Lua with minimal overhead, ensuring your editor stays responsive
  • Extensive customization: Configure colors, components, separators, and layout to match your workflow
  • Rich component library: Display mode, branch, diagnostics, file info, LSP status, and much more
  • Theme integration: Seamlessly integrates with your colorscheme or use custom themes
  • Extension support: Built-in support for popular plugins like fugitive, fzf, and nvim-tree
  • Winbar support: Optional window-local statuslines for better file navigation
  • Tabline functionality: Replace Neovim's default tabline with a customizable alternative

Usage: The statusline is automatically displayed and updates in real-time. The configuration includes custom themes, component positioning, and integration with LSP diagnostics and Git information.

Help: Run :help lualine for comprehensive documentation. The plugin displays current mode, Git branch, file path, diagnostics, and cursor position by default.

For example, the statusline shows your current Vim mode (Normal, Insert, Visual), Git branch with diff statistics, file encoding, and line/column position, all with color-coded indicators for quick visual reference.


GitHub

local colors = {
 black = "#000000",
 white = "#ffffff",
 gray = "#444444",
 light_gray = "#666666",
 background = "#0c0c0c",
 green = "#005000",
 yellow = "#706000",
 blue = "#004090",
 paste = "#5518ab",
 red = "#800000",
}

local lualine_theme = {
 normal = {
   a = { fg = colors.white, bg = colors.green },
   b = { fg = colors.white, bg = colors.grey },
   c = { fg = colors.white, bg = colors.black },
 },

 insert = { a = { fg = colors.white, bg = colors.blue } },
 command = { a = { fg = colors.white, bg = colors.red } },
 visual = { a = { fg = colors.white, bg = colors.yellow } },
 replace = { a = { fg = colors.white, bg = colors.red } },

 inactive = {
   a = { fg = colors.white, bg = colors.black },
   b = { fg = colors.white, bg = colors.black },
   c = { fg = colors.light_gray, bg = colors.black },
 },
}

plug({
  {
    "nvim-lualine/lualine.nvim",
    event = "VeryLazy",
    opts = function()
      return {
        options = {
          theme = lualine_theme,
          component_separators = { left = "", right = "" },
          section_separators = { left = "|", right = "|" },
        },
        sections = {
          lualine_a = { "mode" },
          lualine_b = { "branch", "diff", "diagnostics" },
          lualine_c = {
            {
              "filename",
              path = 4
            },
          },
          lualine_x = { "encoding", "fileformat", "filetype" },
          lualine_y = { "progress" },
          lualine_z = { "location" },
        },
        inactive_sections = {
          lualine_a = {},
          lualine_b = {},
          lualine_c = {
            {
              "filename",
              path = 4
            },
          },
          lualine_x = { "location" },
          lualine_y = {},
          lualine_z = {},
        },
        tabline = {},
        winbar = {
          lualine_c = {
            {
              "filename",
              path = 4,
            },
            "navic"
          },
        },
        inactive_winbar = {
          lualine_c = {
              {
                "filename",
                path = 3
              }
            },
        },
        extensions = {},
      }
    end,
  },
})

@end

NEORG

An all-encompassing tool based around structured note taking, project and task management, time tracking, slideshows, writing typeset documents and much more.


GitHub Spec

plug({
  "nvim-neorg/neorg",
  build = ":Neorg sync-parsers",
  dependencies = {
    "nvim-lua/plenary.nvim",
    "Pocco81/true-zen.nvim",
    "nvim-treesitter/nvim-treesitter",
    "nvim-treesitter/nvim-treesitter-textobjects",
    "hrsh7th/nvim-cmp",
  },
  ft = "norg",
  cmd = "Neorg",
  config = function()
    require("neorg").setup({
      load = {
        ["core.defaults"] = {}, -- Loads default behaviour
        ["core.concealer"] = {  -- Adds pretty icons to your documents
          config = {
            foldlevelstart = "0",
            icon_preset = "diamond",
            icons = {
              code_block = {
                width = "content",
                min_width = 85,
                conceal = true,
              },
            },
          },
        },
        ["core.dirman"] = { -- Manages Neorg workspaces
          config = {
            workspaces = {
              documents = "~/Documents",
              notes = "~/Documents/Notes",
              career = "~/Documents/Career",
              profiles = "~/Documents/Profiles",
            },
            default_workspace = "documents",
          },
        },
        ["core.completion"] = {
          config = {
            engine = 'nvim-cmp',
            name = "[Norg]",
          }
        },
        ["core.integrations.nvim-cmp"] = {},
        ["core.qol.toc"] = {
          config = {
            close_split_on_jump = true,
            toc_split_placement = "right",
          }
        },
        ["core.export"] = {},
        ["core.export.markdown"] = {
          config = {
            extensions = "all",
          }
        },
        ["core.presenter"] = {
          config = {
            zen_mode = "truezen",
          }
        },
        ["core.journal"] = {
          config = {
            workspace = "journal",
            strategy = "flat",
          }
        },
        ["core.summary"] = {},
        ["core.esupports.metagen"] = { config = { type = "auto", update_date = true } },
        ["core.ui.calendar"] = {},
      }
    })

    local neorg_callbacks = require("neorg.core.callbacks")

    neorg_callbacks.on_event("core.keybinds.events.enable_keybinds", function(_, keybinds)
      -- Map all the below keybinds only when the "norg" mode is active
      keybinds.map_event_to_mode("norg", {
        n = { -- Bind keys in normal mode
          { "<localleader>ff", function() Snacks.picker.files({ cwd = vim.fn.getcwd() }) end, opts = { desc = 'Find Norg Files' } },
          { "<localleader>sh", function() Snacks.picker.grep({ cwd = vim.fn.getcwd() }) end, opts = { desc = 'Search Headings' } },
          { "<localleader>cg", "core.looking-glass.magnify-code-block", opts = { desc = 'Looking Glass' } },
        },

        i = { -- Bind in insert mode
          { "<C-l>", function() print("Link insertion not available with snacks") end, opts = { desc = 'Insert Link (unavailable)' } },
          { "<C-L>", function() print("File link insertion not available with snacks") end, opts = { desc = 'Insert File Link (unavailable)' } },
        },
      }, {
        silent = true,
        noremap = true,
      })
    end)
  end,
})

SNACKS

A collection of small QoL plugins for Neovim.


plug({
  "folke/snacks.nvim",
  priority = 1000,
  lazy = false,
  ---@type snacks.Config
  opts = {
    -- Keep only the useful non-picker modules
    bigfile = { enabled = true },
    indent = {
      indent = {
        enabled = true,
        priority = 1,
        char = "",
      },
      animate = { enabled = false },
      scope = {
        enabled = true, -- enable highlighting the current scope
        priority = 200,
        char = "",
      },
    },
    -- Enable snacks notify
    notifier = { 
      enabled = true,
      timeout = 1000,
      width = { min = 20, max = 50 },
      height = { max = 50 },
      style = "compact",
      top_down = true,
    },
    -- Enable snacks input to replace dressing.nvim
    input = { enabled = true },
    -- Enable snacks words for navigation (]]  [[)
    words = { 
      enabled = true,
      debounce = 200,
    },
    -- Enable quickfile for better performance
    quickfile = { enabled = true },
    -- Enable picker instead of telescope
    picker = { enabled = true },
    -- Keep disabled
    dashboard = { enabled = false },
    explorer = { enabled = false },
    scope = { enabled = false },
    scroll = { enabled = false },
    statuscolumn = { enabled = false },
  },
  config = function(_, opts)
    require("snacks").setup(opts)
    vim.notify = Snacks.notifier.notify
  
    -- Add snacks picker keymaps
    local pick = Snacks.picker
  
    -- Shortcuts
    vim.keymap.set('n', '<leader>?', pick.recent, { desc = 'Find Recently Files' })
    vim.keymap.set('n', '<leader>,', pick.buffers, { desc = 'Find buffers' })
    vim.keymap.set('n', '<leader>/', pick.grep_word, { desc = 'Search current word' })

    -- Find Files
    vim.keymap.set('n', '<leader>ff', pick.files, { desc = 'Find Files' })
    vim.keymap.set('n', '<leader>fb', pick.buffers, { desc = 'Find Buffers' })
    vim.keymap.set('n', '<leader>fr', pick.recent, { desc = 'Find Recent Files' })
    vim.keymap.set('n', '<leader>fg', pick.git_files, { desc = 'Find Git Files' })
    vim.keymap.set('n', '<leader>fs', pick.git_status, { desc = 'Find Git Status' })

    vim.keymap.set('n', '<leader>fd', function() pick.files({ cwd = '~/Documents' }) end, { desc = 'Find Documents' })
    vim.keymap.set('n', '<leader>fD', function() pick.files({ cwd = '~/Downloads' }) end, { desc = 'Find Downloads' })
    vim.keymap.set('n', '<leader>fp', function() pick.files({ cwd = '~/Projects' }) end, { desc = 'Find Projects' })
    vim.keymap.set('n', '<leader>fc', function() pick.files({ cwd = vim.fn.stdpath('config') }) end, { desc = 'Find Config' })
    vim.keymap.set('n', '<leader>fB', function() pick.files({ cwd = '~/.local/bin' }) end, { desc = 'Find Local Bin' })

    -- Search for content, help and functions
    vim.keymap.set('n', '<leader>sc', pick.git_log, { desc = 'Search Git Commits' })
    vim.keymap.set('n', '<leader>st', function() pick.commands() end, { desc = 'Search Commands' })
    vim.keymap.set('n', '<leader>sh', pick.help, { desc = 'Search Help' })
    vim.keymap.set('n', '<leader>sw', pick.grep_word, { desc = 'Search Current Word' })
    vim.keymap.set('n', '<leader>sg', pick.grep, { desc = 'Search by Grep' })
    vim.keymap.set('n', '<leader>sd', pick.diagnostics, { desc = 'Search Diagnostics' })
    vim.keymap.set('n', '<leader>sk', pick.keymaps, { desc = 'Search Keymaps' })
    vim.keymap.set('n', "<leader>s'", pick.marks, { desc = 'Search Marks' })
    vim.keymap.set('n', '<leader>s"', pick.registers, { desc = 'Search Registers' })
    vim.keymap.set('n', '<leader>sf', pick.grep_word, { desc = 'Search word under cursor' })
  end,
  keys = {
    {
      "<leader>;n",
      function() Snacks.notifier.show_history() end,
      desc = "Notification History"
    },
    {
      "]]",
      function() Snacks.words.jump(vim.v.count1) end,
      desc = "Next Reference"
    },
    {
      "[[", 
      function() Snacks.words.jump(-vim.v.count1) end,
      desc = "Prev Reference"
    },
  }
})

VIM-ILLUMINATE

Automatically highlighting other uses of the word under the cursor using either LSP, Tree-sitter, or regex matching.


GitHub

plug({
  "RRethy/vim-illuminate",
  event = { "BufReadPost", "BufNewFile" },
  opts = {
    delay = 200,
    large_file_cutoff = 2000,
    large_file_overrides = {
      providers = { "lsp" },
    },
  },
  config = function(_, opts)
    require("illuminate").configure(opts)

    local function map(key, dir, buffer)
      vim.keymap.set("n", key, function()
        require("illuminate")["goto_" .. dir .. "_reference"](false)
      end, { desc = dir:sub(1, 1):upper() .. dir:sub(2) .. " Reference", buffer = buffer })
    end

    map("]]", "next")
    map("[[", "prev")

    -- also set it after loading ftplugins, since a lot overwrite [[ and ]]
    vim.api.nvim_create_autocmd("FileType", {
      callback = function()
        local buffer = vim.api.nvim_get_current_buf()
        map("]]", "next", buffer)
        map("[[", "prev", buffer)
      end,
    })
  end,
  keys = {
    { "]]", desc = "Next Reference" },
    { "[[", desc = "Prev Reference" },
  },
})

FILE NAVIGATION

Oil

A revolutionary file explorer that treats your filesystem like a regular Neovim buffer, allowing you to edit directories with the same commands you use for text editing. Oil transforms file management into a native Neovim experience with unparalleled efficiency.

This file explorer provides:

  • Buffer-based editing: Navigate and modify your filesystem using familiar Vim motions and commands
  • Direct manipulation: Rename files by editing text, delete with dd, copy with yy, and paste with p
  • Floating window support: Quick access via floating windows that don't disrupt your workflow
  • Cross-platform compatibility: Works seamlessly on Windows, macOS, and Linux systems
  • Undo/redo support: Full undo history for filesystem operations with standard Vim commands
  • Integration friendly: Works with your existing Neovim plugins and colorschemes
  • Performance optimized: Fast directory loading and responsive navigation even in large directories

Usage: Open with <leader>o for a floating window or <leader>O for current working directory. Edit filenames directly in the buffer, use dd to delete files, and save with :w to apply changes.

Help: Run :help oil for complete documentation. The plugin treats directories as editable buffers where standard Vim operations translate to filesystem actions.

For example, to rename multiple files, simply edit their names in the buffer using standard text editing commands, then save to apply all changes atomically.


GitHub

plug({
   "stevearc/oil.nvim",
   dependencies = { "nvim-tree/nvim-web-devicons" },
   enabled = true,
   lazy = true,
   config = function ()
     require("oil").setup({
       default_file_explorer = true,
     })

   end,
   cmd = "Oil",
   keys = {
     { "<leader>o", function() require("oil").toggle_float() end, desc = "Oil File Manager" },
     { "<leader>O", function() require("oil").toggle_float(vim.fn.getcwd()) end, desc = "Oil File Manager" },
   }
})

Neo-Tree

A comprehensive and modern file explorer for Neovim that provides an intuitive tree-based interface for navigating your filesystem, buffers, and Git status. Neo-Tree offers a feature-rich sidebar experience with extensive customization options.

This file manager delivers:

  • Multiple source types: Browse filesystem, open buffers, Git status, and LSP document symbols in unified interface
  • Rich visual indicators: File type icons, Git status markers, and diagnostic indicators for comprehensive project overview
  • Advanced navigation: Fuzzy finding, bookmarks, and quick access to recently used files
  • Git integration: Visual Git status with staging/unstaging capabilities directly from the tree
  • Customizable interface: Configurable mappings, filters, and display options to match your workflow
  • Performance optimized: Lazy loading and efficient rendering for large directory structures
  • Plugin ecosystem: Extensive integration with popular Neovim plugins and LSP servers

Usage: Toggle with <leader>e for filesystem view or <leader>be for buffer explorer. Navigate with standard Vim motions, open files with <Enter>, and use various actions via intuitive key mappings.

Help: Run :help neo-tree for detailed documentation. The plugin provides context-sensitive help and customizable key mappings for all operations.

For example, press a to create new files/directories, d to delete, r to rename, and c to copy, all while seeing real-time Git status and file type information.


GitHub

plug({
  "nvim-neo-tree/neo-tree.nvim",
  branch = "v3.x",
  dependencies = {
    "nvim-lua/plenary.nvim",
    "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended
    "MunifTanjim/nui.nvim",
  },
  cmd = "Neotree",
  keys = {
    {
      "<leader>e",
      function()
        require("neo-tree.command").execute({ toggle = true, dir = vim.loop.cwd() })
      end,
      desc = "Explorer NeoTree",
    },
    {
      "<leader>be",
      function()
        require("neo-tree.command").execute({ toggle = true, source = "buffers"  })
      end,
      desc = "Explorer NeoTree Buffers",
    },
  },
  deactivate = function()
    vim.cmd([[Neotree close]])
  end,
  opts = {
    sources = { "filesystem", "buffers", "git_status", "document_symbols" },
    open_files_do_not_replace_types = { "terminal", "Trouble", "qf", "Outline" },
    filesystem = {
      bind_to_cwd = false,
      follow_current_file = { enabled = true },
      use_libuv_file_watcher = true,
    },
    window = {
      mappings = {
        ["<space>"] = "none",
      },
    },
    default_component_configs = {
      indent = {
        with_expanders = true, -- if nil and file nesting is enabled, will enable expanders
        expander_collapsed = "",
        expander_expanded = "",
        expander_highlight = "NeoTreeExpander",
      },
    },
  },
})

Project.nvim

An intelligent project management plugin that automatically detects and manages your project workspaces, providing seamless project switching and workspace organization. Project.nvim eliminates the hassle of manual directory management and enhances your development workflow.

This project manager offers:

  • Automatic project detection: Intelligently identifies projects using Git repositories, LSP roots, and custom patterns
  • Smart directory switching: Automatically changes working directory when switching between projects
  • Recent project history: Maintains a history of recently accessed projects for quick switching
  • Multiple detection methods: Supports Git, LSP, and custom file patterns for flexible project identification
  • Integration ready: Works seamlessly with telescope, dashboard, and other popular plugins
  • Session persistence: Optional integration with session management for complete workspace restoration
  • Customizable patterns: Define your own project root indicators for specialized workflows

Usage: Projects are automatically detected when you open files. Use <leader>sp to search and switch between recent projects. The plugin maintains context and working directory automatically.

Help: Run :help project_nvim for configuration options. The plugin works silently in the background, tracking your project usage patterns.

For example, when you open a file in a Git repository, Project.nvim automatically sets that repository as your current project and remembers it for future quick access via the project picker.


GitHub

plug({
  "ahmedkhalf/project.nvim",
  enabled = true,
  lazy = false,
  config = function()
    require("project_nvim").setup({
      detection_methods = { "lsp", "pattern" },
      patterns = { ".project", ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json" },
      silent_chdir = false,
    })
  end,
  keys = {
    {
      "<leader>sp",
      function() 
        local projects = require("project_nvim").get_recent_projects()
        Snacks.picker.pick({
          items = projects,
          format = function(item) return vim.fn.fnamemodify(item, ":t") .. " (" .. item .. ")" end,
          preview = false,
        }, function(item)
          vim.cmd("cd " .. item)
        end)
      end,
      desc = 'Search for Project',
    },
  },
})

BUFFER NAVIGATION

EYELINER

An innovative motion enhancement plugin that provides unique visual indicators for f/F/t/T movements, making character-based navigation significantly faster and more accurate. Eyeliner eliminates guesswork in horizontal navigation by highlighting optimal jump targets.

This navigation enhancer provides:

  • Unique character highlighting: Each reachable character gets a distinct visual indicator during f/F/t/T motions
  • Smart target selection: Prioritizes the most efficient jump targets based on distance and frequency
  • Customizable appearance: Configure highlight colors and styles to match your visual preferences
  • Performance optimized: Minimal overhead with highlights that appear only when needed
  • Dimming support: Optional dimming of non-target characters for better focus
  • Multi-line awareness: Intelligent handling of line boundaries and wrapped text
  • Integration friendly: Works seamlessly with existing motion plugins and colorschemes

Usage: Simply use f, F, t, or T motions as normal. Eyeliner automatically highlights available targets with unique indicators, making it easy to identify the exact character to jump to.

Help: The plugin works transparently with Vim's built-in motions. Customize highlight colors and behavior through the setup configuration.

For example, when you press f to find a character, Eyeliner highlights each occurrence of that character on the current line with different colors, allowing you to instantly see which one to target.


GitHub

plug({
  "jinh0/eyeliner.nvim",
  priority = 200,
  keys = { "f", "F", "t", "T" },
  opts = {
    highlight_on_key = true,
    dim = true
  },
  init = function()
    vim.api.nvim_create_autocmd('ColorScheme', {
      pattern = '*',
      callback = function()
        vim.api.nvim_set_hl(0, 'EyelinerPrimary', { fg = '#aa00aa', bold = true, underline = false })
        vim.api.nvim_set_hl(0, 'EyelinerSecondary', { fg = '#a0f050', bold = true, underline = false })
      end,
    })
  end,
})

Nvim Spider

Enhanced word motions that move by subwords and skip insignificant punctuation, making navigation through code more precise and efficient.

This plugin improves Vim's standard w, e, b, and ge motions by:

  • Subword navigation: Stops at each meaningful part of camelCase, PascalCase, snake_case, and kebab-case identifiers

  • Smart punctuation handling: Skips over insignificant punctuation marks that don't add semantic meaning

  • Programming-optimized: Perfect for navigating through variable names, function names, and code identifiers

  • Customizable patterns: Allows configuration of what constitutes word boundaries

    Usage: The plugin automatically replaces the default w, e, b, and ge motions. Use them as normal - they will now be smarter about stopping at meaningful word boundaries.

    Help: Run :help spider in Neovim for detailed documentation and configuration options.

    For example, with myVariableName.someMethod(), the w motion will stop at each meaningful part: my, Variable, Name, some, Method rather than jumping over entire compound words.


GitHub

plug({
  "chrisgrieser/nvim-spider",
  enabled = true,
  lazy = false,
  config = function()
    vim.keymap.set({ "n", "o", "x" }, "w", "<cmd>lua require('spider').motion('w')<cr>", { desc = "Spider-w" })
    vim.keymap.set({ "n", "o", "x" }, "e", "<cmd>lua require('spider').motion('e')<cr>", { desc = "Spider-e" })
    vim.keymap.set({ "n", "o", "x" }, "b", "<cmd>lua require('spider').motion('b')<cr>", { desc = "Spider-b" })
    vim.keymap.set({ "n", "o", "x" }, "ge", "<cmd>lua require('spider').motion('ge')<cr>", { desc = "Spider-ge" })
  end,
})

GIT

Fugitive

A Git wrapper so awesome, it should be illegal. Fugitive is the premier Vim plugin for Git, providing a comprehensive interface for Git operations directly within Neovim.

This plugin transforms Neovim into a powerful Git client by:

  • Complete Git workflow integration: Stage, commit, push, pull, and merge without leaving your editor

  • Interactive Git status: Browse and manipulate your repository state with intuitive commands

  • Advanced diff viewing: Compare branches, commits, and working directory changes with sophisticated diff tools

  • Blame integration: See line-by-line authorship and commit history inline with your code

  • Branch management: Create, switch, and merge branches seamlessly

  • Conflict resolution: Resolve merge conflicts with visual three-way diffs

    Usage: Access Git operations through :Git commands or use the configured keybindings. The plugin provides both command-line Git access and specialized buffers for interactive Git operations.

    Help: Run :help fugitive in Neovim for comprehensive documentation and command reference.

    For example, :Git opens an interactive status window where you can stage files with s, unstage with u, and commit with cc, all while seeing a live diff of your changes.


GitHub

plug({
  'tpope/vim-fugitive',
  enabled = true,
  lazy = true,
  keys = {
    { "<leader>gg",
      "<cmd>Git<cr>",
      desc = "Git"
    },
    { "<leader>gp",
      "<cmd>Git push<cr>",
      desc = "Git Push"
    },
    { "<leader>gP",
      "<cmd>Git pull<cr>",
      desc = "Git Pull"
    },
    { "<leader>gl",
      "<cmd>Git log<cr>",
      desc = "Git Log"
    },
    { "<leader>gd",
      "<cmd>Git diff<cr>",
      desc = "Git Diff"
    },
  }
})

Gitsigns

Super fast git decorations implemented purely in Lua. Gitsigns provides comprehensive Git integration for Neovim buffers, displaying visual indicators and enabling seamless Git workflow management.

This plugin enhances your Git workflow by:

  • Visual Git indicators: Display added, modified, and deleted lines with customizable signs in the gutter

  • Hunk navigation: Jump between Git hunks with intuitive keybindings for efficient code review

  • Interactive staging: Stage and unstage individual hunks or entire buffers without leaving your editor

  • Inline blame information: View Git blame data directly in your buffer to understand code history

  • Real-time diff preview: Preview changes with floating windows before committing

  • Branch and status integration: See current branch and repository status at a glance

  • Conflict resolution support: Visual aids for resolving merge conflicts

    Usage: Git signs appear automatically in the gutter when editing tracked files. Use the configured keybindings to navigate hunks (]h/[h), stage changes (<leader>hs), and preview modifications (<leader>hp).

    Help: Run :help gitsigns in Neovim for comprehensive documentation and configuration options.

    For example, when you modify a tracked file, you'll see ~ signs for changed lines, + for additions, and - for deletions, allowing you to quickly identify and manage your changes.


GitHub

plug({
  'lewis6991/gitsigns.nvim',
  enabled = true,
  opts = {
    -- See `:help gitsigns.txt`
    on_attach = function(bufnr)
      local gs = package.loaded.gitsigns
      vim.keymap.set('n', '[h', gs.prev_hunk, { buffer = bufnr, desc = 'Go to Previous Hunk' })
      vim.keymap.set('n', ']h', gs.next_hunk, { buffer = bufnr, desc = 'Go to Next Hunk' })
      vim.keymap.set('n', '<leader>hs', gs.stage_hunk, { buffer = bufnr, desc = 'Git Stage Hunk' })
      vim.keymap.set('n', '<leader>hS', gs.stage_buffer, { buffer = bufnr, desc = 'Git Stage Entire Buffer' })
      vim.keymap.set('n', '<leader>hr', gs.reset_hunk, { buffer = bufnr, desc = 'Git Reset Hunk' })
      vim.keymap.set('n', '<leader>hR', gs.reset_buffer, { buffer = bufnr, desc = 'Git Reset Entire Buffer' })
      vim.keymap.set('v', '<leader>hs', function() gs.stage_hunk { vim.fn.line('.'), vim.fn.line('v') } end,
        { buffer = bufnr, desc = 'Git Stage Selected Hunk' })

      vim.keymap.set('v', '<leader>gr', function() gs.reset_hunk { vim.fn.line('.'), vim.fn.line('v') } end,
        { buffer = bufnr, desc = 'Git Reset Selected Hunk' })

      vim.keymap.set('n', '<leader>hu', gs.undo_stage_hunk, { buffer = bufnr, desc = 'Git Undo Stage Hunk' })
      vim.keymap.set('n', '<leader>ht', gs.toggle_deleted, { buffer = bufnr, desc = 'Git Toggle Deleted' })
      vim.keymap.set('n', '<leader>hd', gs.diffthis, { buffer = bufnr, desc = 'Git Diff Hunk' })
      vim.keymap.set('n', '<leader>hD', function() gs.diffthis('~') end, { buffer = bufnr, desc = 'Git Diff Hunk' })
      vim.keymap.set('n', '<leader>hp', gs.preview_hunk, { buffer = bufnr, desc = 'Git Preview Hunk' })
      vim.keymap.set('n', '<leader>hb', gs.blame_line, { buffer = bufnr, desc = 'Git Blame Line' })
      vim.keymap.set('n', '<leader>hB', gs.toggle_current_line_blame,
        { buffer = bufnr, desc = 'Git Blame Line Toggle' })

      -- Text object
      vim.keymap.set({ 'o', 'x' }, 'ih', ':<C-U>Gitsigns select_hunk<CR>', { desc = 'Hunk' })
      vim.keymap.set({ 'o', 'x' }, 'ah', ':<C-U>Gitsigns select_hunk<CR>', { desc = 'Hunk' })
    end,
  },
})

Diffview

Single tabpage interface for easily cycling through diffs for all modified files for any git rev.


GitHub

plug({
  "sindrets/diffview.nvim",
  enabled = true,
  lazy = true,
  keys = {
    {
      "<leader>dd",
      "<cmd>DiffviewOpen<cr>",
      desc = "Open Diff View",
    }
  },
})

LSP

Language Server Protocol


The Language Server Protocol (LSP) defines the protocol used between an editor or IDE and a language server that provides language features like auto complete, go to definition, find all references etc. The goal of the Language Server Index Format (LSIF, pronounced like "else if") is to support rich code navigation in development tools or a Web UI without needing a local copy of the source code.


Official LSP Home

plug({
-- Collection of functions that will help you setup Neovim's LSP client
'VonHeikemen/lsp-zero.nvim',
branch = 'v3.x',
dependencies = {
  -- LSP Support
  { 'neovim/nvim-lspconfig' },             -- Required
  { 'williamboman/mason.nvim' },           -- Optional
  { 'williamboman/mason-lspconfig.nvim' }, -- Optional

  -- Format
  { 'onsails/lspkind.nvim' }, -- shows icons on completion menu
  { 'kosayoda/nvim-lightbulb' },
  {
    'weilbith/nvim-code-action-menu',
    cmd = 'CodeActionMenu',
  },

  -- Autocompletion
  { 'hrsh7th/nvim-cmp' },
  { 'hrsh7th/cmp-nvim-lsp' },
  {
    'L3MON4D3/LuaSnip',
    dependencies = { "rafamadriz/friendly-snippets" },
  },
  { 'nvimtools/none-ls.nvim',     dependencies = { 'nvim-lua/plenary.nvim' } },
  { "jay-babu/mason-null-ls.nvim" },

  { 'saadparwaiz1/cmp_luasnip' },
  { 'hrsh7th/cmp-nvim-lua' },
  { 'hrsh7th/cmp-buffer' },
  { 'hrsh7th/cmp-cmdline' },
  { 'hrsh7th/cmp-path' },
  { 'hrsh7th/cmp-emoji' },
  { 'hrsh7th/cmp-calc' },
},
config = function()
  local lsp_zero = require('lsp-zero')

  lsp_zero.on_attach(function(client, bufnr)
    -- see :help lsp-zero-keybindings
    -- to learn the available actions
    lsp_zero.default_keymaps({ buffer = bufnr })

    local opts = function(desc)
      return { buffer = bufnr, remap = false, desc = desc }
    end

    vim.keymap.set({ 'n', 'x' }, '<leader>lf', function()
      vim.lsp.buf.format({ async = false, timeout_ms = 10000 })
    end, opts('Lsp format buffer'))

    vim.keymap.set("n", "[d", function() vim.diagnostic.goto_next() end, opts("Go To Next Diagnostic"))
    vim.keymap.set("n", "]d", function() vim.diagnostic.goto_prev() end, opts("Go To Previous Diagnostic"))
    vim.keymap.set("n", "gd", function() Snacks.picker.lsp_definitions() end, opts("Go To Definition"))
    vim.keymap.set("n", "<leader>la", function() vim.lsp.buf.code_action() end, opts("Code Action"))
    vim.keymap.set("n", "<leader>lh", function() vim.lsp.buf.hover() end, opts("Hover"))
    vim.keymap.set("n", "<leader>lH", function() vim.lsp.buf.signature_help() end, opts("Signiture Help"))
    vim.keymap.set("n", "<leader>ls", function() Snacks.picker.lsp_workspace_symbols() end, opts("Workspace Symbol"))
    vim.keymap.set("n", "<leader>lr", function() Snacks.picker.lsp_references() end, opts("References"))
    vim.keymap.set("n", "<leader>li", function() vim.lsp.buf.implementation() end, opts("Implementation"))
    vim.keymap.set("n", "<leader>lR", function() vim.lsp.buf.rename() end, opts("Rename"))
    vim.keymap.set("n", "<leader>lI", '<cmd>LspInfo<CR>', opts("LspInfo"))
  end)

  require('mason').setup({})
  require('mason-lspconfig').setup({
    ensure_installed = {
      'lua_ls',
      'bashls',
      'pyright',    -- python
      'html',
      'clangd',
      "marksman",   -- markdown
    },
    handlers = {
      lsp_zero.default_setup,
      lua_ls = function()
        local lua_opts = lsp_zero.nvim_lua_ls()
        require('lspconfig').lua_ls.setup(lua_opts)
      end,
      marksman = function()
        require('lspconfig').marksman.setup({})
      end,
    }
  })

  -- Open Mason UI
  vim.keymap.set("n", "<leader>;m", "<cmd>Mason<cr>", { desc = "Mason Plugin Manager" })

  local null_ls = require("null-ls")

  local o = vim.o
  null_ls.setup({
    sources = {
      null_ls.builtins.formatting.stylua.with({ extra_args = { '--indent_type=spaces', '--indent_width=' .. o.tabstop } }),
      null_ls.builtins.diagnostics.eslint,
      null_ls.builtins.diagnostics.trail_space,

      null_ls.builtins.formatting.black, -- python formatting

      null_ls.builtins.completion.spell,
      null_ls.builtins.diagnostics.codespell,
      null_ls.builtins.diagnostics.write_good,

      null_ls.builtins.formatting.prettierd,
      null_ls.builtins.diagnostics.markdownlint, -- markdown
    },
  })

  require("mason-null-ls").setup({
    ensure_installed = {
      "stylua",
      "ruff",  -- python linter
      "mypy",  -- python type checker
      "black", -- python formatter
      "eslint",
      "trail_space",
      "spell",
      "codespell",
      "write_good",
      "prettierd",
      "markdownlint", -- markdown linter
    }
  })

  local cmp = require('cmp')
  local cmp_action = require('lsp-zero').cmp_action()

  -- load snippets
  require('luasnip.loaders.from_lua').lazy_load({ paths = './snippets/' })
  require('luasnip.loaders.from_vscode').lazy_load()


  local types = require("luasnip.util.types")

  require('luasnip').config.set_config({
    -- This one is cool cause if you have dynamic snippets, it updates as you type!
    updateevents = "TextChanged,TextChangedI",

    enable_autosnippets = true,

    ext_opts = {
      [types.choiceNode] = {
        active = {
          virt_text = { { " ⬅️c ", "NonTest" } },
        },
      },
      [types.insertNode] = {
        active = {
          virt_text = { { " ⬅️t", "NonTest" } },
        },
      },
    },
  })

  -- snippet keymap
  vim.keymap.set("i", "<c-o>", require "luasnip.extras.select_choice")
  vim.keymap.set("n", "<leader>csc", require "luasnip.extras.select_choice")
  vim.keymap.set("i", "<c-d>", "<Plug>luasnip-next-choice")
  vim.keymap.set("s", "<c-d>", "<Plug>luasnip-next-choice")
  vim.keymap.set("i", "<c-u>", "<Plug>luasnip-prev-choice")
  vim.keymap.set("s", "<c-u>", "<Plug>luasnip-prev-choice")

  cmp.setup({
    sources = {
      { name = 'nvim_lsp' }, -- completion for neovim
      { name = 'nvim_lua' }, -- completion for neovim lua api
      { name = 'luasnip' },  -- show snippets
      { name = 'buffer' },   -- show elements from your buffer
      { name = 'path' },     -- show file paths
      { name = 'calc' },     -- completion for math calculation
      { name = 'emoji' },    -- show emoji's
    },
    snippet = {
      expand = function(args)
        require('luasnip').lsp_expand(args.body)
      end,
    },
    mapping = cmp.mapping.preset.insert({
      ['<CR>'] = cmp.mapping.confirm({ select = false }),
      -- scroll up and down the documentation window
      ['<C-u>'] = cmp.mapping.scroll_docs(-4),
      ['<C-d>'] = cmp.mapping.scroll_docs(4),

      ['<C-l>'] = cmp_action.luasnip_jump_forward(),
      ['<C-h>'] = cmp_action.luasnip_jump_backward(),
    }),
    formatting = {
      fields = { 'abbr', 'kind', 'menu' },
      format = require('lspkind').cmp_format({
        mode = 'symbol_text',  -- show only symbol annotations
        maxwidth = 50,         -- prevent the popup from showing more than provided characters
        ellipsis_char = '...', -- when popup menu exceed maxwidth, the truncated part would show ellipsis_char instead
      })
    }
  })

  -- `/` cmdline setup.
  cmp.setup.cmdline('/', {
    mapping = cmp.mapping.preset.cmdline(),
    sources = {
      { name = 'buffer' }
    }
  })

  -- `:` cmdline setup.
  cmp.setup.cmdline(':', {
    mapping = cmp.mapping.preset.cmdline(),
    sources = cmp.config.sources({
      { name = 'path' }
    }, {
      { name = 'cmdline' }
    })
  })

  require("nvim-lightbulb").setup({
    autocmd = { enabled = true },
    virtual_text = {
      enabled = true,
      text = '󰌵'
    },
  })
end,
})

DEBUG

A Debug Adapter Protocol client implementation for Neovim


GitHub

plug({
'mfussenegger/nvim-dap',
dependencies = {
  -- Creates a beautiful debugger UI
  'rcarriga/nvim-dap-ui',

  -- add virtual text
  'theHamsta/nvim-dap-virtual-text',

  -- Installs the debug adapters for you
  'williamboman/mason.nvim',
  'jay-babu/mason-nvim-dap.nvim',

  -- Add your own debuggers here
  { 'leoluz/nvim-dap-go',           ft = { 'go' } },
  { 'mfussenegger/nvim-dap-python', ft = { 'python' } },
},
config = function()
  local dap = require("dap")
  local dapui = require("dapui")
  local mason_registry = require("mason-registry")

  require("mason-nvim-dap").setup {
    -- Makes a best effort to setup the various debuggers with
    -- reasonable debug configurations
    automatic_setup = true,

    -- You can provide additional configuration to the handlers,
    -- see mason-nvim-dap README for more information
    handlers = {},

    -- You'll need to check that you have the required things installed
    -- online, please don't ask me how to install them :)
    ensure_installed = {
      -- Update this to ensure that you have the debuggers for the langs you want
      'delve',
      'debugpy',
    },
  }

  -- Basic debugging keymaps, feel free to change to your liking!
  vim.keymap.set('n', '<F5>', dap.continue, { desc = 'Debug: Start/Continue' })
  vim.keymap.set('n', '<F1>', dap.step_into, { desc = 'Debug: Step Into' })
  vim.keymap.set('n', '<F2>', dap.step_over, { desc = 'Debug: Step Over' })
  vim.keymap.set('n', '<F3>', dap.step_out, { desc = 'Debug: Step Out' })
  vim.keymap.set('n', '<F4>', dap.step_back, { desc = 'Debug: Step Back' })
  vim.keymap.set('n', '<leader>db', dap.toggle_breakpoint, { desc = 'Debug: Toggle Breakpoint' })
  vim.keymap.set('n', '<leader>dB', dap.set_breakpoint, { desc = 'Debug: Set Breakpoint' })
  vim.keymap.set('n', '<leader>dl', dap.run_last, { desc = 'Debug: Run Last' })
  vim.keymap.set('n', '<leader>dc', function()
    dap.set_breakpoint(vim.fn.input 'Breakpoint condition: ')
  end, { desc = 'Debug: Set Breakpoint Condition' })

  -- Add virtual text showing contained values
  require("nvim-dap-virtual-text").setup({
    highlight_new_as_changed = true, -- highlight new variables in the same way as changed variables (if highlight_changed_variables)
    only_first_definition = false,   -- only show virtual text at first definition (if there are multiple)
  })

  -- Dap UI setup
  -- For more information, see |:help nvim-dap-ui|
  dapui.setup {
    -- Set icons to characters that are more likely to work in every terminal.
    --    Feel free to remove or use ones that you like more! :)
    --    Don't feel like these are good choices.
    icons = { expanded = '', collapsed = '', current_frame = '*' },
    controls = {
      icons = {
        pause = '',
        play = '',
        step_into = '',
        step_over = '',
        step_out = '',
        step_back = 'b',
        run_last = '▶▶',
        terminate = '',
        disconnect = '',
      },
    },
  }

  -- Toggle to see last session result. Without this, you can't see session output in case of unhandled exception.
  vim.keymap.set('n', '<F7>', dapui.toggle, { desc = 'Debug: See last session result.' })

  dap.listeners.after.event_initialized['dapui_config'] = dapui.open
  dap.listeners.before.event_terminated['dapui_config'] = dapui.close
  dap.listeners.before.event_exited['dapui_config'] = dapui.close

  -- Setup golang dap
  require('dap-go').setup()

  -- Setup python dap
  local debug_py_path = mason_registry.get_package("debugpy"):get_install_path() .. "/venv/bin/python"
  require('dap-python').setup(debug_py_path)
end,
})

TEXT MANIPULATION

Comment.nvim

Smart and Powerful commenting plugin for neovim


GitHub

plug({ 'numToStr/Comment.nvim', opts = {} })

Dial.nvim

Extended increment/decrement plugin


GitHub

plug({
 'monaqa/dial.nvim',
 config = function()
   local augend = require("dial.augend")
   require("dial.config").augends:register_group {
     -- default augends used when no group name is specified
     default = {
       augend.integer.alias.decimal,  -- nonnegative decimal number (0, 1, 2, 3, ...)
       augend.constant.alias.bool,    -- boolean value (true <-> false)
       augend.integer.alias.hex,      -- nonnegative hex number  (0x01, 0x1a1f, etc.)
       augend.date.alias["%Y/%m/%d"], -- date (2022/02/19, etc.)
       augend.date.alias["%Y-%m-%d"],
       augend.date.alias["%m/%d"],
       augend.date.alias["%H:%M"],
       augend.constant.new {
         elements = { "and", "or" },
         word = true,   -- if false, "sand" is incremented into "sor", "doctor" into "doctand", etc.
         cyclic = true, -- "or" is incremented into "and".
         preserve_case = true,
       },
       augend.constant.new {
         elements = { "yes", "no" },
         word = true,   -- if false, "sand" is incremented into "sor", "doctor" into "doctand", etc.
         cyclic = true, -- "or" is incremented into "and".
         preserve_case = true,
       },
       augend.constant.new {
         elements = { "&&", "||" },
         word = false,
         cyclic = true,
       },
     },
   }

   vim.keymap.set("n", "<C-a>", require("dial.map").inc_normal(), { noremap = true })
   vim.keymap.set("n", "<C-x>", require("dial.map").dec_normal(), { noremap = true })
   vim.keymap.set("n", "g<C-a>", require("dial.map").inc_gnormal(), { noremap = true })
   vim.keymap.set("n", "g<C-x>", require("dial.map").dec_gnormal(), { noremap = true })
   vim.keymap.set("v", "<C-a>", require("dial.map").inc_visual(), { noremap = true })
   vim.keymap.set("v", "<C-x>", require("dial.map").dec_visual(), { noremap = true })
   vim.keymap.set("v", "g<C-a>", require("dial.map").inc_gvisual(), { noremap = true })
   vim.keymap.set("v", "g<C-x>", require("dial.map").dec_gvisual(), { noremap = true })
 end,
})

Nvim-Surround

Add, delete, change and select surrounding pairs


GitHub

plug({
 "kylechui/nvim-surround",
 version = "*", -- Use for stability; omit to use `main` branch for the latest features
 event = "VeryLazy",
 config = function()
   require("nvim-surround").setup({
     -- Configuration here, or leave empty to use defaults
   })
 end,
})

Nvim-various-textobjs

Bundle of more than two dozen new textobjects for Neovim.


GitHub

plug({
  "chrisgrieser/nvim-various-textobjs",
  lazy = false,
  opts = {
    keymaps = {
      useDefault = true,
      disable = { "gc" },
    }
  },
})

Treesj

A plugin for splitting/joining blocks of code like arrays, hashes, statements, objects, dictionaries and more.


GitHub

plug({
  "Wansmer/treesj",
  dependencies = "nvim-treesitter/nvim-treesitter",
  keys = {
    { "<leader>j", function() require("treesj").toggle() end, desc = "󰗈 Split-join lines" },
  },
})

Text case

Case conversion, upper to lower to camel to snake and more.


GitHub

plug({
  "johmsalas/text-case.nvim",
  init = function()
    local casings = {
      { char = "u", arg = "upper",      desc = "UPPER CASE" },
      { char = "l", arg = "lower",      desc = "lower case" },
      { char = "t", arg = "title",      desc = "Title Case" },
      { char = "c", arg = "camel",      desc = "camelCase" },
      { char = "C", arg = "pascal",     desc = "CamelCase" },
      { char = "s", arg = "snake",      desc = "snake_case" },
      { char = "_", arg = "snake",      desc = "snake_case" },
      { char = "d", arg = "dash",       desc = "dash-case" },
      { char = "D", arg = "title_dash", desc = "Title-Dash-Case" },
      { char = "-", arg = "dash",       desc = "dash-case" },
      { char = "p", arg = "phrase",     desc = "Phrase case" },
      { char = "/", arg = "path",       desc = "path/case" },
      { char = "S", arg = "constant",   desc = "UPPER_SNAKE_CASE" },
      { char = ".", arg = "dot",        desc = "dot.case" },
    }

    for _, case in pairs(casings) do
      vim.keymap.set(
        "n",
        "<leader>c" .. case.char,
        ("<cmd>lua require('textcase').current_word('to_%s_case')<CR>"):format(case.arg),
        { desc = case.desc }
      )
      vim.keymap.set(
        "v",
        "<leader>c" .. case.char,
        ("<cmd>lua require('textcase').operator('to_%s_case')<CR>"):format(case.arg),
        { desc = case.desc }
      )
      vim.keymap.set(
        "n",
        "<leader>C" .. case.char,
        ("<cmd>lua require('textcase').lsp_rename('to_%s_case')<CR>"):format(case.arg),
        { desc = "󰒕 " .. case.desc }
      )
    end
  end,
})

Autolist

Automatic list continuation and formatting.


GitHub

plug({
  "gaoDean/autolist.nvim",
  ft = {
    "markdown",
    "text",
    "tex",
    "plaintex",
    "norg",
  },
  config = function()
    require("autolist").setup()

    -- vim.keymap.set("i", "<tab>", "<cmd>AutolistTab<cr>")
    -- vim.keymap.set("i", "<s-tab>", "<cmd>AutolistShiftTab<cr>")
    -- vim.keymap.set("i", "<c-t>", "<c-t><cmd>AutolistRecalculate<cr>") -- an example of using <c-t> to indent
    vim.keymap.set("i", "<CR>", "<CR><cmd>AutolistNewBullet<cr>")
    vim.keymap.set("n", "o", "o<cmd>AutolistNewBullet<cr>")
    vim.keymap.set("n", "O", "O<cmd>AutolistNewBulletBefore<cr>")
    vim.keymap.set("n", "<CR>", "<cmd>AutolistToggleCheckbox<cr><CR>")
    vim.keymap.set("n", "<C-r>", "<cmd>AutolistRecalculate<cr>")

    -- cycle list types with dot-repeat
    vim.keymap.set("n", "<leader>ln", require("autolist").cycle_next_dr, { expr = true })
    vim.keymap.set("n", "<leader>lp", require("autolist").cycle_prev_dr, { expr = true })

    -- if you don't want dot-repeat
    -- vim.keymap.set("n", "<leader>cn", "<cmd>AutolistCycleNext<cr>")
    -- vim.keymap.set("n", "<leader>cp", "<cmd>AutolistCycleNext<cr>")

    -- functions to recalculate list on edit
    vim.keymap.set("n", ">>", ">><cmd>AutolistRecalculate<cr>")
    vim.keymap.set("n", "<<", "<<<cmd>AutolistRecalculate<cr>")
    vim.keymap.set("n", "dd", "dd<cmd>AutolistRecalculate<cr>")
    vim.keymap.set("v", "d", "d<cmd>AutolistRecalculate<cr>")
  end,
})

TERMINAL

Toggle Term

Persist and toggle multiple terminals during an editing session.


GitHub

plug({
  'akinsho/toggleterm.nvim',
  version = "*",
  opts = {},
  config = function()
    require("toggleterm").setup()

    -- set keymaps to toggle toggleterm
    vim.keymap.set('n', '<c-b>', [[<Cmd>exe v:count1 . "ToggleTerm size=12 direction=horizontal"<CR>]],
      { desc = 'Toggle Term Horizontal' })
    vim.keymap.set('i', '<c-b>', [[<Cmd>exe v:count1 . "ToggleTerm size=12 direction=horizontal"<CR>]],
      { desc = 'Toggle Term Horizontal' })
    vim.keymap.set('t', '<c-b>', [[<Cmd>exe v:count1 . "ToggleTerm size=12 direction=horizontal"<CR>]],
      { desc = 'Toggle Term Horizontal' })

    vim.keymap.set('n', '<c-t>', [[<Cmd>exe v:count1 . "ToggleTerm size=80 direction=vertical"<CR>]],
      { desc = 'Toggle Term Vertical' })
    vim.keymap.set('i', '<c-t>', [[<Cmd>exe v:count1 . "ToggleTerm size=80 direction=vertical"<CR>]],
      { desc = 'Toggle Term Vertical' })
    vim.keymap.set('t', '<c-t>', [[<Cmd>exe v:count1 . "ToggleTerm size=80 direction=vertical"<CR>]],
      { desc = 'Toggle Term Vertical' })

    vim.keymap.set('n', '<c-f>', [[<Cmd>exe v:count1 . "ToggleTerm size=80 direction=float"<CR>]],
      { desc = 'Toggle Term Vertical' })
    vim.keymap.set('i', '<c-f>', [[<Cmd>exe v:count1 . "ToggleTerm size=80 direction=float"<CR>]],
      { desc = 'Toggle Term Vertical' })
    vim.keymap.set('t', '<c-f>', [[<Cmd>exe v:count1 . "ToggleTerm size=80 direction=float"<CR>]],
      { desc = 'Toggle Term Vertical' })

    local terminal = require("toggleterm.terminal").Terminal

    -- Set up task warrior Vit tui app toggle
    local vit = terminal:new({
      cmd = "vit",
      count = 1000,
      direction = "horizontal",
      hidden = true,
      close_on_exit = true,
      auto_scroll = false,
      start_in_insert = true,
    })

    vim.keymap.set({"n", "i", "t", "v"}, "<cm-v>", function () vit:toggle() end, {noremap = true, silent = true, desc = "Toggle Vit"})

    -- Set up powershell toggle term
    local powershell = terminal:new({
      cmd = "powershell.exe",
      count = 2,
      direction = "horizontal",
      hidden = false,
      close_on_exit = false,
      auto_scroll = true,
      start_in_insert = true,
    })

    vim.keymap.set({"n", "i", "t", "v"}, "<cm-p>", function () powershell:toggle() end, {noremap = true, silent = true, desc = "Toggle Powershell"})
  end,
})

Flatten

Open files from terminal buffers without creating a nested session.


GitHub

plug({
   "willothy/flatten.nvim",
   branch = "1.0-dev",
   opts = function()
     ---@type Terminal?
     local saved_terminal

     return {
       window = {
         open = "alternate",
       },
       callbacks = {
         should_block = function(argv)
           -- Note that argv contains all the parts of the CLI command, including
           -- Neovim's path, commands, options and files.
           -- See: :help v:argv

           -- In this case, we would block if we find the `-b` flag
           -- This allows you to use `nvim -b file1` instead of
           -- `nvim --cmd 'let g:flatten_wait=1' file1`
           return vim.tbl_contains(argv, "-b")

           -- Alternatively, we can block if we find the diff-mode option
           -- return vim.tbl_contains(argv, "-d")
         end,
         pre_open = function()
           local term = require("toggleterm.terminal")
           local termid = term.get_focused_id()
           saved_terminal = term.get(termid)
         end,
         post_open = function(bufnr, winnr, ft, is_blocking)
           if is_blocking and saved_terminal then
             -- Hide the terminal while it's blocking
             saved_terminal:close()
           else
             -- If it's a normal file, just switch to its window
             vim.api.nvim_set_current_win(winnr)
           end

           -- If the file is a git commit, create one-shot autocmd to delete its buffer on write
           -- If you just want the toggleable terminal integration, ignore this bit
           if ft == "gitcommit" or ft == "gitrebase" then
             vim.api.nvim_create_autocmd("BufWritePost", {
               buffer = bufnr,
               once = true,
               callback = vim.schedule_wrap(function()
                 vim.api.nvim_buf_delete(bufnr, {})
               end),
             })
           end
         end,
         block_end = function()
           -- After blocking ends (for a git commit, etc), reopen the terminal
           vim.schedule(function()
             if saved_terminal then
               saved_terminal:open()
               saved_terminal = nil
             end
           end)
         end,
       },
     }
   end,
})

VIM TABLE MODE

Table creator & formatter allowing one to create neat tables as you type.


GitHub

plug({ "https://github.com/dhruvasagar/vim-table-mode" })

TODO COMMENTS

To highlight and search for todo comments like TODO, HACK, BUG in your code base.


GitHub

plug({
  "folke/todo-comments.nvim",
  enabled = true,
  cmd = { "TodoTrouble", "TodoTelescope" },
  event = { "BufReadPost", "BufNewFile" },
  config = true,
  -- stylua: ignore
  keys = {
    { "]t",         function() require("todo-comments").jump_next() end, desc = "Next todo comment" },
    { "[t",         function() require("todo-comments").jump_prev() end, desc = "Previous todo comment" },
    { "<leader>xt", "<cmd>TodoTrouble<cr>",                              desc = "Todo (Trouble)" },
    { "<leader>xT", "<cmd>TodoTrouble keywords=TODO,FIX,FIXME<cr>",      desc = "Todo/Fix/Fixme (Trouble)" },
    { "<leader>st", "<cmd>TodoTelescope<cr>",                            desc = "Todo" },
    { "<leader>sT", "<cmd>TodoTelescope keywords=TODO,FIX,FIXME<cr>",    desc = "Todo/Fix/Fixme" },
  },
})

MARKS

A better user experience for interacting with and manipulating Vim marks.


GitHub

plug({
  'chentoast/marks.nvim',
  enabled = true,
  config = function()
    require 'marks'.setup {
      default_mappings = true,
      signs = true,
      mappings = {}
    }
  end,
})

MARKDOWN

Nvim Toc

Generate table of contents for markdown files.


GitHub

plug({
  'richardbizik/nvim-toc',
  ft = { 'markdown' },
  config = function()
    require('nvim-toc').setup({})
  end,
})

Glow

Preview markdown code directly in your neovim terminal.


Requirements

You must install Glow. GitHub

plug({
  "ellisonleao/glow.nvim",
  config = true,
  cmd = "Glow",
})

Preview

Preview Markdown in your modern browser with synchronised scrolling and flexible configuration.


GitHub

plug({
  "iamcco/markdown-preview.nvim",
  cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" },
  ft = { "markdown" },
  build = function() vim.fn["mkdp#util#install"]() end,
})

Hl-MDCodeblock

Add treesitter highlights to markdown code blocks.


GitHub

plug({
  'yaocccc/nvim-hl-mdcodeblock.lua',
  enabled = false,
  dependencies = {'nvim-treesitter/nvim-treesitter'},
  config = function()
    require('hl-mdcodeblock').setup({
      -- option
    })
  end
})

TROUBLE

A pretty list for showing diagnostics, references, telescope results, quickfix and location lists to help you solve all the trouble your code is causing.


GitHub

plug({
  "folke/trouble.nvim",
  enabled = true,
  lazy = true,
  dependencies = { "nvim-tree/nvim-web-devicons" },
  keys = {
    { "<leader>xx", function() require("trouble").open() end, desc = "Trouble" },
    { "<leader>xw", function() require("trouble").open("workspace_diagnostics") end, desc = "Workspace Diagnostics" },
    { "<leader>xd", function() require("trouble").open("document_diagnostics") end, desc = "Document Diagnostics" },
    { "<leader>xq", function() require("trouble").open("quickfix") end, desc = "Quickfix" },
    { "<leader>xl", function() require("trouble").open("loclist") end, desc = "Local List" },
    { "gR", function() require("trouble").open("lsp_references") end, desc = "Lsp References" },
  },
})

WHICH KEY

A lua plugin that displays a popup with possible key bindings of the command you started typing.


GitHub

plug({
  'folke/which-key.nvim',
  enabled = true,
  config = function()
    local wk = require('which-key')

    wk.register({
      ['<leader>'] = {
        ["<Tab>"] = { name = '+Tab' },
        [";"] = { name = '+Command' },
        b = { name = '+Buffer' },
        c = { name = '+Case' },
        C = { name = '+Case' },
        d = { name = '+Debug' },
        f = { name = '+Find' },
        g = { name = '+Git' },
        h = { name = '+Hunk' },
        l = { name = '+Lsp' },
        s = { name = '+Search' },
        t = { name = '+Table' },
        T = { name = '+Text' },
        w = { name = '+Window' },
        x = { name = '+Diagnostics' },
      },
    })
  end,
})

HLSLENS

Nvim-hlslens helps you better glance at matched information, seamlessly jump between matched instances. When searching, search count is shown next to the cursor as virtual text.


GitHub

plug({
  "kevinhwang91/nvim-hlslens",
  enabled = true,
  opts = {},
})

YANKY

Improve yank and put functionalities for Neovim.


GitHub

plug({
  "gbprod/yanky.nvim",
  dependencies = {
    {
      "kkharji/sqlite.lua",
      enabled = not jit.os:find("Windows")
    },
  },
  config = function()
    require("yanky").setup({
      ring = {
        history_length = 100,
        sync_with_numbered_registers = true,
        cancel_event = "update",
      },
      system_clipboard = {
        sync_with_ring = true,
      },
      highlight = {
        on_put = true,
        on_yank = true,
        timer = 500,
      },
      preserve_cursor_position = {
        enabled = true,
      },
    })
  end,
  keys = {
    {
      "<leader>p",
      function() 
        local yanky = require("yanky")
        local history = yanky.history()
        Snacks.picker.pick({
          items = history,
          format = function(item) return item.regcontents end,
          preview = false,
        }, function(item)
          yanky.put(item)
        end)
      end,
      desc = "Open Yank History"
    },
    {
      "y",
      "<Plug>(YankyYank)",
      mode = { "n", "x" },
      desc =
        "Yank text"
    },
    {
      "p",
      "<Plug>(YankyPutAfter)",
      mode = { "n", "x" },
      desc =
        "Put yanked text after cursor"
    },
    {
      "P",
      "<Plug>(YankyPutBefore)",
      mode = { "n", "x" },
      desc =
        "Put yanked text before cursor"
    },
    {
      "gp",
      "<Plug>(YankyGPutAfter)",
      mode = { "n", "x" },
      desc =
        "Put yanked text after selection"
    },
    {
      "gP",
      "<Plug>(YankyGPutBefore)",
      mode = { "n", "x" },
      desc =
        "Put yanked text before selection"
    },
    {
      "[y",
      "<Plug>(YankyCycleForward)",
      desc =
        "Cycle forward through yank history"
    },
    {
      "]y",
      "<Plug>(YankyCycleBackward)",
      desc =
        "Cycle backward through yank history"
    },
    {
      "]p",
      "<Plug>(YankyPutIndentAfterLinewise)",
      desc =
        "Put indented after cursor (linewise)"
    },
    {
      "[p",
      "<Plug>(YankyPutIndentBeforeLinewise)",
      desc =
        "Put indented before cursor (linewise)"
    },
    {
      "]P",
      "<Plug>(YankyPutIndentAfterLinewise)",
      desc =
        "Put indented after cursor (linewise)"
    },
    {
      "[P",
      "<Plug>(YankyPutIndentBeforeLinewise)",
      desc =
        "Put indented before cursor (linewise)"
    },
    {
      ">p",
      "<Plug>(YankyPutIndentAfterShiftRight)",
      desc =
        "Put and indent right"
    },
    {
      "<p",
      "<Plug>(YankyPutIndentAfterShiftLeft)",
      desc =
        "Put and indent left"
    },
    {
      ">P",
      "<Plug>(YankyPutIndentBeforeShiftRight)",
      desc =
        "Put before and indent right"
    },
    {
      "<P",
      "<Plug>(YankyPutIndentBeforeShiftLeft)",
      desc =
        "Put before and indent left"
    },
    {
      "=p",
      "<Plug>(YankyPutAfterFilter)",
      desc =
        "Put after applying a filter"
    },
    {
      "=P",
      "<Plug>(YankyPutBeforeFilter)",
      desc =
        "Put before applying a filter"
    },
  },
})

@end

MINI SESSIONS

Session management (read, write, delete)


GitHub

plug({
  'echasnovski/mini.sessions',
  version = false,
  config = function()
    require('mini.sessions').setup({
    })

    vim.api.nvim_create_user_command(
      'SessionWrite',
      function(opts)
        if (opts['args']) then
          MiniSessions.write(opts.args)
        end
      end,
      { nargs = 1 }
    )
  end,
})

TREESITTER

Treesitter

The goal of nvim-treesitter is both to provide a simple and easy way to use the interface for tree-sitter in Neovim and to provide some basic functionality such as highlighting based on it.


GitHub

plug({
  -- Highlight, edit, and navigate code
  'nvim-treesitter/nvim-treesitter',
  priority = 5000,
  dependencies = {
    'nvim-treesitter/nvim-treesitter-textobjects',
    { "JoosepAlviste/nvim-ts-context-commentstring", lazy = true }
  },
  build = ':TSUpdate',
  main = 'nvim-treesitter.configs',
  opts = {
    -- Add languages to be installed here that you want installed for treesitter
    ensure_installed = {
      'lua',
      'vim',
      'vimdoc',
      'norg',
      'regex',
      'bash',
      'c',
      'cpp',
      'make',
      'markdown',
      'markdown_inline',
      'comment',
      'html',
      'php',
      'http',
      'css',
      'javascript',
      'typescript',
      'go',
      'python',
      'json',
      'toml',
      'yaml',
      'sql',
      'r',
      'gitattributes',
      'gitignore',
    },

    -- Autoinstall languages that are not installed. Defaults to false (but you can change for yourself!)
    auto_install = true,

    highlight = { enable = true },
    indent = { enable = true },
    incremental_selection = {
      enable = true,
      keymaps = {
        init_selection = '<c-space>',
        node_incremental = '<c-space>',
        scope_incremental = '<c-s>',
        node_decremental = '<M-space>',
      },
    },

    textobjects = {
      select = {
        enable = true,
        lookahead = true, -- Automatically jump forward to textobj, similar to targets.vim
        keymaps = {
          -- You can use the capture groups defined in textobjects.scm
          ['aa'] = '@parameter.outer',
          ['ia'] = '@parameter.inner',
          ['af'] = '@function.outer',
          ['if'] = '@function.inner',
          ['ac'] = '@class.outer',
          ['ic'] = '@class.inner',
        },
      },
      move = {
        enable = true,
        set_jumps = true, -- whether to set jumps in the jumplist
        goto_next_start = {
          [']m'] = '@function.outer',
          [']]'] = '@class.outer',
        },
        goto_next_end = {
          [']M'] = '@function.outer',
          [']['] = '@class.outer',
        },
        goto_previous_start = {
          ['[m'] = '@function.outer',
          ['[['] = '@class.outer',
        },
        goto_previous_end = {
          ['[M'] = '@function.outer',
          ['[]'] = '@class.outer',
        },
      },
      swap = {
        enable = true,
        swap_next = {
          ['<leader>a'] = '@parameter.inner',
        },
        swap_previous = {
          ['<leader>A'] = '@parameter.inner',
        },
      },
    },

    -- nvim-treesitter-endwise
    endwise = { enable = true },
  }
})

Endwise

Wisely add "end" in Ruby, Lua, Vimscript, etc.


GitHub

plug({ -- basically autopair, but for keywords
  "RRethy/nvim-treesitter-endwise",
  -- event = "InsertEnter",
  dependencies = "nvim-treesitter/nvim-treesitter",
})

Virtual Text Context

Shows virtual text of the current context after functions, methods, statements, etc.


GitHub

plug({ -- virtual text context at the end of a scope
  "haringsrob/nvim_context_vt",
  event = "VeryLazy",
  dependencies = "nvim-treesitter/nvim-treesitter",
  opts = {
    prefix = "󱞷",
    highlight = "NonText",
    min_rows = 1,
    disable_ft = { "markdown" },
    min_rows_ft = { python = 10, yaml = 15, css = 15 },

    -- set up custom parser to return the whole line for context
    custom_parser = function(node, _, opts)
      -- If you return `nil`, no virtual text will be displayed.
      if node:type() == 'function' then
        return nil
      end

      -- get the context line
      local bufnr = vim.api.nvim_get_current_buf()
      local start_row, _, _, _ = vim.treesitter.get_node_range(node)
      local line = vim.api.nvim_buf_get_lines(bufnr, start_row, start_row + 1, false)[1]

      -- remove whitespace before context
      local context = string.gsub(line, '^%s*', '')

      return opts.prefix .. ' ' .. context
    end,
  },
})

Mini Ai

Extend and create a/i textobjects.


GitHub

plug({ -- extend and create a/i textobjects
  "echasnovski/mini.ai",
  event = "VeryLazy",
  dependencies = { "nvim-treesitter-textobjects" },
  opts = function()
    local ai = require("mini.ai")
    return {
      n_lines = 500,
      custom_textobjects = {
        o = ai.gen_spec.treesitter({
          a = { "@block.outer", "@conditional.outer", "@loop.outer" },
          i = { "@block.inner", "@conditional.inner", "@loop.inner" },
        }, {}),
        f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }, {}),
        c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }, {}),
      },
    }
  end,
  config = function(_, opts)
    require("mini.ai").setup(opts)
    -- register all text objects with which-key
    local i = {
      [" "] = "Whitespace",
      ['"'] = 'Balanced "',
      ["'"] = "Balanced '",
      ["`"] = "Balanced `",
      ["("] = "Balanced (",
      [")"] = "Balanced ) including white-space",
      [">"] = "Balanced > including white-space",
      ["<lt>"] = "Balanced <",
      ["]"] = "Balanced ] including white-space",
      ["["] = "Balanced [",
      ["}"] = "Balanced } including white-space",
      ["{"] = "Balanced {",
      ["?"] = "User Prompt",
      _ = "Underscore",
      a = "Argument",
      b = "Balanced ), ], }",
      c = "Class",
      f = "Function",
      o = "Block, conditional, loop",
      q = "Quote `, \", '",
      t = "Tag",
    }
    local a = vim.deepcopy(i)
    for k, v in pairs(a) do
      a[k] = v:gsub(" including.*", "")
    end

    local ic = vim.deepcopy(i)
    local ac = vim.deepcopy(a)
    for key, name in pairs({ n = "Next", l = "Last" }) do
      i[key] = vim.tbl_extend("force", { name = "Inside " .. name .. " textobject" }, ic)
      a[key] = vim.tbl_extend("force", { name = "Around " .. name .. " textobject" }, ac)
    end
    require("which-key").register({
      mode = { "o", "x" },
      i = i,
      a = a,
    })
  end,
})

LAZY

Set up the lazy.nvim plugin manager, use the plugins table to install and load plugins. See Lazy Helper Function for the plugin() function.


GitHub

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)

-- Plugins to be installed
-- Help with plugin setup: https://github.com/folke/lazy.nvim#-structuring-your-plugins
require('lazy').setup(plugins, {})


-- open lazy menu
vim.keymap.set("n", "<leader>;l", "<cmd>Lazy<cr>", { desc = "Lazy Plugin Manager" })

KEYMAPS

Here I configure my native neovim keybindings, these are any key binds not involved with any plugin.


local function map(mode, lhs, rhs, opts)
  local keys = require("lazy.core.handler").handlers.keys
  ---@cast keys LazyKeysHandler
  -- do not create the keymap if a lazy keys handler exists
  if not keys.active[keys.parse({ lhs, mode = mode }).id] then
    opts = opts or {}
    opts.silent = opts.silent ~= false
    if opts.remap and not vim.g.vscode then
      opts.remap = nil
    end
    vim.keymap.set(mode, lhs, rhs, opts)
  end
end

-- better up/down
map({ "n", "x" }, "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
map({ "n", "x" }, "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })

-- Move to window using the <ctrl> hjkl keys
map("n", "<C-h>", "<C-w>h", { desc = "Go to left window", remap = true })
map("n", "<C-j>", "<C-w>j", { desc = "Go to lower window", remap = true })
map("n", "<C-k>", "<C-w>k", { desc = "Go to upper window", remap = true })
map("n", "<C-l>", "<C-w>l", { desc = "Go to right window", remap = true })

-- Resize window using <ctrl> arrow keys
map("n", "<C-Up>", "<cmd>resize +2<cr>", { desc = "Increase window height" })
map("n", "<C-Down>", "<cmd>resize -2<cr>", { desc = "Decrease window height" })
map("n", "<C-Left>", "<cmd>vertical resize -2<cr>", { desc = "Decrease window width" })
map("n", "<C-Right>", "<cmd>vertical resize +2<cr>", { desc = "Increase window width" })

-- Move Lines
map("n", "<A-j>", "<cmd>m .+1<cr>==", { desc = "Move down" })
map("n", "<A-k>", "<cmd>m .-2<cr>==", { desc = "Move up" })
map("i", "<A-j>", "<esc><cmd>m .+1<cr>==gi", { desc = "Move down" })
map("i", "<A-k>", "<esc><cmd>m .-2<cr>==gi", { desc = "Move up" })
map("v", "<A-j>", ":m '>+1<cr>gv=gv", { desc = "Move down" })
map("v", "<A-k>", ":m '<-2<cr>gv=gv", { desc = "Move up" })

-- Navigate through buffers
map("n", "<S-h>", "<cmd>bprevious<cr>", { desc = "Prev buffer" })
map("n", "<S-l>", "<cmd>bnext<cr>", { desc = "Next buffer" })
map("n", "[b", "<cmd>bprevious<cr>", { desc = "Prev buffer" })
map("n", "]b", "<cmd>bnext<cr>", { desc = "Next buffer" })

map("n", "<leader>bb", "<cmd>e #<cr>", { desc = "Switch to Other Buffer" })
map("n", "<leader>`", "<cmd>e #<cr>", { desc = "Switch to Other Buffer" })

-- Clear search with <esc>
map({ "i", "n" }, "<esc>", "<cmd>noh<cr><esc>", { desc = "Escape and clear hlsearch" })

-- Clear search, diff update and redraw
-- taken from runtime/lua/_editor.lua
map(
  "n",
  "<leader>ur",
  "<Cmd>nohlsearch<Bar>diffupdate<Bar>normal! <C-L><CR>",
  { desc = "Redraw / clear hlsearch / diff update" }
)

map({ "n", "x" }, "gw", "*N", { desc = "Search word under cursor" })

-- https://github.com/mhinz/vim-galore#saner-behavior-of-n-and-n
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" })

-- Add undo break-points
map("i", ",", ",<c-g>u")
map("i", ".", ".<c-g>u")
map("i", ";", ";<c-g>u")

-- save file
map({ "i", "v", "n", "s" }, "<C-s>", "<cmd>w<cr><esc>", { desc = "Save file" })

--keywordprg
map("n", "<leader>K", "<cmd>norm! K<cr>", { desc = "Keywordprg" })

-- better indenting
map("v", "<", "<gv")
map("v", ">", ">gv")

-- new file
map("n", "<leader>fn", "<cmd>enew<cr>", { desc = "New File" })

map("n", "<leader>xl", "<cmd>lopen<cr>", { desc = "Location List" })
map("n", "<leader>xq", "<cmd>copen<cr>", { desc = "Quickfix List" })

-- quit
map("n", "<leader>qq", "<cmd>qa<cr>", { desc = "Quit all" })

-- highlights under cursor
if vim.fn.has("nvim-0.9.0") == 1 then
  map("n", "<leader>ui", vim.show_pos, { desc = "Inspect Pos" })
end


-- Terminal Mappings
map("t", "<esc><esc>", "<c-\\><c-n>", { desc = "Enter Normal Mode" })
map("t", "<c-[><c-[>", "<c-\\><c-n>", { desc = "Enter Normal Mode" })
map("t", "<C-h>", "<cmd>wincmd h<cr>", { desc = "Go to left window" })
map("t", "<C-j>", "<cmd>wincmd j<cr>", { desc = "Go to lower window" })
map("t", "<C-k>", "<cmd>wincmd k<cr>", { desc = "Go to upper window" })
map("t", "<C-l>", "<cmd>wincmd l<cr>", { desc = "Go to right window" })
map("t", "<C-/>", "<cmd>close<cr>", { desc = "Hide Terminal" })
map("t", "<c-_>", "<cmd>close<cr>", { desc = "which_key_ignore" })

-- windows
map("n", "<leader>ww", "<C-W>p", { desc = "Other window", remap = true })
map("n", "<leader>wd", "<C-W>c", { desc = "Delete window", remap = true })
map("n", "<leader>w-", "<C-W>s", { desc = "Split window below", remap = true })
map("n", "<leader>w|", "<C-W>v", { desc = "Split window right", remap = true })
map("n", "<leader>-", "<C-W>s", { desc = "Split window below", remap = true })
map("n", "<leader>|", "<C-W>v", { desc = "Split window right", remap = true })

-- tabs
map("n", "<leader><tab>G", "<cmd>tablast<cr>", { desc = "Last Tab" })
map("n", "<leader><tab>g", "<cmd>tabfirst<cr>", { desc = "First Tab" })
map("n", "<leader><tab><tab>", "<cmd>tabnew<cr>", { desc = "New Tab" })
map("n", "<leader><tab>]", "<cmd>tabnext<cr>", { desc = "Next Tab" })
map("n", "<leader><tab>d", "<cmd>tabclose<cr>", { desc = "Close Tab" })
map("n", "<leader><tab>[", "<cmd>tabprevious<cr>", { desc = "Previous Tab" })
map("n", "<leader><tab>s", "<cmd>tab split<cr>", { desc = "Split Tab" })

-- Convenience
map('n', '\\', ':%s//g<left><left>', { desc = "Search buffer" })
map('v', '\\', ':s//g<Left><Left>', { desc = "Search selection" })
map("n", "<leader>S", "<cmd>set spell!<cr>", { desc = "Toggle spell" })

-- Insert file name
map("i", "<C-f>f", '<C-R>=expand("%:t")<cr>', { desc = "Insert current filename" })
map("i", "<C-f>F", '<C-R>=expand("%:t:r")<cr>', { desc = "Insert current filename without extension" })
map("i", "<C-f>e", '<C-R>=expand("%:e")<cr>', { desc = "Insert extendion of current file" })
map("i", "<C-f>p", '<C-R>=expand("%:p:h")<cr>', { desc = "Insert absolute path of current directory" })
map("i", "<C-f>P", '<C-R>=expand("%:h")<cr>', { desc = "Insert relative path of current directory" })
map("i", "<C-f>d", '<C-R>=expand("%:p:h:t")<cr>', { desc = "Insert parent directory of current file" })

HIGHLIGHTS

Here I configure any highlights.


local highlight_group = vim.api.nvim_create_augroup('YankHighlight', { clear = true })
vim.api.nvim_create_autocmd('TextYankPost', {
  callback = function()
    vim.highlight.on_yank()
  end,
  group = highlight_group,
  pattern = '*',
})

AUTOCOMMANDS

Here I configure any autocommands.


local function augroup(name)
  return vim.api.nvim_create_augroup("shm_" .. name, { clear = true })
end

-- Use internal formatting for bindings like gq.
vim.api.nvim_create_autocmd('LspAttach', {
  callback = function(args)
    vim.bo[args.buf].formatexpr = nil
  end,
})

-- Check if we need to reload the file when it changed
vim.api.nvim_create_autocmd({ "FocusGained", "TermClose", "TermLeave" }, {
  group = augroup("checktime"),
  command = "checktime",
})

-- Highlight on yank
vim.api.nvim_create_autocmd("TextYankPost", {
  group = augroup("highlight_yank"),
  callback = function()
    vim.highlight.on_yank()
  end,
})

-- resize splits if window got resized
vim.api.nvim_create_autocmd({ "VimResized" }, {
  group = augroup("resize_splits"),
  callback = function()
    vim.cmd("tabdo wincmd =")
  end,
})

-- go to last loc when opening a buffer
vim.api.nvim_create_autocmd("BufReadPost", {
  group = augroup("last_loc"),
  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(buf, '"')
    local lcount = vim.api.nvim_buf_line_count(buf)
    if mark[1] > 0 and mark[1] <= lcount then
      pcall(vim.api.nvim_win_set_cursor, 0, mark)
    end
  end,
})

-- close some filetypes with <q>
vim.api.nvim_create_autocmd("FileType", {
  group = augroup("close_with_q"),
  pattern = {
    "PlenaryTestPopup",
    "help",
    "lspinfo",
    "man",
    "notify",
    "qf",
    "spectre_panel",
    "startuptime",
    "tsplayground",
    "neotest-output",
    "checkhealth",
    "neotest-summary",
    "neotest-output-panel",
    "fugitive",
  },
  callback = function(event)
    vim.bo[event.buf].buflisted = false
    vim.keymap.set("n", "q", "<cmd>close<cr>", { buffer = event.buf, silent = true })
  end,
})

-- close some filetypes with <esc>
vim.api.nvim_create_autocmd("FileType", {
  group = augroup("close_with_esc"),
  pattern = {
    "fugitive",
    "git",
  },
  callback = function(event)
    vim.bo[event.buf].buflisted = false
    vim.keymap.set("n", "<esc>", "<cmd>close<cr>", { buffer = event.buf, silent = true })
  end,
})

-- wrap and check for spell in text filetypes
vim.api.nvim_create_autocmd("FileType", {
  group = augroup("wrap_spell"),
  pattern = { "gitcommit", "markdown" },
  callback = function()
    vim.opt_local.wrap = true
    vim.opt_local.spell = true
  end,
})

-- Auto create dir when saving a file, in case some intermediate directory does not exist
vim.api.nvim_create_autocmd({ "BufWritePre" }, {
  group = augroup("auto_create_dir"),
  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,
})

-- disable line numbering and start in insert mode for terminal
vim.api.nvim_create_autocmd({ "TermOpen", "TermEnter" }, {
  group = augroup("terminal"),
  callback = function ()
    vim.opt_local.number = false
    vim.opt_local.relativenumber = false
    vim.cmd("startinsert")
  end,
})

-- reload folds for treesitter bug
-- see https://github.com/nvim-treesitter/nvim-treesitter/issues/1337
vim.api.nvim_create_autocmd({ "BufReadPost" }, {
    group = augroup("folds"),
    callback = function()
        vim.cmd([[ norm zx
        norm zM ]])
    end
})

EXCOMMANDS

Here I configure any custom commands.


local command = vim.api.nvim_create_user_command

command("Shell", function (args)
  local shell = args.args

  if (shell == "powershell") then
    shell = "powershell.exe"
  elseif (shell == "cmd") then
    shell = "cmd.exe"
  end
  vim.cmd("terminal " .. shell)
end, {
    nargs = 1,
    complete = function ()
      return {
        "powershell",
        "cmd",
        "zsh",
        "bash",
        "dash",
      }
    end,
  })

SHM

Here I configure some commonly used personal information.


local shm = {}

shm.name = {
  'Simon H Moore',
  'Simon Hugh Moore',
  'Simon Moore',
  'SH Moore',
}

shm.initials = 'SHM'

shm.email = '[email protected]'
shm.workemail = '[email protected]'

shm.signiture = "Simon H Moore <[email protected]>"
shm.worksigniture = "Simon H Moore <[email protected]>"

UTILS

Here go any helper utilities and functions.


local util = {}

util.number_ordinal = function(n)
  local last_digit = n % 10
  if last_digit == 1 and n ~= 11
  then
    return 'st'
  elseif last_digit == 2 and n ~= 12
  then
    return 'nd'
  elseif last_digit == 3 and n ~= 13
  then
    return 'rd'
  else
    return 'th'
  end
end

util.datef = function(datestr, date)
  local date = date or os.date("*t", os.time())
  local datestr = string.gsub(datestr, "%%o", M.number_ordinal(date.day))
  return os.date(datestr, os.time(date))
end

SNIPPETS

Here I configure my custom snippets.


Luasnip GitHub

Luasnip API Variables

These are used to create snippets.


local ls = require("luasnip")
local snippet = ls.add_snippets
local s = ls.snippet
local t = ls.text_node
local f = ls.function_node
local i = ls.insert_node
local c = ls.choice_node
local d = ls.dynamic_node
local sn = ls.snippet_node
local fmt = require("luasnip.extras.fmt").fmt

Utils

Here I configure snippet related utilities and functions.


local snip_utils = {}

snip_utils.get_name_choice = function()
  local nodes = {}
  for _, name in ipairs(shm.name) do
    table.insert(nodes, t(name))
  end
  return c(1, nodes)
end

snip_utils.shebang = {
  lua = "!/bin/lua",
  sh = "!/bin/sh",
  bash = "!/bin/bash",
  zsh = "!/bin/zsh",
}


snip_utils.get_date_choice = function (arg)
  return c(arg and arg or 1, {
        f(function() return utils.datef("%d%o %B %Y") end),
        f(function() return utils.datef(os.date "%d%o %b %Y") end),
        f(function() return utils.datef(os.date "%a %d%o %b %Y") end),
        f(function() return utils.datef(os.date "%A %d%o %b %Y") end),
        f(function() return utils.datef(os.date "%a %d%o %B %Y") end),
        f(function() return utils.datef(os.date "%A %d%o %B %Y") end),
        f(function() return os.date "%d-%m-%Y" end),
        f(function() return os.date "%d/%m/%Y" end),
        f(function() return os.date "%d-%m-%y" end),
        f(function() return os.date "%d/%m/%y" end),
      })
end

snip_utils.get_header = function(opts)
  opts = opts and opts or {}

  local sntable = {
      c = t(opts.commentstr and opts.commentstr or "# "),
      name = c(1, {
          f(function() return vim.fn.expand("%:t") end),
          f(function() return vim.fn.expand("%:h:t") .. "/" .. vim.fn.expand("%:t") end),
          f(function() return vim.fn.expand("%:t:r") end),
        }),
      author = c(2, {t(shm.signiture), t(shm.worksigniture)}),
      date = M.get_date_choice(3),
      desc = i(4, "Description"),
  }

  local formattable = {
      "{c}filename: {name}",
      "{c}author: {author}",
      "{c}date: {date}",
      "{c}desc: {desc}",
  }

  if opts.shebang then
    table.insert(formattable, 1, "{c}{shebang}")
    sntable.shebang = t(opts.shebang)
  end

  return fmt(table.concat(formattable, "\n"), sntable, {dedent = true})
end

Snippets

local greeting_choice = function(arg)
  return c(arg and arg or 1, {
    t("Hope you are well."),
    t("I hope you are having a nice day."),
    t("I hope you are having a good morning."),
    t("I hope you are having a nice end to the week."),
    t("Nice speaking to you on the phone the other day."),
  })
end

local message_end = function(arg)
  return c(arg and arg or 1, {
    t("Thank you"),
    t("Kind Regards"),
  })
end

All

Common snippets for all file types.


snippet("all", {
  s({
      trig = 'name',
      priority = 10000,
      desc = 'My name'
    },
    { snip_utils.get_name_choice()
    }),
  s({
      trig = 'email',
      priority = 10000,
      desc = 'My email'
    },
    {
      c(1, {
        t("[email protected]"),
        t("[email protected]"),
      }),
    }),
  s({
      trig = 'workemail',
      priority = 10000,
      desc = 'Work Email'
    },
    {
      t(shm.workemail)
    }),
  s({
      trig = 'sign',
      priority = 10000,
      desc = 'My signiture'
    },
    {
      c(1, {
        t(shm.signiture),
        t(shm.worksigniture),
      }),
    }),
  s({
      trig = 'worksign',
      priority = 10000,
      desc = 'Work Sign'
    },
    {
      t("Simon H Moore <[email protected]>")
    }),
  s({
      trig = 'date',
      priority = 10000,
      desc = 'Current date'
    },
    { snip_utils.get_date_choice()
    }),
  s({
      trig = 'americandate',
      priority = 10000,
      desc = 'Current american date, month comes first',
    },
    {
      c(1, {
        f(function() return os.date "%m/%d/%Y" end),
        f(function() return os.date "%m-%d-%Y" end),
        f(function() return os.date "%m/%d/%y" end),
        f(function() return os.date "%m-%d-%y" end),
      })
    }),
  s({
      trig = 'time',
      priority = 10000,
      desc = 'Current time',
    },
    {
      c(1, {
        f(function() return os.date "%H:%M" end),
        f(function() return os.date "%I:%M %p" end),
        f(function() return os.date "%H:%M:%S" end),
        f(function() return os.date "%I:%M:%S %p" end),
      })
    }),
  s({
    trig = 'vigogreeting',
    desc = 'A greeting for vigo email'
  }, fmt([[
      Hi {name},

      {greeting}
      ]], {
          name = i(1, "Name"),
          greeting = greeting_choice(2),
        }
    )
  ),
  s({
    trig = "vigopass",
    desc = "Complete builds message"
  }, fmt([[
      Hi {name},

      {greeting}

      I am currently setting up your {device} and I need your password to continue. Could you send it to me please?
      If you feel uncomfortable sharing your password over email{passmsg}

      Could you also send me a list of apps you would like to see installed?

      {outmsg},
      Simon
      ]], {
          name = i(1, "Name"),
          --NOTE: Could separate out the greeting to be reused
          greeting = greeting_choice(2),
          device = c(3,{
            t("new laptop"),
            t("laptop"),
            t("new desktop"),
            t("desktop"),
            i(1, "device"),
          }),
          passmsg = c(4,{
            t(", you can call our office, or we can reset your password to a temporary one."),
            t(" you can also call our office."),
          }),
          outmsg = message_end(5),
        }
    )
  ),
  s({
    trig = "vigoPassReset",
    desc = "Email client for password reset"
  }, fmt([[
      Hi {name},

      {greeting}

      I will reset your password to: {password}

      Please confirm you have read and taken note of this password by replying to this email. We will only proceed with the password reset once you have replied.

      Important: Once we reset your password, you may be signed out of all sessions you are currently logged in. You can log back in using the new password mentioned above.

      {outmsg},
      Simon
      ]], {
          name = i(1, "Name"),
          --NOTE: Could separate out the greeting to be reused
          greeting = greeting_choice(2),
          password = i(3, "PASSWORD"),
          outmsg = message_end(4),
        }
    )
  ),
  s({
    trig = "vigocomplete",
    desc = "Complete builds message"
  }, fmt([[
      Hi {name},

      {greeting}

      We have completed setting up {name2} {device} and it is ready for collection, we are open Monday to Friday 9am to 5pm.
      Alternatively, I can arrange to have one of our mobile engineers drop the laptop of for you.

      {outmsg},
      Simon
      ]], {
          name = i(1, "Name"),
          --NOTE: Could separate out the greeting to be reused
          greeting = greeting_choice(2),
          name2 = i(3, "Name"),
          device = c(4, {t("laptop"), t("desktop")}),
          outmsg = message_end(5),
        }
    )
  ),
})

Lua

Snippets only for lua file types.


snippet("lua", {
  -- auto type require definition
s('req',
  fmt([[local {} = require("{}")]], { f(function(import_name)
    local parts = vim.split(import_name[1][1], ".", { plain = true })
    return parts[#parts] or ""
  end, { 1 }), i(1) })
),
-- import luasnip functions
s({
    trig = 'luasnip import',
    priority = 10000,
    desc = 'import luasnip functions',
  },
  {
    d(1, function()
      local import_table = {
        'local ls = require("luasnip")',
        'local s = ls.snippet',
        'local t = ls.text_node',
        'local i = ls.insert_node',
        'local f = ls.function_node',
        'local c = ls.choice_node',
        'local fmt = require("luasnip.extras.fmt").fmt',
        'local d = ls.dynamic_node',
        'local sn = ls.snippet_node',
        'local isn = ls.indent_snippet_node',
        'local r = ls.restore_node',
        'local events = require("luasnip.util.events")',
        'local ai = require("luasnip.nodes.absolute_indexer")',
        'local extras = require("luasnip.extras")',
        'local l = extras.lambda',
        'local rep = extras.rep',
        'local p = extras.partial',
        'local m = extras.match',
        'local n = extras.nonempty',
        'local dl = extras.dynamic_lambda',
        'local fmta = require("luasnip.extras.fmt").fmta',
        'local conds = require("luasnip.extras.expand_conditions")',
        'local postfix = require("luasnip.extras.postfix").postfix',
        'local types = require("luasnip.util.types")',
        'local parse = require("luasnip.util.parser").parse_snippet',
        'local ms = ls.multi_snippet',
        'local k = require("luasnip.nodes.key_indexer").new_key',
      }

      return sn(nil, c(1, {
        t({ unpack(import_table, 1, 7) }),
        t({ unpack(import_table, 1, 9) }),
        t(import_table),
      }))
    end)
    }
  ),
})

GitCommit

Snippets for git commit file type, used for committing with fugitive.


snippet("gitcommit", {
  -- conventional commit snippets
  -- see https://www.conventionalcommits.org/en/v1.0.0/#summary
  s({trig = "^br", regTrig = true}, t("BREAKING CHANGE: ")),
  s({trig = "^fe", regTrig = true}, fmt([[feat({}){}: {}]], { i(1, "scope"), c(3, {t(""),t("!")}), i(2, "new feature")})),
  s({trig = "^fi", regTrig = true}, fmt([[fix({}){}: {}]], { i(1, "scope"), c(3, {t(""),t("!")}), i(2, "bug fix")})),
  s({trig = "^do", regTrig = true}, fmt([[docs({}){}: {}]], { i(1, "scope"), c(3, {t(""),t("!")}), i(2, "documentation only change")})),
  s({trig = "^bu", regTrig = true}, fmt([[build({}){}: {}]], { i(1, "scope"), c(3, {t(""),t("!")}), i(2, "build system or external dependency change")})),
  s({trig = "^pe", regTrig = true}, fmt([[perf({}){}: {}]], { i(1, "scope"), c(3, {t(""),t("!")}), i(2, "performance improvement change")})),
  s({trig = "^re", regTrig = true}, fmt([[refactor({}){}: {}]], { i(1, "scope"), c(3, {t(""),t("!")}), i(2, "code change that neither fixes a bug or adds a feature")})),
  s({trig = "^st", regTrig = true}, fmt([[style({}){}: {}]], { i(1, "scope"), c(3, {t(""),t("!")}), i(2, "change that does not affect the meaning of the code")})),
  s({trig = "^pe", regTrig = true}, fmt([[perf({}){}: {}]], { i(1, "scope"), c(3, {t(""),t("!")}), i(2, "adding new or correcting existing test")})),
},{ type = "autosnippets" })

FILETYPE OPTIONS

Norg

  vim.api.nvim_create_autocmd("BufEnter", {
  group = augroup("ftplugin"),
  pattern = "norg",
  callback = function()
      o.wrap = true
      o.foldlevelstart = 0             -- Enable foldlevel when opening file
      o.foldnestmax = 6                -- Set max nested foldlevel
      o.foldenable = true
  end,
  })

About

My personal Neovim config

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages