vim: Kontynuować makro po błędzie w submacro?


15

Jestem w trakcie upiększania kodu źródłowego za pomocą vima. {1}

Stworzyłem kilka makr vim, które wykonują poszczególne kroki: usuwanie końcowej spacji, usuwanie pustych linii po {, usuwanie pustych linii przed {, tego rodzaju rzeczy.

Teraz chcę utworzyć makro, które wykonuje kolejno wszystkie poszczególne makra. Jednak gdy zakończy się pierwsze makro rekurencyjne (ponieważ nie może już znaleźć żadnych dopasowań -> błąd dopasowania), moje makro „otoki” również się kończy.

Czy istnieje sposób na kontynuowanie makra vim po wygenerowaniu błędu przez submacro?

{1} Ja wiem o automatycznych reformatters. Mogę nawet użyć ich do mojego obecnego problemu. Dla przykładu podałem tylko formatowanie źródła. Nie publikuj żadnych odpowiedzi na temat tego źródłowego upiększacza lub tego. To nie jest pytanie o kod formatowania per se , ale o vim makra.

Przykład:

  • Makro 1 - przycinanie końcowych białych znaków - qw/\s\+$d$@wq
  • Makro 2 - usuwanie pustych linii przed} - qe/\n\n *}dd@eq
  • Wrapper Macro - Retabbing, Macro 1, Macro 2 - qr:retab@w@eq

Kiedy wykonam opakowanie - @r- przebije, a następnie uruchom Makro 1, dopóki nie zostaną znalezione końcowe białe znaki, a następnie zakończ ( bez wykonywania Makra 2).

Wyjaśnienie:

To, czego szukam, to jak wywołać submacro, aby po zakończeniu tego submacro makro wywołujące było kontynuowane?

Odpowiedzi:


12

Sugeruję, aby użyć :trydo „wchłonięcia” błędu submakro.

Oto głupi przykład:

:let @a='f|dt|@a'
:let @q=':try|exe "norm! @a"|endtry^Mj0@q'
@q

Twoje makro opakowania wyglądałoby mniej więcej tak:

let @r=':retab^M:try|exe "norm! @w"|endtry|try|exe "norm! @e"|endtry^M'

Choć garyjohn warunkiem obejście dla nie posiadające błąd w submacro, jest to jedyna odpowiedź, że faktycznie nie obsługuje takiego błędu. Muszę jednak przeprosić; I nie sprawdzić swoją odpowiedź w czasie, aby uzyskać (obecnie wygasł) bounty ... :-(
DevSolar

26

Jeśli nieudane polecenie jest podstawieniem, które nie znajduje swojego wzorca, np.

:%s/foo/bar/

gdy foonie istnieje w buforze, możesz dodać eflagę, aby zignorować ten błąd, np.

:%s/foo/bar/e

Widzieć

:help :s_flags

Możesz powiedzieć Vimowi, aby ignorował błędy niektórych poleceń ex, poprzedzając je znakiem :silent!. Widzieć

:help :silent


Edytuj po dodaniu przykładu do pytania

Makro 1 i Makro 2 są rekurencyjne i żadne z nich nie ma wyraźnego mechanizmu kończącego rekurencję. Domyślam się, że uruchamiany jest jeden z wewnętrznych testów Vima pod kątem nieograniczonej rekurencji, który generuje błąd. Jeśli makro 1 generuje taki błąd, błąd ten zakończy wykonywanie makra opakowania natychmiast po tym @w.

Moją sugestią byłoby ograniczenie liczby uruchomień makr poprzez przepisanie ich jako poleceń ex i ograniczenie zakresu wierszy, w których są wykonywane. Na przykład:

qw:%s/\s\+$//^Mq
qe:%s/\n\n *}/\r}/^Mq

gdzie ^Moznacza wpisanie klawisza Enter lub Return. Nie testowałem ich razem w twoim Wrapper Macro, ale myślę, że będziesz w stanie naprawić wszelkie błędy, które popełniłem.


W moim przypadku nie jest to podstawienie, ale proste znalezisko (tj /foo.). Chociaż :silent!rzeczywiście sztuczka rekursywnego submacro nie przerywała makra opakowania, teraz submakro w ogóle się nie kończy ... i podejrzewam, że ponowne uruchomienie go w jakiś sposób spowoduje zakończenie makra opakowania. Wygląda na to, że utknąłem. : - \
DevSolar,

Trudno powiedzieć, co może być nie tak, nie widząc używanych makr ani prostego przykładu, który wykazuje ten sam problem.
garyjohn

Dodano przykład.
DevSolar,

2

Dla mnie zadziałało połączenie odpowiedzi @Peter Rincker i @garyjohn. Osobno po prostu dostawałem dziwne problemy.

nnoremap <leader>rt :silent! %s/\s\+$//e<CR>
let @r='\rt'
let @t=':try|silent! exe "norm! @r"|endtry|w^M'

Myślę, że silent!w <leader>rt, i znaki rur pomiędzy endtryi wbyły klucze - po prostu o przerwę wiersz po endtrypowiodło się. Do trys pracował kiedy ja po prostu wpisać je, ale kiedy uruchomić jako makro błąd o tekście wyszukiwania nie stwierdzono by zachować podnoszone.


1

Rutynowo tworzę makra „w locie”, gdy muszę wykonać powtarzalne zadanie wśród wielu plików. W moim przypadku mam NERDtree ( http://www.vim.org/scripts/script.php?script_id=1658 ) zainstalowany w VIM, które tworzą vsplitokno, a po lewej stronie mam listę wszystkich plików w bieżący katalog. W jednym przykładzie muszę znaleźć pierwszą instancję ciągu MY_TESTw pliku, a następnie usunąć, jeśli jest obecny, prefiks oznaczony jako CUSTOM_PREFIX-z tej linii, zapisać plik, a następnie przejść do następnego.

Oto, jak mam to makro działać na około 2000 plików w bieżącym katalogu. Mógłbym napisać skrypt bash, aby to zrobić, ale w moim przypadku jest to szybsze w VIM. W +oznacza klawiszy zostanie naciśnięty Simul

# Start recording a macro sequence to register 'A'

q,a

# Search silently for the string "MY_TEST"; DO NOT report an error
# if the string could not be found.
:silent! /MY_TEST


# Replace, on just the current line, the string "CUSTOM_PREFIX-", with
# nothing (ie: delete it), and suppress any warning messages if the
# string could not be found on the current line.
:s/CUSTOM_PREFIX-//e


# Now issue some UI commands. CTRL-W then and arrow key lets you hope
# between tabs/splits/windows within vim.

CTRL+ W,

# Scroll down to the next file in the list in NERDtree



# Open the next file

ENTER

# End the macro

q

# Run the macro a thousand times in VIM

1000 @,a

Mam nadzieję że to pomoże!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.