I've released v0.9.0 of Rogallo. The first big change in this release is the addition of syntax highlighting to pre-formatted text.
Much like in Markdown, Gemtext also supports pre-formatted text bounded by code fences. Gemtext supports the concept of "alt-text" for such text, like this:
Until now Rogallo would simply show the text as-is (with some styling to make it stand out from normal paragraphs). From this release, if there is alt-text for the pre-formatted block, and if it's the name of a supported language, the content will have syntax highlighting applied.
Another significant change is to the user input dialog. As mentioned in an earlier post, the Gemini protocol imposes limits on how much text can be submitted to a capsule. As documented, the limit is for a resulting URI of 1024 bytes1. To save someone typing out a long entry, only to have it lost2, I've added a count of how much input is left available (calculated from the size of the URI that would result):
To help ensure that the user doesn't submit too much, I've also added an error display if you go over the limit, which also refuses to submit the input.
With these in place it should be a lot harder to run into an unexpected loss of input.
One final tweak is a small change to the optional link stripe system I recently added. While playing around with some other themes, I noticed that the styling didn't show up well, or at all, in many of them. So I've changed it a little so it now shows in all available themes. I'm still not convinced it's quite right -- I'll play some more. But at least now it's visible in all cases.
Right away I'm now thinking it might be a good idea to re-populate the input dialog in such a situation. I'll have to remember to make that a TODO issue. ↩
Rogallov0.8.0 is now available. This release includes a small bug fix, a big change to how external links and unhandled MIME types are dealt with, and a further improvement to link navigation.
First the big change: hand-off of unhandled content and trust. Until now, if Rogallo was met with a URI it didn't know how to handle, or met with a MIME type it isn't designed to deal with, it would simply hand it off to the browser in your environment. This is generally handy as it means that, when you're browsing gemtext content, if you meet a link that takes you to a conventional website, the link will (normally) be opened in your browser.
There are, of course, any number of schemes that form part of a URI. While Rogallo might commonly be handing off http and https URIs, there's no reason why it can't be handing off a finger or a mailto or whatever. Or, potentially, something a wee bit more dodgy like a javascript URI. While some web browsers don't allow that sort of thing by default (Safari, for example, blocks it unless configured otherwise), others might, and this could result in a nasty surprise.
So now Rogallo has a confirmation step that lets you allow a scheme this once, this and every subsequent time, or just cancel out.
By default the trusted schemes (the ones you say "always" on) are saved in a trusted_schemes file in the data directory.
Similar to the above: if, via a URI that Rogallo can handle, it meets a MIME type it can't handle, it will also pass it off to your operating system. I've added similar protection there too.
In this case any MIME types marked as trusted are dropped into a trusted_mime_types file in the data directory.
ℹ️ Note
If such a MIME type is allowed, it is passed off to your operating system to handle. If you'd like to tell Rogallo to try and internally handle a MIME type, you can set that by configuring the displayable content types.
I feel these changes help remove any possible footguns previously caused by unquestionably handing off URIs to the wider environment.
Another change I've made is to add even more link navigation. This sort of follows on from yesterday's release where I added labelled jumps to links. Again, the usual method of moving between links is to use Tab and Shift+Tab. The problem with those keys is they navigate you through all widgets in the UI that can receive focus. So, if you keep tapping Tab, you'll navigate out of the viewer and into the next available widget, once you reach the last link.
With this release I've added some extra keys which can be used to constantly cycle around the links while you're inside the viewer. These are:
Left, Shift+Up, L to go backwards through the links.
Right, Shift+Down, l to go forwards through the links.
While these might not be to everyone's taste (I'm already getting very used to using Left and Right), they do add another set of options for link navigation.
The final change is a simple bug fix, where the command line history simply wasn't being saved and loaded correctly. From now on it should save correctly and allow navigation of the history using the cursor keys.
With these changes in place, I feel I'm actually getting close to bumping up to a v1.0.0 release. While there are still things I want to add (there are currently a handful of TODO items in the issues), I see these as nice-to-have items that I want to do later on, rather than as must-have items that preclude considering Rogallo a viable daily-driver.
Rogallov0.7.0 is now available. The main changes in this release revolve around the display and navigation of links.
The aim of Rogallo, as a "TUI" application, is that it is usable purely with the keyboard, and also very usable with the mouse too. So far I think I've managed to hit that mark, but I felt that things weren't quite as smooth as they could be when it came to navigating links.
Links, like any other UI element in the application that can receive "focus", can be navigated to using Tab and Shift+Tab. This is fine if there's just a handful of links in a page, but more than that and having to repeatedly press tab gets a bit boring. Meanwhile, if you have a mouse or other pointing device to hand, it's easy to scroll and click. I wanted to try and have a similar keyboard-based speedup available.
So now, by default, all links on a page get a numeric label:
To jump to a link, while the viewer has focus, simply type the number. When you do so, the corresponding link will be focused, then you just need to hit Enter to follow the link.
The input system is written to "wrap around", as it were. So if you type 1 the link with a label of 1 will be focused. If you then type 2, and if there's a link with a label of 12, it will be focused. If there are fewer than 12 links, the input chain resets, and 2 will be focused. The idea being: as you keep typing numbers, they concatenate until there's no matching link and then it starts fresh.
I was quite keen on having the labels over to the right, so they didn't disturb the layout of the main body of text, but there's a small downside with this: if you have a lot of links next to each other it's not always obvious which link and which label go together. While getting close to your desired link should be good enough (you can then still hit Tab to get to your chosen link), I felt something else could be done to give some help. So I added an option to turn on alternating background stripes for links.
If all of this seems a bit too cluttered, especially if you're the sort of person who is mouse-first or mouse-heavy with the terminal, there's still the option to turn off both the labels and the stripes and have Rogallo look like it did before.
I think this covers pretty much all the possible link navigation needs I can imagine anyone having.
As well as the above, other small changes in v0.7.0 include:
Fixed a cosmetic issue with the truncation of the current location shown in the viewer panel, if the location is longer than the available space is wide.
The suggestions provided in the command line now include hosts found in the "known hosts" trust store. So if you are trying to remember a location you visited long ago, and you never bookmarked it and it's fallen out of the location history, it's still there as a reminder/hint/completion.
Also added the same to the history search palette.
I've also done more work on the website. The configuration section now covers pretty much everything you can modify that changes how Rogallo works. I still want to add more to the site -- mostly concentrating on explaining some key features -- but I felt that anyone using Rogallo right now would be most interested in how they can tailor it to their own taste.
I've just released Rogallo v0.6.0, which contains the last big feature that was missing to make it a viable daily-driver Gemini Protocol client. That feature? Client certificates.
From now on, if you visit a capsule that requests a client certificate, rather than an error being shown, a dialog will pop up:
When you select the Create button, the certificate will be created and then, from then on, when you visit the capsule, that client certificate will be used.
As you might have noticed, there are "advanced options" available too. Most are just optional values that go into the certificate itself:
The two advanced options that mostly affect how all of this works are the scope and the transient option. The transient option means that the certificate is only good for the lifetime of this run of Rogallo. If you close Rogallo, the certificate will be discarded. In almost all cases, you'll want to leave this turned off.
The scope toggle affects the scoping of the certificate. As I've been able to understand, the strict reading of the Gemini Protocol says that a certificate should be scoped to the host, port, and path where it was first requested and generated for. However, out in the real world, it seems there are applications built for the protocol that don't work well with that approach. With this in mind, I've built Rogallo to always scope to just the domain and port, by default. If you want a particular certificate to follow the strict letter of the specification, turn the "Scope to domain/port" option off.
With all that in place, it should now be possible to use Rogallo with any Gemini application that needs client-side authentication. For the last couple of days, I've been using it to successfully play AstroBotany, for example.
As I said: with this in place, I believe Rogallo has all of the basic requirements of a Gemini protocol client covered. I'm not quite ready to call it v1.0.0 just yet -- there's a fair bit of testing and tweaking I still want to do, and I can see that, when it comes to certificates for example, there's some extra error handling I need to throw in. Additionally, the "advanced" version of the certificate create dialog is kind of tall for many terminals; I think I might need to play with the layout a bit.
Also, as I've mentioned a few times: I want to get proper documentation written and hosted on a dedicated site.
Back to this release: there's also a handful of other QoL changes and fixes. These include:
Any page that is opened from an in-page link is now always retrieved from the remote location, bypassing any cached copy. The idea being that, if someone is actively navigating documents, they will want the freshest version of the new page.
Fixed the layout of list items. Before now, the text wasn't wrapping, while, at the same time, space was being made for the text as if it was being wrapped.
The bookmark search palette is no longer available if there are no bookmarks to search (the idea being that not being available is less confusing than being available but empty).
The connection timeout, read timeout, and maximum number of redirects can now be set in the configuration file.
The title area of the viewer now has a key icon that appears if a page is using a client certificate.
Pages that require a client-side certificate are never added to the cache (the idea being that such pages are more likely to have dynamic content, and so the freshest version should always be loaded).
Reworked what is recorded in navigation and location history to ensure that what is saved is the landing URI, not the URI that was first visited. This solves the problem of what happens during redirections, and so also solves the issue of what happens with 10/11 response inputs (having the resulting query appear in history could result in duplicated "submissions" to whatever app was in use).
With these enhancements and fixes in place, I'm going to keep tending my plant, and posting away on Station, as a way of continuing to shake down the application. With that in mind, if anyone knows of any other sites and apps I should be testing against out in Geminispace, do let me know!
As mentioned in the last release, I've been afk for a week and a bit, enjoying some downtime over in the Netherlands. Although... it wasn't exactly all afk. I did take a keyboard with me and, while time permitted, I did tinker on Rogallo. That's resulted in quite a few TODO items being ticked off, and quite a few changes and improvements being made.
It's a small tweak, but I found it useful. The status bar of the main viewer panel now shows the MIME type of the document currently being viewed. Normally it will be showing text/gemini:
but Rogallo can show some other text/ types too, so this will also make it obvious what you're looking at:
You might also notice that, depending on the theme being used, the "correct" MIME type gets a "this is fine" colour whereas anything else is in a more "neutral" colour.
Now, if a document comes in that isn't text/gemini, there is no attempt to parse and render it as Gemtext; it's just shown as a simple block of plain text.
Given the above changes, Rogallo now makes an effort to guess the MIME type of any local file you view. This should help ensure that only Gemtext files get parsed and rendered as such.
Where possible, when confronted with a MIME type that Rogallo can't handle, it will attempt to hand it off to your environment's main web browser. While not ideal, I have no wish to turn Rogallo into a terminal-based general content browser/viewer; this is all about Gemini and Gemtext.
It's now possible to set a home page with either a SetHome (which prompts for a URI) or a SetHomeToCurrentLocation (it does what it says) command. There is also a GoHome command that takes you to the home page you've set. The default bindings for all of these can be found by either running rogallo bindings, or by viewing the help screen; pulling up the command palette is also an option.
Bookmarks are now supported. The ToggleBookmarks will show/hide the bookmarks list. AddLocationToBookmarks will add the current location to the bookmarks. SearchBookmarks lets you search the bookmarks.
The completion suggestion facility in the application's command line (where you enter URIs or commands) has been enhanced to include suggestions from the navigation history, the location visit history and the bookmarks. This should make it a little easier to enter a URI you're trying to remember.
Having added the SearchBookmarks command, it made sense to also add a SearchHistory command too. So with that you can quickly search all the locations you've visited (within the limits of the history) and head back to one.
While not something that should generally be obvious to the user, the Gemtext rendering engine has been optimised a little to reduce the number of Textual widgets used to display a document by consolidating all adjacent plain paragraphs.
Some Gemini sites use ANSI escape sequences to add colour to pages. While this isn't, as far as I can tell, part of the standard for Gemtext, it's a simple thing to support and so Rogallo has supported rendering this for a while; if a page has colours, they'll be used.
This meant that if you asked to view the source of a page, you'd also see that rendered in colour. I felt that wasn't in the spirit of viewing the source.
So now, if viewing a page like this:
When you go to view the source, instead of all of the colours still being rendered, you now get to see which ANSI escape codes were used where:
One small change is that, any time a document is loaded (from bookmarks, history, the command line, etc), the viewer now gains focus. Something I kept forgetting to do and finally I got fed up with having to tab over to the viewer each time.
Rogallo now has a content cache for pages loaded from capsules (the aim is to never bother caching content loaded from the filesystem). Any page that is loaded with a success status code (20) gets cached, and when you go back to it, if it's within the TTL of the cache entry (by default set to one hour), the content of the page will be loaded from the cache rather than making a fresh request.
Using the Reload command always bypasses the cache.
There is also a ClearCache command which will delete all cached data.
The TTL of the cache can be changed in the configuration file by updating the value for cache_ttl. Also, if you don't wish to ever use a cache, you can set with_cache to false to disable it.
With all of the above, I feel this gets Rogallo close to being v1.0.0-ready. Not quite, but very close. The main addition that still needs to be tackled is client-side certificates. I don't anticipate this being too tricky, it's just more a case of needing to play around with the code I've got so far, and needing to think about how to implement it in a TUI-friendly way (if, indeed, there are any considerations there at all).
For now though, as long as you don't need a client-side certificate, there's plenty to play with and try out.
I've just made a small update to textual-enhanced, my core library used for most of my Textual-based applications. In v1.6.0 I've extended the "constructor" for ModalInput to allow passing in optional values for password, suggester, title and sub_title.
Most of the time I just want to quickly call on ModalInput to get input from the user. If I need anything more fancy, I roll my own dialog. But in some work I'm doing on Rogallo, it would be helpful for me to at least set the suggester. So, without adding every optional parameter for the Textual Input widget, I've extended what can be passed in to what I think will be a useful subset for my applications.
I've updated Rogallo to v0.4.0. The main new feature in this release is support for capsule-requested user input. There are some other simple additions too.
I've added a Reload command, bound to F5 by default. As you might imagine, it reloads whatever page you're looking at right now.
I've also added a pair of commands for copying things to the clipboard. There is CopyLocationToClipboard (bound to ctrl+shift+c by default) which, as the name suggests, copies the current location (either the Gemini URI or the path to the file depending on what you're viewing) to the clipboard. In a similar way, CopyDocumentToClipboard will copy the content of the document you're viewing (bound to alt+shift+c by default).
It's worth noting that the default bindings for both of those aren't going to be ideal for some terminals. They should be fine in any terminal that supports the Kitty keyboard protocol, but will likely do nothing elsewhere. This can be changed to your taste via the configuration file1.
Talking of a document's content: I've also added a ToggleView command (bound to F3 by default) which toggles the document's view between a rendered view and a plain text (source) view. So if you're looking at a page like this:
and want to know what the underlying source looks like, just toggle the view:
Finally, the most significant addition is support for capsule-requested user input. This handles a 10 or 11 response from a server, prompts the user for input, and then sends it back as a query.
It's worth noting that the sensitive input (response 11) isn't done in the most obvious way, on purpose. Normally I'd have taken the "do obscured password input" thing, which is supported by Textual's Input widget. The problem there though is that an input request from a Gemini server expects and allows for multi-line input2; that requires the use of a TextArea; it doesn't support password-style input.
So what I've done instead is, if it's a sensitive input request, I simply greatly lower the contrast of the text vs the background. This should match the "reduce shoulder-surfing opportunities" requirement while not making it impossible to see what you're doing.
Normally I wouldn't be satisfied with this approach given that the text will still be visible, but I think it's a fair solution given one glaring problem with Gemini's sensitive input facility: the input is always sent back as a URI query string. That means that the resulting input is part of the URI, will be visible in any URI display on the screen, will be part of the history, etc. The sensitive part is only about making it less obvious at the moment of input, so I think this approach is in that spirit.
So... that's it for v0.4.0, and that's also likely it for the next week or so. I'm going to be super busy in AFK life next week and into the week after, so work on Rogallo will pause. It's almost a shame, I'm having tons of fun working on it.
As mentioned in another post about Rogallo, how to do that will be documented when I get round to writing the documentation for Rogallo. Meanwhile look at similar documentation for Hike to get an idea of how to go about it. ↩
Well, technically, it's an optional feature of a client; the specification says "Clients MAY allow for the entry of input composed of multiple lines". I wish Rogallo to be one such client. ↩
I've released Rogallo v0.3.0, which mostly concentrates on adding command line support and sorting support for browsing files in the local filesystem. There are also a couple of cosmetic configuration options thrown in.
Starting with the cosmetic configuration options: I got to feeling that the URI-containing tooltips that show on mouse-hover over a link might be a bit much for some people, so I've added show_link_tooltips to the configuration file1. Set it to false to make the tooltips go away.
Similar to this I've also added disable_animations. Out of the box Textualloves its animations. This is arguably most noticeable if you have a long body of text in a scrolling widget (such as the document viewer in Rogallo), as you use PgUp, PgDn, Home, End, etc., it'll scroll in a fancy animated way. It looks cool for a moment but I can imagine plenty of people getting sick of it, or feeling sick because of it (I sense this is an a11y issue too). With this in mind if disable_animations is set to true they'll all be turned off.
Rogallo now also has a number of command line options that can come in useful. In part borrowing from a number of my other TUI applications, and also adding some specific to Rogallo itself. They can be easily found with the --help switch:
Because I feel it's important that people know where applications drop things in your filesystem, there is the directories command, which shows you which directories are used by Rogallo.
The how of changing bindings still needs to be documented, but it's the same as with most of my other TUI applications, so if you look at how it's done in OldNews, for example, you should get the idea.
This command can be used to open a location from the command line. You can pass it either a URI for a Gemini capsule, or the path to a file in the local filesystem.
Talking of viewing files in the local filesystem... that's now supported too. This is something I wanted to build in from the start, as I feel it could be handy to anyone writing gemtext files prior to deployment. I sense there might be a couple of edge cases relating to this that I might still need to iron out, but mostly it seems to be working well.
At some point I'll probably also pull in textual-fspicker so that the user can browse for files to view, making it just a little easier to open a file in some cases.
So far, to connect to a Gemini capsule, it's been necessary to provide the full URI. That's kind of annoying. It had been deliberately left like this until I sorted the work to allow specifying local files, as I wasn't quite sure how it would all interact. Now that I've got that in place I could address this too. So whereas before you had to type gemini://davep.gemcities.com/ to get to my test capsule, now it's enough to enter davep.gemcities.com.
There is some guesswork going on in the background, with the resolution rules looking something like this:
Have I been given a URI that is obviously a Gemini URI?
If not, if it has no scheme, and it matches the name of a file in the filesystem, let's assume the user meant that.
If it's not a file in the filesystem, and it doesn't have a scheme, let's slap gemini:// on the front and see how we get on with that.
None of the above applied, yet it has a scheme: throw it at the operating system's URI resolution system.
In casual testing so far this is working out well.
I'm still having a blast working on this, and there's still a lot more to do. The TODO list is staying pretty constant in size at the moment because, as I knock an item off, I seem to keep finding new things I want to add or improve. I see this as a good thing.
I have a very busy AFK life for the next week or so, so I don't imagine too many updates during that period. Once things have settled again I want to try and tackle the two big issues of user input and client certificates. I'll be happy that Rogallo is getting close to generally usable when I know I can log in and water my plant in Astrobotany.
~/.config/rogallo/configuration.json on most systems. This and all the options within will eventually be documented, when I get round to creating the site to document Rogallo. ↩
Rogallo v0.2.0 is now available. This version fixes some issues with links, makes gemtext parsing better conform with the specification, and also makes it easier to see where a link will take you.
The first issue is a fix to how page-relative links were resolved if the page you were viewing was the result of a redirection. What was happening was the links were being resolved relative to the initial URI, rather than the final URI of the redirection. This was most noticeably a problem when following links in the geminispace equivalent of webrings. The main change took place in Wasat, with Rogallo making use of the new Response.uri property.
The second fix was to how I parse gemtext. The initial parser was close enough, but I noticed there were some finer points relating to whitespace that I hadn't paid attention to (mainly due to skim-reading the specification). For example, I expected links to always start with => followed by a space, when in fact a link can simply start with a => and then be followed by the URI with no space.
Similar improvements to the detection of headings and quotes have also been added.
Finally, I've added a couple of features which make it easy to know where a link will take you. The first is that I've added a tooltip to each link, so that when you hover the mouse cursor over it the URI will be displayed. But, because not everyone is mouse-oriented in the terminal1, I've also added a status bar to the main viewer panel that shows the URI of the focused link.
As you tab through the links it will update, of course.
This should ensure that links are less likely to be surprising.
If any of this sounds interesting and you want to have a play, Rogallo is licensed GPL-3.0 and available via GitHub and also via PyPI. If you have an environment that has pipx installed, you should be able to get up and running with:
I've just made public, and published to PyPI, v0.1.0 of Rogallo. As mentioned a couple of times recently, it's a terminal-based client for the Gemini Protocol.
This is a very early release, with lots of things still to be added. Right now it's at a place where it interacts with the basics of the protocol, handles the document format, and has the basic navigation facilities you'd expect from a document browser. Things I aim to add over the next few weeks include, in no specific order:
A bookmark facility
Support for the protocol's user input facility (status 1x)
Support for the protocol's client authentication facility (status 6x)
Support for local browsing (I want to be able to view and navigate local gmi files)
A settable home page
The ability to clear down the location history
A cache system
I'll also be updating the TODO list as other ideas come to mind.
Another thing fairly high on the list is documentation. For now, Rogallo should be pretty easy to grasp, and there is a help screen that describes all the keyboard bindings in the current context.
Commands that can be run can also be discovered via the command palette.
For those who care about different looks, there is, of course, support for loading up different themes.
This means that even folk who, for some reason, like light themes, can go light too.
Not really my thing, but I'm told some people like this.
If any of this sounds interesting and you want to have a play, Rogallo is licensed GPL-3.0 and available via GitHub and also via PyPI. If you have an environment that has pipx installed, you should be able to get up and running with:
As I say above, this is very early days for the project, so don't be surprised if you find something missing, or even run into a bug or two. If you need help, have any ideas, or find any problems, please feel free to raise an issue or start a discussion.