Preferências Tab Vs Space no Vim

87

O Vim é muito confortável quando se trata de guia vs. preferências de espaço. Pelo que entendi, a tabstopconfiguração indica a largura de um caractere de tabulação. A shiftwidthconfiguração especifica quantas colunas aumentar / diminuir ao usar os comandos <<e >>, enquanto a softtabstopconfiguração influencia a quantidade de espaço em branco a ser inserido quando você pressiona a Tabtecla no modo de inserção. Se expandtabestiver ativado, a tecla tab insere um softtabstopnúmero de caracteres de espaço. Enquanto com expandtabdesligado, pressionar a Tabtecla insere o menor número possível de caracteres de tabulação + espaço que correspondem softtabstop. (Por favor me corrija se eu estiver errado.)

Este último ponto me faz pensar: existe um caso prático onde você não gostaria shiftwidth == tabstop && tabstop == softtabstop? Não consigo pensar em nenhum. No que me diz respeito, seria mais conveniente se eu pudesse definir todos os 3 com o mesmo valor, em uma única atribuição. por exemplo, ligando para:

:set stab=4

o que seria equivalente a executar:

:set tabstop=4 softtabstop=4 shiftwidth=4 

Alguém pode sugerir como isso poderia ser feito?


ATUALIZAR

Obrigado pelas respostas até agora de muito php , hobbs e kaiser.se . Em vez de responder a cada um individualmente, estou atualizando a pergunta aqui.

Softtabstop com expandtab desativado

Eu disse acima que com expandtab desativado, pressionar a tecla Tab insere o menor número possível de caracteres de tabulação + espaço que correspondem softtabstop. Eu mantenho isso, mas acho que preciso explicar o que quis dizer. Tentarei fazer isso por meio de alguns exemplos. Para acompanhar, corra :set listpara que você possa ver os caracteres da guia.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

No modo de inserção, pressionar a tecla tab insere 2 caracteres de espaço. Pressione a tecla tab uma segunda vez e, em vez de inserir mais dois caracteres de espaço (para um total de 4 caracteres de espaço), substitui os 2 espaços anteriores por um único caractere de tabulação. Tabstop é definido como 4, portanto, um único caractere de tabulação tem a mesma largura que 4 espaços.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

No modo de inserção, pressionar a tecla Tab insere 1 caractere de tabulação mais 2 espaços. O caractere de tabulação tem uma largura de 4, portanto, a largura total é 6, e isso é obtido usando 3 caracteres. Pressionar a tecla tab uma segunda vez insere dois caracteres de tabulação e remove os dois espaços que foram inseridos anteriormente. A largura total é 12, e isso é obtido usando 3 caracteres.

Em ambos os exemplos, o Vim insere o número mínimo possível de caracteres de tabulação + espaço que correspondem ao softtabstop.

Se estou trabalhando com expandtab desativado, não consigo me imaginar querendo o controle granular extra que pode ser obtido definindo softtabstop com um valor diferente de tabstop. Ele ainda seria útil para mim ser capaz de definir tabstop, softtabstope shiftwidthcom o mesmo valor com um único comando.

O expandtab torna o softtabstop redundante?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

No modo de inserção, pressionar a tecla tab insere 4 espaços. Pressionar a tecla delete apaga um único espaço - então você tem que voltar 4 vezes se você apertar a tecla tab por acidente.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

No modo de inserção, pressionar a tecla tab insere 4 espaços. Pressionar a tecla Backspace exclui 4 espaços.

Se estou trabalhando com expandtabativado, prefiro que a tecla delete remova a mesma quantidade de espaço em branco que as inserções da tecla tab. Portanto, também neste caso, acho que seria útil poder atribuir o mesmo valor a tabstop, softtabstope shiftwidthsimultaneamente.

Um atalho ainda seria útil

É ótimo que o Vim forneça tanta flexibilidade, mas não consigo me ver precisando disso. Eu só quero ser capaz de escolher a largura de uma guia, e se é uma guia 'rígida' (usando um caractere de tabulação) ou uma guia 'flexível' (composta de espaços). Alternar entre as guias rígidas e flexíveis é bastante fácil ( :set expandtab!), mas eu gostaria que fosse mais simples definir a largura da guia, sem ter que mexer com 3 parâmetros diferentes.

Portanto, minha sugestão proposta para algo como :set stab=4ainda parece boa para mim.

Nelstrom
fonte
Parece que você tem duas perguntas diferentes aqui, talvez você deva dividir sua pergunta em duas.
Greg Hewgill
Você está certo! Mudei a segunda pergunta para um tópico próprio.
nelstrom
1
Isso parece mais um RFE do que uma pergunta. Como tal, você provavelmente deve propor à comunidade VIM: vim.org/community.php - ou simplesmente escrever um patch. Além disso, o VIM possui um amplo recurso de macro que permite definir novas operações, portanto, é muito provável que você possa simplesmente criar uma macro que faça o que deseja.
kdgregory
@nelstrom Em relação à sua pergunta is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?, o código-fonte do próprio Vim usa set shiftwidth=4 tabstop=8 noexpandtab. Sim, normalmente se quer shiftwidth == softtabstop, mas isso é independente de qual valor tabstoptem.
Jamessan

Respostas:

56

Criar uma stabopção no próprio Vim não seria fácil, mas eu criei este comando / função que você pode colocar no seu .vimrc(ou em um arquivo de plugin se você for superorganizado). Use :Stabe será solicitado um nível de indentação e se deve ou não usar expandtab. Se você pressionar Enter sem dar a ele um novo nível de recuo, ele apenas imprimirá as configurações atuais.

"coloque tudo isso em seu .vimrc ou em um arquivo de plugin
comando! -nargs = * Chamada de punhalada Stab ()
função! Facada()
  let l: tabstop = 1 * input ('set shiftwidth =')

  se l: tabstop> 0
    "queremos expandir a tab também?
    let l: expandtab = confirm ('set expandtab?', "& Sim \ n & Não \ n & Cancelar")
    if l: expandtab == 3
      " abortar?
      Retorna
    fim se

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

    se l: expandtab == 1
      setlocal expandtab
    outro
      setlocal noexpandtab
    fim se
  fim se

  "mostra as opções selecionadas
  experimentar
    echohl ModeMsg
    echon 'set tabstop ='
    echohl Pergunta
    echon & l: ts
    echohl ModeMsg
    echon 'shiftwidth ='
    echohl Pergunta
    echon & l: sw
    echohl ModeMsg
    echon 'sts ='
    echohl Pergunta
    echon & l: sts. ''. (& l: et? '': 'não')
    echohl ModeMsg
    echon 'expandtab'
  finalmente
    echohl Nenhum
  endtry
função final
muito php
fonte
3
Obrigado pelo script! Ele faz mais do que eu pedi - acho que prefiro manter o expandtab fora dele - mas posso personalizá-lo facilmente ao meu gosto. Você me forneceu um pequeno curso intensivo em Vimscript, por isso estou muito grato. A recompensa de 100 pontos é sua!
nelstrom
9

Esta é minha primeira tentativa de escrever VimScript, mas aqui vai:

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

Se eu colocar isso no meu arquivo .vimrc, posso chamá-lo executando :call Stab(X), onde X é a largura de tabulação desejada. Esta é uma solução adequada por enquanto, mas se alguém puder sugerir uma maneira de facilitar a ligação, eu ficaria muito grato.

Também criei uma função que resume rapidamente as configurações atuais, que mapeei para ctrl-Tab:

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

Bem, eu coloquei uma recompensa de 100 pontos por essa resposta, e agora já resolvi meio que sozinho. Não tenho certeza se posso aceitar minha própria resposta ...

Nelstrom
fonte
+1 sim, mas se isso é o que você realmente quer, ainda é uma resposta ok.
DaveParillo
2
Você provavelmente vai querer usar let & l: shiftwidth, etc para definir as versões locais.
SystemParadox
7

Você também pode usar o modo de edição Ctrl-Tpara recuar e Ctrl-Drecuar para o próximo nível de recuo conforme definido por shiftwidth, independentemente das configurações tabstop, softtabstopou expandtab. O Vim adicionará / removerá automaticamente espaços ou guias para trazê-lo para a coluna certa.

Se você usar esses comandos para controlar o recuo em vez de Tab/, Backspacevocê não precisa se preocupar com todas essas configurações da guia se encaixando e sempre obter o nível de recuo correto.

sth
fonte
3

Se expandtabfor definido então (como muitos php indicam), softtabstoptorna-se redundante. A única razão pela qual você pode definir de forma shiftwidthdiferente tabstopseria para atender a um hábito estranho; por exemplo, você usa recuos de quatro espaços, mas prefere tabinserir oito espaços.

Se expandtabnão estiver definido, as coisas ficarão mais confusas. Se você deseja que seu código tenha a mesma aparência no catvim e nos editores não-vim, então tabstopsempre deve ser definido como 8; neste caso, você definiria softtabstope shiftwidthambos para seu nível de recuo preferido. Se, em vez disso, você preferir que cada "guia física" no arquivo represente um nível de indentação, você deve definir tabstope shiftwidthpara seu nível de indentação preferido e deixar softtabstopem zero (configurá-lo igual a tabstopé equivalente, exceto que se você alterar tabstopficará fora de sincronia, enquanto zero significa apenas "ignore, por favor").

hobbs
fonte
3
Eu acho que isso está errado porque apenas com softtabstopo valor correto, o backspace deleta um recuo espaçado como se fosse uma tabulação. que é uma obrigação para um uso racional.
u0b34a0f6ae
2

Seu entendimento de softtabstope expandtabestá errado - então a stabopção que você sugeriu não seria muito útil.

expandtabé para quando você deseja usar espaços em vez de tabulações para tudo . Se você definir expandtab, o Vim ignora a softtabstopopção e usa tabstope shiftwidthpara calcular quantos espaços inserir.

softtabstopé apenas para quando você gostaria de usar uma mistura de tabulações e espaços, permitindo que você recue com controle fino (2 ou 4 espaços), enquanto mantém a largura da tabulação em um valor mais alto (normalmente 8) para que o texto apareça em outros aplicativos . A configuração softtabstop=tabstopnão faz nada porque o Vim sempre usará guias para recuar.

Atualização: como kaizer.se apontou, se você estiver usando expandtab, então ainda precisa definir softtabstopse deseja que o Vim retroceda vários espaços como se fossem uma guia.

muito php
fonte
Embora você esteja certo tabstope softtabstopse torne uma variável a mais quando extpandtabestiver definido, acho que você está errado quanto à prioridade. Experimente: configure ts=8 sts=4 ete pressione tab; o cursor estará na coluna cinco, e quatro espaços serão inseridos, como se você tivesse definido ts=4 sts=0 et.
hobbs,
5
Eu acho que isso está errado porque apenas com softtabstopo valor correto, o backspace deleta um recuo espaçado como se fosse uma tabulação. que é uma obrigação para um uso racional.
u0b34a0f6ae
2

Você está alterando suas configurações de espaço em branco com tanta frequência que realmente precisa de uma função para gerenciar isso? Se você está mexendo muito com tabstop e também configurando expandtab, provavelmente terá uma bagunça ao longo do tempo conforme altera arquivos com diferentes valores passados stab. Hoje eu uso :call stab (4), amanhã é :call stab (2)e semana passada foi :call stab (8). Parece que mesmo se você escrever, em breve irá parar de usá-lo.

Se você planeja passar sempre o mesmo valor para o stab, por que não apenas editar suas configurações globais? In vim:

:e $MYVIMRC

e adicione o seguinte:

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

É assim que meu .vimrc é configurado.

DaveParillo
fonte
1

Uma opção útil é softtabstop=-1definir o valor de shiftwidth.
Você também pode definir shiftwidthcomo 0, caso em que o tabstopvalor será usado.

Pauloue
fonte