<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Atomized &#187; Technology</title>
	<atom:link href="http://atomized.org/Category/technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://atomized.org</link>
	<description>Fragmenting reality.</description>
	<lastBuildDate>Mon, 23 May 2011 23:46:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>I Hate Google Everything</title>
		<link>http://atomized.org/2011/05/i-hate-google-everything/</link>
		<comments>http://atomized.org/2011/05/i-hate-google-everything/#comments</comments>
		<pubDate>Mon, 23 May 2011 23:46:29 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=799</guid>
		<description><![CDATA[Let’s examine a normal interaction with Google products. I get a link to a document on Google Docs. I click the link, and I’m greeted with this: This is likely because I have signed in with my personal account, which I must do to interact with YouTube. No problem, look at that “Sign in as [...]]]></description>
			<content:encoded><![CDATA[<p>Let’s examine a normal interaction with Google products.</p>
<p>I get a link to a document on Google Docs. I click the link, and I’m greeted with this:</p>
<div id="attachment_805" class="wp-caption alignnone" style="width: 1056px"><img src="http://atomized.org/wp-content/uploads/2011/05/hate-signin-1.png" alt="Signing in" title="Signing in" width="1046" height="122" class="size-full wp-image-805" /><p class="wp-caption-text">Seems reasonable.</p></div>
<p>This is likely because I have signed in with my personal account, which I must do to interact with YouTube. No problem, look at that “Sign in as a different user” link just begging to be clicked.</p>
<p>I click it, and one of two things happens: I get bounced to the contents page of my current account, with no prompt to log in as a different user whatsoever. This happens frequently. Alternately, I actually get prompted to sign in.</p>
<p><img src="http://atomized.org/wp-content/uploads/2011/05/hate-login-2.png" alt="Accounts login prompt" title="Accounts login prompt" width="257" height="277" class="alignnone size-full wp-image-804"><img src="http://atomized.org/wp-content/uploads/2011/05/hate-login-1.png" alt="Standard login prompt" title="Standard login prompt" width="333" height="228" class="alignnone size-full wp-image-803"></p>
<p>The Google Accounts login widget implicitly includes the domain portion of your email address.</p>
<p>Unfortunately, the regular login widget requires you to enter a full email address. And even if you have a Google Accounts account, and even if you were going to view a document in another account, you get the standard widget. This defeats tools like 1Password (which I use), as well as just being confusing. You get used to logging in on one way, then have to do it differently; because you’re never sure which one you’ll get, you have to pay attention. Friction, unhappiness, annoyance.</p>
<p>After successfully navigating this, what happens? I get sent back to the list of documents for the new account, rather than sent to the document I actually opened. Incredible.</p>
<p><img src="http://atomized.org/wp-content/uploads/2011/05/hate-link1.png" alt="A link!" title="A link!" width="571" height="300" class="alignright size-full wp-image-800"></p>
<p>After tracking down the original link and opening it <em>again</em>, you finally get to see the document, and now the real usability WTFs can begin. There’s a link in the document, which I would like to follow. When clicked, you get this:</p>
<p><img src="http://atomized.org/wp-content/uploads/2011/05/hate-link2.png" alt="What? " title="What?" width="571" height="300" class="alignnone size-full wp-image-800"></p>
<p>I click it <em>again</em>. Do I get the page I wanted? No, I get a redirect through <code>google.com</code>.</p>
<p><img src="http://atomized.org/wp-content/uploads/2011/05/hate-link3.png" alt="Uuuugggh" title="Uuuugggh" width="502" height="126" class="aligncenter size-full wp-image-802"></p>
<p>Does Google have anyone working on UI/UX? This is absolutely horrible.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2011/05/i-hate-google-everything/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Toggle between root &amp; non-root in Emacs with Tramp</title>
		<link>http://atomized.org/2011/01/toggle-between-root-non-root-in-emacs-with-tramp/</link>
		<comments>http://atomized.org/2011/01/toggle-between-root-non-root-in-emacs-with-tramp/#comments</comments>
		<pubDate>Wed, 19 Jan 2011 03:26:47 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[tramp]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=794</guid>
		<description><![CDATA[I love that I can edit files on remote hosts right from the comfort of my local Emacs session. Even better, you can edit those same files as root, given the proper configuration. Unfortunately, the interface for this is a bit fiddly. I find myself taking one of two approaches: Open a file as non-root, [...]]]></description>
			<content:encoded><![CDATA[<p>I love that I can edit files on remote hosts right from the comfort of my local Emacs session. Even better, you can edit those same files as root, given <a href="http://www.gnu.org/software/emacs/manual/html_node/tramp/Multi_002dhops.html">the proper configuration.</a></p>
<p>Unfortunately, the interface for this is a bit fiddly. I find myself taking one of two approaches:</p>
<ol>
<li>Open a file as non-root, then hit <code>C-x C-v</code> and edit the filename to use <code>/sudo:root@…</code>.</li>
<li>Hit <code>C-x C-f</code>, edit the directory to use <code>/sudo:root@…</code>, then open the file I want.</li>
</ol>
<p>Since I didn&#8217;t like either of these, I wrote two functions to assist:</p>
<ul>
<li><code>find-file-as-root</code> behaves as <code>find-file</code>, except the default shown is changed to be <code>/sudo:root@…</code></li>
<li><code>toggle-alternate-file-as-root</code> is similar to <code>toggle-read-only</code> (<code>C-x C-q</code>), in that it will swap back and forth between the unprivileged version of a file and the as-root version.</li>
</ul>
<p><script src="https://gist.github.com/785600.js?file=toggle-root.el"></script></p>
<p>I bind these to <code>C-c C-x C-q</code> and <code>C-c x f</code>, respectively.</p>
<p>There are two caveats. The first is that you must have <code>tramp-default-proxies-alist</code> configured for the <code>sudo</code> method to work on remote hosts. The second is that it is impossible to know for sure what the previous file name was after invoking <code>toggle-alternate-file-as-root</code>. Any buffer-local values are lost after replacing the buffer with the sudo version, and if I used a persistent structure outside of the buffer, it would require more complexity to prevent it from going stale. So instead, it just make a best effort to come up with something reasonable. Edge cases are going to fail, such as when you are editing a file as another non-root user. Patches are welcomed.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2011/01/toggle-between-root-non-root-in-emacs-with-tramp/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>iPad</title>
		<link>http://atomized.org/2010/10/ipad/</link>
		<comments>http://atomized.org/2010/10/ipad/#comments</comments>
		<pubDate>Tue, 19 Oct 2010 01:48:49 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[ipad]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=786</guid>
		<description><![CDATA[I’ve had my iPad for around six months now, and I wanted to put down some of my thoughts on it and where it fits into my life. When I first got it (a week after launch), everyone wanted to know about it. Some of that magic has worn off, but it still turns heads. [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve had my iPad for around six months now, and I wanted to put down some of my thoughts on it and where it fits into my life.</p>
<p>When I first got it (a week after launch), everyone wanted to know about it. Some of that magic has worn off, but it still turns heads. When I use it in public, everyone wants to know if I like it and how well it works. The number one question I get is, “how much a month does it cost?” and most people are surprised when I answer “nothing.” I have the WiFi model, and free WiFi is ubiquitous. The 3G model might be more useful for people who do a ton of traveling — and the addition of GPS is nice — but I’m not sure most people need it. It’s somewhat interesting that people assume that a mobile device has a monthly fee.</p>
<p>Since I got my it, I’ve stopped using my laptop for almost anything. For serious work, I have a desktop, and I use the iPad for almost everything else. The laptop only comes into play when I’m faced with the intersection of portability <em>and</em> work. For pure portability, it’s iPad all the way, and I use my iMac for straight work.</p>
<p>While the iPad is highly portable — much more so than a full laptop — I don’t take it everywhere like I do my iPhone. While the iPad provides a much better experience than the iPhone, it’s just not as essential. If I had to choose one device, it would be the iPhone. I find the myself taking the iPad places when I have a specific task for it in mind — if I want to write, or read a book. If I’m just going out, I usually leave it at home.</p>
<p>It shares a superficial resemblance with its smaller cousins, but very little beyond that; I use the iPhone and iPad very differently. The iPhone is geared more towards getting your attention for a short amount of time, while the iPad is better for focusing on one thing for an extended period of time. My iPhone is always asking for my attention: People call, text, or email, and I answer or reply. I turn all this stuff off on my iPad — If i’m reading a book or playing a game, the last thing I want is to be interrupted. It feels like something that should be used at its own pace.</p>
<p>When Steve Ballmer was asked about the App Store’s burgeoning catalog, he said that the majority were apps just to access web sites. I think that’s an exaggeration, but with a nugget of truth. With speed and real estate at a premium on the iPhone, native apps feel better, even when they have little to offer over a web app.</p>
<p>The iPad is the exact opposite. I use Safari for the majority of sites I visit, and the experience is fine. Because it’s both more capable and because I use it during times of leisure, I don’t feel the need for apps for most things. There are a few exceptions: I use Echofon because it doesn’t incessantly forget my credentials like Twitter does, and Reeder because Google Reader’s web interface is unusable on any platform.</p>
<h2>iBooks</h2>
<p>I find iBooks provides an excellent reading experience, and I use it often. I’ve read several books on it, and I enjoy the experience immensely. One thing I’d love to see is improved notes and annotations. Right now, notes are plain text, and I’ve found occasions where I’d like to annotate passages with photos or video, and this isn’t possible. Even URLs pasted into notes aren’t linked — you have to laboriously copy and paste them.</p>
<p>Even with the gorgeous display on my iPhone 4, real estate wins the day. Reading on the iPhone is cramped and I almost never use it for the extended periods necessary to complete a book. The sync feature is nice, though, and I will pull out the iPhone to read short passages if I’m waiting in line or such. I’d love to see a retina display on the iPad 2, but I’m not holding my breath. It would be amazing, but I think the display is fine as is.</p>
<p>My major gripe with iBooks is the store. DRM is odious for something you’re ostensibly paying money to <em>own</em>. You’re also locked in to Apple devices, since they’re the only ones capable of handling the DRM. Perhaps if the price were low enough that they felt disposable, it would be okay, but $10-$15 is more than I’m willing to pay. Copy-protected titles are also less functional than their free counterparts: copy and paste is disabled in any purchased book. The selection is not there yet, either. This is true to an extent of other ebook stores, but the situation with iBooks is definitely worse. While it can read DRM-free ePub books handily, I haven’t found a single store selling the sorts of titles I’m interested in without copy protection. I’ve discovered that Adobe’s Digital Editions DRM is easily strippable, so I’ve purchased a number of ebooks with it from online retailers, removed the DRM, and read the resulting DRM-free books on my iPad. It’s quite a run-around, though, and many of the books seem to have been corrupted (intentionally?), so every purchase requires much care and attention. It also needs a full and unrestricted computer; you cannot purchase and read these books directly on the iPad. The situation is extremely unsatisfying, and I hope it improves in the future.</p>
<p>The PDF support could also use some work. It’s usually good enough, but it doesn’t feel as natural as reading ePubs. The main problem is that PDF layouts are pixel-precise, and cannot be zoomed and reflowed. You can zoom in if the text is too small, but you must pan around to read it. Using an orientation different from the one the PDF was laid out in is an exercise in squinting frustration. PDFs are completely useless on the iPhone’s smaller screen.</p>
<p>Some people find the iPad too heavy to read on. Your mileage may vary, but it doesn’t bother me. It’s significantly heavier than a paperback, but not much heavier than a hardbound book, and much less bulky. Even when I am traveling for work, I usually bring the iPad along so I have something to read.</p>
<h2>Work</h2>
<p>I tried to see how viaible it was as a platform for working. For my job, at least, it’s not there, and I don’t know if it ever will be. Emacs runs natively on Macs, and it should be possible to port it to Cocoa Touch without much effort. But the nature of Emacs precludes it from ever getting approved in the app store, unless it was neutered to the point of near-uselessness. It depends on running lots of interpreted code and calling out to UNIX utilities which probably aren’t available.</p>
<p>I tried the next best thing, using the iPad as a SSH terminal with iSSH, a $5 universal SSH/Telnet/X11/VNC client. This isn’t as nice as native Emacs, because you need another system to log in to, but it could make an acceptable stopgap. First thing: the touchscreen keyboard is unusable for this kind of thing. The only reason a soft keyboard is viable at all is because of the autocorrection and completion features, neither of which work in iSSH. This isn’t a knock on the program, it’s just how things are.</p>
<p>With an external keyboard, the situation is improved, though still insufficient. You have the full screen for display, but the modifier keys on the keyboard don’t work. There is an open thread about this in the iSSH forums, but there doesn’t appear to be a fix forthcoming. You also cannot remap caps lock to be a control key. which is essential for efficient Emacsing. If these issues were addressed, the situation would be tenable — barely.</p>
<p>The other place it fails as a programmer work machine is in the multitasking model. I don’t have iOS 4.2 yet, but even when I do, it won’t be very useful. When I’m coding, I need the ability to quickly switch apps, but more importantly, I need to br able to SEE other apps. I very often have a primary Emacs window up with my code, and a web browser off to the side with reference material — API documentation and the like. I code, then glance at the docs, then go back to coding. There is nothing in iOS that can make this work, and I don’t know if there ever will be; it just requires a windowing model. I wholly admit that it’s not a case the average user cares about, but it certainly impacts my ability to consider the iPad a serious work machine.</p>
<p>On the other hand, my iPad has almost completely supplanted my iPhone and iMac as my preferred game machine. I’m obviously not a hardcore gamer, but hear me out. When Steve Jobs announced the original iPhone back in 2007, he touted the flexibility of the touchscreen to adapt to whatever sort of input the user needed, something physical input devices can’t do. This all falls down with games, particularly ports.</p>
<p>Games written with care for touch input can be fantastic: <em>Spider: The Secret of Bryce Manor</em>, <em>Angry Birds</em>, <em>Zen Bound</em> and so on. The problem is with action games that try to replicate d-pad style controls on a touchscreen. These are universally terrible, and it’s really too bad. There are two massive problems:</p>
<ol>
<li>You lose screen real estate representing the controls.</li>
<li>There’s no way to know if you’re touching the right place.</li>
</ol>
<p>The iPad is a lot better for #1, because the screen is so much bigger. The second problem, though, that’s s doozy. I played Assassin’s Creed 2 on my iPhone for a while, but the controls were just too rough. I’d end up dying because I hadn’t managed to stab the right bit of the screen, and it was quite frustrating. I played the same game on a NDS, and even with a smaller screen and worse graphics, it was much more enjoyable because the controls were massively better.</p>
<p>The best controls in a platform-style game I’ve found have been in Mirror’s Edge. They’re entirely gestural, feel natural, and aren’t frustrating. It’s clearly an exception to the general rule, and it has simpler controls which are more easily adapted to gestures.</p>
<h2>It’s coming from inside the iPad!</h2>
<p>Despite my criticisms, I really like my iPad, and I’m probably going to get the new one when it comes out. And despite my problems with it as a work machine, it’s quite capable for others’ needs. And the keyboard is really quite good: I wrote the bulk of this post with the touchscreen, then used a Bluetooth keyboard for final edits, cleanup, and posting.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/10/ipad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I’m Not Going Back</title>
		<link>http://atomized.org/2010/08/i%e2%80%99m-not-going-back/</link>
		<comments>http://atomized.org/2010/08/i%e2%80%99m-not-going-back/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 17:20:16 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[digg]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=777</guid>
		<description><![CDATA[I’ve gotten a lot of responses to my post about Digg, and I want to clarify a couple things. Talent I wrote, Even if they still have the systems and the desire to roll back, they don’t have the talent to maintain Digg v3. I wasn’t saying that the current team is untalented. I know [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve gotten a lot of responses to <a href="http://atomized.org/2010/08/they-can%e2%80%99t-go-back/">my post about Digg</a>, and I want to clarify a couple things.</p>
<h2>Talent</h2>
<p>I wrote, <q>Even if they still have the systems and the desire to roll back, they don’t have the talent to maintain Digg v3.</q> I wasn’t saying that the current team is untalented. I know them to be an extremely bright group, and I have great respect for them. They are my friends and co-workers, and I meant them no disrespect.</p>
<p>I’ll put it another way: The institutional knowledge needed to maintain and extend Digg v3 no longer exists. The people who knew how Digg v3 works – and more importantly <em>why</em> it works that way – are gone. The people who still work there haven&#8217;t worked with the v3 code in any significant way in many months. It’s not that they <em>couldn’t</em> do it, but it would take some time to get up to speed with the v3 code.</p>
<p>Every indication from Digg has been that they will continue iterating on v4, and I think that’s the right thing to do. But I also think that going back is simply not an option, for the reasons I outlined.</p>
<h2>Failure</h2>
<p>I also said, <q>rolling back to v3 would be an admission that v4 is a failure,</q> which some might see as me calling v4 a failure. I don&#8217;t think that’s the case; it’s too early to say that it’s a failure or a success. Certainly, some people are upset, and this should surprise no one. Everyone at Digg knew that <em>any change</em> would make some number of users angry.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/08/i%e2%80%99m-not-going-back/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>They Can’t Go Back</title>
		<link>http://atomized.org/2010/08/they-can%e2%80%99t-go-back/</link>
		<comments>http://atomized.org/2010/08/they-can%e2%80%99t-go-back/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 03:59:07 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[digg]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=767</guid>
		<description><![CDATA[Digg v4 finally launched last week, and it’s taking a lot of fire, for both design decisions and technical issues. There are a lot of angry users asking them to go back to the old version. This is simply not going to happen. Love it or hate it, v4 is here to stay. Digg v4 [...]]]></description>
			<content:encoded><![CDATA[<p>Digg v4 finally launched last week, and it’s <a href="http://t3chh3lp.com/blog/tomorrow-is-abandon-digg-day-its-getting-ugly.html">taking a lot</a> <a href="http://digg.com/news/technology/digg_4_goes_live_ish_to_the_public">of fire</a>, for both design decisions and technical issues. There are a lot of angry users <a href="http://www.gopetition.com/petitions/we-want-old-digg-back.html">asking them to go back to the old version</a>. This is simply not going to happen. Love it or hate it, v4 is here to stay.</p>
<p>Digg v4 is not a redesign, not a reskin, it is a 100% <i>rewrite</i>. It’s completely new design, code, architecture, and infrastructure. It has almost no relationship to the v3 system whatsoever.</p>
<p>When we were figuring out how to launch v4, we settled on an extended side-by-side beta alongside v3, with a cutover when it was deemed good enough.</p>
<p>There were a few options on the table for managing the transition:</p>
<ol>
<li>Keep the data completely separate during the beta period.</li>
<li>Have a one-way migration, where actions on v3 would show up on v4.</li>
<li>Have a two-way migration, where actions on either site would show up on the other.</li>
</ol>
<p>We abandoned #1 because it would make the beta site less useful, and we’d still have to migrate the data eventually. We also wanted to be able to test v4 with the same data as we had on v3 to shake out bugs and get a feeling for the differences.</p>
<p>Option #3 was axed due to complexity. We didn’t even know what v4 would be like, and there might not be equivalent actions; and we didn’t have time to solve the problem of suppressing looping actions. That left #2 as the only viable option, and that’s the one we went with.</p>
<p>Now, assuming they deployed new servers for v4 and left the ones with v3 systems alone, it <i>might</i> be possible to relaunch Digg v3. It’s extremely unlikely it will ever happen, because it wouldn’t have any of the data accumulated since v4 launched. Getting all the data back into v3 would be a significant undertaking, and they’re still trying to get v4 under control. Not to mention the huge political implications: Rolling back to v3 would be an admission that v4 is a failure, and I just don’t see that happening.</p>
<p><ins datetime="2010-08-31T04:07:23+00:00">I forgot to add: Even if they still have the systems and the desire to roll back, they don’t have the talent to maintain Digg v3. Nearly everyone who built and worked on the legacy Digg codebase has left the company. When I started at Digg, the engineering team was: Joe Stump, Matt Erkkila, Eli White, Steve Williams, Steve French, Kurt Wilms, Nancy White, Bill Shupp, and Micah Snyder. Operations had Ron Gorodetzky, Scott Baker, and Tim Ellis. Except for Matt, everyone else has moved on. There were others, but those people were the core team that made the legacy code work, and they’re gone now.</ins></p>
<p><ins datetime="2010-08-31T17:54:43+00:00">Edited again to add: <a href="http://atomized.org/2010/08/i%E2%80%99m-not-going-back/">I wasn’t saying that the current team is untalented</a>. I know them to be an extremely bright group, and I have great respect for them.</ins></p>
<p><em>Disclaimer: I worked for Digg from 2008-2010, and wrote a lot of the early code that would become Digg v4. I left Digg in May. My opinions are purely my own, and I have no inside knowledge of what has happened since I left or what will be happen in the future.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/08/they-can%e2%80%99t-go-back/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Hudson/GitHub build process that works</title>
		<link>http://atomized.org/2010/08/a-hudsongithub-build-process-that-works/</link>
		<comments>http://atomized.org/2010/08/a-hudsongithub-build-process-that-works/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 23:10:44 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[simplegeo]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=759</guid>
		<description><![CDATA[I’m a huge fan of Hudson, and have been since I discovered it. The biggest issue I’ve had with it is that the Git plugin just isn’t very good. The situation has improved lately, with Andrew Bayer making significant improvements. With the features he’s added, reasonable and non-hacky workflows are no possible. After some experimentation, [...]]]></description>
			<content:encoded><![CDATA[<p>I’m a huge fan of <a href="http://hudson-ci.org">Hudson</a>, and have been since I discovered it. The biggest issue I’ve had with it is that the <a href="http://wiki.hudson-ci.org/display/HUDSON/Git+Plugin">Git plugin</a> just isn’t very good.</p>
<p>The <a href="http://issues.hudson-ci.org/browse/HUDSON-7276">situation</a> <a href="http://issues.hudson-ci.org/browse/HUDSON-7176">has</a> <a href="http://issues.hudson-ci.org/browse/HUDSON-6902">improved</a> <a href="http://issues.hudson-ci.org/browse/HUDSON-6856">lately</a>, with <a href="http://github.com/abayer">Andrew Bayer</a> making significant improvements. With the features he’s added, reasonable and non-hacky workflows are no possible.</p>
<p>After some experimentation, this is what we’ve settled on at SimpleGeo:</p>
<ol>
<li>Developers work on whatever branches they choose.</li>
<li>The work is reviewed and merged to the <code>pending</code> branch when it passes.</li>
<li>Hudson polls the <code>pending</code> branch. Changes are merged to <code>master</code> (in the repo on Hudson), and the build is performed.</li>
<li>If the build was successful, the result is pushed to the <code>master</code> branch of the repo on GitHub.</li>
</ol>
<p>This works extremely well with GitHub’s Organizations and forking mechanism. Everyone at SimpleGeo has read-only access to all our repos. Each repo is owned by a particular team, and all team members have read-write access. Because of how Organizations work, any member can fork a private repo, and it will stay private — they don’t even need to be on a paid account. If someone wants to contribute to another team’s code, they just fork it, commit to their fork, and send a pull request to the owners. From there, the changes get reviewed and integrated into the <code>pending</code> branch, which triggers Hudson.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/08/a-hudsongithub-build-process-that-works/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Frame tiling and centering in Emacs</title>
		<link>http://atomized.org/2010/08/frame-tiling-and-centering-in-emacs/</link>
		<comments>http://atomized.org/2010/08/frame-tiling-and-centering-in-emacs/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 02:05:46 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=751</guid>
		<description><![CDATA[Since Emacs predates the widespread adoption of the modern GUI andmouse, its vernacular can be somewhat hard to follow. What you would call a window in a modern GUI is called a frame in Emacs. A window is a panel of a frame in Emacs. Most window managers have some facility to arrange the visible [...]]]></description>
			<content:encoded><![CDATA[<p>Since Emacs predates the widespread adoption of the modern GUI andmouse, its vernacular can be somewhat hard to follow. What you would call a <i>window</i> in a modern GUI is called a <i>frame</i> in Emacs. A <i>window</i> is a panel of a frame in Emacs.</p>
<p>Most window managers have some facility to arrange the visible windows. With Emacs, you cna programmatically manipulate a frame’s size and position from Lisp.</p>
<p>There are a few ways I like to arrange my Emacs frames. I generally use one or two – more are harder to manage – and dedicate them to specific purposes. One always has code buffers in it, and the other can have compilation buffers, IRC, w3m, unit test output, or any other variety of programming-related tools.</p>
<p>When I work with a single frame, I like it to be centered on my screen. When I have two, I like them to be next to each other, in the center. Since it’s hard to align by hand, I wrote some code do to it for me.</p>
<pre>
(defun screen-usable-height (&#038;optional display)
  "Return the usable height of the display.

Some window-systems have portions of the screen which Emacs
cannot address. This function should return the height of the
screen, minus anything which is not usable."
  (- (display-pixel-height display)
     (cond ((eq window-system 'ns) 22)
           (t 0))))

(defun screen-usable-width (&#038;optional display)
  "Return the usable width of the display.

This works like `screen-usable-height', but for the width of the display."
  (display-pixel-width display))

(defun frame-sort-ltr (frames)
  "Sort frames by their visual order, left to right.

This method takes a list of frames, and returns that list, sorted
by the visual display order. This is determined by comparing the
left position of the frames; the leftmost frames are returned
first."
  (sort frames (lambda (framea frameb)
                 (< (frame-parameter framea 'left)
                    (frame-parameter frameb 'left)))))

(defun frame-box-get-center (w h cw ch)
  "Center a box inside another box.

Returns a list of `(TOP LEFT)' representing the centered position
of the box `(w h)' inside the box `(cw ch)'."
  (list (/ (- cw w) 2) (/ (- ch h) 2)))

(defun frame-get-center (frame)
  "Return the center position of FRAME on its display."
  (frame-box-get-center (frame-pixel-width frame) (frame-pixel-height frame)
                        (screen-usable-width) (screen-usable-height)))

(defun frame-center (&#038;optional frame)
  "Center a frame on the screen."
  (interactive)
  (apply 'set-frame-position
         `(,(or frame (selected-frame)) ,@(frame-get-center frame))))

(defun frame-tile-horizonal ()
  "Tile visible frames horizontally.

This function tiles visible frames, distributing them evenly
across the display, and centering them vertically.

It doesn't know about multi-head displays, and will probably fail
dramatically if used in such an environment."
  (interactive)
  (let ((pos)
        (offset 0)
        (vwidth (/ (screen-usable-width) (length (visible-frame-list)))))
    (dolist (frame (frame-sort-ltr (visible-frame-list)))
      (setq pos (frame-box-get-center (frame-pixel-width frame)
                                      (frame-pixel-height frame)
                                      vwidth (screen-usable-height)))
      (set-frame-position frame (+ offset (car pos)) (cadr pos))
      (incf offset vwidth))))

(defun frame-tile-center-horizonal ()
  "Tile visible frames horizontally, center-weighted.

Rather than tiling frames evenly across the available width of
the display, this function tiles them into the center of the
display, adding a 2% margin in between frames.

It doesn't know about multi-head displays, and will probably fail
dramatically if used in such an environment."
  (interactive)
  (let* ((framewidth (apply '+ (mapcar 'frame-pixel-width (visible-frame-list))))
         (margin (/ (screen-usable-width) 50)) ;; = (/ s-u-w *.02) = 2%
         (totalwidth (+ framewidth (* margin
                                      (- (length (visible-frame-list)) 1))))
         (offset (car (frame-box-get-center totalwidth 0 (screen-usable-width)
                                            (screen-usable-height)))))

    (dolist (frame (frame-sort-ltr (visible-frame-list)))
      (set-frame-position frame offset (cadr (frame-get-center frame)))
      (incf offset (+ margin (frame-pixel-width frame))))))

(defun frame-restore-defaults (frame)
  (modify-frame-parameters frame default-frame-alist))

(defun frame-default ()
  (interactive)
  (mapcar 'frame-restore-defaults (frame-list))
  (if (> (length (frame-list)) 1)
      (frame-tile-center-horizonal)
    (frame-center)))

(provide 'ime-frame)
</pre>
<p>You can also call <code>M-x frame-tile-center-horizonal</code> or <code>M-x frame-center</code> by hand, if you like.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/08/frame-tiling-and-centering-in-emacs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scratch buffers for Emacs</title>
		<link>http://atomized.org/2010/08/scratch-buffers-for-emacs/</link>
		<comments>http://atomized.org/2010/08/scratch-buffers-for-emacs/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 03:44:55 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=748</guid>
		<description><![CDATA[I often find myself needing to quickly work on some code that’s mostly unrelated to my task at hand. This comes up often when pair programming and code reviews, where you might want to illustrate a tactic without adding useless code to your current buffer. Ordinarily, you’d use *scratch*, but it’s useful to have your [...]]]></description>
			<content:encoded><![CDATA[<p>I often find myself needing to quickly work on some code that’s mostly unrelated to my task at hand. This comes up often when pair programming and code reviews, where you might want to illustrate a tactic without adding useless code to your current buffer.</p>
<p>Ordinarily, you’d use <code>*scratch*</code>, but it’s useful to have your scratch buffer use mode for the language you want to write code in, and <code>*scratch*</code> doesn’t fulfill this unless you’re hacking on emacs-lisp.</p>
<p>To this end, I created <a href="http://github.com/ieure/scratch-el">scratch-el</a>, a bit of code for doing just this.</p>
<p>When you invoke it with <code>M-x scratch</code>, it gives you a scratch buffer with the same mode as your current buffer. So if you’re editing Python code, you get a <code>*python*</code> buffer which uses python-mode. If you’re in a shell, you get a shell-script-mode buffer, and so on.</p>
<p>If you invoke it with a prefix argument, as <code>C-u M-x scratch</code>, it will prompt you for the mode to use, which can be helpful if you want to noodle on a SQL query while editing your app code. There is tab completion support for all known major modes.</p>
<p>If you want to save the resulting work, it’s just a <code>C-x C-w</code> away.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/08/scratch-buffers-for-emacs/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Reading Apress PDF eBooks on an iPad</title>
		<link>http://atomized.org/2010/06/reading-apress-pdf-ebooks-on-an-ipad/</link>
		<comments>http://atomized.org/2010/06/reading-apress-pdf-ebooks-on-an-ipad/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 18:29:20 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[apress]]></category>
		<category><![CDATA[ebook]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[pdf]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=740</guid>
		<description><![CDATA[Say that you’ve recently purchased an Apress eBook in PDF form. Say that you’d like to read this book on your iPad or other mobile reading device. Say that it’s unlikely that your device will support the password protection which is applied to your eBook. Say that, despite this, you would prefer to read your [...]]]></description>
			<content:encoded><![CDATA[<p>Say that you’ve recently purchased an Apress eBook in PDF form. Say that you’d like to read this book on your iPad or other mobile reading device. Say that it’s unlikely that your device will support the password protection which is applied to your eBook. Say that, despite this, you would prefer to read your eBook however you damn well please.</p>
<ol>
<li>Own a Mac. If you do not currently own a Mac, go purchase one. I’ll wait.</li>
<li>Open the PDF in Preview.</li>
<li>Enter the password when prompted. (<a href="http://twitter.com/ieure/status/17431341971">Which, inexplicably, is your email address</a>.)</li>
<li>File→Save As</li>
<li><code>YOU_SUCK_APRESS.pdf</code></li>
<li>Rejoice in the knowledge that you can read your book however you please, despite the fact that it would have been easier to steal than purchase. Also, if you didn’t previously own a Mac, they’re pretty great, too.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/06/reading-apress-pdf-ebooks-on-an-ipad/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Resolving Merge Conflicts the Easy Way with SMerge &amp; KMacro</title>
		<link>http://atomized.org/2010/06/resolving-merge-conflicts-the-easy-way-with-smerge-kmacro/</link>
		<comments>http://atomized.org/2010/06/resolving-merge-conflicts-the-easy-way-with-smerge-kmacro/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 17:58:48 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[conflicts]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[merging]]></category>
		<category><![CDATA[resolve]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=732</guid>
		<description><![CDATA[If you&#8217;ve ever had to deal with merge conflicts, you know it&#8217;s not much fun. Fortunately, Emacs can help. Piece of Cake The first component we&#8217;re going to work with is smerge. SMerge is invaluable; it&#8217;s a minor mode which allows you to quickly navigate between conflicts and choose which you&#8217;d like to keep. Normally, [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve ever had to deal with merge conflicts, you know it&#8217;s not much fun. Fortunately, Emacs can help.</p>
<h2>Piece of Cake</h2>
<p>The first component we&#8217;re going to work with is <em>smerge</em>. SMerge is invaluable; it&#8217;s a minor mode which allows you to quickly navigate between conflicts and choose which you&#8217;d like to keep. Normally, you must invoke it explicitly with <code>M-x smerge-mode</code>, but there’s an easier way.</p>
<pre>
(defun sm-try-smerge ()
  (save-excursion
    (goto-char (point-min))
    (when (re-search-forward "^<<<<<<< " nil t)
      (smerge-mode 1))))

(add-hook 'find-file-hook 'sm-try-smerge t)
</pre>
<p>Throw this in your <code>.emacs</code>, and smerge-mode will be enabled for files which contain conflict markers. If you’re a Git user (and you should be), the markers will have the branch names they came from tacked on the end. The minor mode will disable itself when there are no more conflicts left in the buffer.</p>
<p>All SMerge’s bindings start with a shared prefix, which is <code>C-c ^</code> by default. This is somewhat cumbersome, but you can change it in customize (<code>M-x customize-variable RET smerge-command-prefix RET</code>). The bindings you’ll want to be familiar with are:</p>
<ul>
<li><code>C-c ^ n</code> – Move to the next conflict.</li>
<li><code>C-c ^ p</code> – Move to the previous conflict.</li>
<li><code>C-c ^ RET</code> – Keep the version of the code point resides in.</li>
<li><code>C-c ^ m</code> – Keep <em>my</em> version of the code. This is the version that was in the branch you merged <em>to</em>.</li>
<li><code>C-c ^ o</code> – Keep the <em>other</em> version of the code. This is the version that was in the branch you merged <em>from</em>.</li>
<li><code>C-c ^ a</code> – Keep <em>all</em> versions of the code. You’ll probably need to edit it to completely resolve the conflict.</li>
</ul>
<h2>Another Slice</h2>
<p>Let’s say that you have a file where you want to resolve each conflict the same way. You either want to keep the changes from the branch you merged, or the changes you've made in your branch. SMerge helps a lot with this, but there’s not reason to kill your fingers when you have KMacro. Let’s assume that you want changes in the branch you merged to take precedence.</p>
<ol>
<li><code>C-x (</code> – Start recording a keyboard macro.</li>
<li><code>C-x ^ n</code> – Move to the next conflict.</li>
<li><code>C-x ^ o</code> – Resolve the conflict by choosing the other version.</li>
<li><code>C-x )</code> – Stop recording the macro.</li>
</ol>
<p>Now, you can apply this macro as many times as you like with:</p>
<ol>
<li><code>M-x kmacro-call-macro RET</code> – Run the macro.</li>
<li><code>RET</code> – Run the macro again; repeat until all conflicts are resolved.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/06/resolving-merge-conflicts-the-easy-way-with-smerge-kmacro/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

