<?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>Here comes the Sun &#187; 装备</title>
	<atom:link href="http://sunng.info/blog/category/%e8%a3%85%e5%a4%87/feed/" rel="self" type="application/rss+xml" />
	<link>http://sunng.info/blog</link>
	<description>47% users on this site use *nix</description>
	<lastBuildDate>Sat, 04 Feb 2012 13:08:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>OpenStreetMap Nanjing: A Year of Edits</title>
		<link>http://sunng.info/blog/2012/01/openstreetmap-nanjing-a-year-of-edits/</link>
		<comments>http://sunng.info/blog/2012/01/openstreetmap-nanjing-a-year-of-edits/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 13:20:51 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[OpenStreetMap]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1142</guid>
		<description><![CDATA[这是2011年OpenStreetMap上，南京的编辑情况。高亮的部分是2011年创建或更新的要素。从这张图上可以看出最近的这一年，南京的数据从无到有到逐渐的完善，这里面倾注了本地几位贡献者结结实实的心血。 对这个可视化感兴趣，可以参考这里的代码和样式表。]]></description>
			<content:encoded><![CDATA[<p><img src="http://i.imgur.com/0mVFk.png" alt="osm nanjing" /></p>
<p>这是2011年OpenStreetMap上，南京的编辑情况。高亮的部分是2011年创建或更新的要素。从这张图上可以看出最近的这一年，南京的数据从无到有到逐渐的完善，这里面倾注了本地几位贡献者结结实实的心血。</p>
<p>对这个可视化感兴趣，可以参考<a href="https://gist.github.com/1639915" target="_blank">这里的代码和样式表</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/01/openstreetmap-nanjing-a-year-of-edits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clojure on CloudFoundry</title>
		<link>http://sunng.info/blog/2012/01/clojure-on-cloudfoundry/</link>
		<comments>http://sunng.info/blog/2012/01/clojure-on-cloudfoundry/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 13:31:55 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[cloudfoundry]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1139</guid>
		<description><![CDATA[In this article, I will show you how to develop and deploy clojure web application on CloudFoundry. As you may know, CloudFoundry is an opensource PaaS backed by VMWare. Java, Ruby and Nodejs are officially supported. As a JVM language, &#8230; <a href="http://sunng.info/blog/2012/01/clojure-on-cloudfoundry/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this article, I will show you how to develop and deploy clojure web application on CloudFoundry. As you may know, CloudFoundry is an opensource PaaS backed by VMWare. Java, Ruby and Nodejs are officially supported. As a JVM language, clojure is born to be also available on this platform, although it&#8217;s not listed. </p>
<p>CloudFoundry accepts a .war file for Java web application deployment. So you don&#8217;t need the ring-jetty-adaptor and a procfile as heroku requires. To help your development and deployment, I strongly recommend the lein-ring plugin:</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; :<span style="color: #555;">dev</span><span style="color: #66cc66;">-</span>dependencies <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>lein<span style="color: #66cc66;">-</span>ring <span style="color: #ff0000;">&quot;0.5.4&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span></div></div>
<p>CloudFoundry provides backend services like mysql, redis, mongodb and more. The connection information are stored as environment variables. <a href="http://env.cloudfoundry.com/env" target="_blank">Here</a> you can find a subset of them. </p>
<p>Take mongodb as example, connection information (host, port, username and password) are encoded as JSON, stored in environment variables. You can get them with this function:</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defn</span> mongo<span style="color: #66cc66;">-</span>config <span style="color: #66cc66;">&#91;</span>key<span style="color: #66cc66;">&#93;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if-let</span> <span style="color: #66cc66;">&#91;</span>services <span style="color: #66cc66;">&#40;</span>System<span style="color: #66cc66;">/</span>getenv <span style="color: #ff0000;">&quot;VCAP_SERVICES&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>services<span style="color: #66cc66;">-</span>dict <span style="color: #66cc66;">&#40;</span>json<span style="color: #66cc66;">/</span>read<span style="color: #66cc66;">-</span>json services false<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">-&gt;</span> services<span style="color: #66cc66;">-</span>dict<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>get <span style="color: #ff0000;">&quot;mongodb-1.8&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">first</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>get <span style="color: #ff0000;">&quot;credentials&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>get key<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>In the server bootstrap function, create the mongodb connection:</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defn</span> app<span style="color: #66cc66;">-</span>init <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">def</span> db<span style="color: #66cc66;">-</span>conn <span style="color: #66cc66;">&#40;</span>make<span style="color: #66cc66;">-</span>connection<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span>mongo<span style="color: #66cc66;">-</span>config <span style="color: #ff0000;">&quot;db&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;lazypress&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:<span style="color: #555;">host</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span>mongo<span style="color: #66cc66;">-</span>config <span style="color: #ff0000;">&quot;hostname&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;localhost&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:<span style="color: #555;">port</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span>mongo<span style="color: #66cc66;">-</span>config <span style="color: #ff0000;">&quot;port&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">27017</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when-not</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">nil?</span> <span style="color: #66cc66;">&#40;</span>mongo<span style="color: #66cc66;">-</span>config <span style="color: #ff0000;">&quot;username&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>authenticate db<span style="color: #66cc66;">-</span>conn<br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>mongo<span style="color: #66cc66;">-</span>config <span style="color: #ff0000;">&quot;username&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>mongo<span style="color: #66cc66;">-</span>config <span style="color: #ff0000;">&quot;password&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>By adding check for nil, local databased is also supported. This is pretty convenience for local development. These environment variables are consistent on all cloudfoundry application, so it&#8217;s possible to deploy the application on multiple accounts without any changes.</p>
<p>Then you can add your web stuff just like standard clojure web development. (If you are using compojure, place your static files under resource/public.)</p>
<p>Finally, package it. (Suppose your application is named as &#8220;lazypress&#8221;)</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">lein ring uberwar lazypress.war</div></div>
<p>Use the vmc tool to deploy it:</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">vmc update lazypress</div></div>
<p>For more usage about the vmc tool, you can read <a href="http://blog.cloudfoundry.com/post/13481010498/simplified-application-deployment-with-cloud-foundry-manifest" target="_blank">this article</a>.</p>
<p>So you have finished deploying your clojure web application to cloudfoundry.</p>
<p>Backed by spring and vmware, cloudfoundry is more Java-friendly than other PaaS like heroku. You don&#8217;t have to start a Java process by yourself (&#8220;lein run&#8221; isn&#8217;t a graceful way to start your app in product environment). And you don&#8217;t have to worry about your web container settings (configure jetty with limited options via ring-jetty-adaptor). All you have to do is package the application as a portable war file, which you can deploy to tomcat, glassfish, and also cloudfoundry. The vmc tool could detect you war file and handle it correctly.</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/01/clojure-on-cloudfoundry/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Roar for mootools 1.4</title>
		<link>http://sunng.info/blog/2011/12/roar-for-mootools-1-4/</link>
		<comments>http://sunng.info/blog/2011/12/roar-for-mootools-1-4/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 15:16:31 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1123</guid>
		<description><![CDATA[早在天下大势还处在分久必合的时候，那时候mootools还有不少简单实用的小库，比如我今天搜索&#8221;mootools notification&#8221;就找到这个08年的库叫做Roar。不过遗憾的是从那以后，这个库就再也没有更新过了。 Mootools本身也沉寂了很久，这个项目恐怕也要思考自己未来的发展方向了。今年9月Mootools迈进了1.4，API上有一些变化。现在的下载页也能看到with/without backward compatibility的版本分开下载。为了用上Roar，我尝试了这两个版本发现都不能使用。最后downgrade到1.2可以确定Roar本身在当时是没有什么问题。 这么多年对mootools痴心不改，所以顺手维护了一下Roar，现在可以在1.4 without compatibility的发布下运行了。主要是几个小修改，大多是一些多年deprecated函数被正式删除： Type常量，原先的String.type，Object.type现在统一到一个Type对象下，变成Type.isString和Type.isObject $empty 常量被删除了，现在直接用function()或Function.from()代替 $pick 方法被Array.pick取代，参数现在也必须接受数组类型了 $merge 方法被Object.merge取代 $type 被typeOf取代 函数对象的create方法被删除了，现在可以用函数对象的bind方法替代 Browser.Engine 被删除了，需要用其他Browser的API替代 修改后的Roar，放在这个gist里，测试过可以在firefox和chromium上健康使用。IE没有做测试。这个08年的库，眼看四年过去了，用起来依然不错。 作为mootools的铁杆，我还是会一直专一地坚守下去的。（于是，我也已经变成了多年前那些我眼中为旧事物顽抗到底的老家伙了）]]></description>
			<content:encoded><![CDATA[<p>早在天下大势还处在分久必合的时候，那时候mootools还有不少简单实用的小库，比如我今天搜索&#8221;mootools notification&#8221;就找到这个08年的库叫做<a href="http://digitarald.de/project/roar/" target="_blank">Roar</a>。不过遗憾的是从那以后，这个库就再也没有更新过了。</p>
<p>Mootools本身也沉寂了很久，这个项目恐怕也要思考自己未来的发展方向了。今年9月Mootools迈进了1.4，API上有一些变化。现在的下载页也能看到with/without backward compatibility的版本分开下载。为了用上Roar，我尝试了这两个版本发现都不能使用。最后downgrade到1.2可以确定Roar本身在当时是没有什么问题。</p>
<p>这么多年对mootools痴心不改，所以顺手维护了一下Roar，现在可以在1.4 without compatibility的发布下运行了。主要是几个小修改，大多是一些多年deprecated函数被正式删除：</p>
<ul>
<li>Type常量，原先的String.type，Object.type现在统一到一个Type对象下，变成Type.isString和Type.isObject</li>
<li>$empty 常量被删除了，现在直接用function()或Function.from()代替</li>
<li>$pick 方法被Array.pick取代，参数现在也必须接受数组类型了</li>
<li>$merge 方法被Object.merge取代</li>
<li>$type 被typeOf取代</li>
<li>函数对象的create方法被删除了，现在可以用函数对象的bind方法替代</li>
<li>Browser.Engine 被删除了，需要用其他Browser的API替代</li>
</ul>
<p>修改后的Roar，放在<a href="https://gist.github.com/1516568" target="_blank">这个gist</a>里，测试过可以在firefox和chromium上健康使用。IE没有做测试。这个08年的库，眼看四年过去了，用起来依然不错。</p>
<p>作为mootools的铁杆，我还是会一直专一地坚守下去的。（于是，我也已经变成了多年前那些我眼中为旧事物顽抗到底的老家伙了）</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2011/12/roar-for-mootools-1-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TF101 101</title>
		<link>http://sunng.info/blog/2011/12/tf101-101/</link>
		<comments>http://sunng.info/blog/2011/12/tf101-101/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 15:38:35 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[pad]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1118</guid>
		<description><![CDATA[上周末决定不再忍耐，又入了一个大件：华硕的平板，变形金刚。TF101上市已经半年了，而且现在TF102号称四核的版本已经开始接受预订了，所以差不多也到了应该出手的时候了。因为我知道如果去等102的话，我还会像现在这样地去和103做比较。 选择这款的主要原因即他的键盘配置，平板加键盘的组合彻底把上网本推进深渊。对于我这种还算是制造内容比率比较高的人来说，有个强有力的输入设备是必要的。目前市面上有这种搭配的只有transformer和think的，而且think似乎又只有配图和说明，没见真正卖那款键盘的。更严重的是，当然，think太贵了。 接下来开始说问题： 第一关叫做充电。TF101在充电方面有严重的缺陷。当电池电量极低时，会出现无法充电的情况。明明接着电源，可是电量提示一直是0%。如此情况下我整整充了一天拔下电源依然无法开机。最后看了网上的说法，在充电自动开机后关机了半个小时终于起死回生。 第二个小问题，键盘底座的平板本身电源是分离的，二者各自充电。所以在前面〝整整充了一天〞之前还有整整充了一晚上键盘。早晨起来键盘电满了，平板没充进去。 系统出厂是Android 3.0，这个系统的伟大之处在于从他一启动开始，就开始不断有程序报出错退出，不断有应用停止响应。他简直都对不起这个版本号。直到后来充上电升级到3.2之后才可以用。但是，还是有浏览器突然僵死然后突然从眼前消失的场面。再有就是机捆绑的什么人人网，电子书，开心网什么的，让你想不root都不行。 再有andrid 3.x上应用可能本来就不多，随机捆的又是一个流氓市场，除了满眼的流氓软件和山寨以外，就是版已经过时的软件。可怜这挺好一机器都不知道该装点什么。要说TF101硬件已经很可以了，只是配上这么个系统，用范伟的话说，白瞎你这个人了。手放键盘上，真恨不得能打开个终端来挡住这个浅薄的外观。等有时间我一定要尝试在这台机器上装个正经系统。也算是对得起这硬件了。 一句话概括一下的话，硬件还好，软件拉倒。]]></description>
			<content:encoded><![CDATA[<p>上周末决定不再忍耐，又入了一个大件：华硕的平板，变形金刚。TF101上市已经半年了，而且现在TF102号称四核的版本已经开始接受预订了，所以差不多也到了应该出手的时候了。因为我知道如果去等102的话，我还会像现在这样地去和103做比较。</p>
<p>选择这款的主要原因即他的键盘配置，平板加键盘的组合彻底把上网本推进深渊。对于我这种还算是制造内容比率比较高的人来说，有个强有力的输入设备是必要的。目前市面上有这种搭配的只有transformer和think的，而且think似乎又只有配图和说明，没见真正卖那款键盘的。更严重的是，当然，think太贵了。</p>
<p>接下来开始说问题：<br />
第一关叫做充电。TF101在充电方面有严重的缺陷。当电池电量极低时，会出现无法充电的情况。明明接着电源，可是电量提示一直是0%。如此情况下我整整充了一天拔下电源依然无法开机。最后看了网上的说法，在充电自动开机后关机了半个小时终于起死回生。</p>
<p>第二个小问题，键盘底座的平板本身电源是分离的，二者各自充电。所以在前面〝整整充了一天〞之前还有整整充了一晚上键盘。早晨起来键盘电满了，平板没充进去。</p>
<p>系统出厂是Android 3.0，这个系统的伟大之处在于从他一启动开始，就开始不断有程序报出错退出，不断有应用停止响应。他简直都对不起这个版本号。直到后来充上电升级到3.2之后才可以用。但是，还是有浏览器突然僵死然后突然从眼前消失的场面。再有就是机捆绑的什么人人网，电子书，开心网什么的，让你想不root都不行。</p>
<p>再有andrid 3.x上应用可能本来就不多，随机捆的又是一个流氓市场，除了满眼的流氓软件和山寨以外，就是版已经过时的软件。可怜这挺好一机器都不知道该装点什么。要说TF101硬件已经很可以了，只是配上这么个系统，用范伟的话说，白瞎你这个人了。手放键盘上，真恨不得能打开个终端来挡住这个浅薄的外观。等有时间我一定要尝试在这台机器上装个正经系统。也算是对得起这硬件了。</p>
<p>一句话概括一下的话，硬件还好，软件拉倒。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2011/12/tf101-101/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Extend slacker server with interceptors</title>
		<link>http://sunng.info/blog/2011/12/extend-slacker-server-with-interceptors/</link>
		<comments>http://sunng.info/blog/2011/12/extend-slacker-server-with-interceptors/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 10:08:42 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[slacker]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1106</guid>
		<description><![CDATA[An interceptor framework was introduced in slacker 0.3.0. It&#8217;s designed to allow user to add custom functionality without hacking into the internal of slacker. Like many server frameworks, slacker abstracts the request processing as a pipeline. The request object is &#8230; <a href="http://sunng.info/blog/2011/12/extend-slacker-server-with-interceptors/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>An interceptor framework was introduced in slacker 0.3.0. It&#8217;s designed to allow user to add custom functionality without hacking into the internal of slacker.</p>
<p>Like many server frameworks, slacker abstracts the request processing as a pipeline. The request object is modified by adding or updating attributes through each node of the pipeline. So it&#8217;s easy to add your interceptor into the pipeline, with which you can get the data before and after function executed.</p>
<p>To create such an interceptor, you should use the <em>slacker.interceptor/definterceptor</em> macro and <em>slacker.interceptor/definterceptor+</em> macro:</p>
<blockquote><p>(definterceptor name<br />
  :before interceptor-function<br />
  :after interceptor-function)</p></blockquote>
<blockquote><p>(definterceptor+ name [arguments]<br />
  :before interceptor-function<br />
  :after interceptor-function)</p></blockquote>
<p>definterceptor+ can accept arguments so you can configure the interceptor when you use it.</p>
<p>See a simple example:</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>definterceptor log<span style="color: #66cc66;">-</span>function<span style="color: #66cc66;">-</span>call<br />
&nbsp; :<span style="color: #555;">before</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">fn</span> <span style="color: #66cc66;">&#91;</span>req<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>println <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">str</span> <span style="color: #ff0000;">&quot;calling &quot;</span> <span style="color: #66cc66;">&#40;</span>:<span style="color: #555;">fname</span> req<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> req<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #66cc66;">&#40;</span>definterceptor<span style="color: #66cc66;">+</span> log<span style="color: #66cc66;">-</span>function<span style="color: #66cc66;">-</span>call<span style="color: #66cc66;">-</span>prefixed <span style="color: #66cc66;">&#91;</span>prefix<span style="color: #66cc66;">&#93;</span><br />
&nbsp; :<span style="color: #555;">before</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">fn</span> <span style="color: #66cc66;">&#91;</span>req<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>println <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">str</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">fn</span>? prefix<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>prefix<span style="color: #66cc66;">&#41;</span> prefix<span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&quot; calling &quot;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>:<span style="color: #555;">fname</span> req<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Then, add it to your slacker server by</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>use '<span style="color: #66cc66;">&#91;</span>slacker<span style="color: #66cc66;">.</span>interceptor<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">import</span> '<span style="color: #66cc66;">&#91;</span>java<span style="color: #66cc66;">.</span>util Date<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>start<span style="color: #66cc66;">-</span>slacker <span style="color: #66cc66;">&#40;</span>the<span style="color: #66cc66;">-</span><span style="color: #b1b100;">ns</span> 'slapi<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">2104</span><br />
&nbsp; :<span style="color: #555;">interceptors</span> <span style="color: #66cc66;">&#40;</span>interceptors log<span style="color: #66cc66;">-</span>function<span style="color: #66cc66;">-</span>call<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>log<span style="color: #66cc66;">-</span>function<span style="color: #66cc66;">-</span>call<span style="color: #66cc66;">-</span>prefixed <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">fn</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">.</span>toString <span style="color: #66cc66;">&#40;</span>Date<span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Now you can log every function call of your slacker server.</p>
<p>For more detail about the interceptor framework, especially the request data, please check the <a href="https://github.com/sunng87/slacker/wiki/Interceptors" target="_blank">wiki page</a>.</p>
<p>In slacker 0.3.0, there is a built-in interceptor to stats function calls. You can find it at <em>slacker.interceptors.stats</em>. The stats data is expose via JMX. You can also write monitoring application to retrieve the data.<br />
<a href="http://imgur.com/vtOoL"><img src="http://i.imgur.com/vtOoL.png" alt="" title="Hosted by imgur.com" /></a></p>
<p>And there will be more built-in interceptors in 0.4.0, includes function call time stats and logging.</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2011/12/extend-slacker-server-with-interceptors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>从GNOME网站安装exaile-doubanfm-gnome-shell-extension</title>
		<link>http://sunng.info/blog/2011/12/%e4%bb%8egnome%e7%bd%91%e7%ab%99%e5%ae%89%e8%a3%85exaile-doubanfm-gnome-shell-extension/</link>
		<comments>http://sunng.info/blog/2011/12/%e4%bb%8egnome%e7%bd%91%e7%ab%99%e5%ae%89%e8%a3%85exaile-doubanfm-gnome-shell-extension/#comments</comments>
		<pubDate>Sat, 03 Dec 2011 06:06:59 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[project]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1088</guid>
		<description><![CDATA[最近GNOME发布了期待已久的extension.gnome.org，这个网站允许你直接通过浏览器安装和管理gnome-shell扩展，有点类似app store的感觉，混乱的~/.local/share/gnome-shell/extensions/终于有了一个官方的界面。 网站开通的第一时间，我提交了exaile-doubanfm-gnome-shell-extension，经过review和修改，这个扩展也得到了进一步的完善，适配了gnome-shell 3.2的风格。 你可以从这个地址直接安装启用 https://extensions.gnome.org/extension/24/exaile-doubanfm-control/ 它会在exaile douban.fm启动后显示一个菜单在gnome-shell上，你可以通过这个菜单进行基本的操作。 如果喜欢，别忘了在extension.gnome.org上vote一下 ：）]]></description>
			<content:encoded><![CDATA[<p>最近GNOME发布了期待已久的extension.gnome.org，这个网站允许你直接通过浏览器安装和管理gnome-shell扩展，有点类似app store的感觉，混乱的~/.local/share/gnome-shell/extensions/终于有了一个官方的界面。</p>
<p>网站开通的第一时间，我提交了exaile-doubanfm-gnome-shell-extension，经过review和修改，这个扩展也得到了进一步的完善，适配了gnome-shell 3.2的风格。</p>
<p>你可以从这个地址直接安装启用<br />
<a href="https://extensions.gnome.org/extension/24/exaile-doubanfm-control/" target="_blank">https://extensions.gnome.org/extension/24/exaile-doubanfm-control/</a></p>
<p>它会在exaile douban.fm启动后显示一个菜单在gnome-shell上，你可以通过这个菜单进行基本的操作。</p>
<p>如果喜欢，别忘了在extension.gnome.org上vote一下 ：）</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2011/12/%e4%bb%8egnome%e7%bd%91%e7%ab%99%e5%ae%89%e8%a3%85exaile-doubanfm-gnome-shell-extension/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Clojalk SCM Visualization</title>
		<link>http://sunng.info/blog/2011/10/clojalk-scm-visualization/</link>
		<comments>http://sunng.info/blog/2011/10/clojalk-scm-visualization/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 15:05:17 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[clojalk]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1053</guid>
		<description><![CDATA[最近有一个小工具非常流行（如果我没有火星的话），gource，可以将你的代码历史可视化出来。这里有reddit的代码历史，fogus也把写the joy of clojure做成了这样的视频。 凑个热闹，来看看我的clojalk项目可视化 And the video link on vimeo. 除了一名contributor，只有一个commiter。又是一幕Forever alone。 PS： gource上的wiki里，ffmpeg如果报错File for preset &#8216;slow&#8217; not found的话，去掉ffmpeg的-vpre slow就OK了。]]></description>
			<content:encoded><![CDATA[<p>最近有一个小工具非常流行（如果我没有火星的话），<a href="http://code.google.com/p/gource/" target="_blank">gource</a>，可以将你的代码历史可视化出来。<a href="http://www.youtube.com/watch?v=ELSsGXGHfZM" target="_blank">这里</a>有reddit的代码历史，fogus也把写the joy of clojure做成了<a href="http://blog.fogus.me/2011/10/27/joy-of-clojure-the-movie/" target="_blank">这样</a>的视频。</p>
<p>凑个热闹，来看看我的<a href="https://github.com/sunng87/clojalk">clojalk</a>项目可视化<br />
<embed src="http://player.youku.com/player.php/sid/XMzE3NzU4NjE2/v.swf" quality="high" width="480" height="400" align="middle" allowScriptAccess="sameDomain" allowFullscreen="true" type="application/x-shockwave-flash"></embed><br />
And the video link on <a href="http://vimeo.com/31328528" target="_blank">vimeo</a>.</p>
<p>除了一名contributor，只有一个commiter。又是一幕Forever alone。<br />
<img src="http://i.imgur.com/FXcNw.png" alt="forever alone" /></p>
<p>PS：<br />
gource上的wiki里，ffmpeg如果报错File for preset &#8216;slow&#8217; not found的话，去掉ffmpeg的-vpre slow就OK了。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2011/10/clojalk-scm-visualization/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Upgraded to GNOME 3.2</title>
		<link>http://sunng.info/blog/2011/10/upgraded-to-gnome-3-2/</link>
		<comments>http://sunng.info/blog/2011/10/upgraded-to-gnome-3-2/#comments</comments>
		<pubDate>Sun, 02 Oct 2011 10:14:27 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[archilinux]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1012</guid>
		<description><![CDATA[ArchLinux最大的魅力就在于Rolling Release，所有的悲喜剧你都比别人早一步见证。 升级到GNOME 3.2后，我的gnome-settings-daemon不能正常工作，导致gtk+的主题都无效。如果没有经验你可能不太容易注意到它的真实原因。最后找到了同病相怜的人，这个问题被报告在这里。恰好是在我发现这个问题几个小时之前。在gnome解决这个问题之前，有一个简单的workaround： sudo mv /usr/lib/gnome-settings-daemon-3.0/libcolor.so /usr/lib/gnome-settings-daemon-3.0/libcolor.so~ 库加载失败后gnome-settings-daemon会自动禁用这个插件，避免出现Segmentation fault。以上的操作，at your own risk。 此外，gnome-shell升级到3.2以后有些api的变化，我更新了exaile豆瓣电台的gnome-shell插件，你可以顺手git pull一下。]]></description>
			<content:encoded><![CDATA[<p>ArchLinux最大的魅力就在于Rolling Release，所有的悲喜剧你都比别人早一步见证。</p>
<p>升级到GNOME 3.2后，我的gnome-settings-daemon不能正常工作，导致gtk+的主题都无效。如果没有经验你可能不太容易注意到它的真实原因。最后找到了同病相怜的人，这个问题被报告在<a href="https://bugzilla.gnome.org/show_bug.cgi?id=660664" target="_blank">这里</a>。恰好是在我发现这个问题几个小时之前。在gnome解决这个问题之前，有一个简单的workaround：<br />
<em>sudo mv /usr/lib/gnome-settings-daemon-3.0/libcolor.so /usr/lib/gnome-settings-daemon-3.0/libcolor.so~</em></p>
<p>库加载失败后gnome-settings-daemon会自动禁用这个插件，避免出现Segmentation fault。以上的操作，at your own risk。</p>
<p>此外，gnome-shell升级到3.2以后有些api的变化，我更新了exaile豆瓣电台的gnome-shell插件，你可以顺手git pull一下。<br />
<a href="http://www.flickr.com/photos/40741608@N08/6203348334/" title="Screenshot at 2011-10-02 17:48:51 by 贝小塔, on Flickr"><img src="http://farm7.static.flickr.com/6162/6203348334_c71d757170.jpg" width="500" height="157" alt="Screenshot at 2011-10-02 17:48:51"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2011/10/upgraded-to-gnome-3-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Moving to ArchLinux</title>
		<link>http://sunng.info/blog/2011/10/moving-to-archlinux/</link>
		<comments>http://sunng.info/blog/2011/10/moving-to-archlinux/#comments</comments>
		<pubDate>Fri, 30 Sep 2011 16:19:40 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[ArchLinux]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1009</guid>
		<description><![CDATA[这是用新入的Nikon 55-300mm的长焦镜头300端排的远处的塔吊，它与本文没有直接关系。如果实在要计算间接关系，它是我等待fedora无尽的启动时间里消磨时光的手段之一。 这周开始fedora彻底崩溃了，现在在默认的run-level下NetworkManager根本无法启动，次次3分钟超时。还由于不明的原因，以越来越大的概率，gdm会僵死在启动启动之前。如果切换到terminal，输入完用户名居然连password都不会prompt出来。有时甚至在runlevel3里都无法启动。本想忍下去等到下个月f16发布，但是今天晚上已经彻底无法进入系统了，算了，其实也就是挥挥刀的事情。 Ubuntu的回头路是走不得的，索性切换到了Arch，从此享受rolling release，不再在每年的4月10月里蠢蠢欲动惊慌失措。重装的经验和上次一样：看准分区，/home留着/干掉；在创建用户的时候看准原先用户的uid，直接用这个id创建新用户，这样$HOME自动就归属新用户了。Arch仓库里的东西甚至要比fedora还多，没有那么多洁癖，甚至Skype和IDEA的社区版都直接进了仓库。我现在年纪大了，能从仓库安装我是不会自己再去下载了。 其实Arch也是老朋友了，直不过以前一直把它憋在VirtualBox里，现在它从VBox里爬出来了，Ubuntu和Windows这些当年的host们被踹进去乖乖作guest了，翻身农奴这就起来把歌唱。]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/40741608@N08/6198252182/" title="DSC_0004 by 贝小塔, on Flickr"><img src="http://farm7.static.flickr.com/6022/6198252182_656282b489.jpg" width="335" height="500" alt="DSC_0004"></a><br />
这是用新入的Nikon 55-300mm的长焦镜头300端排的远处的塔吊，它与本文没有直接关系。如果实在要计算间接关系，它是我等待fedora无尽的启动时间里消磨时光的手段之一。</p>
<p>这周开始fedora彻底崩溃了，现在在默认的run-level下NetworkManager根本无法启动，次次3分钟超时。还由于不明的原因，以越来越大的概率，gdm会僵死在启动启动之前。如果切换到terminal，输入完用户名居然连password都不会prompt出来。有时甚至在runlevel3里都无法启动。本想忍下去等到下个月f16发布，但是今天晚上已经彻底无法进入系统了，算了，其实也就是挥挥刀的事情。</p>
<p>Ubuntu的回头路是走不得的，索性切换到了Arch，从此享受rolling release，不再在每年的4月10月里蠢蠢欲动惊慌失措。重装的经验和上次一样：看准分区，/home留着/干掉；在创建用户的时候看准原先用户的uid，直接用这个id创建新用户，这样$HOME自动就归属新用户了。Arch仓库里的东西甚至要比fedora还多，没有那么多洁癖，甚至Skype和IDEA的社区版都直接进了仓库。我现在年纪大了，能从仓库安装我是不会自己再去下载了。</p>
<p>其实Arch也是老朋友了，直不过以前一直把它憋在VirtualBox里，现在它从VBox里爬出来了，Ubuntu和Windows这些当年的host们被踹进去乖乖作guest了，翻身农奴这就起来把歌唱。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2011/10/moving-to-archlinux/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Beginning Emacs for Clojure</title>
		<link>http://sunng.info/blog/2011/09/beginning-emacs-for-clojure/</link>
		<comments>http://sunng.info/blog/2011/09/beginning-emacs-for-clojure/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 13:29:34 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1003</guid>
		<description><![CDATA[没错我开始用Emacs了！对于一个使用lisp方言的开发的人来说，Emacs无疑是正统，是professional的象征。 其实用Emacs，远不需要太多的配置，就可以创建一个高效率的开发环境。我用了两天不到时间，当然还包括过去三年甚至更长时间里多次试图学习Emacs并最终半途而废残存的精力。 一步一步来，fedora系统的用户，比如这位，还有我，都会奇怪，命名有emacs，可是为什么没有GUI呢。因为系统自带的只是一个简单的版本，用yum安装一下emacs这个包才算是真正完整。 接下来要跳关了，大家注意。Emacs-starter-kit是一个帮助初学者预先配置emacs的一套默认配置文件，有了这个配置文件，也算是爬上了巨人的肩膀，省去了很多探路的时间。安装方式，把这个git仓库的master分支打包下载到~/.emacs.d/里即可（展开到这个目录）。启动emacs后，会自动安装。（作者名字很熟悉，对了，就是leiningen的作者） 由于package.el已经配置好了，接下来就可以安装一些必要的mode，两天的时间初探，我安装了： clojure-mode clojurescript-mode auto-complete color-theme-tangotango slime slime-repl 安装方式： M-x package-install 输入包名即可。 clojure-mode和clojurescript-mode是编辑clojure的mode，不多说。 配色 color-theme我本来是习惯用solarized，不过尝试了几次color-theme-solarized这个包应该是有一些问题。退而选择了tangotango。要默认选择这个颜色，在init.el里加： &#40;require 'color-theme-tangotango&#41; &#40;color-theme-tangotango&#41; 代码提示 auto-complete是代码提示和自动补全插件，安装完成后要简单配置一下才能使用： &#40;require 'auto-complete-config&#41; &#40;add-to-list 'ac-dictionary-directories &#34;~/.emacs.d/elpa/auto-complete-1.4.20110207/dict/&#34;&#41; &#40;ac-config-default&#41; 当然网上有更多的高级配置，可以搜一下。 REPL clojure的IDE必须要有repl的支持，在emacs中，repl通过slime这个mode来实现。此外还要额外安装swank： lein plugin install swank-clojure 1.3.2 在项目目录通过lein swank启动。在emacs中： M-x &#8230; <a href="http://sunng.info/blog/2011/09/beginning-emacs-for-clojure/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>没错我开始用Emacs了！对于一个使用lisp方言的开发的人来说，Emacs无疑是正统，是professional的象征。</p>
<p><a href="http://www.flickr.com/photos/40741608@N08/6162700542/" title="Screenshot--home-sun-projects-clojalk-src-clojalk-wal.clj by 贝小塔, on Flickr"><img src="http://farm7.static.flickr.com/6172/6162700542_50be6d256f.jpg" width="500" height="303" alt="Screenshot--home-sun-projects-clojalk-src-clojalk-wal.clj"></a></p>
<p>其实用Emacs，远不需要太多的配置，就可以创建一个高效率的开发环境。我用了两天不到时间，当然还包括过去三年甚至更长时间里多次试图学习Emacs并最终半途而废残存的精力。</p>
<p>一步一步来，fedora系统的用户，比如<a href="http://superuser.com/questions/242587/install-gnu-emacs-gui-in-fedora">这位</a>，还有我，都会奇怪，命名有emacs，可是为什么没有GUI呢。因为系统自带的只是一个简单的版本，用yum安装一下emacs这个包才算是真正完整。</p>
<p>接下来要跳关了，大家注意。<a href="https://github.com/technomancy/emacs-starter-kit">Emacs-starter-kit</a>是一个帮助初学者预先配置emacs的一套默认配置文件，有了这个配置文件，也算是爬上了巨人的肩膀，省去了很多探路的时间。安装方式，把这个git仓库的master分支打包下载到~/.emacs.d/里即可（展开到这个目录）。启动emacs后，会自动安装。（作者名字很熟悉，对了，就是leiningen的作者）</p>
<p>由于package.el已经配置好了，接下来就可以安装一些必要的mode，两天的时间初探，我安装了：</p>
<ul>
<li>clojure-mode</li>
<li>clojurescript-mode</li>
<li>auto-complete</li>
<li>color-theme-tangotango</li>
<li>slime</li>
<li>slime-repl</li>
</ul>
<p>安装方式：<br />
M-x package-install<br />
输入包名即可。</p>
<p>clojure-mode和clojurescript-mode是编辑clojure的mode，不多说。</p>
<h4>配色</h4>
<p>color-theme我本来是习惯用solarized，不过尝试了几次color-theme-solarized这个包应该是有一些问题。退而选择了tangotango。要默认选择这个颜色，在init.el里加：</p>
<div class="codecolorer-container lisp twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>require 'color-theme-tangotango<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>color-theme-tangotango<span style="color: #66cc66;">&#41;</span></div></div>
<h4>代码提示</h4>
<p>auto-complete是代码提示和自动补全插件，安装完成后要简单配置一下才能使用：</p>
<div class="codecolorer-container lisp twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>require 'auto-complete-config<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'ac-dictionary-directories <span style="color: #ff0000;">&quot;~/.emacs.d/elpa/auto-complete-1.4.20110207/dict/&quot;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>ac-config-default<span style="color: #66cc66;">&#41;</span></div></div>
<p>当然网上有更多的高级配置，可以搜一下。</p>
<h4>REPL</h4>
<p>clojure的IDE必须要有repl的支持，在emacs中，repl通过slime这个mode来实现。此外还要额外安装swank：<br />
<em>lein plugin install swank-clojure 1.3.2</em><br />
在项目目录通过<em>lein swank</em>启动。在emacs中：<br />
<em>M-x slime-connect</em><br />
选择swank启动的host和port即可。这是一个支持tab提示的强大REPL，并且可以引用lein项目中的代码。</p>
<p>Edit/20110920<br />
其实只需要在clojure-mode中通过M-x clojure-jack-in 即可启动swank和slime。</p>
<h4>ParEdit</h4>
<p>ParEdit是编辑括号的利器，Emacs-Starter-Kit已经把这个包配置好了。ParEdit不仅会自动打印括号，最强大的是还能阻止用户误删或误输入括号！有了它基本上括号的问题就轻松多了。<br />
（当然，有时候需要强制删掉括号<em>C-u DEL</em>，也可能要强制输入括号<em>C-q (</em>或<em>C-q )</em>）</p>
<h4>TagList</h4>
<p>很遗憾ctags不支持clojure，而且emacs似乎也没有一个比较好的TagList。我看到有人提到imenu在一定程度上倒是可以做到类似的功能：<br />
<em>M-x imenu<TAB><TAB></em></p>
<p>总得来说，捅破了窗户纸，用emacs编辑clojure还是最好的选择！</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2011/09/beginning-emacs-for-clojure/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

