Skip to content

Instantly share code, notes, and snippets.

@myuhe
Last active December 14, 2015 04:19
Show Gist options
  • Save myuhe/5027300 to your computer and use it in GitHub Desktop.
Save myuhe/5027300 to your computer and use it in GitHub Desktop.
@@ -172,14 +172,9 @@
(lambda (buf)
(string-match "\\*\\(Help\\|info\\|w3m\\|WoMan\\)" (buffer-name buf)))
"Retrun non-nil, if the buffer is a document buffer.")
-(defvar e2wm:c-blank-buffer
- (let ((buf (get-buffer-create " *e2wm:blank*")))
- (with-current-buffer buf
- (setq buffer-read-only nil)
- (buffer-disable-undo buf)
- (erase-buffer)
- (setq buffer-read-only t)) buf)
- "Blank buffer.")
+
+(defvar e2wm:c-blank-buffer-name " *e2wm:blank*"
+ "Blank buffer name.")
(defvar e2wm:prefix-key "C-c ; " "Prefix key")
@@ -413,6 +408,18 @@
(if (and buffer (buffer-live-p buffer))
(funcall e2wm:c-document-buffer-p buffer)))
+(defun e2wm:get-blank-buffer ()
+ "Get blank buffer. See the variable `e2wm:c-blank-buffer-name'."
+ (e2wm:aif (get-buffer e2wm:c-blank-buffer-name)
+ it
+ (let ((buf (get-buffer-create e2wm:c-blank-buffer-name)))
+ (with-current-buffer buf
+ (setq buffer-read-only nil)
+ (buffer-disable-undo buf)
+ (erase-buffer)
+ (setq buffer-read-only t))
+ buf)))
+
;; History data structure
;;
;; 1: buffer a |
@@ -425,7 +432,8 @@
(defun e2wm:history-get ()
"Return a list of buffer history from the current frame."
- (e2wm:frame-param-get 'e2wm:buffer-history))
+ (e2wm:history-filter-killed-buffers
+ (e2wm:frame-param-get 'e2wm:buffer-history)))
(defun e2wm:history-save (buffer-history)
"Save the given list as buffer history in the current frame."
@@ -435,8 +443,9 @@
(defun e2wm:history-get-backup ()
"Return a list of buffer backup-history."
- (e2wm:frame-param-get
- 'e2wm:buffer-history-backup))
+ (e2wm:history-filter-killed-buffers
+ (e2wm:frame-param-get
+ 'e2wm:buffer-history-backup)))
(defun e2wm:history-save-backup (buffer-history-backup)
"Save the given list as buffer backup-history."
@@ -445,6 +454,12 @@
buffer-history-backup)
buffer-history-backup)
+(defun e2wm:history-filter-killed-buffers (history)
+ "[internal] filter killed buffers"
+ (loop for buf in history
+ when (buffer-live-p buf)
+ collect buf))
+
(defun e2wm:history-recordable-p (buffer)
"If BUFFER should be record in buffer history, return t.
See the variable `e2wm:c-recordable-buffer-p'."
@@ -572,7 +587,7 @@
"Return the main buffer that should be display as the current
editing buffer."
(e2wm:aif (e2wm:history-get)
- (car it) e2wm:c-blank-buffer))
+ (car it) (e2wm:get-blank-buffer)))
(defun e2wm:managed-p (&optional frame)
"Return t, if e2wm manages the current frame."
@@ -626,8 +641,13 @@
;; : If this function returns non-nil, the original function `switch-to-buffer' is not evaluated.
;; : If the plug-ins need to be updated, this function should call the
;; : `e2wm:pst-update-windows' to update the plug-ins.
-;; popup : This function overrides `pop-to-buffer' and `special-display-func'. (Arguments: `buffer')
+;; popup : This function overrides `pop-to-buffer'. (Arguments: `buffer')
;; : See the `switch' spec for detail.
+;; display : This function overrides `special-display-func'. (Arguments: `buffer')
+;; : See the `switch' spec for detail.
+;; after-bury : This function is called after `bury-buffer' or `quit-window'
+;; : unlike other pst-class methods, this method does not override
+;; : the original functions. (Arguments: `buried-buffer' `window')
;; leave : This function cleans up buffers and some variables for leaving the perspective.
;; : (Arguments: `wm')
;; : If this slot is nil, the e2wm does nothing during leaving the perspective.
@@ -636,7 +656,7 @@
(defstruct e2wm:$pst-class
name title extend
- init main start update switch popup leave
+ init main start update switch popup display after-bury leave
keymap save)
(defun e2wm:pst-class-register (pst-class)
@@ -677,9 +697,10 @@
;;
;; name : A symbol for this perspective
;; wm : wlf layout object
+;; focus : name of focused window (if any)
;; type : A reference to the perspective class object
-(defstruct e2wm:$pst name wm type)
+(defstruct e2wm:$pst name wm focus type)
(defun e2wm:$pst-get-prop (name pst)
"[internal] Return the value of this perspective."
@@ -772,6 +793,10 @@
(make-e2wm:$pst
:name (e2wm:$pst-name i)
:wm (wlf:copy-windows (e2wm:pst-get-wm))
+ :focus (wlf:get-window-name (e2wm:pst-get-wm)
+ (if (= (minibuffer-depth) 0)
+ (selected-window)
+ (minibuffer-selected-window)))
:type (e2wm:$pst-type i))))
(defun e2wm:pst-get-wm ()
@@ -811,6 +836,16 @@
(e2wm:message "#PST-POPUP %s" buf)
(e2wm:pst-method-call e2wm:$pst-class-popup (e2wm:pst-get-instance) buf))
+(defun e2wm:pst-display-buffer (buf)
+ "[internal] Delegate the `display' function of the current perspective."
+ (e2wm:message "#PST-DISPLAY %s" buf)
+ (e2wm:pst-method-call e2wm:$pst-class-display (e2wm:pst-get-instance) buf))
+
+(defun e2wm:pst-after-bury-buffer (buried-buffer window)
+ (e2wm:message "#PST-AFTER-BURY %s" buried-buffer)
+ (e2wm:pst-method-call e2wm:$pst-class-after-bury (e2wm:pst-get-instance)
+ buried-buffer window))
+
(defun e2wm:pst-change (next-pst-name)
"Leave the current perspective and start the new perspective."
(e2wm:message "#PST-CHANGE %s" next-pst-name)
@@ -1209,19 +1244,8 @@
"[internal] This function is called after `bury-buffer' or
`quit-window' call, resets the buffer tracked by e2wm and
removes the buried buffer from the history list."
- ;; manage the current buffer in e2wm
(when (e2wm:managed-p)
- (let ((win-name (wlf:get-window-name (e2wm:pst-get-wm) window)))
- (when win-name
- (e2wm:with-advice
- (e2wm:pst-buffer-set win-name (window-buffer window))))
- ;; remove the buffer from the history
- (when (get-buffer buried-buffer)
- (e2wm:message "#REMOVED BUFFER %s" buried-buffer)
- (e2wm:history-delete buried-buffer))
- ;; execute plugins -- only for history plugin.
- (when this-command
- (e2wm:pst-update-windows)))))
+ (e2wm:pst-after-bury-buffer buried-buffer window)))
(defadvice quit-window (around
e2wm:ad-override
@@ -1268,6 +1292,8 @@
(defun e2wm:override-special-display-function (buf &optional args)
(e2wm:message "#SPECIAL-DISPLAY-FUNC %s / %S - %S" buf (not e2wm:ad-now-overriding) (e2wm:managed-p))
+ (unless (buffer-live-p buf) ; similar code is in `display-buffer'
+ (error "Invalid buffer"))
(let (overrided)
(when (and
buf
@@ -1276,8 +1302,10 @@
(e2wm:with-advice
(e2wm:message "#AD-SPECIAL-DISPLAY-FUNC %s" buf)
(e2wm:history-add buf)
- (save-excursion
- (setq overrided (e2wm:pst-pop-to-buffer (get-buffer-create buf))))))
+ (save-selected-window
+ (save-excursion
+ (setq overrided
+ (e2wm:pst-display-buffer (get-buffer-create buf)))))))
(if overrided
(progn
;(set-buffer buf)
@@ -1320,8 +1348,8 @@
(when (equal wname main-wname)
(e2wm:history-add buf))
(wlf:set-buffer wm wname buf)))
- (main-wname
- (wlf:set-buffer wm main-wname e2wm:c-blank-buffer)))))
+ ((and wins main-wname)
+ (wlf:set-buffer wm main-wname (e2wm:get-blank-buffer))))))
;; remove it from the history list
(e2wm:history-delete (current-buffer))
(when this-command
@@ -1421,7 +1449,8 @@
(set-window-configuration e2wm:override-window-cfg-backup)
(setq e2wm:override-window-cfg-backup nil)
(let ((i (e2wm:pst-get-instance)))
- (e2wm:aif (e2wm:$pst-main i)
+ (e2wm:aif (or (e2wm:$pst-focus i)
+ (e2wm:$pst-main i))
(wlf:select (e2wm:$pst-wm i) it)))))
(defvar e2wm:override-window-cfg-count 0 "[internal] Window configuration counter")
@@ -1945,19 +1974,21 @@
(defun e2wm:def-plugin-imenu-entries ()
"[internal] Return a list of imenu items to insert the imenu buffer."
- (with-current-buffer (e2wm:history-get-main-buffer)
- (let ((tick (buffer-modified-tick)))
- (if (and (eq e2wm:def-plugin-imenu-cached-tick tick)
- e2wm:def-plugin-imenu-cached-entries)
- e2wm:def-plugin-imenu-cached-entries
- (setq imenu--index-alist nil)
- (setq e2wm:def-plugin-imenu-cached-tick tick
+ (let ((buf (e2wm:history-get-main-buffer)))
+ (when (buffer-live-p buf)
+ (with-current-buffer buf
+ (let ((tick (buffer-modified-tick)))
+ (if (and (eq e2wm:def-plugin-imenu-cached-tick tick)
+ e2wm:def-plugin-imenu-cached-entries)
e2wm:def-plugin-imenu-cached-entries
- (condition-case nil
- (nreverse
- (e2wm:def-plugin-imenu-create-entries
- (imenu--make-index-alist) "" nil))
- (error nil)))))))
+ (setq imenu--index-alist nil)
+ (setq e2wm:def-plugin-imenu-cached-tick tick
+ e2wm:def-plugin-imenu-cached-entries
+ (condition-case nil
+ (nreverse
+ (e2wm:def-plugin-imenu-create-entries
+ (imenu--make-index-alist) "" nil))
+ (error nil)))))))))
(defun e2wm:def-plugin-imenu-create-entries (entries indent result)
"[internal] Make a menu item from the imenu object and return a
@@ -2736,13 +2767,40 @@
(e2wm:pst-class-register
(make-e2wm:$pst-class
- :name 'base
- :update 'e2wm:dp-base-update))
+ :name 'base
+ :display 'e2wm:dp-base-display
+ :after-bury 'e2wm:dp-base-after-bury
+ :update 'e2wm:dp-base-update))
(defun e2wm:dp-base-update (wm)
;;プラグイン更新実行
(e2wm:plugin-exec-update (selected-frame) wm))
+(defun e2wm:dp-base-display (buf)
+ ;; delegate to the popup method
+ (e2wm:pst-pop-to-buffer buf))
+
+(defun e2wm:dp-base-after-bury (buried-buffer window)
+ (let ((win-name (wlf:get-window-name (e2wm:pst-get-wm) window)))
+ ;; manage the current buffer in e2wm
+ (when win-name
+ (e2wm:with-advice
+ (e2wm:pst-buffer-set win-name (window-buffer window))))
+ ;; remove the buffer from the history if it is the last buffer in
+ ;; the current frame
+ (when (loop for other-win in (window-list)
+ for other-buf = (window-buffer other-win)
+ when (and (eq other-buf buried-buffer)
+ (not (eq other-win window)))
+ return nil
+ finally
+ return t)
+ (e2wm:message "#REMOVED BUFFER %s" buried-buffer)
+ (e2wm:history-delete buried-buffer))
+ ;; execute plugins (e.g. to update history)
+ (when this-command
+ (e2wm:pst-update-windows))))
+
;;; code / Code editing perspective
;;;--------------------------------------------------
@@ -2769,14 +2827,15 @@
(e2wm:pst-class-register
(make-e2wm:$pst-class
- :name 'code
- :extend 'base
- :title "Coding"
- :init 'e2wm:dp-code-init
- :main 'main
- :switch 'e2wm:dp-code-switch
- :popup 'e2wm:dp-code-popup
- :keymap 'e2wm:dp-code-minor-mode-map))
+ :name 'code
+ :extend 'base
+ :title "Coding"
+ :init 'e2wm:dp-code-init
+ :main 'main
+ :switch 'e2wm:dp-code-switch
+ :popup 'e2wm:dp-code-popup
+ :after-bury 'e2wm:dp-code-after-bury
+ :keymap 'e2wm:dp-code-minor-mode-map))
(defun e2wm:dp-code-init ()
(let*
@@ -2836,6 +2895,14 @@
(e2wm:with-advice
(e2wm:pst-buffer-set 'sub buf t not-minibufp))))
+(defun e2wm:dp-code-after-bury (buried-buffer window)
+ "Close sub window if it is the current window."
+ (e2wm:$pst-class-super)
+ (let ((wm (e2wm:pst-get-wm)))
+ (when (eq (wlf:get-window-name wm window) 'sub)
+ (wlf:hide wm 'sub)
+ (wlf:select wm (e2wm:$pst-main (e2wm:pst-get-instance))))))
+
;; Commands / Keybindings
(defun e2wm:dp-code ()
@@ -2906,14 +2973,16 @@
(e2wm:pst-class-register
(make-e2wm:$pst-class
- :name 'two
- :extend 'base
- :title "Two Columns"
- :init 'e2wm:dp-two-init
- :main 'left
- :switch 'e2wm:dp-two-switch
- :popup 'e2wm:dp-two-popup
- :keymap 'e2wm:dp-two-minor-mode-map))
+ :name 'two
+ :extend 'base
+ :title "Two Columns"
+ :init 'e2wm:dp-two-init
+ :main 'left
+ :switch 'e2wm:dp-two-switch
+ :popup 'e2wm:dp-two-popup
+ :display 'e2wm:dp-two-display
+ :after-bury 'e2wm:dp-two-after-bury
+ :keymap 'e2wm:dp-two-minor-mode-map))
(defun e2wm:dp-two-init ()
(let*
@@ -2936,47 +3005,48 @@
two-wm))
(defun e2wm:dp-two-switch (buf)
+ "Switch to the buffer BUF. If in the left window the buffer
+BUF is same as the shown one, show the same buffer on the right
+window too."
(e2wm:message "#DP TWO switch : %s" buf)
(let ((wm (e2wm:pst-get-wm))
(curwin (selected-window)))
(cond
- ((eql curwin (wlf:get-window wm 'left))
- ;; left画面の場合
- (cond
+ ((eql curwin (wlf:get-window wm 'left)) ; in left window
+ (cond
((eql (get-buffer buf) (wlf:get-buffer wm 'left))
- ;; leftと同じなら並べる
+ ;; switching to the same buffer. show it in the right.
(e2wm:pst-update-windows)
(e2wm:pst-buffer-set 'right buf)
t)
((e2wm:history-recordable-p buf)
- ;; 普通の編集対象なら履歴につっこんで更新
+ ;; put in the history and show if it is a recordable
(e2wm:pst-show-history-main)
t)
- (t
- ;; それ以外ならとりあえず表示してみる
+ (t
+ ;; otherwise, do the default
nil)))
- ((eql curwin (wlf:get-window wm 'right))
- ;; right画面の場合
+ ((eql curwin (wlf:get-window wm 'right)) ; in right window
(e2wm:pst-buffer-set 'right buf)
(e2wm:dp-two-update-history-list)
t)
(t nil))))
(defun e2wm:dp-two-popup (buf)
- ;;記録バッファ以外はsubで表示してみる
+ "Show the buffer BUF in sub if it is not recordable or document buffer.
+Otherwise show and select it."
(e2wm:message "#DP TWO popup : %s" buf)
- (let ((buf-name (buffer-name buf)))
- (cond
- ((e2wm:document-buffer-p buf)
- (e2wm:pst-buffer-set 'right buf)
- t)
- ((e2wm:history-recordable-p buf)
- (e2wm:pst-show-history-main)
- t)
- (t
- (e2wm:dp-two-popup-sub buf)
- t))))
+ (cond
+ ((e2wm:document-buffer-p buf)
+ (e2wm:pst-buffer-set 'right buf)
+ t)
+ ((e2wm:history-recordable-p buf)
+ (e2wm:pst-show-history-main)
+ t)
+ (t
+ (e2wm:dp-two-popup-sub buf)
+ t)))
(defun e2wm:dp-two-popup-sub (buf)
(let ((wm (e2wm:pst-get-wm))
@@ -2984,6 +3054,33 @@
(e2wm:with-advice
(e2wm:pst-buffer-set 'sub buf t not-minibufp))))
+(defun e2wm:dp-two-display (buf)
+ "Show the buffer BUF in sub if it is not recordable or document buffer.
+Do not select the buffer."
+ (e2wm:message "#DP TWO display : %s" buf)
+ (cond
+ ((or (e2wm:history-recordable-p buf) ; we don't need to distinguish
+ (e2wm:document-buffer-p buf)) ; these two as we don't select
+ (let ((wm (e2wm:pst-get-wm))
+ (curwin (selected-window)))
+ ;; show in the other window, but don't select.
+ (if (eql curwin (wlf:get-window wm 'left))
+ (e2wm:pst-buffer-set 'right buf)
+ (e2wm:pst-buffer-set 'left buf)))
+ (e2wm:pst-update-windows) ; update plugins, etc.
+ t)
+ (t
+ (e2wm:pst-buffer-set 'sub buf t)
+ t)))
+
+(defun e2wm:dp-two-after-bury (buried-buffer window)
+ "Close sub window if it is the current window."
+ (e2wm:$pst-class-super)
+ (let ((wm (e2wm:pst-get-wm)))
+ (when (eq (wlf:get-window-name wm window) 'sub)
+ (wlf:hide wm 'sub)
+ (wlf:select wm (e2wm:$pst-main (e2wm:pst-get-instance))))))
+
;; Commands / Keybindings
(defun e2wm:dp-two ()
@@ -3288,14 +3385,14 @@
do
(cond
((null plugin)
- (plist-put opt ':buffer e2wm:c-blank-buffer))
+ (plist-put opt ':buffer (e2wm:get-blank-buffer)))
((symbolp plugin)
(plist-put opt ':plugin plugin))
((consp plugin)
(plist-put opt ':plugin (car plugin))
(nconc opt (cdr plugin)))
(t
- (plist-put opt ':buffer e2wm:c-blank-buffer)))
+ (plist-put opt ':buffer (e2wm:get-blank-buffer))))
(incf cnt))
wm)
@@ -3528,7 +3625,7 @@
do (plist-put
opt ':buffer
(e2wm:aif (nth cnt buffers)
- it e2wm:c-blank-buffer))
+ it (e2wm:get-blank-buffer)))
(incf cnt))
wm)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment