Jak mogę zamknąć bufor bez zamykania okna?

120

Wielowarstwowe widoki Vima (Windows, bufory i karty) wprawiły mnie w trochę zagubienia. Powiedzmy, że podzielę ekran (: sp), a następnie wybieram inny bufor do wyświetlenia w każdym oknie. Teraz chcę zamknąć jeden z buforów, ale nie chcę, aby okno się zamykało (po zamknięciu może wyświetlić następny bufor na liście lub pusty bufor, to nie ma znaczenia). W jaki sposób mogę to zrobić?

Dzięki.

Mosh
źródło
Czy jest jakiś powód, dla którego chcesz zamknąć bufor, zamiast go już tam nie widzieć?
rampion
9
Właściwie to też się nad tym zastanawiałem. Usunięcie bufora i konieczność późniejszego odbudowania jakiejkolwiek części moich podziałów, które zostały zniszczone w trakcie tego procesu, jest denerwujące.
brettkelly
3
Jak dotąd 29 głosów w górę. Myślę, że jest to dość powszechny przypadek użycia. Potrzebuję tego, gdy pracuję z wieloma buforami. Czasami używam 2 okien i chcę zamknąć bufor. Nie chcę, żeby to okno zniknęło. Chcę tylko, aby następny bufor był tam wyświetlany.
Wilson Freitas,
możliwy duplikat Vima: Usuń bufor bez utraty podzielonego okna
George Hilliard

Odpowiedzi:

145

Trochę się z tym pogodziłem i w końcu wymyśliłem:

:bp | sp | bn | bd

Oto wersja kopiuj / wklej do mapowania klawiszy:

:bp<bar>sp<bar>bn<bar>bd<CR>

Sporo go przetestowałem i działa niezmiennie w różnych warunkach. Użyty na ostatnim buforze pozostawi nowy pusty bufor.

Wrzuć to do swojego .vimrc:

map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>

Zrestartuj Vima lub po prostu, :source ~/.vimrcaby zmiany odniosły skutek. Następnym razem, gdy chcesz zamknąć bufor, po prostu wpisz: \q(jeśli \jest to twój klucz lidera)

Jonah Braun
źródło
1
Dziękuję Ci! Ładne i proste, w przeciwieństwie do prawie każdego innego rozwiązania, które widziałem.
jwd
16
Dla początkujących, rzuć to w swoim .vimrc : map <leader>q :bp<bar>sp<bar>bn<bar>bd<CR>. Zrestartuj VIM, następnym razem, gdy chcesz zamknąć bufor, po prostu wpisz:\q
EasyCo
5
Będzie to miało nieoczekiwany wynik, jeśli masz okno podzielone w pionie. W rzeczywistości każda konfiguracja podziału okna inna niż standardowa (utworzona przez sp).
hitzg
2
Myślę, że fragment tego, co należy umieścić w .vimrc, nie powinien zawierać kropki na końcu. Poza tym super! To powinna być akceptowana odpowiedź.
Ernesto
3
to jest eleganckie. jak powiedzieli inni ludzie, jeśli używasz głównie podziałów pionowych, przełącz spsię na vsp. mój wpis .vimrc wygląda tak:cnoremap bd bp<bar>vsp<bar>bn<bar>bd
Connor,
38

Szukałem tego dzisiaj i wymyśliłem

:b#|bd#

co zmienia bieżące okno na poprzednio otwarty bufor i usuwa / ukrywa bufor, z którego właśnie się wyłączyłeś.

Wymaga to co najmniej dwóch znanych buforów.

Jeśli inne okno, ale bieżące, pokazuje ten sam bufor, nadal zniszczy to podział. Możesz zmienić wszystkie okna na poprzednio otwarty bufor za pomocą

:windo b#

Dodałem więcej szczegółów na temat poprzedniego polecenia, omawiając jego mapowanie (i niektóre pułapki) w odpowiedzi na podobne pytanie .

ważny
źródło
Można to również zrobić ... :#b|#bdWystarczy zamienić polecenie bufora i numer bufora w powyższym.
Ashish
Używałem tego trochę, ale denerwowałem się, że ponownie otworzył poprzednio zamknięty bufor.
pean
@pean Właśnie o tym wspomniałem w połączonej odpowiedzi - zobacz „Ważne uwagi”. Tak, byłoby lepiej, gdyby to przełączyło się na inny otwarty bufor.
ważny
1
Można również zrobić :bn|bd#albo :bp|bd#zamiast przejść do poprzedniego lub następnego otwartej bufora, odpowiednio, zamiast niż bufor ty ostatnio obejrzano (B #).
pavon
12
nmap <leader>d :bprevious<CR>:bdelete #<CR>

Działa tak, jak powinno, dopóki jeden bufor nie zostanie otwarty w kilku oknach. Wystarczająco dobre, chyba że chcesz używać większych skryptów.

Edycja: tego właśnie teraz używam:

function! BufferDelete()
    if &modified
        echohl ErrorMsg
        echomsg "No write since last change. Not closing buffer."
        echohl NONE
    else
        let s:total_nr_buffers = len(filter(range(1, bufnr('$')), 'buflisted(v:val)'))

        if s:total_nr_buffers == 1
            bdelete
            echo "Buffer deleted. Created new buffer."
        else
            bprevious
            bdelete #
            echo "Buffer deleted."
        endif
    endif
endfunction
ggustafsson
źródło
1
Próbowałem w ten sposób, ale nie działało to zbyt dobrze podczas korzystania z wielu podzielonych okien. Oto moje rozwiązanie, jeśli ktoś ma ten sam problem:nmap <leader>d :ene<CR>:bd #<CR>
caio
7

Myślę, że właśnie tego szukasz

http://www.vim.org/htmldoc/windows.html#window-moving

Spróbuj tego:

Sprawdź swój identyfikator bufora za pomocą

:buffers

zobaczysz tam listę buforów

1  a.cpp
2  b.py
3  c.php

jeśli chcesz usunąć b.py z bufora

:2bw

jeśli chcesz usunąć / zamknąć wszystkie bufory

:1,3bw
nie
źródło
1
Nie chcę przesuwać okna. Chcę zamknąć bufor bez dotykania pozycji, rozmiaru lub istnienia okna.
Mosh
5

Dla tych, którzy używają NERDTree.

Naprawiam to za pomocą tej wtyczki https://github.com/jistr/vim-nerdtree-tabs i teraz mogę zamknąć jedyny buff / plik / kartę bez zamykania okna.

Po zainstalowaniu powyższej wtyczki umieść następujący kod na moim .vimrc:

let g:nerdtree_tabs_autoclose=0

Opis powyższej zmiennej to: Zamknij bieżącą kartę, jeśli jest w niej tylko jedno okno i jest to NERDTree (domyślnie 1)

Więcej informacji tutaj: https://github.com/jistr/vim-nerdtree-tabs#configuration

Lucas Serafim
źródło
2

Nie sądzę, aby można to zrobić w jeden sposób, ale możesz to zrobić :enewlub :lswyświetlić listę buforów i zamienić na inny za pomocą :b [number].

Gdy masz inny bufor w oknie :bd #, usuniesz poprzedni bufor w oknie, a ponieważ bieżący bufor nadal istnieje, okno nie zostanie zamknięte.

Andrew Khosravian
źródło
2

Zwykłem używać :

:bp<bar>sp<bar>bn<bar>bd<CR>

Ale znalazłem pewne sytuacje, w których zamykało moje okno.

Niedawno zauważyłem, że zawsze używam tego, gdy pracuję nad projektem i muszę szybko otworzyć mój .tmux.conf .zshrcprzed powrotem do pracy.

W tym przypadku uważam, że lepiej:

  • przełącz się z powrotem na bufor, nad którym wcześniej pracowałem C-6
  • wpisać :bd#, aby usunąć poprzedni bufor (Mam odwzorowane to tak: nnoremap <leader>d :bd#<CR>)

Pozwala mi kontrolować bufor, do którego wracam, i jest bardziej naturalny.

DaftWooly
źródło
1

By

:enew

rób co chcesz? będzie edytować nowy, nienazwany bufor w bieżącym oknie, pozostawiając istniejący plik otwarty w innych oknach.

mikej
źródło
Otworzy się nowy pusty bufor. Chcę zamknąć bieżący bufor bez zamykania okna.
Mosh
1

Moim ulubionym rozwiązaniem jest wtyczka bufkill.vim ( GitHub ). Udostępnia alternatywne wersje różnych :bpoleceń -prefix, które działają tak samo, jak ich odpowiedniki, ale pozostawiają otwarte okno. Wyświetlają ostatni widoczny bufor lub pusty / nowy bufor, jeśli nie było poprzedniego bufora.

Z dokumentacji:

Jeśli chcesz wyładować / usunąć / wyczyścić bufor, użyj:
  : bun /: bd /: bw, aby również zamknąć okno (polecenie vim) lub
  : BUN /: BD /: BW, aby pozostawić okno (a) nienaruszone (ten skrypt).
Jim Stewart
źródło
1

Aby „zamknąć” widok, użyj :hid[e]. Działa, jeśli udało ci się podzielić rzutnię lub otworzyć wiele plików. Nie możesz ukryć ostatniego bufora na wyświetlaczu.

1 Kolejna wskazówka, która mi pomogła: użyj, :e ./path/to/file.workaby otworzyć plik w rzutni bez dzielenia okna.

PS Po dwóch dniach od uruchomienia Vima nadal mam problem ze znalezieniem dokładnych poleceń pomocy. Miejmy nadzieję, że pomoże to komuś innemu pracować, dopóki naprawdę nie będzie miał czasu na zrozumienie vima.

Sennekuyl
źródło
1

Oto bardzo czytelna funkcja vimscript, która dobrze obsługuje wszystkie przypadki ,

  • zachowują się podobnie do wbudowanych :bd(jeśli tylko jedno okno, po prostu je wywołaj!),
    • wydaje ostrzeżenie i nie rób nic, jeśli bufor zostanie zmodyfikowany.
    • jeśli nie ma innego bufora, utwórz go za pośrednictwem :enew.
    • jeśli alternatywny bufor istnieje i jest w buffer-list, przełącz się na niego, w przeciwnym razie przejdź dalej, przez :bn.
  • bardziej rozsądne zachowanie w przypadku układu wielu okien
    • nie zamykanie żadnego okna,
    • zawsze pozostań w oryginalnym oknie.
    • dla każdego okna wyświetlającego bieżący bufor wykonaj czynności wymienione powyżej, a następnie usuń stary bieżący bufor.
nnoremap <Leader> b: call DeleteCurBufferNotCloseWindow () <CR>

func! DeleteCurBufferNotCloseWindow () przerwano
    jeśli & zmodyfikowano
        echohl ErrorMsg
        echom "E89: brak zapisu od ostatniej zmiany"
        echohl Brak
    elseif winnr ('$') == 1
        bd
    else ”wiele okien
        niech oldbuf = bufnr ('%')
        niech oldwin = winnr ()
        podczas gdy 1 "wszystkie okna wyświetlające oldbuf pozostaną otwarte
            jeśli buflisted (bufnr ('#'))
                b#
            jeszcze
                bn
                niech curbuf = bufnr ('%')
                if curbuf == oldbuf
                    enew "oldbuf jest jedynym buforem, utwórz go
                endif
            endif
            niech win = bufwinnr (oldbuf)
            jeśli wygrana == -1
                przerwa
            else ”są inne okna, które wyświetlają oldbuf
                exec win 'wincmd w'
            endif
        koniec
        "usuń oldbuf i przywróć okno do oldwin
        exec oldbuf 'bd'
        exec oldwin 'wincmd w'
    endif
endfunc
qeatzy
źródło
0

Jeśli jesteś podobny do mnie i przyszedłeś tutaj, próbując zrobić odwrotnie , zamknij okno bez zamykania bufora, możesz to zrobić za pomocą:

:close

xdhmoore
źródło
0

Prosta wersja, której osobiście używam, to

:bp|bd#

Przechodzi do poprzedniego bufora i usuwa drugi bufor (który w rzeczywistości jest oryginałem, z którego skoczyliśmy). Robi to, czego można się spodziewać w 99% przypadków bez żadnych skomplikowanych skryptów.

Jako skrót klawiaturowy używam następującego

nnoremap <silent> <Leader>c :bp<BAR>bd#<CR>
Dorian B.
źródło
-5

użyj ": bd" jako polecenia.

Silvanus
źródło