Vim: aplica configurações em arquivos no diretório

103

Como eu especifico as configurações do Vim para todos os arquivos no diretório atual?

A solução ideal seria se o Vim pesquisasse e lesse um .vimrc no diretório atual antes de pesquisar ~ / .vimrc, e aplicasse as configurações lá para toda a árvore.

Eu vi um plugin , mas isso significa que as configurações aplicadas não são transparentes, pois exigem que o plugin seja instalado. Em contraste, uma modeline é transparente, pois independentemente do vimrc de um usuário ou invocação específica do vim, as configurações da modeline serão aplicadas a esse arquivo.

Coisas que eu tentei são

  • colocar um .vimrc no diretório de trabalho
  • :so vimrc no modeline.

Suponho que ambos não funcionam por motivos de segurança. Não preciso de todo o poder de um vimrc; estar vinculado a configurações aceitáveis ​​por um modeline seria suficiente. Meu objetivo é tornar mais fácil para os vimmers adotarem padrões de codificação em um projeto.

Wilhelmtell
fonte

Respostas:

42

Eu sou um defensor da forma de plugins . Por várias razões:

  • Modelines são particularmente limitadas: não podemos definir variáveis ​​(que sintonizam outros (ft) plug-ins, como "as chaves do for-snippet devem estar em uma nova linha?"), Ou chamar funções a partir delas (eu não me limito para os padrões de codificação, também defino o makefile a ser usado, dependendo do diretório atual)
  • DRY : com modelines, uma configuração precisa ser repetida em cada arquivo, se houver muitas coisas para definir ou ajustes para alterar, rapidamente se tornará difícil de manter, além disso, exigirá o uso de um plugin expansor de template ( que você deve considerar se tiver vários vimmers em seu projeto).
  • Nem todo mundo usa o vim para desenvolver. Não quero ser incomodado pelas configurações do editor de outras pessoas, por que devo parasitar as configurações deles?
  • É mais fácil pedir aos vimmers para instalarem um mesmo plugin, em vez de pedir que copiem e colem e mantenham as mesmas linhas em seus .vimrc
  • As configurações podem ser salvas com os outros arquivos de projeto (cvs / svn / git / qualquer)
  • É realmente fácil ter um arquivo de configuração por projeto - com o plugin, eu tenho um arquivo de configuração global para os padrões de codificação do projeto geral e arquivos de configuração específicos para cada subprojeto (que makefile usar, que executável chamar , ...)

BTW, a solução do sth pode ser usada para criar um único arquivo de configuração. Isso é muito semelhante à abordagem do plug-in, exceto que o .vimrc precisa ser parasitado por opções não globais e não suporta arquivos de configuração múltiplos / compartilhados facilmente.

Luc Hermitte
fonte
Percebi que você deve salvar um novo arquivo no caminho antes que ele execute o plugin corretamente
cmcginty
De fato. Esta família de plug-ins apenas define um framework. Você ainda precisa escrever as definições específicas do projeto em um arquivo - que a estrutura irá fornecer automaticamente.
Luc Hermitte
1
Observe que Luc faz um link de seu próprio plugin. Isso parece funcionar muito melhor do que aquele vinculado à pergunta. Obrigado.
dados de
Bem. Eu não sei dizer. Como uso o meu há anos, nunca dei uma olhada de perto nas outras implementações. De vez em quando, recebo um relatório de bug que eventualmente levo em consideração. BTW, minha versão é implementada para ser acionada antes do mu-template para definir variáveis ​​específicas do projeto antes de expandir os modelos (o que é bastante útil para buscar o diretório raiz do projeto atual e removê-lo dos nomes de caminho expandidos)
Luc Hermitte
1
@JasonMcCarrell Minha implementação de local_vimrc e Markus "embear" Braun tem suporte para blacklist, whitelist ... Se você só precisa especificar como o recuo é feito, o plugin EditorConfig-vim seria uma escolha melhor.
Luc Hermitte
91

Você pode colocar algo assim em $VIM/vimrc

autocmd BufNewFile,BufRead /path/to/files/* set nowrap tabstop=4 shiftwidth=4
sth
fonte
1
Isso é recursivo, mas apenas com o *. Se você tentar reduzir para / caminho / para / arquivos / ou / caminho / para / arquivos, não funcionará.
SystemParadox
Isso é ótimo se o seu projeto tem uma árvore de arquivos escritos com "noexpandtab" e outra árvore com todos os arquivos "expandtab" (por exemplo, CodeIgniter). Você pode definir a ação apropriada para os arquivos em cada árvore individualmente com um arquivo de configuração.
user9645
2
Estranhamente, isso não funcionou quando meu caminho incluía um link simbólico; Tive que colocar o caminho completo sem links simbólicos antes que funcionasse.
Dolan Antenucci
Veja a resposta de joseph07 sobre o uso de um "vim confiável" como alternativa, inversão dessa abordagem (.vimrc distribuído versus centralizado).
Nathan Schulte
50

Eu sugiro fortemente não usar set exrc

Mesmo com set secure, sob * nix, vim ainda executará autocommands, shell, et al, se você possuir o arquivo. Então, se por acaso você editar um arquivo nesse tarball, enviei um .vimrccontendo:

autocmd BufEnter * :silent! !echo rm -rf ~/

você provavelmente vai se divertir menos do que eu.

Phen
fonte
6
Isso também é verdade com plug-ins que são executados automaticamente quando o vim é carregado.
Luc Hermitte
31

Essa pergunta é antiga, mas parece uma preocupação bastante natural e persistente.

Minha solução é bem simples. Coloco um .vimrcarquivo no diretório raiz dos meus projetos. A primeira linha do .vimrcarquivo geralmente origina ~/.vimrce, em seguida, adiciona a configuração específica que desejo. Eu alias tvim='vim -u .vimrc'e uso tvimem meus diretórios de projetos pessoais. "tvim" para "vim confiável", o que significa que se eu executá-lo em um diretório com um .vimrcarquivo e algo der errado, não poderei culpar ninguém além de mim mesmo, já que disse explicitamente que confiava nele. Além disso, mantenho um grupo deles armazenado para que às vezes possa simplesmente criar um softlink para aquele que desejo para um tipo específico de projeto.

Joseph07
fonte
1
Essa abordagem é direta e atende perfeitamente às minhas necessidades.
Jinxed em
Quando tento fazer isso source $HOME/.vimrcno meu local .vimrc, o Vim reclama que não consegue encontrar meus plug-ins instalados em todo o sistema (patógeno, neste caso; o execute pathogen#infect()comando sobre meu $HOME/.vimrcfalha com Unknown function ...). Como posso consertar isso?
Nathan Schulte de
20

Colocar um .vimrc no diretório de trabalho na verdade é suportado, apenas desabilitado por padrão. Consulte :h 'exrc'e :h startuppara obter detalhes, a configuração 'exrc'permitirá a leitura .vimrcdo diretório atual.

Também é recomendado ao :set secureusar isso. Isso bloqueia :autocmd, executa o shell e grava comandos .vimrcno diretório atual.

Outra coisa que pode valer a pena é configurar uma sessão ( :h session) com uma visualização e configurações padrão para o projeto.

Dito isso, eu provavelmente escolheria a opção de plug-in detalhada por Luc Hermitte.

séria
fonte
6
Por favor, veja o comentário de phen. Isso pode levar a sérias implicações de segurança.
dados de
11

Para minimizar os riscos de segurança com QUALQUER recurso de "execução automática" para QUALQUER COISA hoje em dia, posso aconselhar você a utilizar os recursos existentes do vim em vez de plug-ins (bagagem de portabilidade)?

Por exemplo.

O arquivo vimrc da minha pasta local é denominado "_gvimrc" (propositalmente). Isso reduz a esperança de pessoas como Phen se divertirem às nossas custas. :-)

No meu arquivo $ VIM / .vimrc, inseri:

if filereadable("_gvimrc")
    source _gvimrc
endif

no fim.

Eu uso "filereadable ()" sobre "fileexists ()", pois o último tem algumas peculiaridades quando torturado com a abertura de vários (10+) arquivos simultaneamente (não tenho certeza do porquê).

Claro, você pode fornecer seu próprio nome de arquivo exclusivo para ofuscar ainda mais os criadores de problemas em potencial. Tal como "_mygvimrc", "_gobbledygook", etc. Você só precisa definir um nome padronizado e fornecê-lo de acordo com o $ VIM / .vimrc. Contar com o vi / vim interno para isso elimina problemas de portabilidade. MAS, NÃO o nomeie .vimrc (ou _vimrc) para evitar sourcing recursivo caso você esteja editando o arquivo $ VIM / .vimrc com o vim posteriormente.

Uso isso desde o Windoze 98SE, através do Windork XP Pro, e agora Windorkier 7 (5+ anos já). Vou marcar uma lista de arquivos .txt no Explorer e, em seguida, usar "Editar com vários Vim", resultando em várias janelas do vim abrindo simultaneamente. Para o meu trabalho, faço isso várias vezes ao dia, diariamente. Todos os arquivos foram tratados com o que eu defini em meu _gvimrc local.

XEQtor
fonte
Aqui, a desconfiança quanto à portabilidade de plug-ins não tem fundamento, já que esses plug-ins local_vimrc (pelo menos o meu) são portáteis (costumava ser mantido em vários sistemas operacionais diferentes, e até mesmo no Windows 95). A questão do risco de segurança também é exagerada: se seguirmos assim, nunca instalaremos nada que facilite nosso trabalho.
Luc Hermitte
Mas, no que me diz respeito, o primeiro problema real é que, com sua abordagem, você tem que trabalhar a partir do diretório exato que contém o arquivo _gvimrc (que é um nome ruim, pois deve conter coisas específicas do gvim). Se o seu projeto é composto por vários diretórios, que podem exigir uma configuração comum, e específicos (no caso de vários módulos), isso mostrará rapidamente suas limitações.
Luc Hermitte
O segundo problema é que você só pode trabalhar em um projeto por vez - se eu quiser trabalhar em OTB, openjpeg e um projeto que integre ambas as bibliotecas, esta solução não me deixará ter uma configuração específica para cada um dos três projetos.
Luc Hermitte
Isso também funciona para carregar em cadeia um arquivo de sintaxe de um diretório local.
maharvey67
2

Supondo que as pessoas não estão adicionando arquivos a cada poucos dias, você provavelmente pode adicionar uma linha de modelo na parte superior de cada arquivo. Na verdade, se o seu sistema de controle de versão permitir, você provavelmente poderá aplicar uma regra que diz que cada arquivo deve ter uma linha de modelo quando for verificado.

Nathan Fellman
fonte
2

Use "editorconfig"

Se os tipos de padrões de codificação que você gostaria de impor estão relacionados ao estilo de indentação, tamanho da guia, formato de arquivo e conjunto de caracteres, você pode querer dar uma olhada em "editorconfig" , que é um padrão de editor cruzado para especificar este tipo de configurações em um projeto específico e faça com que todos os editores sigam essa configuração.

A especificação "editorconfig" permite que os projetos solicitem configurações diferentes dependendo das extensões de arquivo ou nomes dentro do projeto. (Assim, você pode ter Makefiles usando TABs, seus scripts Python usando 4 espaços e seus scripts shell usando 2 espaços para indentação.)

Você precisa de um plug-in para usar "editorconfig" no Vim. O site oficial fornece um, mas pessoalmente eu recomendo sgur / vim-editorconfig , que é escrito em Vimscript puro, então você não precisa se preocupar muito com dependências externas.

Uma vez que "editorconfig" visa a compatibilidade entre editores, é bastante limitado no que faz, então se você quiser espaços em branco consistentes, formato de arquivo (DOS vs. Unix) e codificação (Unicode utf-8, etc.), então "editorconfig " é para você.

Filbranden
fonte
0

Eu olhei para os plug-ins que existiam e realmente não gostei de nenhum deles, então escrevi uma função simples que pega carona no vim-fugitive . A vantagem disso é que ele sabe que a raiz do projeto é sempre a raiz do repositório e, além disso, posso fazer o hash do arquivo para manter uma tabela confiável. Basta colocar o seguinte em seu .vimrcarquivo.

function LoadRepoVimrc()
  let l:path = fugitive#repo().tree('.vimrc')
  if filereadable(l:path)
    let l:sha1 = fugitive#repo().git_chomp('hash-object',l:path)
    if !exists('g:SAFE_VIMRC') | let g:SAFE_VIMRC = {} | endif
    if has_key(g:SAFE_VIMRC,l:path) && g:SAFE_VIMRC[l:path] ==? l:sha1
      execute 'source '.fnameescape(l:path)
    elseif confirm("Trust ".l:path."?", "&Yes\n&No",2) == 1
      let g:SAFE_VIMRC[l:path] = l:sha1
      execute 'source '.fnameescape(l:path)
    else
      execute 'sandbox source '.fnameescape(l:path)
    endif
  endif
endfunction
autocmd User FugitiveBoot call LoadRepoVimrc()
set viminfo ^= !

Se a !opção estiver definida na viminfoconfiguração, o SAFE_VIMRCdicionário será preservado entre as execuções (observe o ^para preceder a opção para não atrapalhar a nopção).

Parakleta
fonte