Index ¦ Archives

Neovim

Neovim is a refactor, and sometimes redactor, in the tradition of Vim (which itself derives from Stevie). It is not a rewrite but a continuation and extension of Vim. Many clones and derivatives exist, some very cleverβ€”but none are Vim. Neovim is built for users who want the good parts of Vim, and more.

Goals

  • Enable new contributors, remove barriers to entry.
  • Unblock plugin authors.
  • Develop first-class Lua/LuaJIT scripting alternative to VimL.
  • Target all platforms supported by libuv.
  • Leverage ongoing Vim development.
  • Optimize out of the box, for new users but especially regular users.
  • Deliver consistent cross-platform experience.
  • In matters of taste/ambiguity, favor tradition/compatibility...
  • ...but prefer usability if the benefits are extreme.

Non-goals

  • Turn Vim into an IDE
  • Limit third-party applications (such as IDEs!) built with Neovim
  • Deprecate VimL
  • POSIX vi-compatibility

Install

sudo apt install neovim

Packer

git clone --depth 1 https://github.com/wbthomason/packer.nvim\
 ~/.local/share/nvim/site/pack/packer/start/packer.nvim

Settings

mkdir -p ~/.config/nvim/lua/configs
mkdir -p ~/.config/nvim/lua/plugins

nvim ~/.config/nvim/init.lua

require('configs.settings')
require('configs.keymaps')
require('plugins.plugins')
require('plugins.style')
require('plugins.telescope')
require('plugins.tree')
require('plugins.lsp')
require('plugins.bufferline')
require('plugins.git')

nvim ~/.config/nvim/lua/configs/settings.lua

vim.cmd[[ syntax on ]]
vim.cmd[[ filetype plugin on ]]
vim.cmd[[ set encoding=UTF-8 ]]
vim.cmd[[ set textwidth=101 ]]
vim.cmd[[ set tabstop=4 ]]
vim.cmd[[ set shiftwidth=2 smarttab ]]
vim.cmd[[ set softtabstop=0 ]]
vim.cmd[[ set autoindent ]]
vim.cmd[[ set expandtab ]]
vim.cmd[[ set smarttab ]]
vim.cmd[[ set laststatus=4 ]]
vim.cmd[[ set ignorecase ]]
vim.cmd[[ set t_Co=256 ]]
vim.cmd[[ set noshowmode ]]
vim.cmd[[ set hlsearch ]]
vim.cmd[[ set hidden ]]
vim.cmd[[ set nobuflisted ]]
vim.cmd[[ set nu! ]]
vim.cmd[[ set termguicolors ]]
vim.cmd[[ let g:blamer_enabled = 1 ]]

nvim ~/.config/nvim/lua/configs/keymaps.lua

vim.cmd[[ nmap <M-n> :bn<CR> ]]
vim.cmd[[ nmap <M-p> :bp<CR> ]]
vim.cmd[[ nmap <M-d> :bd<CR> ]]
vim.cmd[[ nmap <C-s> :Telescope<CR> ]]
vim.cmd[[ nmap <M-e> :NvimTreeOpen<CR> ]]

nvim ~/.config/nvim/lua/plugins/plugins.lua

vim.cmd [[ packadd packer.nvim ]]

return require('packer').startup(function()
    -- Packer
    use 'wbthomason/packer.nvim'

    -- Style
    use 'navarasu/onedark.nvim'
    use {
        'nvim-lualine/lualine.nvim',
        requires = {
            'kyazdani42/nvim-web-devicons',
            opt = true
        }
    }
    use 'lukas-reineke/indent-blankline.nvim'
    use 'norcalli/nvim-colorizer.lua'

    -- Autopairs
    use 'tpope/vim-surround'
    use 'windwp/nvim-autopairs'


    -- LPS
    use 'neovim/nvim-lspconfig'
    use 'hrsh7th/nvim-cmp'
    use 'hrsh7th/cmp-nvim-lsp'
    use 'hrsh7th/cmp-buffer'
    use 'hrsh7th/cmp-path'
    use 'hrsh7th/cmp-cmdline'
    use 'saadparwaiz1/cmp_luasnip'
    use 'L3MON4D3/LuaSnip'
    use 'rafamadriz/friendly-snippets'
    use 'ray-x/lsp_signature.nvim'
    use 'onsails/lspkind-nvim'

    -- Telescope
    use { 'nvim-telescope/telescope.nvim', tag = '0.1.0' }
    use 'nvim-lua/plenary.nvim'
    use 'BurntSushi/ripgrep'
    use {'nvim-telescope/telescope-fzf-native.nvim', run = 'make' }
    use 'sharkdp/fd'
    use 'nvim-treesitter/nvim-treesitter'

    -- Tree
    use {
        'nvim-tree/nvim-tree.lua',
        requires = {
            'nvim-tree/nvim-web-devicons', -- optional
        },
    }

    -- Smartopen
    use {
        "danielfalk/smart-open.nvim",
        branch = "0.1.x",
        config = function()
            require"telescope".load_extension("smart_open")
        end,
        requires = {"kkharji/sqlite.lua"}
    }

    -- Bufferline
    use {'akinsho/bufferline.nvim', tag = "v3.*",
        requires = 'nvim-tree/nvim-web-devicons'
    }

    -- Git
    use {'akinsho/git-conflict.nvim', tag = "*", config = function()
        require('git-conflict').setup()
    end}
    use 'APZelos/blamer.nvim'

    if PACKER_BOOTSTRAP then
        require("packer").sync()
    end
end)

nvim ~/.config/nvim/lua/plugins/style.lua

require('onedark').setup{
    style = 'darker',
    transparent = true
}

require('onedark').load()

require('lualine').setup{
    options = {
        theme = 'onedark'
    }
}

require('lualine').get_config()

vim.opt.listchars:append("space:β‹…")
vim.cmd [[highlight IndentBlanklineIndent1 guifg=#E06C75 gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent2 guifg=#E5C07B gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent3 guifg=#98C379 gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent4 guifg=#56B6C2 gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent5 guifg=#61AFEF gui=nocombine]]
vim.cmd [[highlight IndentBlanklineIndent6 guifg=#C678DD gui=nocombine]]

vim.cmd([[
    hi! MatchParen cterm=NONE,bold gui=NONE,bold guibg=NONE guifg=#FFFFFF
    let g:indentLine_fileTypeExclude = ['dashboard']
]])


require("indent_blankline").setup {
    show_end_of_line = true,
    space_char_blankline = " ",
    char_highlight_list = {
        "IndentBlanklineIndent1",
        "IndentBlanklineIndent2",
        "IndentBlanklineIndent3",
        "IndentBlanklineIndent4",
        "IndentBlanklineIndent5",
        "IndentBlanklineIndent6",
    },
}

require'colorizer'.setup()

require('nvim-autopairs').setup({
    enable_check_bracket_line = false
})

nvim ~/.config/nvim/lua/plugins/telescope.lua

require'nvim-treesitter.configs'.setup {
    ensure_installed = { 'python', 'go', 'javascript', 'help' },
    sync_install = false,
    auto_install = true,
    indent = {
        enable = true
    }
 }

nvim ~/.config/nvim/lua/plugins/lsp.lua

local has_any_words_before = function()
    if vim.api.nvim_buf_get_option(0, "buftype") == "prompt" then
        return false
    end
    local line, col = unpack(vim.api.nvim_win_get_cursor(0))
    return col ~= 0 and vim.api.nvim_buf_get_lines(
        0, line - 1, line, true
    )[1]:sub(col, col):match("%s") == nil
end

require'lspconfig'.clangd.setup{}
require "lsp_signature".setup()
vim.o.completeopt = 'menuone,noselect'

local cmp = require'cmp'
local luasnip = require("luasnip")

local lspkind = require('lspkind')
local source_mapping = {
    buffer = "β—‰ Buffer",
    nvim_lsp = "πŸ‘ LSP",
    nvim_lua = "πŸŒ™ Lua",
    cmp_tabnine = "πŸ’‘ Tabnine",
    path = "🚧 Path",
    luasnip = "🌜 LuaSnip"
}

cmp.setup({
    sources = {
        { name = 'nvim_lsp' },
        { name = 'luasnip' },
        { name = 'buffer' },
        { name = 'path' },
        { name = 'nvim_lua' },
    },

    formatting = {
        format = function(entry, vim_item)
        vim_item.kind = lspkind.presets.default[vim_item.kind]
        local menu = source_mapping[entry.source.name]
        if entry.source.name == 'cmp_tabnine' then
            if entry.completion_item.data ~= nil and entry.completion_item.data.detail ~= nil then
                menu = entry.completion_item.data.detail .. ' ' .. menu
            end
            vim_item.kind = ''
        end
        vim_item.menu = menu
        return vim_item
        end
    },

    snippet = {
        expand = function(args)
            require('luasnip').lsp_expand(args.body)
        end,
    },
    mapping = {
        ['<C-n>'] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }),
        ['<C-p>'] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }),
        ['<Down>'] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Select }),
        ['<Up>'] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Select }),
        ['<C-d>'] = cmp.mapping.scroll_docs(-4),
        ['<C-f>'] = cmp.mapping.scroll_docs(4),
        ['<C-Space>'] = cmp.mapping.complete(),
        ['<C-e>'] = cmp.mapping.close(),
        ['<CR>'] = cmp.mapping.confirm({
            behavior = cmp.ConfirmBehavior.Replace,
            select = true,
        }),

        ['<Tab>'] = function(fallback)
            if cmp.visible() then
                cmp.select_next_item()
            elseif luasnip.expand_or_jumpable() then
                vim.fn.feedkeys(
                    vim.api.nvim_replace_termcodes('<Plug>luasnip-expand-or-jump',
                    true,
                    true,
                    true
                ), '')
            else
                fallback()
            end
        end,
        ['<S-Tab>'] = function(fallback)
        if cmp.visible() then
            cmp.select_prev_item()
        elseif luasnip.jumpable(-1) then
            vim.fn.feedkeys(vim.api.nvim_replace_termcodes(
                '<Plug>luasnip-jump-prev',
                true,
                true,
                true),
            '')
        else
            fallback()
        end
    end,},
})

require("luasnip/loaders/from_vscode").load()

nvim ~/.config/nvim/lua/plugins/bufferline.lua

vim.opt.termguicolors = true
require("bufferline").setup{}

nvim ~/.config/nvim/lua/plugins/git.lua

require'git-conflict'.setup {
    default_mappings = {
        ours = 'o',
        theirs = 't',
        none = '0',
        both = 'b',
        next = 'n',
        prev = 'p',
    },
}

nvim ~/.config/nvim/lua/plugins/tree.lua

vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1

-- set termguicolors to enable highlight groups
vim.opt.termguicolors = true

-- empty setup using defaults
require("nvim-tree").setup()

local function my_on_attach(bufnr)
  local api = require "nvim-tree.api"

  local function opts(desc)
    return {
        desc = "nvim-tree: " .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true
    }
  end

  -- default mappings
  api.config.mappings.default_on_attach(bufnr)

  -- custom mappings
  vim.keymap.set('n', '<C-t>', api.tree.change_root_to_parent,        opts('Up'))
  vim.keymap.set('n', '?',     api.tree.toggle_help,                  opts('Help'))
end


-- OR setup with some options
require("nvim-tree").setup({
  sort_by = "case_sensitive",
  view = {
    width = 30,
  },
  renderer = {
    group_empty = true,
  },
  filters = {
    dotfiles = true,
  },

  on_attach = my_on_attach,
})

Compile

:PackerSync
:LspInstall <lang>
:TSInstall <lang>

Shortcuts

General
:q        close
:w        write/saves
:wa[!]    write/save all windows [force]
:wq       write/save and close
:x        save and quit, same as wq
:q!       force close if file has changed and not save changes
v        Enter visual mode for selection of LINES
C-v      Enter visual mode for selection of BLOCKS
y        Yank/copy selected region
yy       Yank/copy entire line
"<reg>y  Yank/copy marked region into register <reg> (register from a-z)
c        Cut selection
p        Paste yanked content
"<reg>p  Paste yanked content in register <reg> (from a-z)
P        Paste yanked content BEFORE
u        Undo
C-r      Redo
:!<cmd>  Execute shell command <cmd>
C-z      send vim to background (fg brings it to front again)
C-ws     Split current window horizontally (alternative :split)
C-wv     Split current window vertically (alternative :vsplit)
C-ww     Jump to the next window
C-wo     Only one window (close all)
C-wARROW Jump to window left/right/top/bottom (arrow keys) to the current
C-w#<    Shrink/resize current window from the right by # (default 1)
C-w#>    Increase/resize current window to the right by # (default 1)
a        Append text after the cursor
A        Append text at the end of the line
i        Insert text before the cursor
I        Insert text before the first non-blank in the line
o        Begin a new line BELOW the cursor and insert text
O        Begin a new line ABOVE the cursor and insert text
s        Erase the current letter under the cursor, set insert-mode
S        Erase the whole line, set insert-mode
cc       Delete the current line, set insert-mode
cw       Delete word, set insert-mode
dd       Delete line under curser
q[a-z]   Start recording, everything will be recorded including movement actions.
@[a-z]   Execute the recorded actions.
nnoremap <silent> <leader>s :set spell!<cr>
<leader>s Toggle Spelling
]s       Next spelling mistake
[s       Previous spelling mistake
z=       Give Suggestions (prepent 1, use first suggestions automatically)
zg       Add misspelled to spellfile
zug      Remove word from spellfile
Navigation
h        cursor left
j        cursor down
l        cursor right
k        cursor up
H        Jump to TOP of screen
M        Jump to MIDDLE of screen
L        Jump to BOTTOM of screen
C-b      Move back one full screen (page up)
C-f      Move forward one full screen (page down)
C-d      Move forward 1/2 screen; half page down
C-u      Move back (up) 1/2 screen; half page up
w        jump by start of words (punctuation considered words)
e        jump to end of words (punctuation considered words)
b        jump backward by words (punctuation considered words)
0 (zero) start of line
^        first non-blank character of line
$        end of line
G        bottom of file
gg       top of file
E        jump to end of words (no punctuation)
W        jump by words (spaces separate words)
B        jump backward by words (no punctuation)
#G       goto line #
#gg      goto line #
Search
*        search for word under cursor (forward) and highlight occurrence (see incsearch, hlsearch below)
%        jump from open/close ( / #if / ( / { to corresponding ) / #endif / }
[{       jump to start of current code block
]}       jump to end of current code block
gd       jump to var declaration (see incsearch, hlsearch below)
f<c>     Find char <c> from current cursor position -- forwards
F<c>     Find char <c> from current cursor position -- backwards
,        Repeat previous f<c> or F<c> in opposite direction
;        Repeat previous f<c> or F<c> in same direction
'.       jump back to last edited line.
g;       jump back to last edited position.
[m       jump to start of funtion body
[i       show first declartion/use of the word under cursor
[I       show all occurrences of word under cursor in current file
[/       cursor to N previous start of a C comment
:vimgrep /<regex>/g %        Search for <regex> with multiple occasions per line (g)
                             in current file (%)
:vimgrep /<C-r>// %          On the command line, <C-r>/ (that is: CTRL-R followed by /)
                             will insert the last search pattern.
:vimgrep /<a>/g <filelist>   Search in the given files (<filelist>)
:vimgrep /<a>/g *.cc         Search in all *.cc files current directory
:vimgrep /<a>/g **/*.cc      Search in all *.cc files in every sub-directory (recursively)
:vimgrep /<a>/g `find . -type f`
                             Search in all files that are returns by the backtick command.

:vim     short for :vimgrep

:cnext   Jump to next record/match in quickfix list
:cprev   Jump to previous record/match in quickfix list
[q       see :cprev
]q       see :cnext
[Q       see :cfirst
]Q       see :clast
Marks
ma       set mark a at current cursor location
'a       jump to line of mark a (first non-blank character in line)
`a       jump to position (line and column) of mark a
d'a      delete from current line to line of mark a
d`a      delete from current cursor position to position of mark a
c'a      change text from current line to line of mark a
y`a      yank text to unnamed buffer from cursor to position of mark a
:marks   list all the current marks
:marks aB list marks a, B
Editing
x        Delete char UNDER cursor
X        Delete char BEFORE cursor
#x       Delete the next # chars. starting from char under cursor
dw       Delete next word
dW       Delete UP TO the next word
d^       Delete up unto the beginning of the line
d$       Delete until end of the line
D        See d$, delete until end of the line
dd       Delete whole line
dib      Delete contents in parenthesis '(' ')' block (e.g. function args)
diB      Delete inner '{' '}' block
daB      Delete a '{' '}' block
das      Delete a senctence
diw      Delete word under cursor
df<c>    Delete until next occurence of <c> (char) found (including <c>) [in single line]
dt<c>    Delete until next occurence of <c> (char) found (without <c>!!!) [in single line]

ciw      Change word under cursor
ciB      Change inner '{' '}' block
cf<c>    See "df<c>" but change instead of delete
ct<c>    See "dt<c>" but change instead of delete

#J       Merge # number of lines together
Misc
gq       (in visual-mode) format selected text according to line-width
gqq      format current line according to line-width
#gqq     format next #-lines
C-n      Keyword completion
Tab      Keyword completion (SuperTab plugin)
r<c>     Replace char <c>
#r<c>    Replace follow # chars with <c>, : csock, cursor on s, 3re ceeek
:s/xxx/yyy/    Replace xxx with yyy at the first occurrence
:s/xxx/yyy/g   Replace xxx with yyy first occurrence, global (whole sentence)
:s/xxx/yyy/gc  Replace xxx with yyy global with confirm
:%s/xxx/yyy/g  Replace xxx with yyy global in the whole file
u        Convert selection (visual mode) to lowercase
U        Convert selection (visual mode) to uppercase
:g/^#/d  Delete all lines that begins with #
:g/^$/d  Delete all lines that are empty
gg=G    Reident all

Neovim

© 2000-2022 by Daniel Pimentel (d4n1). Under MIT.