VF-1 updates and tips --------------------- I'm very happy to have had both the time and motivation to get quite a bit of good progress made on my gopher client VF-1 recently. This post will mostly be an update on some of the new functionality. But first, some usage tips! I noticed recently that tfurrows has been keeping a list of tips[1] on his circumlunar gopherhole (where he explores the bookmarking functionality more deeply than I ever have!), and thought I might contribute a few of my own. First of all, an embarrassing revelation - when I recently wrote my allegedly definitive guide[2] to viewing "long stuff", I forgot about one option for handling long menus! There are so many options even I forget them. That said, this one is not one of my favourites, it was an early hack to help people who were struggling in earlier days before "less" worked on menus. When you use "ls" to list the current menu selectors, you can give it the "-r" option (i.e. "ls -r") to view the listing in the reverse of the usual order. Thus, items at the top which would normally go flying off the top of your screen appear at the bottom where you can always see them. The obvious downside, of course, is that stuff is backward. I don't really recommend this approach, but thought I'd mention it for completeness. Onto something a little more useful! You are probably already aware that VF-1 lets you set any external command you like as a handler for different kinds of content. By default, the handler for "text/plain" is just good old "cat", which does nothing other than spit the text onto your screen. If it overflows, you can run the "less" command to look at it in your favourite pager. An alternative to this is to use less as your text/plain handler, but feed it a few more options. For the past few days I have been using "less -FXR %s" as my default plain text handler. The -F option tells less to immediately quit if the file is short enough that it fits entirely on one screen, and -X option tells it not to clear the screen after exiting (as is the default behaviour of more). What this does is basically turn less into an automatic "cat if short, less if long" viewer. The -R is just there so that ANSI colour codes don't get mangled (more on that later). This means stuff never flies off the top of your screen, and you never have to manually run less to read the top of something. This results in a pretty seamless experience and I think I'll stick with it. Okay, time for new features. Starting with something very minor, the "text/plain" handler is now used for both item types 0 and 1, whereas previously it only worked for type 0. This change was inspired by Tomasino who, when learning about handlers, immediately set his to lolcat - something I'd never heard of. I encourage you to check it out, even if only briefly for, well, the lols. Basically you can pipe text through it and it uses ANSI colour codes to render that text into a GLORIOUS RAINBOW. We're talking hundreds of colours, each character slightly different from it's neighbours. Tomasino was disappointed that this worked on content but not on menus (which in his case means his entire phlog), the handler is now applied to menus too so you can enjoy ubiquitous rainbows in gopherspace. Tomasino was *also* disappointed that the colours disappeared when he used the "less" command, because until now that command ignored the text/plain handler and just fed the content straight to less. Now, the "less" command runs your text/plain handler and pipes the output of that to less (or rather, less -R, to preserve colours), so you can get colours even when you are lessing! To more fundamental changes, Tomasino has once again spurred me to make some improvements, in his recent championing of better support for the "+" item type which is used to specify redundant severs, i.e. gopher servers which host a mirror of the content at the current server. The RFC is pretty vague about exactly how this is supposed to work. Most modern clients take a very minimal approach to supporting this, and just list the mirror items like they would any other link but do something minor to indicated "hey, this is a mirror". I think the intent was probably for clients to do a bit more with this. The RFC has various comments in it which makes it pretty clear (to me at least) that the target environment for gopher was under-resourced university departments setting up servers on whatever old and under-powered hardware they had lying around, and spreading information over as many servers as possible to reduce load. Early gopher servers were probably expected to fail regularly. So VF-1 tries to handle + items in such a way as to reduce the pain of servers. After seeing that content at server A is mirrored at server B, if an attempt to fetch something from server A later during the same VF-1 session results in any kind of network error, VF-1 will automatically try to fetch the content from server B instead. The usefulness of this in 2019 is arguably limited - for one thing, modern gopher servers are probably extremely powerful and extremely under-loaded compared to early servers, and for another there is no caching of redundant servers, so if the "main" server you attempt to visit is down, you have no way to learn what the backups are. It's not perfect, but it's better than nothing, and I'm proud that VF-1 actually makes an effort to *do* something with this information. Speaking of being proud, the other significant changes are related to text decoding, and I suspect VF-1 might now be the best gopher client in town for people who regularly visit content encoded in a variety of non-UTF-8 forms. Tomasino had nothing to do with this change, which was instead prompted by the latest user at circumlunar.space, tengu[3], who had some initial problems serving Russian text from his gopherhole there, whether using UTF-8 or older Cyrillic encodings like KOI8-R or CP1251. With some digging, it turned out that this was mostly the fault of Gophernicus, but VF-1 could stand some improvement too. In the earliest versions of VF-1, I assumed that all text coming over the wire would be either ASCII or UTF-8 (which decode identically) and left it at that. This worked fine for about a week until someone on BBOARD reported that VF-1 died when trying to read some news article over at floodgap's feeds. It turned out that the article contained a name with an accented character in it, which was encoded in ISO-8859-1. So, I did a bit of research, learned that the 3 most commonly used encodings on the web are, in order, UTF-8, ISO-8559-1 and CP1251. So, I updated VF-1 to try these, in order, moving down the list each time one failed. If you know anything about text encoding you'll recognise how naive this was. Any text which is valid CP1251 is also valid ISO-8559-1, so an attempt to decode as ISO-8559-1 will never fail. It may result in gibberish, but it won't throw an exception, and so CP1251 text will never be decoded properly. So, now VF-1 attempts to decode everything as UTF-8 first and, if that fails, tries a single fallback encoding. That fallback defaults to ISO-8559-1, but it is under direct and easy user control using the "set" command, so you can do "set encoding cp1251" to change the fallback. If you regularly deal with just one non-UTF-8 encoding, you can of course stick this in your ~/.vf1rc file to make it permanently. But wait, there's more. There is a very nice Python library called chardet which attempts to automatically detect text encodings making use of language statistics. You can decode CP1251 as if it were ISO-8559-1 no problem, but you'll end up with gibberish text whose n-gram distribution won't match any natural language. Chardet uses this fact to guess encodings and with a little practice it seems to work quite well. Now, I am very proud of the fact that VF-1 has no dependencies outside the Python standard library and that all of the code is in one single file. All of this makes it extremely easy to install, even in weird environments where modern tools like pip are not available. I don't ever want to change this, so VF-1 does *not* depend on chardet. But, if you install it yourself, VF-1 will recognise that it's there and adopt the alternative strategy of autodetecting the encoding if UTF-8 fails, and will drop back to the user-specified encoding only if chardet fails to identify an encoding with confidence above 0.5. With chardet installed, I was able to use VF-1 to cruise around some Russian gopher sites tengu linked me to, and whether I encountered UTF-8, KOI8-R or CP1251 encoding, it all Just Worked, which was tremendously satisfying. VF-1+chardet seems bullet-proofly international, which is fantastic. As an aside, I was amused to note that the chardet FAQ[4] has the following entry: > Yippie! Screw the standards, I'll just auto-detect everything! > Don't do that. Virtually every format and protocol contains > a method for specifying character encoding. The FAQ goes on to talk about HTTP, HTML, XML, etc. Out here on the plain text frontier, of course, there ain't any such thing (well, maybe the /caps.txt hack does something about this, hmm...), so I don't feel bad at all about auto-detecting everything. It's pretty much the only choice we have. For the record, this is *not* something that I think it is worth extending gopher to work around. There is a much simpler and nicer solution, which is simply to use UTF-8 for absolutely all new content in gopherspace, so that there is no *need* to explicitly specify the character encoding. That's all that's new, aside from some tiny tidy ups and fixes. There are a few other small things I'd like to tackle, but it's starting to feel pretty complete for me. [1] gopher://circumlunar.space:70/1/~tfurrows/tips/ [2] gopher://circumlunar.space:70/0/~solderpunk/phlog/looking-at-long-stuff-with-vf1.txt [3] gopher://circumlunar.space:70/1/~tengu/ [4] https://chardet.readthedocs.io/en/latest/faq.html