„Karty” w stylu przeglądarki dla emacsa?

22

Chciałbym zakładek takich jak Firefox, ale dla Emacsa.

Znalazłem to: http://emacswiki.org/emacs/TabBarMode

Ale po prostu dodaje do każdego bufora ( okno w terminologii Emacsa) pasek, który pokazuje aktualnie otwarte bufory.

Chciałbym, aby karta mogła pomieścić wiele buforów ( okna w teminologii Emacsa), które mogę dowolnie podzielić. Tj. Każda zakładka powinna odpowiadać „stanowi okna” (w sensie window-state-get).

Miałbym jedną kartę do moich zadań, drugą do kodu, drugą do czytania w Internecie itp.

czy to możliwe? Czy pasek narzędzi można tak dostosować?

[edit2]
To pytanie przyciągnęło więcej uwagi, niż się spodziewałem. Wygląda na to, że istnieje rozwiązanie, ale takie, które wymagałoby trochę badań i modyfikacji. Podczas gdy ten / następny tydzień jest dla mnie trochę zajęty, przeanalizuję odpowiedzi i spróbuję zbudować coś, co działa, a następnie zmodyfikuję to pytanie, aby odzwierciedlić moje ustalenia. Proszę czekać =)

[edytuj]
Podobne do:
/programming/24157754/make-frames-in-emacs-gui-behaves-like-frames-in-terminal

Osadziłbym także wiele ramek w jednej sesji GUI.

Lew Ufimcew
źródło
2
„Chciałbym, aby karta mogła pomieścić wiele buforów, które mogę dowolnie podzielić”. Masz na myśli wiele okien ?
Malabarba
1
To bardziej, jak chciałbym mieć bardzo dynamiczne zakładki. Chciałbym je utworzyć, a następnie wypełnić je oknami. Tzn. Chciałbym, aby karta była ramką. Następnie nowa karta nowa ramka. Wewnątrz każdej zakładki / ramki mogłem otworzyć żądane okna / (bufory). Czy to jest wykonalne? (Tj. Brak sztywnych nazw buforów itp.)
Leo Ufimcew
1
Z poszczególnymi oknami związana jest zmienna, ale minął miesiąc lub dwa, odkąd widziałem wątek, który o tym mówił i nie wiem, jak to się nazywa. Możesz być zainteresowany użyciem systemu podobnego do buforów ramki, w którym lista zawiera bufory powiązane z ramką i ta lista jest włączona do parametru ramki. Możesz użyć zmiennej powiązanej z określonym oknem i uczynić ją listą, dodawać / usuwać bufory z listy - ta lista byłaby grupą buforów do użycia przez pasek kart. To wszystko jest teoretyczne, ale wierzę, że to zadziała.
prawnik
1
Myślę, że możesz odnieść się do: stackoverflow.com/questions/24157754/... ale ten post nie wydaje się mieć solidnej odpowiedzi: - /
Leo Ufimtsev
1
Poleciłbym rzucić okiem na pakiet elscreen.
blarghmatey

Odpowiedzi:

8

Podziel bufory na grupy

Jest to możliwe dzięki tabulatorowi. Możesz dodać reguły do ​​buforów grupowych w grupach. Oto podstawowy fragment kodu:

(defun tabbar-buffer-groups ()
  "Returns the list of group names the current buffer belongs to."
  (list
   (cond

    ;; ADD RULES TO SPLIT BUFFERS IN GROUPS HERE!

    ;; if buffer is not grouped by the rules you would add above 
    ;; put it in the "General" group:
    (t
       "General"
     ))))

Przykładowe zasady:

  1. Lista nazw buforów:
    ((member (buffer-name)
             '("*scratch*" "*Messages*" "*Help*"))
     "Common" ;; this is a group name
     )
  1. Jeśli chodzi o wspólne bufory, wolę umieszczać w „Common” każdy bufor, którego nazwa zaczyna się od gwiazdki. To daje przykład utworzenia bufora dla tej reguły:
    ((string-equal "*" (substring (buffer-name) 0 1))
     "Common"
     )
  1. Oto przykład grupowania buforów według trybu głównego:
    ((memq major-mode
           '(org-mode text-mode rst-mode))
     "Text"
     )
  1. Oto przykład grupowania buforów na podstawie trybu, z którego pochodzą:
    ((or (get-buffer-process (current-buffer))
         ;; Check if the major mode derives from `comint-mode' or
         ;; `compilation-mode'.
         (tabbar-buffer-mode-derived-p
          major-mode '(comint-mode compilation-mode)))
     "Process"
     )
  1. Oto przykład grupowania kart według wyrażenia regularnego:
    ((string-match "^__" (buffer-name))
     "Templates"
     )
  1. Grupuj bufory według trybu głównego:
    (if (and (stringp mode-name)
                  ;; Take care of preserving the match-data because this
                  ;; function is called when updating the header line.
                  (save-match-data (string-match "[^ ]" mode-name)))
             mode-name
           (symbol-name major-mode))

Po skomponowaniu reguł możesz nacisnąć + lub - na linii tabulatora na pasku kart, aby przełączać grupy, a także ◀ i ▶, aby przełączać między buforami. Lub po prostu powiąż następujące defuns:

tabbar-forward
tabbar-backward
tabbar-forward-group
tabbar-backward-group

i poruszaj się między kartami i grupami kart za pomocą klawiatury.

Osobiście grupuję karty, aby zobaczyć, co jest otwarte, ale nawigować nimi ido-switch-buffer.

Przełączaj między zestawem reguł

Można również zdefiniować inny zestaw reguł grupowania buforów i przełączać między nimi. Oto przykład przełączania między dwoma zestawami reguł grupowania buforów:

;; tab-groups!
(setq tbbr-md "common")
(defun toggle-tabbar-mode ()
  "Toggles tabbar modes - all buffers vs. defined in the `tabbar-buffer-groups'."
  (interactive)
  (if (string= tbbr-md "groups")
      (progn ;; then
        (setq tabbar-buffer-groups-function 'tabbar-buffer-groups-common)
        (setq tbbr-md "common"))
    (progn ;; else
      (setq tabbar-buffer-groups-function 'tabbar-buffer-groups)
      (setq tbbr-md "groups"))))
;; by default - all tabs:
(setq tabbar-buffer-groups-function 'tabbar-buffer-groups-common)

To przełącza pomiędzy tabbar-buffer-groups-commoni tabbar-buffer-groupsgrupowaniem kart odrzuca.

Sortuj bufory tabulatorów według nazw

Uważam, że warto sortować bufory tabulatorów według nazw. Oto jak to zdobyć:

(defun tabbar-add-tab (tabset object &optional append_ignored)
  "Add to TABSET a tab with value OBJECT if there isn't one there yet.
If the tab is added, it is added at the beginning of the tab list,
unless the optional argument APPEND is non-nil, in which case it is
added at the end."
  (let ((tabs (tabbar-tabs tabset)))
    (if (tabbar-get-tab object tabset)
        tabs
      (let ((tab (tabbar-make-tab object tabset)))
        (tabbar-set-template tabset nil)
        (set tabset (sort (cons tab tabs)
                          (lambda (a b) (string< (buffer-name (car a)) (buffer-name (car b))))))))))
Cegła suszona na słońcu
źródło
Dziękuję za szczegółową odpowiedź. Postaram się wypróbować powyższe i dam ci znać ~ ostatecznie :)
Leo Ufimtsev
Ale OP nie chce „jednego paska kart na okno”, chce jednego paska kart na ramkę, a każda karta na pasku kart powinna reprezentować „konfigurację okna” (tj. Kilka okien) zamiast bufora, więc grupowanie buforów nie jest problemem .
Stefan
6

ATRYBUT: Grupowanie buforów na podstawie ramki jest bezpośrednią implementacją pojęć i wybranych części kodu opracowanych / napisanych przez Alp Aker w bibliotece frame-bufs: https://github.com/alpaker/Frame-Bufs

Poniżej znajduje się przykład tabbar.eldynamicznego używania tabulatorów / buforów w bibliotece i grupowania dla poszczególnych klatek poprzez dodawanie tabulatorów / buforów za pomocą C-c C-alub usuwanie tabulatorów / buforów za pomocą C-c C-n. Istnieją tylko dwie (2) grupy - powiązane z bieżącą ramką (tj. "A") I NIE powiązane z bieżącą ramką (tj "N".). Grupy są lokalne dla ramki, co oznacza, że ​​każda ramka może mieć własne grupowanie. Grupowanie niestandardowe można zresetować za pomocą C-c C-r. Przełączaj między grupami powiązanymi i niepowiązanymi z C-tab. Przejdź do następnej karty / bufora w bieżącej grupie za pomocą M-s-right. Przejdź do poprzedniej karty / bufora w bieżącej grupie za pomocą M-s-left.

Tab / bufory można dodawać lub usuwać programowo za pomocą my-add-bufferi my-remove-buffer. Aby zobaczyć przykład otwierania niektórych buforów w wybranych ramkach, zobacz powiązany wątek zatytułowany Jak przechwycić plik przed jego otwarciem i zdecydować, która ramka : /programming//a/18371427/2112489 Funkcja my-add-buffermusiałaby być umieszczane w odpowiednich miejscach kodu w powyższym linku, jeśli użytkownik zdecyduje się na wdrożenie tej funkcji.

Użytkownik może chcieć utworzyć wpis w niestandardowym, mode-line-formatktóry wyświetla nazwę bieżącej grupy kart w wierszu trybu, dołączając następujący fragment: (:eval (when tabbar-mode (format "%s" (tabbar-current-tabset t)))) Dostosowanie wiersza trybu bardziej szczegółowo, jednak wykracza poza zakres tego przykładu.

Funkcja tabbar-add-tabzostała zmodyfikowana, aby alfabetycznie zakładki / bufory.

Funkcja tabbar-line-tabzostała zmodyfikowana, aby zapewnić cztery (4) różne twarze w zależności od sytuacji. Jeśli tab / bufor jest powiązany z ramką i jest wybrany, użyj tabbar-selected-associatedtwarzy. Jeśli tab / bufor jest powiązany z ramką i NIE jest wybrany, użyj tabbar-unselected-associatedtwarzy. Jeśli tab / bufor NIE jest powiązany z ramką i jest zaznaczony, użyj tabbar-selected-unassociatedtwarzy. Jeśli tab / bufor NIE jest powiązany z ramką i NIE jest wybrany, użyj tabbar-unselected-unassociatedtwarzy.

;; Download tabbar version 2.0.1 by David Ponce:
;;   https://marmalade-repo.org/packages/tabbar
;; or use package-install for marmalade repositories.

;; Place tabbar-2.0.1.el in the `load-path` -- it is okay to rename it to tabbar.el
;; or add the directory (where `tabbar.el` resides) to the `load-path`.
;; EXAMPLE:  (setq load-path (append '("/Users/HOME/.emacs.d/lisp/") load-path))

(require 'tabbar)

(setq tabbar-cycle-scope 'tabs)

(remove-hook 'kill-buffer-hook 'tabbar-buffer-track-killed)

(defun my-buffer-groups ()
  "Function that gives the group names the current buffer belongs to.
It must return a list of group names, or nil if the buffer has no
group.  Notice that it is better that a buffer belongs to one group."
  (list
    (cond
      ((memq (current-buffer) (my-buffer-list (selected-frame)))
        "A")
      (t
        "N"))))

(setq tabbar-buffer-groups-function 'my-buffer-groups) ;; 'tabbar-buffer-groups

;; redefine tabbar-add-tab so that it alphabetizes / sorts the tabs
(defun tabbar-add-tab (tabset object &optional append)
  "Add to TABSET a tab with value OBJECT if there isn't one there yet.
If the tab is added, it is added at the beginning of the tab list,
unless the optional argument APPEND is non-nil, in which case it is
added at the end."
  (let ((tabs (tabbar-tabs tabset)))
    (if (tabbar-get-tab object tabset)
        tabs
      (let* ((tab (tabbar-make-tab object tabset))
             (tentative-new-tabset
               (if append
                 (append tabs (list tab))
                 (cons tab tabs)))
             (new-tabset
               (sort
                  tentative-new-tabset
                  #'(lambda (e1 e2)
                     (string-lessp
                       (format "%s" (car e1)) (format "%s" (car e2)))))))
        (tabbar-set-template tabset nil)
        (set tabset new-tabset)))))

;; AUTHOR:  Alp Aker -- https://github.com/alpaker/Frame-Bufs
;; @lawlist extracted/revised the function(ality) from said library.
(defun my-buffer-list (frame)
  ;; Remove dead buffers.
  (set-frame-parameter frame 'frame-bufs-buffer-list
    (delq nil (mapcar #'(lambda (x) (if (buffer-live-p x) x))
      (frame-parameter frame 'frame-bufs-buffer-list))))
  ;; Return the associated-buffer list.
  (frame-parameter frame 'frame-bufs-buffer-list))

(defun my-kill-buffer-fn ()
"This function is attached to a buffer-local `kill-buffer-hook'."
  (let ((frame (selected-frame))
        (current-buffer (current-buffer)))
    (when (memq current-buffer (my-buffer-list frame))
      (my-remove-buffer current-buffer frame))))

;; AUTHOR:  Alp Aker -- https://github.com/alpaker/Frame-Bufs
;; @lawlist extracted/revised the function(ality) from said library.
(defun my-add-buffer (&optional buf frame)
"Add BUF to FRAME's associated-buffer list if not already present."
(interactive)
  (let* ((buf (if buf buf (current-buffer)))
         (frame (if frame frame (selected-frame)))
         (associated-bufs (frame-parameter frame 'frame-bufs-buffer-list)))
    (unless (bufferp buf)
      (signal 'wrong-type-argument (list 'bufferp buf)))
    (unless (memq buf associated-bufs)
      (set-frame-parameter frame 'frame-bufs-buffer-list (cons buf associated-bufs)))
    (with-current-buffer buf
      (add-hook 'kill-buffer-hook 'my-kill-buffer-fn 'append 'local))
    (when tabbar-mode (tabbar-display-update))))

;; AUTHOR:  Alp Aker -- https://github.com/alpaker/Frame-Bufs
;; @lawlist extracted/revised the function(ality) from said library.
(defun my-remove-buffer (&optional buf frame)
"Remove BUF from FRAME's associated-buffer list."
(interactive)
  (let ((buf (if buf buf (current-buffer)))
        (frame (if frame frame (selected-frame))))
    (set-frame-parameter frame 'frame-bufs-buffer-list
      (delq buf (frame-parameter frame 'frame-bufs-buffer-list)))
    (when tabbar-mode (tabbar-display-update))))

;; AUTHOR:  Alp Aker -- https://github.com/alpaker/Frame-Bufs
;; @lawlist extracted/revised the function(ality) from said library.
(defun my-buffer-list-reset ()
    "Wipe the entire slate clean for the selected frame."
  (interactive)
    (modify-frame-parameters (selected-frame) (list (cons 'frame-bufs-buffer-list nil)))
    (when tabbar-mode (tabbar-display-update)))

(defun my-switch-tab-group ()
"Switch between tab group `A` and `N`."
(interactive)
  (let ((current-group (format "%s" (tabbar-current-tabset t)))
        (tab-buffer-list (mapcar
            #'(lambda (b)
                (with-current-buffer b
                  (list (current-buffer)
                        (buffer-name)
                        (funcall tabbar-buffer-groups-function))))
                 (funcall tabbar-buffer-list-function))))
    (catch 'done
      (mapc
        #'(lambda (group)
            (when (not (equal current-group
                          (format "%s" (car (car (cdr (cdr group)))))))
              (throw 'done (switch-to-buffer (car (cdr group))))))
        tab-buffer-list))))

(defface tabbar-selected-associated
  '((t :background "black" :foreground "yellow" :box (:line-width 2 :color "yellow")))
  "Face used for the selected tab -- associated with the `frame-bufs-buffer-list`."
  :group 'tabbar)

(defface tabbar-unselected-associated
  '((t :background "black" :foreground "white" :box (:line-width 2 :color "white")))
  "Face used for unselected tabs  -- associated with the `frame-bufs-buffer-list`."
  :group 'tabbar)

(defface tabbar-selected-unassociated
  '((t :background "black" :foreground "white" :box (:line-width 2 :color "firebrick")))
  "Face used for the selected tab -- UNassociated with the `frame-bufs-buffer-list`."
  :group 'tabbar)

(defface tabbar-unselected-unassociated
  '((t :background "black" :foreground "white" :box (:line-width 2 :color "blue")))
  "Face used for unselected tabs -- UNassociated with the `frame-bufs-buffer-list`."
  :group 'tabbar)

(setq tabbar-background-color "black")

(defsubst tabbar-line-tab (tab)
  "Return the display representation of tab TAB.
That is, a propertized string used as an `header-line-format' template
element.
Call `tabbar-tab-label-function' to obtain a label for TAB."
  (concat
    (propertize
      (if tabbar-tab-label-function
          (funcall tabbar-tab-label-function tab)
        tab)
      'tabbar-tab tab
      'local-map (tabbar-make-tab-keymap tab)
      'help-echo 'tabbar-help-on-tab
      'mouse-face 'tabbar-highlight
      'face
        (cond
          ((and
              (tabbar-selected-p tab (tabbar-current-tabset))
              (memq (current-buffer) (my-buffer-list (selected-frame))))
            'tabbar-selected-associated)
          ((and
              (not (tabbar-selected-p tab (tabbar-current-tabset)))
              (memq (current-buffer) (my-buffer-list (selected-frame))))
            'tabbar-unselected-associated)
          ((and
              (tabbar-selected-p tab (tabbar-current-tabset))
              (not (memq (current-buffer) (my-buffer-list (selected-frame)))))
            'tabbar-selected-unassociated)
          ((and
              (not (tabbar-selected-p tab (tabbar-current-tabset)))
              (not (memq (current-buffer) (my-buffer-list (selected-frame)))))
            'tabbar-unselected-unassociated))
      'pointer 'hand)
    tabbar-separator-value))

(define-key global-map "\C-c\C-r" 'my-buffer-list-reset)

(define-key global-map "\C-c\C-a" 'my-add-buffer)

(define-key global-map "\C-c\C-n" 'my-remove-buffer)

(define-key global-map (kbd "<M-s-right>") 'tabbar-forward)

(define-key global-map (kbd "<M-s-left>") 'tabbar-backward)

(define-key global-map [C-tab] 'my-switch-tab-group)

(tabbar-mode 1)

Poniższy zrzut ekranu przedstawia dwie możliwe grupy buforów / tabulatorów: (1) po lewej stronie znajduje się grupa buforów / tabulatorów powiązanych z ramką o nazwie SYSTEM[żółte i białe tabulatory], z wielką literą „A” wskazaną w linia trybu; i (2) po prawej stronie znajduje się grupa buforów / zakładek, które NIE są powiązane z ramką o nazwie SYSTEM[niebieskie i czerwone zakładki], z wielką literą „N” wskazaną w linii trybu.

Przykład

lista prawnicza
źródło
Ale OP nie chce „jednego paska kart na okno”, chce jednego paska kart na ramkę, a każda karta na pasku kart powinna reprezentować „konfigurację okna” (tj. Kilka okien), a nie bufor.
Stefan
5

Zastanów się nad sprawdzeniem elscreen , chociaż tak naprawdę nie grupuje on buforów.

Grupuje okna i zapewnia dostęp do wielu układów (kart), między którymi można szybko się poruszać. Mój przepływ pracy często zawiera kod Ruby i powiązane testy na jednym ekranie, podczas gdy moje notatki do zrobienia i organizacji znajdują się na innym, a być może bufor do rysowania zapytań SQL znajduje się na trzecim. Pozwala mi to łatwo przeskakiwać między zadaniami i projektami, mimo że każdy ekran korzysta z tej samej puli buforów.

RP Dillon
źródło
3

Co powiesz na moją wtyczkę, centaur-tabs? Ma wiele opcji konfiguracji, jest naprawdę funkcjonalny, jest obsługiwany przez bardzo popularne motywy, takie jak Motywy Kaolin, a ogólnie jest to naprawdę ładnie wyglądający i estetyczny pakiet (zgodnie z opiniami użytkowników). Jest dostępny w MELPA i wygląda następująco:

wprowadź opis zdjęcia tutaj

Emmanuel Bustos
źródło
Wydaje się, że jest to kolejne „nierozwiązanie każdej karty reprezentuje bufor i każde okno ma swój własny pasek kart”.
Stefan
Właśnie dodałem dostosowanie, aby wyświetlać grupy kart zamiast nazw kart, więc w funkcji ustalasz reguły (tj. Grupa elisp i lisp w jednej grupie, grupa c i c ++ w drugiej itd.), A na kartach te grupy są wyświetlane.
Emmanuel Bustos
To wciąż nie odpowiada na pytanie, gdzie powinien być jeden pasek kart na ramkę (zamiast na okno), a każda karta reprezentuje konfigurację okna.
Stefan
Ok, nie zrozumiałem. Zbadam i popracuję nad tym!
Emmanuel Bustos
0

Oto moja konfiguracja, za co warto. Zawiera:

  • Obsługa myszy na kartach ( mouse-2aby zamknąć, jak w przeglądarkach , mouse-3 otworzyć się w nowym oknie Emacsa, jak w i3 )
  • Sterowanie za pomocą klawiatury ( M-lefti prawe karty przełączników, jak w TMux / Screen )
  • Kolory (zgodne z moe-darkkonfiguracją „ Motyw Moe / ” w zestawie)
  • Grupowanie (obecnie Emacs *buffers*i „zwykłe”)
  • Automatycznie aktualizowany (z pakietem użytkowania )

TabBar

(use-package tabbar
  :ensure t
  :bind
  ("<M-left>" . tabbar-backward)
  ("<M-right>" . tabbar-forward)

  :config
  (set-face-attribute
   'tabbar-button nil
   :box '(:line-width 1 :color "gray19"))

  (set-face-attribute
   'tabbar-selected nil
   :foreground "orange"
   :background "gray19"
   :box '(:line-width 1 :color "gray19"))

  (set-face-attribute
   'tabbar-unselected nil
   :foreground "gray75"
   :background "gray25"
   :box '(:line-width 1 :color "gray19"))

  (set-face-attribute
   'tabbar-highlight nil
   :foreground "black"
   :background "orange"
   :underline nil
   :box '(:line-width 1 :color "gray19" :style nil))

  (set-face-attribute
   'tabbar-modified nil
   :foreground "orange red"
   :background "gray25"
   :box '(:line-width 1 :color "gray19"))

  (set-face-attribute
   'tabbar-selected-modified nil
   :foreground "orange red"
   :background "gray19"
   :box '(:line-width 1 :color "gray19"))

  (custom-set-variables
   '(tabbar-separator (quote (0.2))))

  (defun tabbar-buffer-tab-label (tab)
    "Return a label for TAB.
  That is, a string used to represent it on the tab bar."
    (let ((label  (if tabbar--buffer-show-groups
                      (format " [%s] " (tabbar-tab-tabset tab))
                    (format " %s " (tabbar-tab-value tab)))))
      (if tabbar-auto-scroll-flag
          label
        (tabbar-shorten
         label (max 1 (/ (window-width)
                         (length (tabbar-view
                                  (tabbar-current-tabset)))))))))

  (defun px-tabbar-buffer-select-tab (event tab)
    "On mouse EVENT, select TAB."
    (let ((mouse-button (event-basic-type event))
          (buffer (tabbar-tab-value tab)))
      (cond
       ((eq mouse-button 'mouse-2) (with-current-buffer buffer (kill-buffer)))
       ((eq mouse-button 'mouse-3) (pop-to-buffer buffer t))
       (t (switch-to-buffer buffer)))
      (tabbar-buffer-show-groups nil)))

  (defun px-tabbar-buffer-help-on-tab (tab)
    "Return the help string shown when mouse is onto TAB."
    (if tabbar--buffer-show-groups
        (let* ((tabset (tabbar-tab-tabset tab))
               (tab (tabbar-selected-tab tabset)))
          (format "mouse-1: switch to buffer %S in group [%s]"
                  (buffer-name (tabbar-tab-value tab)) tabset))
      (format "\
mouse-1: switch to %S\n\
mouse-2: kill %S\n\
mouse-3: Open %S in another window"
              (buffer-name (tabbar-tab-value tab))
              (buffer-name (tabbar-tab-value tab))
              (buffer-name (tabbar-tab-value tab)))))

  (defun px-tabbar-buffer-groups ()
    "Sort tab groups."
    (list (cond ((or
                  (eq major-mode 'dired-mode)
                  (string-equal "*" (substring (buffer-name) 0 1))) "emacs")
                (t "user"))))
  (setq tabbar-help-on-tab-function 'px-tabbar-buffer-help-on-tab
        tabbar-select-tab-function 'px-tabbar-buffer-select-tab
        tabbar-buffer-groups-function 'px-tabbar-buffer-groups)

  :init
  (tabbar-mode 1))

Załącznik 1 - Temat Moe

(use-package moe-theme
  :ensure t
  :config
  (progn
    (load-theme 'moe-dark :no-confirm)
    (set-face-attribute 'fringe nil :background "gray19")))

Załącznik 2 - Przełącz ostatnie 2 bufory (makro KB)

(define-key global-map [(control tab)] (kbd "C-x b <return>")) 
yPhil
źródło