This post announces the availability of linenoise-swift-utf8: A Swift replacement for GNU readline.
There is a very useful library called GNU readline which enables line editing and history (and more) for command line programs. I’ve written a few command line programs and I know that having this functionality, or similar, makes them very much easier to use. The Lambda Calculator is much easier to use when you have the ability to access command line history and edit it.
There are a couple of problems with GNU Readline that make it problematic for me:
- it’s written in C, not Swift
- it’s licensed under GPL version 3, which means that (I think – IANAL) my code that links with it has to be GPL licensed. I prefer to use the Apache 2 licence.
I searched around for an alternative and eventually found linenoise-swift. This was, in turn, developed from a C library called linenoise. It is a light weight readline replacement written in Swift and licensed under the BSD licence. That covers both of my problems with the GNU readline. It did, however, have one drawback:
- It only handles fixed width 8-bit character encodings.
In fact, it silently barfs on any UTF-8 character that is not part of ASCII. I say “silently” it screwed them up. This is not good for a command line application where the ability to type a λ character (UTF-8 is CE BB) is vitally important. So I cloned the repository and hacked in a fix. I offered the fix back to the owner of linenoise-swift but he rejected it on the grounds that it was a hack which was true. His main objection was that a user should be able to turn UTF-8 support on and off depending on the expected terminal type.
I’ve finally got around to implementing his suggestion, but I’ve generalised it by allowing the user to specify any 8-bit fixed width character encoding or UTF-8. I also fixed a couple of other issues and have added to the documentation.
This works on macOS Swift 5.5 or higher and should also work on Linux – but I haven’t tested it there. The documentation on how to use it is here.
Hopefully one or two other people will find it useful.