roadrunnertwice: Dee perpetrates some Mess. (Arts and crafts (Little Dee))

So if you have access to an Apache2 server that allows .htaccess overrides and has mod_actions turned on, you can make a single CGI script take over the whole URL hierarchy for an entire site. (Or just for a subtree of it, although the app would need to be aware and ready for that.)

In short, you make a new directory called __internal (or something) at the top of your site, and put your CGI executable in there with a filename of my-app.cgi (or something). Then you make TWO .htaccess files.

The root-level .htaccess disables special handling for bare directories, then tells the server to unconditionally use your CGI script to handle every URL pointing into your site, without consideration for whether a path would otherwise aim at a file on disk.

# Root-level .htaccess file
Options -Indexes
DirectoryIndex disabled
Action my-app "/__internal/my-app.cgi" virtual
SetHandler my-app
AcceptPathInfo on # that's the default, but still

That CGI path in the Action directive needs to be a URL path pointed at somewhere reachable on your site, rather than a path on disk. That's kind of odd, and it hung me up for a while when I was trying to get this working! But the upshot is, we now need a second .htaccess in that __internal directory that un-does everything we did in the root-level .htaccess so that the server can actually resolve that script. (Otherwise you end up in a recursive loop and the site doesn't work.)

# .htaccess file in /__internal
Options +ExecCgi -Indexes
SetHandler None
AddHandler cgi-script .cgi

Ta-daaaa! Now your program can handle all the top-level routing for your site, using CGI vars like REQUEST_URI to reconstruct the original request and do your routing. (And don't worry about needing to keep __internal private or anything, it just needed some kind of weird name to avoid trampling on any of your app's real URL paths.)


A lengthy digression on the nature of Script Soup )

roadrunnertwice: Weedmaster P: "SON OF A DICK. BALL COCKS. NO. FUCKING." (Shitbox (Overcompensating))

As mentioned previously, this year I switched to hosting eardogger.com in what's either a highly unconventional environment or an unusually conventional environment, depending on your perspective. This has mostly gone completely fine! However, I did have one incident several weeks ago, and it was a funny one.

I was out reading webcomics on my phone, and got creepy 500 errors on Eardogger; when I got home, the logs showed a Resource temporarily unavailable error when trying to access the database.

⁉️ (Metal Gear Solid guard alert noise)

All right, first off: That database isn't a remote server; it's a file on the local disk. If THAT's "unavailable," something's very wrong. A quick web search indicated that error comes from the operating system itself, not anything in my tech stack (like sqlite maybe). At some point, I visited a page on the site, then tried to run a command in my SSH session:

$ ls
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: Resource temporarily unavailable

Hahahaha holy shit.

Ok anyway, long story short: I was hitting my user's process limit and being prevented from spawning new processes or threads. The 500s were happening when concurrent DB reads would have made the reader pool spawn a new thread, and it hit the wall instead.

A given user may only run a certain number of processes at once on this server. Eardogger is at maximum a single process instance, so I thought I was fine. But then my web host upgraded my server's OS, which changed the process limit accounting to also include sub-process threads. And Eardogger IS multi-threaded.

How multi-threaded, exactly? Well, I was using the Tokio multi-threaded runtime with default configuration. And it turns out the default behavior is to immediately spawn one worker thread per logical CPU core...

...on what turns out to be a 128-core web server. The process limit (not advertised, but support will divulge if you ask) is 25.

I wouldn't want that even if it WAS allowed!! This app has like three goddamn users! I made my thread pool configurable and set it to single digits, and that immediately banished the errors and the shell lockups. 🌈 As a bonus, it also cut the app's cold startup time from "barely perceptible" to "legit gone" — apparently spawning more than a hundred threads on startup takes a noticeable amount of time, but Rust is so fast in general that it covered most of that sin and I wasn't immediately suspicious.

Lessons learned:

  • Resource heuristics that inspect the local system's capacity are a huge red flag, because they act normal on your laptop and then go berserk elsewhere. Set your ceiling explicitly!
  • top and ps on Linux don't list threads by default, you have to use an extra argument to see that.
  • Wow.

EDIT: But actually, in most modern deployment scenarios, your server's CPU and memory resources really are much closer to the scene on your laptop, since the standard practice is to slice up computer resources into tiny single-purpose shards via containers or VMs. Like, Ruth was showing me something from her work that we would both consider "fairly extreme" in terms of resource allocation, and I was like "oh yeah, that's a whole lot of laptop... but it ain't a web server, you know?" So yes, this whole problem did in fact stem directly from my runtime environment being weirdly atavistic, and most people are probably fine with Tokio's default behavior.

The Rewrite

May. 9th, 2024 10:30 pm
roadrunnertwice: DTWOF's Lois in drag. Dialogue: "Dude, just rub a little Castrol 30 weight into it. Works for me." (Castrol (Lois))

I run Eardogger.com, the web's favorite unpopular bookmarking tool for binge-reading webcomics. It's about four years old, and it's currently built on Typescript, Node.js, the Express web framework (with some add-ons), and PostgreSQL.

I've been rewriting the whole thing in a new Pile of Stuff — Rust, the Axum web framework (and the Tokio + Tower + Hyper ecosystem it's built on), Sqlite, and my experimental FastCGI/HTTP reverse-compatibility layer. (Yup: this was the secret endgame for that whole project.)

All features are complete. I've got the rewrite deployed in realistic hosting to do some soak testing, and it's working amazingly well. Most of the remaining to-dos are either rewriting my integration tests, or ancillary stuff like backup jobs, release scripting, and data import scripting.

A rewrite, huh? 😒

yeah dude )

Also it was fun, right?

Haha yeah, it totally was.

Axum is really nice to work with! It combines some of my favorite parts of Express (Eardogger's old framework) and Bevy (the game engine I've been working with on another project). And the way it's able to give strong type guarantees to handlers (despite being flexible and comfy to work with) means the code can inherently represent a bunch of assumptions that otherwise I would have to remember somehow; that should be really nice for future maintenance after I haven't touched it in two years.

I'm doing the database stuff in sqlx, which is mostly pretty great. I'm using the compile-time-checked query macros; it's true, they add some significant extra build weirdness, but once again, it's all about the maintenance — those automatic checks let me skip a huge amount of otherwise-manual testing. During development, it caught a ton of bugs and schema problems before they could even take root.

For templates I'm using minijinja, and it's all right. I've never met a template language I love yet, so it's par for the course. I investigated a lot of alternatives, and I think the design constraints of this one seemed easiest to live with.

And using busriders makes it feel like I'm somehow beating the system. 😛 I love it.

Here's the code for the rewrite, if anyone's interested.

roadrunnertwice: DTWOF's Lois in drag. Dialogue: "Dude, just rub a little Castrol 30 weight into it. Works for me." (Castrol (Lois))

Julia Evans’ StrangeLoop 2023 keynote was about digging into the different reasons a tool can be hard to learn, and it was a real good talk! At the end, as a tossed-off addendum to a conclusion about continuing to learn things, she said “I still don’t know why Git is hard.”

I happen to have thoughts about that one!

I have had to teach a fair number of (generally clever and persistent) people how to get around in Git or how to use its more advanced features. While doing so, I have often failed to get the basics to stick, which is incredibly aggravating to someone who prides themselves on explaining things. Sometimes this devolves into me talking about wave/particle duality as a crucial metaphor for getting through a rebase intact, and everyone in the room looking at me like my second head just tried to convert them to Gnosticism.

So, I’ve spent some time thinking about this before this weekend.

Read more... )

roadrunnertwice: Wrecked bicyclist. Dialogue: "I am fucking broken." (Bike - Fucking broken (Never as Bad))

I'm brushing up on my Ember this weekend (for reasons), which is something like 50% re-learning syntax and standard library stuff, and 50% just stabilizing my mental models for how stuff fits together.

So since I'm thinking about the experiences I had when learning this stuff the first time around, here's the thing I most wish I'd been told basically before doing anything else:

Ember-style Handlebars isn't a text-processing language.

Every* other templating language I've met is content-agnostic and only does naïve text transformations, and if you go into Ember expecting that, shit like this looks absolutely, comprehensively haunted:

<button 
  {{on "click" this.saveProfile}}
>
  save
</button>

First time I encountered that I felt physically queasy, bc it looks like that on call will be replaced by some run of text that causes the element to get a click handler, and there's z e r o imaginable safe-and-sane way to implement that.

But in fact it's fine — that template directive doesn't get replaced by text at all, because .hbs fucking cheats! It's fully aware of the semantic, structural, and runtime rules of its HTML content, and it gets compiled into live JavaScript instead of a static HTML fragment string. So that "on" thing is a separate piece of syntax called a "modifier," and instead of inserting something into the HTML text, it waits 'til that <button> has a DOM element and then uses .addEventListener on it.

Anyway, tbh I'm not 100% sure what I would have told myself to save me the motion sickness. Maybe just: .hbs cheats and knows how browsers work, so some of its syntax acts on DOM APIs instead of on raw text.


* I guess the one exception is HAML, but HAML is also just generally deranged.

roadrunnertwice: Weedmaster P: "SON OF A DICK. BALL COCKS. NO. FUCKING." (Shitbox (Overcompensating))

Well I already posted about it on the one community where anyone's likely to give a damn, but I built a thing that'll stand up a working Dreamwidth dev instance on your laptop for you. Fill out the config file, vagrant up and answer "1" to its question, go into energy saver and tell your computer to not go to sleep for a while, and literally go out to lunch or something (installing perl modules is way slow for some damn reason), and you should have yourself a Fukken Livejournal when you get back.

The instructions on the wiki were honestly pretty dece, but there is no way in hell I was going to do that all manually. You never wanna be in a situation where if the shitbox VM goes down it takes part of your brain with it.

Why was I even doing this? Well, all the CSS offroading I did in my most recent journal style refresh taught me how to fix at least two or three of the top five (imo) most obnoxious pieces of Dreamwidth mobile jank. I've already got PRs in to fix two of them:

...and across the two of them, I kind of snuck in a fix for another real stinker, where mobile Safari zooms the viewport to unusable hugeness as soon as you focus a form field. Maybe someone'll ask me to rebase that into a separate thing, idk.

Anyway, I feel powerful. 💪🏼

roadrunnertwice: DTWOF's Lois in drag. Dialogue: "Dude, just rub a little Castrol 30 weight into it. Works for me." (Castrol (Lois))

Hi, I redid my journal style for the first time in ages! I did not even briefly consider making it any color other than baby-aspirin orange. Also I named the new one "Scratch the Surface," as an homage to my old five meg home base. (Good god, have I really been Extremely Online for 20+ years.)

This time around, I actually dug into Dreamwidth's S2 style system and made my own "theme layer" over Tabula Rasa. I've never done that before! I was vaguely aware of some kind of concept of "~layers,~" but had no idea what was actually involved until a couple days ago.

How about that S2 business, huh? Though TBH it's more like, "how about LiveJournal-descended technologies in general, huh?" Like many of those, this one is very clearly a product of a particular time and place ("people want to build complex document tree-structures and/or roll their own CSS pre-processors by composing Perl subroutine calls!"), and you can't exactly call it "good" per se... but you definitely have to respect the amount of insight and thoroughness that went into it. I can recognize at least five or six of the specific template language grievances that drove the design here — they're ones I've wrestled before without seeing any good way around them, and S2 has at least semi-reasonable answers. But also, WOW. The language design is usable and the docs really aren't that bad, and ultimately I spent like 80% of my time wrestling with CSS anyway, but I kind of feel like I just french kissed a coelacanth.

Anyway, this was a great chance to fix some things that have always bugged me about most of the built-in layouts, especially on mobile. New one should be fairly solid, unless I use a table in a post, in which case I probably deserve what I get in the first place.

roadrunnertwice: DTWOF's Lois in drag. Dialogue: "Dude, just rub a little Castrol 30 weight into it. Works for me." (Castrol (Lois))

K, idk if y’all have ever messed around with the iOS “Shortcuts” app, but it turns out it is Legit.

So. On my Mac, I use a pair of oddball note-taking systems that I made out of baling wire, scrap lumber, and keyboard shortcuts over a decade ago and have been using daily ever since:

  • “Garbage Book” is just a clone of Apple Notes,* except that it uses my normal text editor instead of a separate app that I don’t like as much.
  • “FMP”** is, uh, baroque. There's a hotkey to get a text field that appends to a special text file. If I append a line that starts with something like ^didread, it’ll eventually get moved to a file like didread.txt (courtesy of a second hotkey that refreshes everything). And there’s yet another hotkey for quickly opening one of those note files by name.

    (I do realize what that all sounds like to a normal person, but trust me, it's a specialized ADHD workaround that solves some particular annoyances for me in a really sweet way.)

Since both sets of notes are just plain text files in a synced folder, I've always been able to access them on my phone. But it was way more awkward and slow, and I've always been on the lookout for ways to improve it.

Anyway, yesterday my dad was having brain surgery (he's doing fine, everything went great), and here's a thing about when someone close to you has major surgery: you sit around for a long-ass time, and you can't concentrate on any actual responsibilities for the whole duration (basically because the entire part of your mind that gives a flying fuck about responsibilities is wholly occupied with reacting whenever it's time to do something for said loved one). But a really frivolous and finicky project can be a great way to not obsess at 20,000 RPM over hypothetical stuff that you can't do anything about, so I decided to crack open that Shortcuts app that came out with iOS 12 and see if there was anything to it.

THERE IS. The card-based editing interface is weird as heck (it has some real strengths for programming on a touchscreen, but it also makes refactoring a pain in the ass, and was probably not intended for use on an iPhone SE), and the lack of some basic niceties like and/or expressions is pretty embarrassing (you can implement boolean logic yourself by adding more variables, but it looks like legit hell), but behind all that is a remarkably functional little scripting language with a coherent and consistent core and really unmatched discoverability.

It's probably even nicer for scripting apps that provide "real" Shortcuts actions, but even with just iA Writer's URL-based scripting and the built-in actions, I was able to completely*** re-implement both Garbage Book and FMP on my telephone over the course of two afternoons!

I now have little buttons on my "today" view for starting a new Garbage Book page, appending a line to my dump file, opening an FMP ^caret-tag file by name, and sorting ^caret-tag lines out of the dump file and into their real homes. (That was the one I didn't think would even be possible, but I totally did it!) And it all plays nicely with the edifice of Mac scripts that I've been using since '06.

Anyway, very satisfying results, a very impressive tool, also A+ distraction for that mandatory fret-in-the-hospital downtime.

_____

* Except this was ca. 2007 so it was more like a clone of Notational Velocity.

** Fast Memo Pencil? Fiendish Master Plan? Free Mashed Potatoes?

*** Wellll mostly completely. There's one thing I couldn't do on my phone from the original Garbage Book script: include part of the first line of text in the filename. That was always a nice feature, but c'est la vie; it's just a problem of different editing paradigms. In BBEdit I start by opening an empty editor window and typing for a while before hitting the Garbage Book hotkey to save, but in iA Writer I have to start by creating the file, so there's no first line of text to grab. I guess the editor itself could update the filename (Notes does this!), but it would have to know about my timestamped naming scheme to do that.

roadrunnertwice: Weedmaster P: "SON OF A DICK. BALL COCKS. NO. FUCKING." (Shitbox (Overcompensating))

the relevant xkcd strip

This is long, and it's about troubleshooting an exotic driver issue. )


Of course, I'm probably going to replace the damn thing eventually anyway because the download speeds are so heinously slow. Earlier I used connection sharing via Ethernet to plug the PC into my MacBook's wireless, and it was literally like ten times faster.

Well, still, I was offended that I couldn't understand what was going on and I really wanted to win, so I guess it was worth it just for that.

zsh

Dec. 23rd, 2014 06:26 pm
roadrunnertwice: DTWOF's Lois in drag. Dialogue: "Dude, just rub a little Castrol 30 weight into it. Works for me." (Castrol (Lois))

I finally switched from bash to zsh, and it was totally worth it.

I was paranoid about how much time it was going to take, but it turns out the trick is to do as little as possible, and most of your bash customizations will still work. It basically went like:

  • Refactor your dotfiles to just isolate any bash-specific stuff that's in there. .bash_profile should consist of source ~/.bashrc; .bashrc should have your little handful of bash-specific configurations followed by source ~/.profile; and .profile should have all the aliases and simple functions that will work in both.
  • Install oh-my-zsh and assemble a really simple .zshrc file. At the bottom, put source ~/.profile to catch all your old bash aliases and functions.
  • Look through the list of themes on the wiki and find something that looks familiar enough that you won't feel weird. I went with muse.
  • Maybe make one or two edits to that theme and save it as a custom one. I looked through lib/git.zsh and figured out how to add an indicator that my git branch is ahead or behind.

In the end, I got pretty much all I needed out of the box and only had to make about a four-line edit to the muse theme. Better tab completion, and I can spend about 90% less time running git status at work.

I realize this is of limited interest to this blog but oh well.

roadrunnertwice: Joe and bike, at top speed. (Bike - Liftoff (Yehuda Moon))
I bought a new iPad! It finally finished syncing! I am totally amped about this. (I went for the regular size with schmancy display and cell phone radio. The mini is cute, but believe it or not, I actually type on these things, and mini seemed too mini for that. Also, apropos of nothing, I’m gonna cough up a lung on the next person who uses the word “consumption” to describe electronics. Stop doing that.)

Listen though, I kind of love the iPad. Contains too many words about gadgets. )
roadrunnertwice: Dialogue: "Craigslist is killing mothra." (Craigslist is killing Mothra (C&G))
@Skud: not sure how i feel about http://app.net. i'm all for paid services to avoid values mismatch b/w users/advertisers/service operators
@Skud: but the sites i know that do that best (eg. @dreamwidth, @Pinboard) also have a very human/community feel that i don't see here
@nfagerlund: @Skud I feel that. W/ DW, I was immediately like “seems legit; I can tell who these folk are & how big it can get.” A.n is like Diaspora.
@nfagerlund: @Skud …by which I mean their story is critically incomplete in some way I can’t yet put my finger on.
@Skud: @nfagerlund yeah, i get that feeling too. which is not necessarily an impediment to their platform taking off...
@Skud: @nfagerlund ... but does mean that my gut feeling about them is a bit nervous

Yeah, so [twitter.com profile] skud was doubting on app.net, and I am doubting on it too, and I don't have much more to say about said putative service at the moment. But I'm posting because I think I finally DID put my finger on what was wrong with Diaspora! And I am very proud of myself for it.

So Diaspora was meant to be Facebook without all the evil, right? Here's the problem with that: Facebook without the evil is NOTHING.

Because what the hell even IS Facebook? The answer changes significantly every nine or ten months. I joined it in January 2005 because it was a visual address book to my college, and I needed that when I was looking for a new sublet. Then it turned into a walled-garden email replacement. Then it turned into Flickr for spring break photos, then it finally managed to replace the .plan file, then it was also Livejournal for about a month, then it tried to be Craigslist for a summer, then it was Twitter with less focus, then it was a platform for shitty little games that you pay real money in order to not have to play. Now it's just sort of an undifferentiated mishmash, although it seems to be turning into Tumblr lately, mostly to accomodate George Takei.

Obviously there is no common thread. Facebook's soul is not in what it does for you or allows you to do. The product itself, the THING that Diaspora tried to copy, is frankly irrelevant. The one thing that has always made Facebook Facebook is that fucking practically everybody you know is on the goddamn thing, and they got there because Facebook was persistently and craftily evil.

The original short-lived college-scope restrictions on the thing were brilliant, because they made people let their guards down, join up, and put their personal info in. That made it easier for peoples' friends in other colleges to find them, which anchored them further in. All the effort to make it difficult to add people to your normal email address book meant that you were signing in on a regular basis to get/send messages, and would be more likely to see new friend requests and other activity, which would keep you interested. Let's not even get into that Zynga Skinner box. Etc. etc. etc. The only reason you're on Facebook now is because they were evil, and although you'd leave if your friends left, they're all still on there because of the evil. The fact that everyone is there makes Facebook a horrible place most of the time, but it also makes it indispensable, and the fact that you can't properly export your information makes it non-disposable and non-replaceable.

I don't think the people behind Diaspora ever understood any of that. They thought people were on Facebook because Facebook was a good app, and people actually wanted some atrocity that was kind of like Tumblr/Flickr/Twitter/LJ/toilet-graffiti/emotionally-abusive-Gameboy except worse. That's manifestly not the case. People want everyone they know in one place, and the only way to give them that is to be evil. Which makes it impossible to replace Facebook with any less-evil alternative -- whatever eventually kills Facebook will win by being either MORE evil, or more SOPHISTICATEDLY evil. And since Diaspora was unable to compete with Facebook, it found itself competing with all the non-Facebook focussed-purpose services like Twitter and Flickr and DW and Tumblr, and it since it was built to be worse than all of them, you probably still aren't using it. Of course, you're probably not using Dreamwidth, either. You probably ARE using Twitter, and I'll be interested to hear app.net's plan for dealing with the fact that 80% of Twitter joined Twitter because all their friends were on Twitter.

Yes, this is depressing and annoying. Whatever, let me have my moment of explanatory triumph.
roadrunnertwice: Weedmaster P: "SON OF A DICK. BALL COCKS. NO. FUCKING." (Shitbox (Overcompensating))
The rest of the house is shoulder-deep in a computer-box, building a gaming PC for a friend of ours. I am staying out of that.

I think the last time I cracked open some compu-tower ribs was at the yarn shop back in 2009. We had these three mildly crappy Dell P4 towers for running the POS system and everything, but they were acting like they were the ultra crappy kind. Just slow as hell and unresponsive and bullshit. Stev and Hannah were all angsting about whether we could afford new ones and how to go about getting them, and I was like, "lemme take a look." Reader, these 3Ghz machines were choking along on a half-gig of RAM each. I got on Newegg, and was like "Gimme the credit card, I'll get you some rejuvenated computers for like $140."

Once the sticks arrived, I got the backroom and cafe computers beefed up and breathing easy in like 20 minutes. Then I upgraded the main counter PC, tried to power it back up, and got nuthin'. I cracked it open again to make sure I hadn't left anything loose, and we were all like "Uh, was that creepy amber light there the last time?" It was totally not.

I searched the internet for the manual again, and it turned out the amber light on the mobo meant "power fault," usually a bunk power supply. So I grabbed a screwdriver and tore the fucker out, tossed it in my backpack, got on my motorbike, and jetted up Milwaukie to Free Geek, where they confirmed it was toast and sold me a better one (for the $15 I had liberated from the petty cash drawer). Which totally solved the problem, and left me feeling like quite the techno-samurai moto-badass.

And then the whole shop folded explosively in August and we were all out of work, but at least the computers were non-bullshit for as long as the shop survived.

Spoilers

Feb. 12th, 2012 01:40 am
roadrunnertwice: Weedmaster P: "SON OF A DICK. BALL COCKS. NO. FUCKING." (Shitbox (Overcompensating))

I like using spoiler text! Spoiler text doesn't like iOS. Or vice-versa, whatever.

Anyway, I found a trick today that works great on both desktop and mobile, and which will work without Javascript, which means I can use it on my Dreamwidth! Unfortunately, you don't get the benefit unless you're viewing the entry in my style, and I don't get the benefit unless you write your spoiler tags such that they'll work the same way on my reading page. Frustrating. But it degrades gracefully to normal-acting spoiler text, so what the hell, I'll use it anyway.

It goes a little like this:

Go here to add custom CSS to your style, and add the following:

a.spoiler, a.spoiler:link, a.spoiler:visited {color: #3a3a3a; background-color: #3a3a3a; text-decoration: none;}
a.spoiler:active, a.spoiler:hover {color: #000 !important; background-color: #e7e7e7 !important; text-decoration: none;}

Then, you can make spoiler text like this:

Normal text, <a href="##" class="spoiler" style="color: #3a3a3a; background-color: #3a3a3a">spoiler text</a>, normal text.

Normal text, spoiler text, normal text.

Honestly they should have put a <spoiler> tag in HTML 5, but this will do for now. Sorta. I guess. And no, I don't know how to make spoiler text work with both screenreaders and iPads. :(

roadrunnertwice: Me looking up at the camera, wearing big headphones and a striped shirt. (Spam tank (Bad Gods))
Whoa hey, looks like Apple just released a new EVERYTHING. I'm kind of just waiting on all of it, though, which mostly comes down to making sure I don't miss a crypto window on upgrading my hacked iPhone -- that shit gets silly fast, by the way, remind me to tell you about it someday -- and trying to decide on a spreadsheet to replace the direly agèd copy of Excel that came with my old iBook.

Spreadsheet dorks: Numbers or the new Excel? I actually quite liked Excel '07 for Windows, and thought Numbers '09 felt kind of flimsy by comparison, but I'm still on the fence a bit, because it's $150 vs. a combined $30 for both Mac and iOS. Plus, I don't reeeeeally need that awesome bolt-on regex substitution function anymore, since it was mostly a workaround for being stranded on computers without proper text editors or language runtimes.
roadrunnertwice: A mermaid singing an unenchanting song. (Doop doop (Kate Beaton))

So I grabbed a new iPad text editor to play with! It’s called iaWriter, and you might have heard of it, since apparently it’s the one Stephen Fry uses or something. I like it a lot. It can’t replace PlainText, because its syncing and organizing are kind of barely sufficient (verging on crappy); it’s completely unusable for making frequent updates to a blizzard of smallish documents, and appears to be meant for working diligently on four or five large files, which will occasionally be switched out. It’s a text drafter, I think, not a text editor. Anyway, the upshot is that I seem to be able to write fiction with it at speed, which is one hell of a feature and which I always found too frustrating to keep trying for on Simplenote and PlainText.

The two real standout touches are that it uses a big ugly font that’s very readable no matter how I’m holding the device, and it extends the iPad keyboard with a row of extra keys – things like always-on apostrophe and quote keys, and cursor keys that can navigate by letter or word. It sounds trivial, but it ends up making a pretty huge difference, and I’m inclined to attribute its surprising usefulness to the amount of friction that takes away. I realize most iPad apps can’t do that with the keyboard, because it makes it take up like 3/5 of the whole screen, but it’s damn nice if you need to type for an hour.

It also has two standout annoyances: there’s a big old scrolling dead zone on either edge of the page, and it doesn’t switch the keys back after you type an apostrophe with the normal punctuation keyboard. Yes, you have a built-in key for that, but that’s no reason to punish me for picking up a little muscle memory elsewhere, geez.

I think I paid like a buck for it? It’s definitely worth checking out, even if you already have a main text editor.

(Oh, and apropos of nothing, apparently it saves newly created files as Little-Endian UTF-16. Who in the world uses that for ANYTHING? Weird!)

roadrunnertwice: Weedmaster P: "SON OF A DICK. BALL COCKS. NO. FUCKING." (Shitbox (Overcompensating))
So after using it on and off for a few months, I think I'm ready to call Firefox's "Panorama" feature a failure. It does interesting things, some of which are awesome, but it amounts to turning Firefox into a completely separate OS with its own window manager, running cordoned-off in its own little virtual machine. Cut for people who don't care about web browsers nearly as much as me. )
roadrunnertwice: Weedmaster P: "SON OF A DICK. BALL COCKS. NO. FUCKING." (Shitbox (Overcompensating))
Oh hey, what the fuck, Tweetie 2 I mean Twitter for Mac finally came out? That was unexpected. Well, if there's one thing I love, it's being kind of a bitch about Twitter clients, so let's ride:
  • It's got support for lists! I think it's the first Twitter app for Mac that does the list thing and yet doesn't seem misguided and broken on a totally fundamental level. (Nambu's probably the closest behind, but I really can't stand it.)
    • Unfortunately, it doesn't expose them flatly the way Twitterrific for iPad does, so you have to drill down every time to get to them. Bogus.
  • Not down with this slide-and-stack UI nonsense they've got going on. Honestly, what the hell is supposed to be happening in this metaphor? That this stack keeps getting taller and taller every time I change views makes me nervous, like I'm going to have to clean it all up someday when the pile tips over and gets all over the foyer. I am only 30% joking, here.
    • On the other hand, I thought the Twitter for iPad UI was godawful at first, but they improved it pretty dramatically in the minor updates. Maybe they'll make it more spatially coherent in a month or three.
  • I've gotten used to Itsy's inline images, which make TfM's popups seem rather outdated in comparison.
  • Ha—when I unplugged my monitor, the window stayed taller than my MacBook's screen; now it won't auto-shrink, and there's no way to grab the resize control. Enjoy the land beyond the bottom of the screen, little window! Go where no man has gone before!
  • Hmm, the keyboard shortcuts seem pretty rich. That's nice.
  • It's still got the ability to do multiple tweet windows, which was always nice to have when I needed it. Does any other app else do that, or is that still Tweetie-only?
  • But DO NOT WANT tweet windows that hover over the top of everything. Eew. I understand the problem they were trying to solve, but I disapprove. I'd prefer that they come to the fore whenever any Twitter window was active but act like normal windows the rest of the time.
  • It's still tough to tell whether the main window is active, but that's less annoying than it was when it looked like it should dim the way normal Leopard/Snow Leopard windows do.
  • Feels pretty fast!
  • I can't remember: Was there ever any actual apology for that debacle where MacHeist and Atebits sold vaporware sneak peeks of Tweetie 2 and basically never delivered? *checks* Hahaha—looks like there's this, and also that, for whatever those're worth.
Anyway, all told I'd say it's a pretty decent app. I'm using it for now. Still hoping Twitterrific for Mac ends up living up to the promise of the iPad version. (Man, come to think of it, that update's been pending for even longer than Tweetie 2, hasn't it?)
roadrunnertwice: Dialogue: "Craigslist is killing mothra." (Craigslist is killing Mothra (C&G))

It has officially been months since I've wasted everyone's time talking about computer bullshit up in here, so let's geek out for a second.

  • Git is the shit and I'm basically in love with it. That's pretty much all there is to say about that.
  • I'm out of love with Simplenote, alas. It was the first iPad writing app that made sense to me, but it started corrupting my text (while I was watching, even!), which is pretty much the one thing I just can't forgive in an app. After I lost a sentence in one of my Turkey diaries and couldn't remember what it'd been, I ditched Simplenote for good, got a Dropbox account, and started using PlainText instead. It's better in some ways (it plays very well with Garbage Book and FMP, for instance) and worse in a few (no search), but since it hasn't thrown away part of my brain as of yet, it currently wins by default.
    • By the way, Dropbox is the shit and I'm basically in love with it. Yes, I am late to the fucking party; what of it.
  • The developer of PlainText also has a to-do list app called TaskPaper, and after extensive consideration I have decided that—evidence of an unfortunate addiction to InterCaps aside—it rocks. The deal is that I've tried working with task managing apps before, and I apparently can't handle any of their interfaces; if it's more complicated than a piece of paper or a text editor buffer, it gets in my way and I eventually just stop using it. (Bonus Kill It W/ Fire points for any app that has a concept of calendar-tied due dates.) Which, fine: I've always just fallen back to using paper or a text editor buffer, and they're perfectly respectable tools.

    As far as I'm concerned, the following are the only problems with using paper and text for to-do lists:

    • They're hard to maintain. Eventually, a to-do list is going to get clogged up with finished tasks, and the only cure is to spend way too long on either re-writing it or deleting the dross.
    • They're not very introspectable. You can do a single-aspect hierarchy pretty easily, but it's a lot more annoying to, say, make an ad-hoc sub-view of tasks you've picked to do today or which have to happen when you're at home.
    • Also, and this is basically less important than anything but it gets on my nerves anyway? "Crossing out" an item in plaintext is kind of fiddly and abstract. Like, how do you even do that? Put an "x" in front of the line? Turn the - bullet into a +? Guh.

    TaskPaper solves all of those without actually making the interface any more complicated than paper or a text buffer, so it wins. I used up its 30-day trial and thought it wasn't really all that special, and then I proceded to get incredibly annoyed at its absence on an almost daily basis, so I ponied up. If you like to-do lists, you should give it a try too.

  • I think my favorite thing about that rubberized iPad folio Apple makes is how schmutzy and gross it gets. No, seriously, I mean it. It signals that its contents are for use and/or abuse, and for someone with a mild fear of Owning Nice Things, that's more useful than it sounds. Also, the unique patterns of filth make it easier to tell otherwise-identical iPads apart.
  • So in Vim, the D key generally indicates destruction, right? dd = delete the current line; D = delete to end of line? Except that ctrl-d means scroll down half a page. This is my Vim face: -_-
roadrunnertwice: Me looking up at the camera, wearing big headphones and a striped shirt. (Roadrunner - Going faster miles an hour)
I learned how to talk to Growl today! Hello, Growl.

Context here is that I'm trying to abandon ship on Quicksilver on account of its oldness, staleness, and general decrepitude, but since I used it for such a weird variety of stuff, I'm having to get a little creative on how to replace it. In this case, I'd rigged QS to throw a Growl alert describing the currently playing track in iTunes whenever I whacked a certain hotkey, and since I wasn't interested in running a whole extra app just for that, I figured I could probably roll my own thingamabob and trigger it with FastScripts.

I figured right! And here's the goods: )

For reasons that are somewhat complicated, you'll have to paste that into AppleScript Editor and save it, then uncomment that one line, run the script a single time, and close the file without saving. After that, it'll work just fine, and you can set the display options for the alert in Growl's preference pane; the name of the application will be "iTunes Track Alert."

(Yes, I could have just left that line uncommented and skipped that extra step, but that seemed to make it run slower when I was testing it, and it really does only have to happen once.)

Incidentally, my hacked-up-in-an-afternoon-bullshit-AppleScript replacement for this feature turns out to be better than Quicksilver's version, because it shows the artwork even when it's not embedded in the file and can display the track's rating. Take that!