Introducción
Neovim es VIM pero mejorado. La documentación oficial lo define como:
Neovim es un editor de texto basado en Vim diseñado para la extensibilidad y usabilidad, para fomentar nuevas aplicaciones y contribuciones.
Instalación
Prerequisitos
Como lo dice el título de este artículo, me estaré concentrando en configurar Neovim como IDE para python, entonces voy a asumir que ya tienes Python y Pip instalados en tu sistema.
Python, Pip y Pipenv
Para verificar que tengas Python instalado corre uno de los siguientes comandos en la consola:
1
2
|
$ python --version
$ python3 --version
|
El comando anterior deberá decirte la versión de Python instalada en tu sistema
Para verificar si Pip está instalado, solo ejecuta pip en la consola. El comando deberá regresar la “ayuda”.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
$ pip
Usage:
pip <command> [options]
Commands:
install Install packages.
download Download packages.
uninstall Uninstall packages.
freeze Output installed packages in requirements format.
list List installed packages.
show Show information about installed packages.
check Verify installed packages have compatible dependencies.
config Manage local and global configuration.
search Search PyPI for packages.
cache Inspect and manage pip's wheel cache.
wheel Build wheels from your requirements.
hash Compute hashes of package archives.
completion A helper command used for command completion.
debug Show information useful for debugging.
help Show help for commands.
|
Si no tienes instalado pip, lo puedes instalar ejectando:
1
|
$ sudo apt-get install python3-pip
|
Para verificar si Pipenv está instalado, puedes ejecutar:
1
2
3
|
$ pipenv --version
pipenv, version 2020.11.15
|
Para instalar Pipenv, utiliza el siguiente comando:
Git
También vas a necesitar git para poder instalar el manejador de plugins “https://github.com/junegunn/vim-plug"
Si no lo tienes instalado, lo puedes instalar utilizando:
1
|
$ sudo apt-get install git
|
Neovim
Por supuesto, debemos tener instalado Neovim con soporte para python, si no lo tienes aún, lo puedes instalar de la siguiente manera:
1
|
$ sudo apt-get install neovim python3-neovim
|
Node.js
Para poder instalar los plugins que nos van a permitir utilizar Neovim como IDE y reemplazar de una vez por todas VsCode, es necesario también instalar Node.js.
1
|
$ sudo apt-get install npm
|
Nerdfont (Tipo de Letra)
Para poder visualizar los iconos en la terminal es necesario tener un tipo de letra que lo soporte, en lo personal a mi me gustan las Nerdfonts.
Puedes descargar DejaVuSansMono Nerd Font.
Una vez que hayas descargado el archivo, descomprimelo y copia los archivos (*.ttf) al siguiente directorio:
1
|
$HOME/.local/share/fonts/
|
Si por alguna razón no tienes el directorio, lo puedes crear.
Ya que hayas copiado los archivos, para poder utilizar este nuevo tipo de letra, debes ejecutar:
Asegurate de configurar este nuevo tipo de letra en la terminal que estés utilizando:
Configuración
Directorio nvim
Aunque puedes tener toda la configuración en tu archivo init.vim yo prefiero tener archivos separados para una mejor organización y fácil manejo.
Crea la siguiente estructura de direcorios:
1
2
3
4
5
|
📂 $HOME/.config/nvim/
├──📁 general
├──📁 keymapping
├──📁 nvim-plugins
└──📁 plug-config
|
1
2
3
4
5
|
mkdir $HOME/.config/nvim
mkdir $HOME/.config/nvim/general
mkdir $HOME/.config/nvim/keymapping
mkdir $HOME/.config/nvim/nvim-plugins
mkdir $HOME/.config/nvim/plug-config
|
Ambiente de Python para Neovim
Vamos a crear un ambiente virtual dentro de la carpeta de configuración de Neovim. Para eso, en la terminal tecleamos lo siguiente:
1
2
3
|
cd ~/.config/nvim
pipenv install
|
Copia la ruta donde se creó el ambiente virtual pues lo usaremos en el siguiente paso:
Archivos .vim
general/settings.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
syntax enable
set guicursor= " Disable blinking for the n-v-c modes
set termguicolors
set guioptions-=T " No Tool bar
set cursorline " Highlight the current line
set hidden " When on a buffer becomes hidden when it is abandoned
set path+=**
set nowrap
set encoding=UTF-8
set number relativenumber
set smartindent
set smarttab
set tabstop=4 softtabstop=4
set shiftwidth=4
set expandtab
set smartcase
set incsearch
set nohlsearch
set completeopt=menuone,noinsert,noselect
set signcolumn=yes
set colorcolumn=80
highlight ColorColumn ctermbg=0 guibg=lightgrey
set noswapfile
set nobackup
set undofile
execute 'set undodir=' . g:nvim_data_root . '/undodir'
" Python virtual environment detection in linux
let g:loaded_python_provider = 0
" Ruta donde se creó el ambiente de Python con pipenv.
let g:python3_host_prog = '/home/{usuario}/.local/share/virtualenvs/{nvim-999999}/bin/python'
|
Plugins
Instala vim-plug
Para instalar vim-plug vamos a ejecutar el siguiente comando:
1
2
|
sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
|
$HOME/.config/nvim/nvim-plugins/plugins.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
call plug#begin(stdpath('data').'/plugged')
" NERDTree
Plug 'preservim/nerdtree'
" VIM-DEVICONS icons for NERDTree
Plug 'ryanoasis/vim-devicons'
" Conquer Of Completion
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" Surround.vim
Plug 'tpope/vim-surround'
" Airline status bar
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
" NERDCommenter
Plug 'preservim/nerdcommenter'
call plug#end()
|
$HOME/.config/nvim/plug-config/coc.vim
El siguiente es un ejemplo funcional tomado de la documentación oficial en github.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
let g:coc_global_extensions = [
\ 'coc-snippets',
\ 'coc-pairs',
\ 'coc-python',
\ 'coc-prettier',
\ 'coc-vimlsp',
\ 'coc-marketplace',
\ ]
" TextEdit might fail if hidden is not set.
set hidden
" Some servers have issues with backup files, see #649.
set nobackup
set nowritebackup
" Give more space for displaying messages.
set cmdheight=2
" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
" delays and poor user experience.
set updatetime=300
" Don't pass messages to |ins-completion-menu|.
set shortmess+=c
" Always show the signcolumn, otherwise it would shift the text each time
" diagnostics appear/become resolved.
if has("patch-8.1.1564")
" Recently vim can merge signcolumn and number column into one
set signcolumn=number
else
set signcolumn=yes
endif
" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config.
inoremap <silent><expr> <TAB>
\ pumvisible() ? "\<C-n>" :
\ <SID>check_back_space() ? "\<TAB>" :
\ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
" Use <c-space> to trigger completion.
if has('nvim')
inoremap <silent><expr> <c-space> coc#refresh()
else
inoremap <silent><expr> <c-@> coc#refresh()
endif
" Make <CR> auto-select the first completion item and notify coc.nvim to
" format on enter, <cr> could be remapped by other vim plugin
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
\: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)
" GoTo code navigation.
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
" Use K to show documentation in preview window.
nnoremap <silent> K :call <SID>show_documentation()<CR>
function! s:show_documentation()
if (index(['vim','help'], &filetype) >= 0)
execute 'h '.expand('<cword>')
elseif (coc#rpc#ready())
call CocActionAsync('doHover')
else
execute '!' . &keywordprg . " " . expand('<cword>')
endif
endfunction
" Highlight the symbol and its references when holding the cursor.
autocmd CursorHold * silent call CocActionAsync('highlight')
" Symbol renaming.
nmap <leader>rn <Plug>(coc-rename)
" Formatting selected code.
xmap <leader>f <Plug>(coc-format-selected)
nmap <leader>f <Plug>(coc-format-selected)
augroup mygroup
autocmd!
" Setup formatexpr specified filetype(s).
autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
" Update signature help on jump placeholder.
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end
" Applying codeAction to the selected region.
" Example: `<leader>aap` for current paragraph
xmap <leader>a <Plug>(coc-codeaction-selected)
nmap <leader>a <Plug>(coc-codeaction-selected)
" Remap keys for applying codeAction to the current buffer.
nmap <leader>ac <Plug>(coc-codeaction)
" Apply AutoFix to problem on the current line.
nmap <leader>qf <Plug>(coc-fix-current)
" Map function and class text objects
" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
xmap if <Plug>(coc-funcobj-i)
omap if <Plug>(coc-funcobj-i)
xmap af <Plug>(coc-funcobj-a)
omap af <Plug>(coc-funcobj-a)
xmap ic <Plug>(coc-classobj-i)
omap ic <Plug>(coc-classobj-i)
xmap ac <Plug>(coc-classobj-a)
omap ac <Plug>(coc-classobj-a)
" Remap <C-f> and <C-b> for scroll float windows/popups.
if has('nvim-0.4.0') || has('patch-8.2.0750')
nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
inoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
inoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
vnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
vnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
endif
" Use CTRL-S for selections ranges.
" Requires 'textDocument/selectionRange' support of language server.
nmap <silent> <C-s> <Plug>(coc-range-select)
xmap <silent> <C-s> <Plug>(coc-range-select)
" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')
" Add `:Fold` command to fold current buffer.
command! -nargs=? Fold :call CocAction('fold', <f-args>)
" Add `:OR` command for organize imports of the current buffer.
command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')
" Add (Neo)Vim's native statusline support.
" NOTE: Please see `:h coc-status` for integrations with external plugins that
" provide custom statusline: lightline.vim, vim-airline.
set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}
" Mappings for CoCList
" Show all diagnostics.
nnoremap <silent><nowait> <space>a :<C-u>CocList diagnostics<cr>
" Manage extensions.
nnoremap <silent><nowait> <space>e :<C-u>CocList extensions<cr>
" Show commands.
nnoremap <silent><nowait> <space>c :<C-u>CocList commands<cr>
" Find symbol of current document.
nnoremap <silent><nowait> <space>o :<C-u>CocList outline<cr>
" Search workspace symbols.
nnoremap <silent><nowait> <space>s :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent><nowait> <space>j :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent><nowait> <space>k :<C-u>CocPrev<CR>
" Resume latest coc list.
nnoremap <silent><nowait> <space>p :<C-u>CocListResume<CR>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
|
$HOME/.config/nvim/plug-config/airline.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
" enable tabline
let g:airline#extensions#tabline#enabled = 1
" let g:airline#extensions#tabline#left_sep = ''
" let g:airline#extensions#tabline#left_alt_sep = ''
" let g:airline#extensions#tabline#right_sep = ''
" let g:airline#extensions#tabline#right_alt_sep = ''
" enable powerline fonts
let g:airline_powerline_fonts = 1
" let g:airline_left_sep = ''
" let g:airline_right_sep = ''
" Always show tabs
set showtabline=2
" We don't need to see things like -- INSERT -- anymore
set noshowmode
|
$HOME/.config/nvim/keymapping/keys.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
" Edit vimrc faster
nnoremap <Leader>v :e $MYVIMRC<cr>
" Reload init.vim
nnoremap <silent> <Leader><Leader> :source $MYVIMRC<cr>
"Change working directory
nnoremap <leader>cd :cd %:p:h<cr>
"Mapping NERDTree
map <C-n> :NERDTreeToggle<cr>
" Use alt + hjkl to resize windows
nnoremap <M-j> :resize -2<CR>
nnoremap <M-k> :resize +2<CR>
nnoremap <M-h> :vertical resize -2<CR>
nnoremap <M-l> :vertical resize +2<CR>
" NerdCommenter Toggle remap to CTRL+/
vmap <C-_> <Plug>NERDCommenterToggle<cr>
nmap <C-_> <Plug>NERDCommenterToggle<cr>
" Start Terminal using PowerShell 7 (Preview)
" For default shell, remove "://pwsh.exe"
" You can customize the shell by replacing "pwsh.exe" with your shell for example:
" :edit term://bash
" :vsplit term://top
" For more :help terminal
nmap <leader>t :vsplit term://bash<cr>
" Move between buffers
nnoremap <leader><tab> :bn<cr>
nnoremap <leader><S-tab> :bp<cr>
" Closing and hiding current buffer
nnoremap <leader>w :bd<cr>
|
$HOME/.config/nvim/init.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
|
let g:nvim_data_root = stdpath('data')
let g:nvim_config_root = stdpath('config')
let g:config_file_list = ['/nvim-plugins/plugins.vim',
\ '/general/settings.vim',
\ '/keymapping/keys.vim',
\ '/plug-config/airline.vim',
\ '/plug-config/coc.vim',
\ '/plug-config/nerdcommenter.vim',
\ ]
for f in g:config_file_list
execute 'source ' . g:nvim_config_root . f
endfor
|
Reiniciar Neovim e instalar los plugins
Una vez que guardes los cambios, debes salir de Neovim y volver a entrar, luego ejecutar :PlugInstall
Esto instalará los plugins y las extensiones de CConquer of Completion (coc).
Paso Final: Configura coc-python
Para que todo funcione correctamente debes instalar de manera global una libreria de python llamada “jedi”. Al instalarlo de manera global te evitarás tener que instalarlo en cada uno de tus ambientes virtuales.
Para Instalar:
Una vez instalada, hay que configurar CoC. Primero copia la ruta donde se instaló jedi, para saber esa ruta ejecuta lo siguiente en la terminal:
1
2
3
4
5
6
7
8
9
10
11
12
|
$ pip show jedi
Name: jedi
Version: 0.17.2
Summary: An autocompletion tool for Python that can be used for text editors.
Home-page: https://github.com/davidhalter/jedi
Author: David Halter
Author-email: davidhalter88@gmail.com
License: MIT
Location: /usr/lib/python3.9/site-packages <== Esta es la ruta que debes copiar en el siguiente archivo de configuración
Requires: parso
Required-by:
|
Abre Neovim y ejecuta :CocConfig
Esto abrirá un buffer vacío, este buffer es donde configuras CoC
Agrega lo siguiente, reemplazando la ruta por la ruta donde está instalado “jedi” en tu sistema:
1
2
3
|
{
"python.jediPath": "/usr/lib/python3.9/site-packages"
}
|
Guarda el archivo, cierra Neovim y vuelve a abrir.
Listo, hasta aquí tienes una configuración lista para trabajar con Neovim y reemplazar VSCode.
Bonus
Gruvbox 💻
En lo personal, el mejor tema para programar en Neovim, es Gruvbox, la combinación de colores se me hace seria y sobretodo muy cómodo para la vista, simple y sencillamente… ¡Me Encanta!
Primero agregamos el plugin en $HOME/.config/nvim/nvim-plugins/plugins.vim
1
2
|
" Other themes
Plug 'morhetz/gruvbox'
|
Recuerda que una vez que guardes los cambios, debes salir de Neovim y volver a entrar, luego correr :PlugInstall
Después hay que editar $HOME/.config/nvim/general/settings.vim para agregar gruvbox como tema por defecto.
1
2
3
4
|
" Gruvbox por defecto
colorscheme gruvbox
let g:gruvbox_contrast_dark='hard'
set background=dark
|
Por último, vamos a configurar Airline con el mismo tema de colores. Para eso hay que editar $HOME/.config/nvim/plug-config/airline.vim
1
2
|
"Gruvbox
let g:airline_theme='gruvbox'
|
Conclusión
Neovim es un editor de textos ligero y sobretodo muy “configurable”, al principio puede parecer intimidante pero con el tiempo y la práctica se vuelve una herramienta muy útil para el desarrollo.
Si deseas conocer que otras extensiones existen para CoC, visita la wiki oficial donde encontraras basta información.
Si tienes algún comentario o recomendación de algún artículo que te gustaría que cubriera en este blog, no dudes en mandarme un mensaje en twitter a @JorgeRS
Si te gustó este artículo por favor compartelo en cualquiera de las redes sociales utilizando los botones más abajo.