GithubHelp home page GithubHelp logo

inputomata's Introduction

Vim FSMs and You

In the Beginning Was the getchar()

Inputomata provides a general-purpose, event-driven finite-state machine triggered by user key presses, with states defined in TimL maps.

What?

See: http://en.wikipedia.org/wiki/Finite-state_machine

Put less simply, you define one or more states of a finite-state machine (FSM) in a [Clojure-like] TimL map, providing each with one or more triggers. Triggers are single characters that you can press on the keyboard while in an FSM, which can either transition you to another state, run a function, or exit the FSM.

What?

It lets you quickly build interactive scripts that react to keypresses.

Why is it called "Inputomata"?

Two reasons:

  1. Names are hard.
  2. It's a portmanteau of "input" and "automata."

How do I pronounce it?

However you like. I say it sort of like "imp pedometer," sans terminal "r."

Other half-rhymes:

Features

  • Implemented in Tim Pope's awesome, Clojure-like TimL language.
  • State maps are very easy to define via Clojure-like TimL maps.
  • The implementation is super small, because TimL is expressive.
  • Allows continuous Vim<->user interaction without any mappings.
  • All of these bullet points have the same number of characters.

Requirements

TimL, Vim, a computer (w/ keyboard), sentience, free time, and maybe free will.

Vim/VimL/TimL interop

  • Your FSMs can interact with Vim/VimL/TimL in the same way that TimL can, i.e. completely.
  • Input from the user - on a key-by-key basis - can trigger state transfer, or can call any arbitrary TimL function (currently without state change).
  • Inputomata.tim uses Vim's getchar in a loop, trapping the user until they find an exit condition (provided in your states map), or they hit ctrl+c, or they realize their computer doesn't own them, and they can just get up and leave whenever they want.
  • Because the entirety of the interaction takes place in a TimL loop/recur, no changes need to be made to Vim, e.g. no mappings are set/changed. This is all purely functional, for some impure value of "purely."

Getting started

This plugin is set up in the standard Vim fashion. Masochists can install it manually; others may use Pathogen, Vundle, NeoBundle, etc...

I recommend installing pathogen.vim, then copying and pasting this (you know where):

cd ~/.vim/bundle
git clone git://github.com/tpope/timl.git

Examples

The Flyover States

The simplest example is the empty states map. State names are TimL keywords, and a nil value is a terminating condition. This FSM would start, immediately exit, and display "done" in the status line. Note that all states maps must at least have a :start state; it is an error otherwise.

(use 'inputomata.core) ; we'll presume this line for the remaining examples
(fsm {:start nil})
Two States, and a Bridge Betwixt

The following FSM allows jumping to :a or :b states on start, then between :a and :b as often as you like, with the ability to quit out at any point. The messages let you know where you are at all times. Though optional, they're a good idea. It gets disorienting and lonely to hop from state to state without receiving any feedback (a sad variant of the traveling salesman problem).

(fsm {:start {:msg "Press 'a' or 'b', or 'q' to quit"
              \a :a
              \b :b
              \q nil}
      :a {:msg "State 'a'. Press 'b' ('q' to quit)"
          \b :b
          \q nil}
      :b {:msg "State 'b'. Press 'a' ('q' to quit)"
          \a :a
          \q nil}})
I Put Some State in Your States...

Your state machines can interact with the state around them, which is to say that your FSMs can interact with things in their scope, or any scope they can access. A nice, local way to do this is to wrap the FSM itself in a let, as we've done below.

There are a few new things happening here. First, we're using a TimL atom, so we can swap! the value with the result of applying a function on it (dec/inc here), and dereference it (@value) to get its current value. Second, this shows off Inputomata's ability to use the result of a function call as the current state's message. Note that on valid key presses, the FSM recurs; this is the seam that allows for in-state message updates.

(let [value (atom 0)]
  (fsm {:start
        {:msg #(str "dec/inc value (" @value ") with j/k, q to quit")
         \j #(swap! value dec)
         \k #(swap! value inc)
         \q nil}}))

License

Copyright © Gary Fixler.

The use and distribution terms for this software are covered by the Eclipse Public License 1.0, which can be found in the file epl-v10.html at the root of this distribution.

By using this software in any fashion, you are agreeing to be bound by the terms of this license. You must not remove this notice, or any other, from this software.

inputomata's People

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.