next-generation programming platform, currently in development
about
help fund the project
swag

Twitter . GitHub . RSS

Building the fancy autocomplete widget for use in the editor



I’m deep in the middle of implementing the design discussed in the earlier post. The ‘navigation’ mode stuff we’ve seen before, it’ mostly done and shown here. The other mode is the ‘explorer’ mode. You navigate around, select a subexpression for editing, and up pops a crazy advanced autocomplete box with a ton of functionality, which is what I’ve been building (have just finished v1, actually), learning a lot about Reflex in the process. It’s a complex component, with a lot of requirements:

A tall order!

Since this explorer widget is going to be used for editing terms, types, type declarations, and other stuff like symbols (for instance when renaming a function parameter), I wanted something somewhat generic. Building components like this is easy with Reflex, you have total control over the results, and the full power of Haskell to abstract over whatever you wish. After some futzing around, I’ve landed on the following signature, which I’ll explain:

explorer :: forall t m k s a . (Reflex t, MonadWidget t m, Eq k, Semigroup s)
         => Event t Int
         -> (s -> String -> Action m s k a)
         -> Event t (m ())
         -> Dynamic t s
         -> m (Dynamic t s, Event t (Maybe a))
explorer keydown parse topContent s = ...

data Action m s k a
  = Request (m s) [(k, Bool, m a)] -- `Bool` indicates whether the choice is selectable
  | Results [(k, Bool, m a)]
  | Cancel
  | Accept a

Let’s walk through this:

The implementation of this function is 60 lines of code. And it actually works… the results are reallly ugly at the moment, but the implementation supplies some CSS classes that can be used to make it look nice. If you are for some reason interested in seeing the ugly test page I put together, you can build the code and then launch this file.

Now that the tough part seems worked out, I’m going to use this to implement the term explorer. Then we can hook everything together and try writing some actual Unison expressions for real! Since the language has let and let rec bindings, we can actually write some nontrivial programs. I’m excited for this moment, and I plan on posting the editor right here online for people to try out. I look forward to getting feedback from people on what they think about the editing experience!

comments powered by Disqus