アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

自分好みにウィンドウ切り換え (1)

こんにちは、chibaです!
ネタ切れなので、Emacsをいじります。
Emacsを利用している方で、 ElScreenを使っている方は多いと思います。
自分も確かに便利だなあと思うのですが、どうも挙動が自分の好みに合わないところがあり、代りにEmacsレジスタ機能を使ってみたりしていました。(逆にややこしいですが…)
先日ふと、ウィンドウの構成はどういう風に保存/復帰しているのかを調べてみたら、(current-window-configuration)で構成を取得、set-window-configurationで設定という感じでした。
思いのほか単純だったので、自分好みの挙動をするようなものを作って行ってみようかと思います。
とりあえずで、window-configuration-listという循環リストにウィンドウの構成を保存するだけの素朴なものをでっち上げてみました。循環リストなので、くるくる回ります。
これだけでも割と使えていますが、もうちょっと便利にしたいですね。

;; 循環リストを作成する
(defun circular-list (&rest elts)
  (cdr (rplacd (last elts) elts)))

(defvar window-configuration-list)

(defun init-window-configuration-list ()
  (setq window-configuration-list
        (circular-list (current-window-configuration))))

;; window-configurationをリストにプッシュ
(defun push-window-configuration ()
  (interactive)
  (push (current-window-configuration)
        (cdr window-configuration-list))
  (message (format "created (%d)"
                   (window-configuration-list-size window-configuration-list))))

;; FIXME eqで比較するだけ
(defun window-configuration-list-size (wc)
  (let ((start wc)
        (cnt 1))
    (catch 'count
      (mapl (lambda (x)
              (when (eq start x)
                (throw 'count nil))
              (incf cnt))
            (cdr wc)))
    cnt))

(defun cycle-window-configuration-list ()
  (interactive)
  ;; 現在の窓の状態で更新
  (setcar window-configuration-list
          (current-window-configuration))
  ;; 順送り
  (setq window-configuration-list
        (cdr window-configuration-list))
  ;; 次の要素を現在の窓設定にする
  (set-window-configuration
   (car window-configuration-list)))

(defun delete-window-configuration ()
  (interactive)
  (setcar window-configuration-list
          (cadr window-configuration-list))
  (setcdr window-configuration-list
          (cddr window-configuration-list))
  (set-window-configuration
   (car window-configuration-list))
  (message (format "deleted (-> %d)"
                   (window-configuration-list-size
                    window-configuration-list)))) )

(progn
  ;; keybind
  (define-key global-map [(control meta ?l)] 'cycle-window-configuration-list)
  (define-key global-map [(control meta shift ?i)] 'push-window-configuration)
  (define-key global-map [(control meta ?!)] 'delete-window-configuration) )

(init-window-configuration-list)