All this stuff is filed under "tips"

MobileMe email settings for Palm Pre

For the record, I finally bit the bullet and ditched my iPhone for a Palm Pre last week, and I’m extremely happy with the switch. I’ll post in more detail about why the Pre (and particularly WebOS) is freaking fantastic soon, but for now here’s a quick tip for other Palm Pre owners who want to configure their Pre to use MobileMe and can’t figure out why it keeps claiming you’re doing it wrong.

Although some people have apparently had luck using the automatic setup (where you just enter an email address and your password), I needed to use the manual setup in order to get it to use IMAP rather than POP. I think recent MobileMe accounts don’t even have POP activated by default, so maybe the age of my account is the problem. In any case, if the automatic setup booted you into POP3 rather than IMAP, delete the account and recreate it. From the screen where it asks for your username and password, open the menu and choose “Manual Setup” (why they didn’t just stick a Manual Setup button on the main screen where anybody could find it is beyond me, but I digress).

Here’s all the settings you’ll need to get rolling:

  • Incoming mail server: mail.me.com
  • Username: [your username, without @me.com or @mac.com]
  • Password: [your password]
  • Encryption: SSL
  • Port #: 993 (this should be automatically selected when you choose SSL)
  • Outgoing mail server: smtp.me.com
  • User Authentication: On
  • (Username and password will be auto-filled)
  • Encryption: TLS (this is what was probably screwing you up if you tried manual setup already)
  • Port #: 587

These settings work perfectly for me; hopefully they’ll save other Pre users with MobileMe the headache of “SMTP setup failed” errors.

Understanding Espresso actions

A fair number of people in the Espresso forums ask questions like, “Is there a shortcut to delete the current line the way there is in Textmate?” Usually the answer is, “No, why don’t you create one?” Yet people remain leery of creating text actions by hand. I understand that; heck it’s extra work, and who wants that? What I think most people don’t realize is that, particularly for text manipulations like deleting the current line, the amount of work is minimal. All you need is a basic understanding of how Espresso works and the ability to author simple Javascript and XML.

Anatomy of an action

Espresso actions come in two parts:

  1. The XML definition, which tells Espresso the action’s title, what Objective-C class to execute when the action is invoked, and additional information like keyboard shortcuts or tab triggers that should invoke the action.
  2. The Objective-C class (or, if using a plugin like TEA or Spice, the script that defines the action’s logic)

Most often, XML action definitions are included with a Sugar (you can make a Sugar for custom text actions simply by adding a .sugar extension to a folder that contains a TextActions folder with the action XML files in it). If you wish, you can also define action XML files outside of a Sugar by enabling TEA custom user actions in the Advanced pane of the Espresso Preferences (more info about TEA custom user actions).

As of Espresso 1.1 there isn’t an in-program GUI for editing actions yet, but hopefully that will come in time.

Spice up your actions

Spice is an Espresso Sugar that I’m currently developing that provides access to the Espresso API using Javascript (thanks to JSCocoa), and additionally provides a selection of utility classes that allow you to interact with the API without needing to know anything about Objective-C or the JSCocoa bridge.

The benefits of this should be fairly obvious, but there’s another reason creating actions with Spice is easier than using TEA or Objective-C; not only are the action scripts not compiled, but you don’t need to relaunch Espresso to see your changes. When I’m coding a Spice action, I usually open the Javascript action in Espresso, and then run the action right there on the Javascript when I need to test it.

Although Spice’s utility classes make creating custom Espresso actions easier, you still need a basic understanding of how the Espresso API works.

Contexts, ranges, recipes, and snippets

When a user invokes an action from the Actions menu, Espresso executes the action’s class and sends it an object representing the text or file context (depending on whether you’re using a text or file action; I’ll be focusing only on text actions because the file action API is currently underwhelming). The text context allows you to access the active file’s text, information about the selection (or selections, since you can select multiple things at once), line information, preferences (like what line ending or indentation is being used), and access to the syntax system.

When you are ready to change some text in the file, your action messages the text context and tells it what to change and how to do it.

As of Espresso 1.1, the easiest actions to create are ones that are invoked by the user, access and change something about the active file’s text, and then immediately exit. It’s possible to do things that are a bit more complicated or on-going, but at the moment Espresso doesn’t make it easy.

When you’re working with text, you’ll mainly be dealing with ranges. A range represents a section of text in the active file and is composed of a location and a length. Internally Espresso keeps track of text by counting all of the characters in the active file starting at zero, so the range location is the index of the starting character and the length is the number of characters contained within the range. Typically you’ll be dealing with selections, so you’ll have ranges like {0, 10} (the first ten characters in the file) or {100, 30} (characters 100 through 130). However, it’s also possible to have ranges like {10, 0}, which represents the cursor location at character index #10 in the file.

A typical text action will fetch the currently selected ranges from Espresso, manipulate the text within them somehow, and then tell Espresso to change the range(s) accordingly. In order to queue up changes like this, you’ll use text recipes.

Text recipes are something that is unique to Espresso, so far as I know. Basically, you create a recipe and tell it things like “delete the text in this range”, “replace the text in this second range”, and “add this text at a third range”. You can compose a multiple step recipe without worrying about tracking how ranges will change; for instance, if you add characters to an early range, you don’t have to adjust the location of later ranges. Instead, the recipe does that for you when you apply it to the document.

Text recipes allow you to make complex changes to multiple ranges in the active file, but you can instead insert text snippets, as well. A text snippet is a specially formatted string that allows Espresso to create tab stops, mirrored segments, and more after you’ve inserted it. Many of the custom actions bundled with Espresso are little more than text snippets; for instance Wrap Selection In Tag merely grabs the selected text and wraps it in a simple snippet that mirrors the HTML element from the opening tag to the closing tag. You can do some pretty magical-seeming things with very simple actions simply through tricky use of text snippets. The one downside to keep in mind for text snippets, however, is that you can only insert one at a time (unlike text recipes, you can’t insert multiple text snippets over discontiguous selections).

Bringing it all together

With an understanding of how the Espresso API works and a quick peek at the Spice docs, setting up an action to delete the current line (to take one example) becomes simple enough:

  1. First, we’ll need to define an action in XML, and create a Javascript file with the action logic
  2. In the Javascript, we’ll need to query the text context to get the range of the current line, and then create a text recipe to delete that range

The action XML is easy enough; simply create the file Actions.xml and place it either in a Sugar’s TextAction folder or in your Espresso Support folder located here:

~/Library/Application Support/Espresso/Support/TextActions/

The contents of the action XML definition should be this:

<action-recipes>
    <action id="com.onecrayon.DeleteLine" category="actions.text.generic">
        <class>Spice</class>
        <title>Delete Line</title>

        <setup>
            <script>delete_line</script>
            <undo_name>Delete Line</undo_name>
        </setup>
    </action>
</action-recipes>

(If you wish to add a keyboard shortcut, you can do that with the key-equivalent entity; see the Spice action XML docs.)

If you’re using the Support folder option, you’ll need to enable TEA custom user actions in the preferences and restart the program twice. Otherwise you’ll need to make sure the Sugar is installed and restart the program once (action XML definitions are loaded when Espresso boots up; unfortunately as of Espresso 1.1 there isn’t a way to refresh action XML definitions without a relaunch).

Now that you’ve got the action defined (and showing up in the Actions menu) you can create the Javascript file delete_line.js (referenced in the script element of the action XML). If you are using a Sugar, it should be located here:

MySugar.sugar/Support/Scripts/

If you’re using custom user actions in the Espresso Support folder, you’ll save it here:

~/Library/Application Support/Espresso/Support/Scripts/

The simplest way to delete the current line would be this:

// Deletes the current line

// require() allows you easy modular access to Spice's helper classes
var textContext = require('text_action_context').textContext;
var TextRecipe = require('text_recipe').TextRecipe;

// exports.main is your primary function, run automatically by Spice
exports.main = function() {
    // Grab the range of the current line
    var linerange = textContext.rangeForLine();
    // Run the actual removal
    return new TextRecipe().remove(linerange).apply();
}

First, the script uses the universal require() function to include the Spice utility object textContext (which contains methods for interacting with the Espresso text context) and utility class TextRecipe (which allows access to Espresso text recipes).

Spice’s utility classes are provided in a modular system that allows you to only require what you need in order to run your action. Spice modules have the following naming conventions:

  • The module is named for the primary class, converted to lowercase and with underscores between words (so primary class TextActionContext becomes module text_action_context)
  • Classes are all camel-case with the first letter capitalized (TextActionContext)
  • Objects (instantiated versions of a class) are camel-case with the first letter lowercase (textContext is an instantiated version of TextActionContext)

You can see what a given module exports in the Spice docs (along with full references to the object methods available). The text_action_context module is one of the few that exports an object as well as the class, since you’ll never need more than one object for referencing the text context.

Once you’ve saved the Javascript file, you’ve officially created your first Espresso action! You can immediately run the action from the Actions menu, and it will delete the current line. If you test it out, though, you may notice that the action behaves differently when you delete the final line in the document; instead of removing the line completely, it only removes all the text. To fix this, you could modify the action like so:

// Deletes the current line

// require() allows you easy modular access to Spice's helper classes
var textContext = require('text_action_context').textContext;
var TextRecipe = require('text_recipe').TextRecipe;
var Range = require('range').Range;

// exports.main is your primary function, run automatically by Spice
exports.main = function() {
    // Grab the range of the current line
    var linerange = textContext.rangeForLine();
    // If on the last line of the doc, remove the line break prior to the line
    // This isn't strictly necessary, but it's nice to have
    if (textContext.lineNumber() != 1 && textContext.rangeForLine(textContext.lineNumber() + 1) === false) {
        linerange = new Range(linerange.location - 1, linerange.length + 1);
    }
    // Run the actual removal
    return new TextRecipe().remove(linerange).apply();
}

The only addition is some logic to check if we’re on the last line of the document, and if so create a custom Range object that includes the linebreak from the previous line.

Debugging

As you work on your own custom actions, you will of course run into problems and errors. The best way to debug is to keep Console.app open (located in your Applications/Utilities folder), since most errors will be output there. You can also use the globally available system.log('message') to output directly to the console. Many Spice utility classes also include a log() method to quickly log the contents of an object.

When using Spice, keep in mind that it’s still under development (at the time of this writing, it’s at version 1.0 beta 6). If you run into something that seems buggy or a limitation of the utility classes, please let me know.

Parting thoughts

Even if you don’t use Spice, the basic strategy for adding a custom action to Espresso remains the same. TEA offers several alternative methods to creating text actions (from Python scripts with full access to the API to scripts in arbitrary languages like Ruby or PHP that have more limited capabilities). Although the basic editor has a nice interface and some great features, I’ve found that the extensibility of Espresso is what keeps me coming back for more. A modicum of effort is often all that’s required to add a custom text action, so there’s little excuse for not giving it a try if you find yourself missing functionality you’ve grown used to in other editors.

If you do write any great custom actions, please think about sharing them either via a Sugar, GitHub, or the Espresso forums! I’d also love to hear how people are using Spice; I’m still planning out the additions I want to make now that I’ve got most of the basic Espresso API for text actions covered by the utility classes, so your input is extremely valuable.

Cinnamon rolls (in five minutes a day)

Ever since I was a kid, I’ve loved cinnamon rolls. I remember a particularly glorious few days when my family went to visit my aunt and uncle and discovered that their son was working for Cinnabon that summer. Every evening he’d bring home left-over Cinnabons and my father and I would eat ourselves sick. Apparently love of gooey cinnamon pastries runs in the blood.

Despite my love affair with cinnamon rolls, however, I have never had the courage to experiment with them before. In part, it’s because yeast scares me (my early experiences with yeast bakes turned out poorly, to say the least). Mainly, it’s that I’ve never really had homemade cinnamon rolls that consistently turned out well. Mom would make them occasionally, but they were hit and miss; sometimes delicious, other times passable.

Fortunately for me, and unfortunately for my cholesterol levels, I have at last braved the cinnamon roll and discovered something wonderful: I make damn fine cinnamon rolls, and they’re really, really easy.

Like most of my recent excursions into yeast bakes, my cinnamon rolls start with Artisan Bread in Five Minutes a Day (available via Amazon or on Kindle). I cannot recommend this book highly enough; it is a brilliant introduction to bread baking that makes the task not only easy but quick. Like any baking, it takes a couple tries to figure out exactly how things work, but although my first attempts at recipes and doughs typically don’t end up quite like I planned, I’ve only had a single total disaster (my first attempt at naan was carbonized thanks to following the book’s instructions to heat the skillet on high prior to cooking the bread). If you’ve tried and been frustrated with yeast baking before, you’ll understand what an astonishing track record that is for a beginning baker.

If you have any interest in making fresh bread, go buy the book. You’ll need it to make cinnamon rolls my way, anyway, because they rely on the dough recipes and preparation methods that are the core of the book. Specifically, Artisan Bread in Five provides a Caramel Sticky Buns recipe on page 187, which will be your starting point. The key is instead of the rigamarole of coating the bottom of the pan and turning things upside down once you finish baking, etc. you’ll want to use this easy cinnamon filling:

Cinnamon filling
1 cup packed brown sugar
2 1/2 tablespoons ground cinnamon

Mix the brown sugar and the cinnamon together. You’ll have enough for 2-3 batches of cinnamon rolls (depending on how liberal you are with the sugar and how large you make the cinnamon rolls), so store it in a tupperware or similarly air-tight container for later.

After you’ve rolled the dough out into a rectangle as per the sticky bun recipe, spread all of it except for 1/2-1 inch around the edges with softened butter. I’m usually a bit more liberal with the butter if I’m using the master recipe, but particularly if you’re using brioche dough (which makes the richest, most desert-like cinnamon rolls) you’ll want to be a bit conservative with the butter. You just need enough to coat the dough with a thin layer.

Once you’ve spread the butter, sprinkle it liberally with the cinnamon-sugar mixture. You want to have enough cinnamon-sugar that you can’t see any dough or butter peeking through (except for the strip around the edge of the dough, of course). If you’re particularly liberal with the cinnamon-sugar, you’ll likely end up with a sticky goo at the bottom of the rolls similar to the stuff you’d find in a Cinnabon. Use a little less, and you’ll have a more subtly-flavored rolls that’s a bit cleaner to eat.

Roll and cut the dough as per the sticky bun recipe. I usually use a greased 9×9 glass pan, and always end up with nine rolls (counting the two end ones) each about 1-2 inches high. You can, of course, make more or less depending on how much dough you’ve got and the size of your pan. Place the rolls in the pan with a little bit of room between each one (they’ll spread out as they rise), and cover lightly with plastic wrap.

Whether the rolls rise or not will depend on the temperature of your kitchen. I often need to place a second 9×9 pan filled with hot water under the one with the rolls for 20-40 minutes of the rising time, since my kitchen tends to be cooler. Ideally, the rolls should rise upwards and outwards both, so that they are just touching their neighbors.

Bake according to the sticky buns recipe, about 40 minutes. Baking time will fluctuate depending on how large your rolls are, so start peeking around 30 minutes. Serve warm, preferably with some icing (I leave it to you to find a good icing recipe online; we typically just mix some powdered sugar with water and drizzle it over the warm rolls).

I’ve tried using brioche dough and the master recipe both, and the cinnamon rolls turn out great either way. As you would expect, the brioche-based rolls are richer and more buttery, while the dough of the master recipe rolls takes more of a backseat to the filling. I’m itching to try the challah dough because it’s in between the two as far as eggs and butter content goes.

The only downside to this recipe is that it takes roughly two hours from when you decide to make cinnamon rolls and when they’re ready to eat, thanks to the rising and baking time (even if it’s passive time, it still makes it hard to make cinnamon rolls for breakfast before work). If anyone has any ideas for how to prep the rolls in the evening and have them ready to bake in the morning, I would love to hear them.

Even if I never find a way to cut down on the rising and baking time, though, needing to think ahead two hours is a miniscule price to pay considering that the payout is a dish that has warmed, comforted, and delighted me since childhood.

Adventures with Yahoo Pipes

When I was testing Tumblr as a platform for beckbits, I discovered that their RSS feeds didn’t offer quite what I was hoping. Since I was primarily planning to use beckbits as a link blog, I wanted it to work Daring Fireball-style: link items should go straight to the source material, and all other items should be permalinks back to the site. I’ve always thought that was a brilliant design choice on John Gruber’s part, and I’ve always been a big believer in integrating aspects of great design that I find around the web into my own projects.

In the hopes that I could take the RSS feed and remix it easily on my own, I turned to Yahoo Pipes. Yahoo Pipes provides a relatively easy graphical interface to parse, modify, and combine data streams, JSON, and RSS and spit it back out as RSS, JSON, or PHP serialized code. I first discovered Pipes when I found someone’s “lifestream”, a website that displayed a list of their activity across numerous different services using Yahoo Pipes. These kind of RSS feed mashups seem to be the most common use of the service, but the service is quite flexible so it seemed well suited for repurposing Tumblr’s RSS feed to my own uses.

Over the course of creating the feed, I discovered some interesting features that I feel are worth sharing. For those of your who are curious about my specific implementation, here’s the actual pipe that is powering beckbits.

Moving data between elements

Very early on in my exploration of the default Tumblr RSS feed I realized that I was going to need to use the Tumblr API if I wanted to get direct access to the various components that make up Tumblr posts. Of course, the API provides completely different elements than an RSS feed, so one of the main tasks of my pipe is to move data around between elements.

For things with a one-to-one relationship, the “Rename” operator typically does the trick. For instance, using the external site’s URL for the RSS item link on Tumblr link items was as easy as throwing in a Rename with the rule “item.link-url renamed to link“.

But what about when I needed to combine multiple fields into one? Rename certainly wasn’t going to help me there, and I couldn’t find any way to pipe data between operators and string functions.

Fortunately, the Regex operator came to the rescue.

Although I couldn’t find any documentation for this, the regex module offers a couple great features:

  • If you reference an element in the first column that doesn’t exist, it will be created.
  • You can include the contents of other elements using the “named backreference” syntax (${element-name}). For instance, when I wanted my description element to include both the Tumblr “quote-text” and “quote-source” elements the “replacement” column looked something like this:

    <blockquote>${quote-text}</blockquote><p><cite>${quote-source}</cite></p>

Simple conditionals using regex

Thanks to the fact that everything in a Yahoo pipe is evaluated sequentially, you can use the regex operator to setup simple conditionals. For instance, regular Tumblr posts have an optional title. If the title existed, I wanted to use it as my RSS item’s title; otherwise it should default to a short excerpt of the text. To accomplish this, I setup the following rules:

Rename
item.regular-title copy as title

Regex
In item.title replace (.*) with $1```${excerpt}
In item.title replace ^```(.*)$ with $1
In item.title replace ^(.+?)```.* with $1

The basic idea is to combine two fields into one separated by some delimiter characters that are unlikely to ever show up otherwise. I chose to use three backticks, since it kept things pretty legible and I rarely use backticks. If you’re not comfortable with regex, the rules in order say:

  1. Copy regular-title to title (because regular-title might not exist, this may result in an empty title element)
  2. Append ``` plus the excerpt element to whatever is in the title element
  3. If the title element starts with backticks (^```), replace its contents with whatever follows the backticks (the excerpt)
  4. If the title element starts with one or more characters followed by backticks (^(.+?)```), replace everything with that starting content

Replacing your site feed with a pipe

Once I’d created my pipe it was time to replace beckbits’ feed with the pipe, and I discovered that Yahoo Pipes has a serious downside when it comes to using it instead of your default site feed: the pipe’s output always links back to the pipe page as the feed’s homepage. Although this wouldn’t be a huge deal, it has the unfortunate side effect of causing the favicon associated with your feed to be the Yahoo Pipes favicon, which is extremely non-ideal. In order to fix this, you actually have to post-process the pipe output.

For myself, I opted to do this by reading in the pipe as serialized PHP and then constructing my own simple RSS feed. If you’re interested in doing something similar and would like a starting point, here’s the gist of it.

Tips, tricks, and gotchas for writing bundles with PyObjC

Part of the reason that I haven’t been posting very actively to Beckism.com or Tagamac is that I’ve recently been getting exceedingly involved in a number of personal projects involving Python. Python itself is super fantastic and learning it has been a blast, but one project in particular has been causing me undue amounts of head-to-desk contact thanks to its reliance on the oh-so-cool but insufficiently documented PyObjC, and I’d like to share some of the things that I’ve discovered for other would-be programmers who want to extend their favorite Mac OS X applications with PyObjC powered plugins.

For those of you who prefer source to exposition, the project that I’ve been working on is TEA for Espresso and you can find the full source code over at the TEA for Espresso project on GitHub. As you may have surmised, it’s a plugin for the upcoming Espresso text editor created because I wanted to play with Espresso but am addicted to Textmate-style HTML actions.

My personal preference for Python is to use four spaces rather than a tab for indentation, so keep that in mind if you’re trying to execute the code samples below and your document is using tabs.

Using py2app to create semi-standalone code

Py2app allows you to work completely in Python without ever needing to boot up Xcode and touch Objective-C. There’s plenty of information around the web about how to setup a basic py2app setup.py file, but one of the things that I had to discover via trial and error was how to make my code semi-standalone.

Semi-standalone is an option you can enable with py2app that makes your code reliant on the version of Python that is installed with the OS. By default, py2app tries to bundle any dependencies for your project into your bundle, but if you’re only distributing the bundle/plugin/app/whatever to people using the same major OS version this makes for about 15 MB minimum of unnecessary junk getting tossed into your bundle.

Turning on semi-standalone is as simple as adding a key to your py2app options dictionary, but what you might not know is that you also need to enable site-packages, as well (which apparently encourages py2app to create the links to Python necessary for getting the bundle up and running, although it’s only supposed to tell it to include the system and user site-packages in the system path). So to get a semi-standalone bundle, your code needs to look something like this:

setup(
    name='My Plugin Bundle',
    plugin = ['MyPluginBundle.py'],
    options=dict(py2app=dict(
        extension='.bundle',
        semi_standalone = True,
        site_packages = True
    )),
)

One of the most frustrating aspects of working with py2app for me was the lack of any decent documentation on the main py2app site. Fortunately, there’s a much more comprehensive page of documentation available in the MacPython py2app SVN repository, which is where I discovered the site-packages option.

Automatically including project data files

Odds are since you’re using Python you’ll need to include some arbitrary data files with your application, be they NIB files, extra Python scripts and classes, or whatever else. However, py2app’s method of declaring what files you want included with your project is to list them explicitly in a data_files array. This is a major pain, since every time you add or remove a file you have to remember to edit setup.py. No thanks.

Fortunately, Python comes with some powerful file system modules that allow you to traipse around your file system, making note of files and folders as you go. The following code snippet, if included in your setup.py script, will automatically parse through a directory of files and add them to your data_files array without you needing to lift a finger (assuming that you configure the first couple variables to fit your project, that is). Files that start with a period (hidden files) will be ignored. If you’re using SVN, you may also need to add some logic to exclude folders that start with a period (TEA for Espresso is using Git, so this hasn’t been an issue for me).

The downside to using this code, of course, is that you’ll need to nest all your files in the directory structure that you want in your final bundle. So, for example, in order to include something in the Resources folder for TEA for Espresso, I have to nest it in src/Contents/Resources/ whereas I otherwise could have placed it in the root project directory. If you’re doing a simple project with very few files, it might be more worth your while to define data_files differently.

import os

# Sets what directory to crawl for files to include
# Relative to location of setup.py; leave off trailing slash
includes_dir = 'src'

# Set the root directory for included files
# Relative to the bundle's Resources folder, so '../../' targets bundle root
includes_target = '../../'

# Initialize an empty list so we can use list.append()
includes = []

# Walk the includes directory and include all the files
for root, dirs, filenames in os.walk(includes_dir):
    if root is includes_dir:
        final = includes_target
    else:
        final = includes_target + root[len(includes_dir)+1:] + '/'
    files = []
    for file in filenames:
        if (file[0] != '.'):
            files.append(os.path.join(root, file))
    includes.append((final, files))

setup(
    name='My Plugin Bundle',
    plugin = ['MyPluginBundle.py'],
    data_files = includes,
    options=dict(py2app=dict(
        extension='.bundle'
    )),
)

Avoid release statements in Python

I’m sure this is extremely obvious for anyone with significant PyObjC experience, but TEA for Espresso lay fallow for over a month after I started it because I couldn’t get the example plugin ported from Objective-C to Python. It turns out that almost everything in Objective-C can be easily ported to Python using the simple conversion rules (colons to underscores, etc.; see the PyObjC intro for more info), except for any calls to release objects. For instance, here’s the code that was breaking my project:

Objective-C
[selectedRanges release];

Ported into Python (don’t do this!)
selectedRanges.release()

PyObjC auto-releases absolutely everything, so don’t port lines like the one above. They will break your project. This is actually described in the PyObjC introduction if you’d like a more technical explanation; apparently I just missed the significance of it when I read the intro the first time.

Handling **NSError arguments

If you’re implementing a bundle that will be loaded into another application, odds are you’ll need to implement an Objective-C protocol in Python, and Objective-C functions occasionally have an **NSError parameter. If you’re not going to be returning any error information, you can safely ignore the **NSError in your Python code. The bridge automatically handles it. If you might return an error, then you may find this thread on the PyObjC-dev mailing list useful.

For example, for TEA for Espresso I needed to implement this Objective-C method in Python:

- (BOOL)performActionWithContext:(id)context error:(NSError **)outError;

Since I’m never returning any error information, in Python this translates to:

def performActionWithContext_error_(self, context):

Although woefully out of date in some respects, one of the most useful and understandable sources of information about using **NSError with PyObjC I found was Apple’s PyObjC for Developing Cocoa Apps page.

Implementing Objective-C interfaces without a protocol

An interesting problem that can arise if your bundle is implementing an Objective-C interface (rather than conforming to a protocol) is that when your code is loaded you may find that Objective-C can’t find your class methods. To solve this, usually all you need to do is explicitly define the type encoding of your class method. For instance, TEA for Espresso’s main bundle class has the following method:

class TEAforEspresso(NSObject):
    @objc.signature('B@:@')
    def canPerformActionWithContext_(self, context):

The @objc.signature() decorator tells PyObjC that this particular method returns a bool (”B”), is an object method (”@” means object, and “:” means method selector), and accepts one argument which should be a generic object (”@” again meaning object). For a full list of available encoding characters, see the Objective-C Runtime Programming Guide.

You can find more information about this bit of weirdness over at Jim Matthews Blog or, to a very limited extent, in the PyObjC class wrapping documentation.

A better bash prompt on Mac OS X

I have always disliked Terminal. I got a basic grounding in Unix command-line usage in a C++ class in college, but Terminal still bugs me. Yes, I can adjust colors and fonts in the preferences, but it isn’t the background color that bothers me; it’s the fact that I can never tell my prompt apart from my output.

This became particularly aggravating when I recently started using Git. Git, unfortunately, does not have a great GUI client on the Mac that I’ve found, so I was doing all my work on the command line and determining where the prompt ended and output began was getting to be a persistent problem. I also was not happy with the fact that almost any command besides a simple cd or ls was wrapping onto multiple lines; the default Terminal prompt just takes up so much horizontal space.

Fortunately, it is possible to modify your bash prompt, and having trolled the internet and tested various solutions, here’s what I’m currently using to distinguish prompt from output:

My very own terminal prompt

Yes, my computer is named Tastefully Delicious. I myself am not entirely certain how this occurred.

My custom prompt isn’t perfect, and it’s certainly a lot more basic than some that you can create, but it does a great job of visually distinguishing between input and output which is exactly what I needed. Fortunately, it’s not terribly difficult to enable something like this; although bash prompt examples around the internet range from gibberish to hundreds of lines of cryptic functions that you have to load into your bash session, understanding the basics of a custom bash prompt in order to make your own peace with Terminal is quite simple.

First off, head over to IBM’s cheat sheet for bash prompt modification. This was by far the best reference I found on modifying the prompt, and offers a complete listing of available bash sequences and colors (as an added bonus, it uses a much simpler syntax for colors than some other sites advise). In my examples below I’ll be using the specific variables for my personal prompt, but you can of course substitute any bash sequence that you like to make the command line your own.

There are two main parts to customizing your prompt: deciding on the right prompt declaration for you, and then writing it to a file so that it’s loaded every time you load bash. The prompt is stored in the PS1 variable in bash, which you can examine like this:

echo $PS1

To temporarily change the variable (for instance, while testing out various prompts), you’ll run something like this:

export PS1="Your prompt here > "

By adding bash sequences to your prompt, you can make it display more interesting information. For instance, if you wanted to use just the second line of my prompt (what folder you’re in, what computer you’re logged into, and what user account you’re using), you could enter this:

export PS1="\W @ \h (\u) \$ "

Which would result in a prompt that reads something like this:

A somewhat modified prompt

You can, of course, use any of the sequences listed on the IBM reference. For myself, I found that changing the content of the prompt itself wasn’t enough (even when I experimented with multi-line prompts); what was really needed was some color.

Colors in bash are rather offputting, but easy enough to use as long as you’re careful. The basic format is \e[0m — "\e[" starts the color code, 0 is the actual color declaration (0 specifically means "reset to default"), and "m" ends the color. However, in order to make sure bash wraps things right (should they need wrapping) you have to add some backslash-escaped brackets to mark the code as taking up no space on the line:

\[\e[0m\]

Fun, illegible times. In the color chart on IBM’s reference, you can see the various codes associated with different colors. To setup a specific color combination, separate different numeric color codes with semicolons (so far as I know, order doesn’t matter). So if you wanted red text on a black background you would use \[\e[31;40m\] and if you wanted bold green text on a blue background you’d use \[\e[1;32;44m\] (the number 1 makes the text bolder and/or brighter for use on a dark background). You can also leave off any of the color codes (to just set the background color without messing with the default text color, for instance).

For my prompt I wanted something more subtle than most of the bash colors provide for, so I set the background of the whole window to light gray in the Terminal preferences, and then used the code \[\e[1;30;47m\] which set the text to the bright variant of black on a white background. I wasn’t too happy with the bold text, but fortunately Terminal offers a pair of options to disable bold text and make it “bright” which worked perfectly for me:

Terminal preferences

With colors worked out, the last step was adding a horizontal rule (via underscores) to separate out the prompt even more. My default Terminal window is 80 characters wide, so I just tossed in 80 underscores. I’m certain there are ways to get tricky with functions and only output as many underscores as you need to fill the window, but that seemed like more effort (and processing overhead) than it was worth.

So without further ado, my complete custom bash prompt:

export PS1="\[\e[1m\]________________________________________________________________________________\n\[\e[1;30;47m\]| \W @ \h (\u) \n| => \[\e[0m\]"

There’s additionally a second level prompt that you may need if you’re entering a command over multiple lines. I just duplicated the final line of my original prompt for the secondary one:

export PS2="\[\e[1;30;47m\]| => \[\e[0m\]"

For both of them, note the “return to default” color code at the end; if you don’t enter that, you’ll end up with an entire window the color of your prompt, which will likely defeat the purpose.

Once you’ve found a prompt that you like, you’ll want to save it so that it automatically loads. To do this, just add the export commands to a hidden file in your home folder named either “.bash_profile” or “.bashrc” (I don’t have any idea what the difference is; I’m personally using .bash_profile because it already existed in my home folder).

Once you’ve saved your path to the file, you should forevermore experience a more visually appealing (and possibly informative) bash prompt, hopefully rendering Terminal a less painful program to use.

Display: block and form legend elements

If you’ve ever tried to make an HTML form look like the fancy PSD mockup that your graphic designer threw together, you know how much hate forms deserve. Forms are an integral part of the web, yet making them semantic, accessible, and visually appealing across browsers can be a major bitch.

There’s lots of information scattered about the interwebs about arm-wrestling forms into submission, but I recently ran across an issue that has not, so far as I know, been adequately discussed. That topic is legends.

No, not like the legend of Jeffrey Zeldman and his big blue ox, although that’s a good one; I’m talking about the legend element that attaches to fieldsets in order to let your visitor know what the heck this group of form controls they’re supposed to fill out pertains to. Legends, it turns out, are some of the most annoying elements to style you can find. Not only do they by default have some bizarre formatting applied to them by every browser out there (usually in slightly different ways), but normal styling rules don’t apply. Display: block, anyone? Yeah, ain’t happening.

Recently I was asked to style a really nicely laid out form; it had everything lined up down the left side, clearly labeled sections, the works. Except that the headings for each section were occasionally long enough to wrap, and were displayed with many of the same rules as the H3’s on the page. Easy enough, I figured, I’ll just stick display: block and some margins on them.

Which is when I discovered that display: block has no effect on legends in any browser (any browser worth testing in, that is, which means IE 6, IE 7, Firefox 2, Firefox 3, and Safari for my company). Legends with lots of text in them tend to stretch themselves or, worse, their parent elements out to keep everything on the same line, and even if they’re supposedly block-level elements with a margin they’re still treated as inline. Not cool. Fortunately, my latent CSS superpowers were activated when I started swearing like a sailor (wish I had a more socially acceptable trigger, but there you go) and I pounded out some CSS that:

  1. Forces long legends to wrap in IE, Firefox, and Safari
  2. Encourages legends to act like they know what display: block is all about

The code looks like this (or see it in action):

HTML

<fieldset>
    <legend><span>Legend text</span></legend>
</fieldset>

CSS

legend {
    margin: 0 0 15px;
    float: left;
    white-space: normal;
    *margin-left: -7px;
}

legend span {
    width: 400px;
    display: block;
}

Seem weird? That’s because it is. Here’s the reasons for the insanity:

If you’re like me, you’ll want a margin on your block level elements; in order to get your margin recognized in Firefox 2, you have to put it on the legend element. Of course, margins won’t be recognized on inline elements or legends, but since display: block does squat for a legend you have to float the legend left. For the full display: block effect, of course, there should be a width on the legend, but since Firefox will collapse the legend’s width down to its content anyway, I left it off.

Instead, the semantically meaningless span gets the width and display: block. The span not only forces Firefox to bump the legend’s width out the correct amount, but it also is necessary for long legends to wrap in some browsers. I’m using a pixel width mainly because IE 6 requires a different pixel width (more on this later). Although in a perfect world your legends would not have anything in them other than the legend text, we don’t live in a perfect world.

Adding white-space: normal to either the span or the legend will fix the wrapping problems in Firefox 3 (I chose to attach it to the legend in the hopes that in fifty years or so I can rid myself of that span with less effort).

The *margin-left: -7px line is a hack to fix an IE-specific problem. Even with no padding, margin, and left: 0px IE will still indent your legends seven pixels. The star-property hack targets both IE 6 and 7 (while being ignored by sane browsers) and bumps the legend back over where it should be. I’m using the star-property hack here because it makes the source a lot less verbose; however, you should probably migrate that rule into an IE-specific stylesheet behind a conditional comment.

There is also one more IE-specific adjustment that you have to make thanks to the seven pixel indent. When calculating its box model, IE 6 will determine the width of the legend and add the seven pixel indent before shifting the legend to the left. Long and short of it is that the parent element will be bumped out seven pixels wider than it should be, so you’ll need to give the span a width seven pixels less than your target width for IE 6. For instance, to make the code above work in IE 6 I would add an IE 6 conditional comment with legend span { width: 393px; } inside somewhere.

And that’s it! You will, of course, want to be using an intelligent CSS reset (I recommend Eric Meyer’s CSS reset), but otherwise the above CSS should give you a legend element that acts like a block-level element instead of some weird border-loving pseudo-element with wrapping issues.

There are some further gotchas to be aware of if you start playing around with legends. IE by default colors all legends blue, for instance, and if you want the legend to overlay the fieldset border (or not) you’ll need to go about things slightly differently. However, if you’ve been frustrated by the inability to get your legends to behave like display: block means something, hopefully this snippet will help you out.

As is usually the case, I discovered this particular combination of HTML and CSS by taking previous solutions, mixing them into a putrescent green cocktail, and force-feeding it to my browsers, tweaking the constituent ingredients until they were saying “Mmm, tasty!” instead of puking a bunch of crap all over my lovely webpage. Specifically, John Faulds provided some basic concepts and examples for styling legends and Stephanie Sullivan wrote up the strategies for encouraging legend wrapping in Firefox 2 and 3. Thanks, guys; you rock.

If you want to see the code in action with various permutations for More Pretty, check out this page o’ examples.

Accept text from either LaunchBar or Quicksilver in Applescript

Here’s the thing: I absolutely adore LaunchBar. I use it constantly throughout the day, and if I’m using a computer without LaunchBar I practically can’t function because I keep habitually hitting the LaunchBar shortcut and opening Spotlight on accident. So when I write Applescripts that I want to accept text and do something with it, I use LaunchBar-specific code.

However, there’s a large number of people out there who prefer Quicksilver (link to Google Code project; also see Blacktree’s site). I don’t know if it’s for the sexier (if more complicated) interface or just because they’ve got Quicksilver embedded in their fingers as badly as I’ve got LaunchBar in mine, but they’re unlikely to switch anytime soon.

And then there’s the folks out there who haven’t discovered the joys of a launcher program and just run Applescripts manually or with something like FastScripts.

All of which adds up to a bit of a conundrum if you want to share your favorite Applescripts with the world. Fortunately, with a bit of Googling and some good old trial and error, I’ve written a simple Applescript template that allows all users, no matter how they like to launch scripts, to use yours. Without further ado, here’s the code:

-- You'll want to rename this function something appropriate
on action_function(someText)
    -- Check to see if we've got text, ask for it if not
    if someText is equal to "" then
        set question to display dialog ("Enter text:") default answer ""
        set someText to text returned of question
    end if
    -- Do whatever your script does here
end action_function

-- Quicksilver tie-in code
using terms from application "Quicksilver"
    on process text qsText
        my action_function(qsText)
    end process text
end using terms from

-- LaunchBar tie-in function
on handle_string(lbText)
    my action_function(lbText)
    open location "x-launchbar:hide"
end handle_string

-- Call the function in case the script was run directly
-- (Don't worry; this line won't execute if called from LB or QS)
my action_function("")

If you’re familiar with Applescript, the code should be pretty self-explanatory. You wrap all of the scripts actions into a function (called action_function in the example), and then call that function using the specific access routines for Quicksilver or LaunchBar (with a normal call to the function included just in case the user directly accesses the script). The code within action_function is merely a fall-back in case it receives a blank string (you’ll likely only need the fallback if they are calling the script directly). I leave any more specific error checking to you.

This template specifically accepts text; if your script needs to process a list of files, for example, you’ll need to change the code for the various programs appropriately (how specifically to do that I leave up to you, but the general template should still serve you well). One caveat is that if you’re compiling the code, you’ll need Quicksilver installed (even if you only use LaunchBar). However, as far as I can tell, if you’re just running the Applescript you don’t need to have either program installed (or you can have just one or the other). The main downside of needing both to compile is that if you rely on your users to adjust config variables in your script, then they will need to install Quicksilver (unless you include instructions to remove Quicksilver’s code if they aren’t using it).

Let me know if you run into any trouble using this code! I haven’t run into any errors with it in my testing, but that certainly doesn’t mean that they don’t exist.

Textmate Emulation Applescripts for Coda

Update: TEA for Coda documentation and other information has now moved over to One Crayon:

http://onecrayon.com/tea/coda/

Textmate is a fantastic editor. Every once in a while I try a different text editor, but none of them allow me to get even close to the speed and productivity that I enjoy with Textmate.

However, I recently took another look at Coda when it was updated to version 1.5 because the update came out at the same time that a project which benefited a lot from Coda’s all-in-one interface hit my plate (gotta love remote editing with SSH access in the other split). Although nothing can salvage Coda’s craptastic CSS editing (nothing but a straight-up duplication of CSSEdit’s fantastic auto-complete and intelligent indentation, that is) with a little Applescript I was able to emulate four of the functions from Textmate that I find absolutely critical to my coding happiness and productivity. Without further ado, I give you the Textmate Emulation Applescripts for Coda:

Download TEA for Coda

TEA for Coda currently offers four of my favorite actions from the Textmate HTML and Hyperlink Helper bundles (in slightly less elegant and feature-rich implementations, of course, given that it’s Applescript and Coda’s less-powerful editing environment):

  • Insert Open/Close Tag: this is the functionality that I can’t live without. Just type the tag you want and run the script to have the tag automatically created and your cursor inserted inside (you can also type a tag with attributes, select it, and the script will intelligently exclude the attributes from the closing tag). The only thing that makes me sad is that Coda doesn’t have Textmate’s intelligent text indentation, so adding divs with the script is still a little frustrating.
  • Tidy HTML: this runs Tidy HTML optimized to correctly indent your code rather than clean up messy code (Coda lacks automatic code indentation, and I write clean code anyway; see the Read Me for info on changing Tidy’s default options if you’d rather use it to fix Word HTML, for instance).
  • Wrap Selection in Link: this mimics the basic functionality of Textmate’s Hyperlink Helper Wrap Word as Link, but without the cool automatic title attribute generation or tab controls. It will automatically grab whatever’s on the clipboard, though, making it easy to create links if you’ve copied them from elsewhere.
  • Wrap Selection in Tag: use this script to wrap the selected text in an arbitrary tag. Like Textmate, it allows you to enter attributes but doesn’t stick them in the closing tag. Unlike Textmate, it forces you to use enter the tag in a dialog box; about the same speed, but much less elegant.

Make sure after installing the scripts that you customize yourself some shortcuts either using the System Preference Keyboard and Mouse area, or with a utility like FastScripts. The ReadMe includes a list of the default Textmate shortcuts for your reference if you’re a Textmate user.

Hopefully these scripts will help other people who want to leverage the awesome HTML editing capabilities of Textmate along with the all-in-one sweetness of Coda. If you’re an Applescript ninja and decide to improve on or add to the scripts, please let me know! I’d love to implement better solutions to my own workflow, and I’m a bit of an Applescript noob so the scripts could doubtless be improved.

As far as my own plans for the bundle go, I intend to add a script to emulate Textmate’s Wrap Each Selection in Open/Close Tag and I’m also hoping to increase the intelligence of some of the scripts by offloading some of the logic to shell scripts; just need to work on my Python-fu or something before that can happen.

While Coda is still a jack of all trades and master of none, the TEA for Coda bundle has at least made it usable for me on those projects where its collection of features and awesome split abilities make it a better choice than Textmate. I just hope that Panic will implement some intelligent indentation for a future version, as that’s still the most glaring omission when trying to perform basic text editing, even with TEA for Coda installed.

Minor update Sept. 1, 2008: With thanks to Brian Haslanger, Format with Em (menu title: Em) and Format with Strong (menu title: Strong) are now a part of the TEA for Coda. If you’ve already installed the bundle, just redownload, copy the HTML/Format folder into your ~/Library/Scripts/Applications/Coda/HTML folder, and add the cmd-I and cmd-B shortcuts in System Preferences.

Minor update Sept. 2, 2008: TEA for Coda now includes the most recent version of Tidy (the HTML Tidy site provides binaries that are several years out of date). Additionally, the Tidy script will now accept selected text and only tidy that text (without inserting a bunch of useless body tags and so forth). If you don’t select any text, it will tidy the entire document. I’ve also revised the tidy_config.txt file to some more sensical defaults. Updating procedure is the same as before.

Minor update Sept. 25, 2008: TEA for Coda now has a dedicated landing page; please reference that for the most up-do-date information about the scripts. I’ve also updated the scripts with bug fixes and more, but I won’t be updating this post any more when I update the scripts down the road.

Minor update Nov. 10, 2008: So I lied about never updating this again; since this post continues to be a popular landing spot for Google, I wanted to let folks know that TEA for Coda now includes a Universal Binary version of Tidy HTML. If you’re using a PPC, definitely grab the download above and update (more info on updating in the Read Me, or here).

Minor update Nov. 11, 2008: TEA for Coda now requires Coda 1.6 (which is a free update for all Coda users), and the scripts will now perform their actions in the active document, even if there are multiple windows open.

Run a Python script in Mac OS X Terminal

Terminal.appI’m sure this is self-evident for anyone with halfway decent knowledge of the Unix command-line, but it took me some searching through multiple sources to figure it out. (Kept getting env: python\r: No such file or directory errors whenever I tried to run the script on its own.)

If you need to run a Python script in the Mac OS X Terminal, save the script somewhere on your hard drive and run the following command:

python path/to/script [options]

Obviously, replace [options] with any options or arguments that the script accepts (or leave it off entirely). Remember that if you’re using bash for your shell, you can hit tab to autocomplete paths (which speeds things up a lot) and you’ll need to escape any spaces in paths with a backslash:

python ~/Documents/My\ Python\ Scripts/script.sh

Please note: I’m using OS 10.5; I believe the above will work with 10.2+ (since I think that’s when Python was bundled with the OS), but your mileage will vary. If you’re having issues, the Python documentation was one of the best resources I found, and of course the help file for the python command was useful once I figured out I needed to use a command other than running the script (type man python to access it).

Track me like a stalker:
  • Tagamac
  • Twitter
  • beckbits
Clicky Web Analytics