Vim'de tüm satırı yukarı ve aşağı taşı


311

Notepad ++ uygulamasında Ctrl+Shift ile geçerli satırı yukarı ve aşağı taşımak için + Up/ tuşlarınıDown . Vim'de buna benzer bir komut var mı? Sonsuz rehberlere baktım ama hiçbir şey bulamadım.

Yoksa, işlemi bu tuş kombinasyonuna nasıl bağlayabilirim?

Düzenleme: Mykola'nın yanıtı, arabellek başında ve sonunda olanlar dışında tüm satırlar için çalışır. İlk satırı yukarı veya alt satırı aşağı taşımak satırı siler ve alt satırı yukarı hareket ettirirken piyon gibi başlangıçta iki boşluk atlar! Herkes herhangi bir ayrıntılandırma sunabilir mi?


Komut dosyası çözümü uygulamaktan başka seçeneğim yoktu. Umarım ihtiyaçlarınız için temiz ve kabul edilebilirdir.
Mykola Golubyev

31
Geleceğin çocukları için: vim.wikia.com/wiki/Moving_lines_up_or_down
silahlar

Neden bir senaryoya ihtiyacınız olduğundan emin değilim, Wikia makalesi örnekleri işe yarıyor. Basitleştirilmiş bir versiyonun altında yayınladım, çünkü Wikia'nın 3 farklı haritalama moduyla örneği oldukça göz korkutucu olabilir (ve gerçekten gerekli değildir. Sadece blok seçim eşlemelerini kullanırsanız, seçmeyi (Vardiya V) ve kullanmayı engellemeyi hatırlayabilirsiniz. bu kısayollar (aşağıdaki

Konu hakkında screencast: vimcasts.org/e/26
glts

Ayrıca vi SE
cfi

Yanıtlar:


81

İşi yapmak için aşağıdakileri .vimrc'nize koyun

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

Hattın kaybolması bir Vim hatası gibi görünüyor. Bundan kaçınmak için bir kesmek koydum. Muhtemelen daha doğru bir çözüm var.

Güncelleme

Sadece Vim kombinasyonlarını kullanırken açıklanamayan birçok zorluk var. Bunlar çizgi eksik ve ekstra çizgi atlama.

İşte .vimrc veya ~ / .vim / plugin / swap_lines.vim içine yerleştirilebilen komut dosyası çözümü

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>

1
Orada benim kurulum ile bir çatışma gibi görünüyor, ama fantastik cevap <cj> ve <ck> değiştirmek zorunda kaldı! Teşekkürler çok
user4812 12:09

1
Teşekkürler, git rebase için harika - interaktif. <cj> ve <ck> 'a bağlanmak zorunda kaldı. cs-up / down işe yaramadı.
Lari Hotari

2
Birisi farklı bir kısayol istiyorsa: c kontrol içindir, A alt içindir, <A-up>tutulmada kullanılan gibi kullanıyorum.
Ocak

1
Kaybolan hat bir Vim hatası değil! Bunun nedeni ddkP, belgenin son satırında gerçekleştirilmesidir . 3 satırlı bir dosyada kendiniz deneyin. Bu tür problemlerden kaçınmak :miçin Vim wiki'de verilen çok daha kolay eşlemeleri kullanın .
Serge Stroobandt

1
Son satırları olarak değiştirdim <A-up>ve tmux'da<A-down> görsel olarak vim'de bu tuşları denediğimde seçim kayboluyor ve imleç satır yukarı hareket ediyor; seçili çizgileri hareket ettirmeden.
Konrad

574

Bir çizgiyi yukarıdaki çizgiyle değiştirmek istersem genellikle aşağıdakileri yaparım

ddkP

açıklama

  • dd satırı siler ve varsayılan kayıt defterine ekler.
  • k bir satır yukarı hareket eder (j bir satır aşağı hareket eder)
  • P, geçerli satırın üstüne yapışır

5
Ve her zaman da mevcuttur. :-)
Henno

71
Ve ddpbir satırı aşağı taşımak için (satırı silin ve geçerli satırın altına yapıştırın)
bcoughlan

2
Satır demetini 4 ddtaşımak için 4 deyin ve sonra 2 satır deyin, sonra :2yapıştırmak istediğiniz yere gidin ve P.
Guru

2
@Guru 4ddbunun yerine olmalı 4 ddmı?
Patrick McDonald

3
Ve dd<number>jpmevcut satırı <sayı> +1 satır aşağı taşımak için. Ve dd<number>kpyukarı hatlarının geçerli satırı <sayı> hareket etmek.
egelev

230

İmlecin taşımak istediğiniz satırda olduğunu varsayarsak.

Yukarı ve aşağı hareket: :m hareket etme hareket için

:m +1 - 1 satır aşağı gider

:m -2 - 1 satır yukarı git

(Kaç satır yukarı veya aşağı taşımak istediğinize bağlı olarak + 1'i herhangi bir sayı ile değiştirebileceğinizi unutmayın, yani +2 2 satır aşağı, -3 2 satır yukarı taşıyacaktır)

Belirli bir satıra geçmek için

:set number - sayı satırlarını görüntüleme (nereye taşıdığınızı görmek daha kolay)

:m 3 - 3. satırdan sonra satırı taşıyın (3'ü istediğiniz herhangi bir satırla değiştirin)

Birden çok satırı taşıma:

V(yani Shift- V) ve VIM'de birden çok satır seçmek için kurser'i yukarı ve aşağı hareket ettir

seçildikten sonra :yukarıdaki komutlara basın ve çalıştırın, m +1vb.


14
benim için: m -2 sadece bir satır yukarı çıkar.
Hermann Ingjaldsson

2
Bu yöntemi benim vimrc koymak ama sonra '.' kullanarak komutu tekrar edemezsiniz. bunun neden olduğunu bilen var mı?
Hermann Ingjaldsson

Çok hoş! Notepad ++ içindeki çözüm kadar rahat değil, ama yine de - gerçek ve çalışıyor.
Arturas M

Hermann, Üzgünüm, yazım hatası / benim açımdan, haklısın,: m -2 onu bir satır yukarı taşıyacak. Ben değiştirdim. Ayrıca çok geç cevap için üzgünüm (.vimrc bölümü hakkında emin değilim) Şerefe
Serg

2
Komutu kullanarak hareket etmek, OP'nin istediği gibi Notepad ++ gibi ciltlerde kullanmak istiyorsanız, aşağıdakileri .vimrc'ye girmeniz gerekir:noremap <c-s-up> :m -2<CR> noremap <c-s-down> :m +1<CR>
kap

74

Bir satırı yukarı taşıma: ddkP

Bir satırı aşağı taşı: ddp


1
vimrc'de buna sahip olmak komutu '.'
Hermann Ingjaldsson

@HermannIngjaldsson, sanırım .tekrarlamak için kullanmak isterseniz komutu bir işlevde sarabilirsiniz .
jacobsimeon

Yess, .. ve daha fazla satır taşımanız gerekiyorsa, dd yerine V kullanabilirsiniz.
sensorario

15

Bu benim için çalıştı:

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

BTW, ALT + some_key kullanmak istiyorsanız ve terminaliniz (urxvt bunu yapar) uymayı reddederse, .vimrc'nize böyle bir şey girmelisiniz:

" 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

burada ^], ALT tuşunu temsil eden tek bir karakterdir . Bu karakteri C+v, Escgirmek için Vim'de ( C+q, EscWindows'ta) kullanın.


1
Bu, Vim'in bir satırı hareket ettirmek için yerleşik komutunu kullanarak iyidir. Geri alma veya bir hata karşısında iyi davranma olasılığı daha yüksektir.
Josh Lee

1
Neden Esc <kbd>Cv<kbd/> <kbd> Esc </kbd> (linux) olarak girmiyorsunuz. Windows, <kbd> Cv <kbd /> yerine <kbd> Cq <kbd />
yazıyor

@sehe: Teşekkürler, o zaman bunu bilmiyordum. Cevabı güncelledim.
emil.p.stanchev

1
@RafaelRinaldi, [niv]noremapnormal | insert | görsel modlar için hatırlatmalardır . <CR>olduğu Carriage Return( Enteranahtar).
vp_arth

1
@vp_arth Hayır yok
sehe

13

~ / .vimrc dosyasına aşağıdakini ekleyin (n, m için eşlemeniz olmadığından emin olun)

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

şimdi tuşuna basıldığında nbir satır aşağı ve mbir satır yukarı hareket eder.


12

Komut modunda, imleci aşağı taşımak istediğiniz satıra getirin ve ardından

ddp

Açıklama: dd geçerli satırı genel arabelleğe siler, imleç konumundan SONRA veya tüm satırlar durumunda bir satır aşağıya geri koyar.

Birçok dokümanda p ve P komutlarıyla ilgili bazı karışıklıklar vardır. Gerçekte p imleç SONRASI ve P AT imleci yapıştırır.


8

Bu kodu .vimrc (veya .gvimrc) 'ye eklemeniz yeterlidir.

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

1
Vim.wikia.com/wiki/… uyarınca kapsamlı bir açıklama için oraya bakın.
Serge Stroobandt

Mac'te <A- bir şey> çalışmıyor, nedenini bilmiyorum. <Cj> <Ck> ile değiştirdim ve Ctrl tuşunu kullanarak iyi çalışıyor.
Cédric NICOLAS



3

Aşağıdaki .vimrc dosyamın sonuna koydum:

noremap H ddkkp
noremap N ddp

Şimdi 'H' ve 'N' mevcut satırı sırasıyla yukarı ve aşağı hareket ettiriyor.


H ve N aslında kullanışlı komutlardır (H imleci ekranın üstüne ve başına taşır, N önceki arama sonucuna gider), bu yüzden farklı tuşlar kullanmanızı öneririm
villapx

Anlıyorum. Onları da yeniden yapılandırdım. Ekranın en üstüne gitmek için a ve ardından yukarı tuşlarına basarım. Kitaplarımda her zaman her şey yolunda. Önceki sonuçları aramak için önce f sonra sol tuşuna basarım. F sonra bulmak anlamına gelir. Ama böyle olmayanlar için o zaman evet .. geçerli.
Hermann Ingjaldsson

1

İşte Wikia makalesi örneklerini ( silahın yorumundan cf. bağlantısı) kullanarak MacVim için basitleştirilmiş bir sürüm .

" 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

Sadece blok seçimi varyantını kullanıyorum, çünkü tüm gereken mevcut satırı seçmek için Shift-V ve isteğe bağlı olarak yukarı / aşağı birkaç satır seçmek için imleç.

Yukarıdaki kısayollara göre, Cmd-ÜstKrkt-Yukarı / Aşağı tuşlarına basmak blok seçimini yukarı / aşağı kaydırır. "D", MacVim'deki Komut anahtarıdır, Windows için "C" (Kontrol) veya "A" (Alt) komutlarını deneyin (örn. <CAf>, Kontrol Alt f olacaktır).

Wikia makalesi, bunlara "= gv" ekliyor; bu, hareketten sonra çevreleyen metne göre blokun girintisini ayarlama etkisine sahip. Bu kafa karıştırıcı, bu yüzden onu kaldırdım ve bunun yerine seçimi hızla girintilemek için kısayollar ekledim.

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

Aynı şey << ve >> için de yapılabilir, ancak seçim kaybolacaktır, bu nedenle yukarıdaki bu kısayollar birden çok kez girintili olmasına ve seçimi korunduğu için bloğu hareket ettirmeye izin verir.

MacVim'im Cmd-Alt-Sol / Sağ kullandığım için Sekmeleri Cmd-Shift-Sol / Sağ ile değiştirecek şekilde yapılandırıldı.

İşte MacVim için Sekme anahtarlama (yukarıdaki geri kalanıyla .gvimrc yazın):

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

1

vim eklentisi unimpaired.vim [e ve] e


2
Bu aşırıya kaçmış gibi görünüyor, bunun için tam bir eklentiye gerçekten ihtiyacınız olduğunu sanmıyorum. Bir vimrc'de 2 satır OP'nin tam olarak ne istediğini yapar
Daniel Gratzer

1

Eğer komutu çarptığında :help moveiçinde vim, burada sonucudur:

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

Örneğin: Geçerli satırı bir satır aşağı taşı => :m+1 .

Örn: 100 numaralı satırı 80 => numaralı satırın altına taşıyın :100 m 80 .

Örn: 100 numaralı satırı 200 => numaralı satırın altına taşıyın :100 m 200 .

Örn: [100, 120] içinde numaralı satırları 200 => satırının altına taşıyın :100,120 m 200 .


1

İşte makinemde çalışan bir çözüm : VIM 8.1 çalıştıran MacBook Pro

Bu komutlar ara belleğinizin üstündeki veya altındaki satırlarınızı silmez.

Alt-J ve Alt-K çıkışlarının gerçek sembollerini kullanmak, anahtar kodlarının ortamımda düzgün eşlenmemeleri için bir çözümdür.

Bunu eski .vimrc'ye atın ve sizin için işe yarayıp yaramadığına bakın.

" 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

: m. + 1 veya: m.-2 tek bir satırı hareket ettirirseniz yapardı. Birden çok satırı hareket ettirmek için komut dosyam. Görsel modda, Alt-up / Alt-down görsel seçimi içeren satırları bir satır yukarı / aşağı hareket ettirir. Ekleme modunda veya normal modda, Sayma öneki verilmezse Alt-yukarı / Alt-aşağı geçerli satırı hareket ettirir. Bir sayım öneki varsa, Alt-up / Alt-down geçerli satırdan başlayarak birçok satırı bir satır yukarı / aşağı hareket ettirir.

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

Bunu belirli bir aramayla eşleşen birden çok satırda yapmak istiyorsanız:

  • Yukarı: :g/Your query/ normal ddpveya:g/Your query/ m -1
  • Aşağı :g/Your query/ normal ddpveya:g/Your query/ m +1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.