Table of Contents
Lisp Text
pyssel/editor/lisp-text reads Lisp's text without the reader, as the
code editor reads it to colour, indent and find forms: it takes text that
does not read, as code being typed is, interns nothing and evaluates
nothing. It depends on Common Lisp alone and asks what it needs of a
Lisp, as whether a name is a macro's, of functions you give it, so that
it can become a library of its own (code-editor.org, decision 6).
(asdf:load-system :pyssel/editor)
(pyssel/editor/lisp-text:scan-line "(defun f (x) ; doubles" :code)
;; => #(0 :TEXT 1 :KEYWORD 6 :TEXT 7 :DEFINITION 8 :TEXT 13 :COMMENT), :CODE
(pyssel/editor/lisp-text:line-indentation (vector "(defun f (x)" "x)") 1)
;; => 2
Texts
A Lisp text is read through line-count and line-text, generic
functions with methods for vectors of strings and for strings, whose line
feeds part their lines. A lisp-text, as make-lisp-text makes of a
vector of lines, also knows the state each line starts in and how many
lists are open there, as Emacs's parse from a text's start counts them,
and the lines its in-package forms are on: it finds them as they are
asked for, reading from the first line once, without allocating, and
keeps them, so that what is read at a place is read from the top-level
form the place is in, and a text's package is found at once, however
long the text. Call lisp-text-changed with the first line changed when
its lines change. A text of your own, as the Script screen's code edits'
lines are, subclasses lisp-text, with methods on line-count and
line-text. Without the depths, as for a plain vector, a bracket at a
line's start is taken for a top-level form's, as Emacs's beginning of
defun takes one.
Colours
scan-line reads a line from the state the line before ended in,
+start-state+ at a text's start, and gives its runs, a simple vector of
each run's start and its kind, as a code edit's highlighter gives them,
and the state it ends in: :code, :string, :bar in a symbol's
multiple escape, or the count of block comments open. The kinds:
:comment; :string, strings and multiple escapes, whose brackets do
not count, as Emacs's syntax has it; :constant, characters, keywords, T
and NIL; :number; :type, lambda-list keywords; :symbol, quotes,
commas and #'; :keyword, :control-flow or :function for the
operator at a form's head, as its :operator-kind, a function of the
operator's text, says, operator-kind by default, which knows Common
Lisp's standard operators; the kind it gives as a second value for the
name a definition defines, as :definition after defun, :variable
after defvar and :type after defclass; and :text.
Forms
read-forms reads lines into forms, as Emacs's Lisp mode counts
sexps: #'car is one, #+sbcl another and #+(or a b) two. A form
knows its kind, :list, :string or :token, where it starts, its
prefixes as ' and #' included, where what follows them starts, where
it ends, or that it is not closed, its children and a token's or a
string's text. Text that does not read is read as far as it goes.
top-level-form-atgives the top-level form at a place, or the last before it, as a form is compiled at the caret;form-beforethe form just before a place, as SLY evaluates the last sexp;forward-formandbackward-formwhere Emacs's forward-sexp and backward-sexp go. Each reads the forms around the place only.enclosing-listsgives the lists that hold a place, the innermost first, andargument-indexwhich argument of one the place is at, as an argument hint wants.form-at-pathfollows a compiler's source path, counted the reader's way, feature expressions in or out as a function you give says, a dispatch as#2Aone object with what follows it, and'xread as(quote x);form-number-pathturns SBCL's form number of a definition into such a path.text-package-namenames the package a place is read in, as SLY finds a buffer's: the lastin-packagebefore it, or else the first after it, its argument's name as the reader makes it,token-symbol-namegiving a token's symbol's name and its package's.
Indentation
line-indentation gives the column a line starts at, as Emacs with SLY
indents Common Lisp, rules written anew from what they do (decision 4):
the list holding the line, Emacs's normal indentation under its first
element or first argument, then SLY's specs of operators, by name, out
through the lists holding it, six at most, def and with- names
guessed as SLY guesses them, quoted lists, vectors, feature expressions
and keyword arguments aligned, and LOOP, TAGBODY, DO and DEFMETHOD by
rules of their own. It returns NIL for a line Emacs leaves as it is,
inside a string, or a comment of three semicolons, and puts a comment of
one at column 40. Its :specs, a function of an operator's text in lower
case, its package prefix included, gives the specs of operators that are
not standard, an indentation-spec, in the language of SLY's specs:
numbers, &lambda, &body, &rest, lists that start with &whole,
keywords as :loop for a form's own rules, and (as "name"), compared
by name so that they may be in any package; macro-indentation-spec
makes one from a macro's lambda list, as Slynk makes SLY's. A spec that
is none is a malformed-spec. The indentation is tested against what
Emacs with SLY makes of 148,000 lines of the workspace's code, and of a
corpus of every rule, line for line.
Thread rules
Its functions keep no state between calls but what a lisp-text keeps,
which is used from one thread at a time.
Getting started
The core
Drawing
Scenes
User interface
Games and the editor
- Playing a Game
- Projects
- The Editor
- The File System Dock
- The Script Screen
- The REPL
- The Debugger
- Lisp Text
- Code Services
- Project Manager
- Undo and Redo
- Exporting
The project