Ruch kursora po $ motion

Aug 22 2020

Gram w świetną grę o nazwie VIM Adventures (z której są poniższe obrazki). Pytanie pochodzi z gry, ale można je również odtworzyć w VIM, więc o to pytam.

Załóżmy, że jesteś w normal modeśrodku, stojąc na jakiejś linii ni kolumnie m. Jeśli naciśniesz klawisz j, twoja pozycja stanie się wierszem n+1i tą samą kolumną m. Jeśli linia n+1ma mniej kolumn niż m, powiedzmy o, znajdujesz się w kolumnie o. Ponownie naciśnij j. Zostaniesz przeniesiony do wiersza n+2, kolumny m(to samo sprawdzenie co poprzednio). Widzisz, kolumna, w której zacząłeś m, jest zapamiętana. Można to zobaczyć na pierwszym zdjęciu, z czerwonymi liniami przedstawiającymi jruch.

Jeśli jednak jesteś w normal modeśrodku i naciśniesz klawisz $, zostaniesz przeniesiony na koniec bieżącej linii. Rozważmy teraz tę samą sekwencję ruchów, jaką opisano w poprzednim akapicie. Każdy ruch jprzeniesie Cię do ostatniego znaku w tej linii. mnie jest pamiętany w tym przypadku. Można to zobaczyć na drugim zdjęciu. Pierwsze naciśnięcie $powoduje umieszczenie kursora na końcu pierwszej linii. Następnie, naciskając wiele jruchów, każdy ląduje kursorem na końcu linii, ignorując to m, co zostało zapamiętane w pierwszym akapicie.

Nie mogę znaleźć tego w żadnej dokumentacji VIM. Czy możesz mi wyjaśnić, jak działa ten mechanizm zapamiętywania, lub wskazać mi część dokumentacji, która to wyjaśnia?


Odpowiedzi

2 filbranden Aug 22 2020 at 16:58

Rzeczywiście, w dokumentacji $samego polecenia nie ma bezpośrednich odniesień do tego zachowania .

Dokumentacja g$ruchu faktycznie odnosi się jednak do tego zachowania, wyjaśniając, czym g$różni się od $:

Różni się od $sytuacji, gdy ostatni znak wiersza nie znajduje się na ekranie lub gdy jest używana licznik. Dodatkowo ruchy pionowe utrzymują kolumnę, zamiast iść do końca linii.

Poza dokumentacją, możesz rzucić okiem na to, jak Vim faktycznie implementuje śledzenie kolumn, ponieważ funkcje takie jak getcurpos()eksportują te informacje jako atrybut "curswant":

curswantLiczba jest preferowana kolumny podczas przemieszczania kursora w pionie.

(Atrybut „curswant” znajdziesz również w dyktandzie zwróconym przez winsaveview()).

Na przykład, jeśli przeszedłeś poziomo w długiej linii do kolumny 24, a następnie pionowo do linii, która ma tylko 17 kolumn, zobaczysz to:

: echo getcurpos ()
[0, 39, 17 , 0, 24 ]

Więc widzisz, że jesteś w kolumnie 17, ale "curswant" to kolumna 24 i Vim przejdzie do kolumny do 24, jeśli linia ma wystarczającą liczbę kolumn.

Po naciśnięciu $i ponownym spojrzeniu na getcurpos()wynik zobaczysz teraz:

: echo getcurpos ()
[0, 39, 17, 0, 2147483647 ]

Więc zobaczysz, że Vim implementuje to $zachowanie ustawiając "curswant" na bardzo dużą liczbę, która jest największą liczbą kolumn, które Vim może przechowywać w jednej linii.

(Ta liczba to w rzeczywistości 2 31-1 , która jest maksymalną dodatnią liczbą całkowitą, którą można przechowywać w inttypie ze znakiem w języku C).