Feuille de chaleur Neovim
Aperçu général
Neovim est un éditeur de texte hyper extensible basé sur Vim qui vise à refactorer Vim agressivement afin de simplifier la maintenance, d'activer les interfaces utilisateur avancées et de maximiser l'extensibilité.
Installation
Gestionnaires de paquets
# Ubuntu/Debian
sudo apt install neovim
# macOS
brew install neovim
# Arch Linux
sudo pacman -S neovim
# Windows (Chocolatey)
choco install neovim
# From source
git clone https://github.com/neovim/neovim.git
cd neovim && make CMAKE_BUILD_TYPE=RelWithDebInfo
sudo make install
Différences de base avec Vim
Principales améliorations
" Built-in terminal emulator
:terminal
:term
" Asynchronous job control
:help job-control
" Better default settings
" No need for 'nocompatible'
" Sensible defaults enabled
" Lua scripting support
:lua print("Hello from Lua!")
" Better plugin architecture
" Native LSP support
" TreeSitter integration
```_
## Configuration
### Fichiers de configuration
```bash
# Neovim config location
~/.config/nvim/init.vim # Vimscript config
~/.config/nvim/init.lua # Lua config
# Check config location
:echo stdpath('config')
```_
### Init.vim de base
```vim
" Enable syntax highlighting
syntax enable
" Line numbers
set number
set relativenumber
" Indentation
set tabstop=4
set shiftwidth=4
set expandtab
set autoindent
set smartindent
" Search
set ignorecase
set smartcase
set incsearch
set hlsearch
" UI improvements
set termguicolors
set signcolumn=yes
set updatetime=300
set timeoutlen=500
" Mouse support
set mouse=a
" Clipboard
set clipboard+=unnamedplus
" Split behavior
set splitbelow
set splitright
" Leader key
let mapleader = " "
Init.lua de base
-- Basic settings
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
vim.opt.autoindent = true
vim.opt.smartindent = true
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.incsearch = true
vim.opt.hlsearch = true
vim.opt.termguicolors = true
vim.opt.signcolumn = "yes"
vim.opt.updatetime = 300
vim.opt.timeoutlen = 500
vim.opt.mouse = "a"
vim.opt.clipboard = "unnamedplus"
vim.opt.splitbelow = true
vim.opt.splitright = true
-- Leader key
vim.g.mapleader = " "
-- Key mappings
vim.keymap.set('n', '<leader>w', ':w<CR>')
vim.keymap.set('n', '<leader>q', ':q<CR>')
vim.keymap.set('n', '<C-h>', '<C-w>h')
vim.keymap.set('n', '<C-j>', '<C-w>j')
vim.keymap.set('n', '<C-k>', '<C-w>k')
vim.keymap.set('n', '<C-l>', '<C-w>l')
Gestion des greffons
Utilisation de vim-plug
" Install vim-plug
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
" Plugin configuration in init.vim
call plug#begin('~/.local/share/nvim/plugged')
" Essential plugins
Plug 'nvim-treesitter/nvim-treesitter', \\\\{'do': ':TSUpdate'\\\\}
Plug 'neovim/nvim-lspconfig'
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'L3MON4D3/LuaSnip'
Plug 'nvim-telescope/telescope.nvim'
Plug 'nvim-lua/plenary.nvim'
Plug 'kyazdani42/nvim-tree.lua'
Plug 'kyazdani42/nvim-web-devicons'
Plug 'nvim-lualine/lualine.nvim'
call plug#end()
" Install plugins: :PlugInstall
" Update plugins: :PlugUpdate
" Clean plugins: :PlugClean
Utilisation packer.nvim (Lua)
-- Install packer.nvim
local install_path = vim.fn.stdpath('data')..'/site/pack/packer/start/packer.nvim'
if vim.fn.empty(vim.fn.glob(install_path)) > 0 then
vim.fn.system(\\\\{'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path\\\\})
end
-- Plugin configuration
require('packer').startup(function(use)
use 'wbthomason/packer.nvim'
-- Essential plugins
use \\\\{'nvim-treesitter/nvim-treesitter', run = ':TSUpdate'\\\\}
use 'neovim/nvim-lspconfig'
use 'hrsh7th/nvim-cmp'
use 'hrsh7th/cmp-nvim-lsp'
use 'L3MON4D3/LuaSnip'
use \\\\{'nvim-telescope/telescope.nvim', requires = 'nvim-lua/plenary.nvim'\\\\}
use \\\\{'kyazdani42/nvim-tree.lua', requires = 'kyazdani42/nvim-web-devicons'\\\\}
use 'nvim-lualine/lualine.nvim'
end)
Protocole de serveur de langue (LSP)
Configuration du LSP
-- Basic LSP configuration
local lspconfig = require('lspconfig')
-- Python
lspconfig.pyright.setup\\\\{\\\\}
-- JavaScript/TypeScript
lspconfig.tsserver.setup\\\\{\\\\}
-- Rust
lspconfig.rust_analyzer.setup\\\\{\\\\}
-- Go
lspconfig.gopls.setup\\\\{\\\\}
-- C/C++
lspconfig.clangd.setup\\\\{\\\\}
-- Lua
lspconfig.lua_ls.setup\\\\{
settings = \\\\{
Lua = \\\\{
runtime = \\\\{version = 'LuaJIT'\\\\},
diagnostics = \\\\{globals = \\\\{'vim'\\\\}\\\\},
workspace = \\\\{library = vim.api.nvim_get_runtime_file("", true)\\\\},
telemetry = \\\\{enable = false\\\\},
\\\\},
\\\\},
\\\\}
LSP Cartes clés
-- LSP key mappings
vim.keymap.set('n', 'gd', vim.lsp.buf.definition)
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration)
vim.keymap.set('n', 'gr', vim.lsp.buf.references)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation)
vim.keymap.set('n', 'K', vim.lsp.buf.hover)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help)
vim.keymap.set('n', '<leader>rn', vim.lsp.buf.rename)
vim.keymap.set('n', '<leader>ca', vim.lsp.buf.code_action)
vim.keymap.set('n', '<leader>f', vim.lsp.buf.format)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next)
vim.keymap.set('n', '<leader>e', vim.diagnostic.open_float)
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist)
Amère d'arbre
Configuration de TreeSitter
require'nvim-treesitter.configs'.setup \\\\{
-- Install parsers synchronously (only applied to `ensure_installed`)
sync_install = false,
-- Automatically install missing parsers when entering buffer
auto_install = true,
-- List of parsers to install
ensure_installed = \\\\{
"c", "lua", "vim", "vimdoc", "query",
"python", "javascript", "typescript", "rust", "go"
\\\\},
highlight = \\\\{
enable = true,
additional_vim_regex_highlighting = false,
\\\\},
indent = \\\\{
enable = true
\\\\},
incremental_selection = \\\\{
enable = true,
keymaps = \\\\{
init_selection = "gnn",
node_incremental = "grn",
scope_incremental = "grc",
node_decremental = "grm",
\\\\},
\\\\},
\\\\}
Complétion automatique
nvim-cmp Configuration
local cmp = require'cmp'
local luasnip = require'luasnip'
cmp.setup(\\\\{
snippet = \\\\{
expand = function(args)
luasnip.lsp_expand(args.body)
end,
\\\\},
mapping = cmp.mapping.preset.insert(\\\\{
['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(),
['<CR>'] = cmp.mapping.confirm(\\\\{ select = true \\\\}),
['<Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end, \\\\{ 'i', 's' \\\\}),
\\\\}),
sources = cmp.config.sources(\\\\{
\\\\{ name = 'nvim_lsp' \\\\},
\\\\{ name = 'luasnip' \\\\},
\\\\}, \\\\{
\\\\{ name = 'buffer' \\\\},
\\\\})
\\\\})
Intégration des terminaux
Terminal intégré
" Open terminal
:terminal
:term
" Terminal in split
:split|terminal
:vsplit|terminal
" Terminal key mappings
tnoremap <Esc> <C-\><C-n>
tnoremap <C-h> <C-\><C-n><C-w>h
tnoremap <C-j> <C-\><C-n><C-w>j
tnoremap <C-k> <C-\><C-n><C-w>k
tnoremap <C-l> <C-\><C-n><C-w>l
Configuration du terminal Lua
-- Terminal configuration
vim.keymap.set('t', '<Esc>', '<C-\\><C-n>')
vim.keymap.set('t', '<C-h>', '<C-\\><C-n><C-w>h')
vim.keymap.set('t', '<C-j>', '<C-\\><C-n><C-w>j')
vim.keymap.set('t', '<C-k>', '<C-\\><C-n><C-w>k')
vim.keymap.set('t', '<C-l>', '<C-\\><C-n><C-w>l')
-- Open terminal in split
vim.keymap.set('n', '<leader>th', ':split|terminal<CR>')
vim.keymap.set('n', '<leader>tv', ':vsplit|terminal<CR>')
Explorateur de fichiers
nvim-tree Configuration
require("nvim-tree").setup(\\\\{
sort_by = "case_sensitive",
view = \\\\{
width = 30,
\\\\},
renderer = \\\\{
group_empty = true,
\\\\},
filters = \\\\{
dotfiles = true,
\\\\},
\\\\})
-- Key mappings
vim.keymap.set('n', '<leader>e', ':NvimTreeToggle<CR>')
vim.keymap.set('n', '<leader>r', ':NvimTreeRefresh<CR>')
vim.keymap.set('n', '<leader>n', ':NvimTreeFindFile<CR>')
Fuzzy Finder
Configuration du télescope
require('telescope').setup\\\\{
defaults = \\\\{
mappings = \\\\{
i = \\\\{
["<C-n>"] = "move_selection_next",
["<C-p>"] = "move_selection_previous",
["<C-c>"] = "close",
["<Down>"] = "move_selection_next",
["<Up>"] = "move_selection_previous",
["<CR>"] = "select_default",
["<C-x>"] = "select_horizontal",
["<C-v>"] = "select_vertical",
["<C-t>"] = "select_tab",
\\\\},
\\\\},
\\\\},
\\\\}
-- Key mappings
vim.keymap.set('n', '<leader>ff', '<cmd>Telescope find_files<cr>')
vim.keymap.set('n', '<leader>fg', '<cmd>Telescope live_grep<cr>')
vim.keymap.set('n', '<leader>fb', '<cmd>Telescope buffers<cr>')
vim.keymap.set('n', '<leader>fh', '<cmd>Telescope help_tags<cr>')
Ligne d'état
Lualine Configuration
require('lualine').setup \\\\{
options = \\\\{
icons_enabled = true,
theme = 'auto',
component_separators = \\\\{ left = '', right = ''\\\\},
section_separators = \\\\{ left = '', right = ''\\\\},
disabled_filetypes = \\\\{
statusline = \\\\{\\\\},
winbar = \\\\{\\\\},
\\\\},
ignore_focus = \\\\{\\\\},
always_divide_middle = true,
globalstatus = false,
refresh = \\\\{
statusline = 1000,
tabline = 1000,
winbar = 1000,
\\\\}
\\\\},
sections = \\\\{
lualine_a = \\\\{'mode'\\\\},
lualine_b = \\\\{'branch', 'diff', 'diagnostics'\\\\},
lualine_c = \\\\{'filename'\\\\},
lualine_x = \\\\{'encoding', 'fileformat', 'filetype'\\\\},
lualine_y = \\\\{'progress'\\\\},
lualine_z = \\\\{'location'\\\\}
\\\\},
\\\\}
Caractéristiques avancées
Lua Scripting
-- Create custom commands
vim.api.nvim_create_user_command('Hello', function()
print('Hello from Neovim!')
end, \\\\{\\\\})
-- Create autocommands
vim.api.nvim_create_autocmd("BufWritePre", \\\\{
pattern = "*.lua",
callback = function()
vim.lsp.buf.format()
end,
\\\\})
-- Custom functions
local function toggle_number()
if vim.opt.number:get() then
vim.opt.number = false
vim.opt.relativenumber = false
else
vim.opt.number = true
vim.opt.relativenumber = true
end
end
vim.keymap.set('n', '<leader>tn', toggle_number)
Contrôle sanitaire
" Check Neovim health
:checkhealth
" Check specific provider
:checkhealth provider
:checkhealth nvim-treesitter
:checkhealth telescope
Migration de Vim
Principales différences
" Neovim uses different paths
:echo stdpath('config') " Config directory
:echo stdpath('data') " Data directory
:echo stdpath('cache') " Cache directory
" Better defaults
" No need for 'nocompatible'
" 'autoindent' is on by default
" 'autoread' is on by default
" 'background=dark' by default
" 'belloff=all' by default
" 'cscopeverbose' is on by default
" 'display=lastline' by default
" 'encoding=utf-8' by default
Compatibilité
" Most Vim plugins work with Neovim
" Vimscript is fully supported
" Can gradually migrate to Lua
" Check if running Neovim
if has('nvim')
" Neovim-specific configuration
endif
Déboguement
Débogage intégré
" Debug mode
nvim -D file.txt
" Verbose mode
nvim -V9 file.txt
" Check startup time
nvim --startuptime startup.log file.txt
" Profile startup
:profile start profile.log
:profile func *
:profile file *
Conseils de performance
Optimisation
-- Disable unused providers
vim.g.loaded_python_provider = 0
vim.g.loaded_ruby_provider = 0
vim.g.loaded_perl_provider = 0
vim.g.loaded_node_provider = 0
-- Lazy load plugins
-- Use event-based loading
-- Minimize startup plugins
-- Optimize search
vim.opt.regexpengine = 1
-- Reduce updatetime for better experience
vim.opt.updatetime = 250
Dépannage
Questions communes
" Plugin not working
:checkhealth
:PlugStatus
" LSP not working
:LspInfo
:LspLog
" TreeSitter issues
:TSInstallInfo
:TSUpdate
" Clear cache
rm -rf ~/.local/share/nvim
rm -rf ~/.cache/nvim
Ressources
- Documentation officielle: [neovim.io] (LINK_4)
- ** Dépôt GitHub** : [github.com/neovim/neovim] (LINK_4)
- Awesome Neovim: github.com/rockerBOO/awesome-neovim
- Communauté: [reddit.com/r/neovim] (LINK_4)