diff options
Diffstat (limited to '')
28 files changed, 8177 insertions, 0 deletions
diff --git a/emacs.d/lisp/rudel/.svn/text-base/.bzrignore.svn-base b/emacs.d/lisp/rudel/.svn/text-base/.bzrignore.svn-base new file mode 100644 index 0000000..5f6312e --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/.bzrignore.svn-base @@ -0,0 +1,2 @@ +*.elc +Makefile diff --git a/emacs.d/lisp/rudel/.svn/text-base/ChangeLog.svn-base b/emacs.d/lisp/rudel/.svn/text-base/ChangeLog.svn-base new file mode 100644 index 0000000..03c4fab --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/ChangeLog.svn-base @@ -0,0 +1,2403 @@ +2009-10-22 Jan Moringen <scymtym@users.sourceforge.net> + + * TODO (Future): added BEEP and SubEthaEdit tasks + +2009-10-15 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-version): bumped to 0.3 + * Project.ede (project rudel): bumped version to 0.3 + + * TODO: whitespace fixes + (Milestone rudel-0.4): new; focus on telepathy transport + (Milestone rudel-0.3): added infinote, document trees + +2009-10-13 Jan Moringen <scymtym@users.sourceforge.net> + + * TODO: new file; TODO items for future development and releases + +2009-10-12 Phil Hagelberg <phil@enigma> + + * rudel-mode.el + (rudel-mode-line-publish-state--add-indicator-to-mode-line): + Replace reference to mode-line indicator that was not present in + Emacs 22. + + * rudel-compat.el: add rudel-get-coding-system wrapper function. + * rudel-obby-util.el (with-parsed-args): Replace call to + Emacs23-specific coding-system-from-name function with + rudel-get-coding-system. + + rudel-compat.el: Add string-match-p if not present. (< Emacs 23) + + * rudel-mode.el, rudel-overlay.el: Move use of :safe flag from + defcustom to a separate put. Required for Emacs 22 compatibility. + + * rudel-loaddefs.el: Only require rudel-zeroconf if zeroconf is + available. + +2009-10-12 Jan Moringen <scymtym@users.sourceforge.net> + + * jupiter/jupiter-delete.el (jupiter-delete::jupiter-transform): + fixed error message + +2009-10-08 Jan Moringen <scymtym@users.sourceforge.net> + + * jupiter/jupiter.el (header): downcased keywords + (object-print): new method; add revisions and log length to string + * jupiter/jupiter-nop.el (header): downcased keywords; cosmetic + representation changes to "commentary" section + * jupiter/jupiter-insert.el (header): downcased keywords; cosmetic + changes to "commentary" section + (object-print): new method; add start, end, length and data to + string representation + * jupiter/jupiter-delete.el (header): downcased keywords; cosmetic + changes to "commentary" section + (jupiter-transform): cosmetic changes + (object-print): new method; add position and length to string + representation + * jupiter/jupiter-compound.el (header): downcased keywords; + cosmetic changes to "commentary" section + (object-print): new method; add number of children to string + representation + +2009-10-07 Jan Moringen <scymtym@users.sourceforge.net> + + * doc/card.tex (Session Initiation): mention configured sessions; + explain Zeroconf-advertised session in more detail + +2009-10-06 Jan Moringen <scymtym@users.sourceforge.net> + + * doc/card.tex (Joining a Session ...): added global and user + passwords + + * rudel.el (rudel-version): use list representation instead of + float + (rudel-allocate-buffer-function): added documentation string + + * INSTALL (COMPILING): fixed typo + +2009-10-06 Phil Hagelberg <phil@enigma> + + * README (JOINING): Mention `rudel-configured-sessions' + customization. + + * README (INTRODUCTION): emphasize obby backend being the only + supported one so far + (JOINING): update example session with passwords. + + * rudel-loaddefs.el: Add autoloads for rudel-host-session and + rudel-speedbar + +2009-10-05 Phil Hagelberg <phil@enigma> + + * README: Mention Eshell issue and license. + +2009-10-03 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-compat.el (make-pulsing-progress-reporter): removed; + `make-progress-reporter' is sufficient + (progress-reporter-pulse): store index in the car of the reporter; + set last update time of the reporter + * obby/rudel-obby.el (rudel-connect): use `make-progress-reporter' + instead of `make-pulsing-progress-reporter' + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-subscribe-to): cosmetic changes in + status messages + + * ChangeLog: updated + +2009-10-02 Phil Hagelberg <phil@enigma> + + * INSTALL: Mention CEDET's inclusion in Emacs + + * rudel-state-machine.el (rudel-state-wait): update progress + reporter usage to match rudel-compat.el + + * rudel-compat.el: Use updated progress reporters + (progress-reporter-update): may be used by pulsing reporters too + (make-progress-reporter): nil max value returns pulsing reporter + (progress-reporter-force-update): may be used by pulsing reporters + too + (progress-reporter-pulsing-p): added + (progress-reporter-pulse): removed message change option + +2009-10-02 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-state-machine.el (rudel-state-wait): accept callback + function instead of message; adjusted documentation string + * obby/rudel-obby.el (rudel-obby-backend::rudel-connect): when + calling `rudel-state-wait', provide a callback; the callback + controls a progress reporter + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-subscribe-to): when calling + `rudel-state-wait', provide a callback; the callback controls a + progress reporter + + * rudel-compat.el (progress-reporter-pulse): store index as float + + * obby/rudel-obby-client.el + (rudel-obby-client-state-idle::rudel-obby/obby_document_create): + cosmetic changes of printed messages + (rudel-obby-client-state-idle::rudel-obby/obby_document_remove): + cosmetic changes of printed messages + + * rudel.el (rudel-session::rudel-remove-document): when necessary, + detach document first; added documentation string + (rudel-document::rudel-attached-p): new method; return non-nil + when document is attached to a buffer + + * obby/rudel-obby-client.el + (rudel-obby-client-state-idle::rudel-obby/net6_client_part): + promoted warning severity to :warning + (rudel-obby-client-state-idle::rudel-obby/obby_document_remove): + fixed lookup of document; added warning message in case it is not + found + (rudel-obby-client-state-idle::rudel-obby/obby_document/rename): + promoted warning severity to :warning + (rudel-obby-connection::rudel-unpublish): new method; ask server + to remove a document + +2009-10-01 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-state-machine.el (rudel-state-wait): fixed progress range + [0, 100] -> [0, 1]; fixed reference to reporter object + * obby/rudel-obby.el (rudel-obby-send): removed remnants of calls + to `working-*' functions; call `progress-reporter-pulse' just + before `progress-reporter-done' + +2009-09-30 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-compat.el: only define pulsing progress reporter when + Emacs does not have one itself + (header): downcased keywords + (make-pulsing-progress-reporter): renamed + `make-progress-reporter-pulse' -> + `make-pulsing-progress-reporter'; cosmetic changes; explanatory + comment + (progress-reporter-pulse): added documentation string + Suggested by Phil Hagelberg + + * rudel-compat.el (progress-pulse-values): new variable; indicator + strings used by pulsing progress reporter + (make-progress-reporter-pulse): new function; creates pulsing + progress reporter + (progress-reporter-pulse): new function; updates pulsing progress + reporter + Suggested by Phil Hagelberg + +2009-09-29 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-server.el + (rudel-obby-server-state-before-join::rudel-obby/net6_client_login): + accept two additional arguments: global-password and user-password + + * rudel-session-initiation.el (rudel-configured-sessions): + improved documentation string + +2009-09-29 Jan Moringen <scymtym@users.sourceforge.net> + + * INSTALL (REQUIREMENTS): wording + (INSTALLING): mention other things that cause rudel to be + autoloaded; minor cosmetic changes + (COMPILING): fixed filename compile.el -> rudel-compile.el + + * rudel-compile.el (header): added copyright and meta data + (code): let-bind rudel-dir; call `byte-recompile-directory' just + once since it operates recursively + +2009-09-28 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-server.el (header): better documentation + (require rudel-state-machine): now required for state machine + style handling of client connections + (require rudel-obby-state): now required; provides base class for + states + (rudel-obby-server-state-new): new class; client connection state + new + (rudel-obby-server-state-encryption-negotiate): new class; client connection state + for negotiating encryption + (rudel-obby-server-state-before-join): new class; client connection state + for waiting for login request + (rudel-obby-server-state-new): new class; client connection state + entered after session setup and joining is complete + (rudel-obby-server-connection-states): new variable; list of + states and their symbolic names + (rudel-obby-client): now derived from rudel-state-machine + + * obby/rudel-obby.el (rudel-obby-backend::rudel-ask-connect-info): + check for :global-password and :user-password correctly; do not + put them into the list when they are "" + (rudel-obby-backend::rudel-connect): comment + + * rudel-session-initiation.el + (rudel-configured-sessions-backend::rudel-discover): let + `rudel-session-initiation-adjust-info' do the heavy lifting + (rudel-session-initiation-adjust-info): new function; adjust + arguments that need adjusting in a session information property + list + + * rudel-session-initiation.el (rudel-configured-sessions): more + precise specification of the customization type + +2009-09-27 Phil Hagelberg <technomancy@gmail.com> + + * compile.el: renamed compile.el -> rudel-compile.el + + * INSTALL: Mention new install process using compile.el and + rudel-loaddefs.el. + + * rudel-loaddefs.el: Autoload rudel as one unit instead of + piece-by-piece. Remove eieio dependency from autoloads. + + * compile.el: Perform compilation from Elisp + + * Makefile: Remove error-prone CEDET-autogenerated build scripts. + +2009-09-27 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-session-initiation.el + (rudel-configured-sessions-backend::rudel-discover): fixed a bug + that dropped the last option in each configured session + + * rudel-session-initiation.el (rudel-configured-sessions): new + customization option; contains a list of session information lists + (rudel-ask-protocol-backend::initialize-instance): maybe call next + method + (rudel-configured-sessions-version): new constant; version of the + configured-sessions backend + (rudel-configured-sessions-backend): new class; + configured-sessions backend + (rudel-configured-sessions-backend::initialize-instance): new + method; set version slot + (rudel-configured-sessions-backend::rudel-discover): new method; + "discover" configured sessions + (autoload rudel-add-backend): register + rudel-configured-sessions-backend as a protocol backend + + * rudel-chat.el (rudel-chat-buffer-name): new constant; name chat + log buffer + (rudel-chat-handle-buffer): raise buffer when logging a chat + message + + * rudel-debug.el (header): fixed meta-data and license + (rudel-debug-sent-data-face): added documentation string + (rudel-debug-received-data-face): added documentation string + (rudel-debug-received-processed-data-face): added documentation + string + (rudel-debug-state-face): added documentation string + (rudel-debug-special-face): added documentation string + (rudel-suspend-session-socket): added documentation string + (rudel-resume-session-socket): added documentation string + + * obby/rudel-obby-util.el (rudel-obby-dispatch): use + `display-warning' instead of `warn' + * obby/rudel-obby-state.el (rudel-obby-state::rudel-accept): use + `display-warning' instead of `warn' + (rudel-obby-document-handler::rudel-obby/obby_document): use + `display-warning' instead of `warn' + * obby/rudel-obby-client.el + (rudel-obby-client-state-idle::rudel-obby/net6_client_part): use + `display-warning' instead of `warn' + (rudel-obby-client-state-idle::rudel-obby/obby_document/record): + use `display-warning' instead of `warn' + * rudel-backend.el (rudel-backend-factory::rudel-load-backends): + use `display-warning' instead of `warn' + + * obby/rudel-obby-client.el (require rudel-chat): used when + handling chat messages + (rudel-obby-client-state-idle::rudel-obby/obby_message): new + method; handles obby 'message' messages by dispatching to + `rudel-chat-dispatch-message' + * rudel-chat.el (whole file): new file; handling of incoming chat + messages + * Project.ede (target rudel): added rudel-chat.el + * Makefile (target rudel_LISP): added rudel-chat.el + +2009-09-26 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-state.el (rudel-obby-server-connection-state): + new class; base class for server connection states + (rudel-obby-server-connection-state::rudel-broadcast): new method; + broadcast message to a set of receivers + +2009-09-25 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (rudel-obby-backend::rudel-connect): new + error state they-finalized; handle join-failed error specially + * obby/rudel-obby-client.el (rudel-obby-client-state-join-failed): + improved comments + (rudel-obby-client-state-they-finalized): new state class; used to + indicate that the connection was closed by the peer + (rudel-obby-client-connection-states): added they-finalized + (rudel-obby-connection::rudel-close): switch state machine to + they-finalized + (rudel-obby-connection::rudel-subscribe-to): new error state + they-finalized + + * rudel.el (rudel-client-session::connection): allow nil value + (rudel-client-session::rudel-end): only try to disconnect the + connection if it is non-nil; ignore errors during disconnect + + * obby/rudel-obby-client.el + (rudel-obby-client-state-encryption-start::rudel-obby/net6_encryption_begin): + do not require rudel-tls; do not try to start TLS encryption if + the connection does not support it + * rudel-tls.el (rudel-tls-make-process): mark process as + supporting TLS encryption + + * obby/rudel-obby-state.el (rudel-obby/net6_ping): return nil to + prevent erratic behavior of the state machine + + * rudel-interactive.el (rudel-allocate-buffer-clear-existing): + added missing whitespace in prompt string + +2009-09-24 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-tls.el (rudel-tls-start-tls): changed displayed message + (rudel-tls-wait-init): ignore all lines until "- Simple Client + Mode.*" is received; then switch back old filter + (rudel-tls-wait-handshake): ignore all lines until "- + Compression.*" is received; then switch to established filter + (rudel-tls-established): do not ignore any lines other than + "- Peer has closed the GNUTLS connection" + + * obby/rudel-obby.el (rudel-ask-connect-info): ask for global and + user passwords + * obby/rudel-obby-client.el + (rudel-obby-client-state-joining::rudel-enter): transmit global + and user passwords when available + + * obby/rudel-obby-errors.el + (rudel-obby-error-wrong-global-password): fixed error code + (rudel-obby-error-wrong-user-password): fixed error code + (rudel-obby-error-protocol-version-mismatch): fixed error code + (rudel-obby-error-not-encrypted): fixed error code + * obby/rudel-obby-client.el + (rudel-obby-client-state-joining::rudel-obby/net6_login_failed): + recognize wrong global/user password error codes + + * obby/rudel-obby-debug.el (whole file): new file; debugging + functions for the obby backend + * rudel-debug.el (whole file): new file; debugging functions + + * obby/rudel-obby-errors.el + (rudel-obby-error-wrong-global-password): new constant; error code + for wrong global password + (rudel-obby-error-wrong-user-password): new constant; error code + for wrong user password + (rudel-obby-error-protocol-version-mismatch): new constant; error + code for protocol version mismatch + (rudel-obby-error-not-encrypted): new constant; error code for not + encrypted + + * Project.ede (target rudel): added rudel-transport.el + * Makefile (target rudel_LISP): added rudel-transport.el + * rudel-transport.el (whole file): new file; interface for + transport backends + +2009-09-20 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-remote-operation): added byte -> char + conversion before the operation is applied to the server-side + document; updated comments + + * obby/rudel-obby-server.el (rudel-obby-client::rudel-broadcast): + cosmetic changes + (rudel-obby-client::rudel-obby/net6_client_login): cosmetic + changes; improved comments + (rudel-obby-client::rudel-obby/obby_document): changed + documentation string; cosmetic changes + (rudel-obby-client::rudel-obby/obby_document/record): added a + comment + (rudel-obby-client::rudel-remote-operation): improved comments + + * obby/rudel-obby-server.el (header): added header comment + (rudel-obby-client::rudel-obby/obby_document_create): changed + documentation comment + (rudel-obby-client::rudel-obby/obby_document/subscribe): changed + documentation comment; cosmetic changes + (rudel-obby-client::rudel-obby/obby_document/unsubscribe): + cosmetic changes + (rudel-obby-server::initialize-instance): do not run :after; call + next method + (rudel-obby-server::rudel-broadcast): signal wrong-type-argument + instead of just error; cosmetic changes + (rudel-obby-server::rudel-check-username-and-color): changed + comments + (rudel-obby-server::object-print): new method; generate string + representation with number of clients + +2009-09-19 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document/record/ins): + construct the operation and use `rudel-remote-operation' + (rudel-obby-client::rudel-obby/obby_document/record/del): + construct the operation and use `rudel-remote-operation' + (rudel-obby-client::rudel-remote-operation): new method; transform + and apply an operation object to the server-side document; send + operation to all other clients + (rudel-obby-server::rudel-broadcast): cosmetic changes + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document/record/del): swapped + local and remote revisions in the operation name to be consistent + with record/ins; does not affect behavior + +2009-09-12 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-mode.el (rudel-header-subscriptions--update-from-document): + force mode line update + (rudel-header-subscriptions--update-from-buffer): force mode line + update + (rudel-header-subscriptions-minor-mode): force mode line update + + * rudel-mode.el + (rudel-mode-line-publish-state-unpublished-string): new + customization option; string used to indicate that a buffer is not + published + (rudel-mode-line-publish-state-published-string): new + customization option; string used to indicate that a buffer is + published + (rudel-mode-line-publish-state--update-string): use + `rudel-mode-line-publish-state-unpublished-string' and + `rudel-mode-line-publish-state-unpublished-string' + + * rudel.el (rudel-session::end-hook): new slot; stores handlers of + the end hook + (rudel-session::rudel-end): run end hook + (rudel-session::rudel-join-session): install handler on session + end hook to set `rudel-current-session' to nil + (rudel-session::rudel-end-session): no need to run + rudel-session-end-hook or reset `rudel-current-session' + * rudel-hooks.el (rudel-hooks--session-start): add handler for the + end hook of the session + (rudel-hooks--session-end): remove the handler from end hook of + the session; run the rudel-session-end hook + (rudel-hooks--install-handlers): do install handler for + rudel-session-end hook; this is now done by installing the in the + session object + (rudel-hooks--uninstall-handlers): no need to remove + rudel-session-end hook + + * rudel-util.el (rudel-socket-owner::rudel-state-change): cover + more states + + * obby/rudel-obby-client.el + (rudel-obby-client-state-idle::rudel-obby/obby_document_remove): + implemented, was stub; untested though + +2009-09-10 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-client.el + (rudel-obby-client-state-idle::rudel-obby/net6_client_join): check + whether we have a user object for the specified user id; modify + the existing object if there is one + +2009-09-09 Jan Moringen <scymtym@users.sourceforge.net> + + * zeroconf/Makefile (whole file): regenerated + * wave/Makefile (whole file): regenerated + * Makefile (target all): build target doc + (target doc): new target; build documentation + (target tags): build target tags in doc directory + (target dist): build target dist in doc directory + +2009-09-06 Jan Moringen <scymtym@users.sourceforge.net> + + * telepathy/rudel-telepathy.el (header): fixes + (require rudel-backend): required, since we define a backend + (require rudel-transport): it is a transport backend + (class rudel-telepathy-backend): derived from + rudel-transport-backend + (rudel-telepathy-backend::initialize-instance): new method; set + version slot + (autoloading): upgraded to new backend registration style + + * INSTALL (REQUIREMENTS): mention Avahi + +2009-09-05 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (require rudel-util): required for `rudel-hook-object' + + * rudel-util.el (property svn:executable): removed property + * rudel-overlay.el (property svn:executable): removed property + + * doc/Project.ede (whole file): new file; project file for the + documentation directory + * doc/Makefile (whole file): new file; generated Makefile for the + documentation directory + * doc/card.tex (whole file): new file; reference card for Rudel; + source + * doc/card.pdf (whole file): new file; reference card for Rudel; + PDF + +2009-09-04 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-interactive.el (rudel-read-document): added comment + (rudel-allocate-buffer-clear-existing): handle the case in which + case a buffer with the desired name exists and is attached to a + different document; added some comments + + * rudel-mode.el (header): list all provided modes; bump version + (require rudel-hooks): required for global hooks + (rudel-mode-line-publish-state-string): new variable; buffer + local, holds publish state string for buffer + (rudel-mode-line-publish-state--add-indicator-to-mode-line): new + function; add publish state indicator to mode line + (rudel-mode-line-publish-state--remove-indicator-from-mode-line): + new function; remove publish state indicator from mode line + (rudel-mode-line-publish-state--update-string): new function; + update publish state indicator according to buffer state + (rudel-mode-line-publish-state--document-attach): new function; + handle document attaching to buffer + (rudel-mode-line-publish-state--document-detach): new function; + handle document detaching from buffer + (rudel-mode-line-publish-state-minor-mode): new minor mode; + displays publish state of buffer in mode line + (global-rudel-mode-line-publish-state-mode): new minor mode; + globalization of `rudel-mode-line-publish-state-minor-mode' + (rudel-minor-keymap): menu entries for buffer local and global + mode line publish state mode + + * rudel.el (require rudel-hooks): required or hook variables + (rudel-session-start-hook): moved to rudel-hooks.el + (rudel-session-end-hook): moved to rudel-hooks.el + * rudel-hooks.el (whole file): new file; contains hook variables + and mapping from object hooks to global hooks + * Project.ede (target rudel): added file rudel-hooks.el + * Makefile (target rudel_LISP): added file rudel-hooks.el + +2009-09-03 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-mode.el (rudel-header-subscriptions-minor-mode): improved + documentation string + +2009-08-30 Jan Moringen <scymtym@users.sourceforge.net> + + * zeroconf/Makefile (whole file): new file; generated Makefile for + the zeroconf subproject + + * wave/rudel-wave.el (whole file): new file; main class of the + wave backend + * wave/Project.ede (whole file): new file; project file for the + wave subproject + * wave/Makefile (whole file): new file; generated Makefile for the + wave subproject + * Project.ede (target autoloads): added wave directory + * Makefile (LOADDIRS): added wave and zeroconf directories + (VERSION): bumped to 0.2 + (target all): added wave and zeroconf + (tags): descend into zeroconf and wave directories + (dist): descend into zeroconf and wave directories + +2009-08-28 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-change-color): run the change hook of the self + user + + * rudel-overlay.el (rudel-overlay-set-face-attributes): check the + face actually exists + +2009-08-27 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-mode.el (rudel-header-subscriptions-use-images): new + variable; controls whether images are used when formatting user + names + (rudel-header-subscriptions-separator): new variable; separator + used when formatting user names + (rudel-header-subscriptions--make-format): new function; make a + format object for header line + (rudel-header-subscriptions--update-from-document): new function; + update header line from document + (rudel-header-subscriptions--update-from-buffer): new function; + update header line from buffer + (rudel-header-subscriptions--options-changed): new function; + update header line in all buffers that have + rudel-header-subscriptions-minor-mode enabled after customization + option change + (rudel-header-subscriptions--user-change): new function; update + header line after a user object change + (rudel-header-subscriptions--add-user): new function; watch newly + subscribed user and update header line + (rudel-header-subscriptions--remove-user): new function; stop + watching user and update header line + (minor mode rudel-header-subscriptions-minor-mode): new minor + mode; display subscribed users in buffer's header line + (rudel-header-subscriptions--attach): new function; enable header + subscription minor mode when attaching + (rudel-header-subscriptions--detach): new function; disable header + subscription minor mode when detaching + (rudel-header-subscriptions--add-document): new function; monitor + attaching/detaching of new document + (rudel-header-subscriptions--remove-document): new function; stop + monitoring attaching/detaching of new document + (rudel-header-subscriptions--session-start): new function; watch + documents being added/removed to/from the session + (rudel-header-subscriptions--session-end): new function; stop + watching documents being added/removed to/from the session + (minor mode global-rudel-header-subscriptions-mode): global minor + mode that controls `rudel-header-subscriptions-minor-mode' in + buffers + (advice global-rudel-header-subscriptions-mode): controls + adding/removing watches for added/removed documents when the + global mode is enabled/disabled + (rudel-minor-keymap): Added entries for + `rudel-header-subscriptions-minor-mode' and + `global-rudel-header-subscriptions-mode' + +2009-08-26 Jan Moringen <scymtym@users.sourceforge.net> + + * . (property svn:ignore): added patterns + * jupiter (property svn:ignore): added patterns + * obby (property svn:ignore): added patterns + + * rudel.el (rudel-session::add-user-hook): new slot; add user hook + function list + (rudel-session::remove-user-hook): new slot; remove user hook + function list + (rudel-session::add-document-hook): updated documentation string + (rudel-session::remove-document-hook): updated documentation + string + (rudel-session::rudel-add-user): run add user hook + (rudel-session::rudel-remove-user): run remove user hook + + * rudel.el (rudel-session-start-hook): new variable; session start + hook function list + (rudel-session-end-hook): new variable; session end hook function + list + (rudel-join-session): run session start hook + (rudel-end-session): run session end hook + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document_create): call + `generate-new-buffer-name' on complete buffer name; not just name + part + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document/subscribe): send + number of bytes instead of number of characters + + * obby/rudel-obby-client.el + (rudel-obby-client-state-document-synching::remaining-bytes): + fixed initarg num-bytes -> remaining-bytes + + * rudel.el (rudel-session::add-document-hook): new slot; run when + a document gets added to the session + (rudel-session::remove-document-hook): new slot; run when a + document gets removed from the session + (rudel-session::rudel-add-document): run add document hook + (rudel-session::rudel-remove-document): run remove document hook + (rudel-document::unsubscribe-hook): fixed initarg subscribe-hook + -> unsubscribe-hook + +2009-08-25 Jan Moringen <scymtym@users.sourceforge.net> + + * www/index.html (Download): link to http://bazaar-vcs.org; + improved wording + + * www/index.html (Download): changed link to source; add browse + source link for bzr + + * INSTALL (REQUIREMENTS): precise CEDET release version + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_user_colour): run change hook + after setting slot + (rudel-obby-server::rudel-remove-client): run change hook after + setting slot + * obby/rudel-obby-client.el + (rudel-obby-client-state-idle::rudel-obby/net6_client_part): run + change hook after setting slots + (rudel-obby-client-state-idle::rudel-obby/obby_user_colour): run + change hook after setting slot + * rudel.el (class rudel-user): derive from `rudel-hook-object' + (rudel-user::change-hook): new slot; stores change hook functions + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_user_colour): cosmetic changes + (rudel-obby-client::rudel-obby/obby_document/subscribe): use + `rudel-add-user' + (rudel-obby-client::rudel-obby/obby_document/unsubscribe): use + `rudel-remove-user' + (rudel-obby-server::rudel-check-username-and-color): whitespace + fixes + +2009-08-23 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-document::attach-hook): new slot; attach hook + function list + (rudel-document::detach-hook): new slot; detach hook function list + (rudel-document::rudel-attach-to-buffer): run hook `attach-hook' + (rudel-document::rudel-detach-from-buffer): run hook `detach-hook' + (rudel-document::rudel-add-user): improved documentation string + (rudel-document::rudel-remove-user): improved documentation string + + * obby/rudel-obby.el + (rudel-obby-user::eieio-speedbar-object-buttonname): fixed typo + +2009-08-21 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-client.el + (rudel-obby-client-state-idle::rudel-obby/obby_document/subscribe): + call `rudel-add-user' + (rudel-obby-client-state-idle::rudel-obby/obby_document/unsubscribe): + call `rudel-remove-user' + * rudel.el (class rudel-document): mixin rudel-hook-object + (rudel-document::subscribe-hook): new slot; subscribe-hook + function list + (rudel-document::unsubscribe-hook): new slot; unsubscribe-hook + function list + (rudel-document::rudel-add-user): new method; add user to list of + subscribed users and run subscribe-hook + (rudel-document::rudel-remove-user): new method; remove user from + list of subscribed users and run unsubscribe-hook + + * obby/rudel-obby.el (header): cosmetic changes + (include rudel-icons): `rudel-display-string' uses icons + (rudel-obby-user::eieio-speedbar-object-buttonname): use + `rudel-display-string' + (rudel-obby-user::rudel-display-string): new method; textual + representation of user object + (rudel-obby-parse-message): cosmetic changes + * rudel.el (include rudel-icons): `rudel-display-string' uses + icons + (rudel-user::rudel-display-string): new method; textual + representation of user object + + * rudel-util.el (rudel-hook-object): new class; abstract mixin for + classes that offer hooks + (rudel-hook-object::object-add-hook): new method; add function to + hook list + (rudel-hook-object::object-remove-hook): new method; remove + function from hook list + (rudel-hook-object::object-run-hook-with-args): new method; run + hook functions + +2009-08-20 Jan Moringen <scymtym@users.sourceforge.net> + + * icons/plaintext.svg (new file): plaintext icon + * icons/person.svg (new file): person icon + * icons/encrypted.svg (new file): encrypted icon + * icons/document.svg (new file): document icon + * icons/disconnected.svg (new file): disconnected icon + * icons/connected.svg (new file): connected icon + * rudel-icons.el (new file): loading icons + * Project.ede (target rudel): added rudel-icons.el + +2009-08-19 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-join-session): renamed local variable backend to + session-initiation-backend + +2009-08-17 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-state.el (rudel-obby-state::rudel-accept): fixed + format of warning message + + * rudel-state-machine.el (require working): needed by + `rudel-state-wait' + + * obby/rudel-obby-client.el + (rudel-obby-client-state-idle::rudel-obby/obby_user_colour): set + face attributes + * rudel.el (rudel-change-color): set face attributes + * rudel-overlay.el (rudel-overlay-make-face): use + `rudel-overlay-set-face-attributes' + (rudel-overlay-set-face-attributes): new function; set face + attributes + + * rudel-overlay.el (rudel-overlay-author-set-properties): call + `rudel-overlay-make-face-symbol' + (rudel-overlay-make-face-symbol): new function; return face symbol + +2009-08-16 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-overlay.el (rudel-overlay-author-display): option that + controls display of author overlays + (rudel-make-author-overlay): call + `rudel-overlay-author-set-properties' to set the overlay + properties + (rudel-overlay-author-set-properties): new function; set overlay + properties; respects rudel-overlay-author-display + (rudel-overlay-author-update): new function; update overlay + properties based on associated user object + (rudel-overlay-options-changed): new function; call + `rudel-overlay-author-update' on all Rudel overlays in all buffers + * rudel-mode.el (header): cosmetic changes + (rudel-minor-menu): added menu entry to toggle display of author + overlays + + * rudel-overlay.el (rudel-make-author-overlay): use `intern' + instead of `make-symbol' when allocating the face name; this way, + faces can actually be created lazily + (rudel-overlay-make-face): call `make-face' for the new face + + * obby/rudel-obby-client.el + (rudel-obby-client-state-document-synching::object-print): fixed + slot name remaining-bytes + + * rudel.el (rudel-host-session): the backend object is the cdr of + the result of `rudel-backend-choose' + +2009-08-15 Jan Moringen <scymtym@users.sourceforge.net> + + * telepathy/rudel-telepathy.el (header): added file comment + * obby/rudel-obby-state.el (header): fixed email address + (whole file): whitespace fixes + * jupiter/jupiter.el (header): cosmetic changes + (whole file): whitespace fixes + * rudel-util.el (header): cosmetic changes + * rudel-mode.el (header): cosmetic changes + * rudel-errors.el (header): fixed type + (whole file): whitespace fixes + + * obby/rudel-obby.el (rudel-ask-connect-info): added optional + argument info; do not ask for things that are already specified in + info + (autoload): register obby service with the Zeroconf backend + * zeroconf/rudel-zeroconf.el (new file): Zeroconf session + initiation for Rudel + * zeroconf/Project.ede (new file): subproject zeroconf + * rudel.el (rudel-join-session): call `rudel-ask-info' to augment + connect info + * Project.ede (target autoloads): added directory zeroconf + * INSTALL (INSTALLING): mention zeroconf subdirectory + (COMPILING): mention zeroconf target + + * rudel-backend.el (rudel-backend-factory::rudel-get-backend): + return backend as a cons + (rudel-backend-get): new function; convenience function for + getting backends + + * obby/rudel-obby.el (header): extended commentary and history + (rudel-obby-version): bumped to 0.2 + (rudel-obby-backend::initialize-instance): set :version slot in + constructor instead of using obsolete lambda expression in + initform + +2009-08-14 Jan Moringen <scymtym@users.sourceforge.net> + + * Project.ede (project rudel): bumped version to 0.2; added + mailing list and path to web files + + * rudel-backend.el (rudel-backend-factory): do not initialize + backends with lambda expression + (rudel-backend-factory::initialize-instance): new method; + initialize backends + (rudel-backend-cons-p): use `object-p' instead of `eieio-object-p' + (rudel-backend-dump): changed format slightly + +2009-08-13 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (include rudel-session-initiation): required for + `rudel-join-session' + (rudel-join-session): mostly rewritten; moved user interaction to + `interactive' form + * rudel-session-initiation.el (new file): session initiation + backend interface and high-level programming interface + * Project.ede (target rudel): added rudel-session-initiation.el + * Makefile (rudel_LISP): added rudel-session-initiation.el + + * rudel-interactive.el (rudel-read-session): discriminate sessions + vs. session generating objects using `rudel-backend-cons-p' + + * rudel-backend.el (rudel-backend-cons-p): new function; checks + whether a cons consists of a backend name and object + +2009-08-12 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-interactive.el (rudel-read-session): new function; read + session by name and return it + + * rudel-interactive.el (rudel-read-backend): argument backends is + no longer optional; always return a cons of backend name and + object; updated documentation string + (whole file): whitespace fixes + * rudel-backend.el (rudel-backend-choose): always return a cons of + backend name and object; updated documentation string + +2009-08-11 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (file header): added project URL + (whole file): improved some comments + +2009-08-10 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (include eieio-base): needed for eieio-named + +2009-08-04 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-state-machine.el (header section commentary): updated + (rudel-state-machine::initialize-instance): use + `rudel--switch-to-return-value' to allow immediate switch to + another state + (rudel-state-machine::rudel-switch): use + `rudel--switch-to-return-value' to switch to successor state + (rudel-state-machine::rudel--switch-to-return-value): new function + switch to successor state for different kinds of specifications of + the successor state + +2009-08-03 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (require rudel-backend): now necessary + (require rudel-protocol): now necessary + (class rudel-obby-backend): now derived from `rudel-backend'; + autoloaded + (autoloading): use `rudel-add-backend' + * rudel.el (require rudel-backend): backends have their own file + (class rudel-backend): moved to rudel-backend.el + (rudel-load-backends): moved to rudel-backend.el + (rudel-suitable-backends): moved to rudel-backend.el + (rudel-choose-backend): moved to rudel-backend.el + (rudel-join-session): use `rudel-backend-choose' + (rudel-host-session): use `rudel-backend-choose' + + * rudel-protocol.el (new file): interface for Rudel protocol + backends + * Project.ede (target rudel): added rudel-protocol.el + * Makefile (rudel_LISP): added rudel-protocol.el + + * rudel-backend.el (rudel-backend-factory::rudel-get-backend): + improved documentation string + (rudel-backend-factory::rudel-suitable-backends): improved + documentation string + (rudel-backend-suitable-backends): improved documentation string + (rudel-backend-choose): When only one backend matches, do not + check interactivity using `interactive-p', that does not work; + call `sit-for' correctly + +2009-08-02 Jan Moringen <scymtym@users.sourceforge.net> + + * jupiter/Makefile (whole file): regenerated; reflects CEDET + changes + * rudel-backend.el (new file): generic backend management, query + and loading functions + * Project.ede (target rudel): added rudel-backend.el to sources + * Makefile (rudel_LISP): added rudel-backend.el + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/net6_client_login): use slot + :object-name instead of calling object-name-string + (rudel-obby-server::rudel-add-context): use slot :object-name + instead of calling object-name-string + * obby/rudel-obby-client.el + (rudel-obby-client-state-idle::rudel-obby/obby_document/rename): + use slot :object-name instead of calling object-name-string + (rudel-obby-connection::rudel-add-context): use slot :object-name + instead of calling object-name-string + (rudel-obby-connection::rudel-publish): use slot :object-name + instead of calling object-name-string + * rudel.el (class rudel-user): added base class eieio-named for + virtual slot :object-name; made abstract + (class rudel-document): added base class eieio-named for virtual + slot :object-name + * rudel-overlay.el (rudel-make-author-overlay): use slot + :object-name instead of calling object-name-string + + * rudel-state-machine.el + (rudel-state-machine::initialize-instance): use &rest slots + instead of just slots + +2009-07-15 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-document::rudel-detach-from-buffer): call + `rudel-overlays-remove-all'; remove `rudel-unpublish-buffer' hook + early + * rudel-overlay.el (rudel-overlays-remove-all): new function; + remove all overlays from the current buffer + (whole file): cosmetic changes; typo fixes; whitespace fixes + + * obby/rudel-obby.el (rudel-obby-document::rudel-unique-name): + Check `next-method-p' before calling the next method + * obby/rudel-obby-client.el + (rudel-obby-connection::initialize-instance): Check + `next-method-p' before calling the next method + (rudel-obby-connection::rudel-register-state): Check + `next-method-p' before calling the next method + (rudel-obby-connection::rudel-disconnect): Check + `next-method-p' before calling the next method + * rudel.el (rudel-client-session::rudel-end): Check + `next-method-p' before calling the next method + +2009-07-13 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (rudel-obby-backend::rudel-connect): only + start the network process after everything is ready; wait for the + connection state machine to reach a success or error state + (rudel-obby-backend::rudel-host): cosmetic changes + (class rudel-obby-user): cosmetic changes + * rudel.el (rudel-join-session): reversed order of creation for + session and connection; do not catch errors to give error messages + a chance + + * jupiter/jupiter-insert.el (jupiter-insert::jupiter-transform): + cosmetic changes + (whole file): whitespace fixes + + * rudel.el (rudel-session::rudel-find-user): added documentation + string; cosmetic changes + (rudel-session::rudel-find-document): added documentation string; + cosmetic changes + (whole file): whitespace fixes + +2009-07-12 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-speedbar.el (eieio-speedbar-object-buttonname): use + `rudel-unique-name' instead of `object-name-string' + + * obby/rudel-obby-state.el (rudel-enter): return nil + + * obby/rudel-obby-client.el + (rudel-obby-client-state-joining::rudel-enter): return nil + (rudel-obby-client-state-join-failed::rudel-enter): return nil + (rudel-obby-client-state-session-synching::rudel-enter): return + nil + (rudel-obby-client-state-session-synching::object-print): new + method; add number of remaining items to string representation + (rudel-obby-client-state-subscribing::rudel-enter): nil + (rudel-obby-client-state-document-synching::rudel-enter): nil + (rudel-obby-client-state-document-synching::object-print): new + method; add number of remaining bytes to string representation + +2009-07-11 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-util.el (with-parsed-arguments): added debug + declaration + (whole file): whitespace fixes + * rudel-util.el (rudel-assemble-line-fragments): added debug + declaration + (rudel-loop-lines): added debug declaration + (rudel-loop-chunks): fixed documentation string; added debug + declaration + + * rudel-state-machine.el (rudel-no-start-state): new error symbol + (rudel-state-machine::initialize-instance): try hard to find a + suitable start sate; call `rudel-switch' instead of just + `rudel-enter' + (rudel-state-machine::rudel-switch): always return the new current + state; accept successor state from `rudel-enter' + (rudel-state-machine::object-print): new method; add current state + of state machine to string representation + (rudel-state-machine::rudel-state-wait): whitespace fixes + +2009-07-07 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (class rudel-obby-backend): better + documentation string + (rudel-obby-backend::rudel-ask-connect-info): added documentation + string + (rudel-obby-backend::rudel-connect): added documentation string + (rudel-obby-backend::rudel-ask-host-info): added documentation + string + (rudel-obby-backend::rudel-host): added documentation string + (rudel-obby-backend::rudel-make-document): added documentation + string + (rudel-obby-send): cosmetic changes + (whole file): whitespace fixes + +2009-07-05 Jan Moringen <scymtym@users.sourceforge.net> + + * INSTALL (REQUIREMENTS): added Emacs itself and GNUTls + + * rudel-tls.el (rudel-tls-start-tls): added a message + (rudel-tls-wait-handshake): switch to filter + `rudel-tls-established' instead of restoring the original filter + (rudel-tls-established): new function; filters GNUTls messages in + encrypted connections + (whole file): whitespace fixes + +2009-07-04 Jan Moringen <scymtym@users.sourceforge.net> + + * README (INTRODUCTION): extended a bit + (JOINING A SESSION): added prompt/input example and an explanation + of encryption issues in the obby backend + (KNOWN BUGS): new section; no known bugs yet, though + +2009-06-17 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-client.el (require rudel-state-machine): the + connection now is a state machine + (require rudel-obby-errors): used when analyzing login failures + (require rudel-obby-state): useful base classes for states + (rudel-obby-client-state-new): new class; initial state of new + connections + (rudel-obby-client-state-encryption-negotiate): new class; + first encryption state + (rudel-obby-client-state-encryption-start): new class; second + encryption state + (rudel-obby-client-state-joining): new class + (rudel-obby-client-state-join-failed): new class; entered after + failed login attempt + (rudel-obby-client-state idle): new class; default state of + established connections + (rudel-obby-client-state-session-synching): new class; + synchronizing session state to client + (rudel-obby-client-state-subscribing): new class; first state of + document subscription + (rudel-obby-client-state-document-synching): new class; + synchronizing document state to client + (rudel-obby-client-connection-states): new variable; alist of + name symbols and associated state classes + (rudel-obby-connection::initialize-instance): register states + (rudel-obby-connection::rudel-register-state): new method; set + connection slot of state to its connection + (rudel-obby-connection::rudel-add-context): cleanup + (rudel-obby-connection::rudel-message): dispatch message using + `rudel-accept' + (rudel-obby-connection::rudel-subscribe-to): initiate subscription + by switching to state 'subscribing' + + * obby/rudel-obby-state.el (rudel-obby-document-handler): new + class; mixin class that provides handling of obby 'document' + messages + + * rudel-state-machine.el + (rudel-state-machine::initialize-instance): find start state in + slots and switch into it + (while-file): whitespace fixes + +2009-06-15 Jan Moringen <scymtym@users.sourceforge.net> + + * www/index.html (section download): fixed link to download area + (whole file): whitespace cleanup + + * obby/rudel-obby-state.el (new file): finite state machine states + for the rudel backend + * obby/Project.ede (target rudel/obby): added rudel-obby-state.el + * obby/Makefile (target obby_LISP): added rudel-obby-state.el + + * rudel-util.el (require rudel-errors): required for dispatch + errors + (symbol rudel-dispatch-error): new condition symbol for dispatch + errors + (rudel-dispatch): new function; dispatch to method based on method + name + (whole file): whitespace fixes + +2009-06-14 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-mode.el (global-rudel-minor-mode): removed; the variable + is created by `define-minor-mode' + (minor-mode-alist): managed by `define-minor-mode' + + * rudel-mode.el (require easy-mmode): used to define global rudel + minor mode + (rudel-minor-keymap): cosmetic changes + (global-rudel-minor-mode): use `define-minor-mode' to define the + mode + (whole file): whitespace cleanup + + * rudel-telepathy.el (whole file): moved to + telepathy/rudel-telepathy.el + * telepathy/rudel-telepathy.el (whole file): moved from + rudel-telepathy.el + + * obby/rudel-obby-server.el (whole file): whitespace cleanup + * obby/rudel-obby-client.el (require rudel-obby): removed; + unnecessary + (rudel-obby-connection::initialize-instance): use &rest for `slots' + argument; cosmetic changes + (rudel-obby-connection::rudel-change-color-): use own `rudel-send' + method instead of the socket's + (rudel-obby-connection::rudel-subscribe-to): cosmetic changes + (rudel-obby-connection::rudel-unsubscribe-from): cosmetic changes + (rudel-obby-connection::rudel-local-operation): cosmetic changes + (whole file): whitespace cleanup + +2009-06-13 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-errors.el (new file): error data + * rudel-state-machine.el (new file): a simple finite state machine + implementation + * Project.ede (target rudel): added rudel-errors.el and + rudel-state-machine.el + * Makefile (target rudel_LISP): added rudel-errors.el and + rudel-state-machine.el + +2009-06-12 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-server.el (require rudel-obby-errors): now + required + (rudel-obby-client::rudel-obby/net6_client_login): check username + and color before adding the client + (rudel-obby-server::rudel-check-username-and-color): new method; + make sure username and color are valid and there are no duplicates + * obby/rudel-obby-errors.el (new file): error data for the obby + backend + * obby/Project.ede (rudel/obby): added rudel-obby-errors.el + * obby/Makefile (obby_LISP): added rudel-obby-errors.el + + * rudel.el (rudel-user::rudel-color): added accessor `rudel-color' + + * obby/rudel-obby-server.el (require cl): required + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/net6_client_login): send suffices + of synchronized documents + +2009-06-11 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document_create): send + document/rename message to client when the document suffix changes + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/net6_client_login): use + `with-parsed-arguments' + (rudel-obby-client::rudel-obby/obby_user_colour): use + `with-parsed-arguments' + (rudel-obby-client::rudel-obby/obby_document_create): use + `with-parsed-arguments' + (rudel-obby-client::rudel-obby/obby_document): use + `with-parsed-arguments' + (rudel-obby-client::rudel-obby/obby_document/subscribe): use + `with-parsed-arguments' + (rudel-obby-client::rudel-obby/obby_document/unsubscribe): use + `with-parsed-arguments' + (rudel-obby-client::rudel-obby/obby_document/record): use + `with-parsed-arguments' + (rudel-obby-client::rudel-obby/obby_document/record/ins): use + `with-parsed-arguments' + (rudel-obby-client::rudel-obby/obby_document/record/del): use + `with-parsed-arguments' + + * obby/rudel-obby-server.el (header): fixed version + +2009-06-10 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-local-operation): fixed wording in + comment + + * www/images/development.png (whole file): changed size 48x48 -> + 64x64 + * www/images/development.svg (whole file): changed size 48x48 -> + 64x64 + * www/images/download.png (whole file): changed size 48x48 -> + 64x64 + * www/images/download.svg (whole file): changed size 48x48 -> + 64x64 + * www/images/info.png (whole file): changed size 48x48 -> 64x64 + * www/images/info.svg (whole file): changed size 48x48 -> 64x64 + + * index.html (section introduction): wording fixes; link to Gobby + (whole file): removed external link class for sourceforge links + (section download): added link to INSTALL file in svn code browser + (section footer): fixed copyright + + * compatibility.html (section footer): fixed copyright + +2009-06-09 Jan Moringen <scymtym@users.sourceforge.net> + + * INSTALL (section REQUIREMENTS): removed ERT which is not + currently used + (section INSTALL): some wording and file name fixes + (section COMPILING): precise make command + + * www/index.html (section development): fixed mailing list and + issue tracker links; removed email address + + * www/compatibility.html (head): fixed charset + (section semantic): added missing <p> tag + + * www/compatibility.html (new file): compatibility information + * www/index.html (new file): start page + * www/style.css (new file): stylesheet + * www/images/development.png (new file): development icon + * www/images/development.svg (new file): development icon + * www/images/download.png (new file): download icon + * www/images/download.svg (new file): download icon + * www/images/email-link.png (new file): icon for email links + * www/images/external-link.png (new file): icon for external links + * www/images/info.png (new file): info icon + * www/images/info.svg (new file): info icon + * www/images/screenshot.png (new file): screenshot for the start + page + + * obby/rudel-obby-serverl.el + (rudel-obby-client::rudel-obby/obby_document_create): find unique + suffix for the new document; send suffix to clients + + * obby/rudel-obby.el (header): fixed license text + * obby/rudel-obby-util.el (header): fixed license text + * obby/rudel-obby-server.el (header): fixed license text + * obby/rudel-obby-client.el (header): fixed license text + * jupiter/jupiter.el (header): fixed license text + * jupiter/jupiter-operation.el (header): fixed license text + * jupiter/jupiter-nop.el (header): fixed license text + * jupiter/jupiter-insert.el (header): fixed license text + * jupiter/jupiter-delete.el (header): fixed license text + * jupiter/jupiter-compound.el (header): fixed license text + * rudel.el (header): fixed license text + * rudel-util.el (header): fixed license text + * rudel-tls.el (header): fixed license text + * rudel-telepathy.e (header): fixed license text + * rudel-speedbar.el (header): fixed license text + * rudel-overlay.el (header): fixed license text + * rudel-operators.el (header): fixed license text + * rudel-operations.el (header): fixed license text + * rudel-mode.el (header): fixed license text + * rudel-interactive.el (header): fixed license text + * rudel-compat.el (header): fixed license text + + * obby/rudel-obby-util.el (require cl): now required + (generic rudel-obby-char->byte): new generic; char positions -> + byte positions + (jupiter-insert::rudel-obby-char->byte): new method; char + positions -> byte positions + (jupiter-delete::rudel-obby-char->byte): new method; char + positions -> byte positions + (jupiter-compound::rudel-obby-char->byte): new method; char + positions -> byte positions + (jupiter-nop::rudel-obby-char->byte): new method; char positions + -> byte positions + (generic rudel-obby-byte->char): new generic; byte positions -> + char positions + (jupiter-insert::rudel-obby-byte->char): new method; byte + positions -> char positions + (jupiter-delete::rudel-obby-byte->char): new method; byte + positions -> char positions + (jupiter-compound::rudel-obby-byte->char): new method; byte + positions -> char positions + (jupiter-nop::rudel-obby-byte->char): new method; byte positions + -> char positions + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-local-operation): call + `rudel-obby-char->byte' before processing + (rudel-obby-connection::rudel-remote-operation): call + `rudel-obby-byte->char' before processing + * rudel.el (rudel-buffer-change-workaround-data): new variable; + holds change data for later use + (rudel-document::rudel-attach-to-buffer): add + `rudel-buffer-change-workaround' to 'before-change-functions' + (rudel-document::rudel-detach-from-buffer): remove + `rudel-buffer-change-workaround' from 'before-change-functions' + (rudel-buffer-change-workaround): new function; stores change data + for later use + +2009-06-07 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-obby/net6_client_join): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/net6_client_part): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_welcome): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_sync_init): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_sync_usertable_user): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_user_colour): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_sync_doclist_document): + use `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_document_create): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_document_remove): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_document): use + `with-parsed-arguments'; cleanup + (rudel-obby-connection::rudel-obby/obby_document/rename): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_document/subscribe): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_document/unsubscribe): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_document/sync_chunk): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_document/record): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_document/record/ins): use + `with-parsed-arguments' + (rudel-obby-connection::rudel-obby/obby_document/record/del): use + `with-parsed-arguments' + +2009-06-06 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-obby/net6_client_part): use `eql', + not `=' when calling `rudel-find-user' since the client id can be + nil + + * obby/rudel-obby-util.el (require jupiter): silence byte compiler + + * obby/rudel-obby-util.el (rudel-obby-dispatch): moved inside file + (with-parsed-arguments): new macro; executed forms with variables + bound to parsed arguments + +2009-06-04 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (require rudel-interactive): interactive functions use + `rudel-read-backend' and `rudel-read-document' + + * rudel.el (rudel-buffer-document): mark as permanent local + variable to prevent deletion in the event of a major-mode change + (rudel-document::rudel-attach-to-buffer): add (buffer-locally) + `rudel-handle-major-mode-change' to 'change-major-mode-hook' such + that it can repair damage caused by major-mode changes + (rudel-document::rudel-detach-from-buffer): remove + `rudel-handle-major-mode-change' from 'change-major-mode-hook' + (rudel-mode-changed-buffers) new variable; temporarily stores + buffers that underwent major-mode changes + (rudel-handle-major-mode-change): new function; schedules buffers + for repair after major-mode changes + (rudel-after-major-mode-change): new function; repairs buffer + objects after major-mode changes + +2009-06-03 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-buffer-has-document-p): use `buffer-local-value' + (rudel-buffer-document): use `buffer-local-value' + (rudel-set-buffer-document): added documentation string + +2009-06-02 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-handle-buffer-change): There are three cases + now: insert, delete and arbitrary changes; arbitrary changes + generate a delete and insert operation + + * rudel-mode.el (rudel-minor-keymap): added some comments + (global-rudel-minor-mode): extended documentation string; cleaned + up code; added comments + + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-obby/net6_client_part): fixed typo + in variable name client-id-numeric + +2009-05-28 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-util.el (header): Fixed version (1.0 -> 0.1) + + * obby/rudel-obby-client.el (header): Fixed version (1.0 -> 0.1) + (rudel-obby-connection::rudel-obby/obby_document/record/split): + introduced temporary variable + +2009-??-?? Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-buffer-document): removed; replaced by + rudel-buffer-documents hash-table + (rudel-buffer-documents): new variable; a hash-table, which + associates documents to buffers + (rudel-buffer-has-document-p): + (rudel-buffer-document): + (rudel-set-buffer-document): + +2009-03-16 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-obby/net6_client_part): do not crash + if the client id cannot be found + + * obby/rudel-obby.el (rudel-obby-backend::rudel-make-document): + specify value 1 for slot suffix + (rudel-obby-document::suffix): new slot; contains the suffix + number of the document + (rudel-obby-document::rudel-unique-name): new method; return + unique name based on document name and suffix + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-obby/obby_sync_doclist_document): do + not ignore the suffix when creating the document object + (rudel-obby-connection::rudel-obby/obby_document_create): do not + ignore the suffix when creating the document object + (rudel-obby-connection::rudel-obby/obby_document/rename): change + document name and suffix as requested + * rudel.el (rudel-document::rudel-unique-name): new method; + returns a unique name for the document + (rudel-document::rudel-suggested-buffer-name): new method; returns + a suggested name for the buffer attached to the document + (rudel-subscribe): use `rudel-suggested-buffer-name' instead of + the object name + * rudel-interactive.el (rudel-read-document): use the unique names + of the documents instead of the object names + +2009-02-27 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-document::rudel-attach-to-buffer): add hook to + detach document from the buffer when the buffer is killed + (rudel-document::rudel-detach-from-buffer): remove unpublish + function kill buffer hook + +2009-02-23 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-document): minor cleanup + (rudel-document::rudel-attach-to-buffer): stylistic changes + (rudel-document::rudel-detach-from-buffer): fixed argument order in + call to `rudel-set-buffer-document' + + * obby/rudel-obby-server.el + (rudel-obby-server::rudel-remove-client): Make sure there is a + user object before setting the status to offline + + * obby/rudel-obby-client.el (rudel-obby/net6_encryption_failed): + only fail if encryption has been requested in the first + place. otherwise, just carry on + + * rudel.el (rudel-document::rudel-attach-to-buffer): use + `rudel-set-buffer-document' + (rudel-document::rudel-detach-from-buffer): use + `rudel-set-buffer-document' + (rudel-buffer-has-document-p): new function; test whether a buffer + has an associated document object + (rudel-buffer-document): new function; returns associated document + object of a buffer + (rudel-set-buffer-document): new functions; sets associated + document object of a buffer + (rudel-handle-buffer-change): use `rudel-buffer-has-document-p' + (rudel-publish-buffer): use `rudel-buffer-has-document-p' + (rudel-unpublish-buffer): use `rudel-buffer-has-document-p' and + `rudel-buffer-document' + * rudel-mode.el (rudel-minor-keymap): use + `rudel-buffer-has-document-p' + + * obby/rudel-obby-client.el (rudel-obby/obby_document/rename): + new method; dummy implementation + + * obby/rudel-obby-client.el (rudel-obby/net6_client_join): + stylistic change + +2009-02-21 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-util.el (generic rudel-operation->message): new + generic function; serializes an operation + (jupiter-insert::rudel-operation->message): new method + (jupiter-delete::rudel-operation->message): new method + (jupiter-compound::rudel-operation->message): new method + (jupiter-nop::rudel-operation->message): new method + (rudel-message->operation): new function; deserializes an + operation from a received message + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-local-insert): do not construct + message string; use `rudel-operation->message' + (rudel-obby-connection::rudel-local-delete): do not construct + message string; use `rudel-operation->message' + (rudel-obby-connection::rudel-local-operation): new method; + handles operation objects that represent local operations + (rudel-obby-connection::rudel-remote-operation): new method; + handles operation objects that represent remote operations + (rudel-obby-connection::rudel-obby/obby_document/record/ins): + construct operation name correctly; do not call jupiter context to + transform operation + (rudel-obby-connection::rudel-obby/obby_document/record/del): + construct operation name correctly; do not call jupiter context to + transform operation + (rudel-obby-connection::rudel-obby/obby_document/record/split): + new method; handles split operation messages + (rudel-obby-connection::rudel-obby/obby_document/record/noop): new + method; handles nop messages + +2009-02-12 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (rudel-obby-backend::rudel-ask-connect-info): + ask whether to encrypt the connection + (rudel-obby-backend::rudel-connect): create connection object + capable of StartTLS encryption when encryption was requested + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-obby/net6_encryption): do not fail + when the server requests encryption + (rudel-obby-connection::rudel-obby/net6_encryption_begin): start + TLS encryption for the connection + (rudel-obby-connection::rudel-obby/net6_encryption_failed): new + method; stub + * rudel-tls.el (new file): StartTLS encryption for Rudel + * Project.ede ("rudel"): added rudel-tls.el + * Makefile (rudel_LISP): added rudel-tls.el + +2009-02-06 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-compat.el (header): fixed email address, keywords, legal + notice and file commentary + +2009-02-05 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (rudel-compat): require rudel-compat for + `read-color' + * rudel.el (rudel-compat): require rudel-compat for `read-color' + * rudel-interactive.el (rudel-compat): require rudel-compat for + `read-color' + * rudel-compat.el (new file): compatibility code + * Project.ede (rudel): added rudel-compat.el + * Makefile (rudel_LISP): regenerated: added rudel-compat.el + +2009-02-04 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (require rudel) + * obby/rudel-obby-util.el (require rudel) + * obby/rudel-obby-client.el (require rudel-obby): make compilation + succeed + + * rudel.el (include eieio-speedbar): I need it for now; I should + get rid of it later + + * INSTALL (REQUIREMENTS): added note that CVS version of cedet is + required + (INSTALLING): added subdirectories jupiter and obby in load path + listing; fixed name of autoload file + +2009-02-02 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (rudel-obby-backend::rudel-ask-connect-info) + (rudel-obby-backend::rudel-host, rudel-obby-replace-in-string) + * obby/rudel-obby-util.el (rudel-obby-dispatch) + * obby/rudel-obby-server.el (rudel-obby-client::rudel-obby/obby_document) + (rudel-obby-server::rudel-broadcast, rudel-obby-server::rudel-make-user) + * obby/rudel-obby-client.el (rudel-obby-connection::rudel-obby/net6_client_join) + (rudel-obby-connection::rudel-obby/obby_document) + * jupiter/jupiter-operation.el (jupiter-operation) + * rudel.el (rudel-backend, rudel-session, rudel-server-session) + (rudel-connection, rudel-document) + (rudel-document::rudel-attach-to-buffer) + (rudel-document::rudel-detach-from-buffer) + (rudel-document::rudel-insert, rudel-document::rudel-delete) + (rudel-change-color) + * rudel-util.el (rudel-assemble-line-fragments, rudel-loop-lines) + * rudel-overlay.el (rudel-make-author-overlay) + * rudel-interactive.el (rudel-read-backend, rudel-read-user-color) + (rudel-read-user, rudel-read-document): replaced 't by t + + * rudel-operators.el (rudel-overlay-operators::rudel-insert): + Fixed computation of insertion offset when appending to the end of + the buffer string + + * rudel.el (rudel-document::rudel-chunks): fixed invalid access to + last chunk for empty buffer + + * rudel.el (rudel-document::rudel-attach-to-buffer): fixed + incorrect slot reference + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document/subscribe): minor + rearrangement of expressions + (rudel-obby-client::rudel-obby/obby_document/unsubscribe): minor + rearrangement of expressions + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document/record/ins): added + documentation string + (rudel-obby-client::rudel-obby/obby_document/record/del): added + documentation string + (rudel-obby-server): cosmetic change + + * jupiter/jupiter.el (jupiter-context::jupiter-remote-operation): + improved documentation string; cosmetic changes + + * jupiter/jupiter-insert.el (jupiter-insert::jupiter-transform): + improved some comments + + * rudel.el (rudel-document::rudel-attach-to-buffer): renamed + some variables; added documentation string + (rudel-document::rudel-insert): improved documentation string + (rudel-document::rudel-chunks): do not create chunks when buffer + string is empty; improved comments + (rudel-choose-backend): compare number using `=' not `eq' + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document/record/ins): use + `rudel-remote-operation' instead of `rudel-remote-insert' + (rudel-obby-client::rudel-obby/obby_document/record/del): use + `rudel-remote-operation' instead of `rudel-remote-delete' + * obby/rudel-obby-client.el (include rudel-operations): for + rudel-insert-op and rudel-delete-op + (rudel-obby-connection::rudel-obby/obby_document/sync_chunk): use + `rudel-remote-operation' with rudel-insert-op to insert chunks + (rudel-obby-connection::rudel-obby/obby_document/record/ins): use + `rudel-remote-operation' instead of `rudel-remote-insert' + (rudel-obby-connection::rudel-obby/obby_document/record/del): use + `rudel-remote-operation' instead of `rudel-remote-delete' + * jupiter/jupiter-operation.el (include rudel-operations): for + rudel-operation + (jupiter-operation): derived from rudel-operation + (jupiter-operation::jupiter-apply): removed; replaced by generic + `rudel-apply' + * jupiter/jupiter-nop.el (jupiter-nop::jupiter-apply): removed; + replaced by `rudel-apply' + (jupiter-nop::rudel-apply): new method; implements generic + `rudel-apply' + * jupiter/jupiter-insert.el (include rudel-operations): for + jupiter-insert-op + (jupiter-insert): derived from jupiter-insert-op + (jupiter-insert::jupiter-apply): removed; inherited from + jupiter-insert-op + (jupiter-insert::slot-missing): removed; inherited from + jupiter-insert-op + * jupiter/jupiter-delete.el (include rudel-operations): for + jupiter-delete-op + (jupiter-delete): derived from jupiter-delete-op + (jupiter-delete::jupiter-apply): removed; inherited from + jupiter-delete-op + (jupiter-delete::slot-missing): removed; inherited from + jupiter-delete-op + * jupiter/jupiter-compound.el (jupiter-compound::jupiter-apply): + removed; replaced by `rudel-apply' + (jupiter-compound::rudel-apply): new method; implements generic + `rudel-apply' + * rudel.el (include rudel-operations): everything is represented + in terms of operations + (include rudel-operators): operations apply changes to objects + through operators + (rudel-document::rudel-insert): new method; performs insert + operation + (rudel-document::rudel-delete): new method; performs delete + operation + (rudel-document::rudel-local-insert): removed; document does not + deal with aspects other than the actual insert and delete + (rudel-document::rudel-local-delete): removed; document does not + deal with aspects other than the actual insert and delete + (rudel-document::rudel-remote-insert): removed; document does not + deal with aspects other than the actual insert and delete + (rudel-document::rudel-remote-delete): removed; document does not + deal with aspects other than the actual insert and delete + (rudel-document::rudel-local-operation): new method; apply + operation using overlay and connection operators + (rudel-document::rudel-remote-operation): new method; apply + operation using document and overlay operators + (rudel-handle-buffer-change): realize buffer changes using + operations + * rudel-operators.el (new file): collections of operations on + Rudel data types + * rudel-operations.el (new file): operation classes + +2009-02-01 Jan Moringen <scymtym@users.sourceforge.net> + + * jupiter/jupiter-insert.el (jupiter-insert::jupiter-transform): + handle jupiter-nop + + * jupiter/jupiter-delete.el (jupiter-delete::jupiter-transform): + in inner cond, use matching pattern but empty body for + no-operation cases; in outer cond, handle jupiter-nop + + * jupiter/jupiter-compound.el (jupiter-compound): now derived from + jupiter-operation; should have been right from the start + +2009-01-31 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-default-username): Default name used when + prompting for user name; required by rudel-interactive + + * rudel-interactive.el (rudel-read-backend): fixed typo + +2009-01-30 Jan Moringen <scymtym@users.sourceforge.net> + + * jupiter/jupiter-insert.el (jupiter-insert::jupiter-transform): + fixed two offset calculations + * jupiter/jupiter-delete.el (jupiter-delete::jupiter-transform): + fixed offset calculation + + * rudel.el (rudel-backend::rudel-ask-connect-info): changed from + method to generic + (rudel-backend::rudel-connect): changed from method to generic + (rudel-backend::rudel-ask-host-info): changed from method to + generic + (rudel-backend::rudel-host): changed from method to generic + (rudel-backend::rudel-make-document): changed from method to + generic + (rudel-session::rudel-disconnect): changed from method to generic + (rudel-session::rudel-change-color-): changed from method to + generic + (rudel-session::rudel-publish): changed from method to generic + (rudel-session::rudel-subscribe-to): changed from method to + generic + (rudel-session::rudel-unsubscribe-from): changed from method to + generic + (rudel-session::rudel-local-insert): changed from method to + generic + (rudel-session::rudel-local-delete): changed from method to + generic + (rudel-session::rudel-remote-insert): changed from method to + generic + (rudel-session::rudel-remote-delete): changed from method to + generic + +2009-01-28 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-overlay.el (header): fixed version + (whole file): cosmetic changes + (rudel-author-overlay-p): added documentation string + (rudel-author-overlays): added documentation string + + * rudel-mode.el (rudel-minor-keymap): cosmetic changes + + * rudel-mode.el (rudel-minor-keymap): Separated session + participation and hosting items + + * obby/rudel-obby.el (rudel-obby-long-message-threshold): Added + documentation string + (rudel-obby-long-message-chunk-size): Added documentation string + (rudel-obby-backend::rudel-connect): Do not set process object; + this is done in the `initialize-instance' method of the base class + (rudel-obby-format-color): retrieve color components with + `color-values' + + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-remove-context): improved + documentation string + (rudel-obby-connection::rudel-publish): added a comment + (rudel-obby-connection::rudel-subscribe-to): added some comments; + cleaned up code + (rudel-obby-connection::rudel-unsubscribe-from): added a comment + (rudel-obby-connection::rudel-obby/net6_ping): added documentation + string + (rudel-obby-connection::rudel-obby/net6_encryption): added + documentation string + (rudel-obby-connection::rudel-obby/net6_login_failed): added + documentation string + (rudel-obby-connection::rudel-obby/net6_client_part): use `=' + instead of `eq' to compare client ids; fixed documentation string; + improved comments + (rudel-obby-connection::rudel-obby/obby_user_colour): use `=' + instead of `eq' to compare user ids + (rudel-obby-connection::rudel-obby/obby_document/sync_chunk): use + `=' instead of `eq' to compare user ids; use accessor + `user-id-numeric' + + * obby/rudel-obby-util.el (rudel-obby-dispatch): new functions; + dispatches to class methods based on message name; handles errors + properly + * obby/rudel-obby-server.el (rudel-obby-client::rudel-message): + use `rudel-obby-dispatch' to dispatch message + (rudel-obby-client::rudel-obby/obby_document): use + `rudel-obby-dispatch' to dispatch message + (rudel-obby-client::rudel-obby/obby_document/record): use + `rudel-obby-dispatch' to dispatch message + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-message): use `rudel-obby-dispatch' + to dispatch message; moved to a different location + (rudel-obby-connection::rudel-obby/obby_document): use + `rudel-obby-dispatch' to dispatch message + (rudel-obby-connection::rudel-obby/obby_document/record): use + `rudel-obby-dispatch' to dispatch message + + * obby/rudel-obby-util.el (generic rudel-message): made the method + a generic function and updated the documentation string + +2009-01-26 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (rudel-obby-document::revision): removed; The + slot is no longer needed + * obby/rudel-obby-server.el (require jupiter): uses jupiter + algorithm + (rudel-obby-client::rudel-obby/obby_document_create): add a + jupiter context for the document + (rudel-obby-client::rudel-obby/obby_document/subscribe): add a + jupiter context for the document + (rudel-obby-client::rudel-obby/obby_document/unsubscribe): remove + the jupiter context associated to the document + (rudel-obby-client::rudel-obby/obby_document/record/ins): + transformed the operation before applying it to the buffer; use + the respective jupiter contexts of the receivers when sending the + operation + (rudel-obby-client::rudel-obby/obby_document/record/del): + transformed the operation before applying it to the buffer; use + the respective jupiter contexts of the receivers when sending the + operation + (rudel-obby-server::contexts): new slot; stores jupiter contexts + for pairs of clients and documents + (rudel-obby-server::initialize-instance): new method; store an + empty hash-table in the `contexts' slot + (rudel-obby-server::rudel-find-context): find the jupiter context + for a pair of a client and a document + (rudel-obby-server::rudel-add-context): add a jupiter context for + a pair of a client and a document + (rudel-obby-server::rudel-remove-context): remove the jupiter + context for a pair of a client and a document + (rudel-obby-context-key): return a list of client id and document + id + * obby/rudel-obby-client.el (require jupiter): uses jupiter + algorithm + (rudel-obby-connection::contexts): new slot; stores jupiter + contexts for documents + (rudel-obby-connection::initialize-instance): new method; store an + empty hash-table in the `contexts' slot + (rudel-obby-connection::rudel-find-context): new method; return + the jupiter context for a document + (rudel-obby-connection::rudel-add-context): new method; add a + jupiter context for a document + (rudel-obby-connection::rudel-remove-context): new method; remove + the jupiter context for a document + (rudel-obby-connection::rudel-publish): add a jupiter context for + the new document + (rudel-obby-connection::rudel-subscribe-to): add a jupiter context + for the new document + (rudel-obby-connection::rudel-unsubscribe-from): remove the + jupiter context associated to the document + (rudel-obby-connection::rudel-local-insert): use revision + information from the jupiter context instead of the document; + supply the operation to the jupiter context + (rudel-obby-connection::rudel-local-delete): use revision + information from the jupiter context instead of the document; + supply the operation to the jupiter context + (rudel-obby-connection::rudel-obby/obby_document/record/ins): + transform the operation using the jupiter context instead of using + it unmodified + (rudel-obby-connection::rudel-obby/obby_document/record/del): + transform the operation using the jupiter context instead of using + it unmodified + +2009-01-22 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby-client.el (rudel-obby-connection): removed + redundant slot `socket' (inherited from base class) + +2009-01-21 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel-interactive.el (rudel-read-user): added comments + (rudel-allocate-buffer-clear-existing): added documentation string + (rudel-allocate-buffer-make-unique): added documentation string + +2009-01-19 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el, rudel-util.el, rudel-telepathy.el, rudel-speedbar.el, + rudel-overlay.el, rudel-mode.el, jupiter/jupiter.el, + jupiter/jupiter-operation.el, jupiter/jupiter-nop.el, + jupiter/jupiter-insert.el, jupiter/jupiter-delete.el, + jupiter/jupiter-compound.el, obby/rudel-obby.el, + obby/rudel-obby-util.el, obby/rudel-obby-server.el, + obby/rudel-obby-client.el (header): changed email address + <scymtym@users.sourceforge.net> -> + <scymtym@users.sourceforge.net> + + * rudel-interactive.el (header): added keywords to file header + comment + + * jupiter/jupiter.el (new file): core Jupiter algorithm + * jupiter/jupiter-operation.el (new file): base class for Jupiter + operations + * jupiter/jupiter-insert.el (new file): insert operation for + Jupiter algorithm + * jupiter/jupiter-delete.el (new file): delete operation for + Jupiter algorithm + * jupiter/jupiter-nop.el (new file): no-operation for Jupiter + algorithm + * jupiter/jupiter-compound.el (new file): compound operation for + Jupiter algorithm + +2009-01-11 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (rudel-obby-user::client-id): added rationale + for type (or null integer) + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-obby/net6_client_join): added + documentation string; cosmetic changes + (rudel-obby-connection::rudel-obby/net6_client_part): use accessor + `rudel-client-id' when searching for the user object; set + client-id to nil in the user object; added documentation string + (rudel-obby-connection::rudel-obby/obby_sync_usertable_user): + store parsed user-id and color in temporaries + (rudel-obby-connection::rudel-obby/obby_user_colour):store parsed + color in a temporary; use accessor `rudel-id' when finding the + user object + + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-change-color-): new function; + implements changing the color + + * obby/rudel-obby-util.el + (rudel-obby-socket-owner::rudel-receive): improved documentation + string + +2009-01-05 Jan Moringen <scymtym@users.sourceforge.net> + + * INSTALL (REQUIREMENTS): proper list of requirements and sources + from which they can be obtained + (INSTALLING): initial version of installation instructions + (COMPLETING): some notes about compiling + * README (INTRODUCTION): short introduction + (GETTING STARTED): some notes about enabling Rudel, joining and + hosting sessions + +2009-01-04 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (rudel-obby-long-message-threshold): new + variable; threshold for message size, above which messages are + sent in multiple chunks + (rudel-obby-long-message-chunk-size): Chunk size used, when + chunking long messages. + (rudel-obby-user::client-id): allow value nil; added accessor; + added documentation string + (rudel-obby-send): new function; handles low-level aspects of + sending obby protocol messages + * obby/rudel-obby-util.el: new file; contains helper + functionality, mainly the class `rudel-obby-socket-owner', which + handles sending and receiving message + * obby/rudel-obby-server.el (includes): replaced rudel-obby with + rudel-obby-util, since it contains `rudel-obby-socket-owner' + (class rudel-obby-client): added base class + `rudel-obby-socket-owner' + (rudel-obby-client::rudel-receive): deleted, the functionality is + provided by the base class `rudel-obby-socket-owner' + (rudel-obby-client::rudel-send): deleted, the functionality is + provided by the base class `rudel-obby-socket-owner' + (rudel-obby-client::rudel-message): new method; called by base + class when a message is received; dispatches to appropriate + handler method + (rudel-obby-client::rudel-obby/obby_user_colour): minor change in + documentation string + * obby/rudel-obby-client.el (includes): replaced rudel-obby with + rudel-obby-util, since it contains `rudel-obby-socket-owner' + (class rudel-obby-connection): added base class + `rudel-obby-socket-owner' + (rudel-obby-connection::rudel-disconnect): just call next method; + it does what this method formerly did + (rudel-obby-connection::rudel-close): new method; end the session, + when the connection is closed + (rudel-obby-connection::rudel-receive): deleted, the functionality + is provided by the base class `rudel-obby-socket-owner' + (rudel-obby-connection::rudel-send): deleted, the functionality is + provided by the base class `rudel-obby-socket-owner' + (rudel-obby-connection::rudel-message): new method; called by + base class when a message is received; dispatches to appropriate + handler method + + * rudel.el (rudel-document::rudel-detach-from-buffer): do nothing, + if the document is not attached to any buffer + + * obby/rudel-obby.el (rudel-obby-user): added missing accessor + `rudel-connected' + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/net6_client_login): transmit number + of synchronization items; transmit list of disconnected users + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document/record/ins): + broadcast only to clients, which are subscribed to the document; + send user id of author instead of client id + (rudel-obby-client::rudel-obby/obby_document/record/del): + broadcast only to clients, which are subscribed to the document; + send user id of author instead of client id + (rudel-obby-client::rudel-subscribed-clients-not-self): new + method; return a list of clients subscribed to a document + excluding the client itself. + + * obby/rudel-obby-server.el (rudel-obby-server::next-client-id): + first id should be 1, not 0; fixed initform accordingly + (rudel-obby-server::next-user-id): + first id should be 1, not 0; fixed initform accordingly + + * rudel.el (rudel-document::rudel-chunks): fixed void variable + `chunks-' -> `augmented-chunks' + + * obby/rudel-obby-server.el + (rudel-obby-client::rudel-obby/obby_document/subscribe): send + individual buffer chunks with their respective authors instead of + one large string without author information + * rudel.el (rudel-document::rudel-chunks): new method; return a + list of buffer position ranges and the respective authors, that + wrote the text + +2009-01-03 Jan Moringen <scymtym@users.sourceforge.net> + + * obby/rudel-obby.el (rudel-obby-backend::rudel-host): cleanup + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-local-insert): accept arguments + `position' and `data' instead of `from', `to' and `what'; since + position is zero-based, transmit it literally + (rudel-obby-connection::rudel-local-delete): instead of `from' and + `to' accept argument `position'; since position is + zero-based. transmit it literally + (rudel-obby-connection::rudel-obby/obby_document/record): + identified remaining arguments; dispatch actions to appropriate + methods; identify methods by interning their symbols + (rudel-obby-connection::rudel-obby/obby_document/record/ins): new + method; handle remote insert actions + (rudel-obby-connection::rudel-obby/obby_document/record/del): new + method; handle remote delete actions + * rudel.el (includes): include rudel-overlay + (rudel-document::rudel-detach-from-buffer): improved readability + (rudel-document::rudel-local-insert): instead of redundant + arguments `from', `to' and `what' accept only `position' and + `data'; update overlays + (rudel-document::rudel-local-delete): instead of redundant + arguments `from', `to' and `length' accept only `position' and + `length'; update overlays + (rudel-document::rudel-remote-insert): renamed arguments `from' -> + `position', `what' -> `data'; update overlays + (rudel-document::rudel-remote-delete): replaced arguments `from' + and `to' by `position'; update overlays + (rudel-handle-buffer-change): call rudel-local-{insert, delete} + with changed arguments + +2009-01-01 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-session::rudel-unsubscribed-documents): new + method; returns documents, to which the user associated with the + session is not yet subscribed + (rudel-subscribe): when called interactively, use + `rudel-unsubscribed-documents' to offer only unsubscribed + documents in completing read + + * rudel-interactive.el (rudel-read-user-name): new function; read + a user name; could be used to enforce certain constraints on the + name + (rudel-read-user-color): new function; read a user color; could be + used to enforce certain constraints on the color + + * obby/rudel-obby.el (rudel-obby-backend::rudel-ask-host-info): + new method; ask user for port number + (rudel-obby-backend::rudel-host): new method; require obby server + component, make the network process and construct the server + * obby/rudel-obby-server.el (new file): initial revision of obby + server for rudel + * obby/rudel-obby-client.el (header section): added keyword and + x-rcs + (rudel-obby-connection::rudel-publish): new method; send document + to server + (rudel-obby-connection::rudel-unsubscribe-from): send unsubscribe + notification to server + (rudel-obby-connection::rudel-local-insert): cleanup + (rudel-obby-connection::rudel-local-delete): new method; send + delete record to server and increase local revision + (rudel-obby-connection::rudel-obby/obby_document/sync_chunk): + improved user locating code; do not complain, when the user is not + found + (rudel-obby-connection::rudel-obby/obby_document/record): removed + useless debug message + * rudel.el (class rudel-session): update documentation string + (class rudel-server-session): new class; base class for server + sessions + (rudel-choose-backend): fixed void-variable when called + interactively + (rudel-host-session): provided initial implementation, which uses + the selected backend to create a server + (rudel-subscribe): call `set-window-buffer' instead of + `show-buffer' + + * obby/rudel-obby.el (header section): fixed history + (rudel-obby-version): new constant; holds version of the obby + backend + (rudel-obby-protocol-version): new constant; holds the obby + protocol version understood by the backend + (rudel-obby-document::rudel-both-ids): new method; useful when + locating documents by means of owner and document id + + * rudel-mode.el (header section): added keywords + + * rudel-interactive.el (header section): added file comment + +2008-12-30 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (class rudel-session): converted to base class for + other session classes; removed slots `connection' and `self' which + are specific for client sessions + (rudel-session::rudel-end): empty now; derived classes do the work + (rudel-session::rudel-add-user): use `object-add-to-list' + (rudel-session::rudel-remove-user): use `object-remove-from-list' + (rudel-session::rudel-add-document): use `object-add-to-list' + (rudel-session::rudel-remove-document): use + `object-remove-from-list' + (class rudel-client-session): derived from `rudel-session'; + additional slots `connection' and `self' + (rudel-client-session::rudel-end): detach buffers from documents + and call `rudel-disconnect' on connection + (class rudel-connection): documentation string + (rudel-connection::rudel-disconnect): remove hook + `after-change-functions' only locally + (rudel-join-session): construct a proper session name; store + backend object in the session; some comments + + * obby/rudel-obby.el (rudel-obby-document): cleanup; improved + documentation strings + + * rudel-overlay.el (new file): functions for managing overlays, + which indicate the authors of contributions in collaborative + buffers + + * rudel.el (rudel-allocate-buffer-function): customization option + for buffer allocation function + (rudel-subscribe): call buffer allocation function instead of just + using the provided name + * rudel-interactive.el (rudel-allocate-buffer-clear-existing): new + function; in case of a conflict, allocate buffer for subscription + by clearing the existing buffer + (rudel-allocate-buffer-make-unique): new function; in case of a + conflict, allocate buffer for subscription by producing a unique + name + + * rudel.el (customization): added customization group definition + for `rudel' + + * obby/rudel-obby.el (includes): require `rudel-util' instead of + `rudel' + (rudel-connect): attach connection to socket object + (rudel-obby-document): removed slot `subscribed' as it is now + contained in the base class `rudel-document' + (rudel-obby-escape-string): call `rudel-obby-replace-in-string' + instead of `obby-replace-in-string' + (rudel-obby-unescape-string): call `rudel-obby-replace-in-string' + instead of `obby-replace-in-string' + * obby/rudel-obby-client.el + (rudel-obby-connection::rudel-state-change): required by + `rudel-sentinel-dispatch' + (rudel-obby-connection::rudel-subscribe-to): do not touch slot + `subscribed' + (rudel-obby-connection::rudel-obby/obby_sync_doclist_document): + retrieve subscribed users and add to `subscribed' slot + (rudel-obby-connection::rudel-obby/obby_document_create): add + document owner to `subscribed' slot + (rudel-obby-connection::rudel-obby/obby_document/subscribe): add + user to `subscribed' slot + (rudel-obby-connection::rudel-obby/obby_document/unsubscribe): + remove user from `subscribed' slot + * rudel.el (rudel-document): added slot `subscribed' which + contains a list of subscribed users + (rudel-subscribe): do not use `rudel-unsubscribed-documents'; + instead list all documents for now + (rudel-publish-buffer): add self to `subscribed' slot + + * rudel-util.el (rudel-state-change): cleanup; added comments + + * rudel-mode.el (rudel-minor-keymap): Fixed invalid menu + definition + + * obby/rudel-obby.el (whole file): moved class + `rudel-obby-connection' and related methods into file + `rudel-obby-client.el' + (rudel-obby-backend): added capability `track-subscriptions' + (rudel-obby-backend::rudel-connect): require `rudel-obby-client' + before constructing the connection object + * obby/rudel-obby-client.el (new file): moved class + `rudel-obby-connection' and related methods into this file + +2008-12-29 Jan Moringen <scymtym@users.sourceforge.net> + + * rudel.el (rudel-connection::rudel-change-color-): new method + handles color changes + (rudel-change-color): added basic implementation, which checks the + backend, asks the user for a new color and calls the connection + object + + * rudel-util.el (rudel-socket-owner::rudel-state-change): called + when the state of the connection changes + (rudel-socket-owner::rudel-close): called when the connection is + closed + (rudel-sentinel-dispatch): the argument is a message, not the + actual state, the state is retrieved with `process-state' + + * rudel-speedbar.el (whole file): cleanup; improved comments + + * rudel-mode.el (whole file): improved comments + (rudel-read-{backend, document}): moved to rudel-interactive.el + (rudel-minor-keymap): added key binding for `rudel-change-color'; + added `options' menu item + + * rudel-interactive.el (whole file): user interaction functions + used by all Rudel components + + * rudel-util.el (whole file): utility functions used by all Rudel + components + + * rudel.el (whole file): improved comments + (rudel-backend::make-document): new function create an appropriate + document object for the backend + (rudel-session::rudel-end): added documentation string + (rudel-session::rudel-add-user): added documentation string + (rudel-session::rudel-remove-user): added documentation string + (rudel-session::rudel-remove-document): new method; remove + document from session + (rudel-connection::rudel-publish): new function; called when a + buffer is published + (rudel-connection::rudel-unsubscribe-from): new function; called + when a subscription is canceled + (class rudel-user): added documentation strings + (class rudel-document): added documentation strings + (rudel-document::rudel-attach-to-buffer): add to + `after-change-functions' hook only for the buffer in question; + added some comments + (rudel-document::rudel-detach-from-buffer): cleanup + (rudel-document::rudel-remote-insert): added comments + (rudel-document::rudel-remote-delete): added comments + (rudel-handle-buffer-change): added comments + (rudel-choose-backend): added comments + (rudel-end-session): additional error check + (rudel-subscribe): call `rudel-unsubscribed-documents' when + completing document name; added comments + (rudel-unpublish-buffer): call `rudel-detach-from-buffer' and + `rudel-unsubscribe-from'; added comments + + * obby/rudel-obby.el (whole file): improved comments + (rudel-obby-backend::rudel-ask-connect-info): removed :override + tag; added comments + (rudel-obby-backend::rudel-connect): removed :override tag; use + `make-network-process' instead of `open-network-stream' and attach + filter and sentinel right away; removed some debug code + (rudel-obby-backend::rudel-disconnect): removed :override tag + (rudel-obby-backend::rudel-subscribe-to): removed :override tag + (rudel-obby-backend::rudel-local-insert): removed :override tag + (rudel-obby-backend::rudel-local-delete): removed :override tag + (rudel-obby-backend::rudel-make-document): new method; creates a + new rudel-obby-document object + (rudel-obby-backend::rudel-available-document-id): obtains an + unused document id, which can be assigned to a new document + (class rudel-obby-connection): removed useless `host' and `port' + slots + (rudel-obby-connection::rudel-receive): removed some debug code + (rudel-obby-connection::rudel-send): removed some debug code + (rudel-obby-connection::rudel-obby/net6_client_join): fixed syntax + error + (class rudel-obby-user): added accessors for slots `client-id' and + `user-id' + (rudel-obby-user::eieio-speedbar-description): removed :override + tag + (rudel-obby-user::eieio-speedbar-object-buttonname): removed + :override tag + (class rudel-obby-document): added accessors and documentation for + slot `id' + (rudel-obby-document::eieio-speedbar-object-buttonname): removed + :override tag + (rudel-obby-replace-in-string): new function; replace a set of + patterns in a string + (rudel-obby-escape-string): new function; replace obby control + characters with their escape sequences + (rudel-obby-unescape-string): new function; inverse of + `rudel-obby-escape-string' + (rudel-obby-parse-color): added documentation + (rudel-obby-format-color): added documentation + (rudel-obby-assemble-message): properly escape message components + (rudel-obby-parse-message): properly unescape message components + + * README (whole file): some initial notes + * INSTALL (whole file): some initial notes + +2008-12-02 Jan Moringen <scymtym@users.sourceforge.net> + + * obby (directory): new directory for files belonging to the obby + backend + * rudel-obby.el (whole file): moved to `obby' directory + * obby/rudel-obby.el (whole file): moved here from parent + directory + + * Changelog (whole file): renamed to `ChangeLog?' + * ChangeLog? (whole file): fixed name + + * INSTALL (whole file): added + + * rudel.el (whole file): fixed some comments, removed some test + code + (rudel-version): new variable; global Rudel version + (rudel-sessions): removed; we only allow one session for now + (rudel-session): cleaned up + (rudel-session::rudel-end): cleaned up; added some comments + (rudel-session::rudel-add-user): cosmetic changes + (rudel-session::rudel-remove-user): cosmetic changes + (rudel-session::rudel-find-user): cosmetic changes + (rudel-session::rudel-add-document): cosmetic changes + (rudel-session::rudel-find-document): cosmetic changes + (rudel-backend::rudel-connect): improved documentation string + (rudel-backend::rudel-ask-host-info): renamed from + `rudel-ask-listen-info' + (rudel-backend::rudel-host): renamed from `rudel-listen' + (rudel-document::rudel-attach-to-buffer): cosmetic changes + (rudel-document::rudel-remote-insert): cleaned up + (rudel-document::rudel-remote-delete): cleaned up + (rudel-load-backends): cosmetic changes + (rudel-choose-backend): fixed message display + (rudel-host-session): improved documentation string + (rudel-change-color): raise an error since this is not yet + implemented + (rudel-subscribe): added comments + (rudel-unpublish-buffer): raise an error if the buffer has not + been published + + * rudel.el (whole file): cleanup up some obsolete code diff --git a/emacs.d/lisp/rudel/.svn/text-base/INSTALL.svn-base b/emacs.d/lisp/rudel/.svn/text-base/INSTALL.svn-base new file mode 100644 index 0000000..2555d09 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/INSTALL.svn-base @@ -0,0 +1,58 @@ +* REQUIREMENTS + + Rudel is developed and tested only with GNU Emacs and therefore + unlikely to run on other Emacs variants like XEmacs. + + To use Rudel, the following software is required: + +** GNU Emacs 22 or above + Rudel should work with recent versions of GNU Emacs starting from + version 22. Older versions of GNU Emacs or XEmacs may or not work + but are not actively tested. + +** Collection of Emacs Development Environment Tools (CEDET) + Cedet contains the object system Eieio, which is used in Rudel's + object-oriented implementation. Cedet can be obtained from + http://cedet.sourceforge.net/ + + IMPORTANT: It is necessary to use at least the 1.0pre6 version of + CEDET since it fixes a serious problem in the object system Eieio. + + As of October 2009, Eieio is included in GNU Emacs. If you are + using a version built since then, you do not have to install it + yourself. + +** GnuTLS (optional) + Connections to Gobby servers require the gnutls-cli program. + +** Avahi (optional) + The Avahi daemon (http://avahi.org) is required for automatic + session discovery and advertising. + + A version of GNU Emacs with Zeroconf support (GNU Emacs 23 or + above) is required to talk to the Avahi daemon. + +* INSTALLING + + To install Rudel, download a released version or the current + development version from http://sourceforge.net/projects/rudel/ and + place the code in any directory you like. + + Once Eieio (see CEDET in the REQUIREMENTS section above) is + installed, add the following to your personal Emacs configuration: + + (load-file "/PATH/TO/RUDEL/rudel-loaddefs.el") + + This will set Rudel up to be loaded on demand when one of the + commands `rudel-join-session', `rudel-host-session' or + `global-rudel-minor-mode' is invoked. + +* COMPILING + + In order to achieve better performance, Emacs can byte-compile the + Rudel code. This can be done by opening rudel-compile.el in Emacs + and invoking M-x eval-buffer. + +Local variables: +mode: org +end: diff --git a/emacs.d/lisp/rudel/.svn/text-base/Project.ede.svn-base b/emacs.d/lisp/rudel/.svn/text-base/Project.ede.svn-base new file mode 100644 index 0000000..ff3a264 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/Project.ede.svn-base @@ -0,0 +1,24 @@ +;; Object rudel +;; EDE project file. +(ede-proj-project "rudel" + :name "rudel" + :version "0.3" + :file "Project.ede" + :targets (list + (ede-proj-target-elisp-autoloads "autoloads" + :name "autoloads" + :path "" + :autoload-file "rudel-loaddefs.el" + :autoload-dirs '("." "jupiter" "obby" "wave" "zeroconf") + ) + (ede-proj-target-elisp "compile" + :name "rudel" + :path "" + :source '("rudel.el" "rudel-util.el" "rudel-mode.el" "rudel-interactive.el" "rudel-overlay.el" "rudel-speedbar.el" "rudel-operators.el" "rudel-operations.el" "rudel-compat.el" "rudel-tls.el" "rudel-errors.el" "rudel-state-machine.el" "rudel-backend.el" "rudel-protocol.el" "rudel-session-initiation.el" "rudel-icons.el" "rudel-hooks.el" "rudel-transport.el" "rudel-chat.el") + ) + ) + :mailinglist "rudel-devel@lists.sourceforge.net" + :web-site-url "http://rudel.sourceforge.net/" + :web-site-directory "/scymtym,rudel@web.sourceforge.net:/home/groups/r/ru/rudel/htdocs" + :configuration-variables 'nil + ) diff --git a/emacs.d/lisp/rudel/.svn/text-base/README.svn-base b/emacs.d/lisp/rudel/.svn/text-base/README.svn-base new file mode 100644 index 0000000..aeacba7 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/README.svn-base @@ -0,0 +1,88 @@ +* INTRODUCTION + + Rudel is collaborative editing environment for GNU Emacs. Its + purpose is to share buffers with other users in order to edit the + contents of those buffers collaboratively. Rudel supports multiple + backends to enable communication with other collaborative editors + using different protocols, though currently Obby (for use with the + Gobby editor) is the only fully-functional one. + + Since Rudel is not an application, but an extension to Emacs, it is + not started and used like most applications (not even Emacs + applications like Gnus). Rudel mostly works in the background to + change the behavior of the set of Emacs buffers for which it has + been activated. + + The user interface consists of a set of key bindings, a menu entry + and some visual status indicators, which are added to the text and + mode line of buffers for which Rudel has been activated. + +* GETTING STARTED + + Assuming Rudel has already been installed and auto loading has been + set up, a global Rudel mode can be enabled as follows: + + : M-x global-rudel-minor-mode + + This will enabled Rudel's key bindings and menu entry. + +** JOINING A SESSION + + : M-x rudel-join-session [ C-c c j ] + + Depending on the installed Rudel backends, system environment and + configuration, a number of questions will be asked, followed by an + attempt to join session described by your answers. + + A typical example of the questions asked when joining a session may + look like this: + + Server: localhost RET + Port (default 6522): RET + Username: jan RET + Color: light sky blue RET + Use Encryption (y or n): n RET + Global Password: RET + User Password: RET + + IMPORTANT: For sessions using the obby backend (like in the example + above), the following restriction has to be taken into account: + + When the server is Rudel inside an Emacs process: + Encryption cannot be used currently in this case. Consequently + the answer to the `Use Encryption (y or n):' prompt above has to + be `n RET'. + + When the server is a Gobby process: + Gobby only supports encrypted connections. So the answer has to + be `y RET' is this case. + + It is possible to configure frequently used sessions using the + customization options `rudel-configured-sessions'. When one or more + sessions are configured, `rudel-join-session' will provide choices + like "my-configured-session", ... and "ask-protocol". Selecting + "ask-protocol" invokes the behavior described above. Selecting one + of the configured sessions connects to that session without asking + for all the data. + +** HOSTING A SESSION + + : M-x rudel-host-session [ C-c c h ] + + Note that the session starts out without any participating users + (This is sometimes referred to as being a dedicated server). If you + want to participate in the session you host, you have to join it as + described above. + +* KNOWN ISSUES + + + Publishing eshell buffers will cause your session to be + disconnected since eshell disables the hooks that Rudel uses to + catch changes to the buffer. As a workaround, you can use M-x + ansi-term or another terminal emulator. + +* LICENSE + + Rudel is licensed under the same terms as GNU Emacs. + +Local variables: +mode: org +end: diff --git a/emacs.d/lisp/rudel/.svn/text-base/TODO.svn-base b/emacs.d/lisp/rudel/.svn/text-base/TODO.svn-base new file mode 100644 index 0000000..e5e4bf4 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/TODO.svn-base @@ -0,0 +1,436 @@ +* Future +** NEW Handle messages spanning multiple frames + + Component :: beep-transport + + Type :: defect + + Reporter :: jan + + Assigned :: +** NEW Operation log can grow beyond all bounds (#37) + + Component :: obby-general + + Type :: defect + + Reporter :: jan + + Assigned :: + When no remote operations are received, the log of local operation + is not reset and therefore grows beyond all bounds. +** NEW Terminating sessions does not work (#47) + + Component :: rudel-general + + Type :: defect + + Reporter :: jan + + Assigned :: + There is a menu entry for terminating sessions which are hosted by + Rudel, but it does not do anything. +** NEW Rename document message is not understood (#7) + + Component :: obby-client + + Type :: defect + + Reporter :: jan + + Assigned :: +** NEW Rename document message is not understood (#8) + + Component :: obby-backend + + Type :: defect + + Reporter :: jan + + Assigned :: +** TODO Notification mechanism + + Component :: user-interface + + Type :: task + + Reporter :: jan + + Type :: task + + Assigned :: +** TODO SubEthaEdit client functionality + + Component :: subethaedit-backend + + Type :: task + + Reporter :: jan + + Assigned :: +** TODO Show cursor positions of other users (#5) + + Component :: rudel-user-interface + + Type :: enhancement + + Reporter :: jan + + Assigned :: +** TODO Some kind of server log buffer (#11) + + Component :: rudel-general + + Type :: enhancement + + Reporter :: jan + + Assigned :: + It would be nice to log server events. This could be done in a + separate buffer or using a dedicated mechanism like + rudel-notification. +** TODO Backends should be able to offer additional menu items (#14) + + Component :: rudel-general + + Type :: enhancement + + Reporter :: jan + + Assigned :: +** TODO Obby session can be protected by passwords (#15) + + Component :: obby-general + + Type :: enhancement + + Reporter :: jan + + Assigned :: +** TODO Obby users can protect their accounts with passwords (#16) + + Component :: obby-general + + Type :: enhancement + + Reporter :: jan + + Assigned :: + The Gobby implementation is in obby/inc/server_buffer.hpp:851 +** TODO Zeroconf session notification (#52) + + Component :: zeroconf + + Type :: task + + Reporter :: jan + + Assigned :: + Watch interesting Zeroconf services and use `rudel-notify` if new + services are discovered +** TODO State machine diagram (#59) + + Component :: obby-client + + Type :: task + + Reporter :: jan + + Assigned :: +** TODO State machine diagram (#60) + + Component :: obby-backend + + Type :: task + + Reporter :: jan + + Assigned :: +** TODO Send key presses as chat messages (#61) + + Component :: rudel-general + + Type :: task + + Reporter :: Jan + + Assigned :: + Sending key presses as chat messages could be really useful for + somebody something using rudel. +** STARTED BEEP transport + + Component :: beep-transport + + Type :: task + + Reporter :: jan + + Assigned :: jan +** STARTED Reference manual (#46) + + Component :: documentation + + Type :: task + + Reporter :: jan + + Assigned :: jan + In addition to the `README`, a proper reference manual would be + nice. At some point, complete info documentation may be + desirable. Docbook seems to be the best approach since we get (at + least): + + Pdf + + Html + + Info + + +* Milestone rudel-0.4 +** TODO Telepathy transport + + Component :: telepathy-backend + + Type :: task + + Reporter :: jan + + Assigned :: + +* Milestone rudel-0.3 +** TODO Multiple username/password attempts in one login attempt + + Component :: rudel-general + + Type :: task + + Reporter :: jan + + Assigned :: +** TODO Infinote client functionality + + Component :: infinote-backend + + Type :: task + + Reporter :: jan + + Assigned :: +** TODO Support for trees of documents + + Component :: rudel-general + + Type :: task + + Reporter :: jan + + Assigned :: +** NEW Get rid of error calls in the server (#58) + + Component :: obby-backend + + Type :: defect + + Reporter :: jan + + Assigned :: + It makes no sense to call `error` when something goes wrong in + server code that is called from the process filter. Instead, we + should try to recover. +** NEW Global mode line publish state mode does not work for all new buffers (#55) + + Component :: rudel-user-interface + + Type :: defect + + Reporter :: jan + + Assigned :: + `global-mode-line-publish-state-mode` is define using + `define-globalized-mode`. This seems to only enabled the associated + minor mode for buffers create by `find-file` and after major mode + changes. The minor mode is not activated for buffers create by + `create-buffer`. Since this is used when subscribing to documents, + this is a problem. +** NEW Handle net6_encryption_info messages (#57) + + Component :: obby-backend + + Type :: defect + + Reporter :: jan + + Assigned :: +** TODO Only read color hue, not complete colors (#53) + + Component :: rudel-user-interface + + Type :: enhancement + + Reporter :: jan + + Assigned :: + Taking control over saturation and value away from the user makes + it impossible to choose unreadable colors. + + +* Milestone rudel-0.2 +** DONE Use state pattern (#18) + + Component :: obby-backend + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** FIXED Server buffers go out of sync when multi-byte characters are used (#56) + + Component :: obby-backend + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** FIXED Terminate connections properly when something goes wrong (#51) + + Component :: rudel-general + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** FIXED Removing documents does not work (#45) + + Component :: obby-backend + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** FIXED Search list of offline users when new users log in (#44) + + Component :: obby-backend + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** DONE Reference card (#2) + + Component :: documentation + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** DONE ode-line indicator of buffer status (#6) + + Component :: rudel-user-interface + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** FIXED Author overlay face may not exist (#54) + + Component :: rudel-user-interface + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** DONE Visualization of user status (#9) + + Component :: rudel-user-interface + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** FIXED Update overlays when users change colors (#23) + + Component :: rudel-user-interface + + Resolution :: fixed + + Type :: defect + + Priority :: minor + + Reporter :: jan +** DONE Allow to toggle display of author overlays (#33) + + Component :: rudel-user-interface + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** DONE Update file headers (#50) + + Component :: documentation + + Resolution :: fixed + + Type :: task + + Priority :: trivial + + Reporter :: jan +** DONE Proper Zeroconf support (#21) + + Component :: zeroconf + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** DONE Add discovery component (#22) + + Component :: obby-general + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** DONE Define initialize-instance with slots or &rest slots? (#49) + + Component :: rudel-general + + Resolution :: fixed + + Type :: task + + Priority :: major + + Reporter :: jan +** DONE Use oref to get object names (#24) + + Component :: rudel-general + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** DONE Overlays should be removed when a buffer is detached from its document (#39) + + Component :: rudel-user-interface + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** FIXED Unsafe use of (call-next-method) (#48) + + Component :: rudel-general + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** FIXED Handle `net6_login_failed' message (#10) + + Component :: obby-backend + + Resolution :: fixed + + Type :: defect + + Priority :: minor + + Reporter :: jan +** DONE Add debug hints to macros (#43) + + Component :: rudel-general + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** DONE Use state pattern (#17) + + Component :: obby-backend + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** DONE Use with-parsed-arguments (#40) + + Component :: obby-general + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan + + +* Milestone rudel-0.1 +** FIXED User names and colors are not checked for conflicts (#12) + + Component :: obby-backend + + Resolution :: fixed + + Type :: defect + + Priority :: minor + + Reporter :: jan +** DONE Write some html for rudel.sourceforge.net (#27) + + Component :: www + + Resolution :: fixed + + Type :: task + + Priority :: major + + Reporter :: jan +** INVALID Repeated publishing leads to multiple document instances (#30) + + Component :: obby-backend + + Resolution :: invalid + + Type :: defect + + Priority :: minor + + Reporter :: jan +** FIXED Document suffixes are not handled properly (#42) + + Component :: obby-backend + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** DONE Fix license texts (#32) + + Component :: rudel-general + + Resolution :: fixed + + Type :: enhancement + + Priority :: trivial + + Reporter :: jan +** WONTFIX Overlays break on last character (#29) + + Component :: rudel-user-interface + + Resolution :: worksforme + + Type :: defect + + Priority :: minor + + Reporter :: jan +** FIXED Encodings are not handled in obby backend (#1) + + Component :: obby-general + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** FIXED Major mode changes break subscribed buffers (#19) + + Component :: rudel-general + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** FIXED Editing in overwrite mode breaks synchronization (#35) + + Component :: rudel-general + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** FIXED Yanking produces insertion and immediate deletion of the region (#36) + + Component :: rudel-general + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** FIXED Documents with identical names but distinct suffixes map to same buffer (#41) + + Component :: obby-backend + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** FIXED Killing a buffer does not detach it from its document (#38) + + Component :: rudel-general + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** INVALID Rudel client crashes Gobby (#25) + + Component :: obby-general + + Resolution :: invalid + + Type :: defect + + Priority :: major + + Reporter :: jan +** DONE Add screenshot of session with Gobby (#20) + + Component :: www + + Resolution :: fixed + + Type :: task + + Priority :: trivial + + Reporter :: jan +** DONE Replace 't with t (#34) + + Component :: rudel-general + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** DONE Operations of type jupiter-compound cannot be applied to buffers + (#31) + + Component :: rudel-general + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan +** DONE Do not sync any chunks when buffer is empty (#28) + + Component :: obby-backend + + Resolution :: fixed + + Type :: enhancement + + Priority :: minor + + Reporter :: jan +** DONE Implement Jupiter algorithm (#13) + + Component :: obby-general + + Resolution :: fixed + + Type :: enhancement + + Priority :: major + + Reporter :: jan +** DONE Replace email address (#26) + + Component :: rudel-general + + Resolution :: fixed + + Type :: task + + Priority :: major + + Reporter :: jan +** FIXED Mark contributions using overlays (#4) + + Component :: rudel-user-interface + + Resolution :: fixed + + Type :: enhancement + + Priority :: major + + Reporter :: jan +** FIXED When a user leaves and joins a second user object is created (#3) + + Component :: obby-general + + Resolution :: fixed + + Type :: defect + + Priority :: major + + Reporter :: jan + +Local variables: +mode: org +end: diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-backend.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-backend.el.svn-base new file mode 100644 index 0000000..79cfef6 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-backend.el.svn-base @@ -0,0 +1,305 @@ +;;; rudel-backend.el --- A generic backend management mechanism for Rudel +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, backend, factory +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file contains a generic mechanism that handles registration, +;; query and instantiation of Rudel backends for any number of +;; functional categories. +;; +;; The class and collaboration design is as follows: for each +;; category, which is identified by a symbol, there is a factory +;; object (an instance of `rudel-backend-factory') that is responsible +;; for creating backend objects of the category. Examples of +;; categories are 'transport', 'protocol' and 'session-initiation'. +;; In addition to creating backend object, factories also allow +;; querying backends based on desired capabilities and load backend +;; implementations only when required. + + +;;; History: +;; +;; 0.1 - Initial revision + + +;;; Code: +;; + +(eval-when-compile + (require 'cl)) + +(require 'eieio) + + +;;; Class rudel-backend +;; + +(defclass rudel-backend () + ((version :initarg :version + :type list + :documentation + "A list of the form (MAJOR MINOR [MICRO +WHATEVER*]) describing the version of the backend.") + (capabilities :initarg :capabilities + :type list + :initform nil + :documentation + "A list of symbols, or lists whose car is a +symbol, that each describe one capability of the backend.")) + "Base class for backend classes." + :abstract t) + +(defmethod rudel-capable-of-p ((this rudel-backend) capability) + "Return t if the backend THIS is capable of CAPABILITY." + (with-slots (capabilities) this + (member capability capabilities))) + + +;;; Class rudel-backend-factory +;; + +(defclass rudel-backend-factory () + ((backends :initarg :backends + :type hash-table + :documentation + "Mapping of symbolic names to classes (prior to +instantiation) or objects (after instantiation) for all backends +known to the factory object.") + (factories :type hash-table + :allocation :class + :documentation + "Mapping of backend categories to responsible +factory objects.")) + "Factory class that holds an object for each known backend +category. Objects manage backend implementation for one backend +category each.") +(oset-default rudel-backend-factory factories + (make-hash-table :test #'eq)) + +(defmethod initialize-instance ((this rudel-backend-factory) &rest slots) + "Initialize slots of THIS with SLOTS." + (when (next-method-p) + (call-next-method)) + (oset this :backends (make-hash-table :test #'eq))) + +;;;###autoload +(defmethod rudel-get-factory :static ((this rudel-backend-factory) + category) + "Return the factory responsible for CATEGORY. +If there is no responsible factory, create one and return it." + (with-slots (factories) this + (or (gethash category factories) + (puthash category (rudel-backend-factory category) factories))) + ) + +;;;###autoload +(defmethod rudel-add-backend ((this rudel-backend-factory) + name class &optional replace) + "Add factory class CLASS with name NAME to THIS. +if REPLACE is non-nil, replace a registered implementation of the +same name." + (with-slots (backends) this + (when (or (not (gethash name backends)) + replace) + (puthash name class backends)))) + +(defmethod rudel-get-backend ((this rudel-backend-factory) name) + "Return backend object for name NAME or nil if there is none. +The returned backend is of the form (NAME . OBJECT). + +Backends are loaded, if necessary." + ;; Load all available backends + (rudel-load-backends this) + + ;; Find the backend and return it. + (with-slots (backends) this + (let ((backend (gethash name backends))) + (when backend + (cons name backend)))) + ) + +(defmethod rudel-all-backends ((this rudel-backend-factory)) + "Return a list of all backends registered with THIS. +Each list element is of the form (NAME . CLASS-OR-OBJECT)." + (let ((backend-list)) + (with-slots (backends) this + (maphash (lambda (name class) + (push (cons name class) backend-list)) + backends)) + backend-list) + ) + +(defmethod rudel-suitable-backends ((this rudel-backend-factory) predicate) + "Return a list of backends which satisfy PREDICATE. +Each list element is of the form (NAME . OBJECT). +Backends are loaded, if necessary." + ;; Load all available backends + (rudel-load-backends this) + + ;; Retrieve and return all backends, possibly filtering the list + ;; using PREDICATE. + (if predicate + (remove-if-not + (lambda (cell) + (and (object-p (cdr cell)) + (funcall predicate (cdr cell)))) + (rudel-all-backends this)) + (rudel-all-backends this)) + ) + +(defmethod rudel-load-backends ((this rudel-backend-factory)) + "Load backends in THIS factory if necessary. +Loading errors are not reported explicitly, but can be detected +by checking for backends that still are classes rather than +objects." + ;; Map lambda that loads unloaded backends over all backends. Store + ;; objects back after loading. + (with-slots (backends) this + (maphash + (lambda (name class) + (unless (object-p class) + (condition-case error + (puthash name (make-instance + class (symbol-name name)) backends) + (error (display-warning + '(rudel backend) + (format "Could not load backend `%s': %s" + name + (error-message-string error)) + :warning))))) + backends)) + ) + + +;;; High-level frontend functions +;; + +(defsubst rudel-backend-cons-p (cell) + "Check whether CELL is a cons of a backend name and object." + (and (consp cell) + (symbolp (car cell)) + (object-p (cdr cell)))) + +;;;###autoload +(defun rudel-backend-get (category name) + "A shortcut for getting backend NAME of category CATEGORY. +The returned backend is of the form (NAME . OBJECT)." + (rudel-get-backend (rudel-backend-get-factory category) name)) + +;;;###autoload +(defun rudel-backend-get-factory (category) + "A shortcut for getting the factory object for CATEGORY." + (rudel-get-factory rudel-backend-factory category)) + +(defun rudel-backend-suitable-backends (category predicate) + "Return backends from category CATEGORY that satisfy PREDICATE. +Each list element is of the form (NAME . OBJECT)." + (rudel-suitable-backends + (rudel-backend-get-factory category) + predicate)) + +(defun rudel-backend-choose (category &optional predicate) + "Choose a backend from CATEGORY satisfying PREDICATE automatically or by asking the user. +The returned backend is of the form (NAME . CLASS-OR-OBJECT)." + (let ((backends (rudel-backend-suitable-backends + category predicate))) + (unless backends + (error "No backends available")) + + (if (= (length backends) 1) + ;; If there is only one backend, we can choose that one right + ;; away displaying a message to avoid confusing the user. + (let ((backend (nth 0 backends))) + (message "Using backend `%s'" (symbol-name (car backend))) + (sit-for 0.5) + backend) + + ;; When we have more than one backend, we have to ask the user, + ;; which one she wants. + (require 'rudel-interactive) + (rudel-read-backend backends nil 'object))) + ) + + +;;; User interaction functions +;; + +(defun rudel-backend-dump (&optional load) + "Create display information about backends in a buffer. +If LOAD is non-nil, load all backends before display. This makes +available information available for the backends" + (interactive "p") + (save-excursion + ;; Setup a new buffer. + (set-buffer (get-buffer-create "*Rudel Backends*")) + (erase-buffer) + (set-window-buffer nil (current-buffer)) + (maphash + (lambda (category factory) + ;; Load backends if requested. + (unless (zerop load) + (rudel-load-backends factory)) + + ;; Insert header for this category. + (insert (propertize + (format "Category %s\n" category) + 'face 'bold)) + (insert (apply #'format + " %-20s %-6s %-7s %s\n" + (mapcar + (lambda (header) + (propertize header 'face 'italic)) + '("name" "loaded" "version" "capabilities")))) + + ;; Insert all backends provided by this factory. + (dolist (backend (rudel-all-backends factory)) + (insert (format " %-20s %-6s %-7s (%s)\n" + (propertize + (symbol-name (car backend)) + 'face 'font-lock-type-face) + (propertize + (prin1-to-string (object-p (cdr backend))) + 'face 'font-lock-variable-name-face) + (propertize + (if (object-p (cdr backend)) + (mapconcat #'prin1-to-string + (oref (cdr backend) :version) + ".") + "?") + 'face 'font-lock-constant-face) + (propertize + (if (object-p (cdr backend)) + (mapconcat #'prin1-to-string + (oref (cdr backend) :capabilities) + " ") + "?") + 'face 'font-lock-constant-face)))) + + ;; One empty line between backend categories. + (insert "\n")) + (oref rudel-backend-factory factories))) + ) + +(provide 'rudel-backend) +;;; rudel-backend.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-chat.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-chat.el.svn-base new file mode 100644 index 0000000..c7e992f --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-chat.el.svn-base @@ -0,0 +1,103 @@ +;;; rudel-chat.el --- Handling of chat messages +;; +;; Copyright (C) 2008, 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, chat, message +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file contains some functions that deal with incoming chat +;; messages. Backends that support receiving chat message should +;; dispatch them using `rudel-chat-dispatch-message'. Chat messages +;; will be processed in a customizable way from there. + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + + +;;; Customization +;; + +(defcustom rudel-chat-handler-function #'rudel-chat-handle-buffer + "A function that is called when chat messages arrive." + :group 'rudel + :type '(choice (const :tag "Display messages in the echo area" + rudel-chat-handle-message) + (const :tag "Log messages into a buffer" + rudel-chat-handle-buffer) + (function :tag "Other function")) + ) + + +;;; Variables and constants +;; + +(defconst rudel-chat-buffer-name "*rudel-chat-log*" + "Name of the buffer into which received chat message should be +inserted.") + + +;;; Interface functions +;; + +(defun rudel-chat-dispatch-message (sender message) + "Dispatch SENDER and MESSAGE to customizable handler function." + (funcall rudel-chat-handler-function sender message)) + + +;;; Handler functions +;; + +(defun rudel-chat-handle-message (sender text) + "Display SENDER and MESSAGE in the echo area." + (message "%s says: %s" + (rudel-chat-format-sender sender) + text)) + +(defun rudel-chat-handle-buffer (sender text) + "Insert SENDER and MESSAGE in a buffer." + (let ((buffer (or (get-buffer rudel-chat-buffer-name) + (pop-to-buffer rudel-chat-buffer-name)))) + (with-current-buffer buffer + (goto-char (point-min)) + (insert (format "%s: %s\n" + (rudel-chat-format-sender sender) + text)))) + ) + + +;;; Miscellaneous functions +;; + +(defun rudel-chat-format-sender (user) + "Format USER handling nil values." + (if user + (object-name-string user) + "<unknown sender>")) + +(provide 'rudel-chat) +;;; rudel-chat.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-compat.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-compat.el.svn-base new file mode 100644 index 0000000..630496c --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-compat.el.svn-base @@ -0,0 +1,158 @@ +;;; rudel-compat.el --- Compatibility code for Rudel +;; +;; Copyright (C) 2009 Jan Moringen +;; Copyright (C) 2009 Phil Hagelberg +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Phil Hagelberg <phil@enigma> +;; Keywords: rudel, compatibility +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file contains compatibility code required to make Rudel work +;; with different versions of Emacs. + + +;;; History: +;; +;; 0.1 - Initial revision + + +;;; Code: +;; + +(unless (fboundp 'read-color) + (defun read-color (prompt &rest ignored) + "Poor man's read color without completion. +You have to take care to only enter valid color names." + (read-string prompt))) + + +;;; Spinner Progress Reporter +;; + +(unless (functionp 'progress-reporter-spin) + (defvar progress-spinner-values ["-" "\\" "|" "/"]) + + (defsubst progress-reporter-update (reporter &optional value) + "Report progress of an operation in the echo area. + +The first parameter, REPORTER, should be the result of a call to +`make-progress-reporter'. For reporters for which the max value +is known, the second argument determines the actual progress of +operation; it must be between MIN-VALUE and MAX-VALUE as passed +to `make-progress-reporter'. + +However, if the change since last echo area update is too small +or not enough time has passed, then do nothing (see +`make-progress-reporter' for details). + +In this case, this function is very inexpensive, you need not +care how often you call it." + (if (progress-reporter-spinner-p reporter) + (progress-reporter-spin reporter) + (when (>= value (car reporter)) + (progress-reporter-do-update reporter value)))) + + (defun make-progress-reporter (message &optional min-value max-value + current-value min-change min-time) + "Return progress reporter object to be used with `progress-reporter-update'. + +MESSAGE is shown in the echo area. When at least 1% of operation +is complete, the exact percentage will be appended to the +MESSAGE. When you call `progress-reporter-done', word \"done\" +is printed after the MESSAGE. You can change MESSAGE of an +existing progress reporter with `progress-reporter-force-update'. + +If provided, MIN-VALUE and MAX-VALUE designate starting (0% +complete) and final (100% complete) states of operation. The +latter should be larger; if this is not the case, then simply +negate all values. Optional CURRENT-VALUE specifies the progress +by the moment you call this function. You should omit it or set +it to nil in most cases since it defaults to MIN-VALUE. + +Optional MIN-CHANGE determines the minimal change in percents to +report (default is 1%.) Optional MIN-TIME specifies the minimal +time before echo area updates (default is 0.2 seconds.) If +`float-time' function is not present, then time is not tracked +at all. If OS is not capable of measuring fractions of seconds, +then this parameter is effectively rounded up. + +If MIN-VALUE and MAX-VALUE are unknown, they may be omitted to +return a \"pulsing\" progress reporter." + (unless min-time + (setq min-time 0.2)) + (let ((reporter + (cons min-value ;; Force a call to `message' now + (vector (if (and (fboundp 'float-time) + (>= min-time 0.02)) + (float-time) nil) + (or min-value 0) + max-value + message + (if min-change (max (min min-change 50) 1) 1) + min-time)))) + (progress-reporter-update reporter (or current-value min-value)) + reporter)) + + (defun progress-reporter-force-update (reporter &optional value new-message) + "Report progress of an operation in the echo area unconditionally. + +First two parameters are the same as for +`progress-reporter-update'. Optional NEW-MESSAGE allows you to +change the displayed message." + (let ((parameters (cdr reporter))) + (when new-message + (aset parameters 3 new-message)) + (when (aref parameters 0) + (aset parameters 0 (float-time))) + (if (progress-reporter-spinner-p reporter) + (progress-reporter-spin reporter) + (progress-reporter-do-update reporter value)))) + + (defun progress-reporter-spinner-p (reporter) + "Return t if REPORTER has an unknown max value." + (null (aref (cdr reporter) 2))) + + (defun progress-reporter-spin (reporter) + "Advance indicator of spinning REPORTER." + (let* ((parameters (cdr reporter)) + (index (+ (aref parameters 1) 1))) + (aset parameters 1 index) + (let ((message-log-max nil)) ; No logging + (message "%s %s" + (aref progress-spinner-values (mod index 4)) + (aref parameters 3)))))) + +(unless (functionp 'string-match-p) + (defsubst string-match-p (regexp string &optional start) + "Same as `string-match' except this function does not change the match data" + (let ((inhibit-changing-match-data t)) + (string-match regexp string start)))) + +(defun rudel-get-coding-system (name) + (if (functionp 'coding-system-from-name) + (coding-system-from-name name) + ;; May need to try a little harder here for Emacs 22 depending on + ;; what kind of encoding names are given us. + (intern name))) + +(provide 'rudel-compat) +;;; rudel-compat.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-compile.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-compile.el.svn-base new file mode 100644 index 0000000..aeba765 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-compile.el.svn-base @@ -0,0 +1,46 @@ +;;; rudel-compile.el --- Byte-compile Rudel +;; +;; Copyright (C) 2009 Phil Hagelberg +;; +;; Author: Phil Hagelberg <phil@enigma> +;; Keywords: Rudel, compile +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; Press M-x eval-buffer to byte-compile Rudel. + + +;;; History: +;; +;; 0.1 - Initial revision + + +;;; Code: +;; + +(let ((rudel-dir (file-name-directory + (or (buffer-file-name) load-file-name)))) + ;; Adjust load path for compilation. + (dolist (dir '("." "jupiter" "obby" "zeroconf")) + (let ((d (concat rudel-dir "/" dir))) + (add-to-list 'load-path d))) + + ;; Byte compile everything. + (byte-recompile-directory rudel-dir 0)) diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-debug.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-debug.el.svn-base new file mode 100644 index 0000000..747bf68 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-debug.el.svn-base @@ -0,0 +1,215 @@ +;;; rudel-debug.el --- Debugging functions for Rudel +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, debugging +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; Debugging functions for Rudel. + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(require 'data-debug) +(require 'eieio-datadebug) + +(require 'rudel-util) + + +;;; Customization +;; + +(defgroup rudel-debug nil + "Customization options related to Rudel's debugging functions." + :group 'rudel) + +(defface rudel-debug-sent-data-face + '((default (:background "orange"))) + "Face used for sent data." + :group 'rudel-debug) + +(defface rudel-debug-received-data-face + '((default (:background "light sky blue"))) + "Face used for received (but not yet processed) data." + :group 'rudel-debug) + +(defface rudel-debug-received-processed-data-face + '((default (:background "DeepSkyBlue1"))) + "Face used for received data after processing." + :group 'rudel-debug) + +(defface rudel-debug-state-face + '((default (:background "light gray"))) + "Face used when indicating state changes." + :group 'rudel-debug) + +(defface rudel-debug-special-face + '((default (:background "light sea green"))) + "Face used for additional information." + :group 'rudel-debug) + +(defvar rudel-debug-tag-faces + '((:sent . (rudel-debug-sent-data-face "< ")) + (:received . (rudel-debug-received-data-face "> ")) + (:received-processed . (rudel-debug-received-processed-data-face ">> ")) + (:state . (rudel-debug-state-face "| ")) + (:special . (rudel-debug-special-face "; "))) + "Associate tag to faces and prefixes.") + + +;;; Data debug functions +;; + +(defun rudel-adebug-session () + "Analyze current session in data debug buffer." + (interactive) + + ;; Make sure we have a session. + (unless rudel-current-session + (error "No active Rudel session")) + + (with-current-buffer (data-debug-new-buffer "RUDEL-SESSION") + (data-debug-insert-thing rudel-current-session "# " ""))) + +(defun rudel-adebug-server (server) + "Analyze server in data debug buffer." + (interactive) + + (with-current-buffer (data-debug-new-buffer "RUDEL-SERVER") + (data-debug-insert-thing server "# " ""))) + + +;;; Advice stuff +;; + +(defadvice rudel-join-session (after rudel-debug last activate) + "Run data-debug inspection on newly created session objects." + (require 'rudel-debug) + (rudel-adebug-session)) + +(defadvice rudel-host-session (after rudel-debug last activate) + "Run data-debug inspection on newly created server objects." + (require 'rudel-debug) + (rudel-adebug-server ad-return-value)) + + +;;; Network functions +;; + +(defun rudel-suspend-session-socket () + "Suspend the socket associated to the current session." + (interactive) + + ;; Make sure we have a session. + (unless rudel-current-session + (error "No active Rudel session")) + + (with-slots (connection) rudel-current-session + (with-slots (socket) connection + (stop-process socket)))) + +(defun rudel-resume-session-socket () + "Resume the socket associated to the current session." + (interactive) + + ;; Make sure we have a session. + (unless rudel-current-session + (error "No active Rudel session")) + + (with-slots (connection) rudel-current-session + (with-slots (socket) connection + (continue-process socket)))) + + +;;; Reset functions +;; + +(defun rudel-kill-processes () + "TODO" + (interactive) + (mapc #'delete-process (process-list))) + +(defun rudel-reset () + "TODO" + (interactive) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when rudel-buffer-document + (setq rudel-buffer-document nil)))) + (rudel-kill-processes) + (setq rudel-current-session nil)) + + +;;; Socket debugging +;; + +(defmethod rudel-state-change :before ((this rudel-socket-owner) + state message) + "Print STATE and MESSAGE to debug stream." + (with-slots (socket) this + (rudel-debug-stream-insert + (rudel-debug-stream-name socket) + :state + (format "connection state changed to %s: \"%s\"" + (upcase (symbol-name state)) + ;; MESSAGE ends with a newline; remove it + (substring message 0 -1)))) + ) + + +;;; Utility functions +;; + +(defun rudel-debug-stream-name (socket) + "Return debug stream name for SOCKET." + (process-name socket)) + +(defun rudel-debug-stream-insert (stream tag data &optional object) + "Insert DATA and possibly OBJECT into stream using TAG as style." + (let* ((buffer-name (format "*%s stream*" stream)) + (buffer (or (get-buffer buffer-name) + (data-debug-new-buffer buffer-name))) + (appearance (cdr (assoc tag rudel-debug-tag-faces))) + (face (when appearance + (or (nth 0 appearance) + 'default))) + (prefix (or (nth 1 appearance) + ""))) + (save-excursion + (set-buffer buffer) + (goto-char 0) + (insert prefix + (propertize data 'face face) + (if (string= (substring data -1) "\n") + "" "\n")) + (when object + (data-debug-insert-thing object prefix "")))) + ) + +(provide 'rudel-debug) +;;; rudel-debug.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-errors.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-errors.el.svn-base new file mode 100644 index 0000000..9811511 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-errors.el.svn-base @@ -0,0 +1,66 @@ +;;; rudel-errors.el --- Error data used in Rudel +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, errors, conditions +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; The following condition hierarchy is defined: +;; +;; error +;; +- rudel-error +;; +- rudel-join-error +;; +- rudel-host-error + + +;;; History: +;; +;; 0.1 - Initial revision + + +;;; Code: +;; + +;; rudel-join-error + +(intern "rudel-join-error") + +(put 'rudel-join-error 'error-conditions + '(error + rudel-error rudel-join-error)) + +(put 'rudel-join-error 'error-message + "Could not join session") + +;; rudel-host-error + +(intern "rudel-host-error") + +(put 'rudel-host-error 'error-conditions + '(error + rudel-error rudel-host-error)) + +(put 'rudel-host-error 'error-message + "Could not host session") + +(provide 'rudel-errors) +;;; rudel-errors.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-hooks.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-hooks.el.svn-base new file mode 100644 index 0000000..0cc9a3e --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-hooks.el.svn-base @@ -0,0 +1,252 @@ +;;; rudel-hooks.el --- Hooks for Rudel events +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, hook +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file contains all global hooks (as opposed to hooks provided +;; by individual objects) provided by Rudel. + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(require 'eieio) + + +;;; Hook variables +;; + +(defvar rudel-session-start-hook nil + "This hook is run when a new session is started. +The only argument is the session object.") + +(defvar rudel-session-end-hook nil + "This hook is run when a session ends. +The only argument is the session object.") + +(defvar rudel-session-add-user-hook nil + "This hook is run when a user is added to a session. +The arguments are the session and the user.") + +(defvar rudel-session-remove-user-hook nil + "This hook is run when a user is removed from a session. +The arguments are the session and the user.") + +(defvar rudel-session-add-document-hook nil + "This hook is run when a document is added to a session. +The arguments are the session and the document.") + +(defvar rudel-session-remove-document-hook nil + "This hook is run when a document is removed from a session. +The arguments are the session and the document.") + + +(defvar rudel-user-change-hook nil + "This hooks is run when a user object changes. +The only argument is the user object.") + + +(defvar rudel-document-attach-hook nil + "This hook is run when a document is attached to a buffer. +The arguments are the document and the buffer.") + +(defvar rudel-document-detach-hook nil + "This hook is run when document is detached from its buffer. +The arguments are the document and the buffer.") + + +;;; Handlers +;; + +(defun rudel-hooks--session-start (session) + "Watch SESSION for added/removed users and documents." + ;; Install handlers for the hooks of the session. + (with-slots (users documents) session + + ;; Watch for session end. + (object-add-hook session 'end-hook + #'rudel-hooks--session-end) + + ;; Watch all users in the session. + (dolist (user users) + (rudel-hooks--session-add-user session user)) + + ;; Watch session for added/removed users. + (object-add-hook + session 'add-user-hook + #'rudel-hooks--session-add-user) + (object-add-hook + session 'remove-user-hook + #'rudel-hooks--session-remove-user) + + ;; Watch all documents in the session. + (dolist (document documents) + (rudel-hooks--session-add-document session document)) + + ;; Watch session for added/removed documents. + (object-add-hook + session 'add-document-hook + #'rudel-hooks--session-add-document) + (object-add-hook + session 'remove-document-hook + #'rudel-hooks--session-remove-document)) + ) + +(defun rudel-hooks--session-end (session) + "Stop watching SESSION for added/removed users and documents." + ;; Remove handlers from the session. + (with-slots (users documents) session + + ;; Stop watching for session end. + (object-remove-hook session 'end-hook + #'rudel-hooks--session-end) + + ;; Stop watching all users in the session. + (dolist (user users) + (rudel-hooks--session-remove-user session user)) + + ;; Stop watching session for added/removed users. + (object-remove-hook + session 'add-user-hook + #'rudel-hooks--session-add-user) + (object-remove-hook + session 'remove-user-hook + #'rudel-hooks--session-remove-user) + + ;; Stop watching all documents in the session. + (dolist (document documents) + (rudel-hooks--session-remove-document session document)) + + ;; Stop watching session for added/removed documents. + (object-remove-hook + session 'add-document-hook + #'rudel-hooks--session-add-document) + (object-remove-hook + session 'remove-document-hook + #'rudel-hooks--session-remove-document)) + + ;; Run the hook. + (run-hook-with-args 'rudel-session-end-hook session) + ) + +(defun rudel-hooks--session-add-user (session user) + "Watch USER for changes and run `rudel-session-add-user-hook'." + ;; Watch USER. + (object-add-hook user 'change-hook #'rudel-hooks--user-change) + + ;; Run the hook. + (run-hook-with-args 'rudel-session-add-user-hook session user)) + +(defun rudel-hooks--session-remove-user (session user) + "Stop watching USER and run `rudel-session-remove-user-hook'" + ;; Stop watching USER. + (object-remove-hook user 'change-hook #'rudel-hooks--user-change) + + ;; Run the hook. + (run-hook-with-args 'rudel-session-remove-user-hook + session user)) + +(defun rudel-hooks--session-add-document (session document) + "Watch DOCUMENT and run `rudel-session-add-document-hook'." + ;; Watch document for attach/detach. + (object-add-hook document 'attach-hook + #'rudel-hooks--document-attach) + (object-add-hook document 'detach-hook + #'rudel-hooks--document-detach) + + ;; Run the hook. + (run-hook-with-args 'rudel-session-add-document-hook + session document) + ) + +(defun rudel-hooks--session-remove-document (session document) + "Stop watching DOCUMENT and run `rudel-session-remove-document-hook'." + ;; Stop watching DOCUMENT for attach/detach. + (object-remove-hook + document 'attach-hook #'rudel-hooks--document-attach) + (object-remove-hook + document 'detach-hook #'rudel-hooks--document-detach) + + ;; Run the hook. + (run-hook-with-args 'rudel-session-remove-document-hook + session document) + ) + + +(defun rudel-hooks--user-change (user) + "Run `rudel-user-change-hook' with argument USER." + (run-hook-with-args 'rudel-user-change-hook user)) + + +(defun rudel-hooks--document-attach (document buffer) + "Run `rudel-document-attach-hook' with arguments DOCUMENT and BUFFER." + (run-hook-with-args 'rudel-document-attach-hook + document buffer)) + +(defun rudel-hooks--document-detach (document buffer) + "Run `rudel-document-detach-hook' with arguments DOCUMENT and BUFFER." + (run-hook-with-args 'rudel-document-detach-hook + document buffer)) + + +;;; Initialization +;; + +(defun rudel-hooks--install-handlers () + "Install handlers for session start/end." + ;; Install handlers for already started sessions. + (when (boundp 'rudel-current-session) + (mapc + #'rudel-hooks--session-start + (when rudel-current-session + (list rudel-current-session)))) + + ;; Watch for session start/end. + (add-hook 'rudel-session-start-hook + #'rudel-hooks--session-start) + ) + +(defun rudel-hooks--uninstall-handlers () + "Uninstall handlers for session start/end." + ;; Stop watching session start/end. + (remove-hook 'rudel-session-start-hook + #'rudel-hooks--session-start) + + ;; Uninstall handlers for already started sessions. + (when (boundp 'rudel-current-session) + (mapc + #'rudel-hooks--session-end + (when rudel-current-session + (list rudel-current-session)))) + ) + +(rudel-hooks--install-handlers) + +(provide 'rudel-hooks) +;;; rudel-hooks.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-icons.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-icons.el.svn-base new file mode 100644 index 0000000..9bb35b5 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-icons.el.svn-base @@ -0,0 +1,90 @@ +;;; rudel-icons.el --- Icons used by Rudel +;; +;; Copyright (C) 2008, 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: rudel, icons +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file loads all icons used in Rudel. + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(require 'image) + + +;;; Image constants +;; + +(defconst rudel-icons-image-formats '(svg png) + "Image formats to try (in that order) when loading Rudel icons.") + +(defconst rudel-icons-directory + (file-name-as-directory + (concat (file-name-directory + (locate-library "rudel-icons.el")) + "icons")) + "Directory that holds Rudel icon files.") + + +;;; Helper macro +;; + +(defmacro rudel-defimage (name &optional docstring) + "Load image from Rudel icon directory and define image named NAME. +Optional argument DOCSTRING is the documentation string to +associate with the image." + (declare (doc-string 2)) + (let ((icon (intern (format "rudel-icon-%s" name))) + (specs (mapcar + (lambda (type) + `(:type ,type + :ascent center + :mask heuristic + :file ,(concat rudel-icons-directory + name "." (symbol-name type)))) + rudel-icons-image-formats))) + `(defimage ,icon + (,@specs) + ,(or docstring + (format "%s icon." (capitalize name))))) + ) + + +;;; Image definitions +;; + +(rudel-defimage "person") +(rudel-defimage "document") +(rudel-defimage "connected") +(rudel-defimage "disconnected") +(rudel-defimage "plaintext") +(rudel-defimage "encrypted") + +(provide 'rudel-icons) +;;; rudel-icons.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-interactive.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-interactive.el.svn-base new file mode 100644 index 0000000..5dda752 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-interactive.el.svn-base @@ -0,0 +1,181 @@ +;;; rudel-interactive.el --- User interaction functions for Rudel. +;; +;; Copyright (C) 2008, 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, user, interface, interaction +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; Functions for user interactions commonly used in Rudel components. + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(require 'rudel-compat) ;; for `read-color' replacement + + +;;; Function for reading Rudel objects from the user. +;; + +(defun rudel-read-backend (backends &optional prompt return) + "Read a backend name from BACKENDS and return that name or the actual backend depending on RETURN. +If RETURN is 'object, return the backend object which is of the +form (NAME . CLASS-OR-OBJECT); Otherwise return the name as +string." + (unless prompt + (setq prompt "Backend: ")) + (let* ((backend-names (mapcar (lambda (cell) + (symbol-name (car cell))) + backends)) + (backend-name (completing-read prompt backend-names nil t))) + (cond + ((eq return 'object) + (assoc (intern backend-name) backends)) + (t backend-name))) + ) + +(defun rudel-read-session (sessions &optional prompt return) + "Read a session name from SESSIONS and return that name or the session info depending on RETURN. +If PROMPT is non-nil use as prompt string. +If RETURN is 'object, return the session object; Otherwise return +the name as string." + (unless prompt + (setq prompt "Session: ")) + ;; For presentation and identification of sessions, use the :name + ;; property. + (flet ((to-string (session) + (if (rudel-backend-cons-p session) + (symbol-name (car session)) + (plist-get session :name)))) + ;; Read a session by name, then return that name or the + ;; corresponding session info. + (let ((session-name (completing-read prompt + (mapcar #'to-string sessions) + nil t))) + (cond + ((eq return 'object) + (find session-name sessions + :key #'to-string :test #'string=)) + (t session-name)))) + ) + +(defun rudel-read-user-name () + "Read a username. +The default is taken from `rudel-default-username'." + (read-string "Username: " rudel-default-username)) + +(defun rudel-read-user-color () + "Read a color." + (read-color "Color: " t)) + +(defun rudel-read-user (&optional users prompt return) + "Read a user name from USERS and return that name or the actual user depending on RETURN. +If USERS is nil, use the user list of `rudel-current-session'. +If RETURN. is 'object, return the user object; Otherwise return +the name as string." + ;; If no user list is provided, the user list of the current session + ;; is used. + (unless users + (if rudel-current-session + (setq users (oref rudel-current-session :users)) + (error "No user list and no active Rudel session"))) + (unless prompt + (setq prompt "User: ")) + ;; Construct a list of user name, read a name with completion and + ;; return a user name of object. + (let* ((user-names (mapcar 'object-name-string users)) + (user-name (completing-read prompt user-names nil t))) + (cond + ((eq return 'object) + (find user-name users + :test 'string= :key 'object-name-string)) + (t user-name))) + ) + +(defun rudel-read-document (&optional documents prompt return) + "Read a document name from DOCUMENTS and return that name or the actual document depending on RETURN. +If RETURN. is 'object, return the backend object; Otherwise +return the name as string." + (unless documents + (if rudel-current-session + (setq documents (oref rudel-current-session :documents)) + (error "No document list and no active Rudel session"))) + (unless documents + (error "No documents")) ; TODO error is a bit harsh + (unless prompt + (setq prompt "Document: ")) + + ;; Construct list of names, read one name and return that name or + ;; the named object. + (let* ((document-names (mapcar #'rudel-unique-name documents)) + (document-name (completing-read prompt document-names nil t))) + (cond + ((eq return 'object) + (find document-name documents + :test #'string= :key #'rudel-unique-name)) + (t document-name))) + ) + + +;;; Buffer allocation functions +;; + +(defun rudel-allocate-buffer-clear-existing (name) + "When the requested buffer NAME exists, clear its contents and use it." + (let ((buffer (get-buffer name))) + (if buffer + (progn + ;; Ask the user whether it is OK to erase the contents of + ;; the buffer. + (unless (yes-or-no-p (format + "Buffer `%s' already exists; Erase contents? " + name)) + (error "Buffer `%s' already exists" name)) ;; TODO throw or signal; not error + ;; When the buffer is attached to a different document, ask + ;; whether it is OK to detach the buffer. + (let ((document (rudel-buffer-document buffer))) + (unless (or (not document) + (yes-or-no-p (format + "Buffer `%s' is attached to the document `%s'; Detach? " + name + (rudel-unique-name document)))) + (error "Buffer `%s' already attached to a document" name))) + ;; Delete buffer contents; maybe detach buffer first. + (when (rudel-buffer-has-document-p buffer) + (rudel-unpublish-buffer buffer)) + (with-current-buffer buffer + (erase-buffer))) + (setq buffer (get-buffer-create name))) + buffer) + ) + +(defun rudel-allocate-buffer-make-unique (name) + "When the requested buffer NAME exists, create another buffer." + (get-buffer-create (generate-new-buffer-name name))) + +(provide 'rudel-interactive) +;;; rudel-interactive.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-loaddefs.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-loaddefs.el.svn-base new file mode 100644 index 0000000..9de8708 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-loaddefs.el.svn-base @@ -0,0 +1,23 @@ +;;; rudel-loaddefs.el + +(autoload 'rudel-join-session "rudel" "Start a collaborative Rudel session" t) +(autoload 'rudel-host-session "rudel" "Host a collaborative Rudel session" t) +(autoload 'rudel-speedbar "rudel-speedbar" + "Show connected users and documents for the Rudel session in speedbar" t) +(autoload 'global-rudel-minor-mode "rudel-mode" + "Bindings for rudel session-level commands" t) + +(global-set-key (kbd "C-c c j") 'rudel-join-session) + +(setq rudel-dir (file-name-directory (or (buffer-file-name) load-file-name))) + +(dolist (dir '("." "jupiter" "obby" "zeroconf")) + (add-to-list 'load-path (concat rudel-dir "/" dir))) + +(eval-after-load 'rudel + '(progn (global-rudel-minor-mode) + (require 'rudel-obby) + (when (require 'zeroconf nil t) + (require 'rudel-zeroconf)))) + +(provide 'rudel-loaddefs)
\ No newline at end of file diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-mode.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-mode.el.svn-base new file mode 100644 index 0000000..182188a --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-mode.el.svn-base @@ -0,0 +1,621 @@ +;;; rudel-mode.el --- Global and buffer-local Rudel minor modes +;; +;; Copyright (C) 2008, 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: rudel, mode +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file contains the following global and buffer-local Rudel +;; minor modes: +;; +;; + `rudel-header-subscriptions-minor-mode': Display subscribed users +;; and their respective status in the header line +;; + `rudel-mode-line-publish-state-minor-mode': Display publication +;; state of buffers in their mode lines +;; + `global-rudel-minor-mode': Installs a keymap and a Rudel menu + + +;;; History: +;; +;; 0.4 - Display buffer publication state in mode line. +;; +;; 0.3 - Display subscriptions in header line. +;; +;; 0.2 - Use define-minor-mode. +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(require 'easy-mmode) +(require 'easymenu) + +(require 'rudel) +(require 'rudel-hooks) + + +;;; Customization Options +;; + +(defcustom rudel-header-subscriptions-use-images t + "Use images when displaying subscribed users in header-line." + :group 'rudel + :type 'boolean + :set (lambda (symbol value) + (set-default symbol value) + (when (featurep 'rudel-mode) + (rudel-header-subscriptions--options-changed)))) + +(defcustom rudel-header-subscriptions-separator " " + "String used to separate indicator strings of subscribed users." + :group 'rudel + :type 'string + :set (lambda (symbol value) + (set-default symbol value) + (when (featurep 'rudel-mode) + (rudel-header-subscriptions--options-changed)))) + +(defcustom rudel-mode-line-publish-state-unpublished-string "-" + "String used to indicate not published state in the mode line." + :group 'rudel + :type 'string + :set (lambda (symbol value) + (set-default symbol value) + (when (featurep 'rudel-mode) + (rudel-mode-line-publish-state--options-changed)))) + +(defcustom rudel-mode-line-publish-state-published-string "P" + "String used to indicate published state in the mode line." + :group 'rudel + :type 'string + :set (lambda (symbol value) + (set-default symbol value) + (when (featurep 'rudel-mode) + (rudel-mode-line-publish-state--options-changed)))) + +(dolist (v '(rudel-header-subscriptions-use-images + rudel-header-subscriptions-separator + rudel-mode-line-publish-state-unpublished-string + rudel-mode-line-publish-state-published-string)) + (put v 'save-local-variable t)) + + +;;; Header line subscriptions helper functions +;; + +(defun rudel-header-subscriptions--make-format (document) + "Return a Lisp object usable as `header-line-format' generated from DOCUMENT." + (with-slots (subscribed) document + (mapconcat + (lambda (user) + (rudel-display-string + user rudel-header-subscriptions-use-images)) + subscribed rudel-header-subscriptions-separator))) + +(defun rudel-header-subscriptions--update-from-document (document) + "Update header-line of the buffer attached to DOCUMENT." + (with-slots (buffer) document + (when buffer + (with-current-buffer buffer + (setq header-line-format + (rudel-header-subscriptions--make-format document)) + (force-mode-line-update))))) + +(defun rudel-header-subscriptions--update-from-buffer () + "Update header-line of the current buffer from associated document." + (setq header-line-format + (when (rudel-buffer-document) + (rudel-header-subscriptions--make-format + (rudel-buffer-document)))) + (force-mode-line-update)) + +(defun rudel-header-subscriptions--options-changed () + "Update headers in buffers that have header subscriptions mode enabled." + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when rudel-header-subscriptions-minor-mode + (rudel-header-subscriptions--update-from-buffer))))) + + +;;; Header line indication of users' status and activities +;; + +(defun rudel-header-subscriptions--user-change (document user) + "Update header line after USER changed." + ;; Update the header line to reflect the changes to USER. + (rudel-header-subscriptions--update-from-document document)) + +(defun rudel-header-subscriptions--add-user (document user) + "Start monitoring USER and update header line." + ;; Monitor USER. + (lexical-let ((document document)) + (object-add-hook user 'change-hook + (lambda (user) + (rudel-header-subscriptions--user-change + document user)))) + + ;; Update the header line once to get the user added. + (rudel-header-subscriptions--update-from-document document) + ) + +(defun rudel-header-subscriptions--remove-user (document user) + "Stop monitoring USER and update header line." + ;; TODO Stop monitoring USER. + ;; (object-remove-hook user 'change-hook + + ;; Update the header line once to get the user removed. + (rudel-header-subscriptions--update-from-document document) + ) + +;;;###autoload +(define-minor-mode rudel-header-subscriptions-minor-mode + "Toggle Rudel header subscriptions minor mode. + +This mode displays users subscribed to the document associated +with the buffer in the header-line. Depending on the kind of +session, additional information like connection status, +encryption or activity indication may be displayed with each +user. + +If ARG is null, toggle Rudel header subscriptions mode. +If ARG is a number greater than zero, turn on Rudel header +subscriptions mode; otherwise, turn it off." + :init-value nil + :group 'rudel + (cond + ;; Emacs session is not interactive + (noninteractive + (setq rudel-header-subscriptions-minor-mode nil)) + + ;; Mode is being enabled and the buffer has an attached document. + ((and rudel-header-subscriptions-minor-mode + (rudel-buffer-document)) + (let ((document (rudel-buffer-document))) + + ;; Monitor all users that already are subscribed to the + ;; document. + (with-slots (subscribed) document + (dolist (user subscribed) + (rudel-header-subscriptions--add-user document user))) + + ;; Monitor future (un)subscribe events. + (object-add-hook document 'subscribe-hook + #'rudel-header-subscriptions--add-user) + (object-add-hook document 'unsubscribe-hook + #'rudel-header-subscriptions--remove-user)) + + ;; Update header line. + (rudel-header-subscriptions--update-from-buffer)) + + ;; Mode is being disabled, but the buffer has an attached document. + ((and (not rudel-header-subscriptions-minor-mode) + (rudel-buffer-document)) + (let ((document (rudel-buffer-document))) + + ;; Stop monitoring all users that are subscribed to the + ;; document. + (with-slots (subscribed) document + (dolist (user subscribed) + (rudel-header-subscriptions--remove-user document user))) + + ;; Stop monitoring (un)subscribe events. + (object-remove-hook document 'subscribe-hook + #'rudel-header-subscriptions--add-user) + (object-remove-hook document 'unsubscribe-hook + #'rudel-header-subscriptions--remove-user)) + + ;; Reset header line to default format. + (setq header-line-format default-header-line-format) + (force-mode-line-update)) ;; TODO remove all handlers + + ;; No buffer document + (t + ;; Ensure the mode is disabled. + (setq rudel-header-subscriptions-minor-mode nil) + + ;; Reset header line to default format. + (setq header-line-format default-header-line-format) + (force-mode-line-update))) + ) + + +;;; Global header subscriptions mode +;; + +;; Tracking stuff for the global mode + +(defun rudel-header-subscriptions--attach (document buffer) + "Activate header subscriptions mode for BUFFER." + (with-current-buffer buffer + (rudel-header-subscriptions-minor-mode 1))) + +(defun rudel-header-subscriptions--detach (document buffer) + "Deactivate header subscriptions mode for BUFFER." + (with-current-buffer buffer + (rudel-header-subscriptions-minor-mode 0))) + +(defun rudel-header-subscriptions--add-document (session document) + "Watch DOCUMENT for attach/detach events." + ;; When document is attached to a buffer, turn the mode on. + (with-slots (buffer) document + (when buffer + (rudel-header-subscriptions--attach document buffer))) + + ;; Watch document for attaching and detaching. + (object-add-hook + document 'attach-hook #'rudel-header-subscriptions--attach) + (object-add-hook + document 'detach-hook #'rudel-header-subscriptions--detach)) + +(defun rudel-header-subscriptions--remove-document (session document) + "Stop watching DOCUMENT for attach/detach events." + ;; When document is attached to a buffer, turn the mode off. + (with-slots (buffer) document + (when buffer + (rudel-header-subscriptions--detach document buffer))) + + ;; Stop watching document for attaching and detaching. + (object-remove-hook + document 'attach-hook #'rudel-header-subscriptions--attach) + (object-remove-hook + document 'detach-hook #'rudel-header-subscriptions--detach)) + +(defun rudel-header-subscriptions--session-start (session) + "Watch SESSION documents and watch for added/removed documents." + ;; Watch all documents in the session. + (with-slots (documents) session + (dolist (document documents) + (rudel-header-subscriptions--add-document session document))) + + ;; Watch session for added/removed documents. + (object-add-hook + session 'add-document-hook + #'rudel-header-subscriptions--add-document) + (object-add-hook + session 'remove-document-hook + #'rudel-header-subscriptions--remove-document) + ) + +(defun rudel-header-subscriptions--session-end (session) + "Stop watching SESSION for added/removed documents." + ;; Stop watching all documents in the session. + (with-slots (documents) session + (dolist (document documents) + (rudel-header-subscriptions--remove-document session document))) + + ;; Stop watching session for added/removed documents. + (object-remove-hook + session 'add-document-hook + #'rudel-header-subscriptions--add-document) + (object-remove-hook + session 'remove-document-hook + #'rudel-header-subscriptions--remove-document) + ) + +;;;###autoload +(define-globalized-minor-mode global-rudel-header-subscriptions-mode + rudel-header-subscriptions-minor-mode + rudel-header-subscriptions-minor-mode + :group 'rudel) + +(defadvice global-rudel-header-subscriptions-mode + (around track-subscriptions activate) + "Start/stop tracking subscriptions when the mode is (de)activated." + (let ((value ad-do-it)) + (if value + + ;; Add handlers to session start and end hooks and run the + ;; start handler on already started sessions. + (progn + + ;; Go through all existing sessions. + (mapc #'rudel-header-subscriptions--session-start + (when rudel-current-session + (list rudel-current-session))) + + ;; Watch for new/ended sessions. + (add-hook 'rudel-session-start-hook + #'rudel-header-subscriptions--session-start) + (add-hook 'rudel-session-end-hook + #'rudel-header-subscriptions--session-end)) + + ;; Remove handlers from session start and end hooks and run the + ;; end handler on active sessions. + (mapc #'rudel-header-subscriptions--session-end + (when rudel-current-session + (list rudel-current-session))) + + (remove-hook 'rudel-session-start-hook + #'rudel-header-subscriptions--session-start) + (remove-hook 'rudel-session-end-hook + #'rudel-header-subscriptions--session-end))) + ) + + +;;; Mode line indication of buffer state +;; + +(defvar rudel-mode-line-publish-state-string + (propertize + "-" + 'mouse-face 'mode-line-highlight + 'help-echo "Buffer is not published") + "Contains a mode line fragment indicating the publication state +of the buffer.") +(make-variable-buffer-local 'rudel-mode-line-publish-state-string) +(put 'rudel-mode-line-publish-state-string 'risky-local-variable t) + +(defun rudel-mode-line-publish-state--add-indicator-to-mode-line () + "Add Rudel publish state indicator to mode line." + (let* ((new-format (copy-list mode-line-format)) + (format-rest (nthcdr + (position 'mode-line-modified mode-line-format) + new-format)) + (format-rest-cdr (cdr format-rest))) + (setcdr format-rest (cons 'rudel-mode-line-publish-state-string + format-rest-cdr)) + (setq mode-line-format new-format)) + (force-mode-line-update)) + +(defun rudel-mode-line-publish-state--remove-indicator-from-mode-line () + "Remove Rudel publish state indicator from mode line." + (let ((format-rest (nthcdr + (position 'mode-line-remote mode-line-format) + mode-line-format))) + ;; Only change the mode line if our indicator is present. + (when (eq (second format-rest) 'rudel-mode-line-publish-state-string) + (setcdr format-rest (cddr format-rest)) + (force-mode-line-update)))) + +(defun rudel-mode-line-publish-state--update-string () + "Update variable `rudel-mode-line-publish-state-string'." + ;; Update `rudel-mode-line-publish-state-string' with appropriate + ;; propertized indicator string. + (setq rudel-mode-line-publish-state-string + (cond + ((rudel-buffer-document) + (propertize + rudel-mode-line-publish-state-published-string + 'mouse-face 'mode-line-highlight + 'help-echo "Buffer is published")) + (t + (propertize + rudel-mode-line-publish-state-unpublished-string + 'mouse-face 'mode-line-highlight + 'help-echo "Buffer is not published")))) + + ;; Update the mode line. + (force-mode-line-update) + ) + +(defun rudel-mode-line-publish-state--document-attach (document buffer) + "Handle attaching of DOCUMENT to BUFFER. +When `rudel-mode-line-publish-state-minor-mode' is enabled in +BUFFER, update the state string." + ;; Only act when BUFFER has the minor mode enabled. + (with-current-buffer buffer + (when rudel-mode-line-publish-state-minor-mode + ;; Update the mode line. + (rudel-mode-line-publish-state--update-string) + + ;; Watch for detaching of DOCUMENT from BUFFER. + (object-add-hook + document 'detach-hook + #'rudel-mode-line-publish-state--document-detach))) + ) + +(defun rudel-mode-line-publish-state--document-detach (document buffer) + "Handle detaching of DOCUMENT from BUFFER." + ;; Update the mode line of BUFFER. + (with-current-buffer buffer + (rudel-mode-line-publish-state--update-string)) + + ;; Stop watching for detaching of DOCUMENT from BUFFER. It (or a + ;; different document) has to attach again first, before the next + ;; detaching can occur. + (object-remove-hook + document 'detach-hook + #'rudel-mode-line-publish-state--document-detach) + ) + +(defun rudel-mode-line-publish-state--options-changed () + "Update mode lines in buffers that have mode line publish state mode enabled." + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when rudel-mode-line-publish-state-minor-mode + (rudel-mode-line-publish-state--update-string))))) + +;;;###autoload +(define-minor-mode rudel-mode-line-publish-state-minor-mode + "Toggle Rudel mode line publish state minor mode. + +This mode displays an indicator of the buffer's state with +respect to an associated Rudel document in the mode line. If the +buffer has an attached document, the string \"P\" is displayed +after the remote file indicator. Otherwise, the string \"-\" is +displayed. + +If ARG is null, toggle Rudel mode line publish state minor mode. +If ARG is a number greater than zero, turn on Rudel minor mode +line publish state mode; otherwise, turn it off." + :init-value nil + :group 'rudel + (cond + ;; Emacs session is not interactive + (noninteractive + (setq rudel-mode-line-publish-state-minor-mode nil)) + + ;; Mode is enabled + (rudel-mode-line-publish-state-minor-mode + ;; Extend and update the mode line, no matter whether the buffer + ;; has a document or not. + (rudel-mode-line-publish-state--add-indicator-to-mode-line) + (rudel-mode-line-publish-state--update-string) + + ;; Watch document, if available or attach events, when a document + ;; is not available. + (let ((document (rudel-buffer-document))) + (if document + ;; Handle detaching of the document from the buffer. + (object-add-hook + document 'detach-hook + #'rudel-mode-line-publish-state--document-detach) + ;; Handle attaching of documents to buffers. We use the global + ;; hook here, installing the handler twice is prevented by + ;; `add-hook'. + (add-hook 'rudel-document-attach-hook + #'rudel-mode-line-publish-state--document-attach)))) + + ;; Mode is disabled + (t + ;; Maybe stop watching for the document detaching from the buffer. + (let ((document (rudel-buffer-document))) + (when document + (object-remove-hook + document 'detach-hook + #'rudel-mode-line-publish-state--document-detach))) + + ;; Remove the indicator from the mode line. + (rudel-mode-line-publish-state--remove-indicator-from-mode-line))) + ) + + +;;; Global mode line publish state mode +;; + +;;;###autoload +(define-globalized-minor-mode global-rudel-mode-line-publish-state-mode + rudel-mode-line-publish-state-minor-mode + rudel-mode-line-publish-state-minor-mode + :group 'rudel) + + +;;; Global Rudel mode, menu and keymap +;; + +(defvar rudel-minor-keymap + (let ((map (make-sparse-keymap)) + (sub-map (make-sparse-keymap))) + ;; Define sub keymap + (define-key sub-map "j" #'rudel-join-session) + (define-key sub-map "h" #'rudel-host-session) + (define-key sub-map "e" #'rudel-end-session) + + (define-key sub-map "c" #'rudel-change-color) + + (define-key sub-map "p" #'rudel-publish-buffer) + (define-key sub-map "u" #'rudel-unpublish-buffer) + (define-key sub-map "s" #'rudel-subscribe) + + ;; Bind the sub keymap into map + (define-key map "\C-cc" sub-map) + map) + "Keymap used in Rudel minor mode.") + +(when rudel-minor-keymap + (easy-menu-define + rudel-minor-menu rudel-minor-keymap "Rudel Minor Mode Menu" + '("Rudel" + [ "Join Session" rudel-join-session + (not rudel-current-session) ] + [ "Leave Session" rudel-end-session + rudel-current-session ] + "---" + [ "Host a Session" rudel-host-session + t ] + "---" + [ "Change Color" rudel-change-color + (and rudel-current-session + (rudel-capable-of-p + (oref rudel-current-session :backend) + 'change-color)) ] ; TODO bulky + "---" + [ "Publish current Buffer" rudel-publish-buffer + (and rudel-current-session + (not (rudel-buffer-has-document-p))) ] + [ "Unpublish current Buffer" rudel-unpublish-buffer + (rudel-buffer-has-document-p) ] + [ "Subscribe to Document" rudel-subscribe + rudel-current-session ] + "---" + [ "Rudel Overview" rudel-speedbar + t ] + "---" + ( "Options" + [ "Highlight Contributions in Authors' Colors" + (lambda () + (interactive) + (setq rudel-overlay-author-display + (not rudel-overlay-author-display)) + (rudel-overlay-options-changed)) + :style toggle + :selected rudel-overlay-author-display ] + ( "Show subscribed Users" + [ "In this Buffer" + rudel-header-subscriptions-minor-mode + :style toggle + :selected rudel-header-subscriptions-minor-mode ] + [ "Globally" + global-rudel-header-subscriptions-mode + :style toggle + :selected global-rudel-header-subscriptions-mode ] ) + ( "Show Status in mode line" + [ "In this Buffer" + rudel-mode-line-publish-state-minor-mode + :style toggle + :selected rudel-mode-line-publish-state-minor-mode ] + [ "Globally" + global-rudel-mode-line-publish-state-mode + :style toggle + :selected global-rudel-mode-line-publish-state-mode ] ) ) ) + ) + ) + +;;;###autoload +(define-minor-mode global-rudel-minor-mode + "Toggle global Rudel minor mode (No modeline indicator). + +If ARG is null, toggle global Rudel mode. +If ARG is a number greater than zero, turn on global Rudel mode; +otherwise, turn it off." + :init-value nil + :keymap rudel-minor-keymap + :global t + :group 'rudel + (cond + ;; Emacs session is not interactive + (noninteractive + (setq global-rudel-minor-mode nil)) + + ;; Mode is enabled + (global-rudel-minor-mode + ) + + ;; Mode is disabled + (t + )) + ) + +(provide 'rudel-mode) +;;; rudel-mode.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-operations.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-operations.el.svn-base new file mode 100644 index 0000000..3637303 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-operations.el.svn-base @@ -0,0 +1,133 @@ +;;; rudel-operations.el --- Rudel domain operations +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, operations +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file contains classes representing operations like insertions +;; and deletions, that are import for Rudel's domain of collaborative +;; editing. + + +;;; History: +;; +;; 0.1 - Initial revision + + +;;; Code: +;; + +(require 'eieio) + + +;;; Class rudel-operation +;; + +(defclass rudel-operation () + () + "Abstract base class for operations." + :abstract t) + +(defgeneric rudel-apply ((this rudel-operation) object) + "Apply the change represented by THIS to OBJECT.") + + +;;; Class rudel-insert-op +;; + +;; TODO should be rudel-insert but there is a method of the same name +(defclass rudel-insert-op (rudel-operation) + ((from :initarg :from + :type (or null (integer 0)) + :documentation + "Start of the region affected by this operation or +nil. nil means end of buffer") + (data :initarg :data + :type string + :documentation + "The inserted string.")) + "Objects of this class represent insertion operations.") + +(defmethod rudel-apply ((this rudel-insert-op) object) + "Apply THIS to OBJECT by inserting the associated data." + (with-slots (from data) this + (rudel-insert object from data))) + +(defmethod slot-missing ((this rudel-insert-op) + slot-name operation &optional new-value) + "Simulate read-only slots :length and :to." + (cond + ;; Slot :length + ((and (or (eq slot-name :length) + (eq slot-name 'length)) + (eq operation 'oref)) + (with-slots (data) this + (length data))) + ;; Slot :to + ((and (or (eq slot-name :to) + (eq slot-name 'to)) + (eq operation 'oref)) + (with-slots (from length) this + (+ from length))) + ;; Call next method + (t (call-next-method))) + ) + + +;;; Class rudel-delete-op +;; + +;; TODO should be rudel-delete but there is a method of the same name +(defclass rudel-delete-op (rudel-operation) + ((from :initarg :from + :type (integer 0) + :documentation + "Start of the region affected by this operation.") + (to :initarg :to + :type (integer 0) + :documentation + "End of the region affected by this operation.")) + "Objects of this class represent deletion operations.") + +(defmethod rudel-apply ((this rudel-delete-op) object) + "Apply THIS to OBJECT by deleting the associated region." + (with-slots (from length) this + (rudel-delete object from length))) + +(defmethod slot-missing ((this rudel-delete-op) + slot-name operation &optional new-value) + "Simulate slot :length" + (cond + ;; Slot :length + ((or (eq slot-name :length) + (eq slot-name 'length)) + (with-slots (from to) this + (if (eq operation 'oref) + (- to from) + (setq to (+ from new-value))))) + ;; Call next method + (t (call-next-method))) + ) + +(provide 'rudel-operations) +;;; rudel-operations.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-operators.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-operators.el.svn-base new file mode 100644 index 0000000..e51982e --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-operators.el.svn-base @@ -0,0 +1,172 @@ +;;; rudel-operators.el --- Sets of modification operators for Rudel objects +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, operators +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; Collections of operations on specific objects are collected into +;; classes. Current there are +;; +;; - rudel-document-operators: realize operations on document objects +;; +;; - rudel-connection-operators: realize operations on connection +;; objects +;; +;; - rudel-overlay-operators: realize operations by altering the +;; overlays of buffer objects +;; +;; - rudel-hook-operators: realize operations by calling hooks + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(require 'eieio) + +(require 'rudel-overlay) + + +;;; Class rudel-document-operators +;; + +(defclass rudel-document-operators () + ((document :initarg :document + :type rudel-document-child + :documentation + "Document to which modification operators are +applied.")) + "Provides operation methods which modify an associated document.") + +(defmethod rudel-insert ((this rudel-document-operators) position data) + "Insert DATA at POSITION into the document attached to THIS." + (with-slots (document) this + (rudel-insert document position data))) + +(defmethod rudel-delete ((this rudel-document-operators) position length) + "Delete a region of LENGTH characters at POSITION from the document attached to THIS." + (with-slots (document) this + (rudel-delete document position length))) + + +;;; Class rudel-connection-operators +;; + +(defclass rudel-connection-operators () + ((connection :initarg :connection + :type rudel-connection-child + :documentation + "Connection on which the operations are +performed.") + (document :initarg :document + :type rudel-document-child + :documentation + "Document object to which operations refer.")) + "Provides operation methods which affect an associated +connection.") + +(defmethod rudel-insert ((this rudel-connection-operators) position data) + "Notify the connection associated to THIS of the insertion of DATA at POSITION." + (with-slots (connection document) this + (rudel-local-insert connection document position data))) + +(defmethod rudel-delete ((this rudel-connection-operators) position length) + "Notify the connection associated to THIS of a deletion of LENGTH at POSITION." + (with-slots (connection document) this + (rudel-local-delete connection document position length))) + + +;;; Class rudel-overlay-operators +;; + +(defclass rudel-overlay-operators () + ((document :initarg :document + :type rudel-document-child + :documentation + "The document to the overlays of which the +operations are applied") + (user :initarg :user + :type rudel-user-child + :documentation + "The user object associated to operations.")) + "Provides operation methods which affect the overlays of a +buffer.") + +(defmethod rudel-insert ((this rudel-overlay-operators) position data) + "Update the overlays associated to THIS to incorporate an insertion of DATA at POSITION." + (with-slots (document user) this + (with-slots (buffer) document + + ;; Since we inserted something, (point-max) is at least the + ;; length of the insertion + 1. So we can safely subtract the + ;; length of the insertion and 1. + (unless position + (with-current-buffer buffer + (setq position (- (point-max) (length data) 1)))) + + + (rudel-update-author-overlay-after-insert + buffer (+ position 1) (length data) user))) + ) + +(defmethod rudel-delete ((this rudel-overlay-operators) position length) + "Update the overlays associated to THIS to incorporate a deletion of LENGTH at POSITION." + (with-slots (document user) this + (with-slots (buffer) document + (rudel-update-author-overlay-after-delete + buffer (+ position 1) length user)))) + + +;;; Class rudel-hook-operators +;; + +(defclass rudel-hook-operators () + ((document :initarg :document + :type rudel-document-child + :documentation + "The document object to which operations refer.") + (user :initarg :user + :type rudel-user-child + :documentation + "The user object associated to operations.")) + "Provides operation methods which cause corresponding hooks to +be called.") + +(defmethod rudel-insert ((this rudel-hook-operators) position data) + "Call insert hook associated to THIS with POSITION and DATA." + (with-slots (document user) this + (with-slots (buffer) document + (run-hook-with-args 'rudel-insert-hook buffer user position data)))) + +(defmethod rudel-delete ((this rudel-hook-operators) position length) + "Call delete hook associated to THIS with POSITION and LENGTH." + (with-slots (document user) this + (with-slots (buffer) document + (run-hook-with-args 'rudel-delete-hook buffer user position length)))) + +(provide 'rudel-operators) +;;; rudel-operators.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-overlay.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-overlay.el.svn-base new file mode 100644 index 0000000..093afdf --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-overlay.el.svn-base @@ -0,0 +1,275 @@ +;;; rudel-overlay.el --- Overlay functions for Rudel +;; +;; Copyright (C) 2008, 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: rudel, overlay +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(require 'custom) + +(eval-when-compile + (require 'cl)) + + +;;; Rudel overlay faces +;; + +(defcustom rudel-overlay-author-display t + "Indicate authorship by setting text color to user color." + :group 'rudel + :type 'boolean + :set (lambda (symbol value) + (set-default symbol value) + (when (featurep 'rudel-overlay) + (rudel-overlay-options-changed)))) + +(put 'rudel-overlay-author-display 'safe-local-variable t) + +(defface rudel-author-overlay-face + '((default (:background "black"))) + "*Face used to highlight contributions according to their authors. +Attributes involving color are not applied literally. Instead the +color is replaced with the color associated with the respective +author." + :group 'rudel) + + +;;; General overlay functions +;; + +(defun rudel-overlay-p (overlay) + "Non-nil if OVERLAY is a Rudel overlay." + (overlay-get overlay :rudel)) + +(defun rudel-overlay-length (overlay) + "Distance between end and start of OVERLAY." + (- (overlay-end overlay) (overlay-start overlay))) + +(defun rudel-overlay-user (overlay) + "User object associated to OVERLAY." + (overlay-get overlay :user)) + +(defun rudel-overlays (&optional predicate) + "Return a list of Rudel-related overlays or overlays satisfying PREDICATE. +If PREDICATE is non-nil returned overlays satisfy PREDICATES; +Otherwise all Rudel-related overlays are returned." + (unless predicate + (setq predicate #'rudel-overlay-p)) + + (let* ((overlay-lists (overlay-lists)) + (overlays (append (car overlay-lists) + (cdr overlay-lists)))) + (remove-if-not predicate overlays)) + ) + +(defun rudel-overlays-at (position &optional predicate) + "Return a list of Rudel-related overlays at POSITION. +If PREDICATE is non-nil returned overlays satisfy PREDICATES; +Otherwise all Rudel-related overlays are returned." + (unless predicate + (setq predicate #'rudel-overlay-p)) + (remove-if-not predicate (overlays-at position))) + +(defun rudel-overlays-in (start end &optional predicate) + "Return a list of Rudel-related overlays in the range START to END. +If PREDICATE is non-nil returned overlays satisfy PREDICATES; +Otherwise all Rudel-related overlays are returned." + (unless predicate + (setq predicate #'rudel-overlay-p)) + (remove-if-not predicate (overlays-in start end))) + +(defun rudel-overlays-remove-all () + "Remove all Rudel overlays from the current buffer." + (mapc #'delete-overlay (rudel-overlays))) + + +;;; Author overlay +;; + +(defun rudel-author-overlay-p (overlay) + "Predicate for author overlays." + (eq (overlay-get overlay :rudel) 'author)) + +(defun rudel-author-overlays () + "Return the list of author overlays in the current buffer." + (rudel-overlays #'rudel-author-overlay-p)) + +(defun rudel-author-overlay-at (position &optional author) + "" + (let ((overlays (rudel-overlays-at + position #'rudel-author-overlay-p))) + ;; There can only be one rudel overlay at any given position + (when overlays + (when (or (not author) + (eq (rudel-overlay-user (car overlays)) author)) + (car overlays)))) + ) + +(defun rudel-author-overlays-in (start end &optional author) + "" + (rudel-overlays-in + start end + (lambda (overlay) + (and (rudel-overlay-p overlay) + (or (not author) + (eq (rudel-overlay-user overlay) author))))) + ) + +(defun rudel-make-author-overlay (buffer from to author) + "Make and return an overlay for the range FROM to TO in BUFFER suitable for contributions by AUTHOR. +AUTHOR has to be an object of type rudel-user-child." + (let ((overlay (make-overlay from to buffer t))) + (rudel-overlay-author-set-properties overlay author) + overlay)) + +(defun rudel-overlay-author-set-properties (overlay author) + "Set properties of OVERLAY according to slots of AUTHOR. +AUTHOR has to be an object of type rudel-user-child." + (with-slots ((name :object-name) color) author + (overlay-put overlay :rudel 'author) + (overlay-put overlay :user author) + (overlay-put overlay 'face (when rudel-overlay-author-display + (rudel-overlay-make-face + (rudel-overlay-make-face-symbol + 'author name) + 'rudel-author-overlay-face + color))) + (overlay-put overlay 'help-echo (when rudel-overlay-author-display + (format "Written by %s" name)))) + ) + +(defun rudel-overlay-author-update (overlay) + "Update properties of OVERLAY from its attached user object." + (let ((author (rudel-overlay-user overlay))) + (rudel-overlay-author-set-properties overlay author))) + + +;;; Update functions for author overlays +;; + +(defun rudel-update-author-overlay-after-insert (buffer position length author) + "Update author overlays in BUFFER to incorporate an insertion of length LENGTH at POSITION by AUTHOR. +POSITION refers to an Emacs buffer position. +AUTHOR has to be an object of type rudel-author-child." + (when author + (with-current-buffer buffer + (let* ((end (+ position length)) + (before (when (> position 1) + (rudel-author-overlay-at (- position 1) author))) + (at (rudel-author-overlay-at position)) + (after (when (< end (point-max)) + (rudel-author-overlay-at (+ end 1) author)))) + (cond + ;; If there is an overlay, we have to split it unless the + ;; author is AUTHOR or we are on its boundary. + (at + (unless (eq (rudel-overlay-user at) author) + (let* ((on-start (= (overlay-start at) position)) + (on-end (= (- (overlay-end at) 1) position)) + (before (unless on-start + (if on-end at (copy-overlay at)))) + (after (unless on-end at))) + (when before + (move-overlay before (overlay-start before) position)) + (when after + (move-overlay after end (overlay-end after))) + (rudel-make-author-overlay buffer position end author)))) + ;; There is no overlay under the insert, but there are + ;; overlays of the same author immediately before and after + ;; the insert. We merge these two into one large overlay + ;; including the insert. + ((and before after) + (let ((end (overlay-end after))) + (delete-overlay after) + (move-overlay before (overlay-start before) end))) + ;; If there is an overlay of the same author before the + ;; insert, we extend it. + (before + (move-overlay before (overlay-start before) end)) + ;; If there is an overlay of the same author after the + ;; insert, we extend it. + (after + (move-overlay after position (overlay-end after))) + ;; If there are no overlays at all, we create a suitable one. + (t + (rudel-make-author-overlay buffer position end author)))))) + ) + +(defun rudel-update-author-overlay-after-delete (buffer position length author) + "Update author overlays in BUFFER to incorporate a deletion of length LENGTH at POSITION by AUTHOR. +POSITION refers to an Emacs buffer position. +AUTHOR has to be an object of type rudel-author-child." + (with-current-buffer buffer + (mapc + (lambda (overlay) + (when (zerop (rudel-overlay-length overlay)) + (delete-overlay overlay))) + (rudel-author-overlays-in position position))) + ) + + +;;; Miscellaneous functions +;; + +(defun rudel-overlay-make-face-symbol (category name) + "Allocate a symbol for a face for CATEGORY and NAME." + (intern (format "rudel-%s-overlay-%s-face" + (if (stringp category) + category + (symbol-name category)) + name))) + +(defun rudel-overlay-make-face (face template color) + "Copy TEMPLATE to FACE and replace color attributes with COLOR. +TEMPLATE has to be a face. FACE can be nil or a face. In the +latter case, FACE is returned unmodified." + (unless (facep face) + (make-face face) + (copy-face template face) + (rudel-overlay-set-face-attributes face color)) + face) + +(defun rudel-overlay-set-face-attributes (face color) + "Set color-related attributes of FACE with respect to COLOR." + (when (facep face) + (dolist (property '(:foreground :background :underline :overline)) + (unless (eq (face-attribute face property) 'unspecified) + (set-face-attribute face nil property color))))) + +(defun rudel-overlay-options-changed () + "Update Rudel overlays after a change of customization options." + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (mapc #'rudel-overlay-author-update (rudel-overlays))))) + +(provide 'rudel-overlay) +;;; rudel-overlay.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-protocol.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-protocol.el.svn-base new file mode 100644 index 0000000..c60718c --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-protocol.el.svn-base @@ -0,0 +1,83 @@ +;;; rudel-protocol.el --- Interface implemented by Rudel protocol backends +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, backend, protocol +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file contains the interface for Rudel protocol backends. This +;; interface consists of the following functions: +;; +;; + joining sessions +;; + `rudel-ask-join-info' +;; + `rudel-join' +;; + hosting sessions +;; + `rudel-ask-host-info' +;; + `rudel-host' +;; + factory functions +;; + `rudel-make-document' + + +;;; History: +;; +;; 0.1 - Initial revision + + +;;; Code: +;; + +(require 'eieio) + +(require 'rudel-backend) + + +;;; Class rudel-protocol-backend +;; + +(defclass rudel-protocol-backend (rudel-backend) + () + "Interface implemented by protocol backends." + :abstract t) + +(defgeneric rudel-ask-join-info ((this rudel-protocol-backend)) + "Retrieve information for joining a session from user. +Return a property list that contains the collected information.") + +(defgeneric rudel-join ((this rudel-protocol-backend) info) + "Create a new connection according to the data in the property list INFO. +Implementations can rely on the fact that the property :session +contains the `rudel-session' object to which the new connection +will be associated.") + +(defgeneric rudel-ask-host-info ((this rudel-protocol-backend)) + "Retrieve information for hosting a session from user. +Return a property list that contains the collected information.") + +(defgeneric rudel-host ((this rudel-protocol-backend) info) + "Create a new session according to the property list INFO.") + +(defgeneric rudel-make-document ((this rudel-protocol-backend) + name session) + "Create a new document object named NAME for SESSION.") + +(provide 'rudel-protocol) +;;; rudel-protocol.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-session-initiation.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-session-initiation.el.svn-base new file mode 100644 index 0000000..395ab07 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-session-initiation.el.svn-base @@ -0,0 +1,352 @@ +;;; rudel-session-initiation.el --- Session discovery and advertising functions +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, session, initiation, service, discovery, advertising +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; Interfaces for session initiation and discovery. +;; +;; The central interface is +;; `rudel-session-initiation-backend'. Backends implementing this +;; interface can provide methods to discover sessions, to advertise +;; sessions, or both. +;; +;; The client programming interface consists of a priority which is +;; one of: +;; +;; + `primary' +;; + `fallback' +;; +;; and the following functions: +;; +;; + `rudel-session-initiation-discover' +;; + `rudel-session-initiation-advertise' +;; + `rudel-session-initiation-withdraw' + + +;;; History: +;; +;; 0.1 - Initial revision + + +;;; Code: +;; + +(eval-when-compile + (require 'cl)) + +(require 'eieio) + +(require 'rudel-backend) + + +;;; Customization options +;; + +(defcustom rudel-configured-sessions nil + "List of configured sessions. + +Each session is described as a plist (a list of keys and values +see Info node `(elisp)Property Lists'). Keys are specified using +keywords and look like this: :host, :username, :color. Values are +mostly strings, but symbols and numbers are possible as well. + +The following keys are required for any session: + +* :name (string) +* :backend (string or symbol) + +Other keys are optional and depend on the selected +backend. Required keys for which no value is specified will be +prompted for when selecting the session. The values of the :name +properties have to be distinct for all configured sessions. + +Additional keys required by most backends: + +* :host (string) +* :port (number) +* :username (string) +* :color (string) + +Here is a complete example of customized values for the obby +backend: + +* :name \"sonian\" +* :backend obby +* :host \"sobby\" +* :port 6522 +* :encryption t +* :username \"phil\" +* :color \"white\" +* :global-password \"\" (this means \"no password\") +* :user-password \"\" + +The programmatic equivalent looks like this: + +(add-to-list + 'rudel-configured-sessions + (list :name \"myserver\" + :backend 'obby + :host \"my.sobby-server.net\" + :username user-login-name + ;; Use M-x list-colors-display to see color choices. + :color \"white\" + :encryption t + :port 6522 + ;; empty string means no password + :global-password \"\" + :user-password \"\"))" + :group 'rudel + :type '(repeat :tag "Connections" + (plist :tag "Connection" + :options ((:name string) + (:backend symbol) + (:username string) + (:color color)))) + ) + + +;;; Variables and constants +;; + +(defvar rudel-session-discovered-hook nil + "This hook is run when collaboration sessions are discovered.") + +(defvar rudel-session-vanished-hook nil + "This hook is run when previously discovered collaboration +session disappear.") + + +;;; Class rudel-session-initiation-backend +;; + +(defclass rudel-session-initiation-backend (rudel-backend) + ((priority :initarg :priority + :type symbol + :accessor rudel-priority + :documentation + "Priority of the session initiation method +implemented by this backend. Has to be either 'primary or +'fallback")) + "Interface implemented by session initiation backends." + :abstract t) + +(defgeneric rudel-discover ((this rudel-session-initiation-backend)) + "Return a list of discovered sessions. +Each list element is a connect info property list. See +`rudel-join-session' for a description of the format of this +list. + +The presence of an implementation of this generic function should +be indicated by the presence of the 'discover' capability.") + +(defgeneric rudel-advertise ((this rudel-session-initiation-backend) info) + "Advertise session described by INFO. +INFO is a connect info property list. See `rudel-host-session' +for a description of the format of this list. + +The presence of an implementation of this generic function should +be indicated by the presence of the 'advertise' capability.") + + +;;; Client programming interface functions. +;; + +(defun rudel-session-initiation-suitable-backends (capability) + "Return primary and fallback backends that have CAPABILITY. +The returned list is of the form (PRIMARY FALLBACK), where +PRIMARY and FALLBACK are lists of backends of the respective +priority." + (let* (;; Select all backends, which can discover sessions + (suitable-backends (rudel-backend-suitable-backends + 'session-initiation + (lambda (backend) + (rudel-capable-of-p backend capability)))) + ;; Select primary backends + (primary-backends (remove* + 'fallback suitable-backends + :key (lambda (backend) + (rudel-priority (cdr backend))))) + ;; Select fallback backends + (fallback-backends (remove* + 'primary suitable-backends + :key (lambda (backend) + (rudel-priority (cdr backend)))))) + (list primary-backends fallback-backends)) + ) + +(defun rudel-session-initiation-discover (&optional backend-name) + "Return a list of session using BACKEND-NAME when non-nil. +BACKEND-NAME is a symbol. When it is non-nil, only the specified +backend is used to discover session. + +The returned list is of the form (INFO-1 ... INFO-N FALLBACK-1 +... FALLBACK-M) where INFO-I are connect info property lists (see +`rudel-join-session') and FALLBACK-I are conses of the form (NAME +. CLASS-OR-OBJECT) that specify fallback backends." + (multiple-value-bind (primary-backends fallback-backends) + (rudel-session-initiation-suitable-backends 'discover) + ;; Retrieve session list from primary backend and fall back to + ;; fallback backends if the list is empty. + (if backend-name + (let ((backend (find backend-name fallback-backends :key #'car))) + (rudel-discover (cdr backend))) + (let ((primary-results + (remove-if #'null + (apply #'append + (mapcar #'rudel-discover + (mapcar #'cdr primary-backends)))))) + (append primary-results fallback-backends)))) + ) + +(defun rudel-session-initiation-advertise (info) + "Advertise the session described by INFO. +INFO is a connect info property list. See `rudel-host-session' +for a description of the format of this list. + +Primary backends are tried first. If none succeeds, fallback +backends are tried. + +The result is non-nil if at least one backend was able to +advertise the session." + (multiple-value-bind (primary-backends fallback-backends) + (rudel-session-initiation-suitable-backends 'advertise) + (or ;; Try to advertise the session using primary backends. + (some (mapcar (lambda (backend) + (rudel-advertise backend info)) + (mapcar #'cdr primary-backends))) + ;; When the primary backends fail, try to advertise the + ;; session using fallback backends + (some (mapcar (lambda (backend) + (rudel-advertise backend info)) + (mapcar #'cdr fallback-backends))))) + ) + + +;;; Class rudel-ask-protocol-backend +;; + +(defconst rudel-ask-protocol-version '(0 1) + "Version of the ask-protocol backend for Rudel.") + +;;;###autoload +(defclass rudel-ask-protocol-backend (rudel-session-initiation-backend) + ((capabilities :initform (discover)) + (priority :initform fallback)) + "This fallback backend can \"discover\" sessions by letting the +user select a suitable backend and asking for connect information +required by the chosen backend.") + +(defmethod initialize-instance ((this rudel-ask-protocol-backend) + &rest slots) + "Set backend version." + (when (next-method-p) + (call-next-method)) + + (oset this :version rudel-ask-protocol-version)) + +(defmethod rudel-discover ((this rudel-ask-protocol-backend)) + "\"Discover\" sessions by asking the user about the backend to use and the connect info." + (let ((backend (rudel-backend-choose + 'protocol + (lambda (backend) + (rudel-capable-of-p backend 'join))))) + (list (append (list :name "asked" + :backend backend) + (rudel-ask-connect-info (cdr backend))))) + ) + +;;;###autoload +(rudel-add-backend (rudel-backend-get-factory 'session-initiation) + 'ask-protocol 'rudel-ask-protocol-backend) + + +;;; Class rudel-configured-sessions-backend +;; + +(defconst rudel-configured-sessions-version '(0 1) + "Version of the configured-sessions backend for Rudel.") + +;;;###autoload +(defclass rudel-configured-sessions-backend + (rudel-session-initiation-backend) + ((capabilities :initform (discover)) + (priority :initform primary)) + "This fallback backend can \"discover\" sessions the user has +configured using customization.") + +(defmethod initialize-instance ((this rudel-configured-sessions-backend) + &rest slots) + "Set backend version." + (when (next-method-p) + (call-next-method)) + + (oset this :version rudel-configured-sessions-version)) + +(defmethod rudel-discover ((this rudel-configured-sessions-backend)) + "\"Discover\" sessions the has configured." + ;; Iterate over all configured sessions in order to make + ;; adjustments. + (mapcar #'rudel-session-initiation-adjust-info + rudel-configured-sessions)) + +;;;###autoload +(rudel-add-backend (rudel-backend-get-factory 'session-initiation) + 'configured-sessions 'rudel-configured-sessions-backend) + + +;;; Miscellaneous functions +;; + +(defun rudel-session-initiation-adjust-info (info) + "Resolve arguments that need resolving in INFO." + ;; Start with a new, empty property list. + (let ((adjusted-info) + (key (car info)) + (value (cadr info)) + (rest info)) + ;; Iterate over all properties in INFO. + (while rest + (setq rest (cddr rest)) + (cond + ;; Resolve backend arguments. + ((eq key :backend) + (let ((backend (rudel-backend-get 'protocol + (if (stringp value) + (intern value) + value)))) + (push backend adjusted-info) + (push key adjusted-info))) + ;; Keep other arguments unmodified. + (t + (push value adjusted-info) + (push key adjusted-info))) + ;; Advance to next key value pair. + (setq key (car rest) + value (cadr rest))) + ;; Return the transformed session information. + adjusted-info) + ) + +(provide 'rudel-session-initiation) +;;; rudel-session-initiation.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-speedbar.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-speedbar.el.svn-base new file mode 100644 index 0000000..8c2caa8 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-speedbar.el.svn-base @@ -0,0 +1,214 @@ +;;; rudel-speedbar.el --- Speedbar rendering of Rudel objects +;; +;; Copyright (C) 2008, 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: rudel, collaboration, speedbar +;; X-RCS: $Id: rudel-speedbar.el,v 1.32 2008/10/10 21:47:28 zappo Exp $ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + +;;; Commentary: +;; +;; This implements rendering of Rudel objects in speedbar. + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(require 'speedbar) +(require 'eieio-speedbar) + + +;;; Class rudel-user methods +;; + +(defmethod eieio-speedbar-description ((this rudel-user)) + "Provide a speedbar description for OBJ." + (format "User %s" (object-name-string this))) + +(defmethod eieio-speedbar-object-buttonname ((this rudel-user)) + "Return a string to use as a speedbar button for OBJECT." + (format "%s" (object-name-string this))) + + +;;; Class rudel-document methods +;; + +(defmethod eieio-speedbar-description ((this rudel-document)) + "Construct a description for from the name of document object THIS." + (format "Document %s" (object-name-string this))) + +(defmethod eieio-speedbar-object-buttonname ((this rudel-document)) + "Return a string to use as a speedbar button for OBJECT." + (rudel-unique-name this)) + +;;; Speedbar support mode +;; +(defun rudel-speedbar-make-map () + "Make the generic object based speedbar keymap." + (speedbar-make-specialized-keymap)) + +(defvar rudel-speedbar-key-map + (rudel-speedbar-make-map) + "A Generic object based speedbar display keymap.") + +(defvar rudel-speedbar-menu + '([ "Compile" rudel-speedbar-compile-line t]) + "Menu part in easymenu format used in speedbar while browsing objects.") + +(defun rudel-speedbar-toplevel-buttons (dir) + "Return a list of objects to display in speedbar. +Argument DIR is the directory from which to derive the list of objects." + (when rudel-current-session + (with-slots (users documents) rudel-current-session + (append users documents)))) + +(eieio-speedbar-create 'rudel-speedbar-make-map + 'rudel-speedbar-key-map + 'rudel-speedbar-menu + "Collaboration Session" + 'rudel-speedbar-toplevel-buttons) + +;;;###autoload +(defun rudel-speedbar () + "Show connected users and available documents of Rudel session in speedbar." + (interactive) + (speedbar-frame-mode 1) + (speedbar-change-initial-expansion-list "Collaboration Session") + (speedbar-get-focus)) + +;;; Speedbar Project Methods +;; +;; (defun rudel-find-nearest-file-line () +;; "Go backwards until we find a file." +;; (save-excursion +;; (beginning-of-line) +;; (looking-at "^\\([0-9]+\\):") +;; (let ((depth (string-to-number (match-string 1)))) +;; (while (not (re-search-forward "[]] [^ ]" +;; (save-excursion (end-of-line) +;; (point)) +;; t)) +;; (re-search-backward (format "^%d:" (1- depth))) +;; (setq depth (1- depth))) +;; (speedbar-line-token)))) +;; +;; (defmethod eieio-speedbar-derive-line-path ((obj rudel-session) &optional depth) +;; "Return the path to OBJ. +;; Optional DEPTH is the depth we start at." +;; "session" ;(file-name-directory (oref obj file)) +;; ) +;; +;; (defmethod eieio-speedbar-derive-line-path ((obj rudel-session) &optional depth) +;; "Return the path to OBJ. +;; Optional DEPTH is the depth we start at." +;; (let ((proj (rudel-target-parent obj))) +;; ;; Check the type of line we are currently on. +;; ;; If we are on a child, we need a file name too. +;; (save-excursion +;; (let ((lt (speedbar-line-token))) +;; (if (or (eieio-object-p lt) (stringp lt)) +;; (eieio-speedbar-derive-line-path proj) +;; ;; a child element is a token. Do some work to get a filename too. +;; (concat (eieio-speedbar-derive-line-path proj) +;; (rudel-find-nearest-file-line))))))) +;; +;; (defmethod eieio-speedbar-description ((obj rudel-session)) +;; "Provide a speedbar description for OBJ." +;; "bla") ;(rudel-description obj)) +;; +;; +;; (defmethod eieio-speedbar-object-buttonname ((object rudel-project)) +;; "Return a string to use as a speedbar button for OBJECT." +;; (if (rudel-parent-project object) +;; (rudel-name object) +;; (concat (rudel-name object) " " (oref object version)))) +;; +;; +;; (defmethod eieio-speedbar-object-children ((this rudel-project)) +;; "Return the list of speedbar display children for THIS." +;; (condition-case nil +;; (with-slots (subproj targets) this +;; (append subproj targets)) +;; (error nil))) +;; +;; +;; ;;; Generic file management for TARGETS +;; ;; +;; (defun rudel-file-find (text token indent) +;; "Find the file TEXT at path TOKEN. +;; INDENT is the current indentation level." +;; (speedbar-find-file-in-frame +;; (expand-file-name token (speedbar-line-directory indent))) +;; (speedbar-maybee-jump-to-attached-frame)) +;; +;; (defun rudel-create-tag-buttons (filename indent) +;; "Create the tag buttons associated with FILENAME at INDENT." +;; (let* ((lst (speedbar-fetch-dynamic-tags filename))) +;; ;; if no list, then remove expando button +;; (if (not lst) +;; (speedbar-change-expand-button-char ??) +;; (speedbar-with-writable +;; ;; We must do 1- because indent was already incremented. +;; (speedbar-insert-generic-list (1- indent) +;; lst +;; 'rudel-tag-expand +;; 'rudel-tag-find))))) +;; +;; (defun rudel-tag-expand (text token indent) +;; "Expand a tag sublist. Imenu will return sub-lists of specialized tag types. +;; Etags does not support this feature. TEXT will be the button +;; string. TOKEN will be the list, and INDENT is the current indentation +;; level." +;; (cond ((string-match "+" text) ;we have to expand this file +;; (speedbar-change-expand-button-char ?-) +;; (speedbar-with-writable +;; (save-excursion +;; (end-of-line) (forward-char 1) +;; (speedbar-insert-generic-list indent token +;; 'rudel-tag-expand +;; 'rudel-tag-find)))) +;; ((string-match "-" text) ;we have to contract this node +;; (speedbar-change-expand-button-char ?+) +;; (speedbar-delete-subblock indent)) +;; (t (error "Ooops... not sure what to do"))) +;; (speedbar-center-buffer-smartly)) +;; +;; (defun rudel-tag-find (text token indent) +;; "For the tag TEXT in a file TOKEN, goto that position. +;; INDENT is the current indentation level." +;; (let ((file (rudel-find-nearest-file-line))) +;; (speedbar-find-file-in-frame file) +;; (save-excursion (speedbar-stealthy-updates)) +;; ;; Reset the timer with a new timeout when cliking a file +;; ;; in case the user was navigating directories, we can cancel +;; ;; that other timer. +;; ; (speedbar-set-timer speedbar-update-speed) +;; (goto-char token) +;; (run-hooks 'speedbar-visiting-tag-hook) +;; ;;(recenter) +;; (speedbar-maybee-jump-to-attached-frame) +;; )) + +(provide 'rudel-speedbar) + +;;; rudel-speedbar.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-state-machine.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-state-machine.el.svn-base new file mode 100644 index 0000000..d96bcc7 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-state-machine.el.svn-base @@ -0,0 +1,331 @@ +;;; rudel-state-machine.el --- A simple state machine for Rudel +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, FSM +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This is a simple implementation of a finite state machine +;; (FSM). The is modeled by rudel-state-machine class, objects of +;; which contain state objects of classes derived from +;; rudel-state. There are no explicit transition rules, since states +;; specify their successors. + + +;;; History: +;; +;; 0.1 - Initial revision + + +;;; Code: +;; + +(eval-when-compile + (require 'cl)) + +(require 'eieio) + +(require 'rudel-errors) +(require 'rudel-compat) ;; for pulsing progress reporter + + +;;; Errors related to the state machine +;; + +;; rudel-state-error + +(intern "rudel-state-error") + +(put 'rudel-state-error 'error-conditions + '(error + rudel-error rudel-state-error)) + +(put 'rudel-state-error 'error-message + "Invalid state or state transition") + +;; rudel-invalid-successor-state + +(intern "rudel-invalid-successor-state") + +(put 'rudel-invalid-successor-state 'error-conditions + '(error + rudel-error rudel-state-error rudel-invalid-successor-state)) + +(put 'rudel-invalid-successor-state 'error-message + "Invalid successor state in state transition") + +;; rudel-entered-error-state + +(intern "rudel-entered-error-state") + +(put 'rudel-entered-error-state 'error-conditions + '(error + rudel-error rudel-state-error rudel-entered-error-state)) + +(put 'rudel-entered-error-state 'error-message + "Transition to error state") + +;; rudel-no-start-state + +(intern "rudel-no-start-state") + +(put 'rudel-no-start-state 'error-conditions + '(error + rudel-error rudel-state-error rudel-no-start-state)) + +(put 'rudel-no-start-state 'error-message + "No start state specified for state machine") + + +;;; Class rudel-state +;; + +(defclass rudel-state () + () + "A state that can be used in state machines." + :abstract t) + +(defgeneric rudel-accept ((this rudel-state) &rest arguments) + "Executed when the machine receives an event while in state THIS.") + +(defgeneric rudel-enter ((this rudel-state) &rest arguments) + "Executed when the machine switches to state THIS.") + +(defgeneric rudel-leave ((this rudel-state)) + "Executed when the machine leaves state THIS.") + + +;;; Class rudel-state-machine +;; + +(defclass rudel-state-machine () + ((states :initarg :states + :type list ;; alist + :initform nil + :documentation + "A list (NAME . STATE) conses where NAME is a symbol +and STATE is an object of a class derived from rudel-state.") + (state :initarg :state + :type rudel-state-child + :documentation + "The current state of the machine.")) + "A finite state machine.") + +(defmethod initialize-instance :after ((this rudel-state-machine) + &rest slots) + "Set current state of THIS to a proper initial value. +If a start state is specified in the arguments to the +constructor, that state is used. If there is no such state, the +list of states is search for a state named start. If that fails +as well, the first state in the state list is used." + (with-slots (states) this + ;; Find a suitable start state and switch to it. + (let ((start (or (plist-get slots :start) + (car (assoc 'start states)) + (when (length states) + (car (nth 0 states)))))) + (unless start + (signal 'rudel-no-start-state nil)) + ;; Make start state the current state and call send an enter + ;; message. + (let ((start (cdr (assoc start states)))) + (oset this :state start) + (rudel--switch-to-return-value + this start (rudel-enter start))))) + ) + +(defmethod rudel-find-state ((this rudel-state-machine) name) + "Return state object for symbol NAME." + (with-slots (states) this + (cdr (assoc name states)))) + +(defmethod rudel-register-state ((this rudel-state-machine) name state) + "Register STATE and its NAME with THIS state machine." + (object-add-to-list this :states (cons name state) t)) + +(defmethod rudel-register-states ((this rudel-state-machine) states) + "Register STATES with THIS state machine. +STATES is a list of cons cells whose car is a symbol - the name +of the state - and whose cdr is a class." + (dolist (symbol-and-state states) + (destructuring-bind (name . class) symbol-and-state + (rudel-register-state + this name (make-instance class (symbol-name name))))) + ) + +(defmethod rudel-current-state ((this rudel-state-machine) &optional object) + "Return name and, optionally, state object of the current state of THIS. +If OBJECT is non-nil, (NAME . OBJECT) is returned. Otherwise, +just NAME." + (with-slots (states state) this + (let ((state-symbol (car (find state states :key #'cdr :test #'eq)))) + (if object + (cons state-symbol state) + state-symbol))) + ) + +(defmethod rudel-accept ((this rudel-state-machine) &rest arguments) + "Process an event described by ARGUMENTS." + (with-slots (state) this + ;; Let the current state decide which state is next. + (let ((next (apply #'rudel-accept state arguments))) + (cond + ;; If NEXT is nil, a symbol or a state object, we switch states + ;; without passing any data. + ((or (null next) (symbolp next) (rudel-state-child-p next)) + (rudel-switch this next)) + + ;; If NEXT is a list, it contains the symbol of the successor + ;; state and additional data. + ((listp next) + (apply #'rudel-switch this next)) + + ;; Other types cannot be processed. + (t + (signal 'wrong-type-argument (list (type-of next))))))) + ) + +(defmethod rudel-switch ((this rudel-state-machine) next + &rest arguments) + "Leave current state and switch to state NEXT. +ARGUMENTS are passed to the `rudel-enter' method of the successor +state." + (with-slots (states state) this + (cond + ;; When NEXT is a state object, use it. + ((rudel-state-child-p next)) + + ;; When NEXT is nil, stay in the current state. + ((null next) + (setq next state)) + + ;; When NEXT is a symbol (but not nil), look up the corresponding + ;; state. Signal an error, if there is none. + ((symbolp next) + (let ((next-state (assoc next states))) + (unless next-state + (signal 'rudel-invalid-successor-state + (list next '<- state))) + (setq next (cdr next-state)))) + + ;; Other types cannot be processed. + (t + (signal 'wrong-type-argument (list (type-of next))))) + + ;; Unless the successor state is equal to the current state, leave + ;; the current state and switch to the successor. + (if (and (eq state next) + (null arguments)) + ;; Return state + state + ;; Notify (old) current state. + (rudel-leave state) + ;; Update current state. + (setq state next) + ;; Notify (new) current state. Using the call's value as next + ;; state is a bit dangerous since a long sequence of immediate + ;; state switches could exhaust the stack. + (rudel--switch-to-return-value + this state (apply #'rudel-enter state arguments)))) + ) + +(defmethod rudel--switch-to-return-value ((this rudel-state-machine) + state next) + "Switch from STATE to the next state indicated by NEXT. +STATE is the current state. +NEXT can nil, a list or a `rudel-state' object." + (cond + ;; Remain in current state. + ((null next) + state) + ;; NEXT contains next state and arguments to pass to it when + ;; switching. + ((listp next) + (apply #'rudel-switch this next)) + ;; Otherwise NEXT is a `rudel-state' object. + (t + (rudel-switch this next))) + ) + +(defmethod object-print ((this rudel-state-machine) &rest strings) + "Add current state to the string representation of THIS." + (if (slot-boundp this 'state) + (with-slots (state) this + (apply #'call-next-method + this + (format " state: %s" + (object-name-string state)) + strings)) + (call-next-method this " state: #start")) + ) + + +;;; Miscellaneous functions +;; + +(defun rudel-state-wait (machine success-states + &optional error-states callback) + "Repeatedly call CALLBACK until MACHINE is in a state in SUCCESS-STATES or ERROR-STATES. +MACHINE should be of type rudel-state-machine-child or at least +have a method `rudel-get-state'. + +SUCCESS-STATES and ERROR-STATES are lists which contain the +names (as symbols) of success and error states respectively. +This function does not return when MACHINE enters states not in +SUCCESS-STATES or ERROR-STATES. As a result, a deadlock can occur +when MACHINE deadlocks or cycles through states not in either +list infinitely. + +When non-nil, CALLBACK has to be a function that accepts one +argument of the form (SYMBOL . STATE) where SYMBOL is the name +symbol of the current state and STATE is the state object." + ;; Wait until MACHINE enter a state in SUCCESS-STATES or + ;; ERROR-STATES. + (let ((result + (catch 'state-wait + (while t + ;; Retrieve current state. + (destructuring-bind (symbol . state) + (rudel-current-state machine t) + + ;; Check against success and error states. + (when (memq symbol success-states) + (throw 'state-wait (cons 'success (cons symbol state)))) + (when (memq symbol error-states) + (throw 'state-wait (cons 'error (cons symbol state)))) + + ;; Update progress indicator and sleep. + (when callback + (funcall callback (cons symbol state))) + (sleep-for 0.05)))))) + (when callback + (funcall callback t)) + + ;; If MACHINE ended up in an error state, signal + (unless (eq (car result) 'success) + (signal 'rudel-entered-error-state (cdr result))) + ;; Return state + (cdr result)) + ) + +(provide 'rudel-state-machine) +;;; rudel-state-machine.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-tls.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-tls.el.svn-base new file mode 100644 index 0000000..a770851 --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-tls.el.svn-base @@ -0,0 +1,201 @@ +;;; rudel-tls.el --- Start TLS protocol. +;; +;; Copyright (C) 2008, 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, TLS, encryption, starttls, gnutls +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This contains a simple implementation of the so calls Start TLS +;; protocol, which means enabling TLS encryption for an existing +;; network connection. + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(require 'format-spec) + +(require 'rudel) +(require 'rudel-util) + + +;;; Customization +;; + +(defcustom rudel-tls-client-program + "gnutls-cli" + "The gnutls client program to use for encrypted connections." + :group 'rudel + :type 'file) + +(defcustom rudel-tls-client-arguments + "--starttls --kx ANON_DH --port %p %h" + "Arguments passed to the gnutls client program." + :group 'rudel + :type 'string) + + +;;; TLS functions +;; + +(defun rudel-tls-make-process (&rest args) + "Make a network process with keyword arguments ARGS. +This function works similar to `make-network-process'. Supported +keyword arguments are :name (ignore), :host, :port, :filter +and :sentinel. The returned process object is suitable for +start-TLS. Once the enclosing protocol indicates TLS encryption +should start, `rudel-tls-start-tls' can be called to enabled TLS +for the network connection." + (let* ((host (plist-get args :host)) ;; TODO clumsy + (port (plist-get args :service)) + (filter (plist-get args :filter)) + (sentinel (plist-get args :sentinel)) + ;; Compile the command to start the TLS binary. + (arguments (format-spec rudel-tls-client-arguments + (format-spec-make + ?h host + ?p (number-to-string port)))) + ;; Start the TLS program. + (process (apply #'start-process + (format "*tls-%s*" host) nil + rudel-tls-client-program + (split-string arguments " ")))) + + ;; Store filter function and attach proxy filter to handle TLS + ;; handshake. + (when filter + (rudel-set-process-object process filter :old-filter)) + (set-process-filter process #'rudel-tls-wait-init) + + ;; Attach sentinel function. + (when sentinel + (set-process-sentinel process sentinel)) + + ;; Mark the process as supporting TLS encryption + (rudel-set-process-object process t :supports-tls) + + process) + ) + +(defun rudel-tls-start-tls (process) + "Enable TLS encryption for the network connection PROCESS. +This only works if PROCESS has been created by +`rudel-tls-make-process'." + ;; Save current filter function. + (rudel-set-process-object + process (process-filter process) :old-filter) + ;; Install TLS handshake filter function and signal program to start + ;; TLS handshake. + (message "tls-start-tls: switching to \"handshake\" filter") + (set-process-filter process #'rudel-tls-wait-handshake) + (signal-process process 'sigalrm) + ) + +(defun rudel-tls-wait-init (process data) + "Is installed as process filter on PROCESS until gnutls is done printing messages." + ;; Retrieve complete lines. + (let ((buffer (rudel-process-object process :buffer))) + (rudel-assemble-line-fragments data buffer) + (rudel-set-process-object process buffer :buffer)) + + (let ((client-data) + (old-filter (rudel-process-object process :old-filter)) + (client-mode)) + + ;; Assemble lines that were not generated by gnutls. It is very + ;; brittle to wait for last line of gnutls output like, but it + ;; cannot be helped. + (rudel-loop-lines data line + (if client-mode + (setq client-data (concat client-data line "\n")) + (when (string-match-p "- Simple Client Mode.*" line) + (setq client-mode t)))) + + ;; When there are any lines not generated by gnutls, + ;; initialization is over. Process the data and install the old + ;; filter function. + (when client-data + (funcall old-filter process client-data)) + (when client-mode + (message "tls-wait-init: switching back to old filter") + (set-process-filter process old-filter))) + ) + +(defun rudel-tls-wait-handshake (process data) + "Is installed as process filter on PROCESS while gnutls is doing the TLS handshake." + ;; Retrieve complete lines. + (let ((buffer (rudel-process-object process :buffer))) + (rudel-assemble-line-fragments data buffer) + (rudel-set-process-object process buffer :buffer)) + + (let ((client-data) + (old-filter (rudel-process-object process :old-filter)) + (client-mode)) + + ;; Assemble lines that were not generated by gnutls. It is very + ;; brittle to wait for last line of gnutls output like, but it + ;; cannot be helped. + (rudel-loop-lines data line + (if client-mode + (setq client-data (concat client-data line "\n")) + (when (string-match-p "- Compression.*" line) + (setq client-mode t)))) + + ;; When there are any lines not generated by gnutls, handshake is + ;; over. Process the data and install `established' filter + ;; function. + (when client-data + (funcall old-filter process client-data)) + (when client-mode + (message "tls-wait-handshake: switching to \"established\" filter") + (set-process-filter process #'rudel-tls-established) + (rudel-set-process-object process t :encryption))) + ) + +(defun rudel-tls-established (process data) + "Is installed as process filter on PROCESS after gnutls has established TLS encryption." + ;; Retrieve complete lines. + (let ((buffer (rudel-process-object process :buffer))) + (rudel-assemble-line-fragments data buffer) + (rudel-set-process-object process buffer :buffer)) + + (let ((client-data) + (old-filter (rudel-process-object process :old-filter))) + + ;; Assemble lines that were not generated by gnutls. + (rudel-loop-lines data line + (unless (string-match-p "- Peer has closed the GNUTLS connection" line) + (setq client-data (concat client-data line "\n")))) + + ;; When there are any lines not generated by gnutls, pass those to + ;; the old filter function. + (when client-data + (funcall old-filter process client-data))) + ) + +(provide 'rudel-tls) +;;; rudel-tls.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-transport.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-transport.el.svn-base new file mode 100644 index 0000000..8f0b21d --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-transport.el.svn-base @@ -0,0 +1,72 @@ +;;; rudel-transport.el --- Rudel transport interface and backend +;; +;; Copyright (C) 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: Rudel, backend, transport +;; X-RCS: $Id:$ +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file contains the interface for Rudel transport backends. + + +;;; History: +;; +;; 0.1 - Initial revision + + +;;; Code: +;; + +(require 'eieio) + +(require 'rudel-backend) + + +;;; Class rudel-transport +;; + +(defclass rudel-transport () + () + "Interface for transport objects.") + +(defgeneric rudel-transport-send ((this rudel-transport) data) + "Send DATA through THIS transport object.") + +(defgeneric rudel-transport-set-handler ((this rudel-transport) + handler) + "Install HANDLER as dispatcher for messages received by THIS.") + + +;;; Class rudel-transport-backend +;; + +(defclass rudel-transport-backend (rudel-backend) + () + "Interface implemented by transport backends." + :abstract t) + +(defgeneric rudel-make-connection ((this rudel-transport-backend) info) + "Create a transport object according to INFO.") + +(defgeneric rudel-wait-for-connections ((this rudel-transport-backend) + info) + "Create a transport object according to INFO.") + +(provide 'rudel-transport) +;;; rudel-transport.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel-util.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel-util.el.svn-base new file mode 100644 index 0000000..12a967c --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel-util.el.svn-base @@ -0,0 +1,261 @@ +;;; rudel-util.el --- Miscellaneous functions for Rudel +;; +;; Copyright (C) 2008, 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: rudel, miscellaneous, util +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with Rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; This file contains miscellaneous functions for Rudel. + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(eval-when-compile + (require 'cl)) + +(require 'eieio) + +(require 'rudel-errors) + + +;;; Errors +;; + +;; rudel-dispatch-error + +(intern "rudel-dispatch-error") + +(put 'rudel-dispatch-error 'error-conditions + '(error + rudel-error rudel-dispatch-error)) + +(put 'rudel-dispatch-error 'error-message + "Could not dispatch message to handler") + + +;;; Class rudel-hook-object +;; + +(defclass rudel-hook-object () + () + "Mixin for classes that offer one or more hooks for each of +their objects. + +This idiom is usually called something like signal/slot or +event/subscription, but for Emacs, the notion of hooks seems more +appropriate." + :abstract t) + +(defmethod object-add-hook ((this rudel-hook-object) + hook function &optional append) + "Add FUNCTION to HOOK for THIS. +If APPEND is non-nil FUNCTION becomes the last element in the +list of hooks." + (let ((value (slot-value this hook))) + (unless (member function value) + (set-slot-value this hook + (if append (append value (list function)) + (cons function value))))) + ) + +(defmethod object-remove-hook ((this rudel-hook-object) + hook function) + "Remove FUNCTION from HOOK for THIS." + (set-slot-value this hook + (remove function (slot-value this hook)))) + +(defmethod object-run-hook-with-args ((this rudel-hook-object) + hook &rest arguments) + "Run HOOK of THIS with arguments ARGUMENTS." + (let ((hook (slot-value this hook))) + (apply #'run-hook-with-args 'hook this arguments))) + + +;;; Class rudel-socket-owner +;; + +(defclass rudel-socket-owner () + ((socket :initarg :socket + :type process + :documentation + "The process object representing the socket through +which the communication happens.")) + "Class rudel-socket-owner ") + +(defmethod initialize-instance :after ((this rudel-socket-owner) + &rest slots) + "Attach THIS to as process object of our socket." + ;; Attach to our socket. + (with-slots (socket) this + (rudel-set-process-object socket this)) + ) + +(defmethod rudel-disconnect ((this rudel-socket-owner)) + "Disconnect the network connection owned by THIS." + (with-slots (socket) this + (delete-process socket))) + +(defmethod rudel-state-change ((this rudel-socket-owner) state message) + "Called when the state of THIS changes to STATE. +MESSAGE is the message emitted when the state transition +occurred." + (with-slots (socket) this + (case state + ;; Nothing to do here. + (run + nil) + + ;; Dispatch events which indicate the termination of the + ;; connection to `rudel-close'. + ((closed failed exit) + (rudel-close this)))) + ) + +(defmethod rudel-close ((this rudel-socket-owner)) + "Called when the connection associated to THIS is closed.") + + +;;; Networking helper functions and macros +;; + +(defun rudel-process-object (process &optional key) + "Return the object attached to PROCESS using identifier KEY." + (unless key + (setq key :object)) + (get (intern (process-name process)) key)) + +(defun rudel-set-process-object (process object &optional key) + "Set object attached to PROCESS using identifier KEY to OBJECT." + (unless key + (setq key :object)) + (put (intern (process-name process)) key object)) + +(defun rudel-filter-dispatch (process data) + "Call `rudel-receive' method of object attached to PROCESS with DATA." + (let ((object (rudel-process-object process))) + (rudel-receive object data))) + +(defun rudel-sentinel-dispatch (process message) + "Call `rudel-state-change' method of the object attached to PROCESS with state and MESSAGE." + (let ((object (rudel-process-object process)) + (state (process-status process))) + (rudel-state-change object state message))) + + +;;; Fragmentation and assembling functions. +;; + +(defmacro rudel-assemble-line-fragments (data storage) + "Find an return complete lines in DATA, store excess data in STORAGE. +If STORAGE is non-nil when calling, consider content as leftover +data from last and concatenate with DATA before processing." + (declare (debug (form form))) + (let ((index (make-symbol "index"))) + `(progn + ;; If there are stored fragments, append them to the new data. + (when ,storage + (setq ,data (concat ,storage ,data)) + (setq ,storage nil)) + ;; Try to find a line break in the augmented data. + (let ((,index (position ?\n ,data :from-end t))) + (unless (and ,index (eq ,index (- (length ,data) 1))) + (setq ,storage (if ,index + (substring ,data (+ ,index 1)) + ,data)) + (setq ,data (when ,index + (substring ,data 0 (+ ,index 1)))))) + ,data)) + ) + +(defmacro rudel-loop-lines (data var &rest forms) + "Execute FROMS with VAR subsequently bound to all lines in DATA." + (declare (indent 2) + (debug (form symbolp &rest form))) + (let ((lines (make-symbol "lines"))) + `(when ,data + (let ((,lines (split-string ,data "\n" t))) + (dolist (,var ,lines) + (progn ,@forms))))) + ) + +(defmacro rudel-loop-chunks (data var size &rest forms) + "Execute FROMS in a loop with VAR bound to chunks of DATA of SIZE. +Unless (zerop (mod (length data) size) 0) the final chunk is +truncated. The expression SIZE is evaluated in each loop unless +it is a number." + (declare (indent 3) + (debug (form symbolp numberp &rest form))) + ;; If we got a constant number as SIZE, we can check right away. + (when (and (numberp size) (<= size 0)) + (error "Size should be positive")) + + (let ((rest (make-symbol "rest")) + (amount (make-symbol "amount")) + ;; If SIZE has to be evaluated, we have to check at runtime. + (check (unless (numberp size) + `((when (<= ,size 0) + (error "Size should be positive")))))) + `(progn + ,@check + (let ((,rest ,data) + (,var) + (,amount)) + (while (not (string= ,rest "")) + (setq ,amount (min (length ,rest) ,size) + ,var (substring ,rest 0 ,amount) + ,rest (substring ,rest ,amount)) + (progn ,@forms))))) + ) + + +;;; Miscellaneous functions +;; + +(defun rudel-dispatch (object prefix name arguments) + "Call method (concat PREFIX NAME) of OBJECT with ARGUMENTS. +If no such method can be found, the condition +rudel-dispatch-error is signalled." + ;; Construct a matching symbol. + (let* ((method (intern-soft (concat prefix name)))) + ;; If we found a suitable method, run it; Otherwise signal. + (unless method + (signal 'rudel-dispatch-error 'method-symbol-unbound)) + (condition-case error + ;; Try to call METHOD. This can still fail when METHOD is not + ;; defined for the class of OBJECT. + (apply method object arguments) + ;; Only handle a condition 'no-method-definition' that refers to + ;; METHOD, otherwise continue unwinding. + (no-method-definition + (if (eq method (cadr error)) + (signal 'rudel-dispatch-error 'no-method-for-object) + (signal (car error) (cdr error)))))) + ) + +(provide 'rudel-util) +;;; rudel-util.el ends here diff --git a/emacs.d/lisp/rudel/.svn/text-base/rudel.el.svn-base b/emacs.d/lisp/rudel/.svn/text-base/rudel.el.svn-base new file mode 100644 index 0000000..88603fa --- /dev/null +++ b/emacs.d/lisp/rudel/.svn/text-base/rudel.el.svn-base @@ -0,0 +1,1012 @@ +;;; rudel.el --- A collaborative editing framework for Emacs +;; +;; Copyright (C) 2008, 2009 Jan Moringen +;; +;; Author: Jan Moringen <scymtym@users.sourceforge.net> +;; Keywords: rudel, collaboration +;; URL: http://rudel.sourceforge.net/ +;; X-RCS: $Id:$ +;; +;; This file is part of Rudel. +;; +;; Rudel is free software: you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; Rudel is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with rudel. If not, see <http://www.gnu.org/licenses>. + + +;;; Commentary: +;; +;; Rudel is a framework for collaborative editing in Emacs. Its +;; architecture allows communication with arbitrary collaborative +;; editors. + + +;;; History: +;; +;; 0.1 - Initial revision. + + +;;; Code: +;; + +(eval-when-compile + (require 'cl)) + +(require 'eieio) +(require 'eieio-base) + +(require 'eieio-speedbar) ;; TODO required for now + +(require 'rudel-util) +(require 'rudel-backend) +(require 'rudel-session-initiation) +(require 'rudel-operations) +(require 'rudel-operators) +(require 'rudel-overlay) +(require 'rudel-hooks) +(require 'rudel-interactive) ;; for `rudel-read-backend', + ;; `rudel-read-document', + ;; `rudel-read-session' +(require 'rudel-icons) +(require 'rudel-compat) ;; for `read-color' replacement + + +;;; Global variables +;; + +(defconst rudel-version '(0 3) + "Version of the Rudel framework.") + +(defvar rudel-current-session nil + "Global object representing the current Rudel session. +nil if there is no active session.") + +(defvar rudel-buffer-document nil + "Buffer-local variable which holds the Rudel document associated with the buffer.") +(make-variable-buffer-local 'rudel-buffer-document) +(put 'rudel-buffer-document 'permanent-local t) + +(defvar rudel-buffer-change-workaround-data nil + "Buffer-local variable which holds change data that could not be accessed otherwise. +It would be nice to find another way to do this.") +(make-variable-buffer-local 'rudel-buffer-change-workaround-data) +(put 'rudel-buffer-change-workaround-data 'permanent-local t) + + +;;; Customization +;; + +(defgroup rudel nil + "Rudel collaborative editing framework." + :group 'applications) + +(defcustom rudel-allocate-buffer-function + 'rudel-allocate-buffer-clear-existing + "A function used to find or create buffers to associate to documents. +The function is called with the document name as the sole +argument and has to return a buffer object which will be attached +to the document in question." + :group 'rudel + :type '(choice (const :tag "Clear content of existing buffer" + rudel-allocate-buffer-clear-existing ) + (const :tag "Create a new uniquely named buffer" + rudel-allocate-buffer-make-unique ) + (function :tag "Other function")) + :require 'rudel-interactive) + +(defcustom rudel-default-username (user-login-name) + "*" + :group 'rudel + :type '(string)) + + +;;; Class rudel-session +;; + +(defclass rudel-session (rudel-hook-object) + ((backend :initarg :backend + :type rudel-backend-child + :documentation + "The backend used by this session.") + (users :initarg :users + :type list + :initform nil + :documentation + "The list of users participating in this +session.") + (documents :initarg :documents + :type list + :initform nil + :documentation + "This list of documents available in +this session.") + ;; Hooks + (end-hook :initarg :end-hook + :type list + :initform nil + :documentation + "") + (add-user-hook :initarg :add-user-hook + :type list + :initform nil + :documentation + "This hook is run when a user gets added +to the session. +The arguments are the session and the user object.") + (remove-user-hook :initarg :remove-user-hook + :type list + :initform nil + :documentation + "This hook is run when a user gets +removed from the session. +The arguments are the session and the user object.") + (add-document-hook :initarg :add-document-hook + :type list + :initform nil + :documentation + "This hook is run when a document gets +added to the session. +The arguments are the session and the document object.") + (remove-document-hook :initarg :remove-document-hook + :type list + :initform nil + :documentation + "This hook is run when a document gets +removed from the session. +The arguments are the session and the document object.")) + "This class serves as a base class for rudel-client-session and +rudel-server-session. Consequently, it consists of slots common +to client and server sessions." + :abstract t) + +(defmethod rudel-end ((this rudel-session)) + "Terminate THIS session performing all necessary cleanup." + ;; Run the hook. + (object-run-hook-with-args this 'end-hook)) + +(defmethod rudel-add-user ((this rudel-session) user) + "Add USER to the user list of THIS session. + +Runs object hook (see `rudel-hook-object') `add-user-hook' with +arguments THIS and USER." + ;; Add USER to list. + (object-add-to-list this :users user) + + ;; Run the hook. + (object-run-hook-with-args this 'add-user-hook user)) + +(defmethod rudel-remove-user ((this rudel-session) user) + "Remove USER from the user list of THIS session. + +Runs object hook (see `rudel-hook-object') `remove-user-hook' +with arguments THIS and USER." + ;; Remove USER from list. + (object-remove-from-list this :users user) + + ;; Run the hook. + (object-run-hook-with-args this 'remove-user-hook user)) + +(defmethod rudel-find-user ((this rudel-session) + which &optional test key) + "Find user WHICH in the user list. +WHICH is compared to the result of KEY using TEST." + (unless test + (setq test #'string=)) + (unless key + (setq key #'object-name-string)) + (with-slots (users) this + (find which users :key key :test test)) + ) + +(defmethod rudel-add-document ((this rudel-session) document) + "" + (unless (slot-boundp document :session) + (oset document :session this)) + + ;; Add DOCUMENT to the list of documents in THIS session. + (object-add-to-list this :documents document) + + ;; Run the hook. + (object-run-hook-with-args this 'add-document-hook document)) + +(defmethod rudel-remove-document ((this rudel-session) document) + "Remove DOCUMENT from THIS session, detaching it if necessary." + ;; Detach document from its buffer when necessary. + (when (rudel-attached-p document) + (rudel-detach-from-buffer document)) + + ;; Remove DOCUMENT from the list of documents in THIS session. + (object-remove-from-list this :documents document) + + ;; Run the hook. + (object-run-hook-with-args this 'remove-document-hook document)) + +(defmethod rudel-find-document ((this rudel-session) + which &optional test key) + "Find document WHICH in the document list. +WHICH is compared to the result of KEY using TEST." + (unless test + (setq test #'string=)) + (unless key + (setq key #'object-name-string)) + (with-slots (documents) this + (find which documents :key key :test test)) + ) + +(defmethod rudel-unsubscribed-documents ((this rudel-session)) + "" + (unless (slot-boundp this :self) + (error "Cannot find unsubscribed documents unless slot self is bound")) + (with-slots (documents self) this + (remove-if + (lambda (document) + (with-slots (subscribed) document + (memq self subscribed))) + documents)) + ) + + +;;; Class rudel-client-session +;; +(defclass rudel-client-session (rudel-session) + ((connection :initarg :connection + :type (or null rudel-connection-child) + :initform nil + :documentation + "The connection used for communication by this +session.") + (self :initarg :self + :type rudel-user-child + :documentation + "Points into USERS to the user object representing +the local user")) + "Objects represent a collaborative editing session from a +client perspective.") + +(defmethod rudel-end ((this rudel-client-session)) + ;; Clean everything up + (with-slots (connection users documents) this + ;; Detach all documents from their buffers + (mapc #'rudel-detach-from-buffer documents) + + ;; Terminate the connection + (when connection + (condition-case nil + (rudel-disconnect connection) + (error nil)))) + + ;; + (when (next-method-p) + (call-next-method)) + ) + + +;;; Class rudel-server-session +;; + +(defclass rudel-server-session (rudel-session) + () + "Class rudel-server-session " + :abstract t) + + +;;; Class rudel-connection +;; + +(defclass rudel-connection () + ((session :initarg :session + :type rudel-session-child + :documentation + "")) + "This abstract class defines the interface implementations of +client protocols have to obey." + :abstract t) + +(defgeneric rudel-disconnect ((this rudel-connection)) + "Close the connection.") + +(defgeneric rudel-change-color- ((this rudel-connection) color) ;; TODO name + "") + +(defgeneric rudel-publish ((this rudel-connection) document) + "") + +(defgeneric rudel-subscribe-to ((this rudel-connection) document) + "") + +(defgeneric rudel-unsubscribe-from ((this rudel-connection) document) ; TODO name should be rudel-unsubscribe + "") + +(defgeneric rudel-local-insert ((this rudel-connection)) + "") + +(defgeneric rudel-local-delete ((this rudel-connection)) + "") + +(defgeneric rudel-remote-insert ((this rudel-connection)) + "") + +(defgeneric rudel-remote-delete ((this rudel-connection)) + "") + + +;;; Class rudel-user +;; + +(defclass rudel-user (eieio-named + eieio-speedbar-file-button + rudel-hook-object) + ((color :initarg :color + :accessor rudel-color + :documentation + "Color used to indicate ownership or authorship +by the user. Examples includes text written by the user or the +user name itself.") + (change-hook :initarg :change-hook + :type list + :initform nil + :documentation + "This hook is run when this user object +changes.")) + "Objects of this class represent users participating in +collaborative editing session. Note that a participating user +does not have to be connected to the session at any given time." + :abstract t) + +(defmethod rudel-display-string ((this rudel-user) + &optional use-images align) + "Return a textual representation of THIS for user interface stuff." + (with-slots ((name :object-name) color) this + (propertize + (concat + (when use-images + (propertize "*" 'display rudel-icon-person)) + name) + 'face (list :background color))) + ) + + +;;; Class rudel-document +;; + +(defclass rudel-document (eieio-named + eieio-speedbar-file-button + rudel-hook-object) + ((session :initarg :session + :type rudel-session + :documentation + "") + (buffer :initarg :buffer + :type (or null buffer) + :initform nil + :documentation + "") + (subscribed :initarg :subscribed + :type list + :initform nil + :documentation + "") + ;; Hooks + (subscribe-hook :initarg :subscribe-hook + :type list + :initform nil + :documentation + "This hook is run when a user subscribes to +this document object.") + (unsubscribe-hook :initarg :unsubscribe-hook + :type list + :initform nil + :documentation + "This hook is run when a user unsubscribes +from this document object.") + (attach-hook :initarg :attach-hook + :type list + :initform nil + :documentation + "This hook is run when a buffer is attached +to this document object.") + (detach-hook :initarg :detach-hook + :type list + :initform nil + :documentation + "This hook is run when the attached buffer +is detached from this document object.")) + "This class represents a document, which participants of a +collaborative editing session can subscribe to." + :abstract t) + +(defmethod rudel-unique-name ((this rudel-document)) + "Returns a suggested name for the buffer attached to THIS document." + (object-name-string this)) + +(defmethod rudel-suggested-buffer-name ((this rudel-document)) + "Returns a suggested name for the buffer attached to THIS document." + (rudel-unique-name this)) + +(defmethod rudel-attached-p ((this rudel-document)) + (with-slots (buffer) this + buffer)) + +(defmethod rudel-attach-to-buffer ((this rudel-document) buffer) + "Attach THIS document to BUFFER" + (with-slots ((doc-buffer :buffer)) this + ;; Set buffer slot of THIS to BUFFER and associated THIS with + ;; BUFFER. + (setq doc-buffer buffer) + (rudel-set-buffer-document this buffer) + + (with-current-buffer doc-buffer + ;; Add the handler function for buffer changes to the buffer's + ;; change hook. + (add-hook 'after-change-functions + #'rudel-handle-buffer-change + nil t) + + ;; Store change data before the change a done. This is necessary + ;; because the number of bytes (not characters) cannot otherwise + ;; be recovered after a deletion. + (add-hook 'before-change-functions + #'rudel-buffer-change-workaround + nil t) + + ;; Add a handler to the kill-buffer hook to unsubscribe from the + ;; document when the buffer gets killed. + (add-hook 'kill-buffer-hook + #'rudel-unpublish-buffer + nil t) + + ;; + (add-hook 'change-major-mode-hook + #'rudel-handle-major-mode-change + nil t)) + + ;; Run the hook. + (object-run-hook-with-args this 'attach-hook doc-buffer)) + ) + +(defmethod rudel-detach-from-buffer ((this rudel-document)) + "Detach document THIS from its buffer. +Do nothing, if THIS is not attached to any buffer." + (with-slots (buffer) this + (let ((buffer-save buffer)) + + ;; Only try to detach from BUFFER, if it is non-nil. BUFFER can + ;; be nil, if the user did not subscribe to the document, or + ;; unsubscribed after subscribing. + (when buffer + + (with-current-buffer buffer + ;; Remove our handler function from the kill-buffer hook. + (remove-hook 'kill-buffer-hook + #'rudel-unpublish-buffer + t) + + ;; Remove our handler function from the after-change hook. + (remove-hook 'after-change-functions + #'rudel-handle-buffer-change + t) + + ;; Remove our handler function from the before-change hook. + (remove-hook 'before-change-functions + #'rudel-buffer-change-workaround + t) + + ;; Remove all overlays. + (rudel-overlays-remove-all) + + ;; Remove the major mode change handler. + (remove-hook 'change-major-mode-hook + #'rudel-handle-major-mode-change + t)) + + ;; Unset buffer slot of THIS and delete association of THIS with + ;; BUFFER. + (rudel-set-buffer-document nil buffer) + (setq buffer nil)) + + ;; Run the hook. + (object-run-hook-with-args this 'detach-hook buffer-save))) + ) + +(defmethod rudel-add-user ((this rudel-document) user) + "Add USER to the list of subscribed users of THIS. + +Runs object hook (see `rudel-hook-object') `subscribe-hook' with +arguments THIS and USER." + ;; Add USER to list. + (object-add-to-list this :subscribed user) + + ;; Run the hook. + (object-run-hook-with-args this 'subscribe-hook user)) + +(defmethod rudel-remove-user ((this rudel-document) user) + "Remove USER from the list of subscribed users of THIS. + +Runs object hook (see `rudel-hook-object') `unsubscribe-hook' +with arguments THIS and USER." + ;; Remove USER from list. + (object-remove-from-list document :subscribed user) + + ;; Run the hook. + (object-run-hook-with-args this 'unsubscribe-hook user)) + +(defmethod rudel-insert ((this rudel-document) position data) + "Insert DATA at POSITION into the buffer attached to THIS. +When POSITION is nil `point-max' is used to determine the +insertion position. +Modification hooks are disabled during the insertion." + (with-slots (buffer) this + (save-excursion + (set-buffer buffer) + + (unless position + (setq position (- (point-max) 1))) + + (let ((inhibit-modification-hooks t)) + (goto-char (+ position 1)) + (insert data)))) + ) + +(defmethod rudel-delete ((this rudel-document) position length) + "Delete a region of LENGTH character at POSITION from the buffer attached to THIS. +Modification hooks are disabled during the insertion." + (with-slots (buffer) this + (save-excursion + (set-buffer buffer) + + (let ((inhibit-modification-hooks t)) + (delete-region (+ position 1) (+ position length 1))))) + ) + +(defmethod rudel-local-operation ((this rudel-document) operation) + "Apply the local operation OPERATION to THIS." + (with-slots (session buffer) this + (with-slots (connection (user :self)) session + (dolist (operators (list + + ;; Update overlays + (rudel-overlay-operators + "overlay-operators" + :document this + :user user) + + ;; Notify connection + (rudel-connection-operators + "connection-operators" + :connection connection + :document this))) + + ;; Apply the operation using each set of operators + (rudel-apply operation operators)))) + ) + +(defmethod rudel-remote-operation ((this rudel-document) user operation) + "Apply the remote operation OPERATION performed by USER to THIS." + (dolist (operators (append + + ;; Update buffer contents + (list (rudel-document-operators + "document-operators" + :document this)) + + ;; Update overlays + (when user + (list (rudel-overlay-operators + "overlay-operators" + :document this + :user user))))) + + ;; Apply the operation using each set of operators + (rudel-apply operation operators)) + ) + +(defmethod rudel-chunks ((this rudel-document)) + "Return a list of text chunks of the associated buffer. +Each element in the chunk is a list structured like this (START +END AUTHOR). START and END are numbers, AUTHOR is of type (or +null rudel-user-child)." + (with-slots (buffer) this + ;; Extract buffer string and a list of chunks partitioning the + ;; string according to the respective author (or nil). + (with-current-buffer buffer + (let ((string (buffer-string)) ;; TODO no-properties? + (overlay-chunks (mapcar + (lambda (overlay) + (list (- (overlay-start overlay) 1) + (- (overlay-end overlay) 1) + (rudel-overlay-user overlay))) + (sort* (rudel-author-overlays) + '< :key 'overlay-start))) + (last) + (augmented-chunks)) + + ;; Iterate through the list of chunks to find gaps between + ;; chunks (also before the first) and insert entries with + ;; author nil accordingly. + (dolist (chunk overlay-chunks) + (when (or (and (not last) + (> (nth 0 chunk) 0)) + (and last + (/= (nth 1 last) + (nth 0 chunk)))) + (push (list (if last (nth 1 last) 0) + (nth 0 chunk) + nil) + augmented-chunks)) + (push chunk augmented-chunks) + (setq last chunk)) + + ;; If there is text after the last chunk, create another one + ;; with author nil. If there were no chunks at all, this chunk + ;; can also cover the whole buffer string. + (when (or (and (not last) + (/= (length string) 0)) + (and last + (/= (nth 1 last) (length string)))) + (push (list (if last (nth 1 last) 0) + (length string) + nil) + augmented-chunks)) + + ;; Sort chunks according to the start position. + (sort* augmented-chunks '< :key 'car)))) + ) + + +;;; Buffer-related functions +;; + +(defun rudel-buffer-has-document-p (&optional buffer) + "Return non-nil if a document object is attached to BUFFER. +If BUFFER is nil, use the current buffer." + (unless buffer + (setq buffer (current-buffer))) + + (buffer-local-value 'rudel-buffer-document buffer)) + +(defun rudel-buffer-document (&optional buffer) + "Return the document object attached to BUFFER. +If BUFFER is nil, use the current buffer." + (unless buffer + (setq buffer (current-buffer))) + + (buffer-local-value 'rudel-buffer-document buffer)) + +(defun rudel-set-buffer-document (document &optional buffer) + "Associate BUFFER to DOCUMENT. +If DOCUMENT is nil, make it not associated to any buffer. +If BUFFER is nil, use the current buffer." + (unless buffer + (setq buffer (current-buffer))) + + (with-current-buffer buffer + (setq rudel-buffer-document document))) + +(defun rudel-handle-buffer-change (from to length) + "Handle buffer change at range FROM to TO with length LENGTH by relaying them to the document object of the buffer. +See after-change-functions for more information." + (when (rudel-buffer-has-document-p) + (let ((document (rudel-buffer-document)) + (text)) ; TODO with-rudel-buffer-document? + (cond + ;; The change was an insert + ((and (/= from to) + (zerop length)) + (with-slots (buffer) document + (with-current-buffer buffer + (setq text (buffer-substring-no-properties from to))) + (rudel-local-operation document + (rudel-insert-op + "insert" + :from (- from 1) + :data text)))) + + ;; The change was a delete + ((and (= from to) + (not (zerop length))) + (rudel-local-operation document + (rudel-delete-op + "delete" + :from (- from 1) + :length length))) + + ;; The operation was neither an insert nor a delete. This seems + ;; to mean that the region has changed arbitrarily. The only + ;; option we have is sending a delete and corresponding insert + ;; message that emulate the change. + (t + (with-slots (buffer) document + (with-current-buffer buffer + (setq text (buffer-substring-no-properties from to))) + (rudel-local-operation document + (rudel-delete-op + "delete" + :from (- from 1) + :length length)) + (rudel-local-operation document + (rudel-insert-op + "insert" + :from (- from 1) + :data text))))))) + ) + +(defun rudel-buffer-change-workaround (from to) + (when (/= from to) + (setq rudel-buffer-change-workaround-data + (list from to + (buffer-substring-no-properties from to))))) + + +;;; Protection against major mode changes +;; + +(defvar rudel-mode-changed-buffers nil + "List of buffers that may need to be repaired after a major + mode change.") + +(defun rudel-handle-major-mode-change () + "Store the current buffer to repair damage done by major mode change. + +Note: The way this works is inspired by mode-local.el by David +Ponce and Eric M. Ludlam." + ;; Store the buffer for later repair. + (add-to-list 'rudel-mode-changed-buffers (current-buffer)) + + ;; Schedule `rudel-after-major-mode-change' to run after the + ;; command, that caused the major mode change. + (add-hook 'post-command-hook + #'rudel-after-major-mode-change) + ) + +(defun rudel-after-major-mode-change () + "Repair damage done by major mode changes. +As a function in `post-command-hook', this is run after there was +a `major-mode' change. + +Note: The way this works is inspired by mode-local.el by David +Ponce and Eric M. Ludlam." + ;; Remove this function from `post-command-hook'. + (remove-hook 'post-command-hook + #'rudel-after-major-mode-change) + + ;; Repair all buffers affected by the major mode change. + (dolist (buffer rudel-mode-changed-buffers) + (let ((document (buffer-local-value 'rudel-buffer-document + buffer))) + (rudel-attach-to-buffer document buffer))) + ) + + +;;; Interactive functions +;; + +;;;###autoload +(defun rudel-join-session (info) + "Join the collaborative editing session described by INFO. +INFO is a property list that describes the collaborative editing +session in terms of properties like :host, :port +and :encryption. The particular properties and their respective +meanings depend on the used backend. + +When called interactively, all data required to join a session +will be prompted for." + (interactive + ;; Try the discover method of session initiation backends to find + ;; available sessions. + (list + (let ((info) + (session-initiation-backend)) + (while (not info) + (message "Discovering Sessions ...") + (let* ((sessions (rudel-session-initiation-discover + session-initiation-backend)) + (maybe-info (if (= (length sessions) 1) + (car sessions) + (rudel-read-session + sessions "Choose Session: " 'object)))) + (if (rudel-backend-cons-p maybe-info) + (setq session-initiation-backend (car maybe-info)) + (setq info maybe-info)))) + info))) + + ;; First, create the session object. + (let* ((backend (cdr (plist-get info :backend))) + (session (rudel-client-session + (plist-get info :name) + :backend backend)) + (connection)) + ;; Give the backend a chance to collect remaining connect + ;; info. For session initiation methods like Zeroconf, we have the + ;; _connection_ info, but are still missing the username and + ;; stuff. + (setq info (rudel-ask-connect-info backend info)) + + ;; Add the session object to the connect information. + (plist-put info :session session) + + ;; Ask BACKEND to connect using INFO. Do not catch errors since + ;; the error messages are probably the best feedback we can give. + (setq connection (rudel-connect backend info)) + + ;; Set the connection slot of the session object and store it + ;; globally. + (oset session :connection connection) + (setq rudel-current-session session) + + ;; Reset the global session variable when the session ends. + (object-add-hook session 'end-hook + (lambda (session) + (setq rudel-current-session nil))) + + ;; Run the hook. + (run-hook-with-args 'rudel-session-start-hook session)) + ) + +;;;###autoload +(defun rudel-host-session () + "Host a collaborative editing session. +All data required to host a session will be prompted for +interactively." + (interactive) + ;; If necessary, ask the user for the backend we should use. + (let* ((backend (cdr (rudel-backend-choose + 'protocol + (lambda (backend) + (rudel-capable-of-p backend 'host))))) + (info (rudel-ask-host-info backend)) + (server)) + + ;; Try to create the server + (condition-case error-data + (setq server (rudel-host backend info)) + ('error + (error "Could not host session using backend `%s' with %s: %s" + (object-name-string backend) + info + (car error-data)))) + server)) + +;;;###autoload +(defun rudel-end-session () + "End the current collaborative editing session." + (interactive) + (unless rudel-current-session + (error "No active Rudel session")) + + ;; Actually end the session. + (rudel-end rudel-current-session) + ) + +;;;###autoload +(defun rudel-change-color () + "Change the color associated with the local user. +Not all backends support this operation." + (interactive) + ;; Make sure we have a session. + (unless rudel-current-session + (error "No active Rudel session")) + + (with-slots (backend connection self) rudel-current-session + ;; Make sure the backend can change colors. + (unless (rudel-capable-of-p backend 'change-color) + (error "Backend `%s' cannot change colors" + (object-name-string backend))) + + (with-slots ((name :object-name) color) self + ;; Ask the user for a new color. + (setq color (read-color "New Color: " t)) + + ;; Tell the connection to announce the change and change it in + ;; our user object. + (rudel-change-color- connection color) + + ;; Run the change hook. + (object-run-hook-with-args self 'change-hook) + + ;; Update overlay color. + (rudel-overlay-set-face-attributes + (rudel-overlay-make-face-symbol 'author name) + color))) + ) + +;;;###autoload +(defun rudel-subscribe (document) + "Subscribe to DOCUMENT offered by a peer in a collaborative editing session. +When called interactively, DOCUMENT is prompted for interactively." + (interactive + (list (progn + ;; We have to retrieve the document list from an active + ;; session. + (unless rudel-current-session + (error "No active Rudel session")) + ;; Select unsubscribed documents. + (let ((documents (rudel-unsubscribed-documents + rudel-current-session))) + ;; Already subscribed to all documents. This is an error. + (when (null documents) + (error "No unsubscribed documents")) + ;; Read an unsubscribed document. + (rudel-read-document documents nil 'object))))) + + ;; Make sure we have a session. + (unless rudel-current-session + (error "No active Rudel session")) + + ;; Create a new buffer and attach the document to it. + (let* ((name (rudel-suggested-buffer-name document)) + (buffer (funcall rudel-allocate-buffer-function name))) + (rudel-attach-to-buffer document buffer) + + (let ((connection (oref (oref document :session) :connection))) + (rudel-subscribe-to connection document)) + + ;; Show the new buffer. + (set-window-buffer nil buffer)) + ) + +;;;###autoload +(defun rudel-publish-buffer (&optional buffer) + "Make the BUFFER available for subscription to peers in a collaborative editing session. +If BUFFER is nil, the current buffer is used." + (interactive (list nil)) + + ;; Make sure we have a session. + (unless rudel-current-session + (error "No active Rudel session")) + + (unless buffer + (setq buffer (current-buffer))) + + (with-current-buffer buffer + (when (rudel-buffer-has-document-p) + (error "Buffer already published or subscribed"))) ; TODO keep this? + + ;; + (with-slots (backend connection self) rudel-current-session + (let ((document (rudel-make-document backend + (buffer-name buffer) + rudel-current-session))) + (rudel-add-document rudel-current-session document) + + (rudel-attach-to-buffer document buffer) + (object-add-to-list document :subscribed self) + + (rudel-publish connection document))) + ) + +;;;###autoload +(defun rudel-unpublish-buffer (&optional buffer) + "Deny peers access to BUFFER in a collaborative editing session. +If BUFFER is nil, the current is used." + (interactive) + + ;; Make sure we have a session. + (unless rudel-current-session + (error "No active Rudel session")) + + (unless buffer + (setq buffer (current-buffer))) + + (with-current-buffer buffer + (unless (rudel-buffer-has-document-p) + (error "Buffer is not published"))) + + ;; + (with-slots (connection) rudel-current-session + (let ((document (rudel-buffer-document buffer))) + (rudel-detach-from-buffer document) + + (rudel-unsubscribe-from connection document))) + ) + +(provide 'rudel) +;;; rudel.el ends here |