Terminal scripting in 10.5

posted by Tim on 11.03.07 @ 2:55 pm

Terminal in 10.5 has seen some great scripting improvements to match its additional functionality. Occasionally I have several Terminal sessions with some ssh‘d remote servers and then I forget which Terminals are local and which are remote.

Here is a simple little command-line AppleScript that will let you set an individual Terminal’s style from the command line;
(2009-09-01: updated for Snow Leopard)setterminalstyle-v2

Put the script in your PATH somewhere and then add a ssh function in your .zshrc, or equivalent:

# Show remote Terminal sessions with a different style.
# TERM_PROGRAM doesn't get set if we are logged in remotely,
# but then the originating Terminal could have done this (hopefully).
if [ "$TERM_PROGRAM" = "Apple_Terminal" ]; then
  function ssh {
    SetTerminalStyle ssh
    /usr/bin/ssh "$@"
    SetTerminalStyle default
  }
fi

Finally, create a ssh Settings entry in Terminal’s preferences:

Terminal-ssh-settings-set.png

Other obvious commands for this include sudo and su.Using RPROMPT and Terminal’s processes scripting property on tab it might be possible to get this to work without the function wrappers, but executing the AppleScript on every command was a little too slow for my taste.

OmniFocus: What We’ve Learned So Far (Engineering)

posted by Linda on 09.17.07 @ 12:38 pm

Today’s post is the first in an ongoing series I’m calling OmniFocus: What We’ve Learned So Far (or OF: WWLSF, if you prefer acronyms). As we move slowly but steadily towards a feature freeze and public beta, I thought it would be interesting to get some input from various people here at Omni on things that have gone well, as well as things that have sucked challenges we didn’t anticipate—basically, the ups and downs behind building a piece of commercial software.

We’re going to start out in the technical arena, so I apologize if code-talk makes you yawn so hard you accidentally drool a little. Here is Omni’s engineering perspective on an important lesson learned during OmniFocus’s development process, which can be boiled down to: we ♥ CoreData, but not as a primary file format. 

With more on this subject, here is Tim Wood, hater of Aeron chairs, terror of the Unreal Tournament battlefield, and OmniFocus team lead:

There are many things that are great about CoreData, but using CoreData as a user-visible file format was really painful. Since inception, our xcdatamodel file has had 92 revisions, with most of those exposed to several thousand people via our automated builds. Most of these changes aren’t things that users would notice; we often add or remove precalculated summaries, denormalize data or generally change the underlying CoreData representation to make our app easier to implement and tune. Yet, with CoreData, the SQLite mapping would be busted beyond hope by adding or removing a column.

Manually building code to migrate between model versions is really not an option. If CoreData had a Rails-like migration facility where columns could be added and removed trivially via SQL ALTER statements, it might be feasible, but it still wouldn’t be good. CoreData explicitly disclaims any support for direct access to the various stores, so it isn’t a public file format and hinders our users from easy access to their data. In practical terms, we all know that a liberal application of the letter ‘Z’ will get you most of the way to accessing your data. Still, this isn’t ideal.

What CoreData is great for is building an optimized cache of your data, fetching against it and then binding it to your interface.

A couple of other key observations are that we already needed a public file format for Export (we chose a custom XML grammar, but that’s merely a detail). And, using a variant of the public file format for the pasteboard format is a great way avoid writing and testing more code (as is using your pasteboard archive/unarchive code to implement your AppleScript ‘duplicate’ support…)

Given that, I tweaked our XML archiving to support writing a set of CoreData inserts, updates and deletes as a transaction. We can then write out a small fragment of our content in a new gzipped XML file inside our document wrapper. The structure of our XML transactions is very simple with a key feature being that we can trivially merge a big batch of transaction into a single XML document that contains only the final set of objects as inserts.

On startup of OmniFocus, it scans the transaction log in the user’s document and builds a cache validation dictionary that contains:

• Version of Mac OS X
• CoreData’s version
• SVN revision of the application
• The last transaction identifier

We then open up the CoreData SQLite persistent store and peek at its metadata. If it isn’t an exact match, we close up the persistent store, and rebuild the entire thing by importing our coalesced transaction log in exactly the same way we would import one of our backup files.

There are many extra implementation details (locking, catching the insert/update/delete notification, undo/redo vs. AppleScript, two-phase commit between the XML and SQLite, …), but we are really happy with the central approach.

Some of the fun things this gives us:

• You can run the same build of the application on 10.4 and 10.5, switching regularly and not worry if CoreData is going to ignite your SQLite store.
• You can run multiple builds of OmniFocus on the same data and not lose anything (more work may be needed for major file format upgrades if there ever is one).
• If we do screw up one of our automated builds and mess up cache updating code, the user’s data doesn’t get touched and it’s just fine on the next build.
• Until the transaction log is compacted, we actually have the full record of edits and we could hypothetically implement persistent undo, allowing the user to rollback to yesterday’s version…
• … or calculate the changes they’ve made since some point in time.

The last point is really interesting and I’m hoping to make good use of that in the future for things like computer-to-computer synchronization (no, I’m not promising anything)!

Interview with Ken Case over at MacApper

posted by Linda on 09.10.07 @ 12:38 pm

For those who might be interested, Ken recently answered some interview questions over at MacApper. Topics include Ken’s Old Skool Programming Street Cred (respectably nerdy!), his thoughts on being Omni’s CEO, and upcoming development plans.

Check it out when you get a chance!

OmniFocus crash statistics

posted by Tim on 07.25.07 @ 10:36 am

For many years now we’ve had an integrated crash reporting system. This has helped improve the stability of our applications immensely (often report now start out with “Wow, this is the first crash I’ve seen…”). But, it hasn’t always been clear (especially in the alpha or beta timeframe) how well we were doing on overall stability. We could guess by counting the number of crash reports vs. an estimate of the number of active users, but that wasn’t very convincing.

Near the beginning of June, I added some support to our software update and crash logging frameworks to keep track of things like:

  • total times the application has been launched
  • total number of crashes
  • total amount of time the application has been running

(As always, our software update system reports its information without including any personal details, and can be disabled entirely if so desired.)

Using this, we can now chart the total number of hours OmniFocus has been running vs. the total number of crashes (reported or not!). As the pool of people testing OmniFocus goes up, or some testers go idle, or some user with large number of crashes isn’t reporting them, we don’t have to wonder as much how that affects our average crash rate.

OmniFocus Hours per Crash 20070725

After my latest crash fix, our rate has improved to about 8000 hours per crash. We aren’t sure yet what constitutes a reasonable lower limit for hours/crash, but this does let us notice when a fix we’ve made actually is addressing the issue. We aren’t yet tracking the number of hours that the application is active (an hour spent hidden counts the same as an hour spent in full use). Whether this matters, when averaged across a large number of users, is open to question.

Still, there are only 8760 hours in a year, so if we can get above that, we’ll be feeling pretty good.

Catching float- and struct-returning messages to nil

posted by Tim on 03.11.07 @ 7:46 pm

Wim came up with a neat trick a while back that we’ve used to find and fix several bugs in our software, and to file a bunch of Radars. There are several messenger dispatch functions in the Objective-C runtime. Of particular interest here are objc_msgSend_fpret and objc_msgSend_stret. These are used by the compiler when calling a method that returns a float or struct, respectively.

Depending on your architecture, the result of such a message can be undefined when sent to nil. Messaging nil is very useful most of the time, but you can introduce rarely manifesting bugs in this case.

Looking at the disassembly for these two functions in gdb, though, gives us an easy way to catch them. Under 10.4.8/x86, we see the following:

(gdb) x/50i objc_msgSend_fpret
0x90a573c0 :        mov    4(%esp),%eax
0x90a573c4 :      test   %eax,%eax
0x90a573c6 :      je     0x90a57420
0x90a573c8 :      mov    0(%eax),%eax
...

That is, load the first argument, check for zero, if so jump to 0x90a57420.

Likewise, in objc_msgSend_stret:

(gdb) x/50i objc_msgSend_stret
0x90a57340 :        mov    8(%esp),%eax
0x90a57344 :      test   %eax,%eax
0x90a57346 :      je     0x90a573a0
0x90a57348 :      mov    0(%eax),%eax
...

In our ~/.gdbinit we can have:

# Nil-handling path for objc_msgSend_fpret.
b *0x90a57420
comm
  p (char *)$ecx
end
# Nil-handling path for objc_msgSend_stret.
b *0x90a573a0
comm
  p (char *)$ecx
end

(where the print command shows the selector).

Senior Cocoa Coder

posted by Tim on 01.23.07 @ 8:05 am

Omni’s currently looking for a coder to help us implement our award winning apps. Send in a resumé and join the fun!

Q & A: Omni answers, take three

posted by Linda on 11.02.06 @ 3:32 pm

Welcome to the third, and for this week anyway, final installment of “You Ask, We Answer!”. Brought to you by Diet Coke and the letter Q.

(Q for Qwality!)

Ayjay asked, many Mac developers have moved away from the use of drawers (especially now that Apple has taken them away from Mail) but you guys still feature drawers-a-plenty. What do you like about drawers? Have you thought about any other ways of implementing the functionality that drawers give you?

Ooh, good question. I had to call in the troops for help on this one, since my opinions on drawers are mainly limited to the kind you put your socks in. Ken, our CEO, and Bill, our UI Lead, put their heads together to answer you:

‘We like drawers because they are a great place for content that belongs to the main window but doesn’t necessarily need to be there all the time. They’re great for “source lists”, from which you can choose what to view in the main window, like OmniGraffle’s canvases or OmniWeb’s tabs. Perhaps best of all, unlike a sidebar, you can show, hide, or resize a drawer all day long without affecting the dimensions or layout of the main content. And in Omni apps, you can move the drawer to whichever side of the window you prefer by Option-clicking the drawer button in the toolbar.

The problem with drawers, of course, is that the things just don’t look modern. While the rest of Mac OS X interface was getting the sleek plastic or metal treatment, drawers are still as pinstripey, space-wastey, and noisy as they were the day they were introduced. Unless we want to cobble together and maintain some sort of custom fake drawer ourselves (or—gasp!—Apple actually updates drawers’ appearance), we’re going to have to get away from drawers eventually.

In meetings for our new products, we’ve talked about how to deal with this problem, and we think we may have come up with a good hybrid of the useful drawer and the sleek sidebar. You may end up seeing the first incarnation of it in OmniFocus, if we can do it right.’

Spencer says, I have had no luck at all with storing OmniGraffle documents in Subverson. The icon seems to contain an illegal character or something.

Here’s the response from our OmniGraffle tech support/product manager NINJA EXTRAORDINAIRE:

‘This is likely due to OmniGraffle saving the files out as packages, which other file systems can have difficulty dealing with.

OmniGraffle will automatically save a file out to a package if an image or external graphic is present in the document; there is a hidden preference to avoid this behavior that can be enabled from the command line. To get OmniGraffle to always save as a “flat” file (which will have no problems on other filesystems), open up Terminal.app and paste this in:

defaults write com.omnigroup.OmniGraffle PrivateGraffleFlatFile 0

Afterwards, new documents should always save as a monolithic file, you may have to perform a “Save As” for existing documents to convert them.’

Man, I’m loving this whole ‘fob off the hard questions on other Omni employees’ gig. What else have you got, commenters? Bring. It. On! *spirit hands*

Matt wants to know, Do you guys plan on fixing RSS anytime soon? Its a sometimes it work, sometimes it doesn’t work symptom. Usually I have to relaunch OmniWeb to get it to recheck RSS feeds- it doesn’t do it by itself even though I have it set to recheck the feeds every hour.

Dang, this one’s less fun to answer. Turns out we’ve seen this issue and we’re able to reproduce it. It’s a bug that we’re hoping to fix in an upcoming release, after the 5.5.1 update. Sorry about that!

Conor asks, Can you tell me if OmniFocus will liason with OmniPlan so that you can plan projects in OmniPlan and then download your personal tasks into OmniFocus? Also, are there any plans to allow Wintel users to edit OmniPlan? I work in a mixed-platform office and, while I do most of the project planning on my mac, it would be nice to enable other employees to check off tasks, etc.

We would love for OmniFocus and OmniPlan to work together that way, but I think it’s safe to say that they won’t for OmniFocus 1.0. We’re trying to limit the scope to what we can actually get out the door in a (hopefully) reasonable amount of time, but it’s definitely on the plate for future consideration.

As for Wintel users…well, we likely won’t ever have a cross-platform version of OmniPlan, but you can use OmniPlan to export to .mpx, .mpp, and MSPDI .xml for sharing with Microsoft Project and other project management applications. You can also export to a .csv file for import into Excel, and if people just need to see the data, not update it, you can export the Gantt, outline or both into several different image formats (PDF, PNG, TIFF, JPEG). And! You can export to html – either a single table of tasks, or a mini-website with a Gantt chart, tables, and calendar files that can be imported into iCal, Outlook or other calendaring apps.

Thanks for all your questions, folks, and if I didn’t get to yours this week, my apologies. Please stay tuned for an Exciting Announcement (note: your excitement may vary) about OmniWeb I will be posting later today. Same blog time, same blog channel.

Q & A: Omni answers, take two

posted by Linda on 10.31.06 @ 3:57 pm

Happy Halloween, Omni blog readers! Troy is wearing a purple wig today, James is sporting some bright orange socks with bats on them (although for James that’s a fairly typical fashion choice), Ken is wearing a lab coat, and Greg’s son Miles has been transformed into…well, Darth Toddler:

darthmiles.jpg

Hee. I love the thumbs up gesture, there.

Okay! On to more questions, before all our pumpkins turn into…uh…chariots, or something.

Dan asks, Is there any sort of official list of ideas and feature requests for future releases? Have you ever thought of doing something like an “OmniProduct Focus Group,” or is this something that would be completely unnecessary?

We definitely have an internal system for tracking ideas, feature requests, and bugs, and assigning things to specific target releases for all of our products. I’m guessing you’re wondering more about a publicly available list, so you can see what’s already been suggested? We don’t have such a thing, exactly, but you can see what other people are talking about on our forums, and add your input there. Otherwise, we always welcome feedback via email, so please feel free to send us your requests.

As for a focus group, we’ve never hosted a formal type of group (the kind where you get free soda and people with clipboards peer at you from behind one-way mirrors), although we have asked people to join an “Alpha Brute Squad” where they get a really early look at our software (sometimes when it’s in a mildly terrifying, devouring-its-own-tail state of bugdom!) and have a chance to provide feedback on features and UI before it goes into public beta.

I don’t yet know what we’ll be doing for OmniFocus, but I’d recommend signing up on this mailing list if you’re interested in potentially being tapped for Brute Squad duty.

Kirk wonders, Any chance of transferring an Outliner license to Focus when it comes out?

Sort of. We will be offering discounted OmniFocus licenses for OmniOutliner customers, so while you won’t be able to transfer one app license to another, you won’t be charged full price either. We haven’t made any final pricing decisions, but we definitely recognize that we need cross-product discounting.

David asks, How do I enter curved text in OmniGraffle? That is, if I want a line of text to follow a curved path (like a squiggle or around a circle/arc), can it be done [...]?

Sorry, you can’t created curved text in OmniGraffle (although you should be able to copy and paste it in from a graphic created elsewhere). If you don’t have Illustrator, as you mentioned, maybe something like LineForm or EazyDraw would work?

Dan asked another question: is there a story for the change in the status of Omni’s apps that come bundled with most Macs, with the switch to Intel? (Specifically, the addition of OmniOutliner to all consumer Macs and the loss of OmniGraffle.)

If there’s a story, only Apple knows it. We don’t really have any influence over what Apple decides to include, or not include, in their hardware – we just review what they ultimately propose and decide if we want to say yea or nay. The expanded bundle deal for Outliner has been great, although in general I wish our software were easier to discover. You know, instead of being all tidily tucked away in the Applications folder, maybe it could be…sitting in the Dock? (Apple? I’m just sayin’.)

Nik asked several questions, most of which I’ve sent on to tech support, but here’s one for the blog: Is it possible to save an OmniOutliner document so that it’s JUST the XML file and doesn’t have the bundle “wrapper” around it? (Then I could check it into source control and stuff.)

You can check it into source control, I’m told. OmniOutliner supports CVS and SVN, so you can check it in as is, folders and all.

All righty then! This concludes today’s Q&A With Omni. I may follow up with a third and final post on Thursday, so if you have any more questions, leave them in the fancy comment box.

And now, I’m off to help my son trample large metropolitan areas. RAARRRRR!

godzilla.jpg

Q & A: Omni answers, take one

posted by Linda on 10.30.06 @ 4:38 pm

Oh crap, you mean you’re actually going to ask, like, real questions? Well FINE. Make me work, why don’t you.

(Note: if you need technical support on any of our apps, it’s best to send it to our support team using Send Feedback.. under the Help menu in your software. I may not get to *everyone’s* question this week.)

Richard asks, How can I get OmniWeb to open up RSS links in Vienna, my preferred RSS reader?

We have a current OmniWeb bug described as:

“Request: Allow news icon to send RSS feed subscriptions to outside program/external viewer [newsfeed default]“ 

This should be implemented in 5.5.2, an update that should be available soon (I’m not sure exactly when, but not too long from now).

Matthew has some Omni software on his laptop, and now that his employer has provided him with a PowerMac, he wants to know how to use those same apps via network licensing.

There is a lengthy explanation of our different licensing types here, but in a nutshell, you’ll just need to install your Omni application of choice on your Power Mac (grab the download from our website), then use the same license you’ve been using on your laptop. You cannot, however, run two copies of the licensed software using one license at the same time – otherwise, both of your computers will explode.

(Okay, they won’t technically “explode”, but it would violate our licensing policy and that would mean that somewhere, a kitten would cry. Won’t you please, please think of the kittens?)

Edward would like to know, Are there any “secret” ways to get OmniWeb to run quicker?

Down at the lower righthand corner of the screen, there is a very, very small button that’s labeled “TURBO”. Click it, and –

Okay, I’m making that up. I wish I had some kind of cool answer like that, but unfortunately there’s no simple response to that question. There are too many variables to consider, like when you’re experiencing the issue (I assume you mean that the browser is running too slow at times?), what else you have going on, etc. You are running 5.5, right? If so, I suggest using the Send Feedback…option to tell us more about this so we can look into it, or email us.

BZ asked a LOT of questions, JEEZ. I’ll answer two of them for now: When is OmniFocus coming out and who do I have to kill to be on the beta?

To be 100% honest, we don’t know when OmniFocus is coming out. There is a team working full time on developing this product, but it’s just too early to make predictions. We all really want to get it in your hands as soon as possible, though. As for the beta, when the time comes we’ll be asking for volunteers. If you want to get your name in the hat now, subscribe to this list and we’ll get in touch with you as soon as it’s Beta Time (like Hammer Time, except with slimmer pants).

Stack said, Tell us a little bit about OmniFocus. [...] The GTD system gives you breathing room to be implemented in a few different ways, but aside from interface stuff I don’t really see how your product can distinguish itself from its competitors in the market. How will OmniFocus be different?

I can’t make any commitments yet on specific features that will be included in OmniFocus (I know, I’m all “ask us anything!” and then I give you, “errr…except that”). We’re still defining how features will work; figuring out implementation and UI, and creating crazy mockups using OmniGraffle (oh, OmniGraffle, is there anything you can’t do?).

I will say that the “interface stuff” – how the software looks, the way that it works, the experience you have when using it – is exactly what can distinguish one app from another and make all the difference in its value. If OmniFocus ends up being a joy to use, if it seamlessly integrates into your workflow, if it stays out of your way but provides you with what you need, then we’ll have accomplished some of our biggest goals.

Our friend Corentin (who has done countless French localizations for us, merci!) asks, in part, What’s planned for OmniWeb 5.6? When will a beta be out the door?

We are planning for 5.6 to be a WebKit update. As for timing, we have to get through 5.5.1 (currently in beta), then 5.5.2, then revisit the WebKit situation so…in short, we’re not sure when 5.6 will be available, but it shouldn’t be too long of a wait. *knock wood*

Daniel says, I’m playing through Oni at the moment, and I’ve found a few bugs. If I report them, do they have a chance of ever being fixed?

Well…probably not. That’s what I’m told, anyway. We did the game port many, many moons ago and no longer have anything to do with Oni, which is now owned by Take 2 Interactive. You could contact them with your bug info and request an update, but it doesn’t sound very likely that it will happen. Sorry, I wish I had a more helpful answer.

WHEW. That’s all for now, folks, I’ll try and answer more tomorrow. Oh, and for the record, we have one cat. Her name is Lotus. She’s kind of mangy and makes horrible yowling sounds, but she is loved nonetheless.

Committed

posted by Tim on 06.09.06 @ 9:12 pm

Since I just committed my last OmniDazzle fix (at least until QA tracks me down…), I thought I’d share a fun graph.

Omni has been using source control systems like CVS and Subversion since forever. A while back, we converted to Subversion and imported most of our CVS repository (none of our old consulting projects, just our apps). Here is a graph of the number of commits in our repository over the last 13 years.