Wskazówki dotyczące gry w golfa w vimie

32

Niedawno zdałem sobie sprawę, jak w , szczególnie w . Ponadto, według meta vim, jest to całkowicie akceptowalny „język programowania” przynajmniej dla zakresu tej strony.

Jakie masz ogólne wskazówki na temat gry w golfa w Vim? Szukam pomysłów, które można by zastosować do problemów związanych z golfem i które są przynajmniej nieco specyficzne dla Vima (np. „Usuń komentarze” nie jest odpowiedzią).

Proszę zamieścić jedną wskazówkę na odpowiedź.

DJMcMayhem
źródło
4
Jest to szczególnie pomocne pytanie, ponieważ „Wskazówki dotyczące gry w vima” i „Wskazówki dotyczące efektywnego używania vima jako edytora tekstu” są w zasadzie tym samym.
DLosc

Odpowiedzi:

15

Uważaj na duże warianty typowych poleceń. Może to w prosty sposób zaoszczędzić jedno naciśnięcie klawisza w wielu kontekstach. Na przykład:

A = $a
C = c$
D = d$
I = ^i
S = cc
X = dh
Y = yy

Innym jest użycie Gzamiast gg, ale tylko jeśli użyjesz liczby! Na przykład bez liczenia ggprzesuwa się na początek i Gprzechodzi na koniec. Jednak z policzeniem oba poruszają się do określonej linii, więc 5Gjest krótsza niż, ale równoważna 5gg .

Innym jest użycie Hzamiast gg, ale ważne jest, aby pamiętać, że działa to tylko wtedy, gdy możesz zagwarantować, że żadne wejście nie zajmie więcej niż domyślna liczba wierszy (uważam, że jest to 24, ale może się różnić).

DJMcMayhem
źródło
1
Jeśli wyzwanie dotyczy redaktora golfa (a zatem zwykle punktowane za pomocą naciśnięć klawiszy), duża litera to także dwa naciśnięcia klawiszy (tak $jednak jest , więc przynajmniej Ci Dcoś by oszczędziło).
Martin Ender
1
Nie jestem pewien, co do tego, kiedy oceniam w naciśnięciach klawiszy, czy kolejne litery, które wymagają klawisza Shift, liczą klawisz Shift tylko raz na grupę, ponieważ możesz (przynajmniej ze względów praktycznych) przytrzymać go podczas naciskania innych klawiszy.
Alex A.
6
@AlexA. Osobiście uważam, że modyfikatory nie powinny się liczyć. Może potrzebujemy meta posta na ten temat ...
DJMcMayhem
Gi ggnie są równoważne. Pierwszy idzie na koniec bufora, a drugi na początek.
Jordan
@Jordan To dobra uwaga. Miałem na myśli, że są takie same, gdy podano liczbę, np. 5GJest równoważne 5gg. Dodam więcej szczegółów na temat tego punktu.
DJMcMayhem
11

Za każdym razem, gdy polecenie nie powiedzie się, wyda odgłos ding, który anuluje bieżące makro. Możesz (ab) użyć tego, aby stworzyć prostą formę pętli. Na przykład, jeśli chcesz powtarzać naciśnięcia klawiszy, <foobar>dopóki bufor nie zawiera mniej niż 3 wiersze. Możesz to zrobić

qq<foobar>3G``@qq

co znaczy:

qq                 'Start recording in register q
  <foobar>         'Keystrokes
          3G       'Go to line 3. If line 3 doesn't exist, this is effectively a "break" statement.
            ``     'Jump back to previous cursor location
              @q   'Call macro q
                q  'Stop recording

Ważne jest, aby pamiętać, że jeśli testujesz to podczas sesji vim, @qmoże to mieć niezamierzone skutki uboczne, ponieważ makra są ładowane z .vim_profile. Możesz obejść to na kilka różnych sposobów. Prawdopodobnie najlepszym obejściem jest uruchomienie vima

vim -i NONE

Możesz także usunąć swój .viminfo.

Jeśli już uruchomiłeś vima, możesz pisać

qqq

na początku zerować makro.

Inne warunki, na które możesz zastąpić 3G to

f<char>    'Jump to first occurence of <char>. Also see F, t and T

lub

<number>|  'Go to the <number>'th character on the current line.
DJMcMayhem
źródło
8

Są bardziej skrócone wersje ex poleceń, które myślisz. Na przykład prawdopodobnie już wiedziałeś, że :globalmożna to skrócić :g, ale czy wiesz, że :nnoremapto jest równoważne :nn?

Dobrym pomysłem jest uruchomienie :h :foowszystkich poleceń ex, których używasz w odpowiedzi, aby sprawdzić, czy jest krótsza wersja.

Klamka
źródło
6
:%s/\n//g

jest zawsze równoważne z

:%s/\n//

który okazuje się być równoważny z

:%s/\n

co zaskakujące. (Ogólnie rzecz biorąc, bez żadnych flag, ostatni ukośnik w :swyrażeniu nigdy nie jest konieczny).

Klamka
źródło
2
Działa to w przypadku nowej linii, ale nie działa w przypadku żadnego znaku, który mógłby pojawić się więcej niż raz w linii. Na przykład :%s/xnie usuwa każdego wystąpienia x, tylko pierwszy w każdej linii.
DJMcMayhem
1
Możesz także użyć :&&do powtórzenia polecenia zastępczego i jego flag.
DJMcMayhem
6

Powiedzmy, że jesteś w trybie wstawiania i chcesz wykonać pojedyncze polecenie w trybie normalnym. Możesz napisać tak:

isome_text<esc><foobar>gisome_more_text

Nie rób tego w ten sposób. Zamiast tego użyj <C-o>, który wykonuje pojedyncze normalne polecenie, a następnie natychmiast powraca do trybu wstawiania.

isome_text<C-o><foobar>some_more_text
DJMcMayhem
źródło
Nie uważam też, żeby te miejsca były potrzebne
pozew Fund Moniki z
@QPaysTaxes Masz rację, nie są. Myślałem, że dzięki temu będzie bardziej czytelny. Zmienię to.
DJMcMayhem
Nie potrzebujesz <CR>póżniej, <foobar>aby wysłać polecenie?
Pozew Fund Moniki w
@QPaysTaxes Tylko jeśli jest to polecenie ex lub wyszukiwanie. (Np wszystkie polecenia wychodząc z :, /lub ?)
DJMcMayhem
Och, mój zły. Myliłem polecenia i normalne tryby. Cool: D
pozew Fund Moniki w
5

Istnieją trzy operatory „zmiany przypadku”,

gu    "Convert to lowercase
gU    "Convert to uppercase
g~    "Toggle case

Ponieważ są to operatory, wykonują ruch, aby przekonwertować bieżący znak na małe litery, których byś użył

gul

Tutaj pojawia się zabawna sztuczka. :) Jeśli chcesz zmienić wielkość liter pojedynczego znaku lub bieżącej linii, w trybie wizualnym jest krótsza o bajt. Na przykład guljest równoważne z

vu

I gu_(_ jest bieżącą linią) jest równoważne

Vu

Ta sztuczka nie działa w przypadku przełączania, ponieważ v?uruchamia wyszukiwanie do tyłu w trybie wizualnym (podobnie jak v/w przeciwnym kierunku), więc vg?zamiast tego potrzebujesz . Jednak tutaj możesz użyć ~operatora, aby zaoszczędzić jeszcze więcej bajtów! (Dzięki @Doorknob za zwrócenie na to uwagi)

Możesz zobaczyć tę sztuczkę w akcji na mojej odpowiedzi vim tutaj i na równoważnej odpowiedzi V na postu i.

DJMcMayhem
źródło
1
Nie zapomnij ~, która przełącza wielkość znaków pod kursorem i przesuwa jedną w prawo!
Klamka
5

Alfabet w 10 naciśnięciach klawiszy

Wszystkie zasługi za tę technikę należą do Lynn, która jako pierwsza zastosowała ją w tej odpowiedzi . Piszę to tutaj dla potomności.

Użyj następujących dziesięciu naciśnięć klawiszy, aby pociągnąć za małe litery:

:h<_␍jjYZZ

(Gdzie jest znak powrotu karetki, tzn. Klawisz Enter.)

Wyjaśnienie

:h<_␍otwiera sekcję pomocy v_b_<_example(przykład wizualnego zaznaczenia blokowego), który zawiera tekst abcdefghijklmnopqrstuvwyxz. jjYprzesuwa się do tej linii i szarpa ją, a następnie ZZzamyka okno pomocy.

Jordania
źródło
4

Poznaj swoje rejestry

Ciągnięcie lub usuwanie tekstu do określonego rejestru (np. "aY), Aby użyć go później, nie zawsze jest konieczne. Vim ma kilka rejestrów, które są automatycznie zapełniane tematami różnych poleceń. Wpisz :help registersje, aby zobaczyć je wszystkie, ale oto kilka szczególnych uwag:

  • Rejestr bez nazwy: ""- Ostatni tekst, który został szarpany lub usunięty.

  • Rejestr numerowany "0- ostatni zrywany tekst.

  • Rejestry numerowane "1- "9- Ostatni usunięty tekst, chyba że jest krótszy niż jeden wiersz. Po każdym "1napełnieniu jego poprzednia zawartość jest przesuwana do"2 i tak dalej.

  • Mały rejestr usuwania: "-- Ostatni tekst krótszy niż jeden wiersz, który został usunięty.

  • Ostatni wstawiony tekst: ".

W szczególności rejestry "-i "1mogą być przydatne razem, umożliwiając usunięcie części tekstu za pomocą np. ddDo "1rejestru i usunięcie innego tekstu za pomocą Ddo "-(oczywiście semantyka nie jest identyczna, ale często nie musi być ).

Wszystkie rejestry mogą być nieco trudne do śledzenia, ale możesz zobaczyć zawartość wszystkich swoich rejestrów w dowolnym momencie, pisząc :registers.

Jordania
źródło
3

To pojawiło się na czacie wcześniej, więc pomyślałem, że równie dobrze mogę opublikować to jako pełną wskazówkę.

<C-a>oraz <C-x>zwiększanie i zmniejszanie następnego numeru na linii. Jest to niezwykle przydatna funkcja dla niektórych prostych obliczeń matematycznych, ale pozwala także na porządny mały hack.

Powiedzmy, że musisz przejść do następnej liczby. Na przykład musimy się zmienić

I need 2 spell better

do

I need to spell better

Oczywistym sposobem jest przeskoczenie do 2, a następnie:

sto                "Synonymous with 'clto'

Ponieważ jest to krótszy niż

:s/2/to<cr>

Istnieje wiele różnych sposobów przejścia do 2. Na przykład:

/2<cr>
ww 
2w
ee
2e
8|
f2

Jak również na wiele innych sposobów.

Są to wszystkie 2 (lub więcej) naciśnięcia klawiszy. Ponieważ jednak <C-a>i <C-x>nie tylko numery góra / dół, ale również przejść do następnego numeru, możemy wziąć bajt mecz

<C-a>sto
DJMcMayhem
źródło
3

Ruchy golfisty

Często, jeśli pracujesz z blokiem tekstu (szczególnie w wyzwaniach ), musisz przejść do pierwszego lub ostatniego znaku w buforze. Gi ggsą całkiem dobre, ale są irytujące rzeczy. Na przykład, aby uzyskać ostatni znak, potrzebujesz G$i ggniekoniecznie umieścisz cię w pierwszej kolumnie, jeśli jest wiodąca biała spacja. Oto kilka ładniejszych ruchów, chociaż zauważ, że działają one tylko wtedy, gdy tekst nie ma pustych linii w środku:

  • Pierwszy znak bufora: {jest lepszy niż gg0. Jeśli na środku tekstu są puste linie, możesz także użyć gotego, który przeniesie Cię do pierwszego znaku w buforze, bez względu na wszystko.

  • Ostatni znak bufora: }jest lepszy niżG$

Działają one również jako argument dla operatora, ale należy pamiętać, że są to ruchy charakterystyczne, a nie ruchy liniowe!

DJMcMayhem
źródło
Hjest bardziej golfowy niżgg
Kritixi Lithos,
@KritixiLithos poza tym, że Hnie jest wiarygodny. Jego zachowanie zależy od wielkości widocznego okna i miejsca w buforze. (Został ponownie mapowany w V, aby uniknąć tego zamieszania)
DJMcMayhem
2

Wykonuj obliczenia za pomocą rejestru wyrażeń

Możesz wykonywać obliczenia zarówno w trybie normalnym, jak i w trybie wstawiania.

Tryb normalny

W trybie normalnym, jeśli wpiszesz @= kursor przejdzie do wiersza polecenia, w którym można wprowadzić dowolne wyrażenie. Po naciśnięciu klawisza Enter wynik wyrażenia zostanie wykonany jako polecenie w trybie normalnym.

Załóżmy na przykład, że chcesz przejść do środkowej kolumny bieżącego wiersza. Wywołanie funkcji col('$')zwraca liczbę kolumn w wierszu, dzięki czemu możemy to osiągnąć, wpisując następujące polecenie:

@=col('$')/2<CR>|

Kiedy naciśniesz enter, kursor powróci do bufora i vim czeka na operatora (jak |) tak, jakbyś właśnie wprowadził liczbę. Ewentualnie możesz wprowadzić to:

@=col('$')/2.'|'

... ale to oczywiście więcej bajtów.

Tryb wstawiania

Rejestru wyrażeń można także użyć w trybie wstawiania, naciskając <Ctrl-r>=zamiast @=. Działa tak samo w trybie normalnym, z wyjątkiem tego, że wpisane wyrażenie zostanie wykonane w trybie wstawiania. Na przykład jeśli wpiszesz<Ctrl-r>=col('$')<CR> , liczba kolumn w bieżącym wierszu zostanie wstawiona pod kursorem, tak jakbyś go wpisał.

Aby uzyskać więcej informacji na temat rejestru wyrażeń, wpisz :help "=.

Ponowne użycie wyrażeń

Ostatnim wyrażenie użyte jest przechowywana w rejestrze ekspresyjnego "=. Wpisanie @=<CR>w trybie normalnym lub <Ctrl-r>=<CR>w trybie wstawiania ponownie oceni wyrażenie, umożliwiając korzystanie z nich podobnie do makr.

Wykonuj obliczenia w zamianach

Możesz również oceniać wyrażenia, wykonując zamiany wyrażeń regularnych. Wszystko, co musisz zrobić, to rozpocząć zamianę \=. Załóżmy na przykład, że chcesz numerować linie w tym pliku:

foo
bar
baz

Wywołanie funkcji line('.')zwraca bieżący numer linii, więc zadanie jest łatwe. Wprowadzanie tego:

:s/^/\=line('.').' '/g<CR>

... daje pożądany wynik:

1 foo
2 bar
3 baz

Aby użyć przechwyconych grup w takim wyrażeniu, możesz użyć submatch()funkcji, gdzie np. submatch(0)Jest równoważne \0zwykłemu podstawieniu, submatch(1)jest równoważne \1, itp. Niestety, to zużywa wiele naciśnięć klawiszy.

Aby uzyskać więcej informacji na temat podstawiania wyrażeń, wpisz :help sub-replace-expression.

Jordania
źródło
W twoim ostatnim przykładzie są krótsze sposoby. Na przykład i1 <esc>bqqywjPb<C-a>@qq@qjest rozwiązaniem w trybie normalnym, który jest o 5 bajtów krótszy. A jeśli jesteś na Uniksie, możesz to zrobić :%!nl. Nadal dobre wskazówki!
DJMcMayhem
1
Moim celem było pokazanie, jak korzystać z tej funkcji, a nie jak numerować linie przy jak najmniejszej liczbie naciśnięć klawiszy.
Jordan
1

Możesz bezpośrednio zmodyfikować tekst makra, który może być znacznie krótszy niż złożony warunek. Załóżmy na przykład, że chcesz wkleić coś n razy, gdzie n oznacza dane wprowadzone przez użytkownika. Najpierw próbowałem to zrobić:

qq/[1-9]<enter><c-x>``p@qq@q

Wyjaśnienie:

qq                             #Start Recording
  /[1-9]<enter>                #Search for a number that isn't 0.
                <c-x>          #Decrement that number
                     ``p       #jump back to your previous location and paste.
                        @q     #Recursive call to macro 'q'
                          q@q  #Stop recording, and run the macro

To 18 naciśnięć klawiszy i naprawdę brzydki sposób na zrobienie tego. Zamiast tego przejdź do lokalizacji tego numeru i zrób to:

Ap<esc>"qdd@q

Wyjaśnienie:

Ap<esc>                 #Append a 'p' to the end of the current line.
       "qdd             #Delete the current line into register q
           @q           #Run macro q.

To 9 naciśnięć klawiszy, ogromna poprawa.

Edytować:

Jeszcze krótsze jest uruchomienie makra dla twojego numeru, a następnie wpisz polecenie. Na przykład:

"qdd@qp

Wyjaśnienie:

"qdd         #Delete the current line into register q
    @q       #Run register q
      p      #Paste

7 uderzeń w klawisze.

DJMcMayhem
źródło
1
1. Użyj D, a nie dd. 2. Jeśli polecenie nie obejmuje rejestrów, możesz je skrócić. Na przykład, jeśli chcesz powtórzyć znak xtyle razy, ile liczba pod kursorem, zamiast "qD@qix<esc>, użyj D@"ix<esc>.
Klamka