Update of /project/climacs/cvsroot/climacs In directory common-lisp.net:/tmp/cvs-serv16638
Modified Files: gui.lisp kill-ring.lisp packages.lisp Log Message: kill ring updated and functioning protocol. Enjoy C-k and M-y like you never have in climacs before:) Date: Fri Jan 7 14:07:46 2005 Author: ejohnson
Index: climacs/gui.lisp diff -u climacs/gui.lisp:1.49 climacs/gui.lisp:1.50 --- climacs/gui.lisp:1.49 Fri Jan 7 08:26:24 2005 +++ climacs/gui.lisp Fri Jan 7 14:07:45 2005 @@ -128,7 +128,7 @@ (setf table (command-menu-item-value item))) finally (return item)))
-(defvar *kill-ring* (initialize-kill-ring 7)) +(defvar *kill-ring* (make-instance 'kill-ring :max-size 7)) (defparameter *current-gesture* nil)
(defun meta-digit (gesture) @@ -347,7 +347,22 @@ (open-line (point (win *application-frame*))))
(define-named-command com-kill-line () - (kill-line (point (win *application-frame*)))) + (let* ((payne (win *application-frame*)) + (pnt (point payne))) + (if (and (beginning-of-buffer-p pnt) + (end-of-line-p pnt)) + NIL + (let ((mrk (offset pnt))) + (end-of-line pnt) + (if (end-of-buffer-p pnt) + nil + (forward-object pnt)) + (if (eq (previous-command payne) 'com-kill-line) + (kill-ring-concatenating-push *kill-ring* + (region-to-sequence mrk pnt)) + (kill-ring-standard-push *kill-ring* + (region-to-sequence mrk pnt))) + (delete-region mrk pnt)))))
(define-named-command com-forward-word () (forward-word (point (win *application-frame*)))) @@ -552,25 +567,23 @@ ;; Kill ring commands
;; Copies an element from a kill-ring to a buffer at the given offset -(define-named-command com-copy-in () - (insert-sequence (point (win *application-frame*)) (kr-copy *kill-ring*))) - -;; Cuts an element from a kill-ring out to a buffer at a given offset -(define-named-command com-cut-in () - (insert-sequence (point (win *application-frame*)) (kr-pop *kill-ring*))) +(define-named-command com-yank () + (insert-sequence (point (win *application-frame*)) (kill-ring-yank *kill-ring*)))
;; Destructively cut a given buffer region into the kill-ring (define-named-command com-cut-out () (with-slots (buffer point mark)(win *application-frame*) - (if (< (offset point) (offset mark)) - ((lambda (b o1 o2) - (kr-push *kill-ring* (buffer-sequence b o1 o2)) - (delete-buffer-range b o1 (- o2 o1))) - buffer (offset point) (offset mark)) - ((lambda (b o1 o2) - (kr-push *kill-ring* (buffer-sequence b o2 o1)) - (delete-buffer-range b o1 (- o2 o1))) - buffer (offset mark) (offset point))))) + (let ((offp (offset point)) + (offm (offset mark))) + (if (< offp offm) + ((lambda (b o1 o2) + (kill-ring-standard-push *kill-ring* (buffer-sequence b o1 o2)) + (delete-buffer-range b o1 (- o2 o1))) + buffer offp offm) + ((lambda (b o1 o2) + (kill-ring-standard-push *kill-ring* (buffer-sequence b o2 o1)) + (delete-buffer-range b o1 (- o2 o1))) + buffer offm offp)))))
;; Non destructively copies in buffer region to the kill ring @@ -579,17 +592,25 @@ (let ((off1 (offset point)) (off2 (offset mark))) (if (< off1 off2) - (kr-push *kill-ring* (buffer-sequence buffer off1 off2)) - (kr-push *kill-ring* (buffer-sequence buffer off2 off1)))))) + (kill-ring-standard-push *kill-ring* (buffer-sequence buffer off1 off2)) + (kill-ring-standard-push *kill-ring* (buffer-sequence buffer off2 off1)))))) +
-;; Needs adjustment to be like emacs M-y -(define-named-command com-kr-rotate () - (kr-rotate *kill-ring* -1)) +(define-named-command com-rotate-yank () + (let* ((payne (win *application-frame*)) + (pnt (point payne)) + (last-yank (kill-ring-yank *kill-ring*))) + (if (eq (previous-command payne) + 'com-rotate-yank) + ((lambda (p ly) + (delete-range p (* -1 (length ly))) + (rotate-yank-position *kill-ring*)) + pnt last-yank)) + (insert-sequence pnt (kill-ring-yank *kill-ring*))))
-;; Not bound to a key yet -(define-named-command com-kr-resize () +(define-named-command com-resize-kill-ring () (let ((size (accept 'integer :prompt "New kill ring size"))) - (kr-resize *kill-ring* size))) + (setf (kill-ring-max-size *kill-ring*) size)))
(define-named-command com-search-forward () (search-forward (point (win *application-frame*)) @@ -666,13 +687,13 @@ (global-set-key '(#\k :control) 'com-kill-line) (global-set-key '(#\t :control) 'com-transpose-objects) (global-set-key '(#\Space :control) 'com-set-mark) -(global-set-key '(#\y :control) 'com-copy-in) +(global-set-key '(#\y :control) 'com-yank) (global-set-key '(#\w :control) 'com-cut-out) (global-set-key '(#\f :meta) 'com-forward-word) (global-set-key '(#\b :meta) 'com-backward-word) (global-set-key '(#\t :meta) 'com-transpose-words) (global-set-key '(#\x :meta) 'com-extended-command) -(global-set-key '(#\y :meta) 'com-kr-rotate) ;currently rotates only +(global-set-key '(#\y :meta) 'com-rotate-yank) (global-set-key '(#\w :meta) 'com-copy-out) (global-set-key '(#\v :control) 'com-page-down) (global-set-key '(#\v :meta) 'com-page-up)
Index: climacs/kill-ring.lisp diff -u climacs/kill-ring.lisp:1.3 climacs/kill-ring.lisp:1.4 --- climacs/kill-ring.lisp:1.3 Thu Dec 30 04:55:14 2004 +++ climacs/kill-ring.lisp Fri Jan 7 14:07:45 2005 @@ -25,70 +25,112 @@ (in-package :climacs-kill-ring)
(defclass kill-ring () - ((max-size :type unsigned-byte - :initarg :max-size - :accessor kr-max-size) - (flexichain :type standard-flexichain - :initarg :flexichain - :accessor kr-flexi)) - (:documentation "Basic flexichain without resizing")) - -(defun initialize-kill-ring (size) - "Construct a kill ring of a given size" - (make-instance 'kill-ring - :max-size size - :flexichain (make-instance 'standard-flexichain))) - - -(defgeneric kr-length (kr) - (:documentation "Returns the length of a kill-ring's flexichain")) - -(defmethod kr-length ((kr kill-ring)) - (nb-elements (kr-flexi kr))) - -(defgeneric kr-resize (kr size) - (:documentation "Resize a kill ring to the value of SIZE")) - -(defmethod kr-resize ((kr kill-ring) size) - (setf (slot-value kr 'max-size) size) - (let ((len (kr-length kr))) + ((max-size :type (integer 5 *) ;5 element minimum from flexichain protocol + :initarg :max-size) + (cursorchain :type standard-cursorchain + :accessor kill-ring-chain + :initform (make-instance 'standard-cursorchain)) + (yankpoint :type left-sticky-flexicursor + :accessor kill-ring-cursor)) + (:documentation "A class for all kill rings")) + +(defmethod initialize-instance :after((kr kill-ring) &rest args) + "Adds in the yankpoint" + (declare (ignore args)) + (with-slots (cursorchain yankpoint) kr + (setf yankpoint (make-instance 'left-sticky-flexicursor :chain cursorchain)))) + +(defgeneric kill-ring-length (kr) + (:documentation "Returns the current length of the kill ring")) + +(defgeneric kill-ring-max-size (kr) + (:documentation "Returns the value of a kill ring's maximum size")) + +(defgeneric (setf kill-ring-max-size) (kr size) + (:documentation "Alters the maximum size of a kill ring, even +if it means dropping elements to do so.")) + +(defgeneric reset-yank-position (kr) + (:documentation "Moves the current yank point back to the start of + of kill ring position")) + +(defgeneric rotate-yank-position (kr &optional times) + (:documentation "Moves the yank point associated with a kill-ring + one or times many positions away from the start + of ring position. If times is greater than the + current length then the cursor will wrap to the + start of ring position and continue rotating.")) + +(defgeneric kill-ring-standard-push (kr vector) + (:documentation "Pushes a vector of objects onto the kill ring creating a new +start of ring position. This function is much like an every- +day lisp push with size considerations. If the length of the +kill ring is greater than the maximum size, then "older" +elements will be removed from the ring until the maximum size +is reached.")) + +(defgeneric kill-ring-concatenating-push (kr vector) + (:documentation "Concatenates the contents of vector onto the end + of the current contents of the top of the kill ring. + If the kill ring is empty the a new entry is pushed.")) + +(defgeneric kill-ring-yank (kr &optional reset) + (:documentation "Returns the vector of objects currently pointed to + by the cursor. If reset is T, a call to + reset-yank-position is called befor the object is + yanked. The default for reset is NIL")) + +(defmethod kill-ring-length ((kr kill-ring)) + (nb-elements (kill-ring-chain kr))) + +(defmethod kill-ring-max-size ((kr kill-ring)) + (with-slots (max-size) kr + max-size)) + +(defmethod (setf kill-ring-max-size) ((kr kill-ring) size) + (unless (typep size 'integer) + (error "Error, ~S, is not an integer value" size)) + (if (< size 5) + (set (slot-value kr 'max-size) 5) + (setf (slot-value kr 'max-size) size)) + (let ((len (kill-ring-length kr))) (if (> len size) (loop for n from 1 to (- len size) - do (pop-end (kr-flexi kr)))))) + do (pop-end (kill-ring-chain kr))))))
-(defgeneric kr-push (kr object) - (:documentation "Push an object onto a kill ring with size considerations")) - -(defmethod kr-push ((kr kill-ring) object) - (let ((flexi (kr-flexi kr))) - (if (>= (kr-length kr)(kr-max-size kr)) +(defmethod reset-yank-position ((kr kill-ring)) + (setf (cursor-pos (kill-ring-cursor kr)) 0) + t) + +(defmethod rotate-yank-position ((kr kill-ring) &optional (times 1)) + (if (> (kill-ring-length kr) 0) + (let* ((curs (kill-ring-cursor kr)) + (pos (mod (+ times (cursor-pos curs)) + (kill-ring-length kr)))) + (setf (cursor-pos curs) pos)))) + +(defmethod kill-ring-standard-push ((kr kill-ring) vector) + (let ((chain (kill-ring-chain kr))) + (if (>= (kill-ring-length kr) + (kill-ring-max-size kr)) ((lambda (flex obj) (pop-end flex) (push-start flex obj)) - flexi object) - (push-start flexi object)))) - -(defgeneric kr-pop (kr) - (:documentation "Pops an object off of a kill ring")) - -(defmethod kr-pop ((kr kill-ring)) - (if (> (nb-elements (kr-flexi kr)) 0) - (pop-start (kr-flexi kr)) - nil)) - -(defgeneric kr-rotate (kr &optional n) - (:documentation "Rotates the kill ring either once forward or an optional amound +/-")) - -(defmethod kr-rotate ((kr kill-ring) &optional (n -1)) - (assert (typep n 'fixnum)(n) "Can not rotate the kill ring ~S positions" n) - (let ((flexi (kr-flexi kr))) - (rotate flexi n))) - -(defgeneric kr-copy (kr) - (:documentation "Copies out a member of a kill ring without deleting it")) - -(defmethod kr-copy ((kr kill-ring)) - (let ((object (kr-pop kr))) - (kr-push kr object) - object)) + chain vector) + (push-start chain vector))) + (reset-yank-position kr)) + +(defmethod kill-ring-concatenating-push ((kr kill-ring) vector) + (let ((chain (kill-ring-chain kr))) + (if (zerop (kill-ring-length kr)) + (push-start chain vector) + (push-start chain + (concatenate 'vector + (pop-start chain) + vector)))) + (reset-yank-position kr)) + +(defmethod kill-ring-yank ((kr kill-ring) &optional (reset NIL)) + (if reset (reset-yank-position kr)) + (element> (kill-ring-cursor kr)))
Index: climacs/packages.lisp diff -u climacs/packages.lisp:1.21 climacs/packages.lisp:1.22 --- climacs/packages.lisp:1.21 Fri Jan 7 08:26:24 2005 +++ climacs/packages.lisp Fri Jan 7 14:07:45 2005 @@ -52,8 +52,7 @@ #:name-mixin #:name #:buffer-lookin-at #:looking-at #:buffer-search-forward #:buffer-search-backward - #:search-forward #:search-backward - #:buffer-search-word-backward #:buffer-search-word-forward)) + #:search-forward #:search-backward))
(defpackage :climacs-abbrev (:use :clim-lisp :clim :climacs-buffer :climacs-base) @@ -68,10 +67,10 @@ #:url))
(defpackage :climacs-kill-ring - (:use :clim-lisp :climacs-buffer :flexichain) - (:export #:initialize-kill-ring #:kr-length - #:kr-resize #:kr-rotate #:kill-ring - #:kr-copy #:kr-push #:kr-pop)) + (:use :clim-lisp :flexichain) + (:export #:kill-ring #:kill-ring-length #:kill-ring-max-size + #:reset-yank-position #:rotate-yank-position #:kill-ring-yank + #:kill-ring-standard-push #:kill-ring-concatenating-push))
(defpackage :climacs-gui (:use :clim-lisp :clim :climacs-buffer :climacs-base :climacs-abbrev :climacs-syntax :climacs-kill-ring))