Ho provato per vari anni i maggiori editor di testi disponibili sul mercato: da Sublime Text, Atom, il famosissimo VSCode, PHPStorm e altri marchiati JetBrains. Devo dire che
i migliori per facilità d’utilizzo, comodi per funzionalità di base o con l’aggiunta di plugins sono quelli di JetBrains e VSCode. Quest’ultimo l’ho utilizzato negli ultimi anni
accantonando i JetBrains solamente per via del loro costo. Ho impostato VSCode per un utilizzo con vari linguaggi di programmazione, ho imparato gli shortcodes per rendere
la digitazione e il movimento all’interno del programma più veloce e fluido e mantenere le dita il più possibile sui tasti e non spostarli su frecce direzionali o mouse.
Devo dire che mi sono sempre trovato bene ma ho sempre usato vim in remoto sui server per modificare configurazioni, settaggi etc..
I PRIMI PASSI CON VIM E NEOVIM
Come dicevo in precedenza, vim l’ho scoperto anni e anni fa appena ho avuto la necessità di gestire server remoti, anche in altri stati: non avendo grafica, la gestione delle
configurazioni avviene tutta tramite riga di comando e vim è un must da saper utilizzare. Selezionare, taglia-copia-incolla, modificare, inserire parole o paragrafi,
ricercare stringhe e sostituirle; insomma, vim è un editor completo a cui non manca nulla rispetto a uno classico da desktop.
Non è complicato da usare, ci sono molti video su Youtube in cui si spiegano i 4 comandi essenziali per iniziare ad utilizzarlo.
Guardando video e leggendo reddit avevo visto che molti suggerivano di abbandonare i ‘classici’ editor e di passare a vim, più nello specifico NeoVim.
Neovim is a Vim-based text editor engineered for extensibility and usability, to encourage new applications and contributions.
Ho voluto provarlo con un progetto già iniziato con VSCode.
Mai scelta fu più azzeccata: dalla console si riesce a fare anche di più di quello che VSCode permette; personalizzare i comandi, combinazione dei tasti per effettuare
anche movimenti all’interno della schermato di lavoro.
Metto a disposizione di chi voglia provare una nuova modalità di scrittura i miei dotfiles.
OCCORRENTE
Questo è un piccolo riassunto di quello che servirà per avere un sistema funzionante.
- NeoVim Versione >= 0.7;
- wbthomason/packer.nvim - Plugin manager per Neovim;
- svrana/neosolarized.nvim - Dark Colorschema;
- nvim-lualine/lualine.nvim - Per la status line di Neovim;
- onsails/lspkind-nvim - Simboli grafici simili a VSCode;
- L3MON4D3/LuaSnip - Snipper Engine scritto in Lua per Neovim,
- hrsh7th/cmp-nvim-lsp - Sorgente nvim-cmp per il built-in LSP di Neovim;
- hrsh7th/cmp-buffer - Sorgent nvim-cmp per il buffer;
- hrsh7th/nvim-cmp - Un plugin per l’aiuto al completamento scritto in Lua;
- neovim/nvim-lspconfig - Una collezione di configurazioni per in built-in LSP;
- jose-elias-alvarez/null-ls.nvim - Con questo plugin Neovim si può utilizzare come diagnostica con LSP, linter e code action attraverso Lua.
- MunifTanjim/prettier.nvim - Plugin per prettier da utilizzare con Neovim e il suo motore LSP;
- williamboman/mason.nvim - Plugin per la gestione degli applicativi che si integrano con LSP come i formatters, linters ecc…;
- williamboman/mason-lspconfig.nvim - Estensione di Mason che rende facile configurare lspconfig di NeoVim;
- nvim-treesitter/nvim-treesitter - Configurazione per TreeSitter;
- nvim-telescope/telescope.nvim - Ottimo plugin per ricercare;
- nvim-telescope/telescope-file-browser.nvim - Plugin per rendere un file browser telescope;
- windwp/nvim-autopairs - Gestione intelligente delle parentisi;
- norcalli/nvim-colorizer.lua - Plugin per visualizzare i colori scelti partendo dal codice colore (Es: #558817);
- lewis6990/gitsigns.nvim - Integrazione di GIT;
- folke/zen-mode.nvim - Zero distrazioni con questo plugin;
- iamcco/markdown-preview.nvim - Markdown Preview Live;
- numToStr/Comment.nvim - Gestione dei commenti nel codice scritto in Lua;
- rmagatti/auto-session - Gestione della sessione di Neovim.
PREREQUISITI
Alacritty è la console che ho scelto di utilizzare. Per visualizzare i glifi sulla console utilizzo Nerd fonts.
Struttura delle directory
Neovim è conforme alla struttura delle directory XDG Base Directory.
Neovim carica $HOME/.config/nvim/init.vim
o ìnit.lua
invece di $HOME/.vimrc.
É presente una guida con i primi passi per utilizzare Neovim.
INSTALLAZIONE
Spiegherò brevemente come installare i pacchetti necessari per un utilizzo basilare
Neovim
Come prima cosa deve essere installato NeoVim:
macOS / OS X
brew install neovim
Arch Linux
sudo pacman -S neovim
Debian / Ubuntu
sudo apt-get install neovim
Packer
Installare prima di tutto wbthomason/packer.nvim con il seguente comando per la gestione dei plugins di Neovim:
git clone --depth 1 https://github.com/wbthomason/packer.nvim \
~/.local/share/nvim/site/pack/packer/start/packer.nvim
Successivamente creare il file ./.config/nvim/lua/plugins.lua
contenente il seguente codice:
local status, packer = pcall(require, "packer")
if (not status) then
print("Packer is not installed")
return
end
vim.cmd [[packadd packer.nvim]]
packer.startup(function(use)
use 'wbthomason/packer.nvim'
-- Your plugins go here
end)
e richiamarlo nel file init.lua
:
git config pull.rebase false
Neosolarized
Utilizzo svrana/neosolarized.nvim con qualche minima modifica:
local status, n = pcall(require, "neosolarized")
if (not status) then return end
n.setup({
comment_italics = true,
})
local cb = require('colorbuddy.init')
local Color = cb.Color
local colors = cb.colors
local Group = cb.Group
local groups = cb.groups
local styles = cb.styles
Color.new('black', '#000000')
Group.new('CursorLine', colors.none, colors.base03, styles.NONE, colors.base1)
Group.new('CursorLineNr', colors.yellow, colors.black, styles.NONE, colors.base1)
Group.new('Visual', colors.none, colors.base03, styles.reverse)
local cError = groups.Error.fg
local cInfo = groups.Information.fg
local cWarn = groups.Warning.fg
local cHint = groups.Hint.fg
Group.new("DiagnosticVirtualTextError", cError, cError:dark():dark():dark():dark(), styles.NONE)
Group.new("DiagnosticVirtualTextInfo", cInfo, cInfo:dark():dark():dark(), styles.NONE)
Group.new("DiagnosticVirtualTextWarn", cWarn, cWarn:dark():dark():dark(), styles.NONE)
Group.new("DiagnosticVirtualTextHint", cHint, cHint:dark():dark():dark(), styles.NONE)
Group.new("DiagnosticUnderlineError", colors.none, colors.none, styles.undercurl, cError)
Group.new("DiagnosticUnderlineWarn", colors.none, colors.none, styles.undercurl, cWarn)
Group.new("DiagnosticUnderlineInfo", colors.none, colors.none, styles.undercurl, cInfo)
Group.new("DiagnosticUnderlineHint", colors.none, colors.none, styles.undercurl, cHint)
Status line: Lualine
nvim-lualine/lualine.nvim è un plugin che permette di creare graziose status line con le informazioni più utili mentre si lavora.
local status, lualine = pcall(require, "lualine")
if (not status) then return end
lualine.setup {
options = {
icons_enabled = true,
theme = 'solarized_dark',
section_separators = { left = '', right = '' },
component_separators = { left = '', right = '' },
disabled_filetypes = {}
},
sections = {
lualine_a = { 'mode' },
lualine_b = { 'branch' },
lualine_c = { {
'filename',
file_status = true, -- displays file status (readonly status, modified status)
path = 0 -- 0 = just filename, 1 = relative path, 2 = absolute path
} },
lualine_x = {
{ 'diagnostics', sources = { "nvim_diagnostic" }, symbols = { error = ' ', warn = ' ', info = ' ',
hint = ' ' } },
'encoding',
'filetype'
},
lualine_y = { 'progress' },
lualine_z = { 'location' }
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_c = { {
'filename',
file_status = true, -- displays file status (readonly status, modified status)
path = 1 -- 0 = just filename, 1 = relative path, 2 = absolute path
} },
lualine_x = { 'location' },
lualine_y = {},
lualine_z = {}
},
tabline = {},
extensions = { 'fugitive' }
}
LSPConfig
Neovim ha all’interno del proprio codice il supporto a LSP. Con neovim/nvim-lspconfig lo si può configurare facilemente.
Per esempio, per attivare il supporto a typescript con neovim:
local status, nvim_lsp = pcall(require, "lspconfig")
if (not status) then return end
local protocol = require('vim.lsp.protocol')
local on_attach = function(client, bufnr)
-- format on save
if client.server_capabilities.documentFormattingProvider then
vim.api.nvim_create_autocmd("BufWritePre", {
group = vim.api.nvim_create_augroup("Format", { clear = true }),
buffer = bufnr,
callback = function() vim.lsp.buf.formatting_seq_sync() end
})
end
end
-- TypeScript
nvim_lsp.tsserver.setup {
on_attach = on_attach,
filetypes = { "typescript", "typescriptreact", "typescript.tsx" },
cmd = { "typescript-language-server", "--stdio" }
}
e non dimentichiamoci di installare il server per typescript con il comando:
npm i -g typescript-language-server
Auto completion: Lspkind and cmp
Per ottenere LSP con l’autocompletamento automatico con i pittogrammi ho usato i seguenti plugins:
- onsails/lspkind-nvim: pittogrammi simili in VSCode;
- L3MON4D3/LuaSnip: snippet engine;
- hrsh7th/cmp-nvim-lsp: nvim-cmp sorgenti per LSP;
- hrsh7th/cmp-buffer: nvim-cmp sorgenti per il buffer;
- hrsh7th/nvim-cmp: plugin per l’autocompletamento di neovim.
E configurarlo come segue:
local status, cmp = pcall(require, "cmp")
if (not status) then return end
local lspkind = require 'lspkind'
cmp.setup({
snippet = {
expand = function(args)
require('luasnip').lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
['<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
}),
}),
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'buffer' },
}),
formatting = {
format = lspkind.cmp_format({ with_text = false, maxwidth = 50 })
}
})
vim.cmd [[
set completeopt=menuone,noinsert,noselect
highlight! default link CmpItemKind CmpItemMenuDefault
]]
Highlight syntax: TreeSitter
TreeSitter è un linguaggio parser popolare per evidenziare e colorare il codice a schermo: installarlo con il seguente comando:
macOS / OS X
brew install tree-sitter
Arch Linux
sudo pacman -S tree-sitter
Debian / Ubuntu
sudo apt-get install tree-sitter
Passo successivo è installare il plugin nvim-treesitter/nvim-treesitter con Packer e configurarlo:
local status, ts = pcall(require, "nvim-treesitter.configs")
if (not status) then return end
ts.setup {
highlight = {
enable = true,
disable = {},
},
indent = {
enable = true,
disable = {},
},
ensure_installed = {
"tsx",
"toml",
"fish",
"php",
"json",
"yaml",
"swift",
"css",
"html",
"lua"
},
autotag = {
enable = true,
},
}
local parser_config = require "nvim-treesitter.parsers".get_parser_configs()
parser_config.tsx.filetype_to_parsername = { "javascript", "typescript.tsx" }
Autotag e Autopair
Con React capita molto spesso di voler chiudere i tags nel modo più rapido ed efficiente possibile. windwp/nvim-ts-autotag ci viene in soccorso:
local status, autotag = pcall(require, "nvim-ts-autotag")
if (not status) then return end
autotag.setup({})
Mentre windwp/nvim-autopairs è per chiudere in automatico le parentesi.
local status, autopairs = pcall(require, "nvim-autopairs")
if (not status) then return end
autopairs.setup({
disable_filetype = { "TelescopePrompt" , "vim" },
})
Telescope
nvim-telescope/telescope.nvim è un utilissimo plugin per la ricerca di files e stringhe, grazie al suo potente motore di ricerca, nella cartella di lavoro.
Con l’aggiunta di nvim-telescope/telescope-file-browser.nvim sarà possibile visualizzare anche un’anteprima del file senza la necessità di aprirlo.
Configurazione richiesta:
local status, telescope = pcall(require, "telescope")
if (not status) then return end
local actions = require('telescope.actions')
local builtin = require("telescope.builtin")
local function telescope_buffer_dir()
return vim.fn.expand('%:p:h')
end
local fb_actions = require "telescope".extensions.file_browser.actions
telescope.setup {
defaults = {
mappings = {
n = {
["q"] = actions.close
},
},
},
extensions = {
file_browser = {
theme = "dropdown",
-- disables netrw and use telescope-file-browser in its place
hijack_netrw = true,
mappings = {
-- your custom insert mode mappings
["i"] = {
["<C-w>"] = function() vim.cmd('normal vbd') end,
},
["n"] = {
-- your custom normal mode mappings
["N"] = fb_actions.create,
["h"] = fb_actions.goto_parent_dir,
["/"] = function()
vim.cmd('startinsert')
end
},
},
},
},
}
telescope.load_extension("file_browser")
-- keymaps
vim.keymap.set('n', ';f',
function()
builtin.find_files({
no_ignore = false,
hidden = true
})
end)
vim.keymap.set('n', ';r', function()
builtin.live_grep()
end)
vim.keymap.set('n', '\\\\', function()
builtin.buffers()
end)
vim.keymap.set('n', ';t', function()
builtin.help_tags()
end)
vim.keymap.set('n', ';;', function()
builtin.resume()
end)
vim.keymap.set('n', ';e', function()
builtin.diagnostics()
end)
vim.keymap.set("n", "sf", function()
telescope.extensions.file_browser.file_browser({
path = "%:p:h",
cwd = telescope_buffer_dir(),
respect_gitignore = false,
hidden = true,
grouped = true,
previewer = false,
initial_mode = "normal",
layout_config = { height = 40 }
})
end)
Gestione tabs: Bufferline
Ho installato anche akinsho/nvim-bufferline.lua per una migliore gestione dei tabs.
Code Formatting: Prettier e null-ls
jose-elias-alvarez/null-ls.nvim
è un plugin per poter utilizzare Neovim come linter, formatter, code action e tanto altro con Lua.
Nella configurazione che segue è impostato la diagnostica con eslint_d
e
il formatting con prettierd
if (not status) then return end
local augroup_format = vim.api.nvim_create_augroup("Format", { clear = true })
null_ls.setup({
sources = {
-- diagnostics
null_ls.builtins.diagnostics.eslint_d.with({
diagnostics_format = '[eslint] #{m}\n(#{c})'
}),
null_ls.builtins.diagnostics.tidy,
-- linters
null_ls.builtins.formatting.prettierd,
-- code action
},
on_attach = function(client, bufnr)
if client.server_capabilities.documentFormattingProvider then
vim.api.nvim_clear_autocmds { buffer = 0, group = augroup_format }
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup_format,
buffer = 0,
callback = function() vim.lsp.buf.formatting_seq_sync() end
})
end
end,
})
Gitsigns
lewis6991/gitsigns.nvim integra le decorazioni ai lati dello schermo delle modifiche per il buffer corrente. É un aiuto per sapere quali linee di codice sono state modificate.
Non c’è bisogno di grandi configurazioni:
require('gitsigns').setup {}
Mason
williamboman/mason.nvim e williamboman/mason-lspconfig.nvim sono utilizzati nel caso servono librerie addizionali per LSP: Mason tramite un popup mostra quali language server sono disponibili e li installa in automatico.
Commenti
Capita spesso di dover commentare porzioni di codice e
numToStr/Comment.nvim è il plugin
perfetto. Supporta treesitter
, commentstring
ed è possibile inserire commenti
su singola linea //
o su blocco di più righe /* */
.
Per creare il default mapping:
require('Comment').setup()
AutoSession
rmagatti/auto-session è un plugin per la gestione della sessione di Neovim. Si avvantaggia della già esistente gestione della sessione presente in Neovim e la automatizza.
La uso associata a tmux/tmux per riprendere il lavoro nello stesso punto lasciato prima di un riavvio del PC. Ci si ritrova il cursore esattamente nella stessa linea.
Questo è attualmente il mio setup per Neovim. Tutta la configurazione e dotfiles sono online nel mio repo.