J'ai souvent des commandes à exécuter lorsque je développe, comme par exemple :
#php symfony phpunit:unit path/to/test/file.php
Jusqu'à récemment, j'avais ajouté la ligne suivante à mon .vimrc pour ne pas avoir à sortir de VIM pour exécuter ce type de commande :
nnoremap <F12> :!php symfony phpunit:unit % 2>&1 \| more<CR>
Ainsi, en appuyant sur la touche F12
de mon clavier, je déclenchais l'exécution du fichier de tests en cours d'édition.
Cette solution fonctionne, mais à quelques inconvénients induit par le fait que le résultat de la commande n'est pas affiché dans une fenêtre de VIM :
- Il n'est pas possible de conserver ou éditer les résultats de la commande.
- Si plusieurs tests ne passent pas, la sortie de la commande peut être très longue.
Bref, à l'usage, ce n'est pas le plus pratique.
La solution consiste donc à injecter le résultat de la commande dans un buffer
afin de l'avoir dans une fenêtre et ainsi disposer de l'ensemble des commandes de VIM pour le manipuler.
Sur la base de cette astuce, j'ai donc ajouté à mon .vimrc
le code suivant :
let s:_ = ''
function! s:ExecuteInShell(command, bang)
let _ = a:bang != '' ? s:_ : a:command == '' ? '' : join(map(split(a:command), 'expand(v:val)'))
if (_ != '')
let s:_ = _
let bufnr = bufnr('%')
let winnr = bufwinnr('^' . _ . '$')
silent! execute winnr < 0 ? 'new ' . fnameescape(_) : winnr . 'wincmd w'
setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap number
silent! :%d
let message = 'Execute ' . _ . '...'
call append(0, message)
echo message
silent! redraw
silent! execute 'silent! %!'. _
silent! execute 'resize ' . line('$')
silent! execute 'au BufUnload <buffer> execute bufwinnr(' . bufnr . ') . ''wincmd w'''
silent! execute 'nnoremap <silent> <buffer> <LocalLeader>r :call <SID>ExecuteInShell(''' . _ . ''', '''')<CR>'
silent! execute 'nnoremap <silent> <buffer> <LocalLeader>g :execute bufwinnr(' . bufnr . ') . ''wincmd w''<CR>'
endif
endfunction
command! -complete=shellcmd -nargs=* -bang Shell call s:ExecuteInShell(<q-args>, '<bang>')
La commande suivante me permet donc maintenant d'exécuter la commande de mon choix et d'en obtenir le résultat dans une fenêtre :
:Shell php symfony phpunit:unit %
Cerise sur le gâteau, s'il existe déjà une fenêtre de résultat pour cette commande, elle sera réutilisée, afin de ne pas multiplier inutilement les fenêtres de résultat.
Et enfin, il est possible d'exécuter à nouveau la commande à partir de la fenêtre de résultat en tapant <localleader>r
en mode normal, ou bien à l'aide de la commande :Shell!
.
Et comme le code évolue rapidement, à tel point que je suis en train de me dire qu'en faire une extension serait intéressant, je vous conseille d'aller consulter mon .vimrc
.
4 réactions
1 De Ivan Enderlin - 23/12/2010, 14:07
Hey :-),
Ce que je fais très souvent, c'est endormir Vim : Ctrl + Z. Puis : fg (dans le terminal), pour le réveiller (le remettre en avant-plan). On contrôle le processus de Vim directement, c'est plus rigolo. C'est peut-être une solution alternative intéressante.
2 De mageekguy - 23/12/2010, 14:13
@Ivan Enderlin : Sauf que tu n'as pas la sortie de ta commande dans un buffer de VIM, qui est justement ce que je veux.
3 De Renaud - 23/12/2010, 19:36
J'ai voulu testé ton vimrc, j'ai donc créé un ~/.vimrc (puisque je n'en ai pas du tout) et copié/collé l'intégralité de ton .vimrc et patatra:
Erreur détectée en traitant /home/marmotz/.vimrc :
ligne 65 :
E185: Impossible de trouver le jeu de couleurs lucius
Je me doutais bien que tout ne fonctionnerait pas
Pourrais-tu expliquer un chouya ?
4 De mageekguy - 23/12/2010, 20:23
@Renaud : mon .vimrc dépend d'autre fichier présent dans mon répertoire .vim.
En l'occurrence, lucius est un thème que j'affectionne particulièrement.
Il te suffit de supprimer la ligne en question pour ne plus avoir de problème.