如何仅循环处于给定主模式(例如Python模式)的缓冲区?

时间:2016-02-19 09:25:49

标签: emacs elisp

如何仅循环使用处于给定主模式的缓冲区(例如Python模式)?

目前我正在使用CX-Left / Right箭头,但这些也显示了各种不相关的(即非源代码)缓冲区,任何想法如何将缓冲区切换仅限于特定类型的缓冲区(给定主要模式)?

1 个答案:

答案 0 :(得分:2)

我找不到现成的东西。但是,制作合适的命令并不是很难。

(defun buffer-mode-alist ()
  "Returns a list of (<buffer-name> . <major-mode>) pairs."
  (let ((all-buffers (buffer-list))
    (rv nil))
    (while all-buffers
      (let* ((this (car all-buffers))
         (name (buffer-name this)))
    (setq all-buffers (cdr all-buffers))
    (when name
      (setq rv (cons (cons name (with-current-buffer this major-mode)) rv)))))
    rv))

(defun buffers-with-major-mode (the-major-mode)
  (let ((buffer-alist (buffer-mode-alist))
    (rv nil))
    (while buffer-alist
      (let ((this (car buffer-alist)))
    (setq buffer-alist (cdr buffer-alist))
    (if (eql (cdr this) the-major-mode)
        (setq rv (cons (car this) rv)))))
    (sort rv #'string<)))

(defun spin-buffers (buffer-list current)
  (cond ((not (member current buffer-list)) buffer-list)
        ((string= current (car buffer-list)) buffer-list)
        (t (spin-buffers (append (cdr buffer-list)
                                 (list (car buffer-list)))
                         current))))

(defvar next-buffer-mode nil)

(defun choose-next-buffer-mode (mode)
  "Ask for what major mode should be used as a selector for next-buffer-with-mode."
  (interactive "aMajor Mode: ")
  (setq next-buffer-mode mode))

(defun next-buffer-with-mode (set)
  "Switches to the 'next' buffer with a given mode. If the mode is not set,
require it to be set, by calling choose-next-buffer-mode. If any prefix
argument is passed, also call choose-next-buffer-mode."
  (interactive "P")
  (when (or (not next-buffer-mode)
        set)
    (call-interactively 'choose-next-buffer-mode))
  (let ((buffers (spin-buffers (buffers-with-major-mode next-buffer-mode)
                   (buffer-name))))
    (when (cdr buffers)
      (switch-to-buffer (cadr buffers)))))

(defun prev-buffer-with-mode (set)
  "Switches to the 'previous' buffer with a given mode. If the mode is not set,
require it to be set, by calling choose-next-buffer-mode. If any prefix
argument is passed, also call choose-next-buffer-mode."
  (interactive "P")
  (when (or (not next-buffer-mode)
        set)
    (call-interactively 'choose-next-buffer-mode))
  (let ((buffers (spin-buffers (buffers-with-major-mode next-buffer-mode)
                   (buffer-name))))
    (when buffers
      (switch-to-buffer (car (last buffers))))))