Jak automatycznie tworzyć pasujące nawiasy klamrowe w vimie?
Powinno działać w następujący sposób: Jeśli wprowadzę nawias otwarty, to nawias zamykający powinien pojawić się automatycznie, a kursor powinien zostać umieszczony pomiędzy. Aby wyskoczyć z pary nawiasów, Ctrl-jużywana jest kombinacja .
Istnieje wiele wtyczek zapewniających automatyczne wstawianie nawiasów klamrowych. Ale oni
- użyj innej kombinacji klawiszy niż Ctrl-jwyskoczyć z pary nawiasów klamrowych lub
- zakłócać powiązania klawiszy UltiSnips .
Poniższe działa zgodnie z oczekiwaniami
:inoremap ( ()<Esc>:let leavechar=")"<CR>i
:imap <C-j> <Esc>:exec "normal f" . leavechar<CR>a
Ale przy tych ustawieniach fragmenty UltiSnips już nie działają. Więc użyłem UltiSnips, aby wstawić klamrę zamykającą:
inoremap ( (<C-R>=UltiSnips_Anon('($1)$0', '(')<CR>
To prawie działa. Dopasowany klamra jest wstawiony i mogę pominąć zamykający za pomocą Ctrl-j. Działa to jednak tylko wtedy, gdy przed otwartą klamrą znajduje się przestrzeń.
main () // works, the closing parentheses is added
main( // fails without a space
Moje rozwiązania albo wymagają innego przypięcia klucza, aby przeskoczyć nad klamrą zamykającą, albo wymagają miejsca przed otwartym. Jak to naprawić?
Uwaga: użyłem nawiasów jako przykładu. Powinien współpracować z nawiasami, nawiasami klamrowymi, nawiasami i znakami mniejszymi niż i nie powinien zakłócać wtyczki UltiSnips.
)
, zmiana mapowaniac-j
na to może działać.Odpowiedzi:
Ten problem nie jest trywialny, jak się przekonacie. Odpowiedź jest prosta: użycie wtyczki, jak AutoClose lub smartinput . Wystarczy naiwnie odwzorować (klucze [... pokażą ci edgecases w kilku liniach), dlatego te wtyczki są tworzone i dlaczego są zwykle dość złożone (jeśli są jakieś dobre).
Możesz spróbować zamiast tego (co różni się od mojej oryginalnej sugestii):
Gdzie UltiSnips podzieli linię
(
zamiast brać udziałmain
w meczu. Problem z używaniem wtyczki do tego fragmentu polega na tym, że (zwykle) nie obsługują one zagnieżdżania, więc zapomną o pozycjach skoku po włożeniu następnego (zagnieżdżonego) fragmentu.Możesz zmienić mapowanie Ctrl-jdla UltiSnips lub wtyczki powodującej konflikt. Jeśli mapowania nie ma na liście w dokumentacji, możesz użyć
:map/imap/nmap <key>
do wyświetlenia mapowania. Jeśli chcesz Ctrl-jwybrać, wybrać i wykonać pracę obu wtyczek, poprosisz o:Rozważ tę pętlę bash:
W takim przypadku musisz nacisnąć Ctrl-j5 razy, aby dostać się do ciała pętli. Użycie zamykających nawiasów w celu wyskoczenia z odpowiedniej pary daje o wiele większą kontrolę nad tym, gdzie faktycznie chcesz przesunąć kursor. Możesz zaimplementować stos, aby śledzić wstawione pary i używać ich Ctrl-jdo pop i przesuwania, ale wtedy wystąpią problemy, jeśli zaczniesz ręcznie usuwać nawiasy klamrowe bez usuwania ich ze stosu. Zaczniesz więc rozwiązywać problemy, które wtyczki klamrowe próbują rozwiązać. To jest trudne koło do wymyślenia na nowo.
Rozwijając to, możesz uzyskać to, o co początkowo prosiłeś, używając Ctrl-jwyskakując z nawiasów klamrowych i fragmentów. Jeśli użyjesz jakiejś wartości fikcyjnej do reprezentowania pozycji urywków i wepchniesz je na stos oprócz zamykających nawiasów klamrowych, z dynamicznym odwzorowaniem Ctrl-jodpowiadającym przekazywaniu urywków lub nawiasów klamrowych. Ale wtedy musisz wdrożyć dość zaawansowaną heurystykę, aby dowiedzieć się, co magia powinna się wydarzyć, ponieważ zasadniczo bierzesz na siebie dwa problemy, które są obecnie rozwiązywane przez twórców wtyczek wstawiania fragmentów i osobno dopasowywania wtyczek i ponownie rozwiązując te problemy, oprócz ich rozwiązań, aby uzyskać wygodę i, no cóż, magię.
Wszystko sprowadza się do kontroli vs. wygody. Myślę, że kontrola w tym przypadku będzie ci lepiej służyć, co oznacza, że powinieneś oddzielić te problemy od powiązanych z nimi wtyczek i mapowań kluczy. Jeśli nadal chcesz wygody, jest to wykonalne, ale trudne.
źródło
Myślę, że delimitMate robi to, czego potrzebujesz.
Automatycznie zamyka nawiasy lub cudzysłowy i umieszcza kursor pomiędzy nimi. Aby wyskoczyć z pary nawiasów (będąc w trybie wstawiania), możesz zrobić Ctrl-g+, gale możesz to zmienić Ctrl-j, dodając to do
vimrc
:źródło
Odkryłem, że automatyczne zamykanie dodaje trochę opóźnienia, a także zakłóca moją konfigurację (Ultisnips i Supertab), ale podoba mi się jego podejście do emulacji CDT Eclipse.
Używam delimitMate z następującymi mapami, aby pomóc w nawigacji i wcięciach, starając się uzyskać te same wyniki:
Używam tego w ten sposób: wstawianie otworu
{ <CR><CR><C-K>
i zacznij pisać w wciętej linii wewnętrznej.źródło
Osobiście używam smartinput do automatycznego wstawiania nawiasów i cytatów. Na przykład pisanie w
{
dowolnym miejscu spowoduje utworzenie{}
kursora pośrodku. Aby opuścić{
grupę nawiasów, wpisz po prostu}
obok wstawionego}
.Jednak to potwierdza twoje wymagania dotyczące tabstops i przeskakiwania poza nawias. Nie tworzy też nowego między nawiasami, ale i tak potrzebujesz tylko jednego dodatkowego klucza -
<CR>
.Możesz mapować,
<C-J>
aby przejść do następnej linii w dół:lub jeśli chcesz przejść do początku następnego wiersza:
źródło
Coś takiego może się dla ciebie sprawdzić.
źródło
W rzeczywistości Ultisnips może to zrobić prawie idealnie (może to być nowy). Nieznacznie modyfikując odpowiedzi podane powyżej, mam spory sukces
inoremap () ()<C-R>=UltiSnips#Anon('($1)$0', '()', 'double parentheses', 'i')<CR>
Trzeba pisać,
()
które są lepsze, ale można je również zmienić(
. Następnie dodatkowe opcjonalne argumentyUltiSnips#Anon
to opis i modyfikator,i
który umożliwia rozwijanie w słowie.Wyskakiwanie z nawiasów za pomocą
<c-j>
utworów, również zagnieżdżonych w innych fragmentach. Jednak wywoływanie zagnieżdżonych()
nawiasów wydaje się przerywać tę funkcję, co nie jest niczym wielkim.źródło