<?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>Xiao Shan</title>
	<atom:link href="http://www.slimeden.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.slimeden.com</link>
	<description>Customize my firefox &#38; learn algorithms</description>
	<lastBuildDate>Wed, 11 Apr 2012 07:22:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
	
<!-- Start Of Script Generated By WP-PostViews Plus -->
<script type='text/javascript' src='http://www.slimeden.com/wp-includes/js/jquery/jquery.js?ver=1.7.1'></script>
<script type="text/javascript">
/* <![CDATA[ */
<div id='error'>
			<p class='wpdberror'><strong>WordPress database error:</strong> [Table &#039;slimeden_com.wp_4iqggl_postviewsplus&#039; doesn&#039;t exist]<br />
			<code>SELECT look_ip, look_ip_time FROM wp_4iqggl_postviewsplus WHERE count_type=&quot;/feed&quot; AND count_id=&quot;1&quot;</code></p>
			</div><div id='error'>
			<p class='wpdberror'><strong>WordPress database error:</strong> [Table &#039;slimeden_com.wp_4iqggl_postviewsplus&#039; doesn&#039;t exist]<br />
			<code>INSERT INTO wp_4iqggl_postviewsplus (count_type, count_id, look_ip, look_ip_time) VALUES (&quot;/feed&quot;, &quot;1&quot;, &quot;&quot;, &quot;1337533977&quot;)</code></p>
			</div><div id='error'>
			<p class='wpdberror'><strong>WordPress database error:</strong> [Table &#039;slimeden_com.wp_4iqggl_postviewsplus&#039; doesn&#039;t exist]<br />
			<code>UPDATE wp_4iqggl_postviewsplus SET look_ip_time=&quot;1337533977&quot; WHERE count_type=&quot;/feed&quot; AND count_id=&quot;1&quot;</code></p>
			</div><div id='error'>
			<p class='wpdberror'><strong>WordPress database error:</strong> [Table &#039;slimeden_com.wp_4iqggl_postviewsplus&#039; doesn&#039;t exist]<br />
			<code>UPDATE wp_4iqggl_postviewsplus SET look_ip=&quot;a:1:{s:14:&amp;quot;38.107.179.237&amp;quot;;i:1337533977;}&quot; WHERE count_type=&quot;/feed&quot; AND count_id=&quot;1&quot;</code></p>
			</div>/* ]]> */
</script>
<!-- End Of Script Generated By WP-PostViews Plus -->
	<item>
		<title>一天一条Vim技巧</title>
		<link>http://www.slimeden.com/2012/04/other/vimtrick</link>
		<comments>http://www.slimeden.com/2012/04/other/vimtrick#comments</comments>
		<pubDate>Sun, 01 Apr 2012 06:40:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=280</guid>
		<description><![CDATA[<ol>
<li>搜索光标处单词
* 向下搜索“当前光标处的单词”（注意：匹配是忽略大小写的，另外如果设置highlight option，可以高亮所有匹配）
# 反向搜索，其他同上
“当前光标处的单词”：
a.当前光标下的单词
b.如果当前光标下空白，就是光标后的本行内第一个单词
g*(俗称gstar）
g#
与*和#对应，不同之处是：前者只匹配完整的单词，后者对于作为单词一部分的匹配也会命中。
比如文本如下,光标在第一行test上：
test
atesta
test

*会定位到第三行的test，g*会定位到第二行atesta中的test上
如果用搜索命令:/和?
* 等价与 /\&#60;keyword\[......]</li></ol><p class='read-more'><a href='http://www.slimeden.com/2012/04/other/vimtrick'>阅读全文</a></p>]]></description>
			<content:encoded><![CDATA[<ol>
<li>搜索光标处单词<br />
<span style="color: #0000ff;">* </span>向下搜索“当前光标处的单词”（注意：匹配是忽略大小写的，另外如果设置highlight option，可以高亮所有匹配）<br />
<span style="color: #0000ff;"># </span>反向搜索，其他同上</p>
<p>“当前光标处的单词”：<br />
a.当前光标下的单词<br />
b.如果当前光标下空白，就是光标后的本行内第一个单词</p>
<p><span style="color: #0000ff;">g*</span>(俗称gstar）<br />
<span style="color: #0000ff;">g#</span><br />
与*和#对应，不同之处是：前者只匹配完整的单词，后者对于作为单词一部分的匹配也会命中。<br />
比如文本如下,光标在第一行test上：</p>
<pre class="brush: jscript; title: ; notranslate">test
atesta
test
</pre>
<p>*会定位到第三行的test，g*会定位到第二行atesta中的test上</p>
<p>如果用搜索命令:<span style="color: #0000ff;">/和?</span><br />
<span style="color: #0000ff;">*</span> 等价与 <span style="color: #0000ff;">/\&lt;keyword\&gt;</span><br />
<span style="color: #0000ff;">#</span> 等价于 <span style="color: #0000ff;">?\&lt;keyword\&gt;</span><br />
<span style="color: #0000ff;">g*</span> 等价于 <span style="color: #0000ff;">/keyword</span><br />
<span style="color: #0000ff;">g#</span> 等价于 <span style="color: #0000ff;">?keyword</span></p>
</li>
<li>配对括号间切换跳转 &#8211; <span style="color: #0000ff;">%</span><br />
支持(), [], {}， /* */， #if #ifdef #else #elif #endif<br />
对于程序员，这个命令非常有用。</p>
<p>还有个<a href="http://www.vim.org/scripts/script.php?script_id=39">matchit.vim</a>插件，可以支持更多的符号对，比如html tag， php tag等，甚至正则表达式。
</li>
<li>插入当前单词到命令行 &#8211; <span style="color: #0000ff;">&lt;C-R&gt;&lt;C-A&gt;或者&lt;C-R&gt;&lt;C-W&gt;</span><br />
有时候想把文本里的单词复制到命令行或者查找栏，可以这样快速操作：<br />
a. 移动光标到需要的单词上<br />
b. 按:进入命令行模式或者按/进入查找模式<br />
c. 这时候&lt;C-R&gt;&lt;C-A&gt;即可把当前单词插入到命令行</p>
<p>&lt;C-R&gt;&lt;C-A&gt;和&lt;C-R&gt;&lt;C-W&gt;两者的区别是，前者（word）识别单词是以空白间隔的非空字符串，后者（WORD）是以&#8217;iskeyword&#8217; option中定义的字符组成的串来作为单词。
</li>
<li>基于单词移动光标 &#8211; <span style="color: #0000ff;">w, e, b</span>
<pre class="brush: jscript; title: ; notranslate">w，向后移动到单词的首字母（如果当前单词的首字母已处于光标之前，则跳过这个单词）
e，向后移动到单词的尾字母
b，反向移动到单词的首字母
ge，反向移动到单词的尾字母（如果当前单词的尾字母已处于光标之后，则跳过这个单词）
</pre>
<p>其他：<br />
a. 命令都可以加数字count前缀<br />
b. w, e, b都有大写的版本，区别是对单词的定义不同（word和WORD）
</li>
<li>上下两行交换 &#8211; <span style="color: #0000ff;">ddp</span>
<pre class="brush: jscript; title: ; notranslate">dd，会删除当前行，并把删除的内容存入寄存器
p，会把寄存器中内容黏贴
</pre>
<p>同理:<br />
<span style="color: #0000ff;">xp</span> &#8211; 可以交换两个字符<br />
<span style="color: #0000ff;">bdwwP</span> &#8211; 可以交换两个单词<br />
<span style="color: #0000ff;">das)P</span>- 可以交换两个句子（这两个有点复杂。。。）
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2012/04/other/vimtrick/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>memcached  client库consistent hashing介绍</title>
		<link>http://www.slimeden.com/2011/09/web/memcached_client_hash</link>
		<comments>http://www.slimeden.com/2011/09/web/memcached_client_hash#comments</comments>
		<pubDate>Sun, 11 Sep 2011 02:50:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[consistent hash]]></category>
		<category><![CDATA[key value]]></category>
		<category><![CDATA[memcached]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=262</guid>
		<description><![CDATA[当前很多大型的web系统为了减轻数据库服务器负载，会采用memchached作为缓存系统以提高响应速度。
目录：
<ol>
<li><a href="#intro">memchached简介</a></li>
<li><a href="#hash">hash</a>
<ul>
<li><a href="#mode">取模</a></li>
<li><a href="#consist">一致性hash</a></li>
<li><a href="#virtual">虚拟节点</a></li>
<li><a href="#source">源码解析</a></li>
</ul>
</li>
<li><a href="#reference">参考资料</a></li>
</ol>
<a name="intro">1. memchached简介</a>
<a href="http://code.google.com/p/memcached/">memcached</a>是一个开源的高性能分布式内存对象缓存系统。
其实思想还是比较简单的，实现包括server端（memcached开源项目一般只单指server端）和client端两部分:
<ul>
<li>server端本质是一个<strong>in-memory key-value store</strong>，通过在内存中维护一个大的hashmap用来存储小块的任意数据，对外通过统一的简单接口（me[......]</li></ul><p class='read-more'><a href='http://www.slimeden.com/2011/09/web/memcached_client_hash'>阅读全文</a></p>]]></description>
			<content:encoded><![CDATA[<p>当前很多大型的web系统为了减轻数据库服务器负载，会采用memchached作为缓存系统以提高响应速度。</p>
<p>目录：</p>
<ol>
<li><a href="#intro">memchached简介</a></li>
<li><a href="#hash">hash</a>
<ul>
<li><a href="#mode">取模</a></li>
<li><a href="#consist">一致性hash</a></li>
<li><a href="#virtual">虚拟节点</a></li>
<li><a href="#source">源码解析</a></li>
</ul>
</li>
<li><a href="#reference">参考资料</a></li>
</ol>
<h2><a name="intro">1. memchached简介</a></h2>
<p><a href="http://code.google.com/p/memcached/">memcached</a>是一个开源的高性能分布式内存对象缓存系统。<br />
其实思想还是比较简单的，实现包括server端（memcached开源项目一般只单指server端）和client端两部分:</p>
<ul>
<li>server端本质是一个<strong>in-memory key-value store</strong>，通过在内存中维护一个大的hashmap用来存储小块的任意数据，对外通过统一的简单接口（memcached protocol）来提供操作。</li>
<li>client端是一个library，负责处理<a href="http://code.google.com/p/memcached/wiki/Start#Wire_Protocols">memcached protocol</a>的网络通信细节，与memcached server通信，针对各种语言的不同实现分装了易用的API实现了与不同语言平台的集成。</li>
<li>web系统则通过client库来使用memcached进行对象缓存。</li>
</ul>
<h2><a name="hash">2. hash</a></h2>
<p>memcached的分布式主要体现在client端，对于server端，仅仅是部署多个memcached server组成集群，每个server独自维护自己的数据（互相之间没有任何通信），通过daemon监听端口等待client端的请求。<br />
而在client端，通过一致的hash算法，将要存储的数据分布到某个特定的server上进行存储，后续读取查询使用同样的hash算法即可定位。</p>
<p>client端可以采用各种hash算法来定位server：<br />
<a name="mode">取模</a><br />
最简单的hash算法</p>
<p style="text-align: center;"><strong>targetServer = serverList[hash(key) % serverList.size]</strong></p>
<p>直接用key的hash值（计算key的hash值的方法可以自由选择，比如算法CRC32、MD5,甚至本地hash系统，如java的hashcode）模上server总数来定位目标server。这种算法不仅简单，而且具有不错的随机分布特性。</p>
<p>但是问题也很明显，server总数不能轻易变化。因为如果增加/减少memcached server的数量，对原先存储的所有key的后续查询都将定位到别的server上，导致所有的cache都不能被命中而失效。</p>
<p><a name="consist">一致性hash</a><br />
为了解决这个问题，需要采用<a href="http://en.wikipedia.org/wiki/Consistent_hashing">一致性hash算法</a>（consistent hash）<br />
相对于取模的算法，一致性hash算法除了计算key的hash值外，还会计算每个server对应的hash值，然后将这些hash值映射到一个有限的值域上（比如0~2^32）。通过寻找hash值大于hash(key)的最小server作为存储该key数据的目标server。如果找不到，则直接把具有最小hash值的server作为目标server。</p>
<p>为了方便理解，可以把这个有限值域理解成一个环，值顺时针递增。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/09/12.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/09/12.png" alt="" title="consistent hash demonstration 1" width="400" height="400" class="aligncenter size-full wp-image-268" /></a><br />
如上图所示，集群中一共有5个memcached server，已通过server的hash值分布到环中。</p>
<p>如果现在有一个写入cache的请求，首先计算x=hash(key)，映射到环中，然后从x顺时针查找，把找到的第一个server作为目标server来存储cache，如果超过了2^32仍然找不到，则命中第一个server。比如x的值介于A~B之间，那么命中的server节点应该是B节点<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/09/2.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/09/2.png" alt="" title="consistent hash demonstration 2" width="400" height="400" class="aligncenter size-full wp-image-264" /></a><br />
可以看到，通过这种算法，对于同一个key，存储和后续的查询都会定位到同一个memcached server上。</p>
<p>那么它是怎么解决增/删server导致的cache不能命中的问题呢？<br />
假设，现在增加一个server F，如下图<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/09/3.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/09/3.png" alt="" title="consistent hash demonstration 3" width="400" height="400" class="aligncenter size-full wp-image-265" /></a><br />
此时，cache不能命中的问题仍然存在，但是只存在于B~F之间的位置（由C变成了F），其他位置（包括F~C）的cache的命中不受影响（删除server的情况类似）。尽管仍然有cache不能命中的存在，但是相对于取模的方式已经大幅减少了不能命中的cache数量。</p>
<p><a name="virtual">虚拟节点</a><br />
但是，这种算法相对于取模方式也有一个缺陷：当server数量很少时，很可能他们在环中的分布不是特别均匀，进而导致cache不能均匀分布到所有的server上。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/09/4.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/09/4.png" alt="" title="consistent hash demonstration 4" width="400" height="400" class="aligncenter size-full wp-image-266" /></a><br />
如图，一共有3台server &#8211; A，B，C。命中B的几率远远高于A和C。<br />
为解决这个问题，需要使用虚拟节点的思想：为每个物理节点（server）在环上分配100～200个点，这样环上的节点较多，就能抑制分布不均匀。<br />
当为cache定位目标server时，如果定位到虚拟节点上，就表示cache真正的存储位置是在该虚拟节点代表的实际物理server上。</p>
<p>另外，如果每个实际server的负载能力不同，可以赋予不同的权重，根据权重分配不同数量的虚拟节点。</p>
<p><a name="source">源码解析</a><br />
下面结合一个java的memcached client（<a href="https://github.com/gwhalin/Memcached-Java-Client">gwhalin / Memcached-Java-Client</a>）的源码来看一下consistent hash的实现。<br />
首先看server的分布：</p>
<pre class="brush: java; title: ; notranslate">
// 采用有序map来模拟环
this.consistentBuckets = new TreeMap();

MessageDigest md5 = MD5.get();//用MD5来计算key和server的hash值

// 计算总权重
if ( this.totalWeight 	for ( int i = 0; i &lt; this.weights.length; i++ )
		this.totalWeight += ( this.weights[i] == null ) ? 1 : this.weights[i];
} else if ( this.weights == null ) {
	this.totalWeight = this.servers.length;
}

// 为每个server分配虚拟节点
for ( int i = 0; i &lt; servers.length; i++ ) {
	// 计算当前server的权重
	int thisWeight = 1;
	if ( this.weights != null &amp;&amp; this.weights[i] != null )
		thisWeight = this.weights[i];

	// factor用来控制每个server分配的虚拟节点数量
	// 权重都相同时，factor=40
	// 权重不同时，factor=40*server总数*该server权重所占的百分比
	// 总的来说，权重越大，factor越大，可以分配越多的虚拟节点
	double factor = Math.floor( ((double)(40 * this.servers.length * thisWeight)) / (double)this.totalWeight );

	for ( long j = 0; j &lt; factor; j++ ) {
		// 每个server有factor个hash值
		// 使用server的域名或IP加上编号来计算hash值
		// 比如server - &quot;172.45.155.25:11111&quot;就有factor个数据用来生成hash值：
		// 172.45.155.25:11111-1, 172.45.155.25:11111-2, ..., 172.45.155.25:11111-factor
		byte[] d = md5.digest( ( servers[i] + &quot;-&quot; + j ).getBytes() );

		// 每个hash值生成4个虚拟节点
		for ( int h = 0 ; h &lt; 4; h++ ) {
			Long k =
				((long)(d[3+h*4]&amp;0xFF) &lt;&lt; 24)
			      | ((long)(d[2+h*4]&amp;0xFF) &lt;&lt; 16)
			      | ((long)(d[1+h*4]&amp;0xFF) &lt;&lt; 8 )
			      | ((long)(d[0+h*4]&amp;0xFF));

			// 在环上保存节点
			consistentBuckets.put( k, servers[i] );
		}

	}
	// 每个server一共分配4*factor个虚拟节点
}
</pre>
<p>每个server根据权重获得一个虚拟节点数量控制因子factor，然后由services[i]+&#8221;-&#8221;+i来生成factor个hash值，生成hash值时采用MD5算法。<br />
由于MD5长度是16个字节，正好划分成4段，每段4字节，这样每段就对应一个虚拟节点。linex-liney通过把这一段的4字节拼装成连续的32bit，作为低32位拉升为一个Long。</p>
<p>为key定位cache存储的server：</p>
<pre class="brush: java; title: ; notranslate">
// 用MD5来计算key的hash值
MessageDigest md5 = MD5.get();
md5.reset();
md5.update( key.getBytes() );
byte[] bKey = md5.digest();

// 取MD5值的低32位作为key的hash值
long hv = ((long)(bKey[3]&amp;0xFF) &lt;&lt; 24) | ((long)(bKey[2]&amp;0xFF) &lt;&lt; 16) | ((long)(bKey[1]&amp;0xFF) &lt;&lt; 8 ) | (long)(bKey[0]&amp;0xFF);

// hv的tailMap的第一个虚拟节点对应的即是目标server
SortedMap tmap = this.consistentBuckets.tailMap( hv );
return ( tmap.isEmpty() ) ? this.consistentBuckets.firstKey() : tmap.firstKey();
</pre>
<h2><a name="reference">3. 参考资料</a></h2>
<ol>
<li>首次提出consistent hash的论文 &#8211; <a href="http://portal.acm.org/citation.cfm?id=258660">&#8220;Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web&#8221;</a></li>
<li>Consistent hashing Wiki &#8211; <a href="http://en.wikipedia.org/wiki/Consistent_hashing">http://en.wikipedia.org/wiki/Consistent_hashing</a></li>
<li><a href="http://www.audioscrobbler.net/development/ketama/">Ketama: Consistent Hashing</a></li>
<li><a href="http://memcached.org/">memcached开源项目主页</a></li>
<li><a href="http://code.google.com/p/memcached/">memcached google code主页</a></li>
<li><a href="https://github.com/gwhalin/Memcached-Java-Client">gwhalin / Memcached-Java-Client主页</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2011/09/web/memcached_client_hash/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[pentadactyl plugin]findmarker</title>
		<link>http://www.slimeden.com/2011/05/firefox/findmarker</link>
		<comments>http://www.slimeden.com/2011/05/firefox/findmarker#comments</comments>
		<pubDate>Thu, 19 May 2011 10:38:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[firefox]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[firefox4]]></category>
		<category><![CDATA[highlight]]></category>
		<category><![CDATA[pentadactyl]]></category>
		<category><![CDATA[scrollbar]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=253</guid>
		<description><![CDATA[<p>把以前的findbarMarker.uc.js脚本按照pentadactyl的操作习惯重新封装了下。</p>
<p>这个插件会在右侧滚动条旁添加一个位置指示器，当使用/?在页面查找时，查找结果的位置会被标记在指示器上。<br />
基本用处就是可以看到查找结果在长页面上的大致位置，点击每个位置标记可以跳转到相应的查找结果。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/05/findmarker.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/05/findmarker.png" alt="" title="findmarker" width="298" height="331" class="aligncenter size-full wp-image-258" /></a></p>
<p>命令</p>
<pre class="brush: jscript; title: ; notranslate">:h findmarker-plugin</pre>
<p>查看帮助</p>
<p><a href="http://www.slimeden.com/wp-content/uploads/2011/05/findmarker-doc.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/05/findmarker-doc.png" alt="" title="findmarker-doc" width="601" height="300" class="aligncenter size-full wp-image-254" /></a></p>
<p>配置项<span style="color:orange">&#8216;findmarker&#8217;</span>可以控制如何标记：<br />
<span style="color:blue">0（默认值）</span>：只在高亮所有查找结果时标记，通过命令<span style="color:#0DA575">:hl</span>可以toggle高亮状态<br />
<span style="color:blue">1</span>：只标记当前查找结果</p>
<p><a href='http://www.slimeden.com/wp-content/uploads/2011/05/findMarker_v0.01.js'>findMarker_v0.01</a></p>]]></description>
			<content:encoded><![CDATA[<p>把以前的findbarMarker.uc.js脚本按照pentadactyl的操作习惯重新封装了下。</p>
<p>这个插件会在右侧滚动条旁添加一个位置指示器，当使用/?在页面查找时，查找结果的位置会被标记在指示器上。<br />
基本用处就是可以看到查找结果在长页面上的大致位置，点击每个位置标记可以跳转到相应的查找结果。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/05/findmarker.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/05/findmarker.png" alt="" title="findmarker" width="298" height="331" class="aligncenter size-full wp-image-258" /></a></p>
<p>命令</p>
<pre class="brush: jscript; title: ; notranslate">:h findmarker-plugin</pre>
<p>查看帮助</p>
<p><a href="http://www.slimeden.com/wp-content/uploads/2011/05/findmarker-doc.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/05/findmarker-doc.png" alt="" title="findmarker-doc" width="601" height="300" class="aligncenter size-full wp-image-254" /></a></p>
<p>配置项<span style="color:orange">&#8216;findmarker&#8217;</span>可以控制如何标记：<br />
<span style="color:blue">0（默认值）</span>：只在高亮所有查找结果时标记，通过命令<span style="color:#0DA575">:hl</span>可以toggle高亮状态<br />
<span style="color:blue">1</span>：只标记当前查找结果</p>
<p><a href='http://www.slimeden.com/wp-content/uploads/2011/05/findMarker_v0.01.js'>findMarker_v0.01</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2011/05/firefox/findmarker/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>[pentadactyl plugin]findhere</title>
		<link>http://www.slimeden.com/2011/04/firefox/findhere</link>
		<comments>http://www.slimeden.com/2011/04/firefox/findhere#comments</comments>
		<pubDate>Thu, 28 Apr 2011 09:49:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[firefox]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[firefox4]]></category>
		<category><![CDATA[pentadactyl]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=245</guid>
		<description><![CDATA[pentadactyl的find功能是从当前caret的位置处开始搜索的，findhere脚本在此之上提供一个findhere命令，可以使搜索起始于当前屏幕可见内容。
pentadactyl的issue列表里有这个<a href="http://code.google.com/p/dactyl/issues/detail?id=170&#038;q=caret">enhancement request</a> &#8211; Issue 170: 	Searches should start within the current viewport，但是一直没时间实现。
20110429升级到v0.02 &#8211; 添加!参数以支持反向查找，增加简化命令:fh
命令：
:find[here]
:fh
:find[here]!
:fh!

帮助：
:[......]<p class='read-more'><a href='http://www.slimeden.com/2011/04/firefox/findhere'>阅读全文</a></p>]]></description>
			<content:encoded><![CDATA[<p>pentadactyl的find功能是从当前caret的位置处开始搜索的，findhere脚本在此之上提供一个findhere命令，可以使搜索起始于当前屏幕可见内容。</p>
<p>pentadactyl的issue列表里有这个<a href="http://code.google.com/p/dactyl/issues/detail?id=170&#038;q=caret">enhancement request</a> &#8211; Issue 170: 	Searches should start within the current viewport，但是一直没时间实现。</p>
<blockquote><p><span style="background-color: #eff3ff; color: red;">20110429升级到v0.02 &#8211; 添加!参数以支持反向查找，增加简化命令:fh</span></p></blockquote>
<p>命令：</p>
<pre class="brush: jscript; title: ; notranslate">:find[here]
:fh
:find[here]!
:fh!
</pre>
<p>帮助：</p>
<pre class="brush: jscript; title: ; notranslate">:h findhere</pre>
<p>可以考虑重新映射/和?键</p>
<pre class="brush: jscript; title: ; notranslate">map -silent / :findhere
map -silent ? :findhere!
</pre>
<p>问题：<br />
当前pentadactyl版本似乎默认的?键功能不是反向搜索，跟/键功能一样也是向下查找，可能是bug</p>
<p>附件:<br />
<a href='http://www.slimeden.com/wp-content/uploads/2011/04/findhere_v0.01.js'>findhere_v0.01</a><br />
<a href='http://www.slimeden.com/wp-content/uploads/2011/04/findhere_v0.02.js'>findhere_v0.02</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2011/04/firefox/findhere/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>[firefox]about URL scheme</title>
		<link>http://www.slimeden.com/2011/04/firefox/abouturlscheme</link>
		<comments>http://www.slimeden.com/2011/04/firefox/abouturlscheme#comments</comments>
		<pubDate>Fri, 22 Apr 2011 04:26:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[firefox]]></category>
		<category><![CDATA[firefox4]]></category>
		<category><![CDATA[guide]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=235</guid>
		<description><![CDATA[喜欢折腾firefox的都知道，firefox支持一种形如about:xxx的内建URL，用来呈现某些内建功能。
目前，about URL scheme还没有标准化，不过IETF正在着手标准化工作，已经有了<a href="http://tools.ietf.org/html/draft-holsten-about-uri-scheme-06">草案</a>。
尽管还未标准化，但是现在主流的浏览器都有自己不程度的支持，包括IE。
今天主要说说firefox的about URL scheme。
以下这些URLs都可以输入到地址栏，用标签呈现内容。（以下以firefox4为例）
<ul>
<li>about:about</li>
列出当前支持的所有about地址。
<a href="http://www.slimeden.com/wp-content/uploads/2011/04/aboutabout.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/04/aboutabout.png" alt="" title="aboutabout" width="731" height="474" class="aligncenter size-full wp-image-236" /></a>
<li>about</li>
显示当前firefox的基本信息
<li>about:logo</li>
显示about页面的logo
<li>abo[......]</li></ul><p class='read-more'><a href='http://www.slimeden.com/2011/04/firefox/abouturlscheme'>阅读全文</a></p>]]></description>
			<content:encoded><![CDATA[<p>喜欢折腾firefox的都知道，firefox支持一种形如about:xxx的内建URL，用来呈现某些内建功能。</p>
<p>目前，about URL scheme还没有标准化，不过IETF正在着手标准化工作，已经有了<a href="http://tools.ietf.org/html/draft-holsten-about-uri-scheme-06">草案</a>。<br />
尽管还未标准化，但是现在主流的浏览器都有自己不程度的支持，包括IE。</p>
<p>今天主要说说firefox的about URL scheme。<br />
以下这些URLs都可以输入到地址栏，用标签呈现内容。（以下以firefox4为例）</p>
<ul>
<li>about:about</li>
<p>列出当前支持的所有about地址。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/04/aboutabout.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/04/aboutabout.png" alt="" title="aboutabout" width="731" height="474" class="aligncenter size-full wp-image-236" /></a></p>
<li>about</li>
<p>显示当前firefox的基本信息</p>
<li>about:logo</li>
<p>显示about页面的logo</p>
<li>about:blank</li>
<p>显示一个空白页面，这个大家都熟悉，基本上所有浏览器都支持</p>
<li>about:copyright</li>
<p>显示firefox采用的软件license信息 &#8211; firefox采用Mozilla Public License</p>
<li>about:license</li>
<p>显示Mozilla Public License的具体内容</p>
<li>about:credits</li>
<p>显示firefox项目的contributors信息</p>
<li>about:home</li>
<p>显示firefox的默认主页</p>
<li>about:buildconfig</li>
<p>显示当前firefox使用的build的构建信息</p>
<li>about:addons</li>
<p>显示扩展管理页面</p>
<li>about:plugins</li>
<p>显示安装的插件信息</p>
<li>about:privatebrowsing</li>
<p>显示privatebrowsing模式切换页面，可以用来切换隐私浏览模式。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/04/aboutprivate.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/04/aboutprivate.png" alt="" title="aboutprivate" width="723" height="349" class="aligncenter size-full wp-image-241" /></a></p>
<li>about:cache</li>
<p>显示cache的使用信息，甚至可以查看到每条cache的存储<br />
另外注意：磁盘cache较多的话，点击查看列表前要谨慎，以防假死。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/04/aboutcache.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/04/aboutcache.png" alt="" title="aboutcache" width="566" height="579" class="aligncenter size-full wp-image-239" /></a></p>
<li>about:memory</li>
<p>显示当前内存使用状况<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/04/aboutmemeory.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/04/aboutmemeory.png" alt="" title="aboutmemeory" width="389" height="752" class="aligncenter size-full wp-image-238" /></a></p>
<li>about:sessionrestore</li>
<p>显示sessionrestore操作页面，可以用来重新恢复上次session中的标签</p>
<li>about:crashes</li>
<p><a href="http://www.slimeden.com/wp-content/uploads/2011/04/aboutcrash.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/04/aboutcrash.png" alt="" title="aboutcrash" width="888" height="261" class="aligncenter size-full wp-image-240" /></a></p>
<li>about:config</li>
<p>这个也常用，用来设置preferrences</p>
<li>about:support</li>
<p>打开support页面，等同于点击菜单Help -> Troubleshooting Information<br />
可以用来打开profile文件夹，查看firefox版本，查看安装的扩展和插件，查看已修改的preferrences，查看Graphics信息</p>
<li>about:sync-log</li>
<p>查看同步的log</p>
<li>about:sync-tabs</li>
<p>打开同步tabs管理页面，用来从其他电脑同步标签页，这个比较有用。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/04/aboutsynctabs.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/04/aboutsynctabs.png" alt="" title="aboutsynctabs" width="593" height="307" class="aligncenter size-full wp-image-242" /></a></p>
<p>下面两个是彩蛋：</p>
<li>about:mozilla</li>
<p>显示一段来自<a href="http://en.wikipedia.org/wiki/The_Book_of_Mozilla">The Book of Mozilla</a>的节选</p>
<li>about:robots</li>
<p>这个菜单开始于March 8, 2008 trunk builds，在bugzilla里还有个<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=417302">bug</a> track</p>
<p>还有一些没有列在about:about页面的</p>
<li>about:blocked</li>
<p>显示恶意软件保护页面</p>
<li>about:certerror</li>
<p>显示“SSL/TLS证书不能验证时的错误”页面</p>
<li>about:feeds</li>
<p>显示“点击地址栏的rss订阅图标时弹出的”页面</p>
<li>about:neterror</li>
<p>显示“地址不能访问时使用的”页面
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2011/04/firefox/abouturlscheme/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>[pentadactyl]打开指定文件夹</title>
		<link>http://www.slimeden.com/2011/04/firefox/openfolderinpentadactyl</link>
		<comments>http://www.slimeden.com/2011/04/firefox/openfolderinpentadactyl#comments</comments>
		<pubDate>Sat, 09 Apr 2011 04:18:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[firefox]]></category>
		<category><![CDATA[dactyl]]></category>
		<category><![CDATA[脚本]]></category>
		<category><![CDATA[firefox4]]></category>
		<category><![CDATA[pentadactyl]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimperator]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=233</guid>
		<description><![CDATA[有网友询问，通过pentadactyl有没有方便的办法在firefox中打开文件夹。
最直接的办法是用firefox的file://方式URL来访问本地文件夹
:tabopen file://c:\\windows
================================================
如果不想输入file://，简单的办法是定义下面的ex命令
:com! folder -description “Open this folder” -nargs=1 -complete dir -js gBrowser.selectedTab = gBrowser.addTab(ar[......]<p class='read-more'><a href='http://www.slimeden.com/2011/04/firefox/openfolderinpentadactyl'>阅读全文</a></p>]]></description>
			<content:encoded><![CDATA[<p>有网友询问，通过pentadactyl有没有方便的办法在firefox中打开文件夹。</p>
<p>最直接的办法是用firefox的file://方式URL来访问本地文件夹</p>
<pre class="brush: jscript; title: ; notranslate">:tabopen file://c:\\windows</pre>
<p>================================================<br />
如果不想输入file://，简单的办法是定义下面的<span style="color:#527BBD;font-weight:bold;">ex</span>命令</p>
<pre class="brush: jscript; title: ; notranslate">:com! folder -description “Open this folder” -nargs=1 -complete dir -js gBrowser.selectedTab = gBrowser.addTab(args);
</pre>
<p>这样使用</p>
<pre class="brush: jscript; title: ; notranslate">:folder C:\\windows</pre>
<p>这个命令只支持绝对路径。</p>
<p>================================================<br />
如果想功能完善点，可以使用下面的js代码，放在<span style="color:#527BBD;font-weight:bold;">rc</span>文件中。</p>
<pre class="brush: jscript; title: ; notranslate">javascript &lt;&lt;EOF
    io.openFolder = function(arg) {
        try{
        if(arg) {
            try {
                arg = arg.toString();
            }catch(e) {
                arg = null;
            }
        }

        var folderPath = arg;
        if (!folderPath) {
            folderPath = io.cwd.path;
        }

        folderPath = File.expandPath(folderPath);
        if(!File.isAbsolutePath(folderPath)) {
            let dirs = modules.options.get(&quot;cdpath&quot;).files;
            for (let dir in values(dirs)) {
                dir = dir.child(folderPath);
                if (dir.exists() &amp;&amp; dir.isDirectory() &amp;&amp; dir.isReadable()) {
                    folderPath = dir.path;
                    break;
                }
            }
        }
        gBrowser.selectedTab = gBrowser.addTab(folderPath);
        }catch(e) { dactyl.echerr(e); }
    };
EOF
</pre>
<p>然后再定义ex命令 &#8211; <span class="keys">folder</span></p>
<pre class="brush: jscript; title: ; notranslate">:com! folder -description &quot;Open this folder&quot; -nargs=? -complete dir -js io.openFolder(args);</pre>
<p><span style="color:blue;font-weight:bold;">用法说明</span>:</p>
<ol>
<li>不指定目录无参数调用时，打开当前目录</li>
<ul>
<li>通过<span class="keys">:pwd</span>查看当前目录</li>
<li>通过<span class="keys">:cd</span>更改当前目录</li>
</ul>
<li>使用绝对路径指定文件夹</li>
<p>比如</p>
<pre class="brush: jscript; title: ; notranslate">:folder e:\\algorithm</pre>
<p>跟前一种简单办法一样。</p>
<li>使用相对路径指定文件夹</li>
<ul>
<li>默认情况下，相对路径只从当前目录开始搜索</li>
<p>比如：当前在firefox的profiles目录下</p>
<pre class="brush: jscript; title: ; notranslate">:folder chrome</pre>
<p>即可打开profiles目录下的chrome文件夹</p>
<li>如果设置了环境变量<span style="color:#527BBD">$CDPATH</span>，<span style="color:#527BBD">$CDPATH</span>定义的目录都作为相对路径的搜索起点。</li>
<li>设置配置项<strong>cdpath</strong></li>
<pre class="brush: jscript; title: ; notranslate">:help cdpath</pre>
<p>配置项<strong>cdpath</strong>下的所有路径都作为相对路径的搜索起点。
</ul>
<li>支持文件夹<span style="color:#527BBD">autocompletion</span></li>
</ol>
<style type="text/css">
.keys {
    color: #0DA575;
    font-weight: bold;
}
</style>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2011/04/firefox/openfolderinpentadactyl/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>pentadactyl键映射</title>
		<link>http://www.slimeden.com/2011/04/firefox/pentadactylkeymapping</link>
		<comments>http://www.slimeden.com/2011/04/firefox/pentadactylkeymapping#comments</comments>
		<pubDate>Sun, 03 Apr 2011 07:54:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[firefox]]></category>
		<category><![CDATA[add-on]]></category>
		<category><![CDATA[dactyl]]></category>
		<category><![CDATA[firefox4]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[key]]></category>
		<category><![CDATA[keybidding]]></category>
		<category><![CDATA[pentadactyl]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimperator]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=230</guid>
		<description><![CDATA[=================================================
目录
<ol>
<li><a href="#modes">模式</a></li>
<li><a href="#commands">键映射命令</a></li>
<li><a href="#args">参数详解</a></li>
<li><a href="#pres">键表示</a></li>
<li><a href="#others">其他</a></li>
</ol>
=================================================
<ul>
<li><a name="modes"><strong>模式</strong></a>
键映射是Pentadactyl提供的最基本的快捷键定义方式。
在Pentadactyl中，每一个键映射定义都与一个模式相关联，比如浏览（普通）模式（normal mode），编辑（插入）模式（insert mode），命令行模式（command line mode）等等。在某个模式下定义的键，只有在该模式激活的情况下才有效。例如，我定义了[......]</li></ul><p class='read-more'><a href='http://www.slimeden.com/2011/04/firefox/pentadactylkeymapping'>阅读全文</a></p>]]></description>
			<content:encoded><![CDATA[<p>=================================================<br />
目录</p>
<ol>
<li><a href="#modes">模式</a></li>
<li><a href="#commands">键映射命令</a></li>
<li><a href="#args">参数详解</a></li>
<li><a href="#pres">键表示</a></li>
<li><a href="#others">其他</a></li>
</ol>
<p>=================================================</p>
<ul>
<li><a name="modes"><span style="color:black"><strong>模式</strong></span></a><br />
键映射是Pentadactyl提供的最基本的快捷键定义方式。<br />
在Pentadactyl中，每一个键映射定义都与一个模式相关联，比如浏览（普通）模式（normal mode），编辑（插入）模式（insert mode），命令行模式（command line mode）等等。在某个模式下定义的键，只有在该模式激活的情况下才有效。例如，我定义了一个命令行模式下的键<C-c>用于复制文本，只有在我打开命令行（:）的情况下才能用来复制。而在一般的浏览模式下，按&lt;C-c&gt;去复制是不生效的，除非在view模式下也有映射。</p>
<p>下面5个模式是我们平时最常用到的基本模式</p>
<style type="text/css">
table{
    border-collapse:collapse;
    margin-bottom: 15px;
}
.keys {
    color: #0DA575;
    font-weight: bold;
}
td{ border:1px solid #0066ff}
.index { text-align:center }
</style>
<table>
<tr>
<td width="20px" class="index"><strong>n</strong></td>
<td><span style="color:#3283FF">Normal Mode</span><br />
普通模式，浏览模式</td>
<td>焦点没有定位于某个特定元素时（通常浏览网页时都处于该模式）</td>
</tr>
<tr>
<td class="index"><strong>v</strong></td>
<td><span style="color:#3283FF">Visual Mode</span><br />
选择模式</td>
<td>①<del>当在普通模式下选中文字时</del><br />
<span style="color:red">×有误：经测试这种仍然是处于普通模式</span><br />
②在Caret（浏览模式下按<span class="keys">i</span>进入）和TextEdit模式下按<span class="keys">v</span>直接进入visual模式</td>
</tr>
<tr>
<td class="index"><strong>i</strong></td>
<td><span style="color:#3283FF">Insert Mode</span><br />
插入模式，编辑模式</td>
<td>当光标位于页面上的文本输入框，处于可编辑文字状态时</td>
</tr>
<tr>
<td class="index"><strong>t</strong></td>
<td><span style="color:#3283FF">TextEdit Mode</span><br />
文本编辑模式</td>
<td>在插入模式下按<span class="keys">&lt;C-t&gt;</span>进入<br />
一般在文本输入框中，对应于可输入字符的快捷键都没法使用，因为要用来输入文字。为了能够在文字输入区域使用类Vim的操作，需要进入TextEdit模式，这时候就可以定义可输入字符键为其他快捷操作。
</td>
</tr>
<tr>
<td class="index"><strong>c</strong></td>
<td><span style="color:#3283FF">Command-line Mode</span><br />
命令行模式</td>
<td>按键<span class="keys">:</span>进入命令行模式，用于输入Ex命令</td>
</tr>
</table>
<p>在vim中，不像一般的编辑器，打开文件后是不能直接按键输入文字的，因为vim会默认进入类似于Pentadactyl的TextEdit模式，目的是为了方便用丰富的命令定位或者操作文本，而当需要输入文字时，用<span class="keys">i、a</span>这类命令进入Insert模式再输入。<br />
而在浏览器中，定位于输入框后，一般都是没有内容的，首先要开始输入文字。所以，Pentadactyl为了与传统Firefox操作方式相一致，当光标定位于输入框时，默认也是进入Insert模式。但是，可别忘了Pentadactyl定位于提供完全的类vim的操作体验，所以当然也是可以实现vim的操作方式的。</p>
<pre class="brush: jscript; title: ; notranslate">:set insertmode=off</pre>
<p>Pentadactyl通过<span style="color:#F4B04C">insertmode</span>配置项来控制进入可输入区域后首先使用何种模式，默认<span style="color:#F4B04C">insertmode</span>=<span style="color:red">on</span>使用InsertMode，置成<span style="color:red">off</span>后会直接进入TextEdit模式。</p>
<p>除了这5个基本模式外，当前最新的Pentadactyl可以支持如下模式树中的模式：<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/04/1.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/04/1.png" alt="" title="Pentadactyl Modes Tree" width="659" height="500" class="aligncenter size-full wp-image-231" /></a><br />
针对某个模式定义的键映射，除了会在该模式下生效外，在该模式的子孙模式下都生效。比如，在base模式下定义的键，在normal和insert模式下都生效。
</li>
<li><a name="commands"><span style="color:black"><strong>键映射命令</strong></span></a><br />
Pentadactyl提供的键映射相关命令比较多，有20+，但是理解了模式后，就一目了然了。</p>
<pre class="brush: jscript; title: ; notranslate">:map   :noremap   :unmap   :mapclear  – both Normal and Visual modes
:nmap  :nnoremap  :nunmap  :nmapclear – Normal mode
:vmap  :vnoremap  :vunmap  :vmapclear – Visual mode
:imap  :inoremap  :iunmap  :imapclear – Insert mode
:tmap  :tnoremap  :tunmap  :tmapclear – Text Edit mode
:cmap  :cnoremap  :cunmap  :cmapclear – Command-line mode</pre>
<p>最基本的命令是map</p>
<pre class="brush: jscript; title: ; notranslate">:m[ap] {lhs} {rhs}</pre>
<p>{lhs}用于指定新定义的键，{rhs}用于指定实现这个新定义所用的原键。<br />
{lhs}和{rhs}都支持多个键组成的序列。</p>
<pre class="brush: jscript; title: ; notranslate">:unmap {lhs}
:unmap!
</pre>
<p>取消已定义的键{lhs}<br />
加!号，取消所有映射</p>
<pre class="brush: jscript; title: ; notranslate">:mapclear</pre>
<p>原本用于取消所有键映射，从b6开始由unmap!替代，最新版已经没有相关命令<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; 感谢<span style="color: #ff9900;">harnack</span>的指点</p>
<pre class="brush: jscript; title: ; notranslate">:noremap</pre>
<p>在进行键映射时，由于map命令的{rhs}支持用户自定义的键，所以存在一个循环引用问题。<br />
比如如下映射，就会导致无限的循环映射。</p>
<pre class="brush: jscript; title: ; notranslate">:map a b
:map b a</pre>
<p>为了解决这个问题，引用了noremap命令 &#8211; no recursive map<br />
这个命令的{rhs}不支持用户定义命令，只能指定pentadactyl默认提供的键，并按照默认提供的逻辑来执行。<br />
当在进行键定义时，如果需要用到pentadactyl默认提供的键逻辑，应该使用noremap。<br />
map命令的-builtin参数提供同样的语意。</p>
<p>这几个基本命令前都可以加5大基本模式的前缀字符（n,v,i,t,c），用于在相应模式下映射键。<br />
map命令的-modes（缩写-m）参数可以用于指定模式。<br />
比如如下映射，恢复ctrl+c复制功能。</p>
<pre class="brush: jscript; title: ; notranslate">:map -m=v,i,c &lt;C-c&gt; &lt;C-v&gt;&lt;C-c&gt;</pre>
</li>
<li><a name="args"><span style="color:black"><strong>参数详解</strong></span></a><br />
映射命令提供了一系列有用的参数。</p>
<ol>
<li><span style="color:blue">-arg</span></li>
<p>缩写-a<br />
使定义的映射按键后，可再接一个参数键，参数的值可以在{rhs}用&lt;arg&gt;取到<br />
比如如下映射：映射新D键，按了<span class="keys">D</span>以后再按一位数字<span class="keys">i</span>，可以直接关闭第i个标签</p>
<pre class="brush: jscript; title: ; notranslate">:map -arg D &lt;arg&gt;bd</pre>
<p>感觉不是很有用，因为参数只能接收一个，且大多数单键都已有功能定义，不能作为参数键。<br />
可能在-js和-ex下能有大用，待测。</p>
<li><span style="color:blue">-builtin</span></li>
<p>缩写-b<br />
使映射命令的{rhs}部分只能指定系统内置的命令，等价于noremap</p>
<pre class="brush: jscript; title: ; notranslate">:map d -js alert('test')
:map t -builtin d
</pre>
<p>这样映射后，即使重新定义了d键，但是按<span class="keys">t</span>键仍然可以关闭标签，而不是alert test字符串。</p>
<li><span style="color:blue">-count</span></li>
<p>缩写-c<br />
使映射的命令支持数字前缀。<br />
比如，如果重新交换d和D的逻辑（默认d是关闭当前标签并选中右侧的，D是选中左侧）</p>
<pre class="brush: jscript; title: ; notranslate">:map d -builtin D
:map D -builtin d
</pre>
<p>这样映射的话，新的d和D就不支持数字前缀了，比如原先2d可以关闭2个标签，重新映射后就只能关闭当前。</p>
<p>要支持数字前缀，应该这样映射</p>
<pre class="brush: jscript; title: ; notranslate">:map -count d -builtin &lt;count&gt;D
:map -count D -builtin &lt;count&gt;d</pre>
<p>另：经测试，不写-count参数，也可以在{rhs}部分直接使用&lt;count&gt;来实现数字前缀。</p>
<li><span style="color:blue">-description</span></li>
<p>缩写-d<br />
用于指定新定义键的名字，在unmap时可以看见。</p>
<pre class="brush: jscript; title: ; notranslate">:map -description &quot;This is a test key mapping&quot; t -js alert(&quot;test&quot;)</pre>
<li><span style="color:blue">-ex</span></li>
<p>缩写-e<br />
一般我们定义键时，都是用已有的键（序列）来定义新键，所以{rhs}表示的是按键</p>
<pre class="brush: jscript; title: ; notranslate">:noremap d D</pre>
<p>这个映射的意思是以后按<span class="keys">d</span>的效果就是原来按<span class="keys">D</span>的效果。</p>
<p>-ex参数可以使{rhs}部分执行ex命令。<br />
比如下面这个映射，映射b键打开百度</p>
<pre class="brush: jscript; title: ; notranslate">:map b -ex tabopen www.baidu.com</pre>
<p>通过这个参数，我们可以把丰富的ex命令映射成快捷键，用处非常大。</p>
<pre class="brush: jscript; title: ; notranslate">:help ex-cmd-index</pre>
<p>通过这个命令，查看系统内建ex命令索引</p>
<p>另外，-ex部分支持条件判断语法。</p>
<pre class="brush: jscript; title: ; notranslate">map &lt;F2&gt; -ex if buffer.URL == 'about:blank'
    \ open about:config
\ else
    \ tabopen about:config
\ fi</pre>
<p>定义<span class="keys">F2</span>打开about:config，如果当前tab是空白页就在当前页打开，否则新开标签<br />
条件判断语法似乎不支持写在单行（待确定<span style="color:red">？？？</span>），所以不能在命令行定义，需要定义在rc文件里，而且多行需要用\标识。</p>
<pre class="brush: jscript; title: ; notranslate">:help conditionals</pre>
<p>查看ex命令条件判断语法。</p>
<li><span style="color:blue">-group</span></li>
<p>缩写-g<br />
为了方便管理脚本、命令以及键映射，pentadactyl中提供了group的概念。</p>
<pre class="brush: jscript; title: ; notranslate">:help group     查看group相关帮助</pre>
<p>在进行键映射时，如果使用-group参数，就可以把该映射关联到一个已创建的group，以后可以通过group来管理一批关联的键映射。另外，group可以指定只在特定的URLs生效，换言之，通过group就可以实现只在某些URLs下生效的键映射。</p>
<p>用这个参数，可以很方便自定义针对某个站点的快捷键。<br />
<span style="color:red">【注意】这个键定义只是示例，不具有通用性。</span><br />
比如：我常常要在blog后台更新文章，写好内容后，需要点个按钮预览，确认没问题了后再提交发布。但是因为我的文章一般都非常长，所以更新好了内容后，还得滚屏定位到预览按钮，再点击预览。预览完了后，还得再滚屏定位到上次输入内容的地方，继续写。这样，页面上下滚来滚去的非常不方便。所以我定义了两个快捷键，一个p用来点击预览按钮，一个s提交发布。这样，我可以一直在文章编辑区域内写东西，而不再需要滚屏定位到相应的按钮了，省了很多事。</p>
<pre class="brush: jscript; title: ; notranslate">:group myblog -description &quot;Xiao Shan's blog&quot; -locations=http://www.slimeden.com/wp-admin/*
:map p -group=myblog -js var preview=content.document.getElementById('post-preview');var evt=preview.ownerDocument.createEvent(&quot;Events&quot;);evt.initEvent(&quot;click&quot;, true, true);preview.dispatchEvent(evt);
:map s -group=myblog -js var preview=content.document.getElementById('publish');var evt=preview.ownerDocument.createEvent(&quot;Events&quot;);evt.initEvent(&quot;click&quot;, true, true);preview.dispatchEvent(evt);
</pre>
<li><span style="color:blue">-javascript</span></li>
<p>缩写-j<br />
与-ex相似，-javascript就是在{rhs}部分使用javascript代码，相当于提供了完整的keyconfig功能。<br />
这样，pentadactyl下的键映射基本上可以说无所不能了。</p>
<p><span style="color:red">【☆推荐】</span>下面列几个pentadactyl中提供的比较有用的javascript函数。</p>
<pre class="brush: jscript; title: ; notranslate">dactyl.execute(&quot;:tabopen &quot;+ content.getSelection());</pre>
<p>执行字符串形式的ex命令。</p>
<pre class="brush: jscript; title: ; notranslate">CommandExMode().open(&quot;tabopen &quot;);</pre>
<p>打开ex命令行，并输入参数中提供的字符串内容。</p>
<pre class="brush: jscript; title: ; notranslate">prefs.get(&quot;browser.tabs.insertRelatedAfterCurrent&quot;, true);
prefs.set(&quot;browser.tabs.insertRelatedAfterCurrent&quot;, true);
</pre>
<p>1. 取preference的值，没有的话返回第二个参数 &#8211; 默认值<br />
2. 设置preference的值</p>
<li><span style="color:blue">-literal</span></li>
<p>缩写-l</p>
<li><span style="color:blue">-modes</span></li>
<p>缩写-m或者-mode<br />
用于指定当前键映射使用的模式。<br />
使用该参数就可以用map命令表达所有的键映射命令，避免记忆不同模式下的映射命令。<br />
比如</p>
<pre class="brush: jscript; title: ; notranslate">map -m=i 等价于 imap
map -m=c {lhs} -builtin {rhs} 等价于 cnoremap</pre>
<p>其实，如果你在命令行用imap这种模式专用映射命令映射键后，保存到rc文件，然后再查看rc文件里的内容就会发现：最后所有的键映射都会转化成map加-modes的形式保存。</p>
<p>另外，在命令行下，-m=后autocomplete会提示出目前pentadactyl支持的所有模式，</p>
<li><span style="color:blue">-nopersist</span></li>
<p>缩写-n<br />
一般的map可以通过:mkpentadactyl!保存到rc文件中，以便以后使用。而使用-nopersist的映射即使使用保存命令也不会保存到rc文件，所以可以使用该参数来临时测试键映射。</p>
<pre class="brush: jscript; title: ; notranslate">:map x -nopersist -js alert('test')
:mkpentadactyl!
:rc
</pre>
<p>比如，临时映射一个测试用的键<span class="keys">x</span>，然后使用mkp命令保存，最后使用rc命令查看，会发现rc文件中并没有该定义，而且如果重启，再按x也不会有alert字符串test的效果了。</p>
<li><span style="color:blue">-silent</span></li>
<p>缩写-s
</ol>
</li>
<li><a name="pres"><span style="color:black"><strong>键表示</strong></span></a><br />
键映射中的键如何表示呢：</p>
<ul>
<li>键盘上对应可打印字符的一般键，直接用对应的字符表示即可。如<span class="keys">a,9,]</span>等</li>
<li>功能键F1-F2表示成<span class="keys">&lt;F1&gt; &lt;F12&gt;</span></li>
<li>数字键盘上的数字表示成<span class="keys">&lt;K0&gt; &lt;K9&gt;</span></li>
<li>方向键表示成<span class="keys">&lt;Left&gt; &lt;Right&gt; &lt;Up&gt; &lt;Down&gt;</span></li>
<li>退格键表示成<span class="keys">&lt;BS&gt;</span></li>
<li>回车键表示成<span class="keys">&lt;Return&gt;</span>或者<span class="keys">&lt;CR&gt;</span></li>
<li>空格键表示成<span class="keys">&lt;Space&gt;</span></li>
<li>其他功能键<span class="keys">&lt;CapsLock&gt; &lt;NumLock&gt; &lt;Insert&gt; &lt;Del&gt; &lt;Tab&gt; &lt;PageUp&gt; &lt;PageDown&gt; &lt;Esc&gt;</span></li>
<li>unicode表示法<span class="keys">&lt;Uxxxx&gt;</span> xxxx对应字符的unicode</li>
<li>组合键表示成<span class="keys">&lt;C-␣&gt; &lt;A-␣&gt; &lt;M-␣&gt; &lt;S-␣&gt;</span><br />
组合键可以互相组合，如ctrl+alt+j表示成<span class="keys">&lt;C-A-j&gt;</span></li>
</ul>
<p>
其他，还有一些伪键</p>
<ul>
<li><span class="keys">&lt;Nop&gt;</span>表示什么都不做<br />
:map &lt;C-n&gt; &lt;Nop&gt;表示按ctrl+n什么都不干，相当于disable了ctrl+n
</li>
<li><span class="keys">&lt;Pass&gt;</span>表示把映射的键直接传递给firefox，不按pentadactyl中的逻辑执行<br />
:map &lt;C-c&gt; &lt;Pass&gt;即可映射ctrl+c为复制，因为直接传递ctrl+c给firefox，而在firefox中ctrl+c是用于复制的键
</li>
<li><span class="keys">&lt;CR&gt;</span> TODO</li>
<li><span class="keys">&lt;Leader&gt;</span> TODO</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2011/04/firefox/pentadactylkeymapping/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>[KeySnail]编辑模式下使用可输入字符作为快捷键</title>
		<link>http://www.slimeden.com/2011/03/firefox/keysineditmode</link>
		<comments>http://www.slimeden.com/2011/03/firefox/keysineditmode#comments</comments>
		<pubDate>Sat, 26 Mar 2011 05:17:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[firefox]]></category>
		<category><![CDATA[firefox4]]></category>
		<category><![CDATA[key]]></category>
		<category><![CDATA[keybidding]]></category>
		<category><![CDATA[keysnail]]></category>
		<category><![CDATA[shortcut]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=225</guid>
		<description><![CDATA[在KeySnail中可以针对编辑模式（Edit Mode）设置快捷键，但是一般我们都不会设置“使用可输入字符”的键，因为设置后就不能输入相应的字符。
下面这个KeySnail插件，可以在编辑模式下支持使用“可输入字符”的键。
<a href='http://www.slimeden.com/wp-content/uploads/2011/03/keysInEditMode.ks.js'>keysInEditMode.ks</a>
安装后，新建一个编辑模式下的命令（比如ctrl+i)，填上如下代码
try {
var prefService = Cc['@mozilla.org/preferences-service;1'].getService(Ci.nsIPrefService).getBranch(&#34;extensions.keysnail.&#038;quo[......]<p class='read-more'><a href='http://www.slimeden.com/2011/03/firefox/keysineditmode'>阅读全文</a></p>]]></description>
			<content:encoded><![CDATA[<p>在KeySnail中可以针对编辑模式（Edit Mode）设置快捷键，但是一般我们都不会设置“使用可输入字符”的键，因为设置后就不能输入相应的字符。</p>
<p>下面这个<span style="color:red">KeySnail插件</span>，可以在编辑模式下支持使用“可输入字符”的键。</p>
<p><a href='http://www.slimeden.com/wp-content/uploads/2011/03/keysInEditMode.ks.js'>keysInEditMode.ks</a><br />
安装后，新建一个编辑模式下的命令（比如ctrl+i)，填上如下代码</p>
<pre class="brush: jscript; title: ; notranslate">try {
var prefService = Cc['@mozilla.org/preferences-service;1'].getService(Ci.nsIPrefService).getBranch(&quot;extensions.keysnail.&quot;);
var statusPrefName = &quot;enabeKeyInEditMode&quot;;
try {
    var status = prefService.getBoolPref(statusPrefName);
    prefService.setBoolPref(statusPrefName, !status);
} catch (e) {
    prefService.setBoolPref(statusPrefName, true);
}
if (prefService.getBoolPref(statusPrefName)) {
    ev.target.addEventListener(&quot;blur&quot;, function (e) {
        this.removeEventListener(&quot;blur&quot;, arguments.callee, false);
        prefService.setBoolPref(statusPrefName, false);
        ev.target.ksMarked = false;
    },
    false);
}
} catch (e) {}
</pre>
<p>这个就是在编辑模式下开启使用可输入字符键命令的开关。</p>
<p>当在编辑模式下（处于可输入区域），ctrl+i就会打开可输入字符键命令模式，这个时候按键会执行定义的快捷键逻辑，而不是输入字符，如果未定义，则输入相应字符。再次按ctrl+i切换回输入模式。</p>
<p>进入编辑区域后，如果未开启该命令模式按单键，也不会像KeySnail默认行为那样执行预定义快捷键命令，导致不能输入字符。</p>
<p>另外，该命令模式会在光标离开输入区域后自动关闭。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
下面是一些编辑模式下可用的代码<br />
<span style="color:blue">ESC &#8211; 关闭可输入字符键命令模式</span></p>
<pre class="brush: jscript; title: ; notranslate">try {
var prefService = Cc['@mozilla.org/preferences-service;1'].getService(Ci.nsIPrefService).getBranch(&quot;extensions.keysnail.&quot;);
var statusPrefName = &quot;enabeKeyInEditMode&quot;;
prefService.setBoolPref(statusPrefName, false);
ev.target.ksMarked = false;
 } catch (e) {}
</pre>
<p><span style="color:blue">v &#8211; toggle visual mode in edit mode</span></p>
<pre class="brush: jscript; title: ; notranslate">ev.target.ksMarked = !ev.target.ksMarked;
</pre>
<p><span style="color:blue">j &#8211; 光标下移一行</span></p>
<pre class="brush: jscript; title: ; notranslate">ev.target.ksMarked?goDoCommand(&quot;cmd_selectLineNext&quot;):goDoCommand(&quot;cmd_lineNext&quot;);
</pre>
<p><span style="color:blue">k &#8211; 光标上移一行</span></p>
<pre class="brush: jscript; title: ; notranslate">ev.target.ksMarked?goDoCommand(&quot;cmd_selectLinePrevious&quot;):goDoCommand(&quot;cmd_linePrevious&quot;);
</pre>
<p><span style="color:blue">h &#8211; 光标左移一个字符</span></p>
<pre class="brush: jscript; title: ; notranslate">ev.target.ksMarked?goDoCommand(&quot;cmd_selectCharPrevious&quot;):goDoCommand(&quot;cmd_charPrevious&quot;);</pre>
<p><span style="color:blue">l &#8211; 光标右移一个字符</span></p>
<pre class="brush: jscript; title: ; notranslate">ev.target.ksMarked?goDoCommand(&quot;cmd_selectCharNext&quot;):goDoCommand(&quot;cmd_charNext&quot;);</pre>
<p><span style="color:blue">u &#8211; undo</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_undo&quot;);
</pre>
<p><span style="color:blue">r &#8211; redo</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_redo&quot;);
</pre>
<p><span style="color:blue">x &#8211; 删除一个字符</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_cutOrDelete&quot;);
</pre>
<p><span style="color:blue">X &#8211; 反向删除一个字符</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_deleteCharBackward&quot;);
</pre>
<p><span style="color:blue">dd &#8211; 删除整行</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_beginLine&quot;);
goDoCommand(&quot;cmd_selectLineNext&quot;);
goDoCommand(&quot;cmd_cutOrDelete&quot;);</pre>
<p><span style="color:blue">d^ &#8211; 从当前位置删除到行首</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_deleteToBeginningOfLine&quot;);</pre>
<p><span style="color:blue">d$ &#8211; 从当前位置删除到行尾</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_deleteToEndOfLine&quot;);</pre>
<p><span style="color:blue">^ &#8211; 移到行首</span></p>
<pre class="brush: jscript; title: ; notranslate">ev.target.ksMarked?goDoCommand(&quot;cmd_selectBeginLine&quot;):goDoCommand(&quot;cmd_beginLine&quot;);
</pre>
<p><span style="color:blue">$ &#8211; 移到行尾</span></p>
<pre class="brush: jscript; title: ; notranslate">ev.target.ksMarked?goDoCommand(&quot;cmd_selectEndNext&quot;):goDoCommand(&quot;cmd_endLine&quot;);
</pre>
<p><span style="color:blue">gg &#8211; 移到最开始</span></p>
<pre class="brush: jscript; title: ; notranslate">ev.target.ksMarked?goDoCommand(&quot;cmd_selectTop&quot;):goDoCommand(&quot;cmd_moveTop&quot;);
</pre>
<p><span style="color:blue">G &#8211; 移到最后</span></p>
<pre class="brush: jscript; title: ; notranslate">ev.target.ksMarked?goDoCommand(&quot;cmd_selectBottom&quot;):goDoCommand(&quot;cmd_moveBottom&quot;);
</pre>
<p><span style="color:blue">复制选中内容</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_copy&quot;);
</pre>
<p><span style="color:blue">yy &#8211; 复制整行</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_beginLine&quot;);
goDoCommand(&quot;cmd_selectLineNext&quot;);
goDoCommand(&quot;cmd_copy&quot;);</pre>
<p><span style="color:blue">y^ &#8211; 从当前位置复制到行首</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_selectBeginLine&quot;);
goDoCommand(&quot;cmd_copy&quot;);</pre>
<p><span style="color:blue">y$ &#8211; 从当前位置复制到行尾</span></p>
<pre class="brush: jscript; title: ; notranslate">gDoCommand(&quot;cmd_selectEndLine&quot;);
goDoCommand(&quot;cmd_copy&quot;);</pre>
<p><span style="color:blue">p &#8211; 黏贴</span></p>
<pre class="brush: jscript; title: ; notranslate">goDoCommand(&quot;cmd_paste&quot;);
</pre>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
最后，KeySnail最好关闭这个preference项 &#8211; false</p>
<pre class="brush: jscript; title: ; notranslate">extensions.keysnail.keyhandler.global_enabled</pre>
<p>避免在其他的chrome窗口输入信息时出问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2011/03/firefox/keysineditmode/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>pentadactyl试用记</title>
		<link>http://www.slimeden.com/2011/03/firefox/pentadactyl</link>
		<comments>http://www.slimeden.com/2011/03/firefox/pentadactyl#comments</comments>
		<pubDate>Tue, 22 Mar 2011 13:18:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[firefox]]></category>
		<category><![CDATA[add-on]]></category>
		<category><![CDATA[dactyl]]></category>
		<category><![CDATA[firefox4]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[pentadactyl]]></category>
		<category><![CDATA[vi]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimperator]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=223</guid>
		<description><![CDATA[20110512更新 &#8211; 更新6. UI设置
Pentadactyl 是由 Vimperator 项目最活跃的开发者 Kris Maglione、Doug Kearns、Martin Stubenschrott维护的针对 Firefox4的一个分支。
官方介绍：
Pentadactyl is a free browser add-on for Firefox, designed to make browsing more efficient and especially more keyboard accessible. Largely inspired by the Vim te[......]<p class='read-more'><a href='http://www.slimeden.com/2011/03/firefox/pentadactyl'>阅读全文</a></p>]]></description>
			<content:encoded><![CDATA[<blockquote><p><span style="background-color: #eff3ff; color: red;">20110512更新 &#8211; 更新6. UI设置</span></p></blockquote>
<p>Pentadactyl 是由 Vimperator 项目最活跃的开发者 Kris Maglione、Doug Kearns、Martin Stubenschrott维护的针对 Firefox4的一个分支。</p>
<p>官方介绍：</p>
<blockquote><p>Pentadactyl is a free browser add-on for Firefox, designed to make browsing more efficient and especially more keyboard accessible. Largely inspired by the Vim text editor, the appearance and finger feel of Pentadactyl should be familiar to Vim users.</p>
<p>Dactyl is a fork of the Vimperator project by most of its primary developers. </p></blockquote>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
目录：<br />
1. <a href="#install">安装</a></p>
<p style="padding-left: 30px;">1.1 <a href="#profile">新建个profile</a><br />
1.2 <a href="#quicklink">创建一个新的启动快捷方式</a><br />
1.3 <a href="#installaddon">安装pentadactyl扩展</a>
</p>
<p>2. </a><a href="#config">配置</a></p>
<p style="padding-left: 30px;">2.1 <a href="#startup">启动</a><br />
2.2 <a href="#createrc">生成rc文件</a><br />
2.3 <a href="#saverc">保存配置到rc文件</a><br />
2.4 <a href="#viewrc">查看_pentadactylrc文件内容</a><br />
2.5 <a href="#editrc">直接编辑_pentadactylrc文件</a><br />
2.6 <a href="#switchrc">多套配置切换</a><br />
2.7 <a href="#viewrcpath">查看当前生效的配置文件路径</a>
</p>
<p>3. <a href="#command">熟悉基本键和命令</a></p>
<p style="padding-left: 30px;">
3.1 <a href="#ctrlcv">支持ctrl+c/v</a><br />
3.2 <a href="#tabs">标签操作</a></p>
<p style="padding-left: 50px;">
3.2.1 <a href="#tabopen">打开标签</a><br />
3.2.2 <a href="#tabclose">关闭标签</a><br />
3.2.3 <a href="#tabpin">Lock/Protect/Pin标签</a><br />
3.2.4 <a href="#tabmove">移动标签</a>
</p>
<p style="padding-left: 30px;">
3.3 <a href="#pageview">页面浏览</a><br />
3.4 <a href="#search">搜索</a></p>
<p style="padding-left: 50px;">
3.4.1 <a href="#normalsearch">一般搜索</a><br />
3.4.2 <a href="#sitesearch">站内搜索</a><br />
3.4.3 <a href="#pagefind">页面搜索</a>
</p>
<p style="padding-left: 30px;">
3.5 <a href="#buffer">缓冲区</a></p>
<p style="padding-left: 50px;">
3.5.1 <a href="#bufferinfo">查看缓冲区信息</a><br />
3.5.2 <a href="#bufferurl">复制缓冲区对应的页面地址</a><br />
3.5.3 <a href="#bufferlist">缓冲区列表（支持filter标签）</a>
</p>
<p style="padding-left: 30px;">
3.6 <a href="#bookmarks">书签</a>
</p>
<p>4. <a href="#hints">Hints</a></p>
<p style="padding-left: 30px;">
4.1 <a href="#hintmodes">Hint模式</a></p>
<p style="padding-left: 50px;">
4.1.1 <a href="#qh">Quick Hint</a><br />
4.1.2 <a href="#sqh">Shift Quick Hint</a><br />
4.1.3 <a href="#eh">Extended Hint</a><br />
4.1.4 <a href="#peh">Persisted Extended Hint</a><br />
4.1.5 <a href="#ch">Caret Hint</a>
</p>
</p>
<p style="padding-left: 30px;">
4.2 <a href="#hintoptions">相关配置项</a>
</p>
<p>5. <a href="#options">options设置</a><br />
6. <a href="#ui">UI设置</a></p>
<p style="padding-left: 30px;">
6.1 <a href="#go">guioptions</a><br />
6.2 <a href="#statusline">状态栏</a><br />
6.3 <a href="#gui">命令行访问GUI</a>
</p>
<p>7. <a href="#plugins">plugins插件</a></p>
<p style="padding-left: 30px;">
7.1 <a href="#pluginsplace">插件存放</a><br />
7.2 <a href="#pluginsload">插件加载</a><br />
7.2 <a href="#pluginssuggest">插件推荐</a>
</p>
<p>8. <a href="#reference">相关资料和站点</a><br />
9. <a href="#css">to do</a><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
使用手记：</p>
<ul>
<li><a name="install"><span style="color:black"><strong>安装</strong></span></a>
<ol>
<li><a name="profile"><span style="color:black">新建一个profile</span></a><br />
使用profile manager创建一个新的profile &#8211; pentadactyl</p>
<pre class="brush: jscript; title: ; notranslate">firefox.exe -profilemanager</pre>
<p>与原来的profile共存一起用
</li>
<li><a name="quicklink"><span style="color:black">创建一个新的启动快捷方式</span></a><br />
使用如下启动参数启动pentadactyl的profile</p>
<pre class="brush: jscript; title: ; notranslate">-no-remote -P pentadactyl -pentadactyl &quot;++cmd 'js services.environment.set(&quot;HOME&quot;, services.directory.get(&quot;ProfD&quot;, Ci.nsIFile).path)&quot;'</pre>
<p>-P指定profile为pentadactyl<br />
-pentadactyl是用来配置pentadactyl扩展的参数，后面再说<br />
到这就可以用这个快捷方式启动pentadactyl专用的firefox了
</li>
<li><a name="installaddon"><span style="color:black">安装pentadactyl扩展</span></a>
<ul>
<li>mozilla的add-on站，<a href="https://addons.mozilla.org/de/firefox/addon/pentadactyl/">下载页面</a></li>
<li>扩展主页 &#8211; <a href="http://dactyl.sourceforge.net/pentadactyl/">pentadactyl</a></li>
<li>googlecode页面 &#8211; 1.0b6，<a href="http://dactyl.googlecode.com/files/pentadactyl-1.0b6.xpi">点击安装</a></li>
<li>每夜版的<a href="http://code.google.com/p/dactyl/downloads/list">下载目录</a></li>
</ul>
</li>
</ol>
</li>
<li><a name="config"><span style="color:black"><strong>配置</strong></span></a>
<ol>
<li><a name="startup"><span style="color:black">启动</span></a></li>
<p>pentadactyl跟vim一样有rc文件用来保存配置，在扩展启动时读取，这样我们辛苦做的配置工作就不会白费。<br />
由于用的firefox是绿色便携的，所以希望rc文件也能便携，并且我准备放到新建的profile目录里，便于维护。</p>
<pre class="brush: jscript; title: ; notranslate">-pentadactyl &quot;++cmd 'js services.environment.set(\&quot;HOME\&quot;, services.directory.get(\&quot;ProfD\&quot;, Ci.nsIFile).path)'&quot;</pre>
<p>或者</p>
<pre class="brush: jscript; title: ; notranslate">-pentadactyl &quot;++cmd 'js services.environment.set(''HOME'', services.directory.get(''ProfD'', Ci.nsIFile).path)'&quot;</pre>
<p>（这两种是比较通用的写法，更多的参见<a href="http://g.mozest.com/thread-38789-1-1">这贴</a>的讨论）</p>
<p>前面提到的firefox启动参数中有这么一段，这是pentadactyl用的启动参数。<br />
++cmd用来在pentadactyl做初始化工作前执行Ex命令。</p>
<pre class="brush: jscript; title: ; notranslate">'js services.environment.set(&quot;HOME&quot;, services.directory.get(&quot;ProfD&quot;, Ci.nsIFile).path)'</pre>
<p>这个执行的Ex命令就是设置系统的环境变量$HOME为profile目录。<br />
这样pentadactyl就可以在初始化时从profile目录去读取rc文件了。<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; 感谢<span style="color: #ff9900;">tuantuan</span>的指点</p>
<p>关于更多-pentadactyl的启动参数，请查看帮助</p>
<pre class="brush: jscript; title: ; notranslate">:help startup-options</pre>
<li><a name="createrc"><span style="color:black">生成rc文件</span></a></li>
<pre class="brush: jscript; title: ; notranslate">:mkp</pre>
<p>这个命令会在$HOME（现在就是profile目录）下生成_pentadactylrc配置文件用于保存配置<br />
（mkp &#8211; make pentadactyl rc file，vimperator下是mkv[imperator]，害得我试了半天=_=|||）</p>
<li><a name="saverc"><span style="color:black">保存配置到rc文件</span></a></li>
<p>以后如果更改了配置，可以通过下面的命令将更新保存到刚才生成的rc文件中</p>
<pre class="brush: jscript; title: ; notranslate">:mkpentadactylrc!</pre>
<p><span style="color:red">问题？？</span><br />
mkp!似乎只能覆盖保存当前键映射和设置的options到rc文件中，所以如果原来在_pentadactylrc文件中手动添加了其他内容，比如javascript代码，mkp!后这些内容不会重新写入到新的_pentadactylrc里。</p>
<li><a name="viewrc"><span style="color:black">查看_pentadactylrc文件内容</span></a></li>
<p>自定义一个Ex命令(:rc)，用来在firefox中直接用新tab查看rc文件内容</p>
<pre class="brush: jscript; title: ; notranslate">:com! rc -description &quot;Open _pentadactylrc file&quot; -js gBrowser.selectedTab = gBrowser.addTab(&quot;file:///&quot;+Components.classes[&quot;@mozilla.org/file/directory_service;1&quot;].getService(Components.interfaces.nsIProperties).get(&quot;ProfD&quot;, Components.interfaces.nsIFile).path+&quot;/_pentadactylrc&quot;);</pre>
<li><a name="editrc"><span style="color:black">直接编辑_pentadactylrc文件</span></a></li>
<p>自定义一个Ex命令(:erc)，用来通过外部编辑器直接编辑rc文件</p>
<pre class="brush: jscript; title: ; notranslate">:com! erc -description &quot;Edit _pentadactylrc file&quot; -js editor.editFileExternally(Components.classes[&quot;@mozilla.org/file/directory_service;1&quot;].getService(Components.interfaces.nsIProperties).get(&quot;ProfD&quot;, Components.interfaces.nsIFile).path+&quot;\\_pentadactylrc&quot;)</pre>
<p><span style="color:red">【注意！！】</span><br />
直接编辑rc文件不能生效（如果这时候用:mkpentadactyl!命令保存设置会覆盖刚才直接编辑更改的内容），需要重新载入。<br />
可以用:rehash命令</p>
<pre class="brush: jscript; title: ; notranslate">:rehash</pre>
<p>rehash命令会重新load整个扩展，或者用下面的命令只重新load rc文件</p>
<pre class="brush: jscript; title: ; notranslate">:source $HOME/_pentadactylrc</pre>
<p>为此我重新定义了Ex命令 &#8211; fresh</p>
<pre class="brush: jscript; title: ; notranslate">:com! fresh -description &quot;Reload _pentadactyl rc file&quot; source $HOME/_pentadactylrc</pre>
<p><span style="color:red">【推荐】</span><br />
另外，如果编辑器用的是vim，可以导出pentadactyl的语法文件到vim，使vim编辑rc文件时可以语法高亮。</p>
<pre class="brush: jscript; title: ; notranslate">:mks!</pre>
<p>生成pentadactyl的语法文件pentadactyl.vim。<br />
（mks命令可以指定生成的语法文件的保存路径。不指定的话会自动识别vim的runtime路径，如果vim安装时注册表没问题，会在syntax文件夹下生成语法文件；否则的话，可能会在pentadactyl的runtime路径下生成，需要手动拷到vim的syntax文件夹下）</p>
<p>生成了语法文件后，在vim的rc文件中配置如下内容</p>
<pre class="brush: jscript; title: ; notranslate">au BufRead,BufNewFile _pentadactylrc set filetype=pentadactyl
au! Syntax pentadactyl source ~/syntax/pentadactyl.vim</pre>
<p>再用vim打开_pentadactylrc时即可开启语法高亮。</p>
<li><a name="switchrc"><span style="color:black">多套配置切换</span></a></li>
<p>用下面的命令可以实现多套配置热切换（无须重启firefox）</p>
<pre class="brush: jscript; title: ; notranslate">:js services.environment.set(&quot;HOME&quot;, &quot;another home path&quot;)
:rehash
</pre>
<p>rehash用于重新加载pentadactyl扩展，包含扩展的所有初始化代码，plugins以及配置。</p>
<li><a name="viewrcpath"><span style="color:black">查看当前生效的配置文件路径</span></a></li>
<pre class="brush: jscript; title: ; notranslate">:scriptnames</pre>
<p>这个命令会按顺序列出所有被source的脚本文件的绝对路径，其中第一个就是rc文件。
</ol>
</li>
</ol>
</li>
<li><a name="command"><span style="color:black"><strong>熟悉基本键和命令</strong></span></a><br />
开始折腾键和命令之前，先设置如下CSS</p>
<pre class="brush: jscript; title: ; notranslate">:style chrome://* #dactyl-commandline-command input {ime-mode: inactive;}
:style chrome://* #dactyl-statusline-field-commandline-command input {ime-mode: inactive;}
</pre>
<p>保证进入命令行时输入法是disable的，这样方便输入命令。（注意这个css在linux下不支持 &#8211; ime-mode: inactive）</p>
<p>关于键命令的使用方法，参见另一篇<a href="http://www.slimeden.com/2011/04/firefox/pentadactylkeymapping">Pentadactyl键详解</a></p>
<ol>
<li><a name="ctrlcv"><span style="color:black">支持ctrl+c/ctrl+v</span></a></li>
<p>pentadactyl为了还原vim的操作体验，几乎重新定义了firefox所有的快捷键，甚至包括终极创新之法ctrl+c/ctrl+v<br />
下面的命令可以找回我们熟悉的这套快捷键。</p>
<p><span style="color:blue">ctrl+c复制</span></p>
<pre class="brush: jscript; title: ; notranslate">:noremap &lt;C-c&gt; &lt;C-v&gt;&lt;C-c&gt;</pre>
<p>noremap命令是用来映射键的，这行的意思是重新定义键ctrl+c为pentadactyl中的键序列ctrl+v，ctrl+c<br />
在pentadactyl中，ctrl+v是用于直接传递后续按键给firefox，所以这个按键序列就相当于在firefox按ctrl+c，这样就实现了firefox原来的ctrl+c复制功能。</p>
<p>这里要用noremap而不能是普通的map命令，因为这条映射的目标定义键（ctrl+c）和使用的实现键（ctrl+v ctrl+c）里面都有ctrl+c，用一般的map的话，实现键里面的键会使用用户定义键，这样就会导致无限递归。而用noremap命令的话，实现键序列中的键只会用系统定义键。（noremap等价于使用-builtin参数的map）</p>
<p>采用未加模式前缀的noremap命令，可以支持normal和visual模式。<br />
所以这条命令等价于</p>
<pre class="brush: jscript; title: ; notranslate">:nnoremap &lt;C-c&gt; &lt;C-v&gt;&lt;C-c&gt;
:vnoremap &lt;C-c&gt; &lt;C-v&gt;&lt;C-c&gt;
</pre>
<p>这样还剩下insert和command line模式</p>
<pre class="brush: jscript; title: ; notranslate">:inoremap &lt;C-c&gt; &lt;C-v&gt;&lt;C-c&gt;
:cnoremap &lt;C-c&gt; &lt;C-v&gt;&lt;C-c&gt;
</pre>
<p>或者用这一条命令，它包含了上面这几条映射。</p>
<pre class="brush: jscript; title: ; notranslate">:map -modes=n,v,i,c &lt;C-c&gt; -builtin &lt;C-v&gt;&lt;C-c&gt;</pre>
<p>到这里，ctrl+c就已经找回来，别忘了用mkp保存到rc文件。</p>
<p><span style="color:blue">ctrl+v黏贴</span><br />
ctrl+v只有在insert和command line才需要</p>
<pre class="brush: jscript; title: ; notranslate">:inoremap &lt;C-v&gt; &lt;C-v&gt;&lt;C-v&gt;
:cnoremap &lt;C-v&gt; &lt;C-v&gt;&lt;C-v&gt;
</pre>
<p><span style="color:blue">ctrl+x剪切</span></p>
<pre class="brush: jscript; title: ; notranslate">:inoremap &lt;C-x&gt; &lt;C-v&gt;&lt;C-x&gt;
:cnoremap &lt;C-x&gt; &lt;C-v&gt;&lt;C-x&gt;
</pre>
<p><span style="color:blue">ctrl+z撤销</span>jj</p>
<pre class="brush: jscript; title: ; notranslate">:inoremap &lt;C-z&gt; &lt;C-v&gt;&lt;C-z&gt;
:cnoremap &lt;C-z&gt; &lt;C-v&gt;&lt;C-z&gt;
</pre>
<p><span style="color:blue">ctrl+a全选</span></p>
<pre class="brush: jscript; title: ; notranslate">:noremap &lt;C-a&gt; &lt;C-v&gt;&lt;C-a&gt;
:inoremap &lt;C-a&gt; &lt;C-v&gt;&lt;C-a&gt;
:cnoremap &lt;C-a&gt; &lt;C-v&gt;&lt;C-a&gt;
</pre>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
其实，pentadactyl中给map相关命令引入了一个特殊字符  &#8211; &lt;Pass&gt;<br />
这个特殊字符可以把前面mapping的键直接传给firefox，所以上面的可以统一写成</p>
<pre class="brush: jscript; title: ; notranslate">map -m n,v,i,c,t &lt;C-a&gt; &lt;Pass&gt;
map -m n,v,i,c,t &lt;C-c&gt; &lt;Pass&gt;
map -m i,c,t &lt;C-v&gt; &lt;Pass&gt;
map -m i,c,t &lt;C-x&gt; &lt;Pass&gt;
map -m i,c,t &lt;C-z&gt; &lt;Pass&gt;
</pre>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; 感谢<span style="color: #ff9900;">harnack</span>的指点</p>
<li><a name="tabs"><span style="color:black">标签操作</span></a></li>
<p><a name="tabselect"><span style="color:blue">标签选择</span></a></p>
<pre class="brush: jscript; title: ; notranslate">Ctrl+n(ext) -下一个标签
Ctrl+p(revious) - 上一个标签
gt - 下一个标签
gT - 上一个标签
g0 - 第一个标签
g^ - 第一个标签
g$ - 最后一个标签
</pre>
<p>这一套键跟vim是一样的，可以看出来按键是按照表意来设计的，容易记，但是我一直都用不惯，按起来不舒服。<br />
在浏览器下，标签切换频繁，操作一定要方便，所以回头还得重新进行键绑定。</p>
<pre class="brush: jscript; title: ; notranslate">Ctrl+^</pre>
<p>切换到上次选的标签，连续使用可以实现在两个标签间切换。</p>
<pre class="brush: jscript; title: ; notranslate">[count]b - 切换到第[count]个标签</pre>
<p>比如：1b就跟g0是一样的效果，切换到第一个标签。<br />
单独按一个b可以列出所有的标签，然后通过(shift+)tab也可以在标签间切换。<br />
单独b后空格，跟URL或者keyword，就是swith-to-tab功能。<br />
其实这里的b是buffer的意思，是pentadactyl中很重要的一个概念，回头细讲。</p>
<p><a name="tabopen"><span style="color:blue">打开标签</span></a><br />
最基本的几个命令</p>
<pre class="brush: jscript; title: ; notranslate">o - 在当前tab打开 - o(pen)
t - 在新tab打开 - t(abopen)
w - 在新窗口打开 - w(inopen)
</pre>
<p>支持打开单个URL，多个URLs（URL之间的分隔符可以通过配置项urlseparator设置），书签（关键字），指定搜索引擎搜索，用默认搜索引擎搜索（默认引擎通过配置项defsearch设置）；<br />
另外打开命令还提供了非常强大的completion（细节请查阅配置项complete和autocomplete）</p>
<pre class="brush: jscript; title: ; notranslate">p - 用剪切板的内容在当前标签打开
P - 这个是新开标签
</pre>
<p>剪切板中的内容如果是URL，就按地址打开，否则搜索（用默认的搜索引擎）。<br />
这里我交换两个键的定义，一般我喜欢新开标签</p>
<pre class="brush: jscript; title: ; notranslate">noremap p P
noremap P p
</pre>
<p>复制当前标签</p>
<pre class="brush: jscript; title: ; notranslate">:tabdu[plicate]
T&lt;CR&gt;
</pre>
<p>最好配上<a href="http://www.slimeden.com/wp-content/uploads/2010/08/openTabNextToCurrent.uc.js">openTabNextToCurrent.uc.js</a>脚本，要不复制的标签追加在最后，很别扭。<br />
<a name="tabclose"><span style="color:blue">关闭标签</span></a></p>
<pre class="brush: jscript; title: ; notranslate">d - 关闭当前标签并选中右边的
D - 关闭当前标签并选中左边的
</pre>
<p>像vim一样，命令前可以加数量前缀指定关闭的标签数，比如2d &#8211; 从当前标签开始关闭2个</p>
<pre class="brush: jscript; title: ; notranslate">:tabc(lose)</pre>
<p>拜completion之福这个命令可以看到所有的标签，用(shift+)tab选择关闭。（这个挺有用的，我经常会不知不觉就开了几十个标签，用这个选择关闭很方便）</p>
<p>这个命令后面可以跟参数keyword，这样会关闭所有主机名包含keyword的标签。<br />
比如，我针对baidu开了很多标签，用这个命令:tabc baidu就可以一次性把baidu的标签都关闭。<br />
如果加上!，:tabc!不仅用主机名来匹配关键字，还会匹配URL和title。</p>
<pre class="brush: jscript; title: ; notranslate">:tabo(nly)</pre>
<p>关闭当前标签之外的所有标签</p>
<pre class="brush: jscript; title: ; notranslate">u - 恢复一个已关闭标签 - 可以加[count]前缀指定恢复第几个
:undoa[ll] - 恢复closed标签列表中的所有标签
</pre>
<p><a name="tabpin"><span style="color:blue">Lock/Protect/Pin标签</span></a><br />
这个是不是pentadactyl还不支持。</p>
<p>(un)pin在1.0b6中不支持，每夜版可以，感谢<span style="color: #ff9900;">harnack</span>指出</p>
<pre class="brush: jscript; title: ; notranslate">:pin
:unpin
:pin! 这个是切换pin状态
</pre>
<p><a name="tabmove"><span style="color:blue">移动标签</span></a></p>
<pre class="brush: jscript; title: ; notranslate">:tabm[ove][!] [+N] | [-N]
:tabm 0                 - 移到第一位
:tabm                    - 移到最后一位
:tabm 4                 - 移到第4个标签后面， 就是变成第5个
:tabm -1                - 向前移动1位
:tabm +2               - 向后移动2位
</pre>
<p>指定N的话，是移到第N个标签的后面，就是成为第N+1个<br />
N加+/-号的话，是相对移动。<br />
tabm!，命令加!，移动时到边界了会循环，默认时不循环。</p>
<li><a name="pageview"><span style="color:black">页面浏览</span></a></li>
<pre class="brush: jscript; title: ; notranslate">   k
 h   l
   j
</pre>
<p>最基本的上下左右，熟悉vim的都用惯了。<br />
但是浏览时，一行一行移有点慢，重新定义下多移几行</p>
<pre class="brush: jscript; title: ; notranslate">:noremap j 5j
:noremap k 5k
</pre>
<p>另外h和l基本上也是用不到的，我重新映射成“切换到前/后一个标签页”</p>
<pre class="brush: jscript; title: ; notranslate">:map -m=n h -builtin &lt;count&gt;gT
:map -m=n l -builtin &lt;count&gt;gt</pre>
<pre class="brush: jscript; title: ; notranslate">ctrl+b 向上滚一屏
ctrl+f 向下滚一屏
ctrl+u 向上滚半屏
ctrl+d 向下滚半屏
</pre>
<p>如果scroll配置项设置了非0值，ctrl+u/d按scroll行来滚屏</p>
<pre class="brush: jscript; title: ; notranslate">gg 滚屏到页面顶端
G 滚屏到页面底部
50% 按百分比滚屏
0 屏幕左移到头
^ 屏幕左移到头
$ 屏幕右移到头
</pre>
<li><a name="search"><span style="color:black">搜索</span></a></li>
<p>首先清理搜索引擎列表</p>
<pre class="brush: jscript; title: ; notranslate">:dialog searchengines</pre>
<p>打开firefox的搜索引擎编辑窗口，删除不用的引擎，并安装需要的<br />
最后保留</p>
<pre class="brush: jscript; title: ; notranslate">google - keyword: google
google ssl - g
baidu - b
</pre>
<p>设置默认引擎为google ssl</p>
<pre class="brush: jscript; title: ; notranslate">:set defsearch=google-ssl</pre>
<p><a name="normalsearch"><span style="color:blue">一般搜索</span></a></p>
<pre class="brush: jscript; title: ; notranslate">t keyword1 keyword2</pre>
<p>用默认引擎新开tab搜索</p>
<pre class="brush: jscript; title: ; notranslate">t b keyword1 keyword1</pre>
<p>用其他引擎（baidu已设搜索引擎关键字b）新开tab搜索</p>
<pre class="brush: jscript; title: ; notranslate">p</pre>
<p>如果已经复制了搜索关键字，直接p用默认引擎新开tab搜索（参考“打开标签”章节相关内容）</p>
<p>因为搜索挺频繁的，所以一定要简化操作<br />
<span style="color:red">【☆推荐】</span></p>
<pre class="brush: jscript; title: ; notranslate">:map t -js content.getSelection().toString()!=&quot;&quot;?dactyl.execute(&quot;:tabopen &quot;+ content.getSelection()):CommandExMode().open(&quot;tabopen &quot;)
:map o -js content.getSelection().toString()!=&quot;&quot;?dactyl.execute(&quot;:open &quot;+ content.getSelection()):CommandExMode().open(&quot;open &quot;)</pre>
<p>重定义t和o：<br />
如果有文字链接被选中，则直接打开链接；如果被选中的是一般文字，则用默认搜索引擎搜索；否则打开:tabopen或者:open命令行，手动输入关键字搜索。</p>
<p><span style="color:red">【☆推荐】</span><br />
网友<span style="color: #ff9900;">x</span>有一个搜索需求：如果选中的文字是空格分隔的多个关键字，则用默认搜索引擎开多个标签分别进行搜索<br />
首先rc文件中定义如下函数</p>
<pre class="brush: jscript; title: ; notranslate">javascript &lt;&lt;EOF
    dactyl.mulSearch = function() {
        let selection = content.getSelection().toString();
        if(!selection || /^\s*$/.test(selection)) {
            CommandExMode().open(&quot;tabopen &quot;);
        } else {
            let keywords = selection.replace(/^\s*/, &quot;&quot;).replace(/\s*$/, &quot;&quot;).split(/\s+/);
            keywords.forEach(function(keyword) {
                dactyl.execute(&quot;:tabopen &quot; + keyword);
            });
        }
    };
EOF
</pre>
<p>然后映射t为对应的功能键</p>
<pre class="brush: jscript; title: ; notranslate">:map t -js dactyl.mulSearch();</pre>
<p>对于有很多搜索引擎的用户，可能希望搜索时能够指定一下引擎。<br />
这两行命令映射S键：弹出搜索引擎列表，可以指定引擎搜索选中内容。<br />
<span style="color:red">【☆推荐】</span></p>
<pre class="brush: jscript; title: ; notranslate">:com! -nargs=? -complete=search engineSelect exe 't &lt;args&gt; ' + content.getSelection()
:map S :engineSelect&lt;Space&gt;
</pre>
<p>按了S后就能自己输入搜索引擎关键字（当然也可以在自动补全菜单里选择），如果不选直接回车就是用默认引擎（对于选中的恰好是链接的情况则是直接打开链接）  &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;by <span style="color: #ff9900;">harnack</span></p>
<p>还有一种搜索需求：当我用google搜索了一个内容后，可能还想再用baidu搜索一下，这时候我不想再重新输入一遍要搜索的内容，希望能够直接切换引擎搜索刚才的内容。<br />
<span style="color:red">【☆推荐】</span></p>
<pre class="brush: jscript; title: ; notranslate">:com! -nargs=? -complete=search switchenginesearch exe 'o &lt;args&gt; ' + (buffer.lastInputField?buffer.lastInputField.value:'')
:map s gi&lt;ESC&gt; :switchenginesearch&lt;Space&gt;
</pre>
<p>映射键s：在某个搜索引擎结果页面按s键，会弹出引擎列表，选中引擎直接更换引擎用当前搜索的内容重新搜索。</p>
<p><a name="sitesearch"><span style="color:blue">站内搜索</span></a><br />
定义一个Ex命令 &#8211; sitesearch，用google站内搜索API搜索当前站点</p>
<pre class="brush: jscript; title: ; notranslate">:com! -nargs=* sitesearch exe &quot;t http://www.google.com/search?q=&quot; + encodeURIComponent(&quot;&lt;args&gt;&quot;) + &quot;&amp;sitesearch=&quot; + window.content.location.hostname</pre>
<p>对应baidu的</p>
<pre class="brush: jscript; title: ; notranslate">:com! -nargs=* sitesearch exe &quot;t http://www.baidu.com/s?ie=utf-8&amp;word=&quot; + encodeURIComponent(&quot;&lt;args&gt; site:&quot; + window.content.location.hostname);</pre>
<p><a name="pagefind"><span style="color:blue">页面内搜索</span></a></p>
<pre class="brush: jscript; title: ; notranslate">/ 正向查找
? 反向查找
</pre>
<p>大小写是否敏感，可以通过findcase配置项设置（ignore，match）<br />
也可以通过在命令中加转义序列</p>
<pre class="brush: jscript; title: ; notranslate">\c 不敏感
\C 敏感
</pre>
<p>转义序列中还有</p>
<pre class="brush: jscript; title: ; notranslate">\l 只查找links</pre>
<p>另外，pentadactyl中查找都是从当前位置开始，不像firefox总是从头开始查找</p>
<p>可惜的是，目前还不支持正则表达式。</p>
<pre class="brush: jscript; title: ; notranslate">n 查找下一个
N 查找上一个
</pre>
<p>这里好像n/N并不会根据/?而变化，我记得vim中使用?查找后，再用n也是反向查找的。目前pentadactyl中，n永远是向下查找下一个。</p>
<pre class="brush: jscript; title: ; notranslate">* 直接向后查找当前光标下的单词
# 反向
</pre>
<p>这个命令不用选中文字，在单词上点击一下鼠标就可以开始查找了，非常方便，但中文下不太有用。</p>
<p><span style="color:green">-> 高亮</span><br />
通过下面两个配置项可以配置高亮规则</p>
<pre class="brush: jscript; title: ; notranslate">:set hlfind    所有的匹配都会高亮
:set nohlfind 只高亮当前匹配
</pre>
<p>自定义一个命令hl用来toggle高亮<br />
<span style="color:red">【☆推荐】</span></p>
<pre class="brush: jscript; title: ; notranslate">:command! hl set hlf!</pre>
<li><a name="buffer"><span style="color:black">缓冲区</span></a></li>
<p>缓冲区(buffer)是vim中的一个概念，最初vim编辑器是单窗口模式，但为了方便同时操作多个文件，采用了缓冲区。每一个文件对应一个缓冲区，里面存储着被打开的文件。这样，如果没有把缓冲区里的文件存盘，那么原始文件不会被更改。同时，可以通过切换缓冲区来实现通过一个窗口编辑多个文件。</p>
<p>pentadactyl也有对应的概念，pentadactyl中每个缓冲区对应一个tab，保存着对应网页的内容，包括所有的frames以及历史信息。<span style="color:red">目前缓冲区可以等价的理解成标签</span>，但也不排除以后会有别的东西出现的可能。</p>
<p><a name="bufferinfo"><span style="color:blue">查看缓冲区信息</span></a></p>
<pre class="brush: jscript; title: ; notranslate">&lt;C-g&gt; 查看buffer的基本信息 - 当前文件名，最后修改时间，feed数量，标题
g&lt;C-g&gt; 查看buffer的详细信息，与:pageinfo等价
gf 查看页面源代码/切换回原始页面
gF 用外部编辑器查看页面源代码
</pre>
<p><a name="bufferurl"><span style="color:blue">复制缓冲区对应的页面地址</span></a><br />
快捷键<span class="keys">y</span>可以复制当前缓冲区对应的URL地址到剪切板</p>
<pre class="brush: jscript; title: ; notranslate">y</pre>
<p>我们还可以定义一个快捷键<span class="keys">&lt;c-y&gt;</span>用于复制当前打开的所有标签的URLs</p>
<pre class="brush: jscript; title: ; notranslate">:map &lt;c-y&gt; -d &quot;Yank all locations to the clipboard&quot; -e yank :tabdo :echo buffer.uri.spec</pre>
<p>相应的，对应于快捷键p，再定义一个<span class="keys">&lt;c-p&gt;</span>用于打开多个URLs<br />
首先，rc文件中添加如下javascript函数</p>
<pre class="brush: jscript; title: ; notranslate">javascript &lt;&lt;EOF
tabs.openURLs = function() {
        let urls = dactyl.clipboardRead();
        let urlsArray = urls.split(options.get(&quot;urlseparator&quot;).value);
        for(var i in urlsArray) {
            dactyl.open(urlsArray[i], { from: &quot;paste&quot;, where: dactyl.NEW_TAB });
        }
    };
EOF
</pre>
<p>然后，定义键<span class="keys">&lt;c-p&gt;</span></p>
<pre class="brush: jscript; title: ; notranslate">:map &lt;c-p&gt; -d &quot;Open urls based on the current clipboard contents&quot; -js tabs.openURLs();</pre>
<p>这个快捷键可以打开剪切板中的一组URLs，这些URLs之间必须用配置项urlseparator设置的分隔符分隔，默认的分隔符是竖线|<br />
所以，如果想支持打开通过<span class="keys">&lt;c-y&gt;</span>复制得到的URLs，还需要添加分隔符-回车换行符</p>
<pre class="brush: jscript; title: ; notranslate">:set urlseparator='(\||\s+)'</pre>
<p>这样设置urlseparator就可以支持|或者任何空白字符（包括换行）作为URLs的分隔符。</p>
<p><a name="bufferlist"><span style="color:blue">缓冲区列表</span></a></p>
<pre class="brush: jscript; title: ; notranslate">B or :buffers</pre>
<p>所有的缓冲区（标签页）会以一个列表的形式呈现：<br />
1. app tab和一般的tab会分开显示。<br />
2. 带%标记的对应当前tab<br />
3. 带#标记的对应上一次选择的tab，可以通过<span class="keys">&lt;C-^&gt;</span>跳转过去</p>
<p>Ex命令形式:buffers可以加filter参数，只显示符合filter条件的缓冲区。</p>
<p><span style="color:red">【问题??】</span><br />
（shift+)tab选中buffer后不能直接对对应的标签页进行操作，比如按d删除，按enter跳转等。</p>
<pre class="brush: jscript; title: ; notranslate">b</pre>
<p>这个快捷键也是显示buffer列表，但是可以通过tab选中跳转到某个buffer<br />
如果加数字前缀修饰，直接跳转到对应位置的标签，比如1b = g0跳转到第一个标签， 4b跳转到第4个标签</p>
<p>最后，还有一个有意思的功能</p>
<pre class="brush: jscript; title: ; notranslate">:pagest[yle] [stylesheet]</pre>
<p>有些站点会提供多套CSS样式，通过pagestyle命令可以热切换<br />
（本站未提供=_=|||，想试的可以去<a href="http://forums.mozillazine.org/">firefox英文论坛</a>）</p>
</ol>
</li>
<li><a name="hints"><span style="color:black"><strong>Hints</strong></span></a><br />
脱离了鼠标，只用键盘，那么该如何与网页上的可点击元素交互呢？<br />
pentadactyl里采用的方案是hints。</p>
<p>进入hints模式后，网页上的可点击元素都会被高亮，并用数字或者字母编号。这时候输入对应编号的字符就可以narrow down高亮元素，当能够唯一定位一个元素时，即执行点击动作。</p>
<p>默认情况下，是用数字给元素进行编号的。</p>
<ul>
<li>缺点是：数字在键盘上的分布并不适合方便快速地输入编号</li>
<li>优点是：定位元素时，不仅可以采用输入数字编号，还可以输入元素上的文字（Follow Hint）</li>
</ul>
<p>这个优点只对英文有效，不过针对中文有一个插件 &#8211; <a href="https://github.com/dangoakachan/Script-Sets/raw/master/Javascript/Pentadactyl/pinyin-hints-mod.js">pinyin-hints-mod.js</a><br />
可以通过输入文字对应的拼音首字母来作为Follow Hint定位元素</p>
<p>通过配置项hintkeys可以修改编号时使用的字符，我个人习惯用字母编号（尽管这样就不方便使用Follow Hint了）</p>
<pre class="brush: jscript; title: ; notranslate">:set hintkeys='asdfjklgheriop'</pre>
<p>如果页面上可点击元素过多，编号显示就会比较密集，看不清楚</p>
<pre class="brush: jscript; title: ; notranslate">:hi Hint font:bold 15px &quot;Droid Sans Mono&quot;, monospace !important; margin:-.2ex; padding: 0 0 0 1px; outline:1px solid rgba(0, 0, 0, .5); background:rgba(255, 248, 231, .8); color:black; text-transform:uppercase;</pre>
<p>使用这个样式可以使编号更醒目（字体大号、加粗、大写 &#8211; 输入时用小写就行）</p>
<ul>
<li><a name="hintmodes">Hints有好几个子模式：</a>
<ol>
<li><a name="qh">Quick Hint</a></li>
<p>按<span class="keys">f</span>键即可进入这个最基本的hint模式。</p>
<li><a name="sqh">Shift Quick Hint</a></li>
<p>在按<span class="keys">f</span>进入的hint模式下，唯一定位到一个元素时会自动触发<strong>点击</strong>动作，如果元素是链接一般是在当前页面跳转。<br />
而在按<span class="keys">F</span>键进入的Shift QuickHint模式下，触发点击动作时等效于按着shift键点击，所以针对链接可以实现在新标签页打开。</p>
<li><a name="eh">Extended Hint</a></li>
<p>上面两个模式会高亮页面上所有的可点击元素，而且定位元素后直接触发点击动作。<br />
使用扩展hint模式，可以更灵活地控制高亮元素的范围，比如只高亮超链、只高亮图片等；可以控制定位元素后的触发动作，比如复制链接地址、另存图片等。</p>
<p><span style="color:blue">;{mode}{hint}</span><br />
按<span class="keys">;</span>键进入扩展Hint模式后，可以通过再输入一个<strong>模式</strong>字符进行进一步的控制。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/03/extended-hint-modes.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/03/extended-hint-modes.png" alt="" title="extended hint modes" width="461" height="537" class="aligncenter size-full wp-image-244" /></a></p>
<li><a name="peh">Persisted Extended Hint</a><br />
上面几个Hint模式，在定位元素触发动作后即自动退出Hint模式。<br />
而持久的扩展Hint模式，在触发动作后仍然保持在Hint模式，因而可以实现连续打开一组链接这样的需求。</p>
<p>要进入持久的扩展Hint模式，只需在一般的扩展模式前多按一个<span class="keys">g</span>键。<br />
<span style="color:blue">g;{mode}{hint}</span></p>
<li><a name="ch">Caret Hint</a></li>
<p>使用Caret Hint可以通过hint的方式来快速移动caret光标，方便caret定位以及文字选择。<br />
pentadactyl本身没有内置Caret Hint，但是有个plugin可以实现。<br />
目前我使用harnack的<a href="http://dactyl.googlecode.com/issues/attachment?aid=-7835177909581330522&#038;name=caret-hint.zip&#038;token=b7f94cc039488ee0d25ffa103602d4d4">简化版本</a><br />
操作命令如下：</p>
<pre class="brush: jscript; title: ; notranslate">;m - 移动Caret到选中hint元素的文字头
;M - 移动Caret到选中hint元素的文字尾
;e - 选中hint元素文字
</pre>
</li>
</ol>
</li>
<li><a name="hintoptions">相关配置项</a></li>
<ul>
<li>hintinputs</li>
<li>hintkeys</li>
<p>定义用于给hint元素编号的字符集</p>
<li>hintmatching</li>
<li>hinttags</li>
<p>设置hint元素的选择规则。<br />
支持css selector和xpath（以xpath:打头表示）两种语法</p>
<li>extendedhinttags</li>
<p>设置扩展hint模式下元素的选择规则。<br />
可以针对不同模式设置选择规则，优先级比hinttags的设置高</p>
<pre class="brush: jscript; title: ; notranslate">[f]:body</pre>
<li>hinttimeout</li>
<p>设置hint自动触发时间（单位ms，默认值0）<br />
值为0时，只有选中hint元素回车确认或者能够唯一定位一个hint元素时才会触发动作。<br />
如果设置了正值，只要按了hintkeys中的按键，就开始计时，当hinttimeout时间过后，即使仍有多个hint元素待选，也会自动触发。
</ul>
</ul>
</li>
<li><a name="options"><span style="color:black"><strong>options设置</strong></span>
<ul>
<li><a name="passkeys">passkeys</a></li>
<p>由于Pentadactyl全面接管了快捷键，对于重度依赖快捷键操作的站点（比如google的众多服务）来说，会存在很大的问题。<br />
通过passkeys这个配置项，可以针对URL来设置哪些键不由pentadactyl处理，而直接传递给firefox。</p>
<pre class="brush: jscript; title: ; notranslate">:set passkeys=www\.google\.com/reader/:jkovA</pre>
<p>这个示例设置是针对我常访问的google reader的，直接传递jkovA这几个常用的快捷键。<br />
语法是这样的：</p>
<pre class="brush: jscript; title: ; notranslate">
URL部分采用正则表达式用来指定站点（注意，由于是正则表达式，所以regex的元字符要转义），如果有冒号需要用引号括起
冒号（:）
需要传递的键（序列）以逗号（,）分隔。如果是单键不需要用逗号分隔，集中放在第一个逗号之前；如果是多个键组成的序列，放在第一个逗号之后，多个的话以逗号分隔。
针对不同URL的设置用逗号（,）分隔
</pre>
<p>其实，passkeys的值类型从1.0b6版本已经由regexpmap更改为sitemap，完整的定义是这样的</p>
<pre class="brush: jscript; title: ; notranslate">{Site Filters}:{Passed Keys},{Site Filters}:{Passed Keys}</pre>
<p>通过查看帮助，可以看到用Site Filters表达URLs有4种方法</p>
<pre class="brush: jscript; title: ; notranslate">:help site-filter</pre>
<ol>
<li>domain</li>
<p>通过域名这种方式可以匹配该域名及其子域名下的所有站点。<br />
比如baidu.com，twitter.com</p>
<li>URL prefix</li>
<p>一个“URL前缀”表示有两点要求，1要以协议名开头，比如http，https；2要以*号结尾。比如</p>
<pre class="brush: jscript; title: ; notranslate">http://www.google.com/reader/*</pre>
<p>这样一个URL prefix可以匹配所有以此开头的URLs<br />
注意事项：</p>
<ul>
<li>因为协议名后的:号与{Site Filters}:{Passed Keys}中的:号冲突，所以URL prefix需要用引号括起</li>
<li>使用命令行设置的URL prefix形式的passkeys，不能通过:mkpentadactyl!保存到rc文件中，因为保存时引号会被自动删掉（<span style="color:red">bug？</span>），重新source rc后该passkeys就不再工作。所以使用URL prefix要么直接手写到rc文件中，要么只能临时生效。</li>
</ul>
<li>Full URL</li>
<p>以协议名开始而不以*结尾的URL就是一个完整的URL，只匹配这个完整的URL</p>
<li>Regular expression</li>
<p>不是上述三种情况的时候都理解成正则表达式，正则表达式要注意转义，否则不能工作。<br />
另外要注意，因为解析的时候优先按照前三种来，所以有时候直接写正则表达式可能会不工作。<br />
比如，这个针对google reader的正则表达式</p>
<pre class="brush: jscript; title: ; notranslate">'http://www\.google\.com/reader/.*'</pre>
<p>就不工作，原因是由于以协议名打头，所以它被理解成full URL。<br />
写成下面的就可以</p>
<pre class="brush: jscript; title: ; notranslate">www\.google\.com/reader/.*</pre>
<p>所以用正则表达式来做passkeys要格外注意这种情况。</p>
<p>{Passed Keys}部分前面已经说过了，是以逗号分隔的键（序列）。</p>
<ul>
<li>所有的单键写在一起，放在第一个逗号之前</li>
<li>多个键组成的键序列，放在第一个逗号之后，并且键序列之间用逗号分隔</li>
</ul>
<p>针对多个站点的passkeys设置{Site Filters}:{Passed Keys}再以逗号分隔或者通过</p>
<pre class="brush: jscript; title: ; notranslate">:set passkeys+=</pre>
<p>追加。</p>
</ol>
</ul>
</li>
<li><a name="ui"><span style="color:black"><strong>UI设置</strong></span></a>
<ul>
<li><a name="go">guioptions</a></li>
<p>通过该配置项可以控制firefox的GUI显示，可以简写成go<br />
go的值是一个字符列表，每个字符对应一个可控GUI元素，包含在go中的会显示出来。<br />
通过命令操作：</p>
<pre class="brush: jscript; title: ; notranslate">:set go+=x      让x对应的GUI元素显示出来
:set go-=x      让x对应的GUI元素不显示
:set go=abc    只显示a,b,c对应的GUI元素
</pre>
<p>目前支持控制的所有GUI元素<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/03/guioptions.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/03/guioptions.png" alt="" title="guioptions" width="494" height="354" class="aligncenter size-full wp-image-249" /></a><br />
其中</p>
<ul>
<li>T对应Toolbar，实际上就是我们熟悉的导航栏。</li>
<li>大C只在状态栏显示（即go中包含s）的情况下有效。</li>
<p>有大C时，用:呼出的命令行会单独有一行；否则的话，命令行集成在状态栏里</p>
<li>小c控制是否始终显示命令行</li>
<p>如果设置了的话，即使没有敲ex命令，也会有一行空白的命令行显示<br />
如果有状态栏s，小c最好和大C一起设置，否则命令行还是集成在状态栏里，ex命令不会显示在新加的单独命令行里，新加的这行只显示 &#8212; EX &#8212; 这种信息。</p>
<li>M用来控制是否用独立行显示提示信息，比如Please ENTER or type command to continue这种，一般是显示在状态栏的</li>
<li>显示标签编号，n是在site icon后显示，N是在icon上，建议用n，N会遮盖图标</li>
</ul>
<li><a name="statusline">状态栏</a></li>
<p>通过命令</p>
<pre class="brush: jscript; title: ; notranslate">:set go+=s</pre>
<p>可以开启状态栏显示。</p>
<p>状态栏会显示如下信息：</p>
<ul>
<li>当前页面URL，另外也可以显示鼠标所悬停的页面上链接信息</li>
<li><strong>[+-❤⋯]</strong></li>
<p><strong>+</strong>代表当前页面有后退历史，可以用<span class="key">H</span>键后退<br />
<strong>-</strong>代表当前页面有前进历史，可以用<span class="key">L</span>键前进<br />
<strong>❤</strong>代表当前页面已经存为书签<br />
其他字符代表有对应的QuickMark</p>
<p>通过下面这个plugin可以把这组符号信息挪到URL之前，看起来更直观。<br />
<a href='http://www.slimeden.com/wp-content/uploads/2011/03/urlFieldTweak.js'>urlFieldTweak.js</a></p>
<li>标签位置索引</li>
<p>[N/M] N对应当前标签的序号，M对应所有标签的总数</p>
<li>当前位置在页面纵向scroll的百分比</li>
<li>当前页面的水平和垂直方向的最大像素</li>
<p>[x=N,y=M] N代表水平方向，M代表竖直方向，单位像素<br />
这个需要plugin &#8211; <a href='http://www.slimeden.com/wp-content/uploads/2011/03/pageScrollInfo.js'>pageScrollInfo.js</a></p>
<li>当前页面放大缩小的百分比</li>
<p>100%大小时不显示
</ul>
<p>状态栏的颜色可以用于查看站点的安全信息<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/03/security.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/03/security.png" alt="" title="security" width="629" height="151" class="aligncenter size-full wp-image-252" /></a></p>
<li><a name="gui">命令行访问GUI</a></li>
<p>通过下面这些ex命令，可以直接访问firefox 的GUI</p>
<pre class="brush: jscript; title: ; notranslate">:emenu {menu} 打开菜单
:dia[log] [Firefox-dialog] 打开firefox的各种对话框
:downl[oads] 显示下载相关信息
:toolbarshow {name} 显示toolbar
:toolbarhide {name}
:toolbartoggle {name}
</pre>
</ul>
</li>
<li><a name="plugins"><span style="color:black"><strong>plugins插件</strong></span></a>
<ul>
<li><a name="pluginsplace">插件存放</a></li>
<ol>
<li>插件应该存放在名为plugins的文件夹下</li>
<li>pentadactyl会从配置项runtimepath定义的文件夹中查找plugins子文件夹</li>
<li>可以有多个plugins文件夹</li>
<li>runtimepath默认值是$PENTADACTYL_RUNTIME，如果没设置，windows系统下则是$HOME/pentadactyl，其他系统下是（$HOME/.pentadactyl）</li>
<p>所以，在windows下，默认情况插件应该放在$HOME/pentadactyl/plugins文件夹里。</p>
<li>我准备把plugins放到profile文件夹下，因此需要将profile加到runtimepath中，由于已在启动参数设置$HOME为profile，所以</li>
<pre class="brush: jscript; title: ; notranslate">set runtimepath+=$HOME</pre>
</ol>
</li>
<li><a name="pluginsload">插件加载</a></li>
<ol>
<li>根据上述查找方式找到的所有plugins文件夹里的脚本文件会被加载</li>
<li>脚本文件通过配置项loadplugins来控制识别，默认是以.js和.penta结尾的文件</li>
<li>设置配置项noloadplugins可以关闭所有脚本的加载，但是最新每夜版（hg6126）无此参数，不过可以通过设置loadplugins达到同样的目的</li>
<pre class="brush: jscript; title: ; notranslate">set loadplugins=''</pre>
<li>设置如下启动参数（++noplugin或者+u=NONE），同样可以关闭脚本加载。具体请查看帮助</li>
<pre class="brush: jscript; title: ; notranslate">:help startup-options</pre>
</ol>
</li>
</li>
<li><a name="pluginssuggest">插件推荐</a></li>
<ol>
<li><a href="https://github.com/dangoakachan/Script-Sets/blob/master/Javascript/Pentadactyl/goo.gl.js">goo.gl</a></li>
<p>集成google短地址服务
</ol>
</li>
</li>
<li><a name="reference"><span style="color:black"><strong>相关资料和站点</strong></span>
<ol>
<li><a href="http://dango-akachan.appspot.com/?p=260001">团子的小窝 &#8211; Vimperator新手教程</a></li>
<li><a href="http://dango-akachan.appspot.com/?p=306001">团子的小窝 &#8211; Vimperator[Pentadactyl]小技巧</a></li>
<li><a href="http://g.mozest.com/thread-36486-1-1">Mozest论坛讨论帖 &#8211; Dactyl[Vimperator分枝]一些使用经验,期待交流</a></li>
</ol>
</li>
</ul>
<style type="text/css">
.keys {
    color: #0DA575;
    font-weight: bold;
}
</style>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2011/03/firefox/pentadactyl/feed</wfw:commentRss>
		<slash:comments>95</slash:comments>
		</item>
		<item>
		<title>查看firefox4 User Interface部分（omni.jar）的源代码</title>
		<link>http://www.slimeden.com/2011/03/firefox/viewomnijar</link>
		<comments>http://www.slimeden.com/2011/03/firefox/viewomnijar#comments</comments>
		<pubDate>Mon, 14 Mar 2011 10:01:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[firefox]]></category>
		<category><![CDATA[firefox4]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[keyconfig]]></category>
		<category><![CDATA[keysnail]]></category>

		<guid isPermaLink="false">http://www.slimeden.com/?p=215</guid>
		<description><![CDATA[firefox是开源的项目，可以在其<a href="http://mxr.mozilla.org/mozilla-central/source/">代码库</a>直接查看源代码。
firefox内核部分，包括底层平台框架、执行渲染引擎等用C++编写，然后编译链接打包后分发，这部分去其代码库可以看到C++源码，有兴趣的可以下载后修改，重新编译打包，这部分不是今天讨论的主题。
今天我们主要关注的是前端用户接口（User Interface），这部分大部分是用html、javascript、css等web技术以及mozilla自己的界面语言xul实现，基于文本的，不需要编译，所以我们很方便查看学习，甚至写些小脚本修改界面元素，定制自己喜欢的界面。
firefox 4.0之前在其安装目录下可以直接看到chrome、co[......]<p class='read-more'><a href='http://www.slimeden.com/2011/03/firefox/viewomnijar'>阅读全文</a></p>]]></description>
			<content:encoded><![CDATA[<p>firefox是开源的项目，可以在其<a href="http://mxr.mozilla.org/mozilla-central/source/">代码库</a>直接查看源代码。</p>
<p>firefox内核部分，包括底层平台框架、执行渲染引擎等用C++编写，然后编译链接打包后分发，这部分去其代码库可以看到C++源码，有兴趣的可以下载后修改，重新编译打包，这部分不是今天讨论的主题。</p>
<p>今天我们主要关注的是前端用户接口（User Interface），这部分大部分是用html、javascript、css等web技术以及mozilla自己的界面语言xul实现，基于文本的，不需要编译，所以我们很方便查看学习，甚至写些小脚本修改界面元素，定制自己喜欢的界面。</p>
<p>firefox 4.0之前在其安装目录下可以直接看到chrome、components、modules等目录，里面就能找到这些用户接口的源文件（比如主Chrome界面browser.js &#8211; %installationpath%/chrome/browser/content/browser/browser.js），打开就能看。但是4.0之后，考虑到性能因素，这些文件已经打包成一个单独的omni.jar，而且由于<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=605524">打包压缩的优化</a>导致一些压缩软件（比如7zip）无法正常打开omni.jar，这样造成了很大的不便。</p>
<p>对于喜欢写脚本扩展或者热衷于学习firefox界面源码的人来说，这种麻烦很影响效率和心情。下面这段代码就是为了解决这个问题，通过在firefox里直接查看omni.jar。</p>
<pre class="brush: jscript; title: ; notranslate">var dirService = Components.classes[&quot;@mozilla.org/file/directory_service;1&quot;].getService(Components.interfaces.nsIProperties);

var installationDirFile = dirService.get(&quot;CurProcD&quot;, Components.interfaces.nsIFile);
var installationDir = installationDirFile.path;
var omnijarURL = &quot;jar:file:///&quot; + installationDir + &quot;/omni.jar!/&quot;;

var browser = document.getElementById(&quot;content&quot;);
var tab = browser.addTab(omnijarURL);
browser.selectedTab = tab;
</pre>
<p>使用快捷键（keyconfig、keysnail）或者手势（firegesture）扩展用这段代码就能用一个新tab打开omni.jar。<br />
<a href="http://www.slimeden.com/wp-content/uploads/2011/03/1.png"><img src="http://www.slimeden.com/wp-content/uploads/2011/03/1.png" alt="" title="omni.jar" width="580" height="210" class="aligncenter size-full wp-image-216" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.slimeden.com/2011/03/firefox/viewomnijar/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

