feature/workspaces: create a fallback 'main' workspace to deal with nil persp quirks

This commit is contained in:
Henrik Lissner 2017-04-10 18:21:42 -04:00
parent 813630fc56
commit ac101e3af6
2 changed files with 45 additions and 20 deletions

View file

@ -3,6 +3,8 @@
(defvar +workspace-workspace-file "_workspaces" (defvar +workspace-workspace-file "_workspaces"
"The file basename in which to store single workspace perspectives.") "The file basename in which to store single workspace perspectives.")
(defvar +workspace--last nil)
(defface +workspace-tab-selected-face (defface +workspace-tab-selected-face
'((((class color) (background light)) '((((class color) (background light))
(:background "#333333" :foreground "#000000")) ;; FIXME (:background "#333333" :foreground "#000000")) ;; FIXME
@ -22,10 +24,7 @@
;;;###autoload ;;;###autoload
(defun +workspace-list (&optional exclude-nil-p) (defun +workspace-list (&optional exclude-nil-p)
"Retrieve a list of names of open workspaces (strings)." "Retrieve a list of names of open workspaces (strings)."
(let ((persps (persp-names))) (delete persp-nil-name (persp-names)))
(if exclude-nil-p
(delete persp-nil-name persps)
persps)))
;;;###autoload ;;;###autoload
(defun +workspace-p (obj) (defun +workspace-p (obj)
@ -101,8 +100,8 @@ Return t on success, nil otherwise."
(defun +workspace-new (name) (defun +workspace-new (name)
"Create a new workspace named NAME. If one already exists, return nil. "Create a new workspace named NAME. If one already exists, return nil.
Otherwise return t on success, nil otherwise." Otherwise return t on success, nil otherwise."
(when (equal name persp-nil-name) (when (+workspace-protected-p name)
(error "Can't create a new %s workspace" name)) (error "Can't create a new '%s' workspace" name))
(unless (+workspace-exists-p name) (unless (+workspace-exists-p name)
(and (persp-add-new name) t))) (and (persp-add-new name) t)))
@ -110,16 +109,16 @@ Otherwise return t on success, nil otherwise."
(defun +workspace-rename (name new-name) (defun +workspace-rename (name new-name)
"Rename the current workspace named NAME to NEW-NAME. Returns old name on "Rename the current workspace named NAME to NEW-NAME. Returns old name on
success, nil otherwise." success, nil otherwise."
(when (equal name persp-nil-name) (when (+workspace-protected-p name)
(error "Can't rename main workspace")) (error "Can't rename '%s' workspace"))
(persp-rename new-name (+workspace-get name))) (persp-rename new-name (+workspace-get name)))
;;;###autoload ;;;###autoload
(defun +workspace-delete (name &optional inhibit-kill-p) (defun +workspace-delete (name &optional inhibit-kill-p)
"Delete the workspace denoted by TARGET, which can be the name of a "Delete the workspace denoted by TARGET, which can be the name of a
perspective or its hash table." perspective or its hash table."
(when (equal name persp-nil-name) (when (+workspace-protected-p name)
(error "Can't delete main workspace")) (error "Can't delete '%s' workspace" name))
(+workspace-get name) ;; error checking (+workspace-get name) ;; error checking
(persp-kill name inhibit-kill-p)) (persp-kill name inhibit-kill-p))
@ -130,6 +129,11 @@ perspective or its hash table."
(if auto-create-p (if auto-create-p
(+workspace-new name) (+workspace-new name)
(error "%s is not an available workspace" name))) (error "%s is not an available workspace" name)))
(let ((old-name (+workspace-current-name)))
(setq +workspace--last
(or (and (not (string= old-name persp-nil-name))
old-name)
+workspaces-main)))
(persp-frame-switch name)) (persp-frame-switch name))
(defun +workspace--generate-id () (defun +workspace--generate-id ()
@ -140,6 +144,10 @@ perspective or its hash table."
(1+ (car (sort numbers (lambda (it other) (> it other))))) (1+ (car (sort numbers (lambda (it other) (> it other)))))
1))) 1)))
(defun +workspace-protected-p (name)
(or (equal name persp-nil-name)
(equal name +workspaces-main)))
;; ;;
;; Interactive commands ;; Interactive commands
@ -233,9 +241,12 @@ workspace to delete."
nil nil current-name) nil nil current-name)
current-name)))) current-name))))
(condition-case ex (condition-case ex
(if (+workspace-delete name) (if (not (+workspace-delete name))
(+workspace-message (format "Deleted '%s' workspace" name) 'success) (error "Couldn't delete %s workspace" name)
(error "Couldn't delete %s workspace" name)) (if (+workspace-exists-p +workspace--last)
(+workspace-switch +workspace--last)
(+workspace-switch +workspaces-main t))
(+workspace-message (format "Deleted '%s' workspace" name) 'success))
('error (+workspace-error (cadr ex) t)))) ('error (+workspace-error (cadr ex) t))))
;;;###autoload ;;;###autoload
@ -244,7 +255,7 @@ workspace to delete."
(interactive) (interactive)
(unless (cl-every '+workspace-delete (+workspace-list t)) (unless (cl-every '+workspace-delete (+workspace-list t))
(+workspace-error "Could not clear session")) (+workspace-error "Could not clear session"))
(+workspace-switch persp-nil-name) (+workspace-switch +workspaces-main t)
(doom/kill-all-buffers) (doom/kill-all-buffers)
(let ((fallback-buf (doom-fallback-buffer))) (let ((fallback-buf (doom-fallback-buffer)))
(switch-to-buffer fallback-buf) (switch-to-buffer fallback-buf)
@ -267,7 +278,7 @@ pre-existing workspace."
(let ((exists-p (+workspace-exists-p name))) (let ((exists-p (+workspace-exists-p name)))
(if exists-p (if exists-p
(error "%s already exists" name) (error "%s already exists" name)
(persp-frame-switch name) (+workspace-switch name t)
(if clone-p (if clone-p
(dolist (window (window-list)) (dolist (window (window-list))
(persp-add-buffer (window-buffer window) persp nil)) (persp-add-buffer (window-buffer window) persp nil))
@ -293,11 +304,13 @@ end of the workspace list."
(let ((dest (nth index names))) (let ((dest (nth index names)))
(unless dest (unless dest
(error "No workspace at #%s" (1+ index))) (error "No workspace at #%s" (1+ index)))
(persp-switch dest))) (+workspace-switch dest)))
((stringp index) ((stringp index)
(unless (member index names) (unless (member index names)
(error "No workspace named %s" index)) (error "No workspace named %s" index))
(persp-frame-switch index))) (+workspace-switch index))
(t
(error "Not a valid index: %s" index)))
(unless (called-interactively-p 'interactive) (unless (called-interactively-p 'interactive)
(if (equal (+workspace-current-name) old-name) (if (equal (+workspace-current-name) old-name)
(+workspace-message (format "Already in %s" old-name) 'warn) (+workspace-message (format "Already in %s" old-name) 'warn)
@ -338,7 +351,7 @@ the workspace and move to the next."
(if (doom-popup-p) (if (doom-popup-p)
(doom/popup-close) (doom/popup-close)
(let ((current-persp-name (+workspace-current-name))) (let ((current-persp-name (+workspace-current-name)))
(cond ((or (equal current-persp-name persp-nil-name) (cond ((or (+workspace-protected-p current-persp-name)
(> (length (doom-visible-windows)) 1)) (> (length (doom-visible-windows)) 1))
(if (bound-and-true-p evil-mode) (if (bound-and-true-p evil-mode)
(evil-window-delete) (evil-window-delete)

View file

@ -15,15 +15,19 @@
(defvar +workspaces-load-session-hook nil (defvar +workspaces-load-session-hook nil
"A hook that runs when persp loads a new session.") "A hook that runs when persp loads a new session.")
(defvar +workspaces-main "main"
"TODO")
(def-package! persp-mode :demand t (def-package! persp-mode :demand t
:config :config
(setq persp-autokill-buffer-on-remove 'kill-weak (setq persp-autokill-buffer-on-remove 'kill-weak
persp-nil-name "main" persp-nil-name "nil"
persp-auto-save-fname "autosave" persp-auto-save-fname "autosave"
persp-save-dir (concat doom-cache-dir "workspaces/") persp-save-dir (concat doom-cache-dir "workspaces/")
persp-set-last-persp-for-new-frames nil persp-set-last-persp-for-new-frames nil
persp-switch-to-added-buffer nil persp-switch-to-added-buffer nil
persp-remove-buffers-from-nil-persp-behaviour nil
;; Don't restore winconf on new frames ;; Don't restore winconf on new frames
persp-init-frame-behaviour t persp-init-frame-behaviour t
persp-init-new-frame-behaviour-override 'auto-temp persp-init-new-frame-behaviour-override 'auto-temp
@ -32,7 +36,15 @@
;; auto-save on kill ;; auto-save on kill
persp-auto-save-opt 1) persp-auto-save-opt 1)
(add-hook 'after-init-hook 'persp-mode) (add-hook! 'after-init-hook
(persp-mode +1)
;; The default perspective persp-mode makes (defined by `persp-nil-name') is
;; odd and doesn't actually represent a real persp object, so buffers can't
;; really be assigned to it, among other quirks. Therefore, we create a
;; *real* main workspace to play this role.
(persp-add-new +workspaces-main)
(unless (= persp-auto-resume-time -1)
(persp-frame-switch +workspaces-main)))
(define-key persp-mode-map [remap delete-window] '+workspace/close-window-or-workspace) (define-key persp-mode-map [remap delete-window] '+workspace/close-window-or-workspace)