Qual é a maneira mais eficiente de usar buffers?

13

Ultimamente, tenho reduzido drasticamente o número de plugins que estou usando, então estou procurando respostas usando apenas os recursos internos do Vim.

Tenho notado uma falha no meu fluxo de trabalho quando estou editando muitos buffers: estou em um buffer e quero mudar para outro que não lembro o nome e que não é o buffer alternativo . Portanto, o uso :b#não é possível e o uso da conclusão com o comando :btambém não é conveniente.

Para fazer isso, eu estava fazendo o seguinte:

  • Primeiro uso :bufferspara obter a lista de buffers abertos
  • Lembre-se do número do buffer que eu quero usar
  • Pressione Enterpara fechar a lista de buffers
  • Use :bXcom Xo número do buffer a ser usado.

Esse fluxo de trabalho me pareceu bastante pesado, então adicionei as seguintes linhas ao meu .vimrc:

" Improve the navigation in the buffers 
nnoremap <Leader><S-b> :B<CR> 
command! B call Buffers() 

function! Buffers() 
    execute "buffers" 
    let buffer=input("Enter a buffer:") 
    execute "b" . buffer 
endfunction 

Isso me dá um comando :B(e um mapeamento) que chama a função :bufferswait for a input e, finalmente, chama :bseguido pela entrada.

Funciona bem, mas estou surpreso por ter desenvolvido essa função: normalmente o Vim tem um fluxo de trabalho padrão bastante eficiente, por isso estou me perguntando se existe uma maneira melhor de mudar para um buffer do qual não sei nada exceto que ele já foi aberto na minha sessão de edição.

statox
fonte
3
Eu sigo :lsseguido :b#(não precisa pressionar return ou escape primeiro, pode ir diretamente da lista de buffers em 'ls'.) (Publicando como comentário porque não parece substancial o suficiente para ser uma resposta? 'estou faltando alguma coisa e respondendo a pergunta errada).
LindaJeanne
2
@LindaJeanne: Como eu disse, :b#não é o que estou procurando, mas sim, o fato de que você pode salvar um pressionamento de tecla digitando diretamente :bsem pressionar enterantes é interessante. (Na verdade, que é talvez leve demais para ser uma resposta, mas valeu a pena um comentário :-))
statox
Estou supondo que LindaJeanne quis dizer o #personagem como substituto de um número (buffer), em vez do #caractere literal .
precisa saber é o seguinte

Respostas:

12

Tenho notado uma falha no meu fluxo de trabalho quando estou editando muitos buffers: estou em um buffer e quero mudar para outro que não lembro o nome e que não é o buffer alternativo . Portanto, o uso :b#não é possível e o uso da conclusão com o comando :btambém não é conveniente.

Pelo contrário, acho o preenchimento de guias extremamente conveniente. Definir as opções corretas para valores que funcionem para você pode ajudar muito. Estas são as linhas relevantes da minha vimrc (elas funcionam para mim, mas podem não funcionar para você, portanto, não as copie) :

nnoremap ,b :buffer *
set wildmenu
set wildignore+=*.swp,*.bak
set wildignore+=*.pyc,*.class,*.sln,*.Master,*.csproj,*.csproj.user,*.cache,*.dll,*.pdb,*.min.*
set wildignore+=*/.git/**/*,*/.hg/**/*,*/.svn/**/*
set wildignore+=*/min/*,*/vendor/*,*/node_modules/*,*/bower_components/*
set wildignore+=tags,cscope.*
set wildignore+=*.tar.*
set wildignorecase
set wildmode=full

Com isso, o buffer correto raramente fica a mais de cinco ou seis teclas:

conclusão de tabulação


Isso me dá um comando :B(e um mapeamento) que chama a função :bufferswait for a input e, finalmente, chama :bseguido pela entrada.

Barry Arthur surgiu com uma solução muito mais simples anos atrás, que se tornou bastante popular desde então:

nnoremap <leader>b :ls<CR>:b<Space>

dos quais propus uma variante um pouco mais versátil há alguns anos:

nnoremap gb :ls<CR>:b

gb


Como estamos falando de vimscript, aqui está uma pequena função interessante que escrevi que "preenche automaticamente" a linha de comando com o stub de comando correto, após comandos do tipo lista, como :lsou :ilist. A vantagem dessa função sobre os mapeamentos acima é que não preciso me lembrar de mapeamentos específicos. Funciona exatamente como o Vim, mas com um pequeno toque .

" smooth listing
cnoremap <expr> <CR> <SID>CCR()

function! s:CCR()
    if getcmdtype() == ":"
        let cmdline = getcmdline()
            if cmdline =~ '\v\C^(dli|il)' | return "\<CR>:" . cmdline[0] . "jump  " . split(cmdline, " ")[1] . "\<S-Left>\<Left>"
        elseif cmdline =~ '\v\C^(cli|lli)' | return "\<CR>:silent " . repeat(cmdline[0], 2) . "\<Space>"
        elseif cmdline =~ '\C^changes' | set nomore | return "\<CR>:sil se more|norm! g;\<S-Left>"
        elseif cmdline =~ '\C^ju' | set nomore | return "\<CR>:sil se more|norm! \<C-o>\<S-Left>"
        elseif cmdline =~ '\C^ol' | set nomore | return "\<CR>:sil se more|e #<"
        elseif cmdline =~ '\C^undol' | return "\<CR>:u "
        elseif cmdline =~ '\C^ls' | return "\<CR>:b"
        elseif cmdline =~ '/#$' | return "\<CR>:"
        else | return "\<CR>" | endif
    else | return "\<CR>" | endif
endfunction

ccr


Dito isto, sou um grande defensor da "navegação baseada em símbolos" sobre a "navegação baseada em arquivos". Quando aplicável, a navegação baseada em símbolos é muito mais rápida e muito mais econômica que a navegação baseada em arquivos.

O último GIF mostra um meio de navegação baseada em símbolos, a propósito. O exemplo é bobo, mas ... tudo bem.

romainl
fonte
Acho que não joguei o suficiente com as wild*opções, tentarei ajustá-lo do meu jeito. Sobre a solução de Barry Arthur, é bem próximo da resposta da @ nobe4 que é interessante. Por fim, terei que analisar mais profundamente sua CCR()função para realmente obtê-la, mas ela parece promissora. Obrigado pela sua resposta.
Statox
5
Veja esta minha resposta . Especialmente os quadrinhos.
precisa saber é o seguinte
Definitivamente vou roubar alguns deles!
Statox
7

Encontrei o mesmo problema há algum tempo e encontrei uma solução:

nnoremap <leader>b :buffers<CR>:buffer<space>

Isso abrirá a lista de buffers e, sem ocultá-la, oferece a opção de alternar o buffer.

Eu acho que faz sentido que o Vim não tenha uma opção "listar e selecionar" aqui, essas são duas ações separadas. Mas o Vim é poderoso o suficiente para combinar comando.

Pense nisso como a filosofia do Unix: faça uma coisa e faça bem.

:bufferslista os buffers e :buffer xxxpermite selecionar um.

nobe4
fonte
1
Essa é uma boa maneira de aliviar a função que sugeri na minha pergunta, interessante!
Statox
1
Se quiser tornar o espaço no final mais visível, você pode: nnoremap <líder> b: buffers <CR>: buffer <Space> |
Tyler Durden
1

Por um tempo, usei a técnica do nobe4 assim:

nnoremap <Leader>b :set nomore<Bar>:ls<Bar>:set more<CR>:b<Space>

Então comecei a usar a conclusão de guias com isso (como sugere o romainl)

Mas, mais recentemente, encontrei o método mais rápido com o menor número de pressionamentos de tecla :

{count} CTRL-^

Isso não é tão diferente, :b#<Enter>mas como você diz, você precisa saber o número do buffer!

Por isso, eu executo o plug- in MiniBufExplorer , que exibe uma lista de nomes de arquivos no topo (como quase todos os outros editores). Tenho certeza que existem inúmeras alternativas.

Finalmente, como Ctrl-^é um pouco exagerado para os meus dedos, e essa é uma operação muito comum, mudei-a para Ctrl-E. A implementação para isso não é muito complexa:

nnoremap <C-E> :<C-U>call SwitchToBuffer()<CR>

function! SwitchToBuffer()
  if v:count > 0
    exec v:count . "b"
    return
  endif

  " Whatever you want to do if you didn't provide a count
  " In this case, fall back to nobe4's technique:
  call feedkeys(":ls\n:b ")
endfunction

Portanto, meu atual processo de comutação de buffer é mais ou menos assim:

  1. Veja o MiniBufExplorer
  2. Bater 3 Ctrl-E

Infelizmente, o MBE e o script acima não são embutidos no Vim, como você solicitou. Quando estou em uma máquina remota sem configuração, apenas uso :b [partial]a conclusão de tabulação.

joeytwiddle
fonte