Mapowanie z ruchem

12

Próbuję zrozumieć, w jaki sposób mogę używać operatora z kolejnym ruchem wewnątrz mapowania. Na przykład:

nmap /c c{here we pending for a motion}/<C-r>"<CR>

Mapa powinna wykonać następujące czynności:

  1. Aktywuj coperatora i nasłuchuj następnego ruchu;
  2. Np. Mogę wpisać tutaj, t,aby zmienić wszystko przed następnym przecinkiem;
  3. Przejdź do trybu wstawiania usuwając wszystko między kursorem a przecinkiem;
  4. Usunięty tekst jest automatycznie przeszukiwany jako wzór

Mówiąc najprościej, po usunięciu tekstu ruchomego pozostaję w trybie wstawiania z wyróżnionymi wystąpieniami usuniętego tekstu. Byłbym bardzo wdzięczny, gdyby ktoś pomógł mi rozwiązać tę sprawę.

AKTUALIZACJA

Odpowiedzi są prawie to, czego chcę. Ale! Kiedy naciskam /cw, wpisz coś zamiast słowa, a następnie naciśnij <Esc>. Po spodziewam się zrobić to samo z następnymi wystąpieniami. Ale po naciśnięciu n(przejdź do następnego wystąpienia) i .(powtórz ostatnie polecenie) po prostu wstawia ostatni wpisany tekst zamiast go zastępować. Głównym celem mapowania jest używanie go n/Ni .powtarzanie. Czy coś przeoczyłem?

Timur Fajzrakhmanov
źródło

Odpowiedzi:

9

vim obsługuje mapowanie operatorów :h map-operator.

Potrzebujesz operatorfuncmapy i mapowania. dla twoich potrzeb działają następujące kody. To tylko przykład, udoskonalasz dalej.

nmap  <silent> /c :set opfunc=SpecialChange<CR>g@
function! SpecialChange(type)
    silent exec 'normal! `[v`]d'    
    silent exec 'let @/=@"' 
    startinsert
endfunction

Pamiętaj, że exec 'let @/=@"'tylko w celu podświetlenia kodów w buforze. Jeśli nie chcesz od razu widzieć podświetlenia, możesz po prostulet @/=@"

Kent
źródło
Zaktualizowałem moje pytanie. Wygląda na to, że twoja odpowiedź jest najbliższa moim potrzebom, ale nie robi tego samego z następnym wystąpieniem, więc wyjaśniłem ten moment w pytaniu.
Timur Fayzrakhmanov
Masz dwóch operatorów ( /ci i) vim po .prostu powtarza ostatni. Jeśli chcesz go rozszerzyć, sprawdź repeatwtyczkę. @TimurFayzrakhmanov również istnieją :gi :spolecenia, mogą ci również pomóc.
Kent
Czy "w twoim kodzie jest coś dziwnego 'let @/=@""'? Myślałem, że jest to możliwe, na przykład silent exec 'normal! [v ]c', ponieważ coperator robi to, czego oczekuję, z wyjątkiem tego, że nie dodaje zmienionego tekstu do wzorca wyszukiwania.
Timur Fayzrakhmanov
1
@TimurFayzrakhmanov to "" była literówka .. poprawka .. Ja też wymyśliłem c, ale dodałem spację, ponieważ jest zmiana trybu n-i-n-i, myślę ... zrób jakiś test, który zobaczysz.
Kent
@TimurFayzrakhmanov można je powtarzalny bez wtyczki zmieniając dsię yi startinsertdo call feedkeys("cgn", 'n')(zobacz moją odpowiedź poniżej)
Jerome Dalbert
4

Łatwiej jest wdrożyć (i udokumentować) złożone mapowania za pomocą funkcji:

function! DoMagic()
   execute "normal! d".input("enter motion: ")
   let @/=@"
   startinsert
endfunction

Następnie wywołaj funkcję mapowania:

nmap /c :call DoMagic()<CR>

Edytować:

Jeśli zamiarem jest, aby wykonać wyszukiwanie i zamienianie w wielu miejscach należy spróbować polecenie zamiany: :s. Możesz zmienić mapowanie, aby skopiować zaznaczenie wizualne do wzorca wyszukiwania:

function! DoMagic2()
   normal! gv"ay
   return @a
endfunction

vmap /c :<c-w>%s/<C-r>=DoMagic2()<CR>//gc<left><left><left>
mMontu
źródło
1
jest to nawet z „ładnym” interfejsem użytkownika, działa na potrzeby OP i może być „więcej” niż oczekiwano, zależy od tego, co wprowadzisz. Np. Kiedy się zobaczy enter motion:, dał: t,ggVGJZZ ^ _ ^ Jest to powszechny problem łączenia poleceń
Kent
To jest prawie to, czego chcę. Np .: Naciskam, /cwa następnie wpisuję coś zamiast słowa, a następnie naciśnij <Esc>. Po tym chcę zrobić to samo z następnymi wystąpieniami. Ale po naciśnięciu n(przejdź do następnego wystąpienia) i .(powtórz ostatnie polecenie) po prostu wstawia ostatni wpisany tekst zamiast go zastępować. Głównym celem mapowania jest używanie go n/Ni .powtarzanie. Czy coś przeoczyłem?
Timur Fayzrakhmanov
1
Ta funkcja ma na celu wyjaśnienie idei używania funkcji w przypadku problemów ze złożonymi mapowaniami. Powinieneś to zmienić, aby zaspokoić swoje potrzeby; spróbuj postępować zgodnie z radą Kenta, aby .powtórzyć polecenie.
mMontu,
Dziękuję za Twoją odpowiedź. Jest to również przydatne, ale akceptuję jeden @Kent, ponieważ wykonuje ruch natychmiast po ich wpisaniu (bez oczekiwania <CR>od input()).
Timur Fayzrakhmanov
1
@TimurFayzrakhmanov możesz również spróbować substytutu, jak wyjaśniono w aktualizacji.
mMontu,
1

To rozwiązanie działa z „powtarzaniem ostatniego polecenia” (alias .):

nmap <silent> /c :set opfunc=ChangeOccurence<CR>g@

function! ChangeOccurence(type)
  exec 'normal! `[v`]y'
  let @/ = @"
  call feedkeys('cgn', 'n')
endfunction

Podczas powtarzania nie musisz nawet używać n, możesz po prostu użyć .bezpośredniego pobierania i zamiany następnego wystąpienia, jeśli chcesz iść szybciej.

Ewentualnie, jeśli chcesz mieć w highlights pasujące słowy, można zastąpić 'cgn'przez 'n``cgn'.

Jerome Dalbert
źródło