With the two new cursors as defined in the previous posts about nonempty cursors and text field cursors we can take the next step towards making a Purely Functional Semantic Forests Editor like Smos. In this post we will write a simple purely functional text editor using brick
, building on the previous single-line text editor: picosmos.
From a single line to a multi-line text editor
The only semantic difference between Picosmos and Nanosmos is that now the contents to be edited are multi-line text instead of a single line of text. Let us start there.
We will take the original code for picosmos and modify it. We will replace the type of the state of our brick application by a TextFieldCursor
. Now we should get a few type errors.
For example, makeTextFieldCursor
cannot fail, while makeTextCursor
could, so we no longer have to case-match on the output. The same is true for textFieldCursorInsertChar
versus textCursorInsert
.
Next, showing a little blinking cursor on the right line and on the right character within that line now needs a bit more code. Instead of textCursorIndex
, we will use textFieldCursorSelection
. However, this new function returns a tuple instead of single index. The first element of that tuple is the line number of the cursor and the second element is the index of the text cursor that represents that line.
That part of the code now uses both parts of that tuple:
let (y, x) = textFieldCursorSelection tc
in showCursor "cursor" (Location (x, y)) $
txtWrap (rebuildTextFieldCursor tc)
Once the type errors are fixed, we can try out nanosmos
after building it. There are many things missing from nanosmos
, when you look at it coming from vim. However, for the purposes of building our tiny simple text editor, there is only one thing missing: moving up and down between lines.
To add this feature, all we need to do is add the following two lines in the handleEvent
function:
KUp -> mDo textFieldCursorSelectPrevLine KDown -> mDo textFieldCursorSelectNextLine
The result looks very dry, but it works:
There we have it: A purely functional semantic text editor in fewer than 100 lines of code.
References
The full code can be found on github. Text cursors are available in the cursor
package on Hackage. This post is part of an effort to encourage contributions to Smos. The simplest contribution could be to just try out smos and provide feedback on the experience. Smos is a purely functional semantic editor of a subset of YAML that is intended to replace Emacs' Org-mode for Getting Things Done.