Flexichain An editable sequence and its gap-buffer implementation Robert Strandh, Tim Moore, Matthieu Villeneuve [email protected], [email protected], [email protected]
Laboratoire Bordelais de Recherche en Informatique (LaBRI)
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.1/19 API Model
An editable sequence of objects containing an arbitrary number of cursors.
Cursors
Arbitrary Objects
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.2/19 Uses of API
• Emacs-like text editors for the entire buffer
• Emacs-like text editors for one line of a buffer
• Emacs-like text editors for the sequence of lines
• Gsharp (at 4 different levels)
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.3/19 Possible representations
• Doubly linked list
• Gap buffer
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.4/19 Doubly linked list
Advantages: fast, easy to implement Inconveniences: no direct access, high memory overhead
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.5/19 Gap buffer
Advantages: direct access, low memory overhead Inconveniences: slow worst-case, hard to implement
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.6/19 Previous work
• Multics Emacs: a doubly-linked list of lines, each line a vector (special instructions)
• GNU Emacs: entire buffer is a gap buffer
• Hemlock: doubly-linked list of lines, the open line is a gap buffer
• Goatee (McCLIM): doubly-linked list of lines, each line is a gap buffer
• Gsharp: currently uses singly-linked lists
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.7/19 Purpose of Flexichain
In order of priorities:
1. Replace specialized, slow code in Gsharp
2. Replace line implementation in Goatee
3. Replace list of lines in Goatee
4. Perhaps use in portable Hemlock
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.8/19 Two layers: Flexichain and cursorchain
The Flexichain layer uses positions to access, insert, and delete elements. The Cursorchain layer uses cursors. The two are compatible.
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.9/19 The Flexichain layer insert<* chain element position insert>* chain element position delete* chain position element* chain position (setf element*) position element chain
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.10/19 Stack and queue operations push-start chain element push-end chain element pop-start chain pop-end chain rotate chain &optional (n 1)
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.11/19 Implementation of Flexichain layer
• Use a gap buffer
• Consider the buffer as circular (avoids bad worst cases)
• Expand and shrink factors
• Moving the gap is messy
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.12/19 Moving the gap
Three situations exist:
Move left or right according to the number of elements that need to be moved in each case.
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.13/19 Moving the gap
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.14/19 The Cursorchain layer at-beginning-p cursor at-end-p cursor move< cursor move> cursor insert< object cursor insert> object cursor delete< cursor &optional (n 1) delete> cursor &optional (n 1) element< cursor element> cursor
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.15/19 The Cursorchain layer
• cursorchain is a subclass of flexichain
• cursors store physical position rather than logical positions in order to avoid updating all cursors at every operation
• to avoid memory leaks, we use weak references to store cursors
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.16/19 The Cursorchain layer
• we use an internal protocol for resizing and for moving the gap
• cursor update are done by :before and :after methods of internal protocol
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.17/19 State of implementation
Flexichain is finished. Cursorchain will be finished this summer (we all have daytime jobs).
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.18/19 That's all
Thank You! Questions?
Flexichain – Lisp and Scheme Conference, Oslo 2004 – p.19/19