Smos: Writing a Purely Functional Semantic Editor

This is the first post in a long series of posts documenting the process of developing Smos. Smos is a purely functional semantic editor of a subset of YAML that is intended to replace Emacs' Org-mode for Getting Things Done.

Emacs' Org-mode

In the past five years, I have routinely switched between using TaskWarrior and Org-mode. I really enjoyed using Taskwarrior, and wrote about it a lot I like Org-mode a lot. It is my tool of choice for implementing Getting Things Done (GTD). It is a mode for emacs that allows for quick editing of a plaintext format that looks like this:

* Smos blogposts                                         :blog:
** DONE [#C] Write up the introduction
  CLOSED: [2018-08-17 Fri 17:14]
  - State "DONE"       from "TODO"       [2018-08-17 Fri 17:14]
** TODO Write the first blogpost

While I really like org-mode, I also really dislike emacs and Lisp. I thought I would take this opportunity to write a purely-functional replacement in Haskell with brick that fixes the shortcomings of org-mode (within emacs) and leaves out the parts that are not relevant to GTD.

Org-mode also has support for a lot of things that are unrelated to GTD, like document outlining, graphs, tables, etc.. Smos is only for GTD, so we will be leaving out these parts.

Org-mode also has some characteristics that I do not like:

  • Emacs often messes up actually writing to a file. This results in stupid missed edits. Smos can make extra assumumptions because it is specifically made for GTD that should make this easier.
  • Emacs configuration happens in lisp, which is untyped. As a result, I have never booted emacs without seeing type errors. Smos will be written and configured in Haskell, like Xmonad.
  • Org-mode works on plaintext. The format is not very machine-readible and therefore not easily automatable. Smos will operate on a subset of YAML, which is easily machine-readible by most modern languages. Smos will be a semantic editor, which means that it can never write something that is not a valid smos file.

Example

Work on smos has already started and it can be found on GitHub. The following is an example .smos file

- entry:
  header: Use Smos
  timestamps:
    DEADLINE: 2018-10-30
    SCHEDULED: 2018-10-20
  state-history:
  - new-state: STARTED
    timestamp: 2018-10-10 14:19:53.988042844000+0000
  tags:
  - online
forest:
- header: Don't mess it up
  state-history:
  - new-state: DONE
    timestamp: 2018-10-10 14:19:54.388413954000+0000
- header: Be smart about it
  state-history:
  - new-state: TODO
    timestamp: 2018-10-10 14:19:54.796427564000+0000
  tags:
  - work

And here is how it would look within smos:

Roadmap

Writing an editor is a daunting task, so both the work and the reporting on the work will be split up into multiple blog posts.

  • Intro: What will we need? (This post)
  • Cursors, Part 1: List
  • Cursors, Part 2: Text
  • picosmos: Writing a simple single-line text-editor with brick.
  • Cursors, Part 3: NonEmpty List
  • Cursors, Part 4: TextField
  • nanosmos: Writing a simple text-editor with brick.
  • Cursors, Part 5: Tree
  • Cursors, Part 6: Forest
  • microsmos: Writing a simple tree editor with brick.

Further:

  • Cursors, Part 7: Map
  • Data Types of the thing we will be editing (smos-data)
  • Smos Cursors: Entry
  • Smos Cursors: Other cursors: Header, Contents, Tags, etc
  • Brick: Drawing the current cursor
  • Brick: Transforming the cursor given an event
  • Brick: Styling

Contribute

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.

If you liked this blog post, please consider becoming a supporter:

Become A Supporter