it-swarm.com.de

Bewegen Sie die gesamte Linie in Vim auf und ab

In Notepad ++ kann ich verwenden Ctrl + Shift + Up / Down um die aktuelle Zeile nach oben und unten zu verschieben. Gibt es in Vim einen ähnlichen Befehl? Ich habe endlose Führer durchgesehen, aber nichts gefunden.

Wenn nicht, wie könnte ich die Aktion an diese Tastenkombination binden?

Bearbeiten: Die Antwort von Mykola funktioniert für alle Zeilen, außer für die am Anfang und Ende des Puffers. Wenn Sie die erste Zeile nach oben oder unten verschieben, wird die Zeile gelöscht, und wenn Sie die untere Zeile nach oben verschieben, werden zunächst zwei Felder übersprungen, wie bei einem Bauern! Kann jemand irgendwelche Verfeinerungen anbieten?

295
user4812

Fügen Sie Ihrer .vimrc Folgendes hinzu, um die Arbeit zu erledigen

noremap <c-s-up> :call feedkeys( line('.')==1 ? '' : 'ddkP' )<CR>
noremap <c-s-down> ddp

Das Verschwinden der Linie sieht wie ein Vim-Fehler aus. Ich habe einen Hack gesetzt, um es zu vermeiden. Wahrscheinlich gibt es eine genauere Lösung.

Update

Es gibt viele unerklärliche Schwierigkeiten, wenn Sie nur Vim-Kombinationen verwenden. Dies sind fehlende Linien und zusätzliche Liniensprünge.

Hier ist die Skriptlösung, die entweder in .vimrc oder ~/.vim/plugin/swap_lines.vim platziert werden kann

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>
75
Mykola Golubyev

Wenn ich eine Zeile mit der darüber liegenden Zeile tauschen möchte, mache ich normalerweise Folgendes

ddkP

Erläuterung

  • dd löscht die Zeile und fügt sie dem Standardregister hinzu.
  • k bewegt sich eine Linie nach oben (j würde sich eine Linie hinunter bewegen)
  • P wird über der aktuellen Zeile eingefügt
532
JaredPar

Angenommen, der Cursor befindet sich auf der Linie, die Sie verschieben möchten.

Auf und ab bewegen: :m zum Bewegen

:m +1 - bewegt sich 1 Zeile nach unten

:m -2 - 1 Zeile nach oben schieben

(Beachten Sie, dass Sie +1 durch beliebige Zahlen ersetzen können, je nachdem, um wie viele Zeilen Sie es nach oben oder unten verschieben möchten, dh +2 würde es um 2 Zeilen nach unten verschieben, -3 würde es um 2 Zeilen nach oben verschieben.)

Zu einer bestimmten Zeile wechseln

:set number - Zahlenzeilen anzeigen (besser zu erkennen, wohin Sie sie verschieben)

:m 3 - verschiebe die Zeile nach der 3. Zeile (ersetze 3 in eine beliebige Zeile)

Mehrere Zeilen verschieben:

V (d. H. Shift-V) und bewegen Sie den Cursor nach oben und unten, um mehrere Zeilen in VIM auszuwählen

einmal ausgewählter Treffer : und führe die obigen Befehle aus, m +1 etc

211
Serg

Verschiebe eine Linie nach oben: ddkP

Eine Zeile nach unten verschieben: ddp

70
jacobsimeon

Das hat bei mir funktioniert:

http://vim.wikia.com/wiki/Moving_lines_up_or_down_in_a_file

Übrigens, wenn Sie ALT + some_key verwenden möchten und Ihr Terminal (urxvt verweigert dies), sollten Sie in Ihrer .vimrc Folgendes eingeben:

" 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

dabei ist ^] ein einzelnes Zeichen , das die ALT-Taste darstellt. Verwenden Sie zur Eingabe dieses Zeichens C+v, Esc in Vim (C+q, Esc unter Windows).

15
emil.p.stanchev

fügen Sie der Datei ~/.vimrc Folgendes hinzu (stellen Sie sicher, dass Sie keine Zuordnung für n, m haben)

nmap n :m +1<CR>
nmap m :m -2<CR>

durch Drücken der Taste n wird eine Zeile nach unten verschoben, und m wird eine Zeile nach oben verschoben.

12
Gajendra Jena

Setzen Sie den Cursor im Befehlsmodus auf die Zeile, die Sie nach unten verschieben möchten, und dann

ddp

Erläuterung: Dd löscht die aktuelle Zeile im allgemeinen Puffer P setzt sie NACH der Cursorposition oder bei ganzen Zeilen eine Zeile darunter zurück.

Es gibt einige Verwirrung bezüglich der Befehle p und P in vielen Dokumenten. In Wirklichkeit p Einfügen nach dem Cursor und P AT - Cursor.

11
szg

Fügen Sie diesen Code einfach zu .vimrc (oder .gvimrc) hinzu.

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
6
alexkv

Eine einfache Lösung besteht darin, in Ihren .vimrc die folgenden Zeilen einzufügen:

nmap <C-UP> :m-2<CR>  
nmap <C-DOWN> :m+1<CR>

Genau das, wonach Sie suchen in diesem tollen Plugin: https://github.com/vim-scripts/upAndDown

5
timoxley

Ich füge am Ende meiner .vimrc-Datei Folgendes ein:

noremap H ddkkp
noremap N ddp

Nun bewegen sich 'H' und 'N' die aktuelle Zeile nach oben bzw. unten.

2

Wenn Sie den Befehl :help move in vim drücken, ist das Ergebnis:

:[range]m[ove] {address} *:m* *:mo* *:move* *E134* Move the lines given by [range] to below the line given by {address}.

E.g: Aktuelle Zeile um eine Zeile nach unten verschieben =>:m+1.

E.g: Zeile mit Nummer 100 unter die Zeile mit Nummer 80 verschieben =>:100 m 80.

E.g: Zeile mit Nummer 100 unter die Zeile mit Nummer 200 verschieben =>:100 m 200.

E.g: Verschiebt Zeilen mit einer Nummer innerhalb von [100, 120] unter die Zeile mit der Nummer 200 =>:100,120 m 200.

1
ako

Für mich hat ddkkp es getan (statt ddkP mit einem Großbuchstaben P, was auch funktionieren würde). 

1

Hier ist eine vereinfachte Version für MacVim, die die Wikia-Artikelbeispiele verwendet (siehe Link aus gun s Kommentar).

" 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

Ich verwende nur die Blockauswahlvariante, da zur Auswahl der aktuellen Zeile lediglich Shift-V und für die Auswahl weiterer Zeilen der Cursor aufwärts/abwärts benötigt wird.

Wenn Sie die Tastenkombination Cmd-Shift-Up/Down drücken, wird die Blockauswahl entsprechend den obigen Tastenkombinationen nach oben/unten verschoben. "D" ist die Befehlstaste in MacVim, für Windows versuchen Sie "C" (Control) oder "A" (Alt) (zB <C-A-f> wäre Control Alt f).

Der Wikia-Artikel fügt "= gv" hinzu, wodurch die Einrückung des Blocks nach dem Verschieben basierend auf dem umgebenden Text angepasst wird. Dies ist verwirrend, also habe ich es entfernt und Verknüpfungen hinzugefügt, um die Auswahl stattdessen schnell einzurücken.

" Indent selection left/right (Cmd Shift Left/Right is used for Tab switching)
:vmap <D-A-Left> <gv
:vmap <D-A-Right> >gv

Das Gleiche kann man mit << und >> tun, aber die Auswahl würde verloren gehen. Diese Abkürzungen erlauben also ein mehrfaches Einrücken und Verschieben des Blocks, da die Auswahl beibehalten wird.

Mein MacVim ist so konfiguriert, dass die Tabs mit Cmd-Shift-Left/Right gewechselt werden. Daher habe ich Cmd-Alt-Left/Right verwendet.

Hier ist die Tab-Umschaltung für MacVim (fügen Sie .gvimrc mit dem Rest oben ein):

:macm Window.Select\ Previous\ Tab key=<D-S-Left>
:macm Window.Select\ Next\ Tab key=<D-S-Right>
1
user58777

vim plugin unimpaired.vim [e and] e

0
Baranina

Wenn Sie dies in mehreren Zeilen tun möchten, die einer bestimmten Suche entsprechen:

  • Up: :g/Your query/ normal ddp oder :g/Your query/ m -1
  • :g/Your query/ normal ddp oder :g/Your query/ m +1
0

Hier ist eine Lösung, die auf meiner Maschine funktioniert : MacBook Pro mit VIM 8.1

Diese Befehle werden Ihre Zeilen am oberen oder unteren Rand Ihres Puffers nicht löschen.

Die Verwendung der tatsächlichen Symbole, die von Alt-J und Alt-K ausgegeben werden, ist eine Problemumgehung, da deren Schlüsselcodes in meiner Umgebung nicht ordnungsgemäß zugeordnet werden. 

Werfen Sie das in das alte .vimrc und sehen Sie, ob es für Sie funktioniert.

" 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
0
Nick Sugar

: m. + 1 oder: m.-2 würde das tun, wenn Sie eine einzelne Linie verschieben. Hier ist mein Skript zum Verschieben mehrerer Zeilen. Im visuellen Modus werden die Zeilen, die die visuelle Auswahl enthalten, um eine Zeile nach oben/unten verschoben. Im Einfügemodus oder im Normalmodus wird mit Alt-Auf/Alt-Ab die aktuelle Zeile verschoben, wenn kein Zähler-Präfix angegeben wird. Wenn es einen Count-Präfix gibt, wird Alt-Up/Alt-Ab so viele Zeilen von der aktuellen Zeile aus um eine Zeile nach oben/unten verschoben.

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
0
Ji Han