Skip to content

shamansir/purescript-blessed

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 

Repository files navigation

What is Blessed

This is the draft implementation of Blessed Node.JS library in PureScript. The library provides you as a developer with windows-driven GUI (including basic components) to the terminal applications.

There are windows a.k.a. boxes with support of dragging, lists of items, a file manager, buttons, and many more, see for yourself.

What is moved

  • All the components from the basic repository;
  • Most of the options, properties and methods;
  • Most of the events;
  • Most of the component styles;
  • Tagging the text;

Not yet translated/implemented:

  • The subjects of the events handlers, so it would be easy for you to subscribe to the event of the component and get the corresponding object decoded from JSON;
  • A lot of things...

Installation

It is crucial to install npm install -g blessed beforehand and ensure to have the latest version of node.js, or just the best one of the latest versions.

The library is not distributed (yet?) so there's no spago install, sorry. But you may add it to packages.dhall using custom git link, just name it blessed or something.

Quick intro to the API

The key in this PureScript implementation is the Key... and Subject :). Subject. NodeKey.

There are type-level values for every kind of component in blessed, called Subject, and this way the library verifies if you specify the property that really belongs to this component (or its parent) or call a method that really belongs to this component and so on.

Every component instance should have an unique Key. Using this key you may call any method of this particular instance, that belongs to the components of this Subject. You may either define all of them in some separate module (e.g. MyApp.Keys) or create them on the fly or define them in the modules of your components. On the type-level, Key contains a Subject and some Symbol (type-level String) that identifies your family of components. On the value-level, there is a hash UUID inside so that you would be able to create many unique keys from the same family if you need. That's what NodeKey.next is for. If you don't have the requirement to spawn several instances of the same component in your application, then it's very probable that you won't need it.

There is a free monad BlessedOp in which you may perform any effects, access and modify the global state (there are no per-component states for the moment, at least it could require some tricks), since it implements State monad, and call methods of your components using keys. BlessedOp.

This monad is where your initial code is performed as well as the code for every handler.

Components are defined this way:

Blessed.box <yourKey>
	[ Box.<someOption> <someValue>
	, Box.<someOption> <someValue>
	, Box.mouse true -- for example
	, Box.tags true -- for example
	, Element.<someOption> <someValue> -- since Element is parent for box
	, Blessed.on Event.Click $ do 
		 <yourKey> >~ Box.<someMethod> <arg1> <arg2>
		 val <- <yourKey> >~ Box.<someProperty> -- get value of the property
		 top <- <yourKey> >~ Box.top -- for example
		 state <- State.get
		 State.modify (\state -> <some code>)	
	     ...
	     pure unit
	]

Where Blessed.box could be Blessed.list or Blessed.fileManager etc.

Or, this way:

Blessed.boxAnd <yourKey>
	[ Box.<someOption> <someValue>
	, Box.<someOption> <someValue>
	, Box.mouse true -- for example
	, Box.tags true -- for example
	, Element.<someOption> <someValue> -- since Element is parent for box
	, Blessed.on Event.Click $ do 
		 <yourKey> >~ Box.<someMethod> <arg1> <arg2>
		 val <- <yourKey> >~ Box.<someProperty> -- get value of the property
		 top <- <yourKey> >~ Box.top -- for example
		 state <- State.get
		 State.modify (\state -> <some code>)	
	     ...
	     pure unit
	]
	$ do 
		 <initial code below>
		 <yourKey> >~ Box.<someMethod> <arg1> <arg2>
		 val <- <yourKey> >~ Box.<someProperty> -- get value of the property
		 top <- <yourKey> >~ Box.top -- for example
		 state <- State.get
		 State.modify (\state -> <some code>)	
	     ...
	     pure unit		

Where Blessed.boxAnd could be Blessed.listAnd or Blessed.fileManagerAnd etc.

>~ is actually just the # operator in disguise. Just to distinguish the parts that work with blessed component from other function calls.

All the components are of type Blessed m where m is usually just the Effect monad, or it can be something else that has instance of MonadEffect. Blessed definition.

BlessedOp state m is the free monad for handlers and initialisation code, where m should be the same as above, and state is the global state of your components.

To run the application, use Blessed.run <initialState> <rootComponent> or Blessed.runAnd <initialState> <rootComponent> $ do .....

Examples

You may see many examples of its usage in the Noodle/Cli application, and currently this repo is just the extract from there. Noodle CLI components.

To tag your text so that it is coloured you may use Blessed.Tagger, here's an example.

As the example shows, it is possible to use these bindings and they do really work in most of the cases. Still, this library is made for a specific project to satisfy its specific needs and lacks a lot of features of node.js-version of blessed. That's why I have no intention to publish it to Pursuit yet, at least until the events system is moved and all of the methods are implemented for basic components, and more documentation to be in the code.`

About

PureScript port of chjj/Blessed

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published