August 29, 2007

Thunderbird 2 bad interface decision: Ctrl+Shift+M

What I see as the primarily, though difficult, goal of user interface design is making the interface as easy to use as possible without sacrificing functionality in the process.

I acknowledge that there's always discrepancy as to where the boundaries lie; however, I'm also of the opinion that some UI decisions are just plain dumb. A significant part of usability is appealing to existing expertise in the user base — this eliminates large fractions of the learning curve straight out of the box.

Some UI choices, like keyboard shortcuts, have lots of inertia. This inertia is not only rooted in history, but also in the muscle memory of users. When my brain thinks "paste", my fingers almost automatically respond with Ctrl+V, as it is still the standard paste operation keystroke. Many people also recognize Shift+Insert to be a valid secondary stroke option, but this is usually in environments where usage of Ctrl+V has historically recognized alternate effects. I posit that this inertia and reinforcement of the Ctrl+V keystroke standard is a Good Thing, as it offloads the thinking process from "what keys do I need to press" to "what is it I want to do" as the keystroke becomes more and more intuitive.

I certainly respect Thunderbird's uniqueness as a mail/newsfeed client, and whatever primary goals they have in UI design have certainly shown with the Thunderbird 2 implementation (it's quite pretty and usable); however, I can't condone their use of Ctrl+Shift+M.

In the two other GUI email clients I've ever used (namely, Evolution at home and Outlook at work), Ctrl+Shift+M composes a new message. Though it's been a few months since my transition from Evolution to Thunderbird, I still push Ctrl+Shift+M sometimes when I want to compose a new message. In Thunderbird 2, this makes the currently selected message magically disappear without explanation.

When this happened to me, undo worked (thankfully), so I knew I hadn't permanently deleted my email. I then looked to Google and realized that Ctrl+Shift+M now performs the "Move / Copy Again" command, via the Thunderbird keyboard shortcut page.

I understand when a UI that departs radically from the functionality of other popular interfaces differentiates keyboard shortcuts as well. This actually serves to establish/reinforce another mode of operation in the user's mind! "These new actions are what I perform when dealing with this radically different scenario," seems to be a strong corollary of Pavlovian reasoning.

Thunderbird, however, looks and functions in a manner very closely resembling other popular GUI mail clients. In disregard of this similarity, it took the existing, inertial interface functionality and made it do something different and potentially destructive. That's far worse than doing nothing.

An aside: I understand that there's probably a way to neutralize that keystroke; however, this is a critique of the UI decision making as it ships "out of the box". Additionally, I've never found altering the hotkeys in Mozilla applications to be as easy as it should be — I've had to do things with unintuitive shell scripts and creating previously non-existent configuration files.

VMware fast file transfer from host

Yet another instance of the readily apparent solution not being the optimal solution.

I always used SFTP to transfer files from the host machine to the virtual machine over the emulated ethernet hardware. This is very stupid, and I had always recognized it. I wondered why VMware server console didn't have a feature to transfer files from the host machine to a virtual disk — it was apparent that it could load local file-like things into "virtual space" from the VMware tools installation mechanism, but a few (poorly formulated) Google searches turned up little information on alternatives. [*]

Today I "sank the battleship", however, and found the search term that got me the hit I was looking for. There's a tool to mount your VMware-format virtual machine disk via the .vmdk file — on UNIX, it's vmware-mount.pl. Here's a short explanation on how to use it:

  1. If you're in an environment where you can't easily spawn new shells, you should probably run screen or something similar.

  2. vmware-mount.pl -p my_disk.vmdk # Prints out the partitions on the disk.

  3. sudo vmware-mount.pl my_disk.vmdk 1 /mnt/vmware_disk # Mounts the first partition in the specified directory

Pretty straighforward. If you're running any kind of recent kernel it spits out this saddening message::

It has been reported that this program does not work correctly with 2.4+ Linux kernels in some cases, and you are currently running such a kernel. Do you really want to continue? [N]

You also seem to get one of these if you're running it for the first time::

There is no Network Block Device defined on this machine. This script is about to create the /dev/nb0 Network Block Device. Continue? [Y]

In the end, it gives you this nice message::

Using another terminal, you can now browse your Virtual Hard Disk partition in /mnt/vmware_disk/. Hit Control-C in this terminal when done.

Thanks for giving us plenty of prior notice, VMware. :P If you can't spawn a new shell at this point and ignored my warning above, background the job with a Control-Z, then bg (in bash). To stop the mount after backgrounding the job, type fg, then Control-C.

If you hit Control-C multiple times, it seems that you get to find out about the developer's back problems::

It seems like somebody unmounted the /mnt/vmware_disk/ mount point in my back. I was about to do it anyway.

Footnotes

[*]

There's a pretty well established notion in search technologies: it's hard to find information that you don't know how to describe. For this reason search developed things like inverted file systems and lexical analysis methods, which garner what you're looking for from related terms that you do have some concept of.

Matching _t types in your .vimrc

Background

I find myself constantly reproducing my .vimrc file. It's most frequently because I'm migrating from system to system; however, I sometimes just lose it during a reformat (or forget to rsync with the -a flag).

One part of Vim that I'm not fond of is its regex. It takes the one thing I like about Perl (the ecumenical regex syntax) and throws it out the window. As a result, I usually write hackish regexes to highlight my type_t cTypes on the fly, which never highlight quite what I want them to.

Evolution

One example is a regex I found doing a Google search for "vim match _t", which, admittedly, doesn't return much. The most relevant hit suggests the following:

syntax match cType /[^ (]*_t[ )]/ " very wrong

This suggestion is pretty bad — it doesn't match cow_t in any of the following, as examples:

typedef struct Cow cow_t;
cow_t* my_cow;
cow_t my_cow;

At first I thought the correct regex was the following, which matches all of the above:

syntax match cType /\w\+_t\W\{-}/ " also wrong

It's annoying Vim regex doesn't have the standard operators (like +) without the escape, and that there's that awkward match on the last atom (W, or non-word character) to drop it with a special funky-looking-dealie. I believe the Perl equivalent is the equally unintuitive ?? postfix, but it has the clear advantage of being the de-facto standard.

The above faultily matches on things like the following, however: cow_tip(); This indicates that we need to match on the previous portion in all cases, except where there's a word character following. For this, we use the following, correct, construct:

syntax match cType /\w\+_t\w\@!/ " CORRECT!

I couldn't have figured it out without this handy reference, as well as the more extensive Vim documentation for fixing my original error by using clown-hat looking constructs.

Efficiency/Readability Fix (July 30, 2008)

My friend Trevor Caira pointed out the existence of the \zs and \ze atoms. These resize the match to the specified start and end (respectively), without using clown-hat trickery. <@:)

This makes the regex look a great deal more straightforward:

syntax match cType /\w\+_t\ze\W/

Unmet dependency solution in Synaptic

Most Linux users have an ugly Pavlovian response to the phrase "unmet dependencies". Because I use a distribution that coddles me to a (sometimes unhealthy) extreme, I had forgotten about the frightening package dependency jumbles that I used to get into when I used Fedora Core 3.

I reformatted my laptop's hard drive in order to switch to XFS. [*] As with all installations that I don't have time to automate, I end up making the same little tweaks I always make in slightly different ways. In tweaking the font clarity, however, I got a bit carried away, and started reading about code that (purportedly) improved font quality dramatically, but hadn't made it into the Feisty version of the Ubuntu distribution.

I (stupidly) installed a third party package instead of searching around for other options first. The result was some mild package mayhem.

Here's a short description of how to go about solving a problem similar to this one using Synaptic (the GUI manager for dpkg systems):

  1. Track the dependency chain down to the first conflicting package. You'll get messages like "This package [you're trying to install] depends on X, but X isn't going to be installed." X is your new target, for each X, iteratively.

  2. Try to force the package to the official version (Ctrl+E). You'll likely get more messages like in 1. If you do, GOTO 1. Otherwise, move on to 3.

  1. End up at a (most reduced) conflicting package. You'll get a message that says, "This whole mess of applications will have to be removed." If you get this, you've found one of the most reduced conflicting packages. In this case I found it to be libfreetype6. I couldn't force libfreetype6, because there were very important packages (e.g. ubuntu-desktop) that depended on upgraded packages that depended on this new version of libfreetype6. You can view dependent packages via the package properties that Synaptic displays; however, you don't see what version they are dependent on (I'll submit a feature request in a few days). As a result, your best bet is to search for dependent packages via Synaptic's search feature.

  1. Knock off 3rd party dependent packages by forcing them to the official version. Be wary of removing a lot of important things by accident in the process! If it has a slew of applications "to be removed", try forcing other dependent packages to the official version first.

  2. Work your way back down to the more shared packages by forcing versions up the dependency tree. Once you force less-shared packages to official versions or prune off unnecessary packages, you should be able to start forcing more-shared packages to official versions. This is a natural result of having less unofficial stuff to support dependencies for!

NOTE: This entry is sloppily written in a stream-of-conscious style, but I don't really have much time to edit it. Sorry!

Footnotes

[*]

I thought that the potential performance benefits of a metadata-only journaling filesystem were intriguing, and I hoped that it would alleviate some of the degradation that I encounter running a 5400rpm drive.