Changeset - 051a184a4239
[Not reviewed]
0 2 0
Sergey Pashinin - 11 years ago 2014-06-25 19:44:24
sergey@pashinin.com
wg-load-last-workgroup works now
2 files changed with 16 insertions and 3 deletions:
0 comments (0 inline, 0 general)
src/workgroups-commands.el
Show inline comments
 
;;; workgroups-commands --- main commands
 
;;; Commentary:
 
;;; Code:
 

	
 
(require 'cl-lib)
 
(eval-when-compile
 
  (require 'ido)
 
  (require 'iswitchb))
 

	
 
(require 'ring)
 
(require 'workgroups-variables)
 
(require 'workgroups-utils-basic)
 
(require 'workgroups-pickel)
 
(require 'workgroups-functions)
 

	
 
;;; workgroup switching commands
 

	
 
(defun wg-switch-to-workgroup (workgroup &optional noerror)
 
  "Switch to WORKGROUP."
 
  (interactive (list (wg-read-workgroup-name)))
 
  ;; Set a parameter when using ECB
 
  (if (wg-current-workgroup t)
 
      (wg-set-workgroup-parameter (wg-current-workgroup t) 'ecb (and (boundp 'ecb-minor-mode)
 
                                                                     ecb-minor-mode)))
 
  (let ((workgroup (wg-get-workgroup-create workgroup))
 
        (current (wg-current-workgroup t)))
 
    (when (and (eq workgroup current) (not noerror))
 
      (error "Already on: %s" (wg-workgroup-name current)))
 
    (when current (push current wg-deactivation-list))
 
    (unwind-protect
 
        (progn
 
          ;; Before switching - turn off ECB
 
          ;; https://github.com/pashinin/workgroups2/issues/34
 
          (if (and (boundp 'ecb-minor-mode)
 
                   ecb-minor-mode
 
                   (equal ecb-frame (selected-frame)))
 
              (let ((ecb-split-edit-window-after-start 'before-deactivation))
 
                (ecb-deactivate)))
 

	
 
          (wg-restore-workgroup workgroup)
 
          (wg-set-previous-workgroup current)
 
          (wg-set-current-workgroup workgroup)
 

	
 
          ;; Save "last-workgroup" to the session params
 
          (if (and (wg-current-session t)
 
                   (wg-current-workgroup t))
 
              (wg-set-session-parameter (wg-current-session t)
 
                                        'last-workgroup
 
                                        (wg-workgroup-name (wg-current-workgroup))))
 

	
 
          ;; If a workgroup had ECB - turn it on
 
          (if (and (boundp 'ecb-minor-mode)
 
                   (not ecb-minor-mode)
 
                   (wg-workgroup-parameter (wg-current-workgroup t) 'ecb nil))
 
              (let ((ecb-split-edit-window-after-start 'before-deactivation))
 
                (ecb-activate)))
 

	
 
          (run-hooks 'wg-switch-to-workgroup-hook)
 
          (wg-fontified-message
 
            (:cmd "Switched: ")
 
            (wg-workgroup-name (wg-current-workgroup t))
 
            ))
 
      (when current (pop wg-deactivation-list)))))
 

	
 
(defun wg-switch-to-workgroup-other-frame (workgroup &optional n)
 
  "Switch to WORKGROUP in the frame N places cyclically from `selected-frame'.
 
Use `current-prefix-arg' for N if non-nil.  Otherwise N defaults to 1."
 
  (interactive (list (wg-read-workgroup-name) current-prefix-arg))
 
  (with-selected-frame (wg-cyclic-nth-from-frame (or n 1))
 
    (wg-switch-to-workgroup workgroup)))
 

	
 
(defun wg-switch-to-workgroup-at-index (index)
 
  "Switch to the workgroup at INDEX in `wg-workgroup-list'."
 
  (interactive (list (or current-prefix-arg (wg-read-workgroup-index))))
 
  (let ((wl (wg-workgroup-list-or-error)))
 
    (wg-switch-to-workgroup
 
     (or (nth index wl) (error "There are only %d workgroups" (length wl))))))
 

	
 
(cl-macrolet
 
    ((define-range-of-switch-to-workgroup-at-index (num)
 
       `(progn
 
          ,@(wg-docar (i (wg-range 0 num))
 
              `(defun ,(intern (format "wg-switch-to-workgroup-at-index-%d" i)) ()
 
                 ,(format "Switch to the workgroup at index %d." i)
 
                 (interactive)
 
                 (wg-switch-to-workgroup-at-index ,i))))))
 
  (define-range-of-switch-to-workgroup-at-index 10))
 

	
 
(defun wg-switch-to-cyclic-nth-from-workgroup (workgroup n)
 
  "Switch N workgroups cyclically from WORKGROUP in `wg-workgroup-list.'"
 
  (let ((workgroup-list (wg-workgroup-list-or-error))
 
        (workgroup (wg-get-workgroup workgroup t)))
 
    (wg-switch-to-workgroup
 
     (cond ((not workgroup) (car workgroup-list))
 
           ((= 1 (length workgroup-list)) (error "There's only one workgroup"))
 
           (t (wg-cyclic-nth-from-workgroup workgroup n))))))
 

	
 
(defun wg-switch-to-workgroup-left (&optional workgroup n)
 
  "Switch to the workgroup (- N) places from WORKGROUP in `wg-workgroup-list'.
 
Use `current-prefix-arg' for N if non-nil.  Otherwise N defaults to 1."
 
  (interactive (list nil current-prefix-arg))
 
  (wg-switch-to-cyclic-nth-from-workgroup workgroup (- (or n 1))))
 

	
 
(defun wg-switch-to-workgroup-right (&optional workgroup n)
 
  "Switch to the workgroup N places from WORKGROUP in `wg-workgroup-list'.
 
Use `current-prefix-arg' for N if non-nil.  Otherwise N defaults to 1."
 
  (interactive (list nil current-prefix-arg))
 
  (wg-switch-to-cyclic-nth-from-workgroup workgroup (or n 1)))
 

	
 
(defun wg-switch-to-workgroup-left-other-frame (&optional n)
 
  "Like `wg-switch-to-workgroup-left', but operates on the next frame."
 
  (interactive "p")
 
  (with-selected-frame (wg-cyclic-nth-from-frame (or n 1))
 
    (call-interactively 'wg-switch-to-workgroup-left)))
 

	
 
(defun wg-switch-to-workgroup-right-other-frame (&optional n)
 
  "Like `wg-switch-to-workgroup-right', but operates on the next frame."
 
  (interactive "p")
 
  (with-selected-frame (wg-cyclic-nth-from-frame (or n -1))
 
    (call-interactively 'wg-switch-to-workgroup-right)))
 

	
 
(defun wg-switch-to-previous-workgroup ()
 
  "Switch to the previous workgroup."
 
  (interactive)
 
  (wg-switch-to-workgroup (wg-previous-workgroup)))
 

	
 

	
 

	
 
;;; workgroup creation commands
 

	
 
(defun wg-create-workgroup (name &optional blank)
 
  "Create and add a workgroup named NAME.
 
Optional argument BLANK non-nil (set interactively with a prefix
 
arg) means use a blank, one window window-config.  Otherwise use
 
the current window-configuration.  Keep in mind that even though
 
the current window-config may be used, other parameters of the
 
current workgroup are not copied to the created workgroup.  For
 
that, use `wg-clone-workgroup'."
 
  (interactive (list (wg-read-new-workgroup-name) current-prefix-arg))
 
  (wg-switch-to-workgroup (wg-make-and-add-workgroup name blank))
 
  (wg-fontified-message
 
    (:cmd "Created: ")
 
    (:cur name) "  "
 
    (wg-workgroup-list-display)))
 

	
 
(defun wg-clone-workgroup (workgroup name)
 
  "Create and add a clone of WORKGROUP named NAME.
 
Keep in mind that only WORKGROUP's top-level alist structure is
 
copied, so destructive operations on the keys or values of
 
WORKGROUP will be reflected in the clone, and vice-versa.  Be
 
safe -- don't mutate them."
 
  (interactive (list nil (wg-read-new-workgroup-name)))
 
  (let* ((workgroup (wg-get-workgroup workgroup))
 
         (clone (wg-copy-workgroup workgroup)))
 
    (setf (wg-workgroup-name clone) name
 
          (wg-workgroup-uid clone) (wg-generate-uid))
 
    (when (wg-check-and-add-workgroup clone)
 
      (wg-flag-workgroup-modified clone))
 
    (wg-set-workgroup-working-wconfig
 
     clone (wg-workgroup-working-wconfig workgroup))
 
    (wg-switch-to-workgroup clone)
 
    (wg-fontified-message
 
      (:cmd "Cloned: ")
 
      (:cur (wg-workgroup-name workgroup))
 
      (:msg " to ")
 
      (:cur name) "  "
 
      (wg-workgroup-list-display))))
 

	
 

	
 

	
 
;;; workgroup killing commands
 

	
 
(defun wg-wconfig-kill-ring ()
 
  "Return `wg-wconfig-kill-ring', creating it first if necessary."
 
  (or wg-wconfig-kill-ring
 
      (setq wg-wconfig-kill-ring (make-ring wg-wconfig-kill-ring-max))))
 

	
 
(defun wg-add-to-wconfig-kill-ring (wconfig)
 
  "Add WCONFIG to `wg-wconfig-kill-ring'."
 
  (ring-insert (wg-wconfig-kill-ring) wconfig))
 

	
 
(defun wg-kill-workgroup (&optional workgroup)
 
  "Kill WORKGROUP, saving its working-wconfig to the kill ring."
 
  (interactive)
 
  (let* ((workgroup (wg-get-workgroup workgroup))
 
         (to (or (wg-previous-workgroup t)
 
                 (wg-cyclic-nth-from-workgroup workgroup))))
 
    (wg-add-to-wconfig-kill-ring (wg-workgroup-working-wconfig workgroup))
 
    (wg-delete-workgroup workgroup)
 
    (if (eq workgroup to) (wg-restore-wconfig (wg-make-blank-wconfig))
 
      (wg-switch-to-workgroup to))
 
    (wg-fontified-message
 
      (:cmd "Killed: ")
 
      (:cur (wg-workgroup-name workgroup)) "  "
 
      (wg-workgroup-list-display))))
 

	
 
(defun wg-kill-ring-save-base-wconfig (&optional workgroup)
 
  "Save WORKGROUP's base wconfig to the kill ring."
 
  (interactive)
 
  (let ((workgroup (wg-get-workgroup workgroup)))
 
    (wg-add-to-wconfig-kill-ring (wg-workgroup-base-wconfig workgroup))
 
    (wg-fontified-message
 
      (:cmd "Saved: ")
 
      (:cur (wg-workgroup-name workgroup))
 
      (:cur "'s ")
 
      (:msg "base wconfig to the kill ring"))))
 

	
 
(defun wg-kill-ring-save-working-wconfig (&optional workgroup)
 
  "Save WORKGROUP's working-wconfig to `wg-wconfig-kill-ring'."
 
  (interactive)
 
  (let ((workgroup (wg-get-workgroup workgroup)))
 
    (wg-add-to-wconfig-kill-ring (wg-workgroup-working-wconfig workgroup))
 
    (wg-fontified-message
 
      (:cmd "Saved: ")
 
      (:cur (wg-workgroup-name workgroup))
 
      (:cur "'s ")
 
      (:msg "working-wconfig to the kill ring"))))
 

	
 
(defun wg-yank-wconfig ()
 
  "Restore a wconfig from `wg-wconfig-kill-ring'.
 
Successive yanks restore wconfigs sequentially from the kill
 
ring, starting at the front."
 
  (interactive)
 
  (when (zerop (ring-length (wg-wconfig-kill-ring)))
 
    (error "The kill-ring is empty"))
 
  (let ((pos (if (not (eq real-last-command 'wg-yank-wconfig)) 0
 
               (1+ (or (get 'wg-yank-wconfig :position) 0)))))
 
    (put 'wg-yank-wconfig :position pos)
 
    (wg-restore-wconfig-undoably (ring-ref (wg-wconfig-kill-ring) pos))
 
    (wg-fontified-message
 
      (:cmd "Yanked: ")
 
      (:msg (format "%S" pos)) "  "
 
      (wg-workgroup-list-display))))
 

	
 
(defun wg-kill-workgroup-and-buffers (&optional workgroup)
 
  "Kill WORKGROUP and the buffers in its working-wconfig."
 
  (interactive)
 
  (let* ((workgroup (wg-get-workgroup workgroup))
 
         (bufs (save-window-excursion
 
                 (wg-restore-workgroup workgroup)
 
                 (mapcar #'window-buffer (window-list)))))
 
    (wg-kill-workgroup workgroup)
 
@@ -530,296 +537,302 @@ See `wg-workgroup-cycle-bufobj-association-type' for details."
 
  (interactive)
 
  (let* ((workgroup (wg-current-workgroup))
 
         (buffer (current-buffer))
 
         (type (wg-workgroup-cycle-bufobj-association-type workgroup buffer)))
 
    (force-mode-line-update)
 
    (wg-fontified-message
 
      (:cur (buffer-name buffer))
 
      (:cmd (cl-case type
 
              (strong " strongly associated with ")
 
              (weak " weakly associated with ")
 
              (otherwise " unassociated with ")))
 
      (:cur (wg-workgroup-name workgroup)))))
 

	
 
(defun wg-dissociate-weakly-associated-buffers (&optional workgroup)
 
  "Dissociate from the current workgroup all weakly associated buffers."
 
  (interactive)
 
  (let ((workgroup (wg-get-workgroup workgroup)))
 
    (wg-workgroup-dissociate-weakly-associated-buffers workgroup)
 
    (wg-fontified-message
 
      (:cmd "Remaining buffers: ")
 
      (wg-buffer-list-display (wg-workgroup-associated-buffers workgroup)))))
 

	
 

	
 

	
 
;;; window-tree commands
 
;;
 
;; TODO: These are half-hearted.  Clean them up; allow specification of the
 
;; window-tree depth at which to operate; add complex window creation commands;
 
;; and add window splitting, deletion and locking commands.
 

	
 
(defun wg-transpose-window-internal (workgroup offset)
 
  "Move `selected-window' by OFFSET in its wlist."
 
  (wg-restore-wconfig-undoably
 
   (wg-wconfig-move-window
 
    (wg-workgroup-working-wconfig
 
     (wg-get-workgroup workgroup))
 
    offset)))
 

	
 
(defun wg-backward-transpose-window (&optional workgroup offset)
 
  "Move `selected-window' backward by OFFSET in its wlist."
 
  (interactive (list nil current-prefix-arg))
 
  (wg-transpose-window-internal workgroup (or offset -1)))
 

	
 
(defun wg-transpose-window (&optional workgroup offset)
 
  "Move `selected-window' forward by OFFSET in its wlist."
 
  (interactive (list nil current-prefix-arg))
 
  (wg-transpose-window-internal workgroup (or offset 1)))
 

	
 
(defun wg-reverse-frame-horizontally (&optional workgroup)
 
  "Reverse the order of all horizontally split wtrees."
 
  (interactive)
 
  (wg-restore-wconfig-undoably
 
   (wg-reverse-wconfig
 
    (wg-workgroup-working-wconfig
 
     (wg-get-workgroup workgroup)))))
 

	
 
(defun wg-reverse-frame-vertically (&optional workgroup)
 
  "Reverse the order of all vertically split wtrees."
 
  (interactive)
 
  (wg-restore-wconfig-undoably
 
   (wg-reverse-wconfig
 
    (wg-workgroup-working-wconfig
 
     (wg-get-workgroup workgroup))
 
    t)))
 

	
 
(defun wg-reverse-frame-horizontally-and-vertically (&optional workgroup)
 
  "Reverse the order of all wtrees."
 
  (interactive)
 
  (wg-restore-wconfig-undoably
 
   (wg-reverse-wconfig
 
    (wg-workgroup-working-wconfig
 
     (wg-get-workgroup workgroup))
 
    'both)))
 

	
 
(defun wg-toggle-window-dedicated-p ()
 
  "Toggle `window-dedicated-p' in `selected-window'."
 
  (interactive)
 
  (set-window-dedicated-p nil (not (window-dedicated-p)))
 
  (force-mode-line-update t)
 
  (wg-fontified-message
 
    (:cmd "Window:")
 
    (:cur (concat (unless (window-dedicated-p) " not") " dedicated"))))
 

	
 

	
 

	
 
;;; misc commands
 

	
 
(defun wg-rename-workgroup (workgroup newname)
 
  "Rename WORKGROUP to NEWNAME."
 
  (interactive (list nil (wg-read-new-workgroup-name "New name: ")))
 
  (let* ((workgroup (wg-get-workgroup workgroup))
 
         (oldname (wg-workgroup-name workgroup)))
 
    (setf (wg-workgroup-name workgroup) newname)
 
    (wg-flag-workgroup-modified workgroup)
 
    (wg-fontified-message
 
      (:cmd "Renamed: ")
 
      (:cur oldname)
 
      (:msg " to ")
 
      (:cur (wg-workgroup-name workgroup)))))
 

	
 
(defun wg-reset (&optional force)
 
  "Reset Workgroups.
 
Resets all frame parameters, buffer-local vars, the current
 
Workgroups session object, etc."
 
  (interactive "P")
 
  (unless (or force wg-no-confirm-on-destructive-operation
 
              (y-or-n-p "Really reset Workgroups? "))
 
    (error "Canceled"))
 
  (wg-reset-internal)
 
  (wg-fontified-message
 
    (:cmd "Reset: ")
 
    (:msg "Workgroups")))
 

	
 

	
 

	
 
;;; file commands
 

	
 
(defun wg-read-session-save-file-name ()
 
  "Read and return a new session filename."
 
  (read-file-name "Save session as: "))
 

	
 
(defun wg-write-session-file (filename &optional confirm)
 
  "Write the current session into file FILENAME.
 
This makes the session visit that file, and marks it as not modified.
 

	
 
If optional second arg CONFIRM is non-nil, this function asks for
 
confirmation before overwriting an existing file.  Interactively,
 
confirmation is required unless you supply a prefix argument.
 

	
 
Think of it as `write-file' for Workgroups sessions."
 
  (interactive (list (wg-read-session-save-file-name)
 
                     (not current-prefix-arg)))
 
  (when (and confirm (file-exists-p filename))
 
    (unless (y-or-n-p (format "File `%s' exists; overwrite? " filename))
 
      (error "Cancelled")))
 
  (unless (file-writable-p filename)
 
    (error "File %s can't be written to" filename))
 
  (wg-perform-session-maintenance)
 
  (setf (wg-session-file-name (wg-current-session)) filename)
 
  (setf (wg-session-version (wg-current-session)) wg-version)
 
  (wg-write-sexp-to-file
 
   (wg-pickel-all-session-parameters (wg-current-session))
 
   filename)
 
  (wg-mark-everything-unmodified)
 
  (wg-fontified-message (:cmd "Wrote: ") (:file filename)))
 

	
 
(defun wg-determine-session-save-file-name ()
 
  "Return the filename in which to save the session."
 
  (or (wg-session-file-name (wg-current-session))
 
      (and wg-use-default-session-file wg-default-session-file)))
 

	
 
(defun wg-save-session (&optional force)
 
  "Save the current Workgroups session if it's been modified.
 
Think of it as `save-buffer' for Workgroups sessions.  Optional
 
argument FORCE non-nil, or interactively with a prefix arg, save
 
the session regardless of whether it's been modified."
 
  (interactive "P")
 
  (if (and (not (wg-modified-p)) (not force))
 
      (wg-message "(The session is unmodified)")
 
    (wg-write-session-file
 
     (or (wg-determine-session-save-file-name)
 
         (wg-read-session-save-file-name)))))
 

	
 
(defun wg-query-and-save-if-modified ()
 
  "Query for save when `wg-modified-p'."
 
  (or (not (wg-modified-p))
 
      (when (y-or-n-p "Save modified workgroups? ")
 
        (wg-save-session))))
 

	
 
(defun wg-save-session-on-exit (behavior)
 
  "Perform session-saving operations based on BEHAVIOR."
 
  (cl-case behavior
 
    (ask (wg-query-and-save-if-modified))
 
    (save
 
     (if (wg-determine-session-save-file-name)
 
         (wg-save-session)
 
       (wg-query-and-save-if-modified)))))
 

	
 
(defun wg-find-session-file (filename)
 
  "Load a session visiting FILENAME, creating one if none already exists."
 
  (interactive "FFind session file: ")
 
  (cond ((file-exists-p filename)
 
         (let ((session (wg-read-sexp-from-file filename)))
 
           (unless (wg-session-p session)
 
             (error "%S is not a Workgroups session file." filename))
 
           (setf (wg-session-file-name session) filename)
 
           (wg-reset-internal (wg-unpickel-session-parameters session)))
 
         (wg-awhen (and wg-switch-to-first-workgroup-on-find-session-file
 
                        (wg-workgroup-list))
 
           (if (and wg-open-this-wg
 
                    (member wg-open-this-wg (wg-workgroup-names)))
 
               (wg-switch-to-workgroup wg-open-this-wg)
 
             (wg-switch-to-workgroup (car it))))
 
             (if (and wg-load-last-workgroup
 
                      (member (wg-session-parameter (wg-current-session t) 'last-workgroup)
 
                              (wg-workgroup-names)))
 
                 (wg-switch-to-workgroup
 
                  (wg-session-parameter (wg-current-session t) 'last-workgroup))
 
               (wg-switch-to-workgroup (car it)))
 
             ))
 
         (wg-fontified-message (:cmd "Loaded: ") (:file filename)))
 
        (t
 
         (wg-query-and-save-if-modified)
 
         (wg-reset-internal (wg-make-session :file-name filename))
 
         (wg-fontified-message
 
           (:cmd "(New Workgroups session file)")))))
 

	
 
(defun wg-find-file-in-new-workgroup (filename)
 
  "Create a new blank workgroup and find file FILENAME in it."
 
  (interactive "FFind file in new workgroup: ")
 
  (wg-create-workgroup (file-name-nondirectory filename) t)
 
  (find-file filename))
 

	
 
(defun wg-find-file-read-only-in-new-workgroup (filename)
 
  "Create a new workgroup and find file FILENAME read-only in it."
 
  (interactive "FFind file read only in new workgroup: ")
 
  (wg-create-workgroup (file-name-nondirectory filename) t)
 
  (find-file-read-only filename))
 

	
 
(defun wg-dired-in-new-workgroup (dirname &optional switches)
 
  "Create a workgroup and open DIRNAME in dired with SWITCHES."
 
  (interactive (list (read-directory-name "Dired (directory): ")
 
                     current-prefix-arg))
 
  (wg-create-workgroup dirname)
 
  (dired dirname switches))
 

	
 

	
 

	
 
;;; toggle commands
 

	
 
(defun wg-toggle-and-message (symbol)
 
  "Toggle SYMBOL's truthiness and message the new value."
 
  (wg-fontified-message
 
    (:cmd (format "%s: " symbol))
 
    (:msg (format "%s" (wg-toggle symbol)))))
 

	
 
(defun wg-toggle-buffer-list-filtration ()
 
  "Toggle `wg-buffer-list-filtration-on'."
 
  (interactive)
 
  (wg-toggle-and-message 'wg-buffer-list-filtration-on))
 

	
 
(defun wg-toggle-mode-line-display ()
 
  "Toggle `wg-mode-line-display-on'."
 
  (interactive)
 
  (wg-toggle-and-message 'wg-mode-line-display-on))
 

	
 

	
 

	
 
;;; echo commands
 

	
 
(defun wg-echo-current-workgroup ()
 
  "Display the name of the current workgroup in the echo area."
 
  (interactive)
 
  (wg-fontified-message
 
    (:cmd "Current: ")
 
    (:cur (wg-workgroup-name (wg-current-workgroup)))))
 

	
 
(defun wg-echo-all-workgroups ()
 
  "Display the names of all workgroups in the echo area."
 
  (interactive)
 
  (wg-fontified-message
 
    (:cmd "Workgroups: ")
 
    (wg-workgroup-list-display)))
 

	
 
(defun wg-echo-time ()
 
  "Echo the current time.  Optionally includes `battery' info."
 
  (interactive)
 
  (wg-message ;; Pass through format to escape the % in `battery'
 
   "%s" (wg-fontify
 
          (:cmd "Current time: ")
 
          (:msg (format-time-string wg-time-format))
 
          (when (and wg-display-battery (fboundp 'battery))
 
            (wg-fontify "\n" (:cmd "Battery: ") (:msg (battery)))))))
 

	
 
(defun wg-echo-version ()
 
  "Echo Workgroups' current version number."
 
  (interactive)
 
  (wg-fontified-message
 
    (:cmd "Workgroups version: ")
 
    (:msg wg-version)))
 

	
 
(defun wg-echo-last-message ()
 
  "Echo the last message Workgroups sent to the echo area.
 
The string is passed through a format arg to escape %'s."
 
  (interactive)
 
  (message "%s" wg-last-message))
 

	
 

	
 

	
 
;;; help commands
 

	
 
(defun wg-help ()
 
  "Just call `apropos-command' on \"^wg-\".
 
There used to be a bunch of help-buffer construction stuff here,
 
including a `wg-help' variable that basically duplicated every
 
command's docstring;  But why, when there's `apropos-command'?"
 
  (interactive)
 
  (apropos-command "^wg-"))
 

	
 

	
 
(require 'workgroups-commands-minibuffer)
 

	
 
(provide 'workgroups-commands)
src/workgroups-variables.el
Show inline comments
 
;;; workgroups-variables --- Workgroups vars and consts
 
;;; Commentary:
 
;;; Code:
 

	
 
(defconst wg-version "1.0.3"
 
  "Current version of workgroups.")
 

	
 
;;; customization
 

	
 
(defgroup workgroups nil
 
  "Workgroups for Emacs -- Emacs session manager"
 
  :group 'convenience
 
  :version wg-version)
 

	
 
(defcustom workgroups-mode nil
 
  "Non-nil if Workgroups mode is enabled."
 
  :set 'custom-set-minor-mode
 
  :initialize 'custom-initialize-default
 
  :group 'workgroups
 
  :type 'boolean)
 

	
 
(defcustom wg-first-wg-name "First workgroup"
 
  "Title of the first workgroup created."
 
  :type 'string
 
  :group 'workgroups)
 

	
 
(defcustom wg-load-last-workgroup nil
 
  "Load last active, not first, workgroup from all your workgroups."
 
(defcustom wg-load-last-workgroup t
 
  "Load last active (not first) workgroup from all your workgroups if it exists."
 
  :group 'workgroups
 
  :type 'boolean)
 

	
 

	
 
;; keybinding customization
 

	
 
(defcustom wg-prefix-key (kbd "C-c z")
 
  "Workgroups' prefix key.
 
Setting this variable requires that `workgroups-mode' be turned
 
off and then on again to take effect."
 
  :type 'string
 
  :group 'workgroups)
 

	
 

	
 
;; hooks
 

	
 
(defcustom workgroups-mode-hook nil
 
  "Hook run when `workgroups-mode' is turned on."
 
  :type 'hook
 
  :group 'workgroups)
 

	
 
(defcustom workgroups-mode-exit-hook nil
 
  "Hook run when `workgroups-mode' is turned off."
 
  :type 'hook
 
  :group 'workgroups)
 

	
 
(defcustom wg-switch-to-workgroup-hook nil
 
  "Hook run by `wg-switch-to-workgroup'."
 
  :type 'hook
 
  :group 'workgroups)
 

	
 
(defcustom wg-buffer-list-finalization-hook nil
 
  "Functions in this hook can modify `wg-temp-buffer-list'
 
arbitrarily, provided its final value is still a list of the
 
names of live buffer.  Any final adjustments the user wishes to
 
make to the filtered buffer list before ido/iswitchb get ahold of
 
it should be made here."
 
  :type 'hook
 
  :group 'workgroups)
 

	
 
(defcustom wg-pre-window-configuration-change-hook nil
 
  "Hook run before any function that triggers
 
`window-configuration-change-hook'."
 
  :type 'hook
 
  :group 'workgroups)
 

	
 

	
 
;; save and load customization
 
(defcustom wg-use-default-session-file (not (daemonp))
 
  "Generally, non-nil means take care of saving and loading automatically,
 
and nil means leave it up to the user.
 

	
 
FIXME: docstring this"
 
  :type 'boolean
 
  :group 'workgroups)
 

	
 
(defcustom wg-default-session-file
 
  "~/.emacs_workgroups"
 
  "Default filename to be used to save workgroups."
 
  :type 'file
 
  :group 'workgroups)
 

	
 
(defcustom wg-open-this-wg nil
 
  "Try to open this workgroup on start. If nil - nothing happens."
 
  :type 'string
 
  :group 'workgroups)
 

	
 
(defcustom wg-switch-to-first-workgroup-on-find-session-file t
 
  "Non-nil means switch to the first workgroup in a session file
 
when it's found with `wg-find-session-file'."
 
  :type 'boolean
 
  :group 'workgroups)
 

	
 
(defcustom wg-emacs-exit-save-behavior 'save
 
  "Determines save behavior on Emacs exit.
 
Possible values:
 

	
 
`ask'           Ask the user whether to save if there are unsaved changes
 

	
 
`save'          Call `wg-save-session' when there are unsaved changes
 

	
 
Anything else   Exit Emacs without saving changes"
 
  :type 'symbol
 
  :group 'workgroups)
 

	
 
(defcustom wg-workgroups-mode-exit-save-behavior 'save
 
  "Determines save behavior on `workgroups-mode' exit.
 
Possible values:
 

	
 
`ask'           Ask the user whether to saveif there are unsaved changes
 

	
 
`save'          Call `wg-save-session' when there are unsaved changes
 

	
 
Anything else   Exit `workgroups-mode' without saving changes"
 
  :type 'symbol
 
  :group 'workgroups)
 

	
 

	
 
;; minibuffer customization
 

	
 
(defcustom wg-confirm-on-get-workgroup-create nil
 
  "Non-nil means request confirmation before creating a new
 
workgroup when `wg-get-workgroup-create' is called with a string
 
that doesn't name an existing workgroup."
 
  :type 'boolean
 
  :group 'workgroups)
 

	
 
(defcustom wg-no-confirm-on-destructive-operation nil
 
  "Non-nil means don't request confirmation before various
 
destructive operations, like `wg-reset'."
 
  :type 'boolean
 
  :group 'workgroups)
 

	
 
(defcustom wg-minibuffer-message-timeout 0.75
 
  "Bound to `minibuffer-message-timeout' when messaging while the
 
minibuffer is active."
 
  :type 'float
 
  :group 'workgroups)
 

	
 

	
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;
 
;; FIXME:
 
;;
 
;; Only set `wg-workgroup-base-wconfig' on `wg-write-session-file' or
 
;; `delete-frame' and only with the most recently changed working-wconfig.
 
;; Then, since it's not overwritten on every call to
 
;; `wg-workgroup-working-wconfig', its restoration can be retried after manually
 
;; recreating buffers that couldn't be restored.  So it takes over the
 
;; 'incorrect restoration' portion of the base wconfig's duty.  All that leaves
 
;; to base wconfigs is that they're a saved wconfig the user felt was important.
 
;; So why not allow more of of them?  A workgroup could stash an unlimited
 
;; number of wconfigs.
 
;;
 
;; TODO:
 
;;
 
;;   * Write new commands for restoring stashed wconfigs
 
;;
 
;;   * Add this message on improper restoration of `base-wconfig':
 
;;
 
;;       "Unable to restore 'buf1', 'buf2'... Hit C-whatever to retry after
 
;;        manually recreating these buffers."
 
;;
 
;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 

	
 

	
 
;; workgroup restoration customization
 

	
 
;; TODO: possibly add `buffer-file-coding-system', `text-scale-mode-amount'
 
(defcustom wg-buffer-local-variables-alist
 
  `((major-mode nil wg-deserialize-buffer-major-mode)
 
    (mark-ring wg-serialize-buffer-mark-ring wg-deserialize-buffer-mark-ring)
 
    (left-fringe-width nil nil)
 
    (right-fringe-width nil nil)
 
    (fringes-outside-margins nil nil)
 
    (left-margin-width nil nil)
 
    (right-margin-width nil nil)
 
    (vertical-scroll-bar nil nil))
 
  "Alist mapping buffer-local variable symbols to serdes functions.
 

	
 
The `car' of each entry should be a buffer-local variable symbol.
 

	
 
The `cadr' of the entry should be either nil or a function of no
 
arguments.  If nil, the variable's value is used as-is, and
 
should have a readable printed representation.  If a function,
 
`funcall'ing it should yield a serialization of the value of the
 
variable.
 

	
 
The `caddr' of the entry should be either nil or a function of
 
one argument.  If nil, the serialized value from above is
 
assigned to the variable as-is.  It a function, `funcall'ing it
 
on the serialized value from above should do whatever is
 
necessary to properly restore the original value of the variable.
 
For example, in the case of `major-mode' it should funcall the
 
value (a major-mode function symbol) rather than just assigning
 
it to `major-mode'."
 
  :type 'alist
 
  :group 'workgroups)
 

	
 
(defcustom wg-special-buffer-serdes-functions
 
  '(wg-serialize-comint-buffer
 
    wg-serialize-speedbar-buffer)
 
  "List of functions providing special buffer serialization/deserialization.
 

	
 
Use `wg-support' macro and this variable will be filled
 
automatically.
 

	
 
An entry should be either a function symbol or a lambda, and should
 
accept a single Emacs buffer object as an argument.
 

	
 
When a buffer is to be serialized, it is passed to each of these
0 comments (0 inline, 0 general)