sábado, 28 de março de 2009

Deletando um autocomando

Use:

:autocmd! FileWritePre *
Ou seja, o mesmo comando (evento e padrão) sem a parte de 'comando' e com
'autocmd' com '!'.

Padrão de arquivo para autocomandos

O argumento padrão de arquivo pode ser na realidade uma lista de padrões
separados por vírgula.

Por exemplo, '*.c,*.h'. Eis um resumo de wildcards que podem ser usados:
* - Obtém qualquer caracter em qualquer número de vezes
? - Obtém qualquer caracter uma vez.
[abc] - Obtém o caracter a, b or c
. - Obtém um ponto
a{b,c} - Obtém "ab" e "ac"

Quando o padrão inclue um '/', o vim compara os nomes de diretório.
Sem a '/' somente a última parte do nome do arquivo é usada.

Quando usando '/', o vim compara tanto path completo do arquivo como path relativo.
Mesmo no MS-Windows deve-se usar '/' como separador de arquivo nos
autocomandos.

Exemplos de eventos de autocomando

Um dos eventos mais úteis é o BufReadPost.
Ele é disparado quando começando a editar arquivo. Use-o para definir valores nas opções vim.

Por exemplo, voce sabe que arquivos '*.gsm' são arquivos de linguagem assembly
GNU. Assim para obter o arquivo de sintaxe correto, defina este autocomando:

:autocmd BufReadPost *.gsm set filetype=asm

Se o vim é capaz de detectar o tipo de arquivo, ele definirá o 'filetype' para
você.

Isto dispara o evento Filetype. Faça isso quando alguma coisa deve ser feita
quando um certo tipo de arquivo é detectado. Por exemplo, carregar uma lista de
abreviações para arquivos texto:

:autocmd Filetype text source ~/.vim/abbrevs.vim

Quando começando a editar um arquivo novo, voce poderia fazer com que o vim
inserisse um esqueleto:

:autocmd BufNewFile *.[ch] 0read ~/skeletons/skel.c

Formato geral de um autocomando (autocmd)

O formato geral do autocomando é:
:autocmd [grupo] {eventos} {padrão-de-arquivos} [nested] {comando}
O nome do 'grupo' é opcional. Ele é usado para gerenciar e chamar os comandos.
O parâmetro 'eventos' é uma lista de eventos (separados por vírgula) que disparam
o comando.
O 'padrão de arquivos' é um nome de arquivo, normalmente com wildcards. Por
exemplo, '*.txt'.
O flag 'nested' permite o aninhamento de autocomandos.
O 'comando' é o comando a ser executado.

Definindo um autocomando

Um autocomando é um comando que é executado automaticamente em resposta a algum
evento, tais como um arquivo ser lido ou gravado ou um buffer ser mudado.

O formato geral de um autocomando é:
:autocmd grupo eventos padrão-de-arquivo nested comando
Grupo é opcional. É usado para gerenciar e chamar os comandos.
Eventos é uma lista de eventos que disparam o comando.
Padrão-do-arquivo é um nome de arquivo, possivelmente com wildcards.
Nested é uma flag para aninhar autocomandos.
Comando é o comando a ser executado.

Suponha que você quer mudar o timestamp no final do arquivo cada vez que é
gravado.

Primeiro você define uma função:
:function DateInsert()
: $delete
: read !date
:endfunction
Voce quer que essa função seja chamada a cada vez, exatamente antes que um
arquivo é gravado.
Use isso:
:autocmd FileWritePre * call DateInsert()
"FileWritePre" é o evento que irá disparar o autocomando: Exatamente antes (pre)
de gravar o arquivo.

'*' é um padrão para selecionar pelo nome de arquivo. No caso, todos arquivos.

Com esse comando ativo, quando voce fizer um ':write' o vim verifica se há
quaisquer autocomandos 'FileWritePre' correspondentes e executa-os.

Use o autocomando de qualquer arquivo ('*') em primeiro lugar. Depois os
autocomandos por tipo de arquivo ('c,cpp'). Isso permite definir definições
gerais serem sobrepostas pelas definições específicas seguintes.

sexta-feira, 27 de março de 2009

Deletando um comando de usuário

Use:
:delcommand SaveIt

Para deletar todos comandos do usuário:
:comclear
Esta operação não pode ser desfeita !

Redefinindo um comando de usuário

Para redefinir o mesmo comando use o argumento '!':
:command −nargs=+ Say :echo "<args>"
:command! −nargs=+ Say :echo <q−args>

Definindo que o comando do usuário só está disponível no buffer corrente

-buffer

Definindo comando de usuário que permite encadear outro comando

-bar - O comando pode ser seguido por '|' seguido de outro comando ou " e um comentário. Um '|' dentro de um argumento não é permitido.

Definindo o tipo de autocompletar do comando do usuário

Por default, os argumentos do comando do usuário não passam pelo autocompletar.
Todavia usando o atributo '-complete' o autocompletar pode ser ativado.

-complete={tipo} - tipo de autocompletar de linha de comando a ser usado. Veja em :
:h command-complete
a lista de valores disponíveis.

Definindo um comando de usuário que suporte registradores

-register - O comando pode especificar um registrador (o default é o registrador sem-nome). A especificação do registrador fica em <reg> ou <register>.

Definindo comando de usuário com !

-bang - o comando pode usar um !. Se presente, <bang> resultará em um !.
O uso é igual a :w ou :q.

Definindo comando do usuário com contagem

Defina o comando com a opção:
-count={contagem} - o comando pode receber uma contagem cujo valor default é
{contagem}. A palavra-chave <count> receber a contagem.

Definindo comando do usuário com intervalo de linhas

Alguns comandos recebem como argumento um intervalo de linhas.
Use a opção -range. Os valores dessa opção são:
-range - intervalo permitido; o default é a linha corrente.
-range=% - intervalo permitido; o default é o arquivo inteiro.
-range={contagem} - intervalo permitido; uma contagem é especificada na posição
do número de linha. O default é 'contagem'.

Quando um intervalo é especificado, as palavras-chave <line1> e <line2> obtém os
valores da primeira e última linha do intervalo.

O comando abaixo salva um intervalo de linhas para o arquivo 'save_file':
:command −range=% SaveIt :<line1>,<line2>write! save_file

Definindo os argumentos do comando do usuário

Dentro da definição do comando, os argumentos são representados pela
palavra-chave <args>:
:command −nargs=+ Say :echo "<args>"

Quando se digita:
:Say Olá mundo
o vim imprime o texto, contudo se digitar com aspas duplas:
:Say Ele disse "olá"
o vim dá um erro.

Para conseguir imprimir caracteres especiais como string, adequadamente
escapados defina o comando com <q-args>:
:command −nargs=+ Say :echo <q−args>
Agora o comando ':Say' acima resultante será:
:Say "Ele disse \"olá\""

A palavra-chave <f-args> é igual a <args> exceto que ele é voltado para uso em
argumentos de chamada de função:
:command −nargs=* DoIt :call AFunction(<f−args>)
:DoIt a b c

Irá executar a seguinte função:
:call AFunction("a", "b", "c")

Definindo o número de argumentos do comando de usuário

O comando do usuário pode ter uma série de argumentos.
O número deve ser especificado pela opção '-nargs'.

Eis as opções:
−nargs=0 Nenhum argumento
−nargs=1 Um argumento
−nargs=* Qualquer número de argumentos
−nargs=? Zero ou mais argumentos
−nargs=+ Um ou mais argumentos

:command −nargs=0 DeleteFirst 1delete
'-nargs=0' é o default e não precisa ser especificado.

Listando os comandos do usuário

Use:
:command
A primeira coluna mostra:

! - o comando tem o atributo -bang
" - o comando tem o atributo -register
b - o comando é local do buffer corrente.

Criando comandos do usuário

Crie seus próprios que podem ser chamados a partir da linha de comando.
Use:
:command {Comando}{sequencia-de-comandos}
Por exemplo:
:command DeleteFirst 1delete
Os comandos do usuário devem começar com uma letra maiúscula. Não pode ser
usados ":X", ":Next" and ":Print". O underscore não pode ser usado, pode ser
usado dígitos mas isso não é recomendado.

Os comandos do usuário podem ser abreviados na chamada, bastando digitar o suficiente para que sejam distinguidos de um outro comando

O autocompletar da linha de comando pode ser usado para obter o nome completo.

quinta-feira, 26 de março de 2009

Mapeando uma tecla para não fazer nada

Use:
:map <F7> <Nop>| map! <F7> <Nop>
A tecla <F7> não fará nada.

O primeiro mapeamento cobre modos normal, visual e operador-pendente e o segundo cobre o modo inserção e linha de comando.

Não deve existir nenhum espaço depois <Nop>.

Falhando se tentar criar um mapeamento ou abreviação existente

Use
:map <unique> ,w /[#&!]<CR>
ocorrerá um erro se o mapeamento ou abreviação já existe.

Se criando um mapeamento local, será testado se já existe um mapeamento global
idêntico.

Usando mapeamentos locais

:map <script> ...
faz o mapeamento ser local do script. Isso é útil para evitar que mapeamentos do lado de fora do script interfiram, porém ele usará mapeamentos feitos dentro do script.
Como :map <script> e :noremap <script> são iguais neste caso é preferível usar :remap pois é o que ocorre e se torna claro.

:map <buffer> ...
faz o mapeamento ser local do buffer. Os mapeamentos locais de buffer sobrepõe os mapeamentos globais.

Diferenças entre mapeamentos e abreviações

As abreviações são bastante parecidas com mapeamentos em modo inserção. Os
argumentos são tratados do mesmo modo.

A principal diferença é como são disparados. Uma abreviação é disparada
digitando um caracter não de palavra depois da palavra. Um mapeamento é
disparado depois do último caracter.

Outra diferença é que na abreviação os caracteres digitados aparecem no texto.
Quando a abreviação é disparada, eles são deletados e substituídos. Quando o
mapeamento é digitado nada acontece no texto até que o último caracter que
dispara o mapeamento.
Com 'showcmd' os caracteres digitados aparecem no rodapé do vim.

Uma exceção é quando o mapeamento é ambíguo:
:imap aa foo
:imap aaa bar
Quando se digita 'aa', o vim não sabe se trata do primeiro ou o segundo
mapeamento. Ele espera até outro caracter ser digitado, se for 'a' é o segundo
mapeamento, se for um espaço é o primeiro.

Caracteres especiais dentro de um mapeamento

'|'
O comando ':map' pode ser seguido por outro comando. Um caracter '|' separa os
dois comandos.
Isto também significa que o caracter '|' não pode ser usado dentro de um comando
:map.

Para incluir um no mapeamento, use <Bar>:
:map <F8> :write <Bar> !checkin %<CR>

O mesmo problema ocorre com o comando ':unmap', com a questão adicional de espaços no final:
:unmap a | unmap b
:unmap a| unmap b
Esses dois comandos são diferentes, o primeiro tenta desmapear 'a ' que tem um
espaço no final.

<Space>
Quando for usar espaço dentro de um mapeamento, use <Space>:
:map <Space> W
este mapeamento faz com que a barra de espaço mova à direita para uma palavra separada por
brancos.

Não é possível abrir um comentário diretamente após o mapeamento, porque o
caracter '"' seria considerado parte do mapeamento. Voce pode usar '|"', isto
inicia um comando novo e vazio com um comentário:
:map <Space> W| " Use a barra de espaço para mover para uma palavra à direita.

Criando um mapeamento para os modos normal e operador-pendente, mas não para o visual

Use:
:map <C−A> /−−−><CR>
:vunmap <C−A>

Desfazendo mapeamentos

Use:
:unmap ^A
Use para criar mapeamentos para um conjunto limitado de
modos. Por exemplo, definir um comando que existe somente nos modos normal e
visual, mas não no modo operador-pendente:
:map ^A 3w
:ounmap ^A
Há um desmapeamento para cada modo vim:
:unmap  Normal, Visual and Operador-pendente
:vunmap Visual
:nunmap Normal
:ounmap Operator−pendente
:unmap! Inserção and Linha de comando
:iunmap Inserção
:cunmap Linha de comando
Para remover todos mapeamentos use:
:mapclear
com as variações por modo como acima.

Cuidado que ele remove os mapeamentos default e não pode ser desfeito

quarta-feira, 25 de março de 2009

Mapeamento recursivo

Quando o mapeamento dispara a si próprio, ele rodará para sempre. Isto pode ser usado para repetir uma ação ilimitadas vezes.

Por exemplo, voce tem uma lista de arquivo que tem o número de versão na primeira linha. Voce edita os arquivos com 'vim *.txt'.
Agora voce está editando o primeiro arquivo e define o mapeamento:

:map ,, :s/5.1/5.2/<CR>:wnext<CR>,,

Agora voce digita ',,' para disparar o mapeamento:
substitue '5.1' por '5.2'
grava o arquivo e edita o próximo.
e chama ',,', o próprio mapeamento.

Isto dispara o mapeamento de novo com as substituições, etc.

Isto continua até ocorrer um erro.
Pode ser que se um arquivo não tem '5.1' então insere-se '5.1' e digita ',,'
de novo.
Ou pode ser que ':wnext' falha pois estamos no último arquivo da lista.

Quando o mapeamento falha no meio do caminho o resto é descartado.

<Ctrl>C interrompe o mapeamento.

Criando e evitando o remapeamento

O resultado de um mapeamento é inspecionado por outros mapeamentos dentro dele.

Por exemplo:
:map <F2> G<F3> 
:imap <F2> <Esc><F3>
:map <F3> oDate: <Esc>:read !date<CR>kJ
Em modo normal <F2> é mapeado para saltar para a última linha e pressionar <F3>.
Em modo inserção <F2> é mapeado para sair do modo inserção com <Esc> e pressionar <F3>.
Finalmente, <F3> é mapeado para fazer a inserção da data.
Com isso há uma redução do texto a ser mapeado.

Mas esse remapeamento pode causar problemas:
:map Q gq
Mapeie 'Q' para 'gq' para que formate texto.
:map gQ Q
Mapeie 'gQ' para 'Q' para que entre em modo Ex como 'Q' original faz.

O que acontece agora é que se digitar 'gQ' ele será mapeado para 'Q' que por sua
vez será mapeado para 'gq'. Ou seja ao invés de entrar em modo Ex ele formata
texto.

Para evitar esse remapeamento use ':noremap':
:noremap gQ Q
agora o vim sabe que 'Q' não deve ser inspecionado para remapeamentos.

Isso é muitas vezes usado para redefinir um comando.

Não-remapeamentos e modos do vim:
:noremap  Normal, Visual e Operador-pendente
:vnoremap Visual
:nnoremap Normal
:onoremap Operador-pendente
:noremap! Inserção e Linha de comando
:inoremap Inserção
:cnoremap Linha de comando

Iniciando vim em modo inserção

O vim inicia em modo normal.

Se quiser inicia-lo em modo inserção entre:
vim -c start
o comando ':start' mudará para o modo inserção logo de cara.

Eis um script bash que pode ser chamado:
#!/bin/bash
exec /usr/local/bin/gvim -c start

Script para converter caracteres especiais para entidades HTML

Certos caracteres como '<','>','&' são reservados no HTML. Se usados no texto, o
browser pode interpreta-los erroneamente como tags.

Coloque no .vimrc, recarregue e a função abaixo e o mapeamento '\e' irá converte-los para entidades HTML que são
convertidas para texto pelo browser.
"Escape de entidades html
function! HtmlEscape()
silent s/&/\&amp;/eg
silent s/</\&lt;/eg
silent s/>/\&gt;/eg
endfunction

map <silent> \e :call HtmlEscape()<CR>


Selecione visualmente o texto e chame o mapeamento.

terça-feira, 24 de março de 2009

Mapeamento para deletar ou copiar um bloco C no modo operador-pendente

O modo operador-pendente é quando se digita um operador, tal como 'd' e 'y' e o
vim espera por um comando de movimento ou um objeto-texto.

Suponha que voce quer definir <F7> para que d<F7> delete um bloco de um programa
C (texto dentro de {}). De maneira similar, y<F7> deverá copiar um bloco para o
registrador sem-nome.

Portanto, <F7> deverá selecionar o bloco assim:
:omap <F7> a{

<F7> seleciona o bloco, no modo operador-pendente. Este mapeamento é útil se
digitar '{' é um pouco difícil em seu teclado.

Definindo uma mapeamento para um modo específico

O comando
:map 
define mapeamentos para o modo normal, visual e operador-pendente.

Para o modo inserção use:
:imap
Exemplo:
:imap <F2> <CR>Date: <Esc>:read !date<CR>kJ
Eis os comandos e os modos que operam:
:map - normal, visual, operador-pendente
:vmap- visual
:nmap- normal
:omap- operador-pendente
:map!- inserção e linha de comando
:imap- inserção
:cmap- linha de comando

O modo operador-pendente é quando um comando como 'd' fica esperando um comando
de movimento.

Exemplos.
Copiar a seleção visual para o registrador 'v':
:map <F5> “vy
Isto mapeia <F5> para os modos normal, visual e operador-pendente. No entanto,
você quer que o mapeamento seja válido somente no modo visual:
:vmap <F5> “vy
Agora suponha que você quer <F7> para que um comando como d<F7> delete um bloco
de um programa C (texto entre chaves, {}). De maneira similar, y<F7> iria copiar
o bloco para o registrador sem-nome.
Portanto, <F7> deveria selecionar o bloco corrente do programa:
:omap <F7> a{
Isto fará <F7> selecionar um bloco (a{) no modo operador-pendente.

Mapeamento para inserir a data do sistema no fim do arquivo

:map <F2> GoDate: <Esc>:read !date<CR>kJ
F2 - a tecla mapeada

G - vai para o fim do arquivo
o - abre uma nova linha embaixo.
Date: - texto
<Esc> - sai do modo inserção.
:read !date - executa o comando 'date' e insere o stdout na linha abaixo.
kJ - desce para a linha e junta com a linha acima (Date: ).

Date: Ter Mar 24 17:23:43 BRT 2009

Voltando e retornando no tempo da árvore de undo

Com base no comando ':undolist' e os ramos com hora listados pode-se voltar no tempo:
:earlier 10s
volta 10 segundos

:earlier 10h
volta 10 horas

:later 1m
retorna 1 minuto

segunda-feira, 23 de março de 2009

Vendo a árvore de undo

Depois de uma série de mudanças a árvore de undo pode se tornar grande. Para ver os ramos existentes use:
:undolist

Ele mostra os ramos que existem no momento na árvore de undo:
o número do ramo
o número de mudanças feitas no ramo até a raíz da árvore.
a hora que a mudança foi feita.

Desfazendo/refazendo a mudança cronologicamente

Se quiser voltar uma mudança no tempo e não seguindo linha de undo use:
-g
para voltar no tempo para uma mudança
+g
para avançar no tempo para refazer uma mudança

Esses comandos são úteis se não se sabe qual número do ramo de undo que se
deseja.

Desfazendo um ramo de mudança específico

Para acessar um ramo de undo específico use o comando:
:undo 2
o comando 'undo n' pula para ramo de undo.

'undo n' é útil se sabe qual o número do ramo a ser saltado. Use ':undolist' para ver os ramos correntes.

Criando novos ramos de undo

O vim segue uma linha de undo/redo sucessivos para desfazer/refazer mudanças no arquivo:
a -> mudança1 -> b -> mudança2 -> c

Agora desfaça (undo) uma mudança e faça uma nova.
As mudanças desfeitas se tornam um ramo:
'u'-> b -> mudança3 -> d

Os comandos 'u' e ctrl-r percorrem somente o último ramo de undo criado. O ramo anterior não é considerado pelos comandos.

O arquivo de startup do gvim

Quando o gvim inicia, ele procura por um arquivo .gvimrc.
Ele é similar ao .vimrc. Ele pode ser usado para definições e comandos que aplicam somente quando usando a versão gráfica do vim.

Por exemplo, usando a opção 'lines' para uma janela: :set lines=55 como isto não funciona em um terminal (o
tamanho é fixo) colocamos no .gvimrc.

O arquivo é procurado nos mesmos locais do arquivo vimrc, normalmente ~/.gvimrc.
A variável $MYGVIMRC recebe o local do gvimrc e pode ser usada assim:
:e $MYGVIMRC

Se não quiser usar o arquivo .gvimrc normal, inicie o vim assim:
gvim -U arquivo

Isto permite iniciar o gvim com diferentes tipos de edição. Voce poderia definir um outro tipo de fonte por
exemplo.

Para não usar nenhum arquivo de inicialização:
gvim -U NONE

Mudando o vim para gvim

Se voce iniciou o vim no terminal e decide usar o modo gráfico use:
:gui
O vim abrirá a versão gráfica e não usará mais o terminal.

Se quiser mudar para o gvim mas bloqueando terminal (rodar como processo-filho) use:
:gui -f

Iniciando o vim como um processo filho do shell.

Se voce iniciar o gvim a partir do shell, ele inicia como um novo processo, disconectado do shell. O terminal fica livre para outras coisas.

Em certos, como usar o vim como editor de mensagens do programa de e-mail, isso não funciona pois ao disconectar do shell o e-mail pensa que o vim acabou de editar a mensagem.

O vim ser lançado como um processo-filho do shell nesse caso. Use:
gvim -f file.txt
-f diz ao vim para bloquear o shell até que o programa termine.

Posição e tamanho da janela do vim no startup

Para ambiente gráfico X-windows somente.

Use argumentos de linha de comando:
gvim -geometry {largura}x{altura}+{deslocamento_x}+{deslocamento_y}

largura e altura em caracteres e deslocamentos em pixels.

gvim −geometry 80x25+100+300

Posição e tamanho da janela do vim em caracteres

Use:
:set lines columns

O tamanho da janela depende do tamanho do fonte.

Pode ser alterado:
:set lines=50
:set columns=80

Posição e tamanho da janela do vim em pixels.

Para ver a posição corrente da janela do vim na tela use:
:winpos
retorna:
'Posição da janela: X 292, Y 25', valores em pixels.

Agora pode mover a janela do vim:
:winpos 172 103

Há uma pequena defasagem por causa da borda da janela, que é controlada pelo gerenciador de janelas do sistema.

Voce pode especificar esse comando no script de startup para posicionar a janela em local específico.

Pedindo uma confirmação antes de regravar um arquivo

Se tentar gravar sobre um arquivo existente, o vim dá um erro e sugere anexar '!' ao comando.
Voce evitar de digitar o comando usando o comando ':confirm' :
:confirm w main.c

Um diálogo aparece dando escolha de regravar ou cancelar.

O comando 'confirm' pode ser combinado com qualque comando que editam outros arquivos:
:confirme browse edit
aparecerá o diálogo de confirmação se o buffer foi mudado. Após a resposta, o browser aparece.

O comando 'confirm' também funciona com o vim em modo texto.

Opção para definir qual diretório usar com o explorador de arquivos

Use:
:set browsedir
default 'last'.
last - usa o mesmo diretório usando anteriormente.
buffer - usa o diretório do buffer relacionado.
current - usa o diretório corrente.
{path} - usa o diretório especificado.

Abrindo um arquivo em outra janela pelo browser de arquivos.

Use:
:browse split

Irá abrir um browser em modo gráfico.
Nele voce seleciona o arquivo e ele é aberto em uma nova janela.

:browse split ~/Imagens
diz ao browser a partir de que diretório deverá listar.
Se não for informado um diretório, o browser usa o diretório anterior. Isso pode ser modificado pela opção 'browsedir'.

O comando ':browse' pode ser seguido por qualquer comando que abra um arquivo.

domingo, 22 de março de 2009

Opção para definir o que é um comentário

O vim sabe distinguir o comentário em uma linha.
O comentário é composto de 3 partes: tem um início, meio e fim.

Muitos comentários de uma linha começam com um caractere específico. Em C++ '//', nos Makefiles '#', nos scripts vim '"'.

Use a opção:
:set comments=flags
O formato geral da opção é :
{flags}:{texto}
aonde ':' é um separador de flags. Os flags podem ser omitidos.

Por exemplo, para o vim identificar um comentário C++:
:set comments=://
Esses itens podem ser concatenados com ',' permitindo reconhecer diferentes tipos de comentários ao mesmo tempo.

Por exemplo, um citação de um e-mail anterior é precedida por '>' e '!'.
Este comando iria identifica-lo:
:set comments=n:>,n:!
Existem 2 itens. Um para comentários começando com '>' e outro começando com '!'.
Ambos usam flags 'n'.
Isto significa que os comentários aninham. Assim um comentário começando com '>' pode ter outro comentário apos '>':

> ! Did you see that site? ~
> ! It looks really great. ~
> I don't like it. The ~
> colors are terrible. ~
What is the URL of that ~
site? ~
Com um 'textwidth' diferente (80 por exemplo) e formatando com 'gq' resulta em :

> ! Did you see that site? It looks really great. ~
> I don't like it. The colors are terrible. ~
What is the URL of that site? ~
O vim não mistura um tipo de comentário com outro (> com !).

Um comentário C é um exemplo de comentário de 3 partes: começa com '/*', tem no meio '*' e '*/' no final.
A opção fica:
:set comments=s1:/*,mb:*,ex:*/
O início é definido com 's1:/*'.
's' indica o início de comentário de 3 partes.
o flag '1' indica que a parte do meio tem um deslocamente de 1 espaço
'/*' é o texto que se reconhece o início do comentário.

A parte do meio é 'mb:*'.
'm' indica que é a parte do meio.
o flag 'b' indica que um branco deve seguir o texto. Caso contrário o vim iria considerar texto como '*pointer' como meio de comentário.
'*' é o texto do meio do comentário.

A parte final é 'ex:*/'.
'e' indica que é a parte final.
o flag 'x' significa que depois que o vim inseriu um asterisco automaticamente, ao digitar '/' removerá o espaço extra.

Para mais detalhes:
:h format-comments

Opção para formatar a inserção de linhas em comentários C

A opção
:set formatoptions
deve ter as seguintes flags:
r - insere um asterisco quando pressiona <enter> no modo inserção.
o - insere um asterisco quando usando 'o' ou 'O' no modo normal.
c - quebra o texto do comentário quando excede 'textwidth'.
Se posicionar no meio de um comentário e digitar o comando 'o', o vim automaticamente insere '*' e um espaço.
Se o comentário exceder o 'textwidth', o vim quebrará a linha com um '*' inserido novamente.

Formatando comentários C

Posicione o cursor no início do comentário e use o comando:
gq]/
'gq' é um operando.
']/' é um comando de movimento de saltar para o fim do comentário.

Ou selecione visualmente o texto a ser formatado e use 'gq'.