Plaster

common-lisp
x
 
1
(cl:in-package #:text.editing)
2
3
(defstruct search-input
4
  cursor
5
  index)
6
7
(defun buffer-length (input)
8
  (c:item-count (c:buffer (search-input-cursor input))))
9
10
(defun buffer-ref (input index)
11
  (let* ((cursor    (search-input-cursor input))
12
         (old-index (search-input-index input))
13
         (diff      (- index old-index)))
14
    (format *trace-output* "~D -> ~D~%" old-index index)
15
    (cond ((zerop diff))
16
          ((plusp diff)
17
           (loop :repeat diff :do (forward-item* cursor))
18
           (setf (search-input-index input) index))
19
          ((minusp diff)
20
           (loop :repeat diff :do (backward-item* cursor))
21
           (setf (search-input-index input) index)))
22
    (item-after-cursor* cursor)))
23
24
(defun make-buffer-layout ()
25
  (one-more-re-nightmare::make-layout :array-type 'search-input
26
                                      :length     'buffer-length
27
                                      :ref        'buffer-ref))
28
29
(text.editing.test::call-with-buffer
30
 (lambda (buffer)
31
   (let ((input (make-search-input :cursor (point buffer) :index 0)))
32
     (one-more-re-nightmare:first-match "f«o+» *«b$+»" input :layout (make-buffer-layout))))
33
 "foo bar")
34
; => #(0 7 1 3 4 7)
35