Vim, guía de referencia rápida

Vim (Vi IMproved) es uno de los mejores editores que existen para consola (aunque también hay una versión gráfica). Destaca por su simplicidad y la posibilidad de trabajar sin tener que levantar las manos del teclado, no obstante la curva de aprendizaje inicial es algo elevada y esto puede frenar a algunos usuarios.

Por defecto Ubuntu instala una versión reducida (tiny) de este editor que no es tan configurable como la versión completa, así que antes de empezar nos aseguramos de tener esta última:

sudo aptitude install vim

A continuación creamos el fichero ‘/etc/vim/vimrc.local’ (o ~/.vimrc si solo queremos que afecte nuestro usuario) con la siguiente configuración:

" Modified by Sergi Blanco Cuaresma
" Based on Awesome Vim version 5.0 - 29/05/12 15:43:36:
"       Amir Salihefendic
" -

" => General
" Sets how many lines of history VIM has to remember
set history=700

" Enable filetype plugins
filetype plugin on
filetype indent on

" Set to auto read when a file is changed from the outside
set autoread

" With a map leader it's possible to do extra key combinations
" like <leader>w saves the current file
let mapleader = ","
let g:mapleader = ","

" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap w!! %!sudo tee > /dev/null %

" Correct typical mistakes (capital letters)
nmap :W :w
nmap :Q :q
nmap :WQ :wq
nmap :wQ :wq
nmap :Wq :wq

"" Tab indentation in other modes and shift-tab for unidenting
" for command mode
nmap <S-Tab> <
" for insert mode
imap <S-Tab> <Esc><i
" for visual mode
vmap <S-Tab> <gv
vmap <Tab> >gv

" Copy/paste from system clipboard
map <C-y> "+y<CR>
map <C-p> "+P<CR>

" Toogle mouse
nnoremap <F8> :call ToggleMouse()<CR>

" Indentation guides
nmap <S-F5> :call ToggleIndentGuidesTabs()<cr>
nmap <F5> :call ToggleIndentGuidesSpaces()<cr>

" Troggle wrapping
" - For moving within wrapped lines use g[cursor] in normal mode 
map <F6> :set nowrap! <CR>

" => VIM user interface
" Set 7 lines to the cursor - when moving vertically using j/k
set so=7

" Turn on the WiLd menu. Try it using:
" - :b <Tab>
" - :e <Tab>
set wildmenu

" Ignore compiled files
set wildignore=*.o,*~,*.pyc

"Always show current position
set ruler

" Height of the command bar
set cmdheight=2

" A buffer becomes hidden when it is abandoned
set hid

" Configure backspace so it acts as it should act
set backspace=eol,start,indent
set whichwrap+=<,>,h,l

" Ignore case when searching
set ignorecase

" When searching try to be smart about cases 
set smartcase

" Highlight search results
set hlsearch

" Makes search act like search in modern browsers
set incsearch 

" Don't redraw while executing macros (good performance config)
set lazyredraw 

" For regular expressions turn magic on
set magic

" Show matching brackets when text indicator is over them
set showmatch 
" How many tenths of a second to blink when matching brackets
set mat=2

" Show line number
set nonumber
"set number

" Activate mouse
"set mouse=a

" No annoying sound on errors
set noerrorbells
set novisualbell
set t_vb=
set tm=500
set vb

" => Colors and Fonts
" Enable syntax highlighting
syntax enable 

    colorscheme desert

set background=dark

" Set extra options when running in GUI mode
if has("gui_running")
        colorscheme koehler
    set guioptions-=T
    set guioptions+=e
    set t_Co=256
    set guitablabel=%M\ %t

" Set utf8 as standard encoding and en_US as the standard language
set encoding=utf8

" Use Unix as the standard file type
set ffs=unix,dos,mac

" Set font according to system
if has("mac") || has("macunix")
    set gfn=Monaco:h15
    set shell=/bin/bash
elseif has("win16") || has("win32")
    set gfn=Bitstream\ Vera\ Sans\ Mono:h12
elseif has("linux")
    set guifont=Monospace\ 11
    set shell=/bin/bash
    set guifont=Monospace\ 11
    set shell=/bin/bash

" Open MacVim in fullscreen mode
if has("gui_macvim")
    set fuoptions=maxvert,maxhorz
    "au GUIEnter * set fullscreen

" => Files, backups and undo
" Turn backup off, since most stuff is in SVN, git et.c anyway...
set nobackup
set nowb
set noswapfile

" => Turn persistent undo on 
"    means that you can undo even when you close a buffer/VIM
    set undodir=~/.vim/undodir
    set undofile
    set undolevels = 1000 "maximum number of changes that can be undone
    set undoreload = 10000 "maximum number lines to save for undo on a buffer reload

" => Parenthesis/bracket
" Visual selection and $1 to suround it by (), etc...
vnoremap $1 <esc>`>a)<esc>`<i(<esc>
vnoremap $2 <esc>`>a]<esc>`<i[<esc>
vnoremap $3 <esc>`>a}<esc>`<i{<esc>
vnoremap $$ <esc>`>a"<esc>`<i"<esc>
vnoremap $q <esc>`>a'<esc>`<i'<esc>
vnoremap $e <esc>`>a"<esc>`<i"<esc>

" Map auto complete of (, ", ', [ in insert mode
inoremap $1 ()<esc>i
inoremap $2 []<esc>i
inoremap $3 {}<esc>i
inoremap $4 {<esc>o}<esc>O
inoremap $q ''<esc>i
inoremap $e ""<esc>i
inoremap $t <><esc>i

" => Text, tab and indent related
" Use spaces instead of tabs
set expandtab

" Be smart when using tabs ;)
set smarttab

" 1 tab == 4 spaces
set shiftwidth=4
set tabstop=4

" Linebreak on 500 characters
set lbr
set tw=500

set autoindent "Auto indent
" indent depending on the filetype
"set smartindent
set nosmartindent
filetype indent on

set wrap "Wrap lines

    " Mark at 80 characters
    set colorcolumn=81

" => Visual mode related
" Visual mode pressing * or # searches for the current selection
" Super useful! From an idea by Michael Naumann
vnoremap <silent> * :call VisualSelection('f')<CR>
vnoremap <silent> # :call VisualSelection('b')<CR>

" => Moving around, tabs, windows and buffers
" Treat long lines as break lines (useful when moving around in them)
map <Down> gj
map <Up> gk

" Map <Space> to / (search) and Ctrl-<Space> to ? (backwards search)
map <space> /
map <c-space> ?

" Disable highlight when <leader><cr> is pressed
map <silent> <leader><cr> :noh<cr>

" Smart way to move between windows
map <M-Down> <C-W>j
map <M-Up> <C-W>k
map <M-Left> <C-W>h
map <M-Right> <C-W>l

" Buffer shortcuts
nmap <C-Left> :bprevious!<cr>
nmap <C-Right> :bnext!<cr>
" Close the current buffer
map <leader>bc :Bclose<cr>
map <leader>bd :bdelete<cr> 

" Quickly open a buffer for scripbble
map <leader>q :e ~/buffer<cr>

" When editing a file, always jump to the last cursor position
autocmd BufReadPost *
      \ if line("'\"") > 0 && line ("'\"") <= line("$") |
      \   exe "normal g'\"" |
      \ endif

" Tell vim to remember certain things when we exit
"  '10  :  marks will be remembered for up to 10 previously edited files
"  "100 :  will save up to 100 lines for each register
"  :20  :  up to 20 lines of command-line history will be remembered
"  %    :  saves and restores the buffer list
"  n... :  where to save the viminfo files
"set viminfo='10,\"100,:20,%,n~/.viminfo
set viminfo='10,\"100,:20,n~/.viminfo

" => Status line
" Always show the status line
set laststatus=2

" Format the status line
set statusline=\ %{HasPaste()}%F%m%r%h\ %w\ \ CWD:\ %r%{getcwd()}%h\ \ \ Line:\ %l

" In case the Powerline plugin is installed:
set nocompatible   " Disable vi-compatibility
set t_Co=256 " Explicitly tell vim that the terminal supports 256 colors
let g:Powerline_stl_path_style ='relative'

" => Editing mappings
" Delete trailing white space on save, useful for Python and CoffeeScript ;)
func! DeleteTrailingWS()
  exe "normal mz"
  exe "normal `z"
autocmd BufWrite *.py :call DeleteTrailingWS()
autocmd BufWrite *.coffee :call DeleteTrailingWS()

" => vimgrep searching and cope displaying
" When you press gv you vimgrep after the selected text
vnoremap <silent> gv :call VisualSelection('gv')<CR>

" Open vimgrep and put the cursor in the right position
map <leader>g :vimgrep // **/*.<left><left><left><left><left><left><left>

" Vimgreps in the current file
map <leader><space> :vimgrep // <C-R>%<C-A><Home><right><right><right><right><right><right><right><right><right>

" When you press <leader>r you can search and replace the selected text
vnoremap <silent> <leader>r :call VisualSelection('replace')<CR>

" Do :help cope if you are unsure what cope is. It's super useful!
" When you search with vimgrep, display your results in cope by doing:
"   <leader>cc
" To go to the next search result do:
"   <leader>n
" To go to the previous search results do:
"   <leader>p
map <leader>cc :botright cope<cr>
map <leader>co ggVGy:tabnew<cr>:set syntax=qf<cr>pgg
map <leader>n :cn<cr>
map <leader>p :cp<cr>

" => Spell checking
" Pressing ,ss will toggle and untoggle spell checking
map <leader>ss :setlocal spell!<cr>

" Shortcuts using <leader>
map <leader>sn ]s
map <leader>sp [s
map <leader>sa zg
map <leader>s? z=

" => Misc
" Remove the Windows ^M - when the encodings gets messed up
noremap <Leader>m mmHmt:%s/<C-V><cr>//ge<cr>'tzt'm

" Toggle paste mode on and off
map <leader>pp :setlocal paste!<cr>

" => :Explore
" Open file in current window
let g:netrw_browse_split=0

" Hide files
let g:netrw_hide=1

" Files to be hidden (comma separated)
let g:netrw_list_hide='^\..*'

" Long list mode (details)
let g:netrw_longlist=1

" Sort by name, time or size
let g:netrw_sort_by="name"

" Sorted in a normal or reverse
let g:netrw_sort_direction="normal"

" => bufExplorer plugin
"let g:bufExplorerSortBy='name'
let g:bufExplorerSortBy='number'
map <leader>o :TMiniBufExplorer<cr>

" => Nerd Tree
map <leader>nn :NERDTreeToggle<cr>
"map <leader>nf :NERDTreeFind<cr>

" => tagList plugin
map <leader>tt :Tlist <CR>

" => Python section
let python_highlight_all = 1
au FileType python syn keyword True None False self

au FileType python map <buffer> F :set foldmethod=indent<cr>

au FileType python inoremap <buffer> $r return 
au FileType python inoremap <buffer> $i import 
au FileType python inoremap <buffer> $p print 
au FileType python inoremap <buffer> $f #--- PH ----------------------------------------------<esc>FP2xi
au FileType python map <buffer> <leader>1 /class 
au FileType python map <buffer> <leader>2 /def 
au FileType python map <buffer> <leader>C ?class 
au FileType python map <buffer> <leader>D ?def 

" => Helper functions
function! CmdLine(str)
    exe "menu Foo.Bar :" . a:str
    emenu Foo.Bar
    unmenu Foo

function! VisualSelection(direction) range
    let l:saved_reg = @"
    execute "normal! vgvy"

    let l:pattern = escape(@", '\\/.*$^~[]')
    let l:pattern = substitute(l:pattern, "\n$", "", "")

    if a:direction == 'b'
        execute "normal ?" . l:pattern . "^M"
    elseif a:direction == 'gv'
        call CmdLine("vimgrep " . '/'. l:pattern . '/' . ' **/*.')
    elseif a:direction == 'replace'
        call CmdLine("%s" . '/'. l:pattern . '/')
    elseif a:direction == 'f'
        execute "normal /" . l:pattern . "^M"

    let @/ = l:pattern
    let @" = l:saved_reg

" Returns true if paste mode is enabled
function! HasPaste()
    if &paste
        return 'PASTE MODE  '
    return ''

" Don't close window, when deleting a buffer
command! Bclose call <SID>BufcloseCloseIt()
function! <SID>BufcloseCloseIt()
   let l:currentBufNum = bufnr("%")
   let l:alternateBufNum = bufnr("#")

   if buflisted(l:alternateBufNum)
     buffer #

   if bufnr("%") == l:currentBufNum

   if buflisted(l:currentBufNum)
     execute("bdelete! ".l:currentBufNum)

function! ToggleMouse()
  if &mouse == 'a'
    set mouse=
    echo "Mouse usage disabled"
    set mouse=a
    echo "Mouse usage enabled"

function! ToggleIndentGuidesTabs()
	if exists('b:iguides_tabs')
		setlocal nolist
		let &l:listchars = b:iguides_tabs
		unlet b:iguides_tabs
		let b:iguides_tabs = &l:listchars
		setlocal listchars=tab:?\ "protect the space
		setlocal list

function! ToggleIndentGuidesSpaces()
	if exists('b:iguides_spaces')
		call matchdelete(b:iguides_spaces)
		unlet b:iguides_spaces
		let pos = range(1, &l:textwidth, &l:shiftwidth)
		call map(pos, '"\\%" . v:val . "v"')
		let pat = '\%(\_^\s*\)\@<=\%(' . join(pos, '\|') . '\)\s'
		let b:iguides_spaces = matchadd('CursorLine', pat)

Por otra parte, si queremos utilizar la versión gráfica de vim instalaremos “vim-full”:

apt-get install vim-full


Para editar un archivo con Vim ejecutaremos:

vim nombre_archivo.txt
gvim nombre_archivo.txt

Es habitual que se tenga definido un alias de forma que cuando ejecutemos “vi”, realmente estemos ejecutando “vim”:

alias vi='vim'

Este texto debe ser incluido en los archivos .bashrc y .bash_profile del directorio personal del usuario (cd $HOME).

Una vez tenemos abierto vim y estamos editando un archivo debemos conocer diversos comandos para poder utilizar el entorno. El editor se puede encontrar en 3 modos diferentes:

  • Modo normal (Normal mode): Se pueden utilizar ciertas combinaciones de teclas para realizar ciertas acciones. Para acceder a este modo presionar escape.
  • Modo inserción (Insertion mode): Se puede insertar (insert) o sobreescribir el texto (append). Para acceder a este modo presionar ‘i’, ‘a’ o la tecla ‘insert’ (1 vez = insert, 2 veces = append).
  • Modo comando (Command mode): Se puede utilizar cualquier comando SED además de funciones propias de Vim. Para acceder a este modo se debe estar en modo normal y pulsar ‘:’, a continuación se escribirá nuestra petición.
  • Modo visual (visual mode): Se puede selecionar texto para tratarlo en conjunto. Para acceder a este modo se debe estar en modo normal y pulsar ‘v’.

Modo Normal

  • Desplazamiento con los cursores del teclado o con h (izquierda), j (arriba), k (abajo) y l (derecha)
  • Última línea
  • G

  • Primera línea
  • gg

  • Deshacer
  • u

  • Rehacer
  • CTRL+r

  • Buscar un texto
  • /texto[ENTER]

  • Buscar el texto donde se encuentra el cursor
  • %

  • Buscar el texto donde se encuentra el cursor en sentido inverso
  • #

  • Repetir última búsqueda
  • n

  • Repetir última búsqueda en sentido contrario
  • N

  • Dividir la pantalla horizontalmente en 2:
  • CTRL+ws

  • Dividir la pantalla verticalmente en 2:
  • CTRL+wv

  • Crear un nuevo archivo en una pantalla dividida horizontalmente:
  • CTRL+wn

  • Cerrar la división actual
  • CTRL+wq

  • Moverse a la ventana de arriba (j), abajo (k), izquierda (h) o derecha (l):
  • CTRL+w{j,k,h,l} ó CTRL+w{cursores del teclado}

  • Hacer todas las ventanas del mismo tamaño
  • CTRL+w=

  • Incrementar/Decrementar la altura de la ventana actual
  • CTRL+{+,-}

  • Nueva pestaña
  • CTRL+t

  • Siguiente o anterior pestaña
  • CTRL+n

  • Cerrar pestaña
  • CTRL+c

  • Seleccionar todo el texto
  • ggVG

  • Establecer una marca con el nombre ‘a’
  • ma

  • Ir a la marca ‘a’
  • ‘a

  • Ir a la última línea modificada
  • ‘.

Modo Inserción

  • Autocompletar palabra en base al texto ya existente
  • CTRL+N y CTRL+P (p.ej. “hola hCTRL+N” resultado “hola hola”)

  • Indentar
  • CTRL+t

  • Desindentar
  • CTRL+d

Modo Comando

Pulsar [ENTER] después de cada comando

  • Ir a la linea 25
  • :25

  • Salir
  • :q

  • Salir cerrando todos los ficheros abiertos
  • :qa

  • Guardar
  • :w

  • Salir guardando
  • :wq

  • Salir sin guardar
  • :q!

  • Guardar en fichero de solo lectura (sólo root)
  • :w!

  • Guardar con otro nombre
  • :w archivo

  • Editar archivo
  • :e archivo

  • Cerrar archivo
  • :bdelete

  • Navegar a partir de un directorio
  • :e directorio

  • Substituir una cadena de texto A por B (si alguna de estas cadenas contiene caracteres que tengan algun significado especial como por ejemplo ‘/’ se debe anular antes la funcionalidad de este con \, por ejemplo, substituir los ‘/’ por ‘.’ seria :s/\//./)
  • :%s/A/B/ (p.ej. :s/hola/adios)

  • Substituir una cadena de texto A por B en todo el texto
  • :%s/A/B/g

  • Substituir una cadena de texto A por B entre la linea 2 y 10
  • :2,10s/A/B/g

  • Activar la inserción en “modo paste”, esto permite pegar cosas al documento (usando el ratón) de forma que no tabule lo que pegamos, ya que si ese texto ya esta tabulado lo único que hace es pegar desordenando el texto.
  • :set paste

  • Desactivar la inserción en “modo paste”
  • :set nopaste

  • Cortar las líneas que no caben en pantalla.
  • :set wrap

  • No cortar las líneas que no caben en pantalla
  • :set nowrap

  • Dividir pantalla horizontalmente
  • :split

  • Dividir pantalla verticalmente
  • :vsplit

  • Crear nueva pantalla dividida
  • :new

  • Quedarse solo con la ventana actual y ocultar el resto
  • :only

  • Listar todos los ficheros abiertos (buffers)
  • :files ó :buffers

  • Ir al buffer X (los numeros aparecen al hacer un :files o :buffers *en plural*)
  • :file X ó :buffer X

  • Ir al buffer X (pulsar tabulador para autocompletar)
  • :b X

  • Ayuda
  • :help ó :help termino

Modo Visual

Como ya hemos comentado, para acceder a este modo se debe estar en modo normal y pulsar ‘v’. No obstante, si en lugar de ‘v’ pulsamos ‘Ctrl+v’ pasaremos al modo visual en bloque (permite seleccionar un bloque de texto por columnas en lugar de por filas). Y si pulsamos ‘gv’ se repetirá la última selección.

  • Seleccionar texto utilizando h(izquierda), j (arriba), k (abajo) y l (derecha) o con los cursores del teclado.
  • Es posible aplicar las mismas instrucciones vista en el modo comando y modo normal, pero esto solo se realizará sobre el texto seleccionado.
  • Si seleccionamos texto y pasamos a modo comando pulsando ‘:’ se nos mostrar una linea como esta “:’ <,’>”, no debemos borrar estos símbolos ya que es la forma de reconocer vim que estamos aplicando el comando al texto seleccionado.
  • Copiar el texto selecionado
  • y

  • Copiar el texto selecionado en el portapapeles del sistema (teclear el + también)
  • “+y

  • Cortar el texto seleccionado
  • d

  • Pegar el texto copiado o cortado. Debemos estar en modo normal, se pasará automáticamente a ese modo despues de copiar o cortar con ‘y’ o ‘d’.
  • p

  • Pegar el texto desde el portapapeles del sistema (teclear el + también)
  • “+p

  • Indentar
  • >>

  • Indentar
  • <<

  • Modo visual seleccionando columnas en lugar de lineas
  • CTRL+v

  • Insertar texto delante de la columna
  • CTRL+v SHIFT+i ‘texto’ ESC

Corrector ortográfico

Por defecto, vim dispone de corrector para Inglés pero si activamos otros idiomas, el editor nos pregunará si deseamos descargar los correspondientes diccionarios automáticamente.

  • Activar corrector
  • :set spell

  • Desactivar corrector
  • :set nospell

  • Seleccionamos idioma
  • :set spelllang=es
    :set spelllang=ca
    :set spelllang=en
    :set spelllang=fr

Las palabras incorrectas se marcaran en color rojo y podremos interaccionar en modo normal:

  • Siguiente palabra incorrecta
  • ]s

  • Previa palabra incorrecta
  • [s

  • Sugerencias de corrección para una palabra
  • z=

  • Añadir una palabra al diccionario
  • zg

  • Borrar una palabra del diccionario
  • zw

En la página de Vim se puede encontrar más información, incluso scripts que añaden funcionalidades interesantes. Recomendables:

  • MiniBuffExplorer: Añade una barra con el listado de ficheros (buffers) abiertos (F2 para visualizarlo, CTRL+n y CTRL+p para el siguiente/anterior segun establecido en el archivo de configuración de este artículo).
  • TagList: Acceso a funciones/métodos para diversos lenguajes de programación mediante :Tlist (Requiere apt-get install exuberant-ctags) o F4 (segun la configuración indicada en este artículo)
  • NERD Comment: Comentar lineas o bloques de código utilizando ,cc / ,cu / ,c[espacio]
  • NERD Tree: Alternativa al navegador de ficheros :Explore visualizable mediante :NERDTreeToggle o F3/shift-F3
  • PowerLine: Línea de estado con colores e indicaciones configurables.
  • VCScommand: Comandos para controlar el repositorio de control de versiones (Subversion, Git…) desde vim.

Es possible instalar los scripts anteriores mediante:

#### Taglist
sudo apt-get install exuberant-ctags
mkdir ~/.vim
mkdir ~/.vim/plugin
mkdir ~/.vim/doc
rm -f ~/.viminfo
cd ~/.vim
wget -O
rm -f

### Git
wget -O
rm -f 
# It can be used in individual files or in a Explorer for the directory:
# :VCSStatus or \cs 
# :VCSCommit    \cc
# :VCSUpdate    \cu
# :VCSAdd       \ca
# :VCSDelete    \cD
# :VCSAnnotate  \cN
# :VCSVimDiff   \cv
# :VCSLog       \cl

### Nerd Tree
wget -O
rm -f 

### PowerLine
wget -O Lokaltog-vim-powerline-d885f90.tar.gz
tar -zxvf Lokaltog-vim-powerline-d885f90.tar.gz
mv -f Lokaltog-vim-powerline-d885f90/* ~/.vim/
rm -rf Lokaltog-vim-powerline-d885f90 Lokaltog-vim-powerline-d885f90.tar.gz

#### MiniBufExplorer
cd ~/.vim/plugin
#wget -O minibufexpl.vim

#### Comments
wget -O
# ,cc to comment
# ,cu to uncomment
# ,c[space] to toggle

Finalmente, para que cada vez que abramos un fichero en nautilus con gvim lo haga en la misma instancia debemos
crear ‘~/.local/share/applications/gvim-buf.desktop’ con el siguiente contenido:

[Desktop Entry]
Name=GVim (Buffers)
Comment=Edit text files in a new tab
Exec=gvim --remote-silent %F

Y para tener el mismo efecto desde una terminal, editamos ‘~/.bashrc’ y añadimos:

alias gvim='gvim --remote-silent'

2 thoughts on “Vim, guía de referencia rápida

  1. Después del ultimo valor de gvim en .bashrc agregamos %F para que funcione correctamente:
    alias gvim=’gvim –remote-silent %F’

    Buena guía.

Leave a Reply

Your email address will not be published. Required fields are marked *