<?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; emacs</title>
	<atom:link href="http://atomized.org/tag/emacs/feed/" rel="self" type="application/rss+xml" />
	<link>http://atomized.org</link>
	<description>Fragmenting reality.</description>
	<lastBuildDate>Tue, 31 Aug 2010 18:00:43 +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>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>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>
		<item>
		<title>Emacs builds on hiatus</title>
		<link>http://atomized.org/2010/05/emacs-builds-on-hiatus/</link>
		<comments>http://atomized.org/2010/05/emacs-builds-on-hiatus/#comments</comments>
		<pubDate>Tue, 04 May 2010 17:30:50 +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=719</guid>
		<description><![CDATA[My nightly Cocoa Emacs builds are going on a brief hiatus while I reshuffle things. They should be back soon, hosted on Amazon S3 like the official 23.1 release.]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://atomized.org/wp-content/cocoa-emacs-nightly/">nightly Cocoa Emacs</a> builds are going on a brief hiatus while I reshuffle things.</p>
<p>They should be back soon, hosted on Amazon S3 like the official 23.1 release.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/05/emacs-builds-on-hiatus/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>pep8 &amp; pylint in Emacs</title>
		<link>http://atomized.org/2010/02/pep8-pylint-in-emacs/</link>
		<comments>http://atomized.org/2010/02/pep8-pylint-in-emacs/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 19:02:00 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=685</guid>
		<description><![CDATA[I do a lot of hacking on Python these days, and of course, I use Emacs. The built-in python-mode has the ability to run pychecker on your source, but doesn&#8217;t integrate other tools. I like to run pep8.py &#038; pylint regularly to keep my code clean, so I hacked together compilation-derived modes to drive them. [...]]]></description>
			<content:encoded><![CDATA[<p>I do a lot of hacking on Python these days, and of course, I use Emacs. The built-in python-mode has the ability to run pychecker on your source, but doesn&#8217;t integrate other tools. I like to run pep8.py &#038; pylint regularly to keep my code clean, so I hacked together compilation-derived modes to drive them.</p>
<p>Compile.el is really great for this kind of thing, since it lets you quickly navigate over the lines mentioned in the program&#8217;s output. It&#8217;s quite efficient, and I enjoy it immensely. One note of interest: pep8.py doesn&#8217;t output line numbers in order, which confuses compile-mode. I just pipe the output through sort to work around this.</p>
<p>The code is on GitHub: <a href="http://gist.github.com/302847">python-pep8.el</a> and <a href="http://gist.github.com/302848">python-pylint.el</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2010/02/pep8-pylint-in-emacs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Minor OS X Emacs Tip</title>
		<link>http://atomized.org/2009/09/minor-os-x-emacs-tip/</link>
		<comments>http://atomized.org/2009/09/minor-os-x-emacs-tip/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 22:28:01 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[hide]]></category>
		<category><![CDATA[os x]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=601</guid>
		<description><![CDATA[I like to use M-h in Emacs to mark paragraphs. I also like to use the Command key as Meta. Further, I like to use ⌘H to hide applications in OS X. If you hit M-h in Emacs, it runs mark-paragraph, which is good, but means that you can’t hide Emacs. However, if you hit [...]]]></description>
			<content:encoded><![CDATA[<p>I like to use <code>M-h</code> in Emacs to mark paragraphs. I also like to use the Command key as Meta. Further, I like to use <code>⌘H</code> to hide applications in OS X.</p>
<p>If you hit <code>M-h</code> in Emacs, it runs <code>mark-paragraph</code>, which is good, but means that you can’t hide Emacs. However, if you hit <code>⌘tab</code> to trigger the app switcher, then select Emacs, <em>then</em> hit <code>⌘H</code>, it will hide instead.</p>
<p>Alternately, you could bind <code>ns-do-hide-emacs</code> to some other key combination.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2009/09/minor-os-x-emacs-tip/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Cocoa Emacs 23.1, CVS Builds, and the NextStep port</title>
		<link>http://atomized.org/2009/08/cocoa-emacs-231-cvs-builds-and-the-nextstep-port/</link>
		<comments>http://atomized.org/2009/08/cocoa-emacs-231-cvs-builds-and-the-nextstep-port/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 18:19:29 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[23.1]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[cvs]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[gnustep]]></category>
		<category><![CDATA[nextstep]]></category>
		<category><![CDATA[ns]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=579</guid>
		<description><![CDATA[I’ve been providing nightly builds of Emacs CVS HEAD for Mac OS X for a few months now. I’m going to keep building them, since the NS port is in bad shape and CVS should surpass 23.1 soon. Moving forward, I hope to transition the nightlies to S3 and build them from Git instead of [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been providing <a href="http://atomized.org/wp-content/cocoa-emacs-nightly/">nightly builds</a> of Emacs CVS HEAD for Mac OS X for a few months now. I’m going to keep building them, since the NS port is in bad shape and CVS should surpass 23.1 soon.</p>
<p>Moving forward, I hope to transition the nightlies to S3 and build them from Git instead of CVS.</p>
<h2>Cocoa Emacs 23.1</h2>
<p>For people who prefer the stable release, I built <a href="https://cocoa-emacs.s3.amazonaws.com/Cocoa%20Emacs%2023.1.dmg">Cocoa Emacs 23.1</a>. This is a vanilla build of the official release.</p>
<h2>What’s wrong with the NS port?</h2>
<p>Lots. It’s significantly slower, less stable, and lacks features which were in the 22.x Carbon port, like fullscreen. It’s really not ready for prime time, and it sucks that people will get such a bad experience on OS X. What sucks even more is that new users will get a bad first impression. This could have been a chance to turn people on to Emacs and GNU software, but it’s more likely to alienate them instead.</p>
<p>The Carbon port was discontinued in the hopes that a single NextStep port could work on OS X and GNUStep. Unfortunately, relatively few people cared to work on it, and the result is that the stable Carbon port is dead and it’s replacement just isn’t as good. I also hear that the GNUstep builds are completely broken, though I haven’t personally verified such.</p>
<p>The politics of GNU bear some of the blame, too. Non-free platforms like Macintosh are second class citizens in their eyes, and there is very little desire to improve the experience of GNU software on them. The idea being that if they want things to work well, they should use GNU/Linux instead.</p>
<p>This is backwards, painfully stupid and wrong. If a user tries some of your software and it sucks, they’re going to stop using <em>all</em> of your software. Nobody is going to use crap software and think it’s a great idea to switch to a whole platform of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2009/08/cocoa-emacs-231-cvs-builds-and-the-nextstep-port/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Abbrevs in the REPL</title>
		<link>http://atomized.org/2009/06/abbrevs-in-the-repl/</link>
		<comments>http://atomized.org/2009/06/abbrevs-in-the-repl/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 18:01:39 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[abbrev]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=571</guid>
		<description><![CDATA[I love abbrevs, and I use them all the time. While I prefer yasnippet for more complex things, abbrevs are great. I use them for simple (1-5 word) expansions, and they’re particularly helpful with SQL mode. One of my gripes is that when I define abbrevs for a programming mode like python-mode, the abbrevs don’t [...]]]></description>
			<content:encoded><![CDATA[<p>I love <a href="http://www.emacswiki.org/emacs/AbbrevMode">abbrevs</a>, and I use them all the time. While I prefer <a href="http://code.google.com/p/yasnippet/">yasnippet</a> for more complex things, abbrevs are great. I use them for simple (1-5 word) expansions, and they’re particularly helpful with SQL mode.</p>
<p>One of my gripes is that when I define abbrevs for a programming mode like <code>python-mode</code>, the abbrevs don’t get used when I use the REPL via <code>run-python</code>.</p>
<p>This is pretty straightforward to fix:</p>
<pre language="emacs-lisp">
(eval-after-load 'python
  '(progn
     (derived-mode-merge-abbrev-tables python-mode-abbrev-table
                                       inferior-python-mode-abbrev-table)))
</pre>
<p>This tells Emacs to merge the python-mode abbrevs into the inferior-python-mode abbrev table. Now, when I fire up Python in Emacs, I have all my usual abbrevs. This may be inadvisable if you’re using abbrev to hook into auto-insert or to trigger behavior which expects a non-interactive environment, but it’s perfect when you just want to type &#8220;imp&#8221; instead of &#8220;import.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2009/06/abbrevs-in-the-repl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Brief updates on Elisp projects</title>
		<link>http://atomized.org/2009/06/brief-updates-on-elisp-projects/</link>
		<comments>http://atomized.org/2009/06/brief-updates-on-elisp-projects/#comments</comments>
		<pubDate>Mon, 08 Jun 2009 23:25:05 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=569</guid>
		<description><![CDATA[I’m behind on my twit.el fork. Some of my changes got rolled in to mainline, but many didn’t, and this led to a merge nightmare. I’m wiping out what I did and starting over. I also need to figure out if there’s a way to line wrap variable-width fonts, since auto-fill doesn’t seem to work [...]]]></description>
			<content:encoded><![CDATA[<p>I’m behind on <a href="https://github.com/ieure/twit-el/tree">my twit.el fork</a>. Some of my changes got rolled in to mainline, but many didn’t, and this led to a merge nightmare. I’m wiping out what I did and starting over. I also need to figure out if there’s a way to line wrap variable-width fonts, since auto-fill doesn’t seem to work quite right.</p>
<p>I <a href="https://github.com/ieure/php-mode-el/tree">forked</a> <a href="http://php-mode.sourceforge.net/">php-mode</a>. I don’t have anything major planned, but I fixed the fontification of docblock comments.</p>
<p>I <a href="http://github.com/ieure/test-case-mode/blob/cacba6a3d524c75baa6315fce5df87a8496d12dd/test-case-phpunit.el">added</a> <a href="http://phpunit.de/">PHPUnit</a> support to <a href="http://github.com/ieure/test-case-mode/tree/master">test-case-mode</a>. Consider <a href="https://github.com/ieure/phpunit-el/tree">phpunit-el</a> deprecated.</p>
<p>There are a couple things missing vs. phpunit-el, some of which may need some changes to test-case-mode.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2009/06/brief-updates-on-elisp-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Emacs Nerdery: Search &amp; replace across files</title>
		<link>http://atomized.org/2009/05/emacs-nerdery-search-replace-across-files/</link>
		<comments>http://atomized.org/2009/05/emacs-nerdery-search-replace-across-files/#comments</comments>
		<pubDate>Thu, 07 May 2009 18:12:21 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[dired]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[grep]]></category>
		<category><![CDATA[query-replace]]></category>

		<guid isPermaLink="false">http://atomized.org/?p=560</guid>
		<description><![CDATA[Whenever I encounter a problem that’s painful to solve, I consider finding a better way to do it. This involves weighing how long I think it might take to find (or create) a better solution versus the amount of time it would take to suck it up and do it the hard way. Where this [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever I encounter a problem that’s painful to solve, I consider finding a better way to do it. This involves weighing how long I think it might take to find (or create) a better solution versus the amount of time it would take to suck it up and do it the hard way. Where this fails is with painful processes encountered infrequently; since they don’t happen often, it’s less worthwhile to invest the time to improve it.</p>
<p>Multi-file search and replace is a perfect example of this kind of infrequently painful process. After messing around with for loops and sed in the shell, I finally sucked it up and got familiar with the Emacs way of doing it. It’s a great example of the synergy of Emacs tools, since it combines familiar features in a new way.</p>
<h3>Search and replace in a single file</h3>
<p>The facility for one-file S&amp;R is called <em>query-replace</em>, and it’s bound to <code>M-%</code> (plain strings) and <code>C-M-%</code> (regexes) by default. As you’d expect, it prompts for search and replacement text, then replaces it in your buffer. When using regular expressions, you have the full power of them, with the ability to capture sub-expressions and use them in your replacement.</p>
<h3>Directory editing</h3>
<p>Dired is the Emacs file management package, and it’s quite powerful. You can invoke it with <code>C-x d</code>, or by pointing <code>find-file</code> (<code>C-x C-f</code>) at a directory.</p>
<p>Dired lets you mark files with <code>m</code>, or files matching a regular expression with <code>% m</code>. Pressing <code>Q</code> runs <code>query-replace</code> over the contents of those files.</p>
<p>Dired only shows files in one directory, so this doesn’t work if you want to replace in files which span directories.</p>
<h3>Find with dired</h3>
<p>This can be mostly solved with <code>find-dired</code>. As the name implies, it runs <code>find</code>, putting the results in a dired buffer. Once you have that, you can use <code>Q</code> to S&amp;R in the matched files.</p>
<p>This is good if you need to replace a string in every file under a subdirectory, or in every file whose name matches a pattern. Where it fails is when you need to replace a string in files which contain that string.</p>
<h3>Grep</h3>
<p>Emacs has excellent integration with grep, in several flavors:</p>
<ul>
<li><code>grep</code>. Basic grepping, with results placed in <code>*grep*</code>. The buffer shows filenames, line numbers, and the content from the file which matched.</li>
<li><code>rgrep</code>. My favorite, <code>rgrep</code> performs a recursive grep and filters out unwanted files, such as backups, stuff in <code>.svn</code>, etc.</li>
<li><code>lgrep</code>. Just like <code>rgrep</code>, but not recursive.</li>
<li><code>find-grep</code>. Getting close to what we want, <code>find-grep</code> runs grep on files located with <code>find</code>. And finally…</li>
<li><code>find-grep-dired</code>. Just like <code>find-grep</code>, but puts the results in a dired buffer instead.</li>
</ul>
<p>As you’ve no doubt figured out, we’ll be using <code>find-grep-dired</code> for this task.</p>
<h2>Putting it together</h2>
<p>Now we have all the pieces, let’s put them together. As an example, let’s say that we renamed an exception and need to change the <code>catch</code> blocks in every <code>.php</code> file in package.</p>
<p>We start by running <code>find-grep-dired</code>:</p>
<pre>M-x find-grep-dired RET catch (FooException RET</pre>
<p>This gives us a buffer of files containing <code>catch (FooException</code>. It includes stuff in <code>.svn</code>; we only want <code>.php</code> files, so we can mark those:</p>
<pre>% m .php$ RET</pre>
<p>Now that they’re marked, run <code>query-replace</code> on them:</p>
<pre>Q catch (FooException RET catch (BarException RET</pre>
<p>At this point, Emacs will cycle through every match in every file and ask you to confirm the replacement. If you press <code>!</code>, it will replace the rest of the matches in the current file, and start prompting you for the next; <code>Y</code> will replace every match in every file with no further prompting. Then you’ll need to save the files:</p>
<pre>C-x s</pre>
<p>This saves every modified file at once, and we’re done.</p>
]]></content:encoded>
			<wfw:commentRss>http://atomized.org/2009/05/emacs-nerdery-search-replace-across-files/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
