2012-06-13 11 views
9

Czy można ponownie użyć zakresu poleceń EX w VIM?Ponowne użycie poprzedniego zakresu w poleceniach ex w VIM

Jako przykład można napisać (kopia) wiersze 4 do 10 z moim obecnym pliku do nowego pliku za pomocą następującego polecenia:

:4,10w foo/bar.txt 

ale to, co naprawdę chcesz zrobić, to przenieść linie do nowy plik. Mogę to zrobić tak:

:4,10w foo/bar.txt 
:4,10d 

Ale to trochę denerwujące, gdy trzeba wpisać 4,10 razy.

Mam więc dwa pytania:

  1. Ogólnie, Czy istnieje sposób, aby odwołać się do wcześniej używanego w zakres ex poleceń?
  2. W szczególności, jeśli nie ma sposobu, aby zrobić (1), istnieje łatwiejszy sposób na wycięcie i wklejenie kilku linii z jednego pliku do nowego.

Odpowiedz

1

Ogólnie rzecz biorąc, usuwam linie z jednego pliku, przełączam się do innego pliku i wklejam.

Również generalnie używam znaków. Zamiast wpisywać rzeczywiste liczby, uderzam mb, aby zaznaczyć linię początkową, a następnie przechodzę do linii końcowej i uderzam d'b, aby usunąć z powrotem do linii oznaczonej jako b. Ale można użyć mb oznaczyć linię rozpoczęcia i me aby zaznaczyć linię końcową, a następnie uruchomić komendę: ex

:'b,'e w somefile.txt<Enter> 

Oczywiście można użyć dowolnej litery z a przez z dla swoich znaków; Zwykle używam b i e, ale możesz używać tego, co lubisz.

Jak bym przenieść linie:

m'b 
<navigate to end line> 
d'b 
:n somefile.txt<Enter> 
p 
Ctrl+^ 

Ctrl +^przełączniki z obecnego otwartego pliku do poprzedniego otwartego pliku. (Możesz też po prostu otworzyć panel i przełączyć panele, jeśli wolisz, panele nie działają w zwykłym vi, ale działają w vim.)

Powyższe zakłada, że ​​ustawiono opcję autowrite. Z autowrite, komenda :n i Ctrl +^po prostu zapisują bieżący plik, a następnie przełączają pliki, zamiast narzekać, że plik został zmieniony bez zapisywania go. Możesz także wykonać powyższe czynności i po prostu jawnie zapisać plik przed użyciem :n lub Ctrl + ^.

Nawiasem mówiąc, używam Ctrl +^tak bardzo, że zmapowałem to na K. Łatwiejsze do wpisania, ale mam ten zwyczaj dawno temu, kiedy musiałem czasami używać niemego terminalu, który nie mógł wpisać Ctrl + ^.

Przy okazji, po usunięciu linii, przechodzą one do "bufora bez nazwy". W vim, nienazwany bufor jest zachowywany po przełączeniu plików. W oryginalnym vi, nienazwany bufor jest wyczyszczony. Tak więc powyższe nie będzie działać ze starym vi. Możesz sprawić, żeby działało, usuwając do nazwanego bufora, a następnie wklejając go z nazwanego bufora; który działa w dowolnej wersji vi.

m'b 
<navigate to end line> 
"ad'b 
:n somefile.txt<Enter> 
"ap 
Ctrl+^ 

Powyższy usuwa w buforze o nazwie a, a następnie wkleja z a w drugim pliku. Działa to oczywiście w vimie; po prostu tego nie potrzebujesz.

4

Nie jestem świadomy odpowiedzi na (1), ale aby odpowiedzieć (2), istnieje wiele różnych sposobów robienia tego, które nie wymagają ponownego wyboru linii ręcznie. W trybie wizualnym to będzie działać:

4GV10G 
:w foo/bar.txt 
gvd 

ponieważ GV dokonuje ponownego wyboru poprzedni wybór, który jest niemal co chcesz, bez użycia zakres ex.

Ale można po prostu włączyć ten problem na głowie, i spróbuj:

:4,10d 
:sp foo/bar.txt 
pZZ 

wyciąć, a następnie wkleić do nowego pliku, a następnie zamknij ją.

0

Możesz najpierw usunąć, a następnie otworzyć nową kartę i wkleić zawartość - tak :4,10d, a następnie :tabe foo/bar.txt, a następnie p ... czy to brzmi lepiej?

3

Inny niż przy użyciu historię Vima (:kursor w górę, q:) i usuwając poprzednie polecenie tak, że tylko zakres jest utrzymany, nie ma sposobu, aby ponownie wykorzystać ostatni zakres, nie zmienną magiczne.

Gdybym użył tego linie ruch kombinację częściej, chciałbym napisać niestandardowe polecenie do niego:

command! -bang -range -nargs=1 -complete=file MoveWrite <line1>,<line2>write<bang> <args> | <line1>,<line2>delete _ 

trzeba określić zakres i zapisać tylko raz pisać.

Możesz napisać coś takiego również dla innych kombinacji. Głównym wyzwaniem jest określenie wszystkich atrybutów polecenia (huk, zakres, zakończenie), a później zapamiętywanie niestandardowej nazwy polecenia.

2

Oto mapowanie w wierszu polecenia, które to umożliwia. Związałem go z CTRL-G CTRL-U, ponieważ wykonuje podobną akcję jak CTRL-U. (Ale można to zmienić, oczywiście!)

" c_CTRL-G_CTRL-U Remove all characters between the cursor position and 
"   the closest previous |:range| given to a command. When 
"   directly after a range, remove it. 
"   Useful to repeat a recalled command line with the same 
"   range, but a different command. 
let s:singleRangeExpr = '\%(\d\+\|[.$%]\|''\S\|\\[/?&]\|/[^/]*/\|?[^?]*?\)\%([+-]\d*\)\?' 
let s:rangeExpr = s:singleRangeExpr.'\%([,;]'.s:singleRangeExpr.'\)\?' 
let s:upToRangeExpr = '^\%(.*\\\@<!|\)\?\s*' . s:rangeExpr . '\ze\s*\h' 
" Note: I didn't take over the handling of command prefixes (:verbose, :silent, 
" etc.) to avoid making this overly complex. 
function! s:RemoveAllButRange() 
    let l:cmdlineBeforeCursor = strpart(getcmdline(), 0, getcmdpos() - 1) 
    let l:cmdlineAfterCursor = strpart(getcmdline(), getcmdpos() - 1) 

    let l:upToRange = matchstr(l:cmdlineBeforeCursor, s:upToRangeExpr) 
    if empty(l:upToRange) 
     return getcmdline() 
    else 
     call setcmdpos(strlen(l:upToRange) + 1) 
     return l:upToRange . l:cmdlineAfterCursor 
    endif 
endfunction 
cnoremap <C-g><C-u> <C-\>e(<SID>RemoveAllButRange())<CR> 
1

Można też zrobić coś takiego napisać zawartość anonimowego rejestru do file2.txt

:4,10d | :call writefile(split(@@, "\n", 1), 'file2.txt') 
5

Zwykle używam kota zrobić to:

:4,10!cat > foo/bar.txt 

Działa to, ponieważ przepuszczasz linie przez kota i zastępujesz je wynikowym wynikiem, który jest niczym. Oczywiście można dołączyć do końca istniejącego pliku, wykonując >> zamiast>.

+0

To interesujący sposób, aby sobie z tym poradzić! Niby elegancko. – steveha