(cl:in-package #:cluffer-base)

;;;; This file contains definitions of :BEFORE methods on generic
;;;; functions that may take an attached CURSOR as one of the
;;;; arguments.  The :BEFORE method checks that the cursor is attached
;;;; and if not, signals an error of type CURSOR-DETACHED.

;;; NAME is the name of a generic function to which the method should
;;; be added.  ARGUMENTS is a lambda list that may contain lambda-list
;;; keywords.  A parameter named CURSOR is treated specially in that a
;;; specializer is added to it in the method lambda list generated by
;;; this macro.
(defmacro check-cursor-attached (name arguments)
  (let ((args (substitute '(cursor cluffer:cursor) 'cursor arguments)))
    `(defmethod ,name :before ,args
       (declare (ignore ,@(set-difference (remove 'cursor arguments)
					  lambda-list-keywords)))
       (unless (cluffer:cursor-attached-p cursor)
	 (error 'cluffer:cursor-detached)))))

(check-cursor-attached cluffer:cursor-position (cursor))
(check-cursor-attached (setf cluffer:cursor-position) (position cursor))
(check-cursor-attached cluffer:beginning-of-line-p (cursor))
(check-cursor-attached cluffer:end-of-line-p (cursor))
(check-cursor-attached cluffer:forward-item (cursor))
(check-cursor-attached cluffer:backward-item (cursor))
(check-cursor-attached cluffer:beginning-of-line (cursor))
(check-cursor-attached cluffer:end-of-line (cursor))
(check-cursor-attached cluffer:item-before-cursor (cursor))
(check-cursor-attached cluffer:item-after-cursor (cursor))
(check-cursor-attached cluffer:insert-item (cursor item))
(check-cursor-attached cluffer:delete-item (cursor))
(check-cursor-attached cluffer:erase-item (cursor))
(check-cursor-attached cluffer:beginning-of-buffer-p (cursor))
(check-cursor-attached cluffer:end-of-buffer-p (cursor))
(check-cursor-attached cluffer:split-line (cursor))
(check-cursor-attached cluffer:join-line (cursor))
(check-cursor-attached cluffer:buffer (cursor))
(check-cursor-attached cluffer:line (cursor))
(check-cursor-attached cluffer:items (cursor &key start end))
