11.01. Meu .vimrc

17 minute read Published: 2015-12-22

Essa é a parte em que você vai ver um arquivo de configuração meio estranho.

Como falamos sobre arquivo de configuração, eu vou mostrar o que eu tenho hoje configurado no meu VIM, explicando o que cada comando faz. Boa parte do que eu tenho veio da configuração global do VIM, que eu copiei apenas para garantir que não importando onde eu esteja ou qualquer alteração que seja feita neste arquivo, as funcionalidades que eu estou acostumado continuarão funcionando como esperado.

set encoding=utf-8

Garante que os arquivos salvos estarão em UTF-8, ao invés de tentar converter para o encoding do sistema operacional.

set nocompatible

Desativa o modo de compatilidade com o VI original. Existem algumas diferenças entre ambos (por exemplo, depois de um fazer um undo (u), no VI original fazer undo de novo desfazia o undo anterior (efetivamente, fazendo um "redo") e para continuar fazendo undo, o primeiro comando depois de undo deveria ser .; no VIM, fazer um undo depois de um undo irá continuar desfazendo o que foi entrado no texto, até retornar ao estado original) e a não ser que você seja fã do VI original, eu não recomendaria usar o modo de compatilibidade.

set backspace=indent,eol,start

Apenas garante que o backspace consiga remover identações, apagar o fim da linha e o começo de uma linha (neste último, forçando a linha atual e se juntar com a anterior). Esse é o funcionamento normal de qualquer editor.

" Don’t use Ex mode, use Q for formatting
map Q gq

" Map Y to do the same (well, almost) as the D command
map Y y$

Estes dois mapeamentos eu peguei da configuração global, mas nunca efetivamente usei. Mas, por via das dúvida...

Ainda, uma coisa que eu não havia comentado: Comentários. Você pode comentar qualquer linha começando a mesma com aspas (") sem as aspas finais (senão o VIM irá interpretar o conteúdo como string). Então: Uma aspa, comentário; duas aspas, string; mais de duas, erro.

if &t_Co > 2 ||&
  syntax on
  set hlsearch
endif

Ah, nosso primeiro encontro com ifs. Se o terminal tiver mais de duas cores (&t_Co > 2) ou estivermos rodando em GUI (has("gui_running")) então o suporte à sintaxes deve ser ligado (syntax on) e pesquisas devem marcar todas as ocorrências encontradas no último comando de pesquisa(set hlsearch)1.

" ------------------------
"  Those are my settings
" ------------------------

set tabstop=4           " tabs are displayed as 4 spaces
set shiftwidth=4        " by default, when auto-identing, add 4 spaces (or 1 tabstop)
set foldmethod=marker   " fold on markers
set scrolloff=1         " always show one line around the cursor
set laststatus=2        " always show the status bar (’cause I like to see the line and column, always)
set showtabline=2       " always show the tabline
set showmatch           " show matching bracket
set noerrorbells        " no error bells
set autowrite           " write the file when switching between files or something
set nowrap              " do not wrap long lines
set nobackup            " do not keep a backup file, use versions instead
set history=50          " keep 50 lines of command line history
set ruler               " show the cursor position all the time
set showcmd             " display incomplete commands
set incsearch           " do incremental searching
set formatoptions=tcq   " wrap with textwidth, wrap comments, insert commend leader (twice), format comments
set smartindent         " smart identation
set number              " show line numbers
set wim=longest,list    " file auto-completion
set background=dark     " to follow most of the colorschemes I use
set vb t_vb=            " convert bells to visual bells and do nothing as visual bell

set t_Co=256            " 256 color terminals

let mapleader=","     " use comma to start user-defined (in plugins) functions

Um grande bloco de configurações. Vamos ver um por um:

if has("autocmd")

Eu falei sobre auto-commands, mas na verdade é uma feature que deve ser adicionada na hora de compilar o VIM. Entretanto, até agora eu não vi um pacote disponível que não tenha essa feature. Apenas para garantir, verificamos se a funcionalidade foi adicionada mesmo ou não.

Boa parte do que tem daqui pra frente ou eu já falei ou veio do arquivo de configuração global.

  filetype plugin indent on

Ativa as configurações vindas do arquivo de sintaxe. Quando eu disse que as configurações de auto-identação vem do arquivo de sintaxe, é esta linha que garante que isso vai acontecer.

  autocmd FileType text setlocal textwidth=78

Quando o tipo de arquivo for texto ("text") define localmente para aquele buffer que o tamanho da linha é de 78 colunas. Como "formatoptions" tem um "t", o VIM irá automaticamente quebrar a linha (adicionando um [Enter] antes da palavra que passa do limite) na coluna 78.6

  " When editing a file, always jump to the last known cursor position.
  " Don’t do it when the position is invalid or when inside an event handler
  " (happens when dropping a file on gvim).
  autocmd BufReadPost *
    \ if line("’\"") > 0 && line("’\"") <= line("$") |
    \   exe "normal g`\"" |
    \ endif

Este comando existe no arquivo de configuração global, mas é bem interessante. Lendo exatamente o que ele faz: Depois de carregar qualquer arquivo, se a linha que o marcador de saída do buffer existir e estiver entre o começo do arquivo e antes do fim da linha, executa, em modo normal, g\", que efetivamente "pula" para o marcador de saída do buffer. A diferença entre \`` eg`é que `g não mexe no jumplist quando pular (logo, ```` não vai funcionar). Como não mexer no jumplist é algo que não se faz normalmente, nem comentei antes.

  autocmd FileType python autocmd BufWritePre <buffer> :%s/\s\+$//e

Eu falei deste comando antes, mas vamos de novo: Quando o tipo de arquivo for "python", adicione um auto-comando que antes de gravar o buffer, execute, no buffer, a expressão regular /\s\+$//e, que basicamente, serve para remover espaços em branco no final das linhas.

  " omni completion
  au FileType python setlocal ofu=pythoncomplete#Complete
  au FileType javascript setlocal ofu=javascriptcomplete#CompleteJS
  au FileType html setlocal ofu=htmlcomplete#CompleteTags
  au FileType css setlocal ofu=csscomplete#CompleteCSS
  au FileType xml setlocal ofu=xmlcomplete#CompleteTags
  au FileType php setlocal ofu=phpcomplete#CompletePHP

  set completeopt-=preview

Eu não falei do Omni-complete antes porque até o momento o auto-complete ([Ctrl]p e [Ctrl]n em modo de inserção) tem resolvido todos meus problemas. Mas, em teoria, o omni-complete consegue detectar quais elementos fazem sentido no contexto atual, "encherga" coisas que estão no arquivo de tags e conhece toda a sintaxe da linguagem que você está usando. Mas, realmente, o simples auto-complete já resolve 99% dos problemas que tenho encontrado.

E desliga a apresentação dos resultados do omni-complete na janela de preview, que é semelhante ao quickfix, mas na minha experiência, ela quebra muito o fluxo de edição do código.

Se você quiser tentar, para usar o omni complete basta usar [Ctrl]x seguido de [Ctrl]o.

  " ------------------------
  "  Auto-commands
  " ------------------------

  " default python style
  " (use spaces instead of tabs (expandtab), uses 4 spaces for tabs (tabstop),
  " when auto-indenting, also use 4 spaces (shiftwidth), when deleting text, 4
  " spaces are a tab (softtabstop) and break the line at column 78 (textwidth))
  au FileType python setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 textwidth=78

  " reStructured files follow python closely, but use 3 tab stops instead of 4
  au FileType rst setlocal expandtab tabstop=3 sw=3 sts=3 textwidth=78

  " templates (Jinja2 in this case) will use tabs instead (to reduce file size)
  au FileType htmldjango setlocal noet tabstop=4 shiftwidth=4 softtabstop=4 textwidth=0
  au FileType jinja setlocal noet tabstop=4 shiftwidth=4 softtabstop=4 textwidth=0

  " the smarty filetypes doesn’t have any sort of indentation, so we set it to
  " auto
  au FileType smarty setlocal ai

  " PHP break lines at column 79, like Python
  au FileType php setlocal textwidth=79

  " svn (when editing svn commit messages, break lines at
  " column 70)
  au FileType svn setlocal tw=70

  " email (mostly mutt stuff)
  au FileType mail setlocal spell spelllang=en

  " JavaScript (who though those were "good" defaults?)
  au FileType javascript setlocal expandtab tabstop=2 sw=2 sts=2 textwidth=0

Uma série de auto-comandos baseados no tipo de arquivo. Como eu falei antes neste capítulo, você pode botar vários "set" um atrás do outro separados por espaço e sets tem versões com nomes longos e nomes curtos ("sts" é um atalho para "softtabstop", "sw" para "shiftwidth", "noet" para "noexpandtabs", "ai" para "autoindent" e "tw" para "textwidth"). E sim, eu sei que não manti nenhum padrão no meio, mas pelo menos agora você alguns nomes curtos para algumas opções.

else
  set autoindent                " always set autoindenting on
endif " has("autocmd")

E, se autocmd não estiver disponível, simplesmente seta auto-indent.

" ------------------------
" mapings
" ------------------------

" Easy switching between tabs (just use Alt+<tab number>)
if has(‘mac’)
    map <D-1> :tabn 1<CR>
    map <D-2> :tabn 2<CR>
    map <D-3> :tabn 3<CR>
    map <D-4> :tabn 4<CR>
    map <D-5> :tabn 5<CR>
    map <D-6> :tabn 6<CR>
    map <D-7> :tabn 7<CR>
    map <D-8> :tabn 8<CR>
    map <D-9> :tabn 9<CR>
    map <D-0> :tabn 10<CR>

    imap <D-1> <ESC>:tabn 1<CR>a
    imap <D-2> <ESC>:tabn 2<CR>a
    imap <D-3> <ESC>:tabn 3<CR>a
    imap <D-4> <ESC>:tabn 4<CR>a
    imap <D-5> <ESC>:tabn 5<CR>a
    imap <D-6> <ESC>:tabn 6<CR>a
    imap <D-7> <ESC>:tabn 7<CR>a
    imap <D-8> <ESC>:tabn 8<CR>a
    imap <D-9> <ESC>:tabn 9<CR>a
    imap <D-0> <ESC>:tabn 10<CR>a
else
    map <M-1> :tabn 1<CR>
    map <M-2> :tabn 2<CR>
    map <M-3> :tabn 3<CR>
    map <M-4> :tabn 4<CR>
    map <M-5> :tabn 5<CR>
    map <M-6> :tabn 6<CR>
    map <M-7> :tabn 7<CR>
    map <M-8> :tabn 8<CR>
    map <M-9> :tabn 9<CR>
    map <M-0> :tabn 10<CR>

    imap <M-1> <ESC>:tabn 1<CR>a
    imap <M-2> <ESC>:tabn 2<CR>a
    imap <M-3> <ESC>:tabn 3<CR>a
    imap <M-4> <ESC>:tabn 4<CR>a
    imap <M-5> <ESC>:tabn 5<CR>a
    imap <M-6> <ESC>:tabn 6<CR>a
    imap <M-7> <ESC>:tabn 7<CR>a
    imap <M-8> <ESC>:tabn 8<CR>a
    imap <M-9> <ESC>:tabn 9<CR>a
    imap <M-0> <ESC>:tabn 10<CR>a
endif

Ok, este é um mapeamento que eu sempre achei interessante:

  1. Existe uma diferença entre OS X e outros sistemas que a tecla "Command" é usada para praticamente tudo, inclusive trocar as abas nos browsers; já em outros sistemas, a tecla para isto é "Alt". Um VIM compilado para OS X tem, estranhamente, uma feature chamada "mac"; checando isso você consegue descobrir se está rodando num OS X ou não.

  2. Mapeamentos diferentes para modo normal e de inserção: Se estiver no modo normal, basta usar :tabn {número} para pular diretamente para uma aba (:tabn {número} é a versão de modo de comando do {número}gt do modo normal78); quando estiver em modo de inserção, saida do modo de inserção (simulando pressionar [Esc] com , execute o mesmo comando usado no modo normal para pular para uma aba específica e volte para o modo de inserção ("a").

BOOM! Você acabou de adicionar no VIM uma feature que existe nos browsers.

" custom PHP syntax file configuration
let php_smart_members=1

Essa é uma das coisas que eu falei antes: "let" permite definir variáveis, incluindo algumas dentro do arquivo de sintaxe. No caso "php_smart_members" altera a forma como funções membro de uma classe em PHP seja coloridas de forma diferente.

O resto do meu arquivo de configuração é usado para manter plugins, que eu vou explicar o que cada um faz mais pra frente. Se você quiser ver o arquivo original, ele pode ser encontrado no meu repositório de configurações (que eu uso para manter as configurações sincronizadas entre meu computador pessoal e o computador do trabalho).

1 Apenas para fazer um gancho com o que foi falado anteriormente: No capítulo #2.5, quando estava falando de comandos do modo de comando, eu comentei sobre :noh para desmarcar as ocorrências encontradas no último comando de pesquisa. Bom, hlsearch faz com que estas ocorrências sejam marcadas e se você colocar set nohlsearch, nenhuma ocorrência será marcada e você nunca irá precisar usar :noh.

2 ... ou quando você usar >{movimentação} ou <{movimentação} em modo normal, que eu não havia mencionado antes porque estávamos falando de edição de qualquer texto e não de código fonte. >> irá adicionar um "shiftwidth" para a direita e << irá remover um "shiftwidth" na esquerda.

3 Aqui acabamos de ver duas configurações de flags: Uma ativando uma configuração ("showmatch") e outra desligando ("noerrorbells").

4 Uma pequena nota sobre as posições apresentadas: algumas vezes, você verá o VIM apresentar a coluna como "{número}-{número}". Isso acontece principalmente quando se está usando tabulações ao invés de espaços e o VIM está indicando a contagem de caracteres na esquerda e a coluna de exibição na direita (ou seja, o valor da direita é {quantidade de caracteres menos tabulações} + ({quantidade de tabulações} * {"tabstop"}).

5 E quando digo "quebrar" eu quero dizer "quebrar" mesmo: Enquanto que "wrap" irá cuidar apenas da apresentação do texto, "textwidth" com "formatoptions=t" irá inserir um caractere de nova linha quando a palavra digitada ultrapassar o limite indicado.

9 Note que o VIM define uma variável para isso, mas nada garante que o autor do plugin utilizou essa tecla. Existe um padrão em usar "mapleader" como início de comando normal de um plugin, mas nada obriga o autor do plugin à usar esta tecla.

6 E, recapitulando, para reformatar o parágrafo caso você altere alguma coisa no texto, use gq sobre a região do mesmo. O VIM irá considerar o "textwidth" na hora de reformatar.

7 E não, não são todos os comandos que tem versões tanto em modo normal o quanto em modo de comando.

8 E porque eu usei :tabn {número} ao invés de {número}gt? Porque quando eu pesquisei como pular de abas, este foi o primeiro resultado que eu encontrei.

<< Arquivos de Configuração
 
Meu .gvimrc >>