Changeset - 47a5e584b06f
[Not reviewed]
0 2 9
Sergey Pashinin - 11 years ago 2014-08-31 12:49:12
sergey@pashinin.com
Docs
11 files changed with 568 insertions and 4 deletions:
0 comments (0 inline, 0 general)
doc/_static/list-packages.png
Show inline comments
 
new file 100644
 
binary diff not shown
Show images
doc/conf.py
Show inline comments
 
@@ -14,6 +14,7 @@
 

	
 
import sys
 
import os
 
import sphinx_rtd_theme
 

	
 
# If extensions (or modules to document with autodoc) are in another directory,
 
# add these directories to sys.path here. If the directory is relative to the
 
@@ -99,6 +100,7 @@ pygments_style = 'sphinx'
 
# The theme to use for HTML and HTML Help pages.  See the documentation for
 
# a list of builtin themes.
 
html_theme = 'default'
 
html_theme = "sphinx_rtd_theme"
 

	
 
# Theme options are theme-specific and customize the look and feel of a theme
 
# further.  For a list of options available for each theme, see the
 
@@ -106,7 +108,7 @@ html_theme = 'default'
 
#html_theme_options = {}
 

	
 
# Add any paths that contain custom themes here, relative to this directory.
 
#html_theme_path = []
 
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
 

	
 
# The name for this set of Sphinx documents.  If None, it defaults to
 
# "<project> v<release> documentation".
doc/guide/contribute.rst
Show inline comments
 
new file 100644
 
.. _contribute:
 

	
 
==========
 
Contribute
 
==========
 

	
 
Start using the git repo
 
========================
 

	
 
1. Remove ``workgroups2`` package you installed from Melpa
 
#. Clone `the repo from Github
 
   <https://github.com/pashinin/workgroups2>`_ (or make a submodule in
 
   your .emacs repo)
 

	
 
   .. code-block:: bash
 

	
 
       cd ~/some/path
 
       git clone https://github.com/pashinin/workgroups2.git
 

	
 
   .. code-block:: bash
 

	
 
       cd ~/.emacs.d
 
       git submodule add git://github.com/pashinin/workgroups2.git workgroups2
 

	
 
#. Add repo's ``src/`` directory to ``load-path`` and then use a simple
 
   ``(require ...)``
 

	
 
   .. code-block:: cl
 

	
 
       (add-to-list 'load-path "~/.emacs.d/workgroups2/src")
 
       (require 'workgroups2)
 

	
 
       ;; your existing settings...
 
       (workgroups-mode 1)
 

	
 

	
 
Then to make changes I think you need to understand :doc:`How this
 
extension work <how-it-works>`.
 

	
 
Modify something
 
================
doc/guide/data-structures.rst
Show inline comments
 
new file 100644
 
.. _data_structures:
 

	
 
=================
 
 Data structures
 
=================
 

	
 
Let's look at ~/.workgroups file:
 

	
 
.. code-block:: cl
 

	
 
    [cl-struct-wg-session "0G3A08BU1E35GEA0-18GPMY" ...
 
      ([cl-struct-wg-workgroup "0G3A08D8APKR11T4-1C1G10" "Tasks" ...
 
         [cl-struct-wg-wconfig "0GGI0JY4B3HD0WEO-86RSR3" ...
 
            [cl-struct-wg-wtree ...
 
               ([cl-struct-wg-win ...
 
                [cl-struct-wg-win ...
 

	
 

	
 
General info
 
============
 

	
 
All these structs (better to say functions to work with these objects)
 
are created with :keyword:`wg-defstruct` macro. For example for:
 

	
 
.. code-block:: cl
 

	
 
    (wg-defstruct wg session
 
      (uid (wg-generate-uid))
 
      (field-2)
 
      ...
 

	
 
wg-defstruct creates functions like ``wg-make-session``,
 
``wg-copy-session`` and ``wg-session-...``, (to manipulate
 
structures). Then you will have ``(wg-session-field-2 obj)`` and other
 
defined fields to read properties of this object.
 

	
 
To set values ``(setf ...)`` function is used.
 

	
 
Example for current session object:
 

	
 
.. code-block:: cl
 

	
 
     ;; Read
 
     (wg-session-file-name (wg-current-session))         ; Get a filename of current session
 
     (wg-workgroup-parameters (wg-current-workgroup))    ; Get workgroup parameters
 

	
 
     ;; Write (used just before saving session to file)
 
     (setf (wg-session-file-name (wg-current-session)) filename)    ; Set session filename
 
     (setf (wg-session-version (wg-current-session)) wg-version)    ; Write workgroups version
 

	
 
.. warning::
 

	
 
   Changing these defstructs themselves may break everyone's session
 
   files. That's why many of them have :ref:`parameters` field. This one
 
   is exactly for extending saved information.
 

	
 

	
 
How to work with these structures?
 
----------------------------------
 

	
 
Ok, we define a session structure, and you can get the
 
value of it with (wg-current-session)
 

	
 
wg-defstruct creates functions like wg-session-..., wg-make-session (to
 
manipulate structures). So if you have (wg-defstruct wg session ...) -
 
then you have wg-session-file-name and other defined fields.
 

	
 
.. _wg-session:
 

	
 
Session
 
=======
 

	
 
The ``session`` object is the top level "class" that has workgroups in it.
 

	
 
.. code-block:: cl
 

	
 
    (wg-defstruct wg session
 
      (uid (wg-generate-uid))
 
      (name)
 
      (modified)
 
      (parameters)
 
      (file-name)
 
      (version wg-version)
 
      (workgroup-list)
 
      (buf-list))
 

	
 
.. note::
 

	
 
   List of buffers is a common pool for all workgroups. When you open a
 
   file (doesn't matter in which workgroup) - the corresponding
 
   :ref:`wg-buffer` object will be added in
 
   ``wg-session-buf-list``
 

	
 
.. _wg-workgroup:
 

	
 
Workgroup
 
=========
 

	
 
``workgroups`` contain frame states (that includes window configuration)
 

	
 
.. code-block:: cl
 

	
 
    (wg-defstruct wg workgroup
 
      (uid (wg-generate-uid))
 
      (name)
 
      (modified)
 
      (parameters)
 
      (base-wconfig)
 
      (selected-frame-wconfig)
 
      (saved-wconfigs)
 
      (strong-buf-uids)
 
      (weak-buf-uids))
 

	
 
.. _wg-wconfig:
 

	
 
Wconfig
 
=======
 

	
 
.. code-block:: cl
 

	
 
    (wg-defstruct wg wconfig
 
      (uid (wg-generate-uid))
 
      (name)
 
      (parameters)
 
      (left)
 
      (top)
 
      (width)
 
      (height)
 
      (vertical-scroll-bars)
 
      (scroll-bar-width)
 
      (wtree))
 

	
 
What's the difference between wconfig and wtree? Well a workgroup can
 
have several wconfigs (buffer layouts). But to keep it simple let's say
 
each workgroup has only 1 wconfig.
 

	
 
wconfig = wtree + additional parameters
 

	
 
.. _wg-wtree:
 

	
 
Wtree
 
=====
 

	
 
.. code-block:: cl
 

	
 
     (wg-defstruct wg wtree
 
       (uid)
 
       (dir)
 
       (edges)
 
       (wlist))
 

	
 

	
 
.. _wg-win:
 

	
 
Win
 
===
 

	
 
.. code-block:: cl
 

	
 
     (wg-defstruct wg win
 
       (uid)
 
       (parameters)
 
       (edges)
 
       (point)
 
       (start)
 
       (hscroll)
 
       (dedicated)
 
       (selected)
 
       (minibuffer-scroll)
 
       (buf-uid))
 

	
 

	
 
.. _wg-buffer:
 

	
 
Buffer
 
======
 

	
 

	
 
.. _parameters:
 

	
 
Parameters
 
==========
 

	
 
Changing main structures may lead to huge problems in
 
compatibility. That's why there are parameters for :ref:`wg-session`,
 
:ref:`wg-workgroup`, :ref:`wg-wconfig` and :ref:`wg-win`
 
objects. They allow you to save your custom data.
 

	
 
For example to set (key, value) pair for current workgroup:
 

	
 
.. code-block:: cl
 

	
 
     ;; Write (key, value)
 
     (wg-set-workgroup-parameter
 
      'ecb                                            ; name
 
      (and (boundp 'ecb-minor-mode) ecb-minor-mode))  ; value
 

	
 
Usually these functions are called like:
 

	
 
.. code-block:: cl
 

	
 
     wg-<object>-parameter          ; to read
 
     wg-set-<object>-parameter      ; to set
 
     wg-remove-<object>-parameter   ; to remove parameter
 

	
 
For session: wg-session-parameter, wg-set-session-parameter, wg-remove-session-parameter
 
For workgroup: wg-workgroup-parameter, wg-set-workgroup-parameter, wg-remove-workgroup-parameter
doc/guide/how-it-works.rst
Show inline comments
 
new file 100644
 
===================
 
 How does it work?
 
===================
 

	
 
.. note::
 

	
 
   The most important part to understand is :doc:`Data structures
 
   <data-structures>`. After that it's easy to write code in other
 
   parts.
 

	
 

	
 
.. _serialize:
 

	
 
Serialization / Deserialization of objects
 
==========================================
 

	
 
In Emacs we have many types of objects like:
 

	
 
- ``#<buffer tests.el>``
 
- ``#<marker at 3427 in tests.el>``
 
- simple ``"string"``
 
- integers 123
 
- ... and other
 

	
 
And we have to represent them as text to save. This is done using
 
``wg-pickel`` and functions defined in this var:
 

	
 
.. code-block:: cl
 

	
 
   (defvar wg-pickel-object-serializers
 
     '((integer    . identity)
 
       (float      . identity)
 
       (string     . identity)
 
       (symbol     . wg-pickel-symbol-serializer)
 
       (cons       . wg-pickel-cons-serializer)
 
       (vector     . wg-pickel-vector-serializer)
 
       (hash-table . wg-pickel-hash-table-serializer)
 
       (buffer     . wg-pickel-buffer-serializer)
 
       (marker     . wg-pickel-marker-serializer))
 
     "Alist mapping types to object serialization functions.")
 

	
 
So when you meet an object that cannot be represented as text - you:
 

	
 
1. Add it's type in this variable
 
#. Write mentioned "serializer" function itself
 

	
 
For example for "buffer" objects:
 

	
 
.. code-block:: cl
 

	
 
   (defun wg-pickel-buffer-serializer (buffer)
 
     "Return BUFFER's UID in workgroups buffer list."
 
     (list 'b (wg-add-buffer-to-buf-list buffer)))
 

	
 
'b - is just a marker that will tell to run
 
``wg-pickel-deserialize-buffer`` when restoring a buffer.
 

	
 
Last element is buffer UID and it is enough to restore the buffer with
 
``(wg-restore-buffer (wg-find-buf-by-uid uid))``
 

	
 
Loading a session file
 
======================
 

	
 
It is done in ``wg-open-session``. First you read a
 
:ref:`Session object <wg-session>` from file in this line:
 

	
 
.. code-block:: cl
 

	
 
   (let ((session (read (f-read-text filename))))
 
     ...
 

	
 
Then you just switch to 1 of the saved workgroups in this object
 
according to settings.
 

	
 

	
 
Saving session
 
==============
 

	
 
Writing objects to file is done in... (function stack):
 

	
 
    wg-write-sexp-to-file
 
        wg-pickel-all-session-parameters
 
            wg-pickel-workgroup-parameters
 
                wg-pickel <-- main function
 

	
 
So the main function to transform Lisp objects to strings is ``wg-pickel``.
 

	
 
Switching workgroups
 
====================
doc/guide/installation.rst
Show inline comments
 
new file 100644
 
==============
 
 Installation
 
==============
 

	
 
Very simple with recent Emacs. Make sure you have these lines:
 

	
 
   .. code-block:: cl
 

	
 
       (require 'package)
 
       (add-to-list 'package-archives
 
                    '("melpa" . "http://melpa.milkbox.net/packages/") t)
 

	
 
before
 

	
 
   .. code-block:: cl
 

	
 
       (package-initialize)
 

	
 
Then type :kbd:`M-x list-packages`
 

	
 
.. image:: /_static/list-packages.png
 
   :align: center
 

	
 
mark ``workgroups2`` with :kbd:`i` and install with :kbd:`x`.
 

	
 
Then :doc:`Configure and activate workgroups-mode <usage>`.
doc/guide/problems.rst
Show inline comments
 
new file 100644
 
==========
 
 Problems
 
==========
 

	
 
.. contents:: You do have problems, right?
 
   :local:
 

	
 

	
 
Buffer was not restored
 
=======================
 

	
 
I doubt it was a simple file buffer (or `report a bug
 
<https://github.com/pashinin/workgroups2/issues/new>`_).
 

	
 
.. warning::
 

	
 
   You know ``major-mode`` you use **better than me**. So please if you
 
   ask to add support for any particular ``major-mode`` - write how you
 
   install, configure and run yours.
 

	
 
Such complex buffers are called "special buffers". A simple way to
 
restore them is to use ``wg-support`` macro:
 

	
 
.. code-block:: cl
 

	
 
     (wg-support 'inferior-emacs-lisp-mode 'ielm
 
       `((deserialize . ,(lambda (buffer vars)
 
                           (ielm) (get-buffer "*ielm*")))))
 

	
 
To understand how this works - see :doc:`special-buffers`
 

	
 
Restored, but not the way I want
 
--------------------------------
 

	
 
`Discuss it <https://github.com/pashinin/workgroups2/issues/new>`_
doc/guide/special-buffers.rst
Show inline comments
 
new file 100644
 
=================
 
 Special buffers
 
=================
 

	
 
TODO
doc/guide/tests.rst
Show inline comments
 
new file 100644
 
.. _tests:
 

	
 
=======
 
 Tests
 
=======
 

	
 
Tests are cool now. To run them just use:
 

	
 
   .. code-block:: bash
 

	
 
       make deps
 
       make testgui
 

	
 
Tests also run automatically on `Travis-CI
 
<https://travis-ci.org/pashinin/workgroups2/builds>`_ using the GUI
 
version of Emacs. So you can tests any frames as on your
 
desktop.
 

	
 
Tests themselves are in ``tests/workgroups2-tests.el``
 

	
 

	
 
Serialization tests
 
===================
 

	
 
If you see an error like this:
 

	
 
   .. code-block:: cl
 

	
 
        wg-add-buffer-to-buf-list(nil)
 
        wg-pickel-marker-serializer(#<marker in no buffer>)
 
        #[(obj id) "..." [id obj result wg-pickel-object-serializer] 3](#<marker in no buffer> 18)
 
        maphash(#[(obj id) "..." [id obj result wg-pickel-object-serializer] 3] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8 data (((#<buffer todo-orgx.org> #<marker at 1 in todo-orgx.org> #<marker at 158366 in todo-orgx.org>) (#<buffer refile-orgx.org> #<marker at 39 in refile-orgx.org> #<marker at 39 in refile-orgx.org>) (nil #<marker in no buffer> #<marker in no buffer>)) 0 (#<buffer todo-orgx.org> #<marker at 1 in todo-orgx.org> #<marker at 158366 in todo-orgx.org>) 1 #<buffer todo-orgx.org> 2 (#<marker at 1 in todo-orgx.org> #<marker at 158366 in todo-orgx.org>) 3 #<marker at 1 in todo-orgx.org> 4 (#<marker at 158366 in todo-orgx.org>) 5 #<marker at 158366 in todo-orgx.org> 6 nil 7 ((#<buffer refile-orgx.org> #<marker at 39 in refile-orgx.org> #<marker at 39 in refile-orgx.org>) (nil #<marker in no buffer> #<marker in no buffer>)) 8 (#<buffer refile-orgx.org> #<marker at 39 in refile-orgx.org> #<marker at 39 in refile-orgx.org>) 9 #<buffer refile-orgx.org> 10 (#<marker at 39 in refile-orgx.org> #<marker at 39 in refile-orgx.org>) 11 #<marker at 39 in refile-orgx.org> 12 (#<marker at 39 in refile-orgx.org>) 13 #<marker at 39 in refile-orgx.org> 14 ((nil #<marker in no buffer> #<marker in no buffer>)) 15 (nil #<marker in no buffer> #<marker in no buffer>) 16 (#<marker in no buffer> #<marker in no buffer>) 17 #<marker in no buffer> 18 (#<marker in no buffer>) 19 #<marker in no buffer> 20 ...)))
 
        wg-pickel-serialize-objects(#s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8 data (((#<buffer todo-orgx.org> #<marker at 1 in todo-orgx.org> #<marker at 158366 in todo-orgx.org>) (#<buffer refile-orgx.org> #<marker at 39 in refile-orgx.org> #<marker at 39 in refile-orgx.org>) (nil #<marker in no buffer> #<marker in no buffer>)) 0 (#<buffer todo-orgx.org> #<marker at 1 in todo-orgx.org> #<marker at 158366 in todo-orgx.org>) 1 #<buffer todo-orgx.org> 2 (#<marker at 1 in todo-orgx.org> #<marker at 158366 in todo-orgx.org>) 3 #<marker at 1 in todo-orgx.org> 4 (#<marker at 158366 in todo-orgx.org>) 5 #<marker at 158366 in todo-orgx.org> 6 nil 7 ((#<buffer refile-orgx.org> #<marker at 39 in refile-orgx.org> #<marker at 39 in refile-orgx.org>) (nil #<marker in no buffer> #<marker in no buffer>)) 8 (#<buffer refile-orgx.org> #<marker at 39 in refile-orgx.org> #<marker at 39 in refile-orgx.org>) 9 #<buffer refile-orgx.org> 10 (#<marker at 39 in refile-orgx.org> #<marker at 39 in refile-orgx.org>) 11 #<marker at 39 in refile-orgx.org> 12 (#<marker at 39 in refile-orgx.org>) 13 #<marker at 39 in refile-orgx.org> 14 ((nil #<marker in no buffer> #<marker in no buffer>)) 15 (nil #<marker in no buffer> #<marker in no buffer>) 16 (#<marker in no buffer> #<marker in no buffer>) 17 #<marker in no buffer> 18 (#<marker in no buffer>) 19 #<marker in no buffer> 20 ...)))
 
        wg-pickel(((#<buffer todo-orgx.org> #<marker at 1 in todo-orgx.org> #<marker at 158366 in todo-orgx.org>) (#<buffer refile-orgx.org> #<marker at 39 in refile-orgx.org> #<marker at 39 in refile-orgx.org>) (nil #<marker in no buffer> #<marker in no buffer>)))
 
        ...
 

	
 
then we have a problem in ``wg-pickel`` function. More precisely object
 
``#<marker in no buffer>`` cannot be serialized. And that was a bug.
 

	
 
To create a test in ``workgroups2-tests.el`` for such situation find this:
 

	
 
   .. code-block:: cl
 

	
 
        (defmacro test-pickel (value)
 
          "Test `wg-pickel' `wg-unpickel' on VALUE."
 
          `(eq (wg-unpickel (wg-pickel ,value)) ,value))
 

	
 
        (ert-deftest 110-wg-pickel ()
 
          (test-pickel 123)
 
          (test-pickel "str")
 
          (test-pickel 'symbol)
 
          (test-pickel (current-buffer))  ; #<buffer tests.el>
 
          (test-pickel (point-marker))    ; #<marker at 3427 in tests.el>
 
          (test-pickel (make-marker))     ; #<marker in no buffer>
 
          (test-pickel (list 'describe-variable 'help-xref-stack-item (get-buffer "*Help*")))
 
          )
 

	
 
And pass an object that cannot be serialized and should be checked. Then
 
you need to fix something in ``wg-pickel``, see :ref:`serialize`.
doc/guide/usage.rst
Show inline comments
 
new file 100644
 
=======
 
 Usage
 
=======
 

	
 
The whole config should look like this:
 

	
 
.. code-block:: cl
 

	
 
   (require 'workgroups2)
 
   ;; Change some settings
 
   (workgroups-mode 1)        ; put this one at the bottom of .emacs (init.el)
 

	
 
Now you activated ``workgroups-mode``.
 

	
 
Basic commands
 
==============
 

	
 
Most commands are bound to both :kbd:`<prefix> <key>` and :kbd:`<prefix> C-<key>`.
 

	
 
By default prefix is: :kbd:`C-c z` (To change it - see settings below)
 

	
 
.. code-block:: cl
 

	
 
  <prefix> <key>
 
  <prefix> c          ; create workgroup
 
  <prefix> A          ; rename workgroup
 
  <prefix> k          ; kill workgroup
 
  <prefix> v          ; switch to workgroup
 
  <prefix> C-s        ; save session
 
  <prefix> C-f        ; load session
 

	
 

	
 
Settings
 
========
 

	
 
.. code-block:: cl
 

	
 
   (require 'workgroups2)
 
   ;; Your settings here
 

	
 
   ;;(setq wg-session-load-on-start t)    ; default: (not (daemonp))
 

	
 
   ;; Change prefix key (before activating WG)
 
   (setq wg-prefix-key (kbd "C-c z"))
 

	
 
   ;; Change workgroups session file
 
   (setq wg-session-file "~/.emacs.d/.emacs_workgroups")
 

	
 
   ;; Set your own keyboard shortcuts to reload/save/switch WGs:
 
   ;; "s" == "Super" or "Win"-key, "S" == Shift, "C" == Control
 
   (global-set-key (kbd "<pause>")     'wg-reload-session)
 
   (global-set-key (kbd "C-S-<pause>") 'wg-save-session)
 
   (global-set-key (kbd "s-z")         'wg-switch-to-workgroup)
 
   (global-set-key (kbd "s-/")         'wg-switch-to-previous-workgroup)
 

	
 
   (workgroups-mode 1)   ; put this one at the bottom of .emacs
 

	
 

	
 
More settings
 
-------------
 

	
 
You can use :kbd:`M-x customize-group RET workgroups` to see all
 
variables and faces to change.
 

	
 
.. code-block:: cl
 

	
 
   ;; What to do on Emacs exit / workgroups-mode exit?
 
   (setq wg-emacs-exit-save-behavior           'save)      ; Options: 'save 'ask nil
 
   (setq wg-workgroups-mode-exit-save-behavior 'save)      ; Options: 'save 'ask nil
 

	
 
   ;; Mode Line changes
 
   ;; Display workgroups in Mode Line?
 
   (setq wg-mode-line-display-on t)          ; Default: (not (featurep 'powerline))
 
   (setq wg-flag-modified t)                 ; Display modified flags as well
 
   (setq wg-mode-line-decor-left-brace "["
 
         wg-mode-line-decor-right-brace "]"  ; how to surround it
 
         wg-mode-line-decor-divider ":")
 

	
 
Hooks
 
-----
 

	
 
Hooks' names can tell when they are executed
 

	
 
.. code-block:: cl
 

	
 
   workgroups-mode-hook                    ; when `workgroups-mode' is turned on
 
   workgroups-mode-exit-hook               ; `workgroups-mode' is turned off
 
   wg-before-switch-to-workgroup-hook
 
   wg-after-switch-to-workgroup-hook
doc/index.rst
Show inline comments
 
@@ -3,14 +3,26 @@
 
   You can adapt this file completely to your liking, but it should at least
 
   contain the root `toctree` directive.
 

	
 
Welcome to Workgroups2's documentation!
 
=======================================
 
===================================
 
Workgroups2 - Emacs session manager
 
===================================
 

	
 
Like it: *The original workgroups was already wonderful, the best window
 
configuration manager for Emacs. The new maintainer has lifted the
 
package from merely awesome to wild ecstasy*.
 

	
 
Contents:
 

	
 
.. toctree::
 
   :maxdepth: 2
 

	
 
   guide/installation
 
   guide/usage
 
   guide/how-it-works
 
   guide/data-structures
 
   guide/tests
 
   guide/problems
 
   guide/contribute
 

	
 

	
 
Indices and tables
 
@@ -19,4 +31,3 @@ Indices and tables
 
* :ref:`genindex`
 
* :ref:`modindex`
 
* :ref:`search`
 

	
0 comments (0 inline, 0 general)