Dans Notepad ++, je peux utiliser Ctrl + Shift + Up / Down pour déplacer la ligne actuelle de haut en bas. Existe-t-il une commande similaire à celle-ci dans Vim? J'ai parcouru d'innombrables guides, mais je n'ai rien trouvé.
S'il n'y en a pas, comment pourrais-je lier l'action à cette combinaison de touches?
Edit: La réponse de Mykola fonctionne pour toutes les lignes, à l'exception de celles situées au début et à la fin du tampon. Déplacer la première ligne vers le haut ou la ligne inférieure vers le bas supprime la ligne. Lorsque vous déplacez la ligne inférieure, elle saute initialement de deux espaces, comme un pion! Quelqu'un peut-il offrir des améliorations?
Mettez ce qui suit à votre .vimrc pour faire le travail
noremap <c-s-up> :call feedkeys( line('.')==1 ? '' : 'ddkP' )<CR>
noremap <c-s-down> ddp
La disparition de la ligne ressemble à un bogue de Vim. Je mets un bidouillage pour l'éviter. Il existe probablement une solution plus précise.
Mettre à jour
Il y a beaucoup de difficultés inexpliquées à utiliser simplement les combinaisons Vim. Ce sont des lignes manquantes et des sauts de ligne supplémentaires.
Voici donc la solution de script qui peut être placée dans .vimrc ou ~/.vim/plugin/swap_lines.vim
function! s:swap_lines(n1, n2)
let line1 = getline(a:n1)
let line2 = getline(a:n2)
call setline(a:n1, line2)
call setline(a:n2, line1)
endfunction
function! s:swap_up()
let n = line('.')
if n == 1
return
endif
call s:swap_lines(n, n - 1)
exec n - 1
endfunction
function! s:swap_down()
let n = line('.')
if n == line('$')
return
endif
call s:swap_lines(n, n + 1)
exec n + 1
endfunction
noremap <silent> <c-s-up> :call <SID>swap_up()<CR>
noremap <silent> <c-s-down> :call <SID>swap_down()<CR>
Si je veux échanger une ligne avec la ligne ci-dessus, je fais habituellement ce qui suit
ddkP
Explication
En supposant que le curseur se trouve sur la ligne que vous souhaitez déplacer.
Déplacement de haut en bas: :m
pour le déplacement
:m +1
- se déplace vers le bas d'une ligne
:m -2
- augmente de 1 ligne
(Notez que vous pouvez remplacer +1 par n'importe quel nombre en fonction du nombre de lignes que vous souhaitez déplacer vers le haut ou le bas, c.-à-d. +2 le déplacerait de 2 lignes, -3 le ferait de 2 lignes.)
Pour passer à une ligne spécifique
:set number
- Affiche les lignes numériques (il est plus facile de voir où vous le déplacez)
:m 3
- déplace la ligne après la 3ème ligne (remplacez 3 par la ligne de votre choix)
Déplacement de plusieurs lignes:
V
(i.e. Shift-V) et déplacez-vous de haut en bas pour sélectionner plusieurs lignes dans VIM
une fois sélectionné hit : et lancez les commandes ci-dessus, m +1
etc
Déplacer une ligne: ddkP
Déplacer une ligne vers le bas: ddp
Cela a fonctionné pour moi:
http://vim.wikia.com/wiki/Moving_lines_up_or_down_in_a_file
En passant, si vous voulez utiliser ALT + some_key et que votre terminal (ce que urxvt fait) refuse de se conformer, vous devez entrer quelque chose comme ceci dans votre fichier .vimrc:
" For moving lines (^] is a special character; use <M-k> and <M-j> if it works)
nnoremap ^]k mz:m-2<CR>`z==
inoremap ^]j <Esc>:m+<CR>==gi
inoremap ^]k <Esc>:m-2<CR>==gi
vnoremap ^]j :m'>+<CR>gv=`<my`>mzgv`yo`z
nnoremap ^]j mz:m+<CR>`z==
vnoremap ^]k :m'<-2<CR>gv=`>my`<mzgv`yo`z
où ^] est un seul caractère qui représente la touche ALT. Pour saisir ce caractère, utilisez C+v, Esc à Vim (C+q, Esc sous Windows).
ajoutez ce qui suit au fichier ~/.vimrc (assurez-vous de ne pas avoir de mappage pour n, m)
nmap n :m +1<CR>
nmap m :m -2<CR>
appuyez maintenant sur la touche n
pour déplacer une ligne vers le bas et m
pour déplacer une ligne vers le haut.
En mode commande, positionnez le curseur sur la ligne que vous souhaitez déplacer, puis
ddp
Explication: Dd supprime la ligne en cours dans le tampon général P la remet APRÈS la position du curseur ou, dans le cas de lignes complètes, une ligne en dessous.
Il existe une certaine confusion concernant les commandes p et P dans de nombreux documents . En réalité, p colle APRES le curseur et le curseur P AT.
Ajoutez simplement ce code à .vimrc (ou .gvimrc)
nnoremap <A-j> :m+<CR>==
nnoremap <A-k> :m-2<CR>==
inoremap <A-j> <Esc>:m+<CR>==gi
inoremap <A-k> <Esc>:m-2<CR>==gi
vnoremap <A-j> :m'>+<CR>gv=gv
vnoremap <A-k> :m-2<CR>gv=gv
Une solution simple est de mettre dans votre .vimrc
ces lignes:
nmap <C-UP> :m-2<CR>
nmap <C-DOWN> :m+1<CR>
Exactement ce que vous cherchez dans cet impressionnant plugin: https://github.com/vim-scripts/upAndDown
Je mets ce qui suit à la fin de mon fichier .vimrc:
noremap H ddkkp
noremap N ddp
Alors maintenant, "H" et "N" déplacent la ligne actuelle de haut en bas, respectivement.
Lorsque vous appuyez sur la commande :help move
dans vim
, voici le résultat:
:[range]m[ove] {address} *:m* *:mo* *:move* *E134*
Move the lines given by [range] to below the line
given by {address}.
E.g: Déplace la ligne en cours d’une ligne vers le bas =>:m+1
.
E.g: Déplace la ligne avec le numéro 100 en dessous de la ligne avec le numéro 80 =>:100 m 80
.
E.g: Déplace la ligne avec le numéro 100 en dessous de la ligne avec le numéro 200 =>:100 m 200
.
E.g: Déplace les lignes dont le nombre est compris entre [100, 120] sous la ligne portant le nombre 200 =>:100,120 m 200
.
Pour moi, ddkkp
l’a fait (au lieu de ddkP
avec un P majuscule, ce qui fonctionnerait aussi).
Voici une version simplifiée, pour MacVim, utilisant les exemples d’articles de Wikia (cf. lien depuis le commentaire de gun).
" Move selection up/down (add =gv to reindent after move)
:vmap <D-S-Up> :m-2<CR>gv
:vmap <D-S-Down> :m'>+<CR>gv
J'utilise uniquement la variante de sélection de bloc, car il suffit de déplacer Shift-V pour sélectionner la ligne en cours, et éventuellement un curseur haut/bas pour sélectionner d'autres lignes.
Selon les raccourcis ci-dessus, une pression sur Cmd-Shift-Up/Down décale la sélection de bloc vers le haut ou le bas. "D" est la touche de commande de MacVim, pour Windows, essayez "C" (Contrôle) ou "A" (Alt) (par exemple, <C-A-f> correspondrait à Contrôle Alt f).
L'article de Wikia ajoute "= gv" à ceux-ci, ce qui a pour effet d'ajuster l'indentation du bloc après le déplacement, en fonction du texte environnant. C'est déroutant, alors je l'ai supprimé et ajouté des raccourcis pour indenter rapidement la sélection.
" Indent selection left/right (Cmd Shift Left/Right is used for Tab switching)
:vmap <D-A-Left> <gv
:vmap <D-A-Right> >gv
Bien sûr, on peut faire la même chose avec << et >>, mais la sélection serait perdue. Ces raccourcis permettent de mettre en retrait plusieurs fois tout en déplaçant le bloc car la sélection est conservée.
Mon MacVim est configuré pour permuter les onglets avec Cmd-Shift-Left/Right. J'ai donc utilisé Cmd-Alt-Left/Right.
Voici le changement d'onglet pour MacVim (mis en .gvimrc avec le reste ci-dessus):
:macm Window.Select\ Previous\ Tab key=<D-S-Left>
:macm Window.Select\ Next\ Tab key=<D-S-Right>
vim plugin unimpaired.vim [e et] e
Si vous souhaitez le faire sur plusieurs lignes correspondant à une recherche spécifique:
:g/Your query/ normal ddp
ou :g/Your query/ m -1
:g/Your query/ normal ddp
ou :g/Your query/ m +1
en panneVoici une solution qui fonctionne sur ma machine : MacBook Pro sous VIM 8.1
Ces commandes ne supprimeront pas vos lignes en haut ou en bas de votre tampon.
L'utilisation des symboles réels générés par les sorties Alt-J et Alt-K constitue une solution de contournement car les codes-clés ne sont pas correctement mappés dans mon environnement.
Jetez ceci dans l'ancien .vimrc et voyez si cela fonctionne pour vous.
" Maps Alt-J and Alt-K to macros for moving lines up and down
" Works for modes: Normal, Insert and Visual
nnoremap ∆ :m .+1<CR>==
nnoremap ˚ :m .-2<CR>==
inoremap ∆ <Esc>:m .+1<CR>==gi
inoremap ˚ <Esc>:m .-2<CR>==gi
vnoremap ∆ :m '>+1<CR>gv=gv
vnoremap ˚ :m '<-2<CR>gv=gv
: m + 1 ou: m.-2 suffiraient si vous ne déplacez qu'une seule ligne. Voici mon script pour déplacer plusieurs lignes. En mode visuel, Alt-haut/Alt-bas déplace les lignes contenant la sélection visuelle vers le haut/bas d'une ligne. En mode insertion ou en mode normal, Alt-up/Alt-down déplace la ligne en cours si aucun préfixe de comptage n'est indiqué. S'il y a un préfixe de nombre, Alt-up/Alt-down déplace ce nombre de lignes à partir de la ligne actuelle haut/bas d'une ligne.
function! MoveLines(offset) range
let l:col = virtcol('.')
let l:offset = str2nr(a:offset)
exe 'silent! :' . a:firstline . ',' . a:lastline . 'm'
\ . (l:offset > 0 ? a:lastline + l:offset : a:firstline + l:offset)
exe 'normal ' . l:col . '|'
endf
imap <silent> <M-up> <C-O>:call MoveLines('-2')<CR>
imap <silent> <M-down> <C-O>:call MoveLines('+1')<CR>
nmap <silent> <M-up> :call MoveLines('-2')<CR>
nmap <silent> <M-down> :call MoveLines('+1')<CR>
vmap <silent> <M-up> :call MoveLines('-2')<CR>gv
vmap <silent> <M-down> :call MoveLines('+1')<CR>gv