2013-04-25 9 views
5

Mam funkcję, która przesuwa kursor z wbudowaną funkcją cursor() i działa poprawnie w trybie normalnym.
Dla konkretności przypuszczać, że jest to funkcja:Jak wywołać funkcję, która przesuwa kursor bez opuszczania trybu wizualnego?

function! F() 
    call cursor(line('.')+1, 1) 
endfunction 

używany z odwzorowań jak:

nnoremap <buffer> a :call F()<cr> 

Teraz chcę ponownie użyć tej funkcji, aby przesunąć kursor w dowolnym trybie wizualnym (wizualnej, linii wizualne i blokowe wizualnie) i bez utraty poprzedniej selekcji.

Na przykład, z początkowym buforem w trybie widzenia (c oznacza kursor znajduje się na jednej linii, v oznacza, że ​​linia jest częścią obecnego wyboru wizualnej)

vc 1 
    2 
    3 

uderzenia a da:

v 1 
vc 2 
    3 

i uderzanie a ponownie dałaby:

v 1 
v 2 
vc 3 

, więc stary wybór został zachowany.

Chciałbym ponownie użyć F() tak bardzo, jak to możliwe, ponieważ w mojej aplikacji F() jest dość duży.
Jaki jest najlepszy sposób na zrobienie tego?

Do tej pory najlepsze co mogłem zrobić, to użyć funkcji Wrapper:

function! VisMove(f) 
    normal! gv 
    call function(a:f)() 
endfunction 

i map jak:

vnoremap <buffer> a :call VisMove('F')<cr> 

jednak nie jestem zadowolony, ponieważ w ten sposób:

  1. Wymaga to umieszczenia irytującej otoki na każdym nowym pliku fgplugin, który piszę.
  2. Wywołanie funkcji, która przesuwa kursor (lub ma inne arbitralne efekty uboczne) bez opuszczania trybu wizualnego (bieżącego), wydaje się być tak naturalną rzeczą, którą można zrobić. Istnieje nawet już <expr>, który prawie to robi, ale resetuje pozycję kursora.
+0

Nie mogę myśleć o innym obejście od szczytu głowy; Myślę, że każda mapa wizualna straciłaby swoją wizualną selekcję. – dsummersl

+0

Muszę oprzeć się pokusie, aby wszystkie polecenia w twoim pytaniu były bardziej czytelne. – romainl

+0

W trybie wizualnym kursor znajduje się na początku lub na końcu zaznaczenia, czy próbujesz rozwinąć/wycofać zaznaczenie do dowolnego punktu? – romainl

Odpowiedz

2

rozwiązać ten problem przez przepuszczenie mode argumentu (lub alternatywnie logiczna isVisual flag) do funkcji:

fu! F(mode) range 
    if a:mode ==# 'v' 
     normal! gv 
    endif 
    ... 
endf 
nn <buffer> a :cal F('n')<cr> 
vn <buffer> a :cal F('v')<cr> 
+0

dzięki Ingo, ale myślę, że wolę mój obecny rozwiązanie polegające na dodaniu pojedynczego opakowania dla wszystkich funkcji, zamiast dodawania jednego dodatkowego argumentu i klauzuli "jeśli" do każdej funkcji ruchu. –

Powiązane problemy