Desactivar la sangría automática al pegar texto en vim


1186

Estoy haciendo el esfuerzo de aprender Vim.

Cuando pego el código en mi documento desde el portapapeles, obtengo espacios adicionales al comienzo de cada nueva línea:

line
  line
    line

Sé que puede desactivar la sangría automática, pero no puedo hacer que funcione porque tengo otras configuraciones en conflicto o algo así (que parece bastante obvio en mi .vimrc pero no parece importar cuando las elimino).

¿Cómo desactivo la sangría automática cuando pego el código pero aún tengo la sangría automática vim cuando escribo el código? Aquí está mi .vimrcarchivo:

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  

44
FWIW, vim 8.0.210 agrega soporte nativo para pegar entre corchetes, por lo que evitará sangrar el texto pegado.
sh1

Para archivos nuevos para evitar jugar con vim's paste / nopaste, puede cat > mynewfile.txtpresionar Enter , pegar su texto, presionar Enter nuevamente, y luego Ctr + D para guardar. El archivo ya está creado y puede editarlo con vim mynewfile.txt.
ccpizza

Respuestas:


2066

Actualización: Mejor respuesta aquí: https://stackoverflow.com/a/38258720/62202

Para desactivar el autoindent cuando pega el código, hay un modo especial de "pegar".

Tipo

:set paste

Luego pegue su código. Tenga en cuenta que el texto en la información sobre herramientas ahora dice -- INSERT (paste) --.

Después de pegar su código, desactive el modo de pegado, para que la sangría automática cuando escriba funcione de nuevo correctamente.

:set nopaste

Sin embargo, siempre me pareció engorroso. ¡Es por eso que mapeo de <F3>modo que pueda cambiar entre los modos de pegar y no pegar mientras edito el texto! Agrego esto a.vimrc

set pastetoggle=<F3>

38
Esto no es más fácil que lo :set noaiseguido :set ai. La sugerencia de :r! cates más corta.
Leopd

69
Creo que set pastees más fácil, definitivamente. Es mucho más semántico que noaio incluso noautoindent, lo cual es más importante cuando se escribe "noai" y "pegar" toma aproximadamente la misma cantidad de tiempo insignificante cuando eres lo suficientemente competente como mecanógrafo.
Victor Zamanian

52
:set noaino siempre funciona, dependiendo de cómo se configuren las otras configuraciones relacionadas con sangría según el OP. :set pasteparece ser una abreviatura de varias configuraciones a la vez.
MarkHu

13
Tarde a la fiesta, pero set copyindentse encargará de esto sin problemas.
Matt Ryan

33
:set pastetambién deshabilita otras características como la finalización de llaves, que tampoco se desea al pegar código.
Manuel Faux

263

Para evitar efectos no deseados al pegar, hay una opción que debe configurarse:

set paste

Un comando útil para tener en su .vimrc es set pastetoggle=<F10>o algún otro botón, para alternar fácilmente entre pegar y no pegar.


13
¡Finalmente! Seguí escribiendo: set paste /: set nopaste, ¡qué estúpido! Gracias.
imwilsonxu

44
desde un punto de vista práctico, su respuesta es más útil que la respuesta aceptada
Lynob

8
Otra opción es agregar una macro a su vimrc:nmap <silent> <leader>p :set paste<CR>"*p:set nopaste<CR>
Chris

¡Buena sugerencia @Chris - secuencia de teclas única para pegar sin problemas de sangría!
RichVel

¿Qué pasa si nunca quiero estar en modo pegar? ¿Hay alguna manera de desactivar permanentemente?
maxwell

132

Usualmente uso :r! caty luego pego ( shift + insert )el contenido, y CTRL+D.

No es necesario habilitar y deshabilitar, uso directo.


Me gusta esta opción de uso directo. Sin embargo, todavía estoy aprendiendo a leer la sintaxis vim en las páginas web. ¿Qué significan tus pasos? En particular, suponiendo que tengo algo en el portapapeles del sistema, ¿qué presiono para pegarlo en un documento en vim?
jvriesem

99
Esta respuesta sería más útil con información sobre por qué y cómo :r! catfunciona.
K Erlandsson

11
@KErlandsson, :rinserta el contenido de un archivo en el documento actual. !catdice, ejecute cat que esencialmente abre stdin (* nix shells) (shift + insert)o para algunos terminales, el clic derecho del mouse pegará el contenido del portapapeles en el terminal al CTRL+Dfinal del archivo, por lo que cerrará la :r !catsesión.
Daniel

¿Es esto 'directo' realmente? ¿Que establecer una opción pastehecha únicamente para este propósito? @jvriesem Esta no es una opción 'directa', si lo que supongo de su comprensión de esa palabra es correcto.
0xc0de

También puede usar :r! catluego CTRL+SHIFT+Vpara pegar en el terminal (entonces CTRL+D).
Paul Rougieux el

86

Si está trabajando localmente, puede pegar desde el portapapeles del sistema con la secuencia de teclas:

"+p

Este es un comando vim adecuado, por lo que no debe preocuparse por ingresar al modo de inserción o desactivar primero el autoindent.

Por supuesto, si está trabajando de forma remota (consola sobre SSH, por ejemplo), entonces esto no funcionará y debe ir al :set noaimodo de inserción, pegar en la consola, dejar el modo de inserción, :set aienrutar como se describe en otro lugar.


10
Escribí esta respuesta hace mucho tiempo. Hoy en día lo uso :set pastey, en :set nopastecambio, porque a pesar de ser más largo, ¡es más fácil de recordar y no tengo que buscarlo siempre!
thomasrutter

66
En algunos sistemas embebidos (basados ​​principalmente en busybox) :set pasteno está implementado, por lo que :set noaidebe usarse en su lugar.
jcarballo

Cuando tiene que copiar un texto grande, ¿no es más rápido usar el registro + en su lugar?
pedromanoel

1
@pedromanoel que solo funciona cuando se trabaja localmente. No funcionará accediendo a vim a través de SSH, por ejemplo, si copió algo localmente y desea pegarlo en vim que está en su sesión SSH.
thomasrutter

1
@thomasrutter pero mapeé esto a <leader>p... ¡muy útil!
Dane

51

Si bien configurar el modo pegar con paste/nopaste/pastetoggleestá perfectamente bien, aún debe habilitar manualmente el modo pegar antes de pegar y deshabilitar el modo pegar después de pegar. Siendo la persona perezosa que soy, a continuación es la mejor solución que he encontrado hasta ahora, que alterna automáticamente el modo de pegar cuando pegas.

Aquí hay un pequeño truco que usa el modo de pegado entre corchetes del terminal para establecer / deshabilitar automáticamente el modo de pegado de Vim cuando pegas. Ponga lo siguiente en su .vimrc:

let &t_SI .= "\<Esc>[?2004h"
let &t_EI .= "\<Esc>[?2004l"

inoremap <special> <expr> <Esc>[200~ XTermPasteBegin()

function! XTermPasteBegin()
  set pastetoggle=<Esc>[201~
  set paste
  return ""
endfunction

Ahora puede pegar sin activar / desactivar explícitamente el modo pegar: se gestiona automáticamente por usted.

Fuente: Coderwall

Nota: Esta solución no funciona en WSL (Windows 10 Subsystem for Linux). Si alguien tiene una solución para WSL, actualice esta respuesta o agréguela en los comentarios.

Tmux Si se usa tmux, entonces las declaraciones deben tener doble escape. El código para esto también está en Coderwall


Esto es brillante. Sin embargo, una cosa ... Con cada pasta obtengo un carácter "0" (cero) al comienzo de cada pasta. ¿Algún consejo para eso?
Julius Š.

También tenga en cuenta que si usa tmux, entonces necesita doble escape. El código para esto está en el enlace Coderwall en respuesta
Daithí

1
Si es aún más vago y copia pegar el código anterior en su .vimrc, cuide la sangría de la función XTermPasteBegin ().
k1133

Tenía curiosidad por saber cómo funcionaba, así que busqué el Horquillado de pegado y encontré gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing, lo que explica que las variables t_SIy t_EIestán habilitando el horquillado de pegado y deshabilitándolo. Cuando el horquillado de pegado está activado, el texto pegado tiene el prefijo esc[200~seguido de esc[201~.
PatS

37

Los usuarios de Mac pueden evitar el formateo automático leyendo directamente desde el tablero con:

:r !pbpaste

3
Esta es una respuesta asombrosa. Sin embargo, cuando hago esto, oculta el documento (parece que he vuelto a la línea de comando), pero tiene el texto en mi portapapeles. Me indica que presione Intro, así que lo hago, y me devuelve a mi documento sin ningún cambio. ¿Qué pasó y cómo hago lo que dices?
jvriesem

Si solo escribe :.!pbpaste, esto debería funcionar reemplazando la línea actual con la salida del búfer de pegado. En general, vim le permite canalizar datos que están en su archivo actual a otro programa y reemplazar el texto con la salida del comando. Por lo tanto, :1,3!pbpastereemplaza las primeras tres líneas de su archivo con el búfer de pegado. Solía :.!ppjsontomar una cadena JSON muy larga (sin formato JSON) y formatearla y reemplazar la cadena larga con el equivalente formateado. ppjson es solo un script bash que se ejecuta python -m json.tool.
PatS

19

Aquí hay una publicación de alguien que descubrió cómo reasignar el evento de pegado para activar y desactivar automáticamente el modo de pegado. Funciona para mí en tmux / iTerm en MacOSX.


1
Gracias por el consejo. También rastreé un complemento donde la persona ha agrupado funcionalidades similares: stackoverflow.com/a/36512548/255961 .
studgeek

Esto parece causar una cadena de 'eeeeeee' cuando inserto un texto desde mi portapapeles.
John Jiang

16

Agregue esto a su ~/.vimrcy solo tendrá que presionar F2 antes y después de pegar:

set pastetoggle=<F2>

12

Acabo de poner set clipboard=unnamedmi .vimrc. Eso hace que el búfer de pegado predeterminado se asigne al portapapeles de X.

Entonces, si marco un poco de texto en un terminal, simplemente puedo presionar ppara pegarlo en vim. Del mismo modo, puedo tirar cosas en vim (por ejemplo, YYpara tirar la línea actual en el búfer) y hacer clic con el botón central en cualquier ventana para pegarla.

No sé. Me parece muy conveniente.


En mi humilde opinión, esta es la mejor respuesta, no es necesario alternar con F11 (que está preconfigurado por defecto en vim). Esto funciona en el sistema Mac OSX, no sé sobre los demás.
LightMan

9

Al trabajar dentro de una terminal, la pasta vim-bracketed complemento vim manejará automáticamente las pastas sin necesidad de pulsar ninguna tecla antes o después de pegar.

Funciona detectando el modo de pegado entre paréntesis, que es una secuencia de escape enviada por terminales "modernas" compatibles con términos x como iTerm2, gnome-terminal y otros terminales que usan libvte. Como beneficio adicional, también funciona para sesiones tmux. Lo estoy usando con éxito con iTerm2 en una Mac que se conecta a un servidor Linux y estoy usando tmux.


Tenga cuidado con lo que también señala: desafortunadamente, esto significa que también ejecutarán el contenido del búfer de entrada si hay una nueva línea en cualquier cosa que pegue en el terminal.
0xc0de

1
@ 0xc0de, esa cita no es relevante aquí. Eso está hablando de lo que hará un shell cuando no admite el modo de pegado entre paréntesis. Ese es el punto en el modo pegar entre corchetes: evitar que eso suceda.
sh1

Esto funcionó mucho mejor para mí que las otras soluciones. Gracias.
jjj

8

Pegue esto en su ~ / .vimrc y sea feliz:

" enables :Paste to just do what you want
command Paste execute 'set noai | insert | set ai'

Editar: en reflexión, :r !cates un enfoque mucho mejor ya que es corto, semántico y no requiere vimrc personalizado. ¡Usa eso en su lugar!


5

Aunque :pastetoggleo :pastey :nopastedeberían estar funcionando bien (si se implementan, no siempre son como podemos ver en la discusión) Recomiendo encarecidamente pegar usando el enfoque directo "+po "*py leer con "+ro "*r:

Vim tiene acceso a diez tipos de registros ( :help registers) y el interlocutor está interesado en quotestary quoteplusdesde la sección

  1. Selección y caída de registros "*, "+y "~

Utilice estos registros para almacenar y recuperar el texto seleccionado para la GUI. Ver quotestaryquoteplus . Cuando el portapapeles no está disponible o no funciona, se utiliza el registro sin nombre. Para los sistemas Unix, el portapapeles solo está disponible cuando está presente la función + xterm_clipboard. {no en Vi}

Tenga en cuenta que solo hay una distinción entre "* y" + para los sistemas X11.

:help x11-selectionaclara aún más la diferencia de *y +:

                                                  quoteplus quote+

Hay tres selecciones X documentadas: PRIMARIA (que se espera que represente la selección visual actual, como en el modo Visual de Vim), SECUNDARIA (que está mal definida) y CLIPBOARD (que se espera que se use para operaciones de cortar, copiar y pegar) )

De estos tres, Vim usa PRIMARY cuando lee y escribe el registro "* (por lo tanto, cuando las selecciones X11 están disponibles, Vim establece un valor predeterminado para 'portapapeles' de" selección automática ") y CLIPBOARD cuando lee y escribe el registro" + ". Vim no accede a la selección SECUNDARIA.

Ejemplos: (suponiendo los valores de opción predeterminados)

  • Seleccione una URL en modo Visual en Vim. Vaya a su navegador y haga clic en el botón central del mouse en el campo de texto URL. Se insertará el texto seleccionado (¡con suerte!). Nota: en Firefox puede establecer la preferencia middlemouse.contentLoadURL como verdadera en about: config, luego la URL seleccionada se usará al presionar el botón central del mouse en la mayoría de los lugares de la ventana.

  • Seleccione texto en su navegador arrastrando con el mouse. Vaya a Vim y presione el botón central del mouse: se inserta el texto seleccionado.

  • Seleccione un texto en Vim y haga "+ y. Vaya a su navegador, seleccione texto en un campo de texto arrastrando con el mouse. Ahora use el botón derecho del mouse y seleccione" Pegar "en el menú emergente. El texto seleccionado se sobrescribe el texto de Vim. Tenga en cuenta que el texto en el registro "+" permanece disponible cuando se realiza una selección visual, lo que hace que otro texto esté disponible en el registro "*. Eso permite sobrescribir el texto seleccionado.

Me he dado cuenta de que usar el clic medio en vim no parece estropear la sangría, por lo que podría ser una idea
Fuseteam

4

Esto funciona para mí (caso para + registro, lo que uso como buffer de intercambio entre aps):

imap <silent> <S-Insert> <C-O>:set noai<CR><C-R>+<C-O>:set ai<CR>

2

Si está en una Mac, Macvim parece manejarlo bien sin tener que alternar pegar.

instalar brew macvim --override-system-vim


¿Es ese el caso si incluye las directivas de OP en su .vimrcarchivo?
Drew Noakes


1

La forma más rápida que conozco para ir rápidamente al modo de inserción de pegado para un pegado de una sola vez es el intacto de tpope , que presenta yoy yO, presumiblemente, nemotécnicos para "abrir". Solo están documentados en su vimdoc, como:

No se ha proporcionado una alternancia para 'pegar' porque el caso de uso típico de envolver una inserción solitaria es muy derrochador: alternar dos veces, pero solo pegar una vez (YOPO). En su lugar, presione yo o yO para invocar oo O con 'pegar' ya configurado. Al salir del modo de inserción, se establece 'nopaste' automáticamente.


1

Otra forma de pegar es mediante <CR>y soltando el contenido del registro (aquí el registro global). Ver: :h i_ctrl-ry h i_CTRL-R_CTRL-O.

De la documentación de ayuda de vim:
Insert the contents of a register literally and don't auto-indent. Does the same as pasting with the mouse<MiddleMouse>. Does not replace characters! The '.' register (last inserted text) is still inserted as typed.{not in Vi}

Por lo tanto, para pegar contenido en vim sin sangría automática, úselo <CR><CO>*en la mayoría de los sistemas unix.

Nota: esto solo funciona si se compila vim clipboard.



1

Otra respuesta que no vi hasta ahora:

:se paste noai

1

La pasta nativa / pasta entre corchetes es la mejor y más simple desde vim 8(lanzada en 2016). ¡Incluso funciona sobre ssh! (La pasta entre corchetes funciona en Linux y Mac, pero no en Windows Git Bash)

  1. Asegúrese de tener vim 8+ (no necesita las opciones +clipboardu +xterm_clipboard).

    vim --version | head -1

  2. Simplemente use el comando de pegado nativo del sistema operativo (p. Ej. ctrl+shift+VO cmd+V) en modo normal. No presione ipara el Modo Insertar.


Prueba

  1. Copie ( ctrl+shift+Co cmd+C) el resultado de esto (2 líneas con una sangría de tabulación) en el portapapeles del sistema:

    echo -e '\ta\n\tb'

  2. Inicie un vim 8+ limpio con autoindent:

    vim -u NONE --noplugin -c 'set autoindent'

  3. Pegue desde el portapapeles del sistema ( ctrl+shift+Vo cmd+V) en modo normal. No presione ipara el Modo Insertar. El ay bdebe estar alineado con una sola sangría de pestaña. Incluso puede hacer esto mientras se transmite a una máquina remota (la máquina remota necesitará vim 8+).

  4. Ahora intente a la antigua usanza, que autoindentificará la segunda línea con una pestaña adicional: presione ipara Insertar Modo. Luego pegue usando ctrl+shift+Vo cmd+V. Los ay bestán desalineados ahora.


Instalar Vim 8


1
mejor y más simple! Además, Google lo sugirió Featured snippetpara mi búsqueda 'pegar contenido sin pestañas vim', tal vez porque usé la palabra clave 'tab', solo en esta respuesta mencionada :)
David

0

Lamentablemente, encontré que el complemento vim mencionado no funciona con iTerm2 3.0.15 (para ser justos, no sé si esto se rompió en versiones anteriores), pero encontré este truco.

Mapee el comando-p para pegar y usar las teclas iTerm2 vim. Obviamente, esto solo funciona para iTerm2.

Cómo funciona. Uso "jk" para ingresar al modo de escape, por lo que también necesitarás:

: inoremap jk

en tu .vimrc.

Luego solo invoca P para ingresar al modo pegar, "+ p para pegar desde el portapapeles y luego P para deshabilitar el modo pegar. Hth.

ingrese la descripción de la imagen aquí


1
Espera, ¿usas 'jk' para esto?
0xc0de

Oh sí, me había olvidado de mencionar eso. Simplemente agregue ": inoremap jk <esc>" a su .vimrc. En cuanto a por qué uso jk, pregúntale a Apple y por qué sintieron la necesidad de moverse y deshacerse de la llave de escape física. 8 (
Neil McGill

Por cierto, requiere algo de entrenamiento, pero después de un tiempo, jk se siente más rápido y creo que prefiero ahora antes que escapar ... De todos modos, sería interesante saber si iTerm2 acepta <ESC> aquí también.
Neil McGill el

¡Así se hace Apple!
0xc0de
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.