diff options
Diffstat (limited to 'emacs.d/lisp/rudel/rudel-operations.el')
-rw-r--r-- | emacs.d/lisp/rudel/rudel-operations.el | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/emacs.d/lisp/rudel/rudel-operations.el b/emacs.d/lisp/rudel/rudel-operations.el new file mode 100644 index 0000000..3637303 --- /dev/null +++ b/emacs.d/lisp/rudel/rudel-operations.el @@ -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 |