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
Lazzy
mkdir -p ~/.config/nvim/lua/
touch ~/.config/nvim/init.lua
touch ~/.config/nvim/lua/init.lua
touch ~/.config/nvim/lua/settings.lua
touch ~/.config/nvim/lua/keymaps.lua
touch ~/.config/nvim/lua/plugins.lua
touch ~/.config/nvim/lua/configs.lua
nvim ~/.config/nvim/init.lua
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or 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)
require("init")
nvim ~/.config/nvim/lua/init.lua
-- Lazy
require("lazy").setup("plugins")
-- Settings, keymaps and plugins configs
require("settings")
require("keymaps")
require("configs")
nvim ~/.config/nvim/lua/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=4 smarttab ]]
vim.cmd[[ set softtabstop=0 ]]
vim.cmd[[ set smartindent ]]
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 ]]
nvim ~/.config/nvim/lua/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 <M-l> :Lazy<CR>]]
vim.cmd[[nmap <M-e> :NvimTreeToggle<CR>]]
vim.cmd[[nmap <M-g> :Neogit<CR>]]
vim.cmd[[nmap <M-t> :Telescope<CR>]]
nvim ~/.config/nvim/lua/plugins.lua
return {
-- Style
{
'navarasu/onedark.nvim',
'nvim-lualine/lualine.nvim',
'norcalli/nvim-colorizer.lua',
'windwp/nvim-autopairs',
'lukas-reineke/indent-blankline.nvim'
},
-- Tree
{
'nvim-tree/nvim-tree.lua',
'nvim-tree/nvim-web-devicons',
'akinsho/bufferline.nvim',
},
-- Git
{
{ 'NeogitOrg/neogit', tag = 'v0.0.1' },
'nvim-lua/plenary.nvim',
'sindrets/diffview.nvim',
'ibhagwan/fzf-lua',
'APZelos/blamer.nvim'
},
-- Telescope
{
{ 'nvim-telescope/telescope.nvim', tag = '0.1.6' },
'BurntSushi/ripgrep',
'nvim-telescope/telescope-fzf-native.nvim',
'sharkdp/fd',
'nvim-treesitter/nvim-treesitter'
},
-- LPS
{
'neovim/nvim-lspconfig',
'hrsh7th/nvim-cmp',
'hrsh7th/cmp-nvim-lsp',
'hrsh7th/cmp-buffer',
'hrsh7th/cmp-path',
'hrsh7th/cmp-cmdline',
'saadparwaiz1/cmp_luasnip',
'L3MON4D3/LuaSnip',
'rafamadriz/friendly-snippets',
'ray-x/lsp_signature.nvim',
'onsails/lspkind-nvim'
}
}
nvim ~/.config/nvim/lua/configs.lua
-- Style
require('onedark').setup{
style = 'darker',
transparent = true
}
require('onedark').load()
require('lualine').setup()
require'colorizer'.setup()
require'nvim-autopairs'.setup()
require("ibl").setup()
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
vim.opt.termguicolors = true
-- Tree
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
api.config.mappings.default_on_attach(bufnr)
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
require("nvim-tree").setup({
sort_by = "case_sensitive",
view = {
width = 30,
},
renderer = {
group_empty = true,
},
filters = {
dotfiles = false,
},
update_focused_file = {
enable = true,
},
on_attach = my_on_attach,
})
require('bufferline').setup()
-- Git
require('neogit').setup()
local async = require "plenary.async"
require('fzf-lua').setup()
require('diffview').setup()
vim.g.blamer_enabled = true
-- Telescope
require('telescope').setup()
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
-- LSP
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()
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