Ustaw opcję wklejania, ale tylko dla jednego wstawiania


16

Chcę mieć szybki sposób na ustawienie 'paste'opcji Vima , wstawienie tekstu i powrót do poprzedniej wartości 'paste'.

Typowy przypadek użycia wstawia zawartość schowka OS dosłownie, niezależnie od tego, który tryb przepisywania w trybie wstawiania może być aktywny, taki jak automatyczne wcięcie i bez zmiany stanu Vima. Innym przykładem użycia byłoby umożliwienie funkcji makra systemu operacyjnego wstrzykiwania naciśnięć klawiszy do Vima i interpretowania ich jako dosłowny tekst.

To oczywiście uogólnia na inne opcje - ogólną ideą jest ustawienie niektórych opcji, ale tylko na czas jednej podróży przez tryb wstawiania.

Zasadniczo chcę powiązać sekwencję klawiszy (powiedzmy _i) z makrem, które to robi

:set paste
i…<Esc>
:set nopaste

gdzie i…<Esc>mam na myśli przejście do trybu wstawiania (jak w przypadku ipolecenia) i wznowienie makra po powrocie do trybu polecenia, z tym wyjątkiem, że chcę skończyć z 'paste'nadal aktywnym, jeśli był wcześniej aktywny. W jaki sposób mogę to zrobić?

Uwaga: zawartość schowka OS jest mapowana do "*rejestru . Kiedy to działa, 'paste'opcja nie jest bardzo przydatna. Scenariusz motywujący dla tego pytania dotyczy czasów, w których warunki obsługi "*rejestru nie są spełnione - Vim nie jest skompilowany z tą +xterm_clipboardfunkcją lub działa w terminalu, takim jak Screen lub przez SSH, który izoluje go od serwera X otoczenia.


1
Podoba mi się twoje pytanie (byłem tam wiele razy). Czy nie jest jednak łatwiej wkleić z +lub *zarejestrować?
yo „

@yo ' Tylko wtedy, gdy działają . Co w przypadku moich zastosowań Vima często nie jest prawdą.
Gilles „SO- przestań być zły”

Odpowiedzi:


15

Wypróbuj to:

function! Paste_Func()
    let s:inPaste = &paste
    if !s:inPaste
        set paste
    endif

    echom s:inPaste
    augroup paste_callback
        autocmd!
        autocmd InsertLeave <buffer> call Paste_End()
    augroup END

    startinsert
endfunction

function! Paste_End()
    augroup paste_callback
        autocmd!
    augroup END
    augroup! paste_callback

    if !s:inPaste
        set nopaste
    endif
endfunction

map _i :call Paste_Func()<cr>

Przechowuje bieżący stan wklejania w zmiennej inPaste i ustawia wklej, jeśli nie jest jeszcze ustawiony. Następnie ustawia autocmd, kiedy wychodzisz z trybu wstawiania, a następnie wprowadza cię w tryb wstawiania.

Po wyjściu z trybu wstawiania uruchamia on autocmd, który najpierw usuwa autocmd (więc nie uruchamia się, gdy opuścisz tryb wstawiania w inny sposób), a na końcu ustawia nopaste, jeśli pierwotnie nie byłeś w trybie wklejania.

Ponadto, jeśli używasz vima w terminalu, możesz rzucić okiem na vim-bracketing-paste , który używa funkcji trybu wklejania w nawiasach udostępnionej przez kilka emulatorów terminali w celu wykrycia, czy wklejasz i ustawiasz tryb automatycznie.

Edycja: naprawiono skrypt


Wydaje się, że jest to właściwa ścieżka (w szczególności nie miałem pojęcia, jak „spakować” odcinek wstawiania przez normalne polecenia świata). Dzięki. Nie jest to jednak w porządku i nie widzę, gdzie jest problem: po _i, pasteopcja jest wyłączona, nawet jeśli była wcześniej włączona.
Gilles „SO- przestań być zły”

Masz rację! Jestem pewien, że to przetestowałem, ale musiałem coś zmienić. Zaktualizowałem skrypt w poście, sprawdź, czy teraz działa.
Czad

4

z wyjątkiem tego, że chcę skończyć z 'paste'wciąż aktywną, jeśli była wcześniej aktywna.

'paste'powinien być aktywny tak krótko, jak to możliwe. Wyłącza wiele funkcji (w tym map), ponieważ jego jedynym celem jest uniknięcie błędnej interpretacji wklejanego tekstu. Dlatego uważam, że podany wymóg nie powinien być konieczny.

To powiedziawszy, w rzeczywistości jest dość łatwe do wklejenia bez konieczności ustawiania 'paste'. Jeśli korzystasz z gvim lub masz +xterm_clipboardvim konsoli, możesz po prostu użyć "+pdo wklejenia ze schowka systemu operacyjnego.

Problem automatycznego wcięcia podczas wklejania zdarza się tylko w dwóch scenariuszach. Wstawianie zawartości rejestru w trybie wstawiania ( <C-r>+) lub wklejanie środkowym przyciskiem myszy.

Zamiast wstawiać zawartość rejestru w trybie wstawiania, wklejenie rejestru w trybie normalnym pozwoli uniknąć problemu z formatowaniem.

Jeśli chcesz wkleić kliknięcie środkowym przyciskiem myszy, użyj 'mouse'opcji, aby Vim zamiast terminala zajął się kliknięciem środkowym. Vim wstawi następnie zawartość dosłownie zamiast interpretować tekst przychodzący jako pisany.


2
Żadna z tych odpowiedzi nie odpowiada na moje pytanie. Nie bez powodu stawiam wyraźne wymagania! Zazwyczaj 'paste'rzeczywiście nie jest wcześniej aktywny, ale nie chcę o tym myśleć. Często pracuję w Vimie, który nie ma dostępu do schowka X lub myszy, albo dlatego, że moja kompilacja Vima nie ma tej xterm_clipboardfunkcji, albo dlatego, że pracuję np. W sesji ekranowej, która akurat jest aktualnie dołączona do Terminal X
Gilles „SO- przestań być zły”

@Gilles Czy mógłbyś wyjaśnić, jak wklejasz? Są to istotne informacje, aby móc udzielić odpowiedzi, która może zakończyć to działanie tym, co chcesz zrobić.
jamessan

1
Moim podstawowym przypadkiem użycia jest wklejanie środkowym przyciskiem myszy lub Shift + Insert. Nie ma to jednak większego znaczenia: sedno pytania brzmi: jak ustawić opcję, przejść do trybu wstawiania (z i, nie pytam, jak to sparametryzować) i przywrócić wartość opcji po powrocie z trybu wstawiania.
Gilles „SO- przestań być zły”

1
@Gilles Trzon twojego pytania, jak stwierdzono w tym komentarzu, jest dla mnie znacznie bardziej przejrzysty niż twoje pierwotne pytanie. Dzięki.
jamessan

1
@Gilles Nie dotyczy Ciebie , ale może być istotny dla przyszłych gości. Dlatego albo możesz umieścić to w samym pytaniu („Wiem, że mogę używać "*plub "+pwklejać ze schowka, ale nie chcę używać zdolności wklejania systemu”), a wtedy ta odpowiedź jest niepotrzebna. Albo nie, i myślę, że ta odpowiedź ma tutaj swoje miejsce.
yo ”

4

Osobiście korzystam z yoklawiszy z doskonałej wtyczki Tima Pope'a bez wad . Z jego dokumentacji:

Nie podano przełącznika dla „wklejania”, ponieważ typowy przypadek użycia owijania pojedynczego wstawienia jest tak marnotrawny: Przełączasz dwa razy, ale wklejasz tylko raz (YOPO). Zamiast tego naciśnij yolub, yOaby wywołać |o|lub |O|z ustawionym „wklejaniem”. Opuszczenie trybu wstawiania powoduje automatyczne ustawienie „nopaste”.

Zainstalowanie wtyczki może być przesadą tylko dla twojego pytania, ale uważam, że zapewnia ona także wiele innych przydatnych skrótów klawiszowych (więcej informacji w pliku README ).


1

W Vimie 8+ na Linuksie lub Macu możesz teraz po prostu użyć natywnej pasty terminala (np. Środkowy przycisk myszy, ctrl+shift+Vw Gnome, cmd+Vna Macu), jeśli terminal obsługuje wklejanie w nawiasach. Nie naciskaj, iaby włączyć tryb wstawiania.

Wklei zawartość schowka systemu operacyjnego, zachowując spacje i tabulatory bez dodawania automatycznego wcięcia. Jest to odpowiednik starego :set paste, i, ctrl+shift+V, esc, :set nopastemetody.

Nie potrzebujesz nawet zainstalowanych funkcji +clipboardlub +xterm_clipboardvim. Ta funkcja nosi nazwę „wklejania w nawiasach”. Aby uzyskać więcej informacji, zobacz /programming/2514445/turning-off-auto-indent-when-pasting-text-into-vim/56781763#56781763

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.