An open API service indexing awesome lists of open source software.

https://github.com/scymtym/text.editing

Motion, editing, search, etc. operations for Cluffer buffers
https://github.com/scymtym/text.editing

editing search text undo

Last synced: 4 months ago
JSON representation

Motion, editing, search, etc. operations for Cluffer buffers

Awesome Lists containing this project

README

          

#+TITLE: text.editing README
#+AUTHOR: Jan Moringen
#+EMAIL: jmoringe@techfak.uni-bielefeld.de
#+LANGUAGE: en

#+OPTIONS: toc:nil num:nil
#+SEQ_TODO: TODO STARTED | DONE

* Introduction

This library provides protocols and implementations of those
protocols for text editing operations which are required by, for
example, text editors or commandline processors (like REPLs). This
library relies on the [[https://github.com/Robert-Strandh/cluffer][Cluffer]] library for the fundamental concepts
of buffers, lines and cursors. The functionality provided by this
library includes:

+ Cursor movement (by various "units")

+ Insertion and deletion (by various "units")

+ Transformations (for example changing case or transposing)

+ Killing, copying and inserting

+ Multiple cursors

+ "Mark" cursors and regions

+ Undo (work in progress)

+ Operations on expression (like paredit for Emacs)

+ Search and incremental search

+ Abbreviations (work in progress)

This library does not provide

+ Data structures for editor buffers (the cluffer library does that)

+ Input handling or a command processor

+ Advanced parsing (see [[https://github.com/s-expressionists/incrementalist][incrementalist]] for that)

+ Syntax highlighting (see TODO for that)

+ Presentation/rendering/display functions for the contents of text buffers

*This library is under active development. Its ASDF system
structure, package structure, exported symbols and protocols may
change at any time. Consult the NEWS file or the "Changelog" section
of the manual for lists of changes in specific versions.*

This document only gives a very brief overview and highlights some
features. Proper documentation can be found in the
file:documentation directory.

* Usage Overview

Using this library typically requires a buffer class defined by the
client which includes the desired mixin classes. For example

#+BEGIN_SRC lisp :exports both :results value verbatim :wrap EXAMPLE
(defclass my-buffer (text.editing:multiple-site-mixin
text.editing:site-mixin
cluffer-standard-buffer:buffer)
())
#+END_SRC

#+RESULTS:
#+BEGIN_EXAMPLE
#
#+END_EXAMPLE

This buffer class is like a Cluffer buffer but also has a primary
and zero or more additional sites. Creating an instance of the
buffer class automatically creates the primary site an attaches its
point cursor to the initial line of the buffer:

#+BEGIN_SRC lisp :exports both :results output verbatim :wrap EXAMPLE
(defvar *my-buffer*
(make-instance 'my-buffer :initial-line (make-instance 'cluffer-standard-line:closed-line)))

(print *my-buffer*)
(print (text.editing:site *my-buffer*))
(print (text.editing:sites *my-buffer*))
(print (text.editing:point (text.editing:site *my-buffer*)))
#+END_SRC

#+RESULTS:
#+BEGIN_EXAMPLE

#
#
(#)
#
#+END_EXAMPLE

This buffer instance is usable with the operations provided by this
library:

#+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE
(defvar *point* (text.editing:point *my-buffer*))
(setf (text.editing:items *point* text.editing:buffer :forward)
(format nil "one~%two!~%three~%"))
(defun summary ()
(values (coerce (text.editing:items *point* text.editing:buffer :forward) 'string)
(text.editing:sites *my-buffer*)))
(summary)
#+END_SRC

#+RESULTS:
#+BEGIN_EXAMPLE
"one
two!
three
"
(#)
#+END_EXAMPLE

#+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE
(text.editing:change-case *point* text.editing:word :backward :up)
(summary)
#+END_SRC

#+RESULTS:
#+BEGIN_EXAMPLE
"one
two!
THREE
"
(#)
#+END_EXAMPLE

While many operations can be applied directly to a cursor, it is
preferable use to the "operation protocol" and let the library
figure out how and to which object to apply the operation in
question:

#+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE
(text.editing:perform *my-buffer* 'text.editing:move text.editing:word :backward)
(text.editing:perform *my-buffer* 'text.editing:delete text.editing:line :forward)
(summary)
#+END_SRC

#+RESULTS:
#+BEGIN_EXAMPLE
"one

THREE
"
(#)
#+END_EXAMPLE

The deleted word is now in the insertion stack (which is like the
"kill ring" in Emacs) and can be inserted:

#+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE
(loop :repeat 3 :do (text.editing:perform *my-buffer* 'text.editing:yank :forward))
(summary)
#+END_SRC

#+RESULTS:
#+BEGIN_EXAMPLE
"one
two!two!two!
THREE
"
(#)
#+END_EXAMPLE

It is easy to see how the operation protocol comes into play when
multiple sites are used:

#+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE
(text.editing:push-site-relative *my-buffer* text.editing:line :forward)
(summary)
#+END_SRC

#+RESULTS:
#+BEGIN_EXAMPLE
"one
two!two!two!
THREE
"
(# #)
#+END_EXAMPLE

#+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE
(text.editing:perform *my-buffer* 'text.editing:move text.editing:line-boundary :backward)
(text.editing:perform *my-buffer* 'text.editing:change-case text.editing:word :forward :capital)
(summary)
#+END_SRC

#+RESULTS:
#+BEGIN_EXAMPLE
"one
Two!two!two!
Three
"
(# #)
#+END_EXAMPLE