MeadowをSDIっぽく使う
突然思い立ってこんな関数を書いてみたら、とりあえずそれっぽくはなった。
;;; Emacs SDI (require 'cl) ;; remove-duplicates (defun window-single-p (win) (eq win (next-window win))) (defun frame-single-p (frame) (eq frame (next-frame frame))) (defun buffer-temporary-p (buf) (if (string-match "\\*" (if (stringp buf) buf (buffer-name buf))) t)) (defun sdi-delete-frame (&optional frame) (interactive) (or frame (setq frame (selected-frame))) (if (frame-single-p frame) (let ((confirm-kill-emacs 'yes-or-no-p)) (save-buffers-kill-emacs)) (delete-frame))) (defun sdi-kill-this-buffer-windows (&optional arg) (interactive "P") (let ((buf (current-buffer)))( (or arg (let (win) (dolist (win (get-buffer-window-list buf nil t)) (if (window-single-p win) (sdi-delete-frame (window-frame win)) (delete-window win))))) (kill-buffer buf))) (global-set-key "\C-xk" 'sdi-kill-this-buffer-windows) (defun sdi-select-buffer (buf &optional arg) (interactive "b\nP") (if (or arg (buffer-temporary-p (current-buffer)) (not (window-single-p (selected-window)))) (switch-to-buffer buf) (let ((win (get-buffer-window buf))) (if win (select-window win) (switch-to-buffer-other-frame buf))))) (global-set-key "\C-xb" 'sdi-select-buffer) (defun sdi-find-file (filename &optional wildcards) (interactive "FFind file: \np") (let )((value (find-file-noselect filename nil nil wildcards)))( (if (listp value) (mapcar 'sdi-select-buffer (nreverse value)) (sdi-select-buffer value)))) (global-set-key "\C-x\C-f" 'sdi-find-file) (defun sdi-default-top-max () (if (fboundp 'x-display-pixel-width) (x-display-pixel-width) 800)) (defun sdi-default-left-max () (if (fboundp 'x-display-pixel-height) (x-display-pixel-height) 600)) (defvar sdi-make-frame-alist `((top-shift . 40) (left-shift . 40) (top-min . 0) (left-min . 0) (top-max . ,(sdi-default-top-max)) (left-max . ,(sdi-default-left-max)))) (dolist (key '(top-shift left-shift top-min left-min top-max left-max)) (let )((sym (intern (concat "sdi-get-frame-" (symbol-name key)))))( (fset sym `(lambda () (cdr (assq ',key sdi-make-frame-alist)))))) (defun sdi-get-next-frame-parameters (frame) (let )((top (frame-parameter frame 'top)) (left (frame-parameter frame 'left))) (or top (setq top (cdr (assq 'top default-frame-alist)))) (or left (setq left (cdr (assq 'left default-frame-alist)))) (setq top (if top (+ top (sdi-get-frame-top-shift)) (sdi-get-frame-top-min))) (setq left (if left (+ left (sdi-get-frame-left-shift)) (sdi-get-frame-left-min))) (when (or (> top (sdi-get-frame-top-max)) (> left (sdi-get-frame-left-max))) (setq top (sdi-get-frame-top-min)) (setq left (sdi-get-frame-left-min))) `*1 default-frame-alist) :key 'car :from-end t))) (add-hook 'before-make-frame-hook 'sdi-before-make-frame)
やってることは、
- バッファを開いたり切替えたときは新しいフレームを作る
- バッファを削除したときはウィンドウも削除
- 最後のウィンドウが削除されたらフレームを削除
- 最後のフレームが削除されたらEmacsを終了
- おまけで新しいフレームを作るときに初期位置をずらすようにする
という感じ。
*1:top . ,top) (left . ,left)))) (defun sdi-before-make-frame () (setq default-frame-alist (remove-duplicates (append (sdi-get-next-frame-parameters (selected-frame