Como crio automaticamente chaves correspondentes no vim?
Ele deve funcionar da seguinte maneira: Se eu inserir uma chave aberta, a chave de fechamento deve aparecer automaticamente e o cursor deve ser colocado no meio. Para pular para fora do par de chaves, a combinação Ctrl-jé usada.
Existem muitos plugins que fornecem a inserção automática de chaves. Mas eles
- use uma combinação de teclas diferente da que Ctrl-jpular para fora do par de chaves ou
- interferir nas ligações de teclas do UltiSnips .
O seguinte funciona como esperado
:inoremap ( ()<Esc>:let leavechar=")"<CR>i
:imap <C-j> <Esc>:exec "normal f" . leavechar<CR>a
Mas com essas configurações, os trechos do UltiSnips não funcionam mais. Então, usei o UltiSnips para inserir a chave de fechamento:
inoremap ( (<C-R>=UltiSnips_Anon('($1)$0', '(')<CR>
Isso quase funciona. A chave correspondente é inserida e posso pular a chave de fechamento com Ctrl-j. Isso, no entanto, funciona apenas se houver um espaço na frente da chave aberta.
main () // works, the closing parentheses is added
main( // fails without a space
Minhas soluções exigem uma ligação de tecla diferente para pular a chave de fechamento ou exigem um espaço na frente da chave aberta. Como consertar isto?
Nota: usei parênteses como exemplo. Ele deve funcionar com parênteses, chaves, colchetes e sinais de menor que e não interferir no plug-in UltiSnips.
)
, remapearc-j
para isso pode funcionar.Respostas:
Esse problema não é trivial, como você verá. A resposta simples é: Use um plugin, como autoclose ou smartinput . Apenas remapeando ingenuamente (as teclas [.. apresentarão algumas bordas em algumas linhas, é por isso que esses plugins são feitos e por que eles geralmente são bastante complexos (se são bons).
Você pode tentar fazer isso (que é diferente da minha sugestão original):
Onde o UltiSnips dividirá a linha em
(
vez de incluirmain
na partida. O problema com o uso de um plug-in de snippet para isso é que eles (geralmente) não suportam aninhamento; portanto, esquecerão todas as posições de salto quando o próximo snippet (aninhado) for inserido.Você pode remapear Ctrl-jpara o UltiSnips ou o plugin conflitante. Se os mapeamentos não estiverem listados na documentação, você pode usar
:map/imap/nmap <key>
para mostrar o mapeamento. Se você deseja Ctrl-jescolher e executar o trabalho de ambos os plugins, está solicitando:Considere este loop bash:
Nesse caso, você precisará pressionar Ctrl-j5 vezes para chegar ao corpo do loop. Usar as chaves de fechamento para pular para fora de um par correspondente oferece muito mais controle sobre onde você realmente deseja que o cursor se mova. Você pode implementar uma pilha para acompanhar os pares inseridos e usá Ctrl-j-los para mover e mover, mas depois terá problemas se começar a excluir manualmente os aparelhos sem removê-los da pilha. Então você começará a resolver problemas que os plug-ins estão tentando resolver. É uma roda difícil de reinventar.
Expandindo isso, você pode obter o que solicitou inicialmente, usando Ctrl-jpara pular de chaves e trechos. Se você usar algum valor fictício para representar as posições dos trechos e empurrá-los para a pilha, além das chaves de fechamento, com o remapeamento dinâmico de Ctrl-jpara corresponder à entrega de trechos ou chaves. Mas você precisará implementar algumas heurísticas bastante avançadas para descobrir qual mágica deve acontecer, já que você está enfrentando dois problemas ao mesmo tempo, que estão sendo resolvidos pelos criadores dos plug-ins de inserção de trechos e plug-ins de correspondência separadamente, e resolvendo esses problemas novamente, além de suas soluções, para obter comodidade e, bem, mágica.
Tudo se resume ao controle versus conveniência. Eu acho que o controle irá atendê-lo melhor nesse caso, o que significa que você deve manter esses problemas e seus plugins e chaves associados separados. Se você ainda quer conveniência, é factível, mas é difícil.
fonte
Eu acho que delimitMate faz o que você precisa.
Fecha automaticamente parênteses ou aspas e coloca o cursor no meio. Para pular de um par de parênteses (enquanto estiver no modo de inserção), você faria Ctrl-g+, gmas poderá remapear isso Ctrl-jadicionando isso ao seu
vimrc
:fonte
Eu encontrei o fechamento automático adicionando um pouco de atraso e também interferindo na minha configuração (Ultisnips e Supertab), mas eu gosto da abordagem de emular o Eclipse CDT.
Uso delimitMate com os seguintes mapas para ajudar na navegação e no recuo, tentando obter os mesmos resultados:
Eu o uso desta maneira: insira a abertura
{ <CR><CR><C-K>
e comece a escrever na linha interna recuada.fonte
Pessoalmente, eu uso o smartinput para inserção automática de colchetes e aspas. Por exemplo, digitar em
{
qualquer lugar produzirá{}
com o cursor no meio. Para sair do{
grupo de colchetes, basta digitar o}
quando ao lado do inserido}
.No entanto, isso suporta sua exigência de tabstops e saltar para fora do suporte. Ele também não cria um novo entre seus colchetes, mas você só precisa de uma chave extra para isso -
<CR>
.Você pode mapear
<C-J>
para ir para a próxima linha abaixo:ou se você quiser passar para o início da próxima linha:
fonte
Algo como isso pode funcionar para você.
fonte
Na verdade, o Ultisnips pode fazer isso quase perfeitamente (isso pode ser novo). Modificando levemente as respostas dadas acima, tenho um bom sucesso com
inoremap () ()<C-R>=UltiSnips#Anon('($1)$0', '()', 'double parentheses', 'i')<CR>
É preciso digitar
()
quais são as melhores, mas que também podem ser alteradas(
. Em seguida, os argumentos opcionais adicionaisUltiSnips#Anon
são uma descrição e o modificadori
que permite a expansão em palavras.Saltar entre parênteses com
<c-j>
obras, também aninhadas em outros trechos. No entanto, invocar()
parênteses aninhados parece quebrar esse recurso, o que não é grande coisa.fonte