usql
usql copied to clipboard
Add wrapper for C's readline library
Add a standalone package that works on Linux, macOS, and Windows that wraps the C readline library. Ideally, it'll have more or less the same interface as the existing rline
package, and would ideally be configurable by tags at build time.
After I looked into this further, this seems to be much easier than I had originally thought. Just giving a heads up that I'm already working on this, and will probably have it done in the next few days. Only mentioning it in the very off chance that someone saw this issue and had decided to take it up.
I wrote a wrapper around readline
, replxx
and editline
, and have the ability to build each using an appropriate build tag, it leads to some undesirable issues that are preventing me (in a philosophical sense, not a technical sense) from merging it to usql
. For any other ambitious developers out there who are interested in working on this, let me summarize the issues:
-
readline
andeditline
do not seem to have any clear or easy way to do syntax highlighting -
editline
would not haveinputrc
support -
replxx
does have syntax highlighting, tab completion, and other aspects, however it only allows a limited set of colors. As such, thechroma
based highlighting would no longer be possible. It would be possible to try to match achroma
theme's styles to the colors thatreplxx
supports, but this would of course be limited or a half-measure at best as the colors would be "clamped" to only those provided by thereplxx
library.replxx
would also not haveinputrc
support. Overhauling thereplxx
package would be difficult, and no guarantee it'd get accepted into the upstream repo - Adding
replxx
or a static build ofreadline
would breakgo get
(unless the.a
and other platform's static build equivalents were included in the source repo, which would make the dependent repo grow extremely large over time) - Having
readline
as a dynamic dependency as default would require thereadline
library to be installed somewhere on the system. While not an issue for Linux, BSDs, and others, macOS and Windows do not have these out of the box - Ideally, for this project to continue being "universal" (ala the 'u' in
usql
), the default configuration/build should be the same out of the box on all platforms, including downloading binaries, building viabrew
, building from source, or fromgo get
should be identical (with the exception of which drivers are enabled by default, which I find to a fair trade off, as it's easy to add additional build tags for brew, source, orgo get
) - As a minor positive though, it does appear that
readline
andreplxx
can be built into the same project, and that they do not stomp on each other by implementing the same API. As such, it should be possible to allow the user to change whichreadline
library they would like to use at runtime
Based on the above, even though I have not wanted to do it, my next great endeavor will be to do a clean, new implementation of a rline
package that supports chroma
out-of-the-box, works on all platforms, and hopefully fixes issues. inputrc
(or some kind of equivalent) support will follow, but the first task will be to just do a clean implementation. Additionally, since it is possible to support both readline
and replxx
at the same time, I will make it possible to build those. My plan is that there will be a new usql
only setting that allows the user to choose their readline library, and the Go implementation, readline
and replxx
implementations will all be built by default into usql
releases or dynamically enabled with the appropriate build tag.
The new package will be called xo/rline
.
Once completed, my expectation is that usql
will have the additional tags for go build
like the following:
rline_all - enable readline and replxx statically
rline_all_dynamic - include readline dynamically, replxx statically
rline_readline - include readline statically
rline_readline_dynamic
rline_replxx - include replxx statically
The rline
package itself, while the API is not finalized, will end up looking something like the following:
import "github.com/xo/rline"
r, err := rline.New(opts...)
r.Prompt("a prompt string")
r.SetPrompter(rline.Readline) // sets it to the readline library
r.SetPrompter(rline.Replxx) // to replxx
r.SetPrompter(rline.Default) // to the Go based implementation
In the above the Readline
Replxx
and Default
will likely be a uint
const following the constant strategy pattern common in the Go standard library (see the crypto
package for an example, if not familiar with the pattern).
This is probably answered in other issues but what are the issues with the current readline lib? Have you considered using other Go based replacements, like https://github.com/peterh/liner/?
@nineinchnick Yes, I've seen that package before. It might be a better jumping off point than "nothing" to implement a pure Go version, rather than trying to adopt the chyzer/readline
or gohxs/readline
packages. I haven't looked at it much. Based off a quick reading of of liner
's API documentation, I don't see that it supports syntax highlighting out of the box, or otherwise will be able to support all the specific requirements.
At this point, I've more-or-less decided to just bite the bullet and write a from the ground-up implementation in idiomatic Go, that's designed to do efficient syntax highlighting out of the box, and to additionally provide a wrapper around with C's readline and replxx libraries. At least then the user will be able to decide which to use.
I just pushed the initial commit to the aforementioned rline
package that builds both readline
and replxx
into the repository. None of the Go implementation has been started yet, as I just wanted to put this together to see what the effect would be on usql
and to work out the various build tags, dependencies, etc. Will start authoring a ground-up Go prompt implementation shortly.