Imposta l'opzione incolla, ma solo per un inserimento


16

Voglio avere un modo rapido di impostare l' 'paste'opzione Vim , inserire del testo e ripristinare il valore precedente di 'paste'.

Un tipico caso d'uso inserisce letteralmente il contenuto degli Appunti del sistema operativo, indipendentemente da qualsiasi riscrittura della modalità di inserimento che può essere attiva, come il rientro automatico, e senza cambiare lo stato di Vim. Un altro caso d'uso sarebbe quello di consentire a una funzione di macro del sistema operativo di inserire sequenze di tasti in Vim e di interpretarle come testo letterale.

Questo ovviamente si generalizza ad altre opzioni: l'idea generale è di impostare alcune opzioni, ma solo per la durata di un viaggio attraverso la modalità di inserimento.

Fondamentalmente voglio associare una sequenza di tasti (diciamo _i) a una macro che fa questo

:set paste
i…<Esc>
:set nopaste

dove i…<Esc>intendo passare alla modalità di inserimento (come con il icomando) e riprendere la macro al ritorno alla modalità di comando, tranne per il fatto che voglio finire con 'paste'ancora attivo se era attivo in precedenza. Come posso fare questo?

Nota: il contenuto degli Appunti del SO è mappato al "*registro . Quando funziona, l' 'paste'opzione non è molto utile. Lo scenario motivante per questa domanda è per quei momenti in cui le condizioni per il "*supporto del registro non sono soddisfatte: Vim non è compilato con la +xterm_clipboardfunzione o è in esecuzione in un terminale come Screen o su SSH che lo isola dal server X ambiente.


1
Mi piace la tua domanda (ci sono stato molte volte anche io). Tuttavia, non è più facile incollarlo dal +o *registrarsi?
yo

@yo ' Solo quando funzionano . Il che, per i miei usi di Vim, spesso non è il caso.
Gilles 'SO- smetti di essere malvagio' il

Risposte:


15

Prova questo:

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>

Memorizza il tuo stato attuale di incolla nella variabile inPaste e imposta incolla se non è già impostato. Quindi imposta un autocmd per quando si esce dalla modalità di inserimento e quindi si mette in modalità di inserimento.

Quando si esce dalla modalità di inserimento, esegue autocmd, che per prima cosa rimuove autocmd (quindi non viene eseguito quando si lascia la modalità di inserimento in altro modo), e infine imposta nopaste se non si fosse originariamente in modalità incolla.

Inoltre, se si utilizza vim in un terminale, è possibile dare un'occhiata a vim-bracketed-paste , che utilizza la funzione di modalità di bracketing fornita da diversi emulatori di terminale per rilevare se si sta incollando e impostare automaticamente la modalità.

Modifica: risolto lo script


Questo sembra sulla strada giusta (in particolare, non avevo idea di come "racchiudere" un tratto di inserimento con normali comandi del mondo). Grazie. Tuttavia, non è del tutto corretto e non vedo dove sia il problema: dopo _i, l' pasteopzione è disattivata, anche se era attiva prima.
Gilles 'SO- smetti di essere malvagio' il

Hai ragione! Sono abbastanza sicuro di averlo provato, ma devo aver cambiato qualcosa. Ho aggiornato lo script nel post, vedi se funziona ora per te.
Chad,

4

tranne che voglio finire con 'paste'ancora attivo se fosse attivo prima.

'paste'dovrebbe essere attivo il più breve tempo possibile. Disabilita molte funzionalità (comprese le mappe), poiché il suo unico scopo è evitare l'interpretazione errata del testo che viene incollato. In quanto tale, penso che il requisito citato non dovrebbe davvero essere necessario.

Detto questo, in realtà è abbastanza facile da incollare senza bisogno di impostare 'paste'. Se stai eseguendo gvim o hai +xterm_clipboardin console vim, puoi semplicemente usare "+pper incollare dagli appunti del sistema operativo.

Il problema del rientro automatico mentre incolla si verifica davvero solo in due scenari. Inserimento del contenuto di un registro in modalità inserimento ( <C-r>+) o incollamento con il clic centrale con il mouse.

Invece di inserire il contenuto di un registro in modalità di inserimento, incollare dal registro in modalità normale eviterà il problema di riformattazione.

Se si desidera fare clic con il pulsante centrale incolla con il mouse, utilizzare l' 'mouse'opzione per consentire a Vim, anziché al terminale, di gestire il clic centrale. Vim inserirà quindi i contenuti letteralmente invece di interpretare il testo in arrivo come digitato.


2
Niente di tutto questo risponde alla mia domanda. Ho inserito requisiti espliciti per un motivo! Di solito in 'paste'effetti non è attivo prima, ma non voglio pensarci. Lavoro spesso in un Vim che non ha accesso agli Appunti o al mouse X, sia perché la mia build Vim non ha la xterm_clipboardfunzione, o perché sto lavorando ad esempio in una sessione dello schermo che è attualmente collegata a un Terminale X.
Gilles 'SO- smetti di essere malvagio' il

@Gilles Allora potresti spiegare come stai incollando? Queste sono informazioni rilevanti per essere in grado di fornire una risposta che può racchiudere quell'azione con ciò che vuoi fare.
Jamessan,

1
Il mio caso d'uso di base è incollare con il pulsante centrale del mouse o con Maiusc + Inserisci. Questo non è molto rilevante, tuttavia: il nocciolo della domanda è come impostare un'opzione, passare alla modalità di inserimento (con i, non sto chiedendo come parametrizzare questo) e ripristinare il valore dell'opzione al ritorno dalla modalità di inserimento.
Gilles 'SO- smetti di essere malvagio' il

1
@Gilles Il nucleo della tua domanda, come affermato in questo commento, mi è molto più chiaro della tua domanda originale. Grazie.
Jamessan,

1
@Gilles Non è rilevante per te , ma può essere rilevante per i futuri visitatori. Quindi o puoi metterlo nella domanda stessa ("So che posso usare "*po "+pincollare dagli appunti, ma non voglio usare le capacità di incolla del sistema") e quindi questa risposta non è necessaria. Oppure no, e quindi penso che questa risposta abbia il suo posto qui.
yo

4

Personalmente, uso il yokeybinding dell'ottimo plug -in senza compromessi di Tim Pope proprio per questo motivo. Dalla sua documentazione:

Non è stato fornito un interruttore per 'incolla' perché il tipico caso d'uso dell'involucro di un inserimento solitario è così dispendioso: si attiva / disattiva due volte, ma si incolla solo una volta (YOPO). Invece, premere yoo yOper richiamare |o|o |O|con 'incolla' già impostato. L'uscita dalla modalità di inserimento imposta automaticamente 'nopaste'.

Potrebbe essere eccessivo installare il plug-in semplicemente per la tua domanda, ma trovo che fornisca anche molte altre utili combinazioni di tasti (maggiori informazioni nel README ).


1

Con Vim 8+ su Linux o Mac, ora puoi semplicemente usare la copia nativa del terminale (ad esempio il pulsante centrale del mouse, ctrl+shift+Vin Gnome, cmd+Vsu Mac) se il terminale supporta la pasta tra parentesi. Non premere iper la modalità di inserimento.

Incollerà il contenuto degli appunti del sistema operativo, preservando gli spazi e le schede senza aggiungere autoindenting. E 'corrisponde alla vecchia :set paste, i, ctrl+shift+V, esc, :set nopastemetodo.

Non hai nemmeno più bisogno delle funzionalità di +clipboardo +xterm_clipboardvim installate. Questa funzione è chiamata "incolla tra parentesi". Per maggiori dettagli, consultare /programming/2514445/turning-off-auto-indent-when-pasting-text-into-vim/56781763#56781763

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.