Как я могу сократить список буферов Vim, чтобы включить только активные буферы - PullRequest
8 голосов
/ 04 июня 2010

Как я могу сократить свой список буферов, чтобы включить только те буферы, которые в данный момент открыты в окне / вкладке?

Когда я долгое время запускал Vim, список буферов, показанных командой :ls, слишком велик для работы. В идеале я хотел бы удалить все буферы, которые в данный момент не видны на вкладке или в окне, запустив пользовательскую команду, например :Only. Кто-нибудь может подсказать, как этого добиться?

Похоже, что команда :bdelete может принимать список номеров буферов, но я не уверен, как преобразовать вывод из :ls в формат, который может использоваться :bdelete команда. Любая помощь будет оценена.

Разъяснение

Допустим, в моем сеансе Vim я открыл 4 файла. Команда :ls выводит:

:ls
1  a   "abc.c"
2  h   "123.c"
3  h   "xyz.c"
4  a   "abc.h"

Буфер 1 находится на текущей вкладке, а буфер 4 - на отдельной вкладке, но буферы 2 и 3 скрыты. Я хотел бы запустить команду :Only, и он уничтожит буферы 2 и 3, поэтому команда :ls выведет:

:ls
1  a   "abc.c"
4  a   "abc.h"

В этом примере предложенная команда :Only не выглядит очень полезной, но если у вас есть список из 40 буферов, это было бы очень кстати.

Ответы [ 5 ]

11 голосов
/ 05 июля 2010

Я адаптировал Решение Laurence Gonslaves .

command! -nargs=* Only call CloseHiddenBuffers()
function! CloseHiddenBuffers()
  " figure out which buffers are visible in any tab
  let visible = {}
  for t in range(1, tabpagenr('$'))
    for b in tabpagebuflist(t)
      let visible[b] = 1
    endfor
  endfor
  " close any buffer that are loaded and not visible
  let l:tally = 0
  for b in range(1, bufnr('$'))
    if bufloaded(b) && !has_key(visible, b)
      let l:tally += 1
      exe 'bw ' . b
    endif
  endfor
  echon "Deleted " . l:tally . " buffers"
endfun

Я изменил его на использование bwipeout вместо bdelete и добавил сообщение, чтобы показать, сколько буферов было удалено.

7 голосов
/ 04 июня 2010

Вы ищете:

:echo map(filter(range(0, bufnr('$')), 'bufwinnr(v:val)>=0'), 'bufname(v:val)')

или точнее:

exe 'bw '.join(filter(range(0, bufnr('$')), 'bufwinnr(v:val)<0'), ' ')


РЕДАКТИРОВАТЬ: предыдущий ответ не учитывал несколько вкладок.

Кажется, я использовал комплексный подход. Список открытых и отображаемых буферов можно получить благодаря tabpagebuflist() с:

let tabs = range(1, tabpagenr())
echo lh#list#unique_sort(eval(join(map(tabs, 'tabpagebuflist(v:val)'), '+')))

(lh#list#unique_sort() взято из lh-vim-lib , оно определяет функцию sort + unique, которую vim не предоставляет)

Для того, чтобы иметь не открытые буферы, становится немного сложнее. Либо мы используем цикл каждой вкладки для получения не отображаемых буферов, либо мы делаем различие между предыдущим результатом и буферизирующими буферами:

let tabs = range(1, tabpagenr())
let windowed = lh#list#unique_sort(eval(join(map(tabs, 'tabpagebuflist(v:val)'), '+')))
let existing = filter(range(0,bufnr('$')), 'bufexists(v:val)')
let non_windowed = filter(copy(existing), 'match(windowed, "^".v:val."$")<0')  
echo non_windowed
1 голос
/ 29 марта 2011
" Active Buffers
function ListActive()
    let result = ""
    silent! redir => result
    silent! exe "ls"
    redir END
    let active = ""
    for i in split(result, "\n")
      if matchstr(i, '\m[0-9][0-9]* .a.. ') != ""
        let active .= "\n".i
      endif
    endfor
    echo active
endfunction

например.

Из оболочки:

$ vim -p foo bar baz

Внутри VIM:

:call ListActive()

Выход:

1 %a   "foo"                          line 1
2  a   "bar"                          line 0
3  a   "baz"                          line 0
Press ENTER or type command to continue

Закрыть один файл:

:q

:call ListActive()

Выход:

2 %a   "bar"                          line 1
3  a   "baz"                          line 0
Press ENTER or type command to continue

Открыть другой файл:

:split ~/.vimrc

:call ListActive()

Выход:

2 #a   "bar"                          line 1
3  a   "baz"                          line 0
4 %a   "~/.vimrc"                     line 244
0 голосов
/ 19 мая 2011

Я не использую set hidden, поэтому мое желание закрыть буферы, которые не отображаются ни в одном окне, просто очистить вывод :ls. Эта функция делает именно это:

function! CloseUnloadedBuffers()
    let lastBuffer = bufnr('$')

    let currentBuffer = 1
    while currentBuffer <= lastBuffer
        " If buffer exists, is shown in :ls output, and isn't loaded
        if bufexists(currentBuffer) && buflisted(currentBuffer) && bufloaded(currentBuffer) == 0
            execute 'bdelete' currentBuffer
        endif

        let currentBuffer = currentBuffer + 1
    endwhile
endfunction

Из этой нитью Nabble

0 голосов
/ 04 июня 2010

Если у вас есть, скажем, 4 открытых буфера:

:ls
1    abc.c
2    123.c
3    xyz.c
4    abc.h

и вы хотите "закрыть" буфер 3 "xyz.c":

:bd3

Результаты после удаления буфера 3:

:ls
1    abc.c
2    123.c
4    abc.h
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...