web-dev-qa-db-fra.com

Passez automatiquement une récompense dans Vim

Je passe comme trop de temps à tâtonner car Vim ne gère pas les accolades fermantes comme le font la plupart des IDE. Voici ce que je veux arriver:

Tapez ceci:

if( whatever )
{ <CR>

et obtenez ceci:

if( whatever )
{
  |  
}

<CR> signifie frappé le ENTER key et | est la position du curseur. C'est ce que fait Eclipse. C'est ce que fait Visual Studio. Et c'est ce que je veux que Vim fasse.

J'ai vu quelques plugins, essayé quelques-uns, et aucun ne semble me donner ce comportement. Je ne peux sûrement pas être le premier programmeur à vouloir cela.

62
Bob

Dans VimL, ​​vous pouvez mapper le { à faire exactement comme vous le souhaitez:

inoremap { {<CR>}<Esc>ko

en fonction de la configuration de votre autoindent, vous pouvez ajouter un <BS> après le <CR>.

Pour une solution plus complète, je vous suggérerais de regarder les plugins vim de Luc Hermitte . Ils ne m'ont jamais manqué jusqu'à présent.

30
Michael Foukarakis

Pour placer les parenthèses fermantes sur une nouvelle ligne et le curseur sur la ligne entre les deux parenthèses, suivez la suggestion du premier commentaire dans l'article intitulé Faciliter la gestion des parenthèses et des crochets.

16
Derek Mahar

Utiliser AutoClose avec ce qui suit fonctionne correctement.

inoremap {<CR> {<CR>}<C-o>O

Ceci est vrai au moins pour mon système (terminal Unix sous Mac OS X).

9
dmonopoly

Voici ce que j'ai dans mon vimrc:

let s:pairs={
            \'<': '>',
            \'{': '}',
            \'[': ']',
            \'(': ')',
            \'«': '»',
            \'„': '“',
            \'“': '”',
            \'‘': '’',
        \}
call map(copy(s:pairs), 'extend(s:pairs, {v:val : v:key}, "keep")')
function! InsertPair(left, ...)
    let rlist=reverse(map(split(a:left, '\zs'), 'get(s:pairs, v:val, v:val)'))
    let opts=get(a:000, 0, {})
    let start   = get(opts, 'start',   '')
    let lmiddle = get(opts, 'lmiddle', '')
    let rmiddle = get(opts, 'rmiddle', '')
    let end     = get(opts, 'end',     '')
    let prefix  = get(opts, 'prefix',  '')
    let start.=prefix
    let rmiddle.=prefix
    let left=start.a:left.lmiddle
    let right=rmiddle.join(rlist, '').end
    let moves=repeat("\<Left>", len(split(right, '\zs')))
    return left.right.moves
endfunction
 noremap! <expr> ,f   InsertPair('{')
 noremap! <expr> ,h   InsertPair('[')
 noremap! <expr> ,s   InsertPair('(')
 noremap! <expr> ,u   InsertPair('<')

Et pour certains types de fichiers:

inoremap {<CR> {<C-o>o}<C-o>O

// Je sais que la fonction InsertPair est simple, mais elle permet de gagner du temps, car je peux définir les mappages des commandes et des modes normaux avec une seule commande sans avoir à écrire beaucoup de <Left>s.

4
ZyX

Pour tous ceux qui rencontrent ce problème comme moi, et qui recherchaient quelque chose de plus récent que AutoClose: delimitMate j’ai trouvé que ce n’était pas seulement une solution préférable à AutoClose, en ce qui concerne le comportement, mais également en développement actif. Selon vim.org , AutoClose n’a pas été mis à jour depuis 2009.

3
Eric H

Mettez ce qui suit dans votre fichier .vimrc:

inoremap { {}<ESC>ha

Chaque fois que vous appuyez sur { en mode insertion, {} est généré et place votre curseur sur l'accolade droite pour que vous puissiez commencer à taper directement entre eux. En mettant les accolades en séquence plutôt que sur des lignes différentes, vous pouvez placer les onglets devant } manuellement. De cette façon, vous n'avez jamais le mauvais nombre d'onglets devant.

Quelqu'un peut peut-être comprendre comment compter le nombre de tabulations sur lequel se trouve le curseur, puis générer un nombre égal de tabulations devant le } sur une nouvelle ligne.

2
user1534664

delimitMate a un paramètre pour cela.

2
Henrik N

Comme vous le verrez dans la astuce wikia : il existe de nombreuses solutions à cette question récurrente (j'ai même mine ). 

C'est-à-dire si vous vous limitez à des paires de crochets. Vous êtes ici dans le contexte d’une instruction de contrôle. Il est donc plus probable que vous trouviez des systèmes de fragments qui ne vous attendez pas à taper le ") {" lorsque vous tapez une instruction "if". Le raccourci Vim a tendance à être plus court que ce que j'ai lu dans votre question. Là encore, il y a beaucoup de choix, vous trouverez très probablement snipmate, et peut-être ma suite C & C++ .

2
Luc Hermitte

J'ai essayé différents plugins mais j'ai trouvé le plus précis et le plus facile à utiliser auto-paires . C'est vraiment intuitif et lorsque vous l'installez, vous obtenez ce que vous attendez de la boîte.

2
egelev

J'ai toujours préféré quelque chose comme ce que fait le texte sublime quand il ajoute l'accolade de fermeture comme prochain caractère. J'ai donc ajouté ce qui suit à mon .vimrc:

inoremap (  ()<ESC>hli

qui déplace le curseur entre les deux accolades.

1
Aneesh Durg

Juste une note à @Bob.

La fonction AutoClose de Karl Guertin a une fonction nommée `` double accolade '', c’est-à-dire que vous pouvez taper accolade deux fois, comme ci-dessous.

int func_name(void) {{ ==> Type `{' twice here.

aboutirait à:

int func_name(void) {
| ==> Cursor here.
}

Ensuite, vous pouvez taper un onglet single pour le mettre en retrait en fonction de votre paramètre `shiftwidth ', puis tapez.

1
jtuki

Installez et utilisez le script Vim AutoClose comme recommandé dans l'article intitulé Ajoutez automatiquement les caractères de fermeture .

1
Derek Mahar

Une solution pour les accolades, les parenthèses et les parenthèses.

" Automatically closing braces
inoremap {<CR> {<CR>}<Esc>ko<tab>
inoremap [<CR> [<CR>]<Esc>ko<tab>
inoremap (<CR> (<CR>)<Esc>ko<tab>

Résultat:

function() {
  |
}
1
Rodrigo Pedroso

Le correctif Vim 7.4.849 a ajouté une liaison pour permettre le déplacement du curseur sans relancer la séquence d'annulation. Une fois mis à jour à> = 7.4.849, quelque chose comme cela fonctionne très bien.

inoremap ( ()<C-G>U<Left>

Notez que j’ai tiré cela directement de la documentation incluse dans le correctif. Meilleure solution simple pour cette fonctionnalité pour le moment.

1
John Eikenberry

Ma solution:

inoremap <expr> <CR> InsertMapForEnter()
function! InsertMapForEnter()
    if pumvisible()
        return "\<C-y>"
    elseif strcharpart(getline('.'),getpos('.')[2]-1,1) == '}'
        return "\<CR>\<Esc>O"
    elseif strcharpart(getline('.'),getpos('.')[2]-1,2) == '</'
        return "\<CR>\<Esc>O"
    else
        return "\<CR>"
    endif
endfunction

Explication:

Le code ci-dessus vérifie d’abord si vous utilisez Enter pour confirmer la complétion du code, sinon, il indenterait le {|} lorsque vous tapez Enter. En outre, il fournit des balises html à retrait automatique.

Exemples:

if( whatever ){|}

appuyez sur Enter et vous obtiendrez

if( whatever )
{
  |  
}

Cela fonctionne également pour le fichier html. Voir l'exemple suivant

<html>|<html>

appuyez sur Enter et vous obtiendrez

<html>
    |
</html>
0
Yun Zhi
inoremap ( ()<ESC>i
inoremap " ""<ESC>i
inoremap ' ''<ESC>i
inoremap { {<Cr>}<Esc>O
0
alvy

Vous n'avez pas besoin d'un plugin spécial pour le faire, mais c'est un processus en deux étapes. 

Tout d’abord, ajoutez ce qui suit à votre .vimrc pour manger le caractère qui déclenche:

" eat characters after abbreviation
function! Eatchar(pat)
    let c = nr2char(getchar(0))
    return (c =~ a:pat) ? '' : c
endfunction

puis ajoutez cette abréviation à votre .vimrc

inoreabbr <silent> { {
      \<cr><space><space>
      \<cr><esc>0i}<esc>k$i<c-r>=Eatchar('\m\s\<bar>\r')<cr>

Le \ au début des lignes deux et trois est juste un caractère de continuation de ligne. Cependant, vous auriez pu le faire sur une seule ligne et je l'ai ajouté pour pouvoir diffuser l'abréviation de manière à refléter le résultat recherché - pour que les choses soient un peu plus intuitives. 

0
ricardo