Vim nombre de archivo / ruta completada

10

Sé que puedo completar nombres de archivo / rutas desde el directorio actual usando ctrl + x, ctrl + f ( compl-filename). Eso funciona muy bien en combinación con set autochdir, que cambia las actualizaciones del directorio actual al directorio del búfer activo.

Sin embargo, comencé a usar airblade/vim-rooterpara hacer del directorio actual la carpeta "proyecto". Ahora la finalización del nombre de archivo siempre comienza desde la carpeta del proyecto.

La pregunta: ¿Hay alguna forma de hacer que la finalización del nombre de archivo use el directorio del búfer activo en lugar del directorio actual? ¿O alguna otra solución?

También preguntado en stackoverflow

Rafael Barbosa
fuente
55
C-xC-f siempre usa el directorio de trabajo del búfer actual, sin ninguna opción para configurarlo (tampoco es compatible path). Depende de cuál sea su uso previsto para vim-rooter. Dependiendo de lo que desee de él, podríamos usar otros complementos. Aparte: uso youcompleteme, que completa las rutas desde el directorio del búfer actual si comienzas a escribir ./. Ver reddit.com/r/vim/comments/216jdd/…
muru

Respuestas:

7

Como @muru mencionó, no hay opciones para configurar el directorio desde el cual completar la ruta y los nombres de archivo. Siempre usa el directorio de trabajo de la ventana.

He escrito un par de funciones y asignaciones para ayudar con esto. Detrás de escena, cambian el directorio de trabajo local (usando :lcd) temporalmente, luego restauran el directorio de trabajo anterior cuando terminan.

Elefante

Por razones desconocidas para mí, he llamado a este micro-plugin Elephant .

Aquí está el código (copiado de mi configuración de Vim en GitHub ):

let g:elephant_map = {
    \ 'f': function('elephant#current_file'),
    \ 'p': function('elephant#vcs_project')
\ }

function! elephant#prompt(base)
    let l:Fcn = get(g:elephant_map, a:base, function('elephant#identity'))
    let l:basedir = l:Fcn()
    execute 'lcd' l:basedir
    let l:file = fnamemodify(input(l:basedir.'/', '', 'file'), ':p')
    lcd -
    return fnamemodify(l:file, ':.')
endfunction

function! s:elephant_init()
    let l:base = getchar()
    return elephant#prompt(nr2char(l:base))
endfunction

function! elephant#identity()
    return '.'
endfunction

function! elephant#vcs_project()
    return fnamemodify(finddir('.git', '.;'), ':h')
endfunction

function! elephant#current_file()
    return expand('%:h')
endfunction

inoremap <silent> <expr> <C-R><C-E> <SID>elephant_init()
cnoremap <silent> <C-R><C-E> <C-R>=<SID>elephant_init()<CR>

Cómo usarlo

El uso de estas asignaciones se realiza en 3 pasos.

1. Invocar el mapeo

En el modo de inserción o en el modo de línea de comandos, invoque el mapeo utilizando <C-R><C-E>.

2. Elija un directorio

Escriba un solo carácter para elegir desde qué directorio raíz desea completar. El código anterior proporciona dos tipos de raíces:

  • f - El directorio en el que reside el archivo actual (búfer)
  • p - El directorio base del proyecto Git al que pertenece el archivo actual

3. Ingrese la ruta o el nombre del archivo

Se le pedirá que ingrese la ruta o el nombre de archivo relativo al directorio especificado, con finalización disponible. Presione Entercuando haya terminado.

Algunas notas

  • Esto no proporciona la finalización en línea en el modo Insertar como lo <C-X><C-F>hace; en su lugar, escribirá la ruta o el nombre del archivo en la línea de comandos (donde :van los comandos). Al presionar Enter, la ruta se insertará en el búfer.
  • Lo mismo es cierto en el modo de línea de comandos, que a veces puede ser confuso cuando golpeas Entery olvidas que aún tienes que golpear Enterpara emitir cualquier comando que estés escribiendo.
  • Se pueden registrar otras funciones de directorio agregándolas a g:elephant_map.
  • La ruta insertada será la ruta completa y absoluta. El guión se puede modificar para cambiar ese comportamiento, pero no lo he logrado.
tommcdo
fuente
No probé la solución, pero la acepté por su integridad. En su lugar, utilicé la solución alternativa sugerida : YouCompleteMe en lugar de ctrl + x, ctrl + f.
Rafael Barbosa