[climacs-devel] latest progress

Luigi Panzeri matley at muppetslab.org
Thu Jan 6 11:52:03 UTC 2005


Robert Strandh <strandh at labri.fr> writes:

> Do not hesitate taking on even minor tasks such as fixing a bug or
> adding documentation strings.  And please add your favorite Emacs
> command that is currently missing from Climacs, but please let us know
> (by mailing to this list) what you are working on in that case. 
>

Hi,

i am lookig at climacs, which i consider a nice project. I wrote for
fun a little function for the buffer library that implements the
dabbrev-expand function (plus two utility function), commonly
keybinded with M-/ on emacs (one of my favourite command for writing
texts)

It tries to expand the current word in one that is found in the
buffer. It works incrementally, using a closure and avoid duplicated
expansion.

It is not a beautiful code imho, but it works well. I don not have a
lot of real experience with cl programming, so i have many doubts
about design and style.

I ll try to change it, but i ll be happy if you look at it and point
me what could be wrong.

(in-package :climacs-buffer)

;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Dynamic Abbrev
;;; Simple implementation
;;;;;;;;;;;;;;;;;;;;;;;;;

(defun previous-word (mark)
  "Return a freshly allocated sequence, that is word before the mark"
  (region-to-sequence
   (loop for i downfrom (1- (offset mark))
      until (zerop i)
      while (constituentp (buffer-object (buffer mark) (1- i)))
      finally (return i))
   mark))

(defun buffer-search-word-backward (buffer offset word &key (test #'eql))
  "return the largest offset of BUFFER <= (- OFFSET (length WORD))
containing WORD as a word or NIL if no such offset exists"
  (loop for i downfrom (- offset (length word)) to 0
	when (and (or (zerop i) (whitespacep (buffer-object buffer (1- i))))
	      (buffer-looking-at buffer i word :test test))
	  return i
	finally (return nil)))

(let ((last-match-off nil)
      (matches nil)
      (cur-search nil))
  (defun dabbrev-expand (mark)
    "Expand word, dynamically. Expands to the most recent,
preceding word for which it is a prefix. Move mark and insert text."
    (flet ((sequence-equal (s1 s2)
	     (not (mismatch s1 s2))))
      (let ((word (previous-word mark))
	    (buffer (buffer mark)))
	(unless (and last-match-off    ;; restart search
		     (member word matches :test #'sequence-equal)
		     (search cur-search word)
		     (zerop (search cur-search word)))
	  (setf cur-search word 
		matches nil
		last-match-off (offset mark)))
	(backward-delete-word mark)
	(let* ((new-match-off (buffer-search-word-backward
			       buffer last-match-off cur-search :test #'eql))
	       (new-match
		(if new-match-off
		    (buffer-sequence buffer new-match-off 
				     (loop for i 
					upfrom new-match-off
					while (constituentp 
					       (buffer-object buffer i))
					finally (return i)))
		    cur-search)))
	  (setf last-match-off new-match-off)
	  (insert-sequence mark new-match)
	  (if (and new-match-off
		   (member new-match matches :test #'sequence-equal))
	      (dabbrev-expand mark)
	      (pushnew new-match matches :test #'sequence-equal)))))))

(in-package :climacs-gui)

(define-named-command com-dabbrev-expand ()
  (dabbrev-expand (point (win *application-frame*))))

(global-set-key '(#\/ :meta) 'com-dabbrev-expand)


-- 
Luigi Panzeri



More information about the climacs-devel mailing list