Our webinars are continuing to be as popular as ever and Tom Sydney Kerckhove's (Tech Lead at FP Complete) webinar on "Building Terminal User Interfaces with Haskell" was no exception. We had 426 people registered for the event which aired on Wednesday, November 28th at 10:00 am PST. If you tuned in live you would have seen Tom Sydney Kerckhove programming at lightning speeds. We are so glad we recorded the event because you need to be able to stop and start the video at your own pace to keep up with the action. IMPORTANT NOTE: Before you watch the video you may want to check out the Free Training offer we are making available to the first 20 people who register. You can find out more below or by clicking here to register now.About the Webinar
In this month's webinar, Tom Sydney Kerckhove will demonstrate just how easy it is to get started with Terminal User Interfaces (TUIs). As a recap, TUIs are text-based user interfaces for use from a terminal. They are usually lightweight, and most importantly, in this webinar, you will learn how easy they are to use. You will also learn how to get up and running by making your own TUI applications with live-coding example TUIs with the Brick library.
Topics to be covered:
- The Brick architecture
- Basic cursors
- Simple example TUI applications
We decided to include the chat log for this webinar, and it can be seen at the end of this blog post. For those of you that want more information the TUI Syd built check out the following links:
A base to start a TUI from: https://github.com/NorfairKing/tui-base
A semantic tree-based editor to replace Emacs Org Mode for GTD: https://github.com/NorfairKing/smos
A declarative terminal UI programming library written in Haskell: https://github.com/jtdaugherty/brick
If you think there is a typo in this paragraph heading, you are not alone. We are testing two new training programs, and we would like to offer you FREE training in either Haskell or Rust. That's right, it's absolutely FREE, and there is no catch. We want to beta test the training programs to ensure we are providing maximum value to our students. This is a time-limited offer because, in the future, we will be charging a fee for these courses. This training will be available for free to the first 20 students who register for each class.
These spots will fill up quickly so register now by clicking one of the images below.
At FP Complete, we do so many things to help companies it's hard to encapsulate our impact in a few words. They say a picture is worth a thousand words, so a video has to be worth 10,000 words (at least). Therefore, to tell all we can in as little time as possible, we recently produced a new explainer video. Check it out by clicking the video link below. It's only 108 seconds to get the full story of FP Complete. One last thing. We have a home page a facelift, and you can check it out here.
Check out our new Explainer Video
We want your feedback for webinar topics
We would like to hear your suggestions for future webinar topics. The simplest way to accomplish this is to add a comment to this blog post with your suggestion. Alternatively, send your suggestion via email to firstname.lastname@example.org.
Webinar Chat Log
We find it useful to share what was chatted about during the webinar. You can see the chat flow below.
10:00:38 From oren rozen : Hi
10:00:48 From Michael Snoyman : Welcome everyone
10:00:51 From Alexandre Garcia de Oliveira : Hi
10:00:57 From Nick Linker to All panelists : Hi!
10:01:00 From Andre Artus to All panelists : hi
10:01:21 From oren rozen : my first webinar so guide me if I need to do something special
10:01:22 From Andrey Prokopenko : Hi everybody!
10:01:34 From Tristian Azuara : Hello!
10:01:37 From Frank Stüss to All panelists : hi everyone!
10:01:40 From Artem Chernyak : Hi!
10:01:40 From bogdan : Hi!
10:01:41 From Dan Banta : Hello. :)
10:01:44 From furnost to All panelists : Hello
10:01:45 From Joerg W to All panelists : Hi!
10:01:46 From Alexei Pastuchov to All panelists : Hi
10:02:09 From Frank Stüss to All panelists : thanks for doing this!
10:02:19 From Pedro Furlanetto : Hello
10:02:32 From furnost to All panelists : Hi all!
10:02:33 From Andrew Starodubtsev to All panelists : hello!
10:02:40 From Daniel Leones to All panelists : Hello.
10:03:06 From Michael Snoyman : Feel free to ask questions here, I'll try to either respond or pass them along :)
10:03:50 From Pedro Furlanetto : Curses?
10:03:58 From Pedro Furlanetto : * Library I mean
10:04:12 From Michael Snoyman : I'm not sure what the question is, sorry
10:04:29 From R Primus : Is it using the nurses library?
10:04:45 From Michael Snoyman : Under the surface, yes, though we'll get into the libraries
10:04:51 From Pedro Furlanetto : curses and lcurses library for Unix terminal UIs
10:04:52 From Michael Snoyman : https://github.com/NorfairKing/tui-base
10:05:03 From oren rozen : Is it possible to run it with nix?
10:05:21 From Michael Snoyman : I believe so, though I haven't tested it myself in this case
10:05:46 From Tristian Azuara : Hi I might have to leave the webinar; for a work call; will the recording be available somewhere?
10:05:54 From Niklas Hambuechen to All panelists : It uses vty, a competitor to ncurses: https://hackage.haskell.org/package/vty
10:06:16 From Michael Snoyman : Yes, we'll make the recording available when ready (probably in the next few days)
10:06:19 From Niklas Hambuechen to All panelists : See the dependencies of https://hackage.haskell.org/package/brick
10:06:35 From Michael Snoyman : And announce on our blog and Twitter account
10:06:41 From Michael Snoyman : Niklas: thanks for the correction
10:06:43 From Tristian Azuara : Awesome!!, thank you; I’ll stay for as long as possible.
10:06:59 From furnost to All panelists : Awesome, thanks for the recording!
10:07:56 From Alexandre Garcia de Oliveira : Widget is a dependent type?
10:07:59 From Alexandre Garcia de Oliveira : is
10:08:19 From Corey O'Connor to All panelists : (a R Primus to be clear - The "ncurses" UI widgets are not used. ncurses is only used for loading termcap data. )
10:08:46 From Alexandre Garcia de Oliveira : Ok. Thank you
10:08:58 From Michael Snoyman : +1
10:09:08 From Michael Snoyman : https://www.stackage.org/haddock/lts-12.20/brick-0.37.2/Brick-Types.html#t:Widget
10:09:12 From Pedro Furlanetto : Are the slides a brick app?
10:09:30 From Robert Pearce : ^ +1
10:09:33 From Konstantin Yegorov to All panelists : C:\Haskell\TUI_webinar\tui-base>stack install
Downloaded lts-12.18 build plan.
AesonException "Error in $.packages.cassava.constraints.flags: failed to parse field packages: failed to parse field constraints: failed to parse f
ield flags: Invalid flag name: \"bytestring--lt-0_10_4\""
10:09:42 From Michael Snoyman : You need to upgrade Stack, try `stack upgrade`
10:09:50 From Konstantin Yegorov to All panelists : 10x
10:10:10 From Michael Snoyman : I'll save the slides question to the end
10:10:41 From Niklas Hambüchen to All panelists : oren rozen: The example is a simple Haskell package, so like all other packages, it work with nix as well.
10:11:24 From Niklas Hambüchen to All panelists : *works
10:11:33 From Alexandre Garcia de Oliveira : Nope
10:11:40 From furnost to All panelists : Fine by me
10:11:41 From oren rozen : Go ahead
10:11:52 From Nick Linker to All panelists : clear
10:15:43 From Andrey Prokopenko : please move on
10:15:47 From Pedro Furlanetto : can you please, write the type vBox in a comment in the source
10:15:50 From Nick Linker : its ok
10:16:13 From Andre Artus : I'm battling to watch and follow along at the same time.
10:16:17 From Michael Snoyman : https://www.stackage.org/haddock/lts-12.20/brick-0.37.2/Brick-Widgets-Core.html#v:vBox
10:16:51 From Michael Snoyman : Andre: if you're having trouble, keep in mind that the video will also be recorded if you'd like to try going through it with a pause button later
10:17:34 From Andre Artus : Thanks, Michael, I will just watch it now and follow through it later.
10:18:12 From Pedro Furlanetto : Cursor == Zipper?
10:18:18 From Michael Snoyman : Yes
10:18:21 From Alexandre Garcia de Oliveira : Yes
10:18:28 From Pedro Furlanetto : thx
10:18:49 From Nick Linker : Why do we need nonEmptySelectNext/Prev functions and not just fields of NonEmptyCursor data type?
10:19:37 From Michael Snoyman : We would need to tie the knot in a funny way to make that happen. If you try to implement such a field-based approach, you'll see the problem
10:20:59 From Nick Linker : Hm, ok.
10:22:39 From Nick Linker : What the signature of `continue` function?
10:22:46 From Michael Snoyman : One sec
10:22:56 From Nick Linker : a -> EventM a?
10:23:08 From Michael Snoyman : Almost https://www.stackage.org/haddock/lts-12.20/brick-0.37.2/Brick-Main.html#v:continue
10:23:14 From Michael Snoyman : continue :: s -> EventM n (Next s)
10:23:15 From Nick Linker : Thanks!
10:23:23 From Nick Linker : I see.
10:23:38 From Michael Snoyman : In case anyone's curious, I'm using the Stackage search on this page: https://www.stackage.org/lts-12.20/hoogle?q=continue&package=brick
10:23:51 From Nick Linker : Thanks, Michael.
10:25:53 From Corey O'Connor to All panelists : true that @ boolean blindness ;)
10:26:17 From furnost to All panelists : everything clear
10:26:19 From Andre Artus : good so far
10:26:50 From Michael Snoyman : wehavetogodeeper.gif
10:27:01 From Nick Linker : haha
10:29:54 From Alexandre Garcia de Oliveira : Go ahead
10:30:00 From Nick Linker : cool, no question so far
10:30:39 From Pedro Furlanetto : That’s cool
10:30:49 From Niklas Hambüchen : I can't see vty or patat in the deps of patat
10:30:58 From Niklas Hambüchen : sorry "vty or brick"
10:31:18 From Pedro Furlanetto : Let’s dive deeper
10:31:40 From Daniel Leones to All panelists : I think you're using vim. Does Haskell autocompletion is included?
10:31:49 From Robert Pearce : Thanks! gotta bounce. looking forward to the video. This is great <3
10:32:32 From Corey O'Connor to All panelists : (probably a vty bug XD)
10:32:35 From Andrey Prokopenko : cool
10:32:35 From Alexandre Garcia de Oliveira : This is cooler than doing front-end
10:32:39 From bogdan : Hi, can you make a small overview of brick
10:32:42 From bogdan : ?
10:32:47 From Bulent Basaran : How easy would it be to draw dir/files differently?
10:32:52 From Karol Kopiec to All panelists : thx really cool
10:34:08 From Corey O'Connor to All panelists : I would akin brick to a UI toolkit. Like GTK or QT.
10:34:15 From Peter Young : Thanks for presentation. Very cool!
10:34:18 From bogdan : Ok, thank you)
10:34:21 From oren rozen : thank you
10:34:24 From oren rozen : :)
10:34:30 From Andre Artus : Are there higher level UI elements? I.e. composing a from without having to construct everything?
10:34:39 From furnost to All panelists : thanks! amazed at the dev speed
10:34:46 From Daniel Leones to All panelists : Thanks for the presentation.
10:34:59 From Bulent Basaran : in emacs/shell mode: I am getting an error: tui: user error (Terminal does not define required capability "cup")
10:35:17 From Corey O'Connor to All panelists : "composing a form"? As in, handling the user interaction and data submission?
10:35:30 From Michael Snoyman : I don't think we'll be able to debug the emacs shell mode support, sorry
10:35:48 From Bulent Basaran : no problem :-)
10:36:08 From Mo Kweon : will the code be available after this?
10:36:38 From Daniel Leones to All panelists : This: https://github.com/NorfairKing/tui-base
10:36:42 From Pedro Furlanetto : Update the attributes map
10:37:11 From Michael Snoyman : Good call Pedro :)
10:37:18 From Michael Snoyman : I was about to mention it
10:37:23 From Michael Snoyman : But Syd got there first
10:38:02 From oren rozen : Both the selection is red and the file are red
10:38:42 From Pedro Furlanetto : making selected the last?
10:38:45 From Marc Paterno : I am accustomed to using test-driven development,. What Haskell tool or library would you suggest for doing that?
10:38:45 From Iurii Lukaniuk to All panelists : Can we send events to Brick app from another thread?
For example, events about changes of directory contents
10:38:49 From Pedro Furlanetto : (pure guessing)
10:39:08 From Alexandre Garcia de Oliveira : nice
10:39:10 From bogdan : Question is of topic: what extensions are used for vim? or neovim? (you can not answer for this question)
10:39:12 From Corey O'Connor to All panelists : cool!
10:39:13 From Frank Stüss to All panelists : (y)
10:39:13 From Pedro Furlanetto : yep
10:39:13 From SORIN STOICESCU to All panelists : Hi, could you share some thoughts about structuring Brick as an interface to something multithreaded/async? like, imagine you select a file & the program uploads it somewhere, in the background, showing some progress bar for it
10:39:16 From Bulent Basaran : beautiful!
10:39:49 From bogdan : * is out of topic
10:39:52 From Andre Artus : Cool
10:40:28 From Artem Chernyak : Brick reminds me a lot of the Redux architecture
10:40:35 From Artem Chernyak : From JS
10:41:53 From Pedro Furlanetto : is the draw always of the entire screen or is it able to update only certain portions?
10:41:53 From Nick Linker : Or ELM, but with some additional type params
10:42:01 From Pedro Furlanetto : *screen ~= terminal
10:42:08 From bogdan : Can I have like deadlocks with channels?
10:42:23 From Mo Kweon : Where is the code available?
10:42:39 From Pedro Furlanetto : The link is in the beginning of the chat
10:42:41 From Michael Snoyman : We'll send out an email with code and video links
10:42:48 From Daniel Leones to All panelists : Nice.
10:43:13 From Marc Paterno : I am accustomed to using test-driven development,. What Haskell tool or library would you suggest for doing that?
10:43:16 From bogdan : Thanks for answering)
10:43:27 From Nick Linker : Let me some more side questions:
Could you describe your workspace environment. I guess this is zsh with oh-my-zsh installed, but is there something beyound this?
How do you make immediate stack build on save?
How do you make fast reformatting of the last entered piece of code?
How do you configured type hints?
10:43:29 From Jon Schoning to All panelists : Do you ever embed a brick App into a higher level component in your application? or just use the App directly?
10:43:53 From Jon Schoning to All panelists : i.e. Brick does not seem like a Monad Transformer itself
10:44:22 From Marc Paterno : Thanks
10:45:41 From Pedro Furlanetto : xmonad is going on, no?
10:46:02 From Karl Berger to All panelists : There was a good webinar previously on Haskell workflow, would recommend!
10:46:06 From Mo Kweon : looks like it
10:46:44 From Nick Linker : Thank you for the answers!
10:46:46 From Mo Kweon : yeah
10:46:48 From oren rozen : this is a tooling question as well: just wonder did you guys have tried haskell-ide-engine
10:47:07 From oren rozen : Ok thanks
10:47:08 From furnost to All panelists : +1 for webinar idea
10:47:12 From Artem Chernyak : Thank you so much this was a great demo and walkthrough!
10:47:15 From bogdan : Wonderful presentation)
10:47:16 From LUC DUZAN to All panelists : What is the biggest TUI you have written so far ?
10:47:17 From Mo Kweon : Thank you
10:47:18 From furnost to All panelists : thanks !
10:47:19 From Frank Stüss to All panelists : super! thank you
10:47:21 From Andre Artus : Thanks, very informative
10:47:23 From Daniel Leones to All panelists : Thank you
10:47:24 From Michael Irving : Thank you
10:47:26 From SORIN STOICESCU to All panelists : Thank you
10:47:28 From Karl Berger to All panelists : Thanks everyone
10:47:29 From Pedro Furlanetto : Thanks a lot Tom and Michael
10:47:36 From Niklas Hambüchen to All panelists : I have tried HIE a couple times, getting better, but still way to go, also depending on the editor you use
10:47:39 From Dan Banta : Fantastic. Thank you.
10:47:41 From Carlos Gomez : thx
10:47:43 From Marcel Tilly to All panelists : Thx
10:47:44 From Inga Shchelik to All panelists : thank you!
10:47:45 From Alexandre Garcia de Oliveira : Thank you
10:47:45 From Karol Kopiec to All panelists : thank you
10:47:45 From Nick Linker : Awesome
10:47:46 From Andre Artus : Bye.
10:47:46 From Franck Rasolo : Thanks for the presentation, looking forward to the links!
10:47:47 From Frank Stüss to All panelists : bye all
10:47:47 From LUC DUZAN to All panelists : Thank you a lot!
10:47:48 From Corey O'Connor to All panelists : Thanks!
10:47:48 From Andrey Prokopenko : Thanks!
10:47:48 From Pedro Furlanetto : You too
10:47:50 From Konstantin Yegorov to All panelists : Thanks everyone
10:47:53 From Marcel Tilly to All panelists : great presentation
10:47:55 From Mo Kweon : What is a next presentation in the plan?