Posts tagged with "textual"

Rogallo v1.3.0

2 min read; 9 GFI

Rogallo has been updated to v1.3.0. This release adds an extra cosmetic feature to the Gopher support, and also extends what the internal command line is capable of.

Both of the changes come from suggestions made by -fab-, who's been an avid tester of Rogallo and a good source of pointers and ideas. The first change comes from a mention they made of how some Gopher clients will prefix links in a map with a three-letter ID to give a clue as to what the linked resource is. TXT for a text file, SND for any audio file, MNU for a link to a further map, that sort of thing. While I didn't add that when I initially added Gopher support, it did seem like a useful option to provide.

However, this being a "modern" TUI application, with access to a wee bit more than plain old ASCII, I thought I'd mix it up a little. By default, little "icons" or "badges" are shown with each link. So to take the examples given above, I'm using 📄 for a text file, 🎵 for an audio file, and 📁 for a menu.

Rogallo showing a Gopher hole

Of course, some people might not want this, and this can be turned off entirely in the configuration file by setting gopher_show_type_badges to false. However, it might be that someone wants this, but not the emoji. That's where gopher_type_badges comes in. This is an association of Gopher types with text to use as the "badge". If three-letter all-ASCII "badges" are what you want:

"gopher_type_badges": {
    "0": "(TXT)",
    "1": "(DIR)",
    "2": "(CSO)",
    "3": "(ERR)",
    "4": "(HQX)",
    "5": "(DOS)",
    "6": "(UUE)",
    "7": "(FND)",
    "8": "(TEL)",
    "9": "(BIN)",
    "i": "(INF)",
    "g": "(GIF)",
    "I": "(IMG)",
    "h": "(WEB)",
    "d": "(DOC)",
    "s": "(SND)",
    "P": "(PDF)",
    "X": "(XML)",
    "unknown": "(???)"
}

The other feature springs from another suggestion -fab- made. This time it was the idea of adding direct command-line support for Gemini and Gopher search engines. This struck me as an excellent idea, but I got to thinking that it could be a little more generic than that. So I've added support for declaring simple command-line aliases. There's now a section in the configuration file1 called aliases. It's an association of a command alias and an expansion. The alias itself must be a single "word" of characters, and the expansion the actual command that will be used. It can be any other command-line command, or a URI. Anything that the command line can normally handle.

When the user types something into the command line, the input will be split on the first space. If the first half matches an alias, it will be substituted for the input, and the tail of the input will be made available as a parameter to the expansion.

There are three placeholders that do the expansion:

  • {q} -- The tail of the command quoted for use in a URI
  • {qp} -- As above, but spaces will be + rather than %20
  • {r} -- The raw, unquoted, tail of the command

I've probably done a bad job of explaining it. But hopefully the following default set of aliases will nicely illustrate it:

"aliases": {
    "fg": "gopher://gopher.floodgap.com/1/v2/vs?{q}",
    "gp": "gemini://gemi.dev/cgi-bin/wp.cgi/search?{q}",
    "ken": "gemini://kennedy.gemi.dev/search?{q}",
    "tlgs": "gemini://tlgs.one/search?{q}"
}

Given this, if you type ken test search, the actual command that gets input is gemini://kennedy.gemi.dev/search?test%20search. As I said, it's not just about search engines; you can also expand to other built-in commands. For example:

"whois": "!finger {r}"

Would have whois davep@plan.cat expand to !finger davep@plan.cat.

I feel this nicely solves the original request and adds an extra layer of utility to the internal command line.


  1. Which I totally forgot to document when putting together this release. It'll come to the docs soon. 

Rogallo v1.2.0

2 min read; 10 GFI

Rogallo v1.2.0 is now available. The main change in this release is the kick-off of support for the Gopher protocol.

As I've mentioned before: Gopher is kind of an unknown to me, in terms of actually using it. I'm aware of it, I've known about it ever since I first got on the Internet back in the 1990s, I have a half-recalled memory of dabbling with a Gopher client at some point back then, but I had no conscious knowledge of its workings. So, when I say "kick-off" above, I say it because I suspect there's going to be more work to do to make it work "just so".

However, right now, gopher:// URIs are supported in Rogallo.

Viewing a Gopher site

The approach to supporting this is pretty simple: given a gophermap, as pulled from a server, Rogallo converts it into Gemtext and then displays it using the normal Gemtext viewer.

There is more to Gopher than just displaying the maps, of course: there's access to all kinds of resources. Where possible, Rogallo will display text-based resources within the viewer; all other kinds of resources are handed off to the operating system as they probably need applications and tools that Rogallo doesn't offer (viewing images, playing audio, etc).

Searches (item type 7) are supported, and when following such a link, you will be prompted for input, which will be used as the query.

Prompting for search input

Note that, for the moment, there is no support for extensions to the protocol such as Gopher+. Doubtless I'll look into doing something with this in the future; Rogallo's development is incremental and for me it's all about having fun (re)discovering new/old things.

There are two other notable changes in Rogallo v1.2.0:

  • I've modified the ordering of entries in the history search so that the items appear in most to least recent order. While being able to type in things to find back a location is the primary use, I also found I was often pulling it up to find something I'd visited very recently.
  • I fixed the "view source" status being sticky during navigation. If I was viewing the source of a location, and then navigated to another location (by using the Back command, for example), that other location would also show the source. The status is now reset every time you navigate to somewhere else.

That's it for this release. There's still a good few things on the TODO list so I'll be tinkering and enhancing for some time to come. As always, questions or suggestions are very welcome.

Rogallo v1.1.1

1 min read; 7 GFI

I've just made a small bug-fix release for Rogallo. v1.1.1 fixes two (mostly) cosmetic issues that were reported by a user. From the ChangeLog:

  • Fixed cosy_link_jumps not being loaded from configuration when Rogallo starts up. (#230)
  • Fixed viewer status line being lost when maximum_document_width is set to something other than 0. (#231)

Thanks to fab1 for alerting me to these issues.

One other small change in this release is that the version of Port79 is included in the output from the diagnostics CLI command.


  1. See here if you don't have a Gemini client. 

Rogallo v1.1.0

3 min read; 11 GFI

Rogallo v1.1.0 is now available. This release includes a number of new features and improvements, plus a small cosmetic fix.

Diagnostics

On the off chance that someone else does use Rogallo, and needs help getting to the bottom of some sort of issue, I thought it might be useful to add a diagnostics command to the CLI. Right now it's pretty simple, just dumping some version and environment information.

$ rogallo diagnostics
# Libraries
bagofstuff: 1.2.1
cryptography: 49.0.0
gemtext: 1.0.0
rogallo: 1.1.0
textual: 8.2.8
textual_enhanced: 1.6.0
textual_fspicker: 1.0.1
wasat: 1.0.1

# Python
Compiler: Clang 17.0.0 (clang-1700.3.19.1)
Executable: /Users/davep/.local/share/uv/tools/rogallo/bin/python3
Implementation: CPython
Version: 3.14.0

# System
Name: Darwin
Release: 25.5.0
Version: Darwin Kernel Version 25.5.0: Mon Apr 27 20:40:51 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T8112

# Terminal
Detected: ghostty

Finger protocol support

This was something I was interested in adding, and a couple of people have already requested it, so Rogallo now has finger support. This has been added in a couple of ways. The first and most obvious is that finger: URIs are now natively supported in Gemtext content. So now if you follow a finger:// link you'll see the response in Rogallo itself.

Following a finger URI

The other method is to use the new !finger command that has been added to the application's command line.

Using the finger command

Of course, in the command line, you can also just enter a finger:// URI if you wish, which I guess is a third way of doing it.

Finger URIs are recorded in the history, and can also be bookmarked.

Using an external editor for user input

This was also something I was keen on doing, and then someone else happened to ask for it: support for swapping out to an external editor for writing user input. While the current mechanism is fine for entering a one-liner -- or composing a very short message -- a proper editor (for me that's ideally one with the ability to check spellings) is generally going to be far more useful for a longer body of text. So, with this in mind, the internal editor can now optionally swap out to your text editor of choice.

If you have either VISUAL or EDITOR set in your environment (VISUAL beats EDITOR), Rogallo will let you swap to it by pressing F3 in the internal editor. You can also override that choice by setting external_editor in the configuration file.

Using the external editor

Personally, I'm finding this is working really well with emacsclient. From now on, I'm going to find writing content in Geminispace a lot easier.

Blended pre-formatted text

Now that I've been wandering around Geminispace some more, I've noticed that a common use of pre-formatted text is for logos, ASCII art, that sort of thing. Generally, the sort of things that are best presented with the background the same as the surrounding text. A different shade of background is fine if showing code and stuff, but I feel that this:

AstroBotany logo blended

looks better than this:

AstroBotany logo not blended

To this end, I've modified the pre-formatted text rendering so that, by default, if pre-formatted text has no alt-text, the background is the same as the surrounding text. On the other hand, if it does have alt-text (and so is likely the name of a programming language, which implies syntax highlighting, which in turn implies you want it to stand out), it isn't blended with the rest of the text.

If your preferences differ from mine, you can control this with the new blend_pre_formatted_with_background configuration file setting. It takes a list of alt-text strings that should be blended. By default it looks like this:

    "blend_pre_formatted_with_background": [
        "",
    ]

That is, by default, it only blends empty alt-text pre-formatted text. As it happens, Station uses alt-text for the logo and the user image, but I'd like them blended in too, so I'm running with this:

    "blend_pre_formatted_with_background": [
        "",
        "Station logo",
        "User image"
    ]

Doubtless I'll add others as I run into them.

Fixed mouse hover effect

The last change is a small cosmetic fix to mouse interaction with links. When the mouse cursor is over a link, there should be a hover effect (that is, the background should change colour). This wasn't working if you had link stripes turned on. This is now fixed.

Rogallo v1.0.0

2 min read; 8 GFI

Thirty-three days ago, back on the 18th of June, I created a development directory called rogallo, and started adding dependencies and laying out the main user interface of Rogallo. It's been tons of fun working on it while exploring Geminispace. Given that it's quickly turned into my daily driver, and I'm finding it stable, I've decided it's time to drag it out of the 0verse and consider it worthy of being v1.0.0.

v1.0.0 of Rogallo

I was going to hold off a little longer, mainly because I wanted to flesh out the documentation some more, but that seems like a poor reason to keep it stuck somewhere in v0.x.

To recap, for anyone who might not have followed the development so far: Rogallo is a terminal-based client for the Gemini Protocol. I've built it for my own education. I've built it for fun. I've built it because I want to use it. I've built it hoping that someone else might enjoy it too. Some of the key features, as of this first "stable" release, are:

  • Keyboard-first TUI interface with good mouse support too.
  • Bookmark support.
  • Forward/backward navigation.
  • Location history.
  • Home page.
  • Designed to work on macOS, GNU/Linux and Windows.
  • Trust-on-first-use support.
  • In-application creation of client-side certificates.
  • Full support for user input, both normal and sensitive.
  • Full support for redirections.
  • Context-sensitive help screens.
  • All main application commands available via a command palette or an in-application command line.
  • Themes.
  • Responsive layout that dynamically adjusts to terminal resizing.
  • Support for viewing Gemtext files in the local file system.
  • View source support.
  • Copy-to-clipboard support for URIs or page content.
  • Optionally-numbered links with quick-jump support.
  • Supports ANSI escape sequences in content.
  • Supports filtering out ANSI escape sequences.
  • Emoji filter (lets you remove emojis from most text).
  • Support for handing off unsupported content to the operating system (with safety checks).

Probably some other stuff I've forgotten right now.

On top of this, there's more to come. v1.0.0 isn't the end of the line with Rogallo. I'm having plenty of fun using it, and improving it, and there's more I want to add. I very much want to add in-app support for the Finger Protocol, and I can see myself falling down the Gopher rabbit-hole1 at some point too. While I don't want the application to grow out of hand, I can see plenty of extensions and enhancements that will be satisfying to add.

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 (note that Python 3.12 or later is required):

pipx install rogallo

It can also be installed using uv:

uv tool install rogallo

If you don't have uv installed, you can use uvx.sh to perform the installation. For GNU/Linux, macOS, or similar:

curl -LsSf uvx.sh/rogallo/install.sh | sh

or on Windows:

powershell -ExecutionPolicy ByPass -c "irm https://uvx.sh/rogallo/install.ps1 | iex"

Once installed, run the rogallo command.


  1. Yeah, I agree, probably not the right phrase there. 

Rogallo v0.12.0

2 min read; 9 GFI

I've bumped Rogallo to v0.12.0.

The first change is a simple addition of a !theme command to the command line. As much as possible, I've tried to make sure that every command that's in the command palette can also be run from the in-app command line, but I'd managed to leave this one out. Now you can type !theme and get the theme picker.

Next is the addition of an OpenFile command, bound to Ctrl+o by default. This opens a dialog for browsing the filesystem, allowing for easy access to local gemtext files.

The file opening dialog

Related to this, if you now enter the name of a directory in the command line, the same dialog will open, starting at that directory. Both these changes should make finding local gemtext files a smoother experience.

Another change is to the way that the recently added emoji removal works. I decided that it was a little too aggressive, in that it shouldn't remove them from the content of pre-formatted text. In my experience in Geminispace, so far, pre-formatted text is where the more creative displays happen. Indeed, I had a go at this myself for my new page:

My page, with my image

Here I've used ANSI escape sequences and half-block characters to recreate my usual avatar. The problem is: the emoji-removal approach I've used sees the half-blocks as something to remove. The result isn't great.

My page, with emoji removed

Given that the unwanted emojis will generally be those in body text, links, quotes and headers, I've tweaked the way that pre-formatted text is shown, with it not having emojis removed. I feel this is a sensible approach.

I guess, if anyone really objects to this, I could add a configuration switch that dictates how aggressive the removal is.

The final change is something I wasn't really ever planning on doing, and I felt I'd removed the need for it when I added link stripes. But I got a request to do it and, really, the cost of doing it is nothing. The request? An option to move the link jump labels over to the left.

So now there's a ToggleCosyLinkNumbers command (bound to Super+F8 by default1) which does what it says:

Toggling the jump labels

Personally, I prefer them on the right, where they don't disrupt the left-aligned margin for all the text, but I can see why this would be far more comfortable for others, so... why the heck not?


  1. One day I'll write a post about why I'm giving every command a default binding, even if it's not so accessible in less-advanced terminal emulators. Mostly it's down to one of my least favourite design decisions in Textual mixed with my wish to have a command-based interface that works via the palette first and bindings second. 

Rogallo v0.11.0

1 min read; 11 GFI

A quick update to Rogallo, with changes concentrating on giving the user more control over the content of a rendered page.

Despite the fact that the Gemini Protocol and gemtext are all about things being minimal, some capsules can deliver pretty busy content. Personally, I rather like it, and I'm generally impressed at how creative some people are with these tools. On the other hand, I've noticed that some people don't always appreciate the use of emojis or ANSI escape sequences to provide colour. So, with this in mind, I've added a couple of features to help control the content.

The first is a command to toggle emoji removal. If you're finding the emojis in a page too distracting, use the command to toggle them off and on (bound to F6 by default).

AstroBotany without emojis

The setting is sticky too, so if you're so inclined, you can turn emojis off and they'll stay off.

There's a similar command related to the handling of ANSI escape sequences. While some applications let you toggle this at the capsule level (AstroBotany is one example where it's part of the game's settings), not all do. So I've added a command to toggle this (bound to Shift+F6 by default).

ANSI colour off

With both these commands, if this sort of view isn't to your taste:

AstroBotany and its rich display

You can quickly and easily turn it into this:

Colour and emojis off

I think I prefer the richer view, but I can see the utility of the more austere view.

Somewhat related to the above, I've also added the ability to configure the main "icons" that get used inside the rendered content. So if you don't like the choice of for links within a capsule, for links outwith a capsule, or for a list item bullet, you can change them in the configuration file.

Rogallo v0.10.0

4 min read; 11 GFI

Rogallo v0.10.0 is now available. This release has a number of changes, including some new features, some changes to the user interface, and a couple of quality-of-life improvements.

Maximum document width

Amongst some feedback someone left on a slightly unrelated post over on station there was mention of how a document "should" wrap at around 72 characters. While no rationale was given for the "should" part, I was happy enough to accept that this could be a preference for some people. With this in mind, I've added a configuration option to set a maximum width for documents.

While, personally, I prefer Rogallo's default behaviour (I work in an environment where I can resize a window, and I'm capable of doing it), I can appreciate that someone might want to cap it. So for folk who prefer this, they can now make Rogallo look like this (with maximum_document_width set to 80):

Max document width in action

For the moment this can only be set via the configuration file. At some point I might make this more of a dynamic thing. I can imagine this being something handy, or at least fun, to change up as you're viewing different content.

The same feedback "suggested" that the link jumping facility that Rogallo has should have a timeout that clears the buildup of the number being looked for. This seemed like a reasonable thing to ask for. So, before, if you typed 1, a link with a label of 1 would be selected. If you did nothing for a while, and then typed 2, a link with the label of 12 would be highlighted. With the new timeout (set to 1 second by default, configurable in the configuration file), if you type 1 and then 2 more than a second later, first link 1 will be selected, then link 2 will be selected. On the other hand, if you type 1 then 2 within a second, 12 will be selected.

Setting the timeout to 0 disables this and Rogallo's link jumping facility will work as it did before.

Failed input recovery

With this new feature, if you send input text to a capsule and it rejects it for some reason, the input will be held on to. If you then visit the same URI again, the input dialog will be pre-populated with what you attempted to send a moment ago. This gives you the opportunity to edit anything wrong with the submission and try again.

Added all application commands to the command line

If you prefer to use Rogallo's command line more than the command palette, I've now ensured that all bindable application commands can be accessed via the command line. There's a difference in their form, to stay in keeping with the command line. So whereas in the command palette you'd run GoHome by typing go home, in the command line it becomes a !-prefixed snake-case command: !go_home.

All possible commands are listed in the help screen if it's brought up while the command line has focus.

Help showing commands

Capsule navigation commands

Rogallo now has two new commands for quickly navigating within the current capsule path. GoToParent will navigate up a level in the path of the current URI, and GoToRoot will go to the root of the capsule.

The icon for links is now used to show if a link is already in the location history (and so has been visited before), or not:

Visited and non-visited links

Here you can see that Account settings isn't in the visit history, but the other two links are. I was going to do the whole link, but I've never been a fan of how web browsers do this, so I've gone with just the icon. I've also made it subtle but still noticeable. So far, I'm much preferring this; I don't need it blasting out the difference, I just need it to be enough for me to notice1.

Swapped around history and bookmark tools

Until now the "history" and "bookmarks" shortcut keys advertised in the footer brought up the sidebar-based management widgets. This made sense when that's all I had in Rogallo. For a while now though I've had palette-based search tools for both history and bookmarks. Normally I want to search for and select a bookmark or history item way more than I want to manage those lists. So I've relegated the sidebar-based tools to a secondary position and placed the palette-based search tools up front.

This also means that the default bindings have changed a bit. As always, you can discover the bindings with rogallo bindings.

Conclusion

I know I've nodded towards this before, but I think I'm getting close to making a v1.0.0 release. I want to daily-drive for a few more days, and I'd also like to expand the website. I'd also like to build a Gemini/Gemtext-based site for Rogallo -- it'd be pretty weird if I only documented it in http(s)space. I won't let those wishes become blockers for moving to calling Rogallo "stable", but it would be nice to have.


  1. I do recognise that there's an a11y issue here with the subtle difference; there's some work to be done at some point to allow for a high-contrast theme that will resolve this sort of issue. 

Terminal bean soup

3 min read; 10 GFI

I'm sure most people reading this will be familiar with the concept of "bean soup theory". In case anyone isn't, here's how Wikipedia describes it:

A specific phenomenon described as a 'What about me' effect. An individual watches a video that doesn't pertain to them, but finds a way to make it about them anyway. Stems from a 2023 TikTok recipe for bean soup, with commenters saying "What if I don't like beans?"

I feel there's a very specific set of folk who love to "bean soup" anything relating to terminals, and it's common to have them turn up in your mentions if you happen to do anything in the terminal, or for the terminal, that isn't about their purist opinions and how everything must be a Vim clone, or worse.

I first encountered this when I started working at Textualize. Unsurprisingly, given the point, purpose and focus of Textual, some folk would turn up in the Discord server, in the issues, in the discussions, in the mentions of posts in various places, and post their very important opinions about how TUI software must work. Not... discuss their preferences, or offer suggestions (there were plenty of people who were pleasant like that, they were lovely to converse with), no: their engagement was written as if every word that was mashed into their keyboard was a well-crafted, handed-from-on-high RFC-like holy document that MUST and SHOULD be followed1.

If I was being very charitable I could cut them some slack. If you're building a framework for building applications for the terminal, there's a good reason to make it at least possible for the application authors to follow recognised best practice and to stick with hard-won conventions. Indeed, Textual has some design choices that I think are deeply questionable and misguided and I objected to them on more than one occasion. So, yeah, if I was being charitable, I could cut them some slack.

I could... if they weren't such arseholes about it.

This gets worse though if you're building an application for the terminal, especially if it's built as Free Software and the motivation is to build something for yourself and be kind enough to share. It irks the hell out of me when I build some application for myself, as a TUI, and then someone turns up and starts complaining about my choice of default key bindings, that work in my choice of terminal emulator and my configuration for that emulator.

It's even worse when they do it in a way where they have to show their very deep knowledge of terminals, and how they're very proud of just how lacking in features and progress their own choice of terminal emulator is.

Dude...2 I know. I've used physical terminals. I've written COBOL on a minicomputer using a line editor on some honking great dumb all-green all-in-one box. I've even written code on a terminal using fan-fold paper. I've used all sorts of terminal emulators. I spent well over a decade doing shit inside rxvt which was running on my GNU/Linux server while displaying on my Windows desktop machine.

I've installed and tested plenty of terminal emulators.

I'm well aware of the conventions and expectations. If Ctrl+C doesn't quit... that is my choice. It's not ignorance, it's not a lack of history with this stuff, it's a choice. For my software.

So when you turn up and feel the need to tell me that some function keys might not work in some terminal on some GNU/Linux box... I get it, you don't like beans. If that's the case, how about you either don't make my hobby all about your tastes and how I should build my application to suit you, or how about you RTFM and configure my application so it works in your choice of terminal?

I mean... we know you won't. We know you don't even care about the application I'm having tons of fun building, that I'm spending time in a joyous flow-state creating and tinkering with. You just care about making the post all about you and your purity. We know you just care about showing how smart you are.

We know you just can't resist the urge to reply-guy3.

We get it: you don't like bean soup. Nobody cares. Nobody asked.


  1. That reminds me: one day I should write a rant about the folk who obsess about the "Zen of Python"

  2. Let's be honest: it's always a dude. 

  3. Let's be honest: it's always a guy. 

Rogallo v0.9.0

1 min read; 9 GFI

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:

```python
def hello(name: str = "World") -> str:
    return f"Hello, {name}!"
```

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.

Pre-text with syntax highlighting

If you're curious which languages are supported, it should be anything that Pygments supports.

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):

The input count

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.

Too much 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.


  1. Although I've already encountered one capsule that limits to 1022, from what I can tell

  2. 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.