Plugins - mr-martian/quest-editor GitHub Wiki

An editor is only as powerful as its extensibility.

Quest is to be built on a relatively simple base process we'll call Core. Quest Core implements a simple text editor with two modes, rich and formatted (gui) (subject to change depending on gui library), a configuration and settings menu (gui), a plugin API that exposes editor data and settings in a safe, well behaved manner; and a keyboard shortcut translation table. Everything else is a plugin, which are classified to either an extension or a service/overlay. An extension extends the capabilities of the editor for the type of data in an open file, whereas a service or overlay is something that performs some data-type agnostic operation, like jot down a todo note or execute a region of selected text as a shell command.

1st Party Plugins

  • Plugin Development IDE
  • Emacs Helm clone
  • Auto-complete
    • I would like this to either be able to plug in to an LSP or just use context clues to deduce variable names within the file.
    • Perhaps a system to insert skeletons of commonly used structures in a language (loops, statements, functions, maybe even the main function)?
  • Which-key clone
  • Hierarchical project explorer (like treemacs)
  • Org clone
  • Zettelkasten/Personal Wiki system or Zim integration
  • Git porcelain
  • Tab/frame manager
  • Build system integration
  • Terminal integration
  • "Run sed expression/shell script on buffer or selected region"
  • Run word under cursor as command (similar to eval last s-exp)
  • Effective large file editing (might end up being included in Core)
    • Different treatment of regular, large and massive files (normal size, larger than a user determined threshold, and too large to fit in the machine's memory).
    • Editing operations previewed on screen before committing
    • Possibility to queue up multiple actions
  • Elastic tabstops
  • Intelligent/adaptive spellcheck using identifier declarations and word splitting
  • Linter/formatter integration
  • Flexible highlighting engine
    • Hierarchical, per-language token classes (i.e. String -> {SingleQuoteString, DoubleQuoteString}) for ease of theming
    • Something comparable to Notepad++ UDLs, or at least allowing highlighting from an EBNF-like input
    • Themable identifier-hash-based coloring and rainbow brace highlighting
  • Format-aware hex editor
    • Decode/destructure known formats
    • Syntax highlighting/phantom brace insertion
  • Code folding
  • Advanced editing commands
    • Case conversion
    • Line operations
    • Whitespace/blank line operations
      • Remove unnecessary whitespace (language-aware)
    • Toggle block/line comments

Core Functionality/Plugin Interface

  • Settings database
    • Built-in persistence with optional per-setting volatility
    • Key-value based and backed by text files (TOML?)
    • Can be used for inter-plugin communication with configuration-changed event hooks
    • For consistency in speed of accessing settings, perhaps a tree-based map instead of a hash map?
      • Using a B Tree or one of its variants would even allow us to cache some settings on disk and still have somewhat consistent performance.
  • Network support
    • accessing files on a server
    • syncing across devices
    • collaborative editing
  • Buffer Interaction
    • Arbitrary number of text entry points (cursors)
    • setting editable text boundaries
    • Use of a persistent rope or other such data structure as first-class data type for buffer access
    • Piping/creating a temp file for external command
  • Large file support
    • Only part of the file loaded in
    • Streaming used for full-file access
  • Buffer Content Manipulation
    • Language Server Protocol support
    • Debugger support
  • Built in generic tokenizer
    • plugin provides a specification of token types, and the tokenizer does the rest and returns a list of tokens.
    • not limited only to buffers, but anything Quest exposes to the user.
  • Creating GUI interfaces for specialized tasks that might be nicer with a gui rather than either a command line or entering text into the text area.

Finer details worth experimenting with

  • Perhaps make use of event oriented/driven design.
  • Contract based event dispatch table
    • Extensions have a contract with the core process where they promise to react when some events occur. Core adds those handlers to its default EDT, and adds any new events the extension supports (that it or derived extensions emit) to the table. When an event occurs, core keeps a reference to the state of each affected open file before the plugin acts on them. core waits for a confirmation that the event was handled correctly, and if it wasn't it restores each buffer to its last stable state.
    • Other extensions can use an extension as a dependency, because it provides other events to the EDT, and likewise, similar contracts are made with core.
  • Extensions can either live in separate kernel threads or separate processes depending on performance needs, or depending on what makes practical sense without sacrificing stability.