Preferencias de Tab Vs Space en Vim

87

Vim es muy complaciente cuando se trata de tab Vs. preferencias de espacio. Según tengo entendido, la tabstopconfiguración indica el ancho de un carácter de tabulación. La shiftwidthconfiguración especifica cuántas columnas aumentar / disminuir cuando se usan los comandos <<y >>, mientras que la softtabstopconfiguración influye en la cantidad de espacio en blanco que se insertará cuando presione la Tabtecla en el modo de inserción. Si expandtabestá activado, la tecla de tabulación inserta un softtabstopnúmero de caracteres de espacio. Mientras que con expandtabapagado, al presionar la Tabtecla se inserta el menor número posible de caracteres de tabulación + espacio que coincida softtabstop. (Por favor corrígeme si estoy equivocado.)

Este último punto me hace preguntarme: ¿hay algún caso práctico en el que no quisieras shiftwidth == tabstop && tabstop == softtabstop? No puedo pensar en uno. En lo que a mí respecta, sería más conveniente si pudiera establecer los 3 con el mismo valor, en una sola asignación. por ejemplo, llamando:

:set stab=4

que sería equivalente a ejecutar:

:set tabstop=4 softtabstop=4 shiftwidth=4 

¿Alguien puede sugerir cómo se podría hacer esto?


ACTUALIZAR

Gracias por las respuestas hasta ahora de demasiado php , hobbs y kaiser.se . En lugar de responder a cada uno individualmente, estoy actualizando la pregunta aquí.

Softtabstop con la pestaña de expansión apagada

Dije anteriormente que con expandtab desactivado, al presionar la tecla Tab se inserta el menor número posible de caracteres de tabulación + espacio que coincida softtabstop. Lo mantengo, pero creo que necesito explicar lo que quise decir. Intentaré hacerlo mediante algunos ejemplos. Para seguirlo, ejecute :set listpara que pueda ver los caracteres de tabulación.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

En el modo de inserción, al presionar la tecla de tabulación se insertan 2 caracteres de espacio. Presione la tecla de tabulación por segunda vez, y en lugar de insertar dos caracteres de espacio más (para un total de 4 caracteres de espacio), reemplaza los 2 espacios anteriores con un solo carácter de tabulación. Tabstop se establece en 4, por lo que un solo carácter de tabulación tiene el mismo ancho que 4 espacios.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

En el modo de inserción, al presionar la tecla de tabulación se inserta 1 carácter de tabulación más 2 espacios. El carácter de tabulación tiene un ancho de 4, por lo que el ancho total es 6, y esto se logra usando 3 caracteres. Al presionar la tecla de tabulación por segunda vez, se insertan dos caracteres de tabulación y se eliminan los dos espacios que se insertaron anteriormente. El ancho total es 12, y esto se logra usando 3 caracteres.

En ambos ejemplos, Vim inserta el número mínimo posible de caracteres de tabulación + espacio que coincida con softtabstop.

Si estoy trabajando con expandtab desactivado, no puedo imaginarme queriendo el control granular adicional que se puede lograr configurando softtabstop en un valor diferente de tabstop. Todavía sería útil para mí poder establecer tabstop, softtabstopy shiftwidthal mismo valor con un solo comando.

¿Expandtab hace que la función softtabstop sea redundante?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

En el modo de inserción, al presionar la tecla de tabulación se insertan 4 espacios. Al presionar la tecla Eliminar, se elimina un solo espacio, por lo que debe retroceder 4 veces si presiona la tecla Tab por accidente.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

En el modo de inserción, al presionar la tecla de tabulación se insertan 4 espacios. Al presionar la tecla de retroceso se borran 4 espacios.

Si estoy trabajando con expandtabla tecla encendida, preferiría que la tecla de eliminación elimine la misma cantidad de espacios en blanco que la tecla de tabulación inserta. Así pues, en este caso, también, siento que sería útil poder asignar el mismo valor a tabstop, softtabstopy shiftwidthal mismo tiempo.

Un atajo aún sería útil

Es genial que Vim brinde tanta flexibilidad, pero no me veo necesitándolo. Solo quiero poder elegir el ancho de una pestaña, y si es una pestaña 'dura' (usando un carácter de pestaña) o una pestaña 'blanda' (formada por espacios). Alternar entre pestañas duras y blandas es bastante fácil ( :set expandtab!), pero desearía que fuera más sencillo establecer el ancho de la pestaña, sin tener que jugar con 3 parámetros diferentes.

Entonces, mi sugerencia propuesta para algo como :set stab=4todavía me suena bien.

Nelstrom
fuente
Parece que tiene dos preguntas diferentes aquí, tal vez debería dividir su pregunta en dos.
Greg Hewgill
¡Tienes razón! He movido la segunda pregunta a un tema propio.
nelstrom
1
Esto parece más una RFE que una pregunta. Como tal, probablemente debería proponer a la comunidad VIM: vim.org/community.php - o simplemente escribir un parche. Aparte de eso, VIM tiene una extensa función de macro que le permite definir nuevas operaciones, por lo que es muy probable que simplemente pueda crear una macro que haga lo que desee.
kdgregory
@nelstrom Con respecto a su pregunta is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?, el propio código fuente de Vim usa set shiftwidth=4 tabstop=8 noexpandtab. Sí, normalmente uno quiere shiftwidth == softtabstop, pero eso es independiente del valor que tabstoptenga.
jamessan

Respuestas:

56

Crear una stabopción en Vim en sí no sería fácil, pero he creado este comando / función que puede colocar en su .vimrc(o en un archivo de complemento si está súper organizado). Use :Staby se le pedirá un nivel de sangría y si debe usarlo o no expandtab. Si presiona Intro sin darle un nuevo nivel de sangría, simplemente imprimirá la configuración actual.

"Pon todo esto en tu .vimrc o en un archivo de complemento
¡mando! -nargs = * Stab call Stab ()
¡función! Puñalada()
  let l: tabstop = 1 * input ('set shiftwidth =')

  si l: tabstop> 0
    "¿También queremos expandtab?
    let l: expandtab = confirm ('¿establecer expandtab?', "& Sí \ n & No \ n & Cancelar")
    si l: expandtab == 3
      "abortar?
      regreso
    terminara si

    let & l: sts = l: tabstop
    let & l: ts = l: tabstop
    let & l: sw = l: tabstop

    si l: expandtab == 1
      setlocal expandtab
    más
      setlocal noexpandtab
    terminara si
  terminara si

  "mostrar las opciones seleccionadas
  tratar
    echohl ModeMsg
    echon 'set tabstop ='
    pregunta echohl
    echon & l: ts
    echohl ModeMsg
    echon 'shiftwidth ='
    pregunta echohl
    echon & l: sw
    echohl ModeMsg
    echon 'sts ='
    pregunta echohl
    echon & l: pts. ''. (& l: et? '': 'no')
    echohl ModeMsg
    echon 'expandtab'
  finalmente
    echohl Ninguno
  endtry
función final
demasiado php
fuente
3
¡Gracias por el guión! Hace más de lo que pedí, creo que preferiría mantener la pestaña de expansión fuera de ella, pero puedo personalizarla fácilmente a mi gusto. Me proporcionó un pequeño curso intensivo en Vimscript, así que estoy muy agradecido. ¡La recompensa de 100 puntos es tuya!
nelstrom
9

Este es mi primer intento de escribir VimScript, pero aquí va:

function! Stab(value)
    let &shiftwidth  = a:value
    let &softtabstop = a:value
    let &tabstop     = a:value
endfunc

Si pongo esto en mi archivo .vimrc, puedo llamarlo ejecutando :call Stab(X), donde X es el ancho de pestaña deseado. Esta es una solución adecuada por ahora, pero si alguien puede sugerir una forma de facilitar la llamada, se lo agradecería.

También he creado una función que resume rápidamente la configuración actual, que he asignado a ctrl-Tab:

nmap <C-Tab> :call TabParams()<CR>
function! TabParams()
    echo "tabstop:     ".&tabstop
    echo "shiftwidth:  ".&shiftwidth
    echo "softtabstop: ".&softtabstop
endfunc

Bueno, ofrecí una recompensa de 100 puntos por esta respuesta, y ahora la he resuelto a medias. No estoy seguro de poder aceptar mi propia respuesta ...

Nelstrom
fuente
+1 sí, pero si esto es lo que realmente quieres, sigue siendo una buena respuesta.
DaveParillo
2
Probablemente querrá usar let & l: shiftwidth, etc. para configurar las versiones locales.
SystemParadox
7

En el modo de edición, también puede usar Ctrl-Tpara sangrar y Ctrl-Dquitar la sangría al siguiente nivel de sangría según lo establecido por shiftwidth, independientemente de la configuración de tabstop, softtabstopo expandtab. Vim agregará / eliminará automáticamente espacios o pestañas para llevarlo a la columna de la derecha.

Si usa estos comandos para controlar la sangría en lugar de Tab/ Backspace, no tiene que preocuparse de que todas estas configuraciones de pestañas encajen y siempre llegue al nivel de sangría correcto.

algo
fuente
3

Si expandtabse establece entonces (como señala demasiado php), se softtabstopvuelve redundante. La única razón por la que podría establecer de manera shiftwidthdiferente tabstopsería para satisfacer un hábito extraño; por ejemplo, utiliza sangrías de cuatro espacios pero prefiere tabinsertar ocho espacios.

Si no expandtabestá configurado, las cosas se vuelven más confusas. Si desea que su código tenga el mismo aspecto con caty sin editores vim que en vim, entonces tabstopsiempre debe establecerse en 8; en este caso, establecería softtabstopy shiftwidthambos en su nivel de sangría preferido. Si, en cambio, prefiere que cada "pestaña física" en el archivo represente un nivel de sangría, debe establecer tabstopy shiftwidthen su nivel de sangría preferido y dejarlo softtabstopen cero (establecerlo en igual a tabstopes equivalente, excepto que si lo cambia tabstopse desincronizará, mientras que cero solo significa "ignore esto, por favor").

hobbs
fuente
3
Creo que esto es incorrecto porque solo con softtabstopel valor correcto, se eliminará una sangría espaciada como si fuera una pestaña. que es imprescindible para un uso sano.
u0b34a0f6ae
2

Su comprensión de softtabstopy expandtabes incorrecta, por lo que la stabopción que sugiere no sería muy útil.

expandtabes para cuando desee utilizar espacios en lugar de tabulaciones para todo . Si lo configura expandtab, Vim ignora la softtabstopopción y usa tabstopy shiftwidthpara calcular cuántos espacios insertar.

softtabstopes solo para cuando le gustaría usar una combinación de pestañas y espacios, lo que le permite sangrar con un control fino (2 o 4 espacios), mientras mantiene el ancho de la pestaña en un valor más alto (generalmente 8) para que el texto aparezca en las otras aplicaciones . La configuración softtabstop=tabstopno logra nada porque Vim siempre usará pestañas para sangrar.

Actualización: como ha señalado kaizer.se , si está utilizando expandtab, aún debe establecer softtabstopsi desea que Vim retroceda varios espacios como si fueran una pestaña.

demasiado php
fuente
Si bien tiene razón en eso tabstopy se softtabstopconvierte en una variable de más cuando extpandtabse establece, creo que se equivoca en la prioridad. Pruébelo: configúrelo ts=8 sts=4 ety presione el tabulador; el cursor estará en la columna cinco y se insertarán cuatro espacios, como si lo hubiera establecido ts=4 sts=0 et.
hobbs
5
Creo que esto es incorrecto porque solo con softtabstopel valor correcto, se eliminará una sangría espaciada como si fuera una pestaña. que es imprescindible para un uso sano.
u0b34a0f6ae
2

¿Está cambiando la configuración de los espacios en blanco con tanta frecuencia que realmente necesita una función para administrarlo? Si está jugando mucho con tabstop y también configurando expandtab, probablemente tendrá un lío con el tiempo al cambiar archivos con diferentes valores pasados stab. Hoy lo uso :call stab (4), mañana es :call stab (2)y la semana pasada fue :call stab (8). Parece que incluso si lo escribe, pronto dejará de usarlo.

Si planea pasar siempre el mismo valor para apuñalar, ¿por qué no editar su configuración global? En vim:

:e $MYVIMRC

y agregue lo siguiente:

set tabstop=4
set shiftwidth=4  "tabs are 4 spaces wide (default = 8)
set expandtab     "Convert tabs to spaces

Así es como se configura mi .vimrc.

DaveParillo
fuente
1

Una opción útil es softtabstop=-1cuál lo establecerá en el valor de shiftwidth.
También puede establecerlo shiftwidthen 0, en cuyo caso tabstopse utilizará el valor.

Paulue
fuente