Nome do arquivo / conclusão do caminho do Vim

10

Eu sei que posso concluir nomes de arquivos / caminhos do diretório atual usando ctrl + x, ctrl + f ( compl-filename). Isso funciona muito bem em combinação com o conjunto autochdir, que altera atualiza o diretório atual para o diretório do buffer ativo.

No entanto, comecei a usar airblade/vim-rooterpara tornar o diretório atual a pasta "projeto". Agora, a conclusão do nome do arquivo sempre começa na pasta do projeto.

A pergunta: Existe uma maneira de fazer a conclusão do nome do arquivo usar o diretório do buffer ativo em vez do diretório atual? Ou alguma outra solução alternativa?

Também solicitado no stackoverflow

Rafael Barbosa
fonte
5
O C-xC-f sempre usa o diretório de trabalho do buffer atual, sem opções para configurá-lo (ele também não é compatível path). Depende do uso pretendido para o vim-rooter. Dependendo do que você deseja dele, poderíamos usar outros plugins. Além disso: eu uso o youcompleteme, que completa os caminhos do diretório do buffer atual se você começar a digitar ./. Veja reddit.com/r/vim/comments/216jdd/…
muru

Respostas:

7

Como o @muru mencionou, não há opções para configurar o diretório a partir do qual concluir os nomes de caminho e arquivo. Ele sempre usa o diretório de trabalho da janela.

Eu escrevi algumas funções e mapeamentos para ajudar nisso. Nos bastidores, eles alteram o diretório de trabalho local (usando :lcd) temporariamente e, em seguida, restauram o diretório de trabalho anterior.

Elefante

Por motivos desconhecidos para mim, chamei este micro-plugin de elefante .

Aqui está o código (copiado da minha configuração do Vim no 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>

Como usá-lo

O uso desses mapeamentos ocorre em 3 etapas.

1. Invoque o mapeamento

No modo Inserir ou no modo de linha de comando, chame o mapeamento usando <C-R><C-E>.

2. Escolha um diretório

Digite um único caractere para escolher de qual diretório raiz você deseja concluir. O código acima fornece dois tipos de raízes:

  • f - O diretório em que o arquivo atual (buffer) reside
  • p - O diretório base do projeto Git ao qual o arquivo atual pertence

3. Digite o caminho ou o nome do arquivo

Você será solicitado a inserir o caminho ou o nome do arquivo em relação ao diretório especificado, com a conclusão disponível. Pressione Enterquando terminar.

Algumas notas

  • Isso não fornece conclusão em linha no modo Inserir, da mesma maneira que <C-X><C-F>faz; em vez disso, você digitará o caminho ou o nome do arquivo no prompt da linha de comando (para onde :vão os comandos). Ao pressionar Enter, o caminho será inserido no buffer.
  • O mesmo acontece no modo de linha de comando, que às vezes pode ser confuso quando você pressiona Entere esquece que ainda precisa pressionar Enterpara emitir o comando que estava digitando.
  • Outras funções de diretório podem ser registradas adicionando-as ao g:elephant_map.
  • O caminho inserido será o caminho completo e absoluto. O script pode ser ajustado para alterar esse comportamento, mas eu não cheguei a isso.
tommcdo
fonte
Não testou completamente a solução, mas a aceitou por causa da integridade. Em vez disso, usei a solução alternativa sugerida : YouCompleteMe em vez de ctrl + x, ctrl + f.
Rafael Barbosa