<?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>Emacs中文网 &#187; IDE</title>
	<atom:link href="http://emacser.com/c-ide.htm/feed" rel="self" type="application/rss+xml" />
	<link>http://emacser.com</link>
	<description>没有我做不到的，只有你想不到的</description>
	<lastBuildDate>Thu, 17 May 2012 14:05:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Emacs 自动填充头文件</title>
		<link>http://emacser.com/include_files_helper.htm</link>
		<comments>http://emacser.com/include_files_helper.htm#comments</comments>
		<pubDate>Tue, 03 Apr 2012 14:22:39 +0000</pubDate>
		<dc:creator>bigclean</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Elisp]]></category>
		<category><![CDATA[自动补全]]></category>
		<category><![CDATA[配置]]></category>
		<category><![CDATA[高级]]></category>
		<category><![CDATA[Emacs]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41916</guid>
		<description><![CDATA[作者: 杨英超
目标

写 C/C++ 代码时候，可以根据自动补全头文件。注意，是补全，也就是说至少我们需要输入几个字符让它帮忙补全。
如果头文件存放在搜索路径的子目录中，可以自动列出子目录中的文件，并将这些文件添加到用于补齐的候选名单中。
补齐完成之后，可以自动判断到底应该使用 #include  还是 #include &#8220;FILE&#8221; 。


方案
emacser.org 上有一篇文章，其中提到了这个解决方法，主要是利用了 abbrev-mode 和 skeleton-mode 来实现，通过这个方法，我们输入 inc, 然后按空格, 会提示输入文件名称。
代码如下：

?View Code LISP1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
;; 安装 abbrev
&#40;mapc
 &#40;lambda &#40;mode&#41;
   &#40;define-abbrev-table mode '&#40;
                           [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #0000ff;">作者: </span><a href="http://www.cnblogs.com/yangyingchao/" target="_blank"><span style="color: #0000ff;"><b>杨英超</b></span></a></p>
<h3>目标</h3>
<ol>
<li>写 C/C++ 代码时候，可以根据自动补全头文件。注意，是补全，也就是说至少我们需要输入几个字符让它帮忙补全。</li>
<li>如果头文件存放在搜索路径的子目录中，可以自动列出子目录中的文件，并将这些文件添加到用于补齐的候选名单中。</li>
<li>补齐完成之后，可以自动判断到底应该使用 #include <FILE> 还是 #include &ldquo;FILE&rdquo; 。</li>
</ol>
<p><span id="more-41916"></span></p>
<h3>方案</h3>
<p>emacser.org 上有一篇文章，其中提到了这个<a href="http://emacser.com/include-sys-header.htm">解决方法</a>，主要是利用了 abbrev-mode 和 skeleton-mode 来实现，通过这个方法，我们输入 inc, 然后按空格, 会提示输入文件名称。</p>
<p>代码如下：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41916code3'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p419163"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code" id="p41916code3"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;; 安装 abbrev</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapc</span>
 <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>mode<span style="color: #66cc66;">&#41;</span>
   <span style="color: #66cc66;">&#40;</span>define-abbrev-table mode '<span style="color: #66cc66;">&#40;</span>
                               <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;inc&quot;</span> <span style="color: #ff0000;">&quot;&quot;</span> skeleton-include <span style="color: #cc66cc;">1</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;">&#40;</span>c-mode-abbrev-table c++-mode-abbrev-table<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; 输入 inc , 可以自动提示输入文件名称,可以自动补全.</span>
<span style="color: #66cc66;">&#40;</span>define-skeleton skeleton-include
  <span style="color: #ff0000;">&quot;generate include&lt;&gt;&quot;</span> <span style="color: #ff0000;">&quot;&quot;</span>
  <span style="color: #66cc66;">&gt;</span> <span style="color: #ff0000;">&quot;#include &lt;&quot;</span>
  <span style="color: #66cc66;">&#40;</span>completing-read <span style="color: #ff0000;">&quot;Include File:&quot;</span>
                   <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> #'<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>f<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> f <span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                           <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">apply</span> '<span style="color: #b1b100;">append</span>
                                  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span>
                                   #'<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>dir<span style="color: #66cc66;">&#41;</span>
                                       <span style="color: #66cc66;">&#40;</span>directory-files dir<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                                   <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> <span style="color: #ff0000;">&quot;/usr/include&quot;</span>
                                         <span style="color: #ff0000;">&quot;/usr/local/include&quot;</span>
                                         <span style="color: #ff0000;">&quot;/usr/include/g++-3&quot;</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>
  <span style="color: #ff0000;">&quot;&gt;&quot;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>该方法有若干局限性：</p>
<ul>
<li>头文件的搜索路径是写死的，如果某个目录不存在，上面的代码会报错，不能补全。</li>
<li>无法补全搜索路径的子目录下的文件 （ 即前面的 AIM 2）。</li>
<li>没有判断在 #include 一个文件的时候，是应该使用符号 &lt;> 还是符号 &ldquo;&rdquo; （即前面的 AIM 3）</li>
</ul>
<p>解决方法并不复杂，对应如下：</p>
<ul>
<li>通过某种方法来从系统中自动获取 include 的搜索路径。比如 CEDET 提供的： semantic-gcc-get-include-paths 函数。</li>
<li>重定义 minibuffer-mode 下的按键 &ldquo;/&#8221;。将其绑定到一个用于搜索和展开某个目录，并更新 minibuffer-completion-table 的函数(minibuffer-completion-table 是 minibuffer-mode 中补全的候选 list)。</li>
<li>在 skeleton-include 中不使用 &lt;> 或者 &ldquo;。我们可以使用一个特殊的标记，然后在 skeleton-include 的结尾，根据头文件的路径判断到底应该使用什么符号。</li>
</ul>
<p>整理以后的代码实现如下：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41916code4'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p419164"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
</pre></td><td class="code" id="p41916code4"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;; 输入 inc , 可以自动提示输入文件名称,可以自动补全.</span>
<span style="color: #808080; font-style: italic;">;; Provided by yangyingchao@gmail.com</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapc</span>
 <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>mode<span style="color: #66cc66;">&#41;</span>
   <span style="color: #66cc66;">&#40;</span>define-abbrev-table mode '<span style="color: #66cc66;">&#40;</span>
                               <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;inc&quot;</span> <span style="color: #ff0000;">&quot;&quot;</span> skeleton-include <span style="color: #cc66cc;">1</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;">&#40;</span>c-mode-abbrev-table c++-mode-abbrev-table<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defconst yc/inc-dir-<span style="color: #b1b100;">list</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">append</span> <span style="color: #66cc66;">&#40;</span>semantic-gcc-get-include-paths <span style="color: #ff0000;">&quot;c++&quot;</span><span style="color: #66cc66;">&#41;</span> '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;./&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;nil&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>defvar inc-minibuffer-compl-<span style="color: #b1b100;">list</span> <span style="color: #b1b100;">nil</span> <span style="color: #ff0000;">&quot;nil&quot;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> yc/update-minibuffer-complete-table <span style="color: #66cc66;">&#40;</span> <span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Complete minibuffer&quot;</span>
  <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>prompt <span style="color: #66cc66;">&#40;</span>minibuffer-prompt<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>comp-part <span style="color: #66cc66;">&#40;</span>minibuffer-contents-no-properties<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span>string<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Include File:&quot;</span> prompt<span style="color: #66cc66;">&#41;</span>
               <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">length</span> comp-part<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> minibuffer-completion-table
            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">append</span> minibuffer-completion-table
                    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>inc-files <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
                          <span style="color: #66cc66;">&#40;</span>dirname <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
                          <span style="color: #66cc66;">&#40;</span>tmp-<span style="color: #b1b100;">name</span> <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapc</span>
                       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>d<span style="color: #66cc66;">&#41;</span>
                         <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> dirname <span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;%s/%s&quot;</span> d comp-part<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                         <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>file-exists-p dirname<span style="color: #66cc66;">&#41;</span>
                           <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapc</span>
                            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span>
                              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span>string<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;.&quot;</span> x<span style="color: #66cc66;">&#41;</span>
                                             <span style="color: #66cc66;">&#40;</span>string<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;..&quot;</span> x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> tmp-<span style="color: #b1b100;">name</span> <span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;%s/%s&quot;</span> comp-part x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                                <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'inc-files tmp-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                            <span style="color: #66cc66;">&#40;</span>directory-files dirname<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                       yc/inc-dir-<span style="color: #b1b100;">list</span><span style="color: #66cc66;">&#41;</span>
                      inc-files<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>
  <span style="color: #66cc66;">&#40;</span>insert <span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>map minibuffer-local-completion-map<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>define-key map <span style="color: #ff0000;">&quot;/&quot;</span> 'yc/update-minibuffer-complete-table<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> yc/update-inc-marks <span style="color: #66cc66;">&#40;</span> <span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;description&quot;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>statement <span style="color: #66cc66;">&#40;</span>buffer-substring-no-properties
                      <span style="color: #66cc66;">&#40;</span>point-at-bol<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>point-at-eol<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>inc-file <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>to-begin <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>to-end <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>yc/re-include
           <span style="color: #66cc66;">&#40;</span>rx <span style="color: #ff0000;">&quot;#include&quot;</span> <span style="color: #66cc66;">&#40;</span>+ ascii<span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;|XXX|&quot;</span> <span style="color: #66cc66;">&#40;</span>group <span style="color: #66cc66;">&#40;</span>+ ascii<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;|XXX|&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>string-match yc/re-include statement<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> inc-file <span style="color: #66cc66;">&#40;</span>match-string <span style="color: #cc66cc;">1</span> statement<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>file-exists-p <span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;./%s&quot;</span> inc-file<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> to-begin <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span> to-end <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> to-begin <span style="color: #ff0000;">&quot;&lt;&quot;</span> to-end <span style="color: #ff0000;">&quot;&gt;&quot;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>move-beginning-of-line <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>kill-line<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>insert <span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;#include %s%s%s&quot;</span> to-begin inc-file to-end<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>move-end-of-line <span style="color: #cc66cc;">1</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>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define-skeleton skeleton-include
  <span style="color: #ff0000;">&quot;generate include&lt;&gt;&quot;</span> <span style="color: #ff0000;">&quot;&quot;</span>
  <span style="color: #66cc66;">&gt;</span> <span style="color: #ff0000;">&quot;#include |XXX|&quot;</span>
  <span style="color: #66cc66;">&#40;</span>completing-read
   <span style="color: #ff0000;">&quot;Include File:&quot;</span>
   <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>f<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> f <span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">apply</span>
     '<span style="color: #b1b100;">append</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>dir<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>directory-files
         dir <span style="color: #b1b100;">nil</span>
         <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>(<span style="color: #000099; font-weight: bold;">\\</span>.h<span style="color: #000099; font-weight: bold;">\\</span>)?&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      yc/inc-dir-<span style="color: #b1b100;">list</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: #ff0000;">&quot;|XXX|&quot;</span>
  <span style="color: #66cc66;">&#40;</span>yc/update-inc-marks<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<h3>使用和效果</h3>
<p>使用方法很简单：</p>
<ol>
<li>将上述的代码添加到 Emacs 的配置文件后，打开一个 C/C++ 程序，</li>
<li>输入 inc 然后按下空格，然后在 minibuffer 中输入部分头文件的名字，并通过 TAB 来补全。</li>
<li>如果头文件位于子目录中，则输入目录名后输入 &ldquo;/&rdquo; 。这样子目录中的内容也会添加到补齐的候选名单中，然后就又可以继续他过 TAB 补全了。</li>
<li>确认 minibuffer 中填写的内容无误后，回车， skeleton-include 将自动更新标记符号。</li>
</ol>
<h3>截图：</h3>
<p>下面是几张截图：</p>
<p><center><img src="https://dea.googlecode.com/svn/trunk/screenshots/include_files_helper-01.png" title="Include 系统文件" /></center></p>
<p><center>Include 系统文件</center></p>
<p><center><img src="https://dea.googlecode.com/svn/trunk/screenshots/include_files_helper-02.png" title="Include 自定义文件" /></center></p>
<p><center>Include 自定义文件</center></p>
<p><center><img src="https://dea.googlecode.com/svn/trunk/screenshots/include_files_helper-03.png" title="全部完成后截图" /></center></p>
<p><center>全部完成后截图</center></p>
<p></body><br />
</html></p>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/include_files_helper.htm' t='Emacs 自动填充头文件' d='' tag='C/C++,Elisp,Emacs,配置,高级' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>
	<h4>相关日志</h4>
	<ul class="st-related-posts">
	<li><a href="http://emacser.com/auto-complete.htm" title="Emacs才是世界上最强大的IDE － 用auto-complete实现自动补全 (2009年11月11日)">Emacs才是世界上最强大的IDE － 用auto-complete实现自动补全</a> (114)</li>
	<li><a href="http://emacser.com/emacs-beginner-must-know.htm" title="Emacs初学者必知必会 (2010年01月24日)">Emacs初学者必知必会</a> (9)</li>
	<li><a href="http://emacser.com/to-emacs-beginner.htm" title="致Emacs初学者 (2009年11月30日)">致Emacs初学者</a> (121)</li>
	<li><a href="http://emacser.com/svn-status-mode-line.htm" title="在mode-line上标记svn状态 (2010年01月28日)">在mode-line上标记svn状态</a> (30)</li>
	<li><a href="http://emacser.com/bing.htm" title="在 emacs 中使用 bing translate api 实现高效翻译 (2012年05月12日)">在 emacs 中使用 bing translate api 实现高效翻译</a> (6)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://emacser.com/include_files_helper.htm/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>用flymake检测C/C++语法</title>
		<link>http://emacser.com/flymake.htm</link>
		<comments>http://emacser.com/flymake.htm#comments</comments>
		<pubDate>Sun, 05 Dec 2010 15:54:17 +0000</pubDate>
		<dc:creator>Meteor Liu</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[中级]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41759</guid>
		<description><![CDATA[

1 前言 
2 flymake基本用法 
3 ahei的改进 
4 我的修改 
5 检测python语法 
6 遗留问题 



1 前言 


前段时间ahei使劲推荐flymake，而且在dea中还给出一段flymake配置，勾起了我学习flymake的兴趣。在此之前只是听说过flymake，偶尔浅尝一下还没学会怎么用就放弃了，这几天折腾flymae后觉得实在很给力。生活不是缺少美，而是缺少发现美的眼睛这话说得还真有点道理。



2 flymake基本用法 


flymake是一个实时的语法检查工具，好像是从emacs22开始已经自带flymake，自带的flymake提供了对C,C++,XML,HTML,C#,perl,php,java,tex,idl的支持。查看flymake-allowed-file-name-masks这个变量可以得到支持语言的详细信息。想要了解其它语言的支持，可以看看http://www.emacswiki.org/FlyMake。


在以下四种情况下，flymake会执行语法检测：



打开文件时


换行(可通过flymake-start-syntax-check-on-newline配置)


代码改变0.5秒后(可通过flymake-no-changes-timeout配置)


手工执行flymake-start-syntax-check


下面是flymake基本配置：


?View Code LISP&#40;autoload 'flymake-find-file-hook &#34;flymake&#34; &#34;&#34; t&#41;
&#40;add-hook 'find-file-hook 'flymake-find-file-hook&#41;
&#40;setq flymake-gui-warnings-enabled nil&#41;
&#40;setq flymake-log-level 0&#41;


加上以上配置后，打开文件时会检测是否是flymake支持的语言，是的话就会自动打开flymake-mode。flymake-gui-warnings-enabled设置为nil表示出错时不弹个对话框显示错误；flymake-log-level设置为0表示记录错误日志。


本文主要讨论C/C++(因为别的我不会)，自带的flymake对C/C++的支持是通过Makefile实现的，Makefile中必须有一个check-syntax目标，比如我在Linux下用automake，那我在Makefile.am中加了这么一段(其实就是调用gcc)：


?View Code MAKEFILEcheck-syntax:
    $(CXXCOMPILE) -Wall -Wextra -pedantic -fsyntax-only $(CHK_SOURCES)


如果不用automake，手写Makefile的话，相应地修改一下就行了。


有了这些设置后，打开项目中的cpp文件，应该会自动检测语法了，语法有错误的话会用颜色标识出错的行，M-x flymake-goto-next-error和M-xflymake-goto-prev-error可以在错误行间移动；鼠标在错误行上停留会用tooltip显示错误信息；M-x flymake-display-err-menu-for-current-line能弹出一个菜单显示错误。


另外，ahei写了几个函数可以在错误行间移动时在minibuffer显示出错误信息：


?View Code LISP&#40;defun flymake-display-current-error &#40;&#41;
  &#34;Display errors/warnings under cursor.&#34;
  &#40;interactive&#41;
  &#40;let [...]]]></description>
			<content:encoded><![CDATA[<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1 前言 </a></li>
<li><a href="#sec-2">2 flymake基本用法 </a></li>
<li><a href="#sec-3">3 ahei的改进 </a></li>
<li><a href="#sec-4">4 我的修改 </a></li>
<li><a href="#sec-5">5 检测python语法 </a></li>
<li><a href="#sec-6">6 遗留问题 </a></li>
</ul>
</div>
<div id="outline-container-1" class="outline-3">
<h3 id="sec-1"><span class="section-number-3">1</span> 前言 </h3>
<div class="outline-text-3" id="text-1">
<p>
前段时间ahei使劲推荐<a href="http://flymake.sourceforge.net/">flymake</a>，而且在dea中还给出一段flymake配置，勾起了我学习flymake的兴趣。在此之前只是听说过flymake，偶尔浅尝一下还没学会怎么用就放弃了，这几天折腾flymae后觉得实在很给力。生活不是缺少美，而是缺少发现美的眼睛这话说得还真有点道理。<span id="more-41759"></span></p>
</div>
</div>
<div id="outline-container-2" class="outline-3">
<h3 id="sec-2"><span class="section-number-3">2</span> flymake基本用法 </h3>
<div class="outline-text-3" id="text-2">
<p>
flymake是一个实时的语法检查工具，好像是从emacs22开始已经自带flymake，自带的flymake提供了对C,C++,XML,HTML,C#,perl,php,java,tex,idl的支持。查看flymake-allowed-file-name-masks这个变量可以得到支持语言的详细信息。想要了解其它语言的支持，可以看看<a href="http://www.emacswiki.org/FlyMake">http://www.emacswiki.org/FlyMake</a>。
</p>
<p>
在以下四种情况下，flymake会执行语法检测：
</p>
<ul>
<li>
打开文件时
</li>
<li>
换行(可通过flymake-start-syntax-check-on-newline配置)
</li>
<li>
代码改变0.5秒后(可通过flymake-no-changes-timeout配置)
</li>
<li>
手工执行flymake-start-syntax-check</p>
</li>
</ul>
<p>下面是flymake基本配置：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41759code12'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4175912"><td class="code" id="p41759code12"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>autoload 'flymake-find-file-hook <span style="color: #ff0000;">&quot;flymake&quot;</span> <span style="color: #ff0000;">&quot;&quot;</span> t<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>add-hook 'find-file-hook 'flymake-find-file-hook<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> flymake-gui-warnings-enabled <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> flymake-log-level <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
加上以上配置后，打开文件时会检测是否是flymake支持的语言，是的话就会自动打开flymake-mode。flymake-gui-warnings-enabled设置为nil表示出错时不弹个对话框显示错误；flymake-log-level设置为0表示记录错误日志。
</p>
<p>
本文主要讨论C/C++(因为别的我不会)，自带的flymake对C/C++的支持是通过Makefile实现的，Makefile中必须有一个check-syntax目标，比如我在Linux下用automake，那我在Makefile.am中加了这么一段(其实就是调用gcc)：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41759code13'); return false;">View Code</a> MAKEFILE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4175913"><td class="code" id="p41759code13"><pre class="makefile" style="font-family:monospace;">check-syntax:
    $(CXXCOMPILE) -Wall -Wextra -pedantic -fsyntax-only $(CHK_SOURCES)</pre></td></tr></table></div>

<p>
如果不用automake，手写Makefile的话，相应地修改一下就行了。
</p>
<p>
有了这些设置后，打开项目中的cpp文件，应该会自动检测语法了，语法有错误的话会用颜色标识出错的行，M-x flymake-goto-next-error和M-xflymake-goto-prev-error可以在错误行间移动；鼠标在错误行上停留会用tooltip显示错误信息；M-x flymake-display-err-menu-for-current-line能弹出一个菜单显示错误。
</p>
<p>
另外，ahei写了几个函数可以在错误行间移动时在minibuffer显示出错误信息：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41759code14'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4175914"><td class="code" id="p41759code14"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-display-current-<span style="color: #b1b100;">error</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Display errors/warnings under cursor.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>ovs <span style="color: #66cc66;">&#40;</span>overlays-in <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>+ <span style="color: #66cc66;">&#40;</span>point<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>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">catch</span> 'found
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">dolist</span> <span style="color: #66cc66;">&#40;</span>ov ovs<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>flymake-overlay-p ov<span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>message <span style="color: #66cc66;">&#40;</span>overlay-<span style="color: #b1b100;">get</span> ov 'help-echo<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">throw</span> 'found t<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><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-goto-next-error-disp <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Go to next error in err ring, then display error/warning.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>flymake-goto-next-<span style="color: #b1b100;">error</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>flymake-display-current-<span style="color: #b1b100;">error</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-goto-prev-error-disp <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Go to previous error in err ring, then display error/warning.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>flymake-goto-prev-<span style="color: #b1b100;">error</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>flymake-display-current-<span style="color: #b1b100;">error</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
我把它绑定到了这几个按键：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41759code15'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4175915"><td class="code" id="p41759code15"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defvar flymake-mode-map <span style="color: #66cc66;">&#40;</span>make-sparse-keymap<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>define-key flymake-mode-map <span style="color: #66cc66;">&#40;</span>kbd <span style="color: #ff0000;">&quot;C-c &lt;f4&gt;&quot;</span><span style="color: #66cc66;">&#41;</span> 'flymake-goto-next-error-disp<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>define-key flymake-mode-map <span style="color: #66cc66;">&#40;</span>kbd <span style="color: #ff0000;">&quot;C-c &lt;S-f4&gt;&quot;</span><span style="color: #66cc66;">&#41;</span> 'flymake-goto-prev-error-disp<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>define-key flymake-mode-map <span style="color: #66cc66;">&#40;</span>kbd <span style="color: #ff0000;">&quot;C-c &lt;C-f4&gt;&quot;</span><span style="color: #66cc66;">&#41;</span>
  'flymake-display-err-menu-for-current-line<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> 'flymake-mode minor-mode-map-alist<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> minor-mode-map-alist
          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">cons</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">cons</span> 'flymake-mode flymake-mode-map<span style="color: #66cc66;">&#41;</span>
                minor-mode-map-alist<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
编辑过程中，每次修改过代码0.5秒后，flymake都会检测错误，这就可以随时发现代码编写的错误了。
</p>
<p>
在这补充一下flymake检测的方法：
</p>
<p>
对于cpp文件，每次检测时，flymake是把buffer内的内容另存一份，再检测另存出来的文件。
</p>
<p>
而对于h文件，gcc没办法单独检查头文件，flymake会在flymake-master-file-dirs设定的目录中查找include过这个头文件的实现文件，把buffer另存为xxx_flymake.h，把查找到的第一个满足条件的实现文件另存yyy_flymake_master.cpp，并把里面的include语句改为include另存的文件，然后通过yyy_flymake_master.cpp来间接检测头文件。
</p>
</div>
</div>
<div id="outline-container-3" class="outline-3">
<h3 id="sec-3"><span class="section-number-3">3</span> ahei的改进 </h3>
<div class="outline-text-3" id="text-3">
<p>
自带的flymake对C++只能通过Makefile来支持，还必须在Makefile中加入check-syntax目标，实在很麻烦。要是代码不是通过Makefile来管理的，flymake就无能为力了。
</p>
<p>
其实Makefile也是通过gcc来检测代码了，那要是跳过Makefile直接调用gcc来检测代码该多好啊，所以<a href="http://emacser.com/about.htm#ahei">ahei</a>在<a href="http://code.google.com/p/dea">DEA</a>中配置了flymake直接调用gcc检测C++代码，具体代码在<a href="http://code.google.com/p/dea/source/browse/trunk/my-lisps/flymake-settings.el">flymake-setting.el</a>中，主要是以下几个函数：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41759code16'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4175916"><td class="code" id="p41759code16"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defvar flymake-makefile-filenames '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Makefile&quot;</span> <span style="color: #ff0000;">&quot;makefile&quot;</span> <span style="color: #ff0000;">&quot;GNUmakefile&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;File names for make.&quot;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-get-make-gcc-cmdline <span style="color: #66cc66;">&#40;</span>source base-dir<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span>found<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">dolist</span> <span style="color: #66cc66;">&#40;</span>makefile flymake-makefile-filenames<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>file-readable-p <span style="color: #66cc66;">&#40;</span>concat base-dir <span style="color: #ff0000;">&quot;/&quot;</span> makefile<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> found t<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> found
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> <span style="color: #ff0000;">&quot;make&quot;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> <span style="color: #ff0000;">&quot;-s&quot;</span>
                    <span style="color: #ff0000;">&quot;-C&quot;</span>
                    base-dir
                    <span style="color: #66cc66;">&#40;</span>concat <span style="color: #ff0000;">&quot;CHK_SOURCES=&quot;</span> source<span style="color: #66cc66;">&#41;</span>
                    <span style="color: #ff0000;">&quot;SYNTAX_CHECK_MODE=1&quot;</span>
                    <span style="color: #ff0000;">&quot;check-syntax&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>string<span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>file-name-extension source<span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;c&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;gcc&quot;</span> <span style="color: #ff0000;">&quot;g++&quot;</span><span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> <span style="color: #ff0000;">&quot;-o&quot;</span>
                  <span style="color: #ff0000;">&quot;/dev/null&quot;</span>
                  <span style="color: #ff0000;">&quot;-S&quot;</span>
                  source<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>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-simple-make-gcc-init-impl <span style="color: #66cc66;">&#40;</span>create-temp-f use-relative-base-dir use-relative-source build-file-<span style="color: #b1b100;">name</span> get-cmdline-f<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Create syntax check command line for a directly checked source file.
Use CREATE-TEMP-F for creating temp copy.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>args <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>source-file-<span style="color: #b1b100;">name</span> buffer-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>buildfile-dir <span style="color: #66cc66;">&#40;</span>file-name-directory source-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> buildfile-dir
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>temp-source-file-<span style="color: #b1b100;">name</span>  <span style="color: #66cc66;">&#40;</span>flymake-init-create-temp-buffer-copy create-temp-f<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> args
                <span style="color: #66cc66;">&#40;</span>flymake-get-syntax-check-program-args
                 temp-source-file-<span style="color: #b1b100;">name</span>
                 buildfile-dir
                 use-relative-base-dir
                 use-relative-source
                 get-cmdline-f<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    args<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-simple-make-gcc-init <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>flymake-simple-make-gcc-init-impl 'flymake-create-temp-inplace t t <span style="color: #ff0000;">&quot;Makefile&quot;</span> 'flymake-get-make-gcc-cmdline<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
主要思路就是先检测Makefile文件，如果存在就调用make，否则就直接调用gcc检测。
</p>
</div>
</div>
<div id="outline-container-4" class="outline-3">
<h3 id="sec-4"><span class="section-number-3">4</span> 我的修改 </h3>
<div class="outline-text-3" id="text-4">
<p>
ahei配置的gcc非常实用，我就是因为它喜欢上flymake的，不过用过几天后，发现ahei的配置里有几个问题没解决：
</p>
<ul>
<li>
没有对make或gcc进行检测 <br/></p>
<p>
flymake进行语法检测都是通过调用外部程序来实现的，比如make或gcc，如果没有安装这两个程序，flymake还是会死心眼地启动一个process去调用。
</p>
</li>
<li>
不支持用gcc直接检测头文件 <br/></p>
<p>
ahei好像是把头文件忘掉了。
</p>
</li>
<li>
目标没有权限写入时会出错 <br/></p>
<p>
因为flymake检测文件时会把buffer内容另存到一个临时文件中再检测，如果我以普通用户身份打开/usr/include/下的头文件，或者/usr/src/下的实现文件时，flymake会报靠说权限有问题，并且你会发现这个文件没在emacs中被打开。
</p>
</li>
<li>
不支持父目录中的Makefile <br/></p>
<p>
原始的flymake调用flymake-init-find-buildfile-dir来查找Makefile，它会从当前目录一直往上找，直到根目录为止，只要找到Makefile都可以。这有一个好处就是对一个有很多子目录的大工程，不需要对每个子目录下的Makefile文件都加上check-syntax目标，只需要在最顶层的Makefile中加就可以了。但ahei修改的时候可能是因为flymake-init-find-buildfile-dir找不到Makefile就会报错退出而无法转而使用gcc而放弃了这个函数，改为只在当前目录下找Makefile文件而不支持查找父目录了。
</p>
</li>
</ul>
<p>我的配置主要是在ahei的基础上进行修改，解决了这几个我发现的问题：
</p>
<p>
1.没有检测make或gcc存在的问题，我在配置文件中先检测有没有对应的外部程序，没有的话就不配置到flymake-allowed-file-name-masks中了。
</p>
<p>
2.我加了两个函数：flymake-master-make-gcc-header-init和flymake-master-make-gcc-init来支持直接用gcc检测头文件。
</p>
<p>
3.用ignore-error忽略掉权限错误，用flymake-report-fatal-status把错误通过minibuffer报告出来。
</p>
<p>
4.用flymake-find-buildfile来查找Makefile文件，能支持父目录Makefile查找。
</p>
<p>
修改后的代码如下(完整的配置见<a href="http://github.com/meteor1113/dotemacs/blob/master/init-basic.el">http://github.com/meteor1113/dotemacs/blob/master/init-basic.el</a>)：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41759code17'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4175917"><td class="code" id="p41759code17"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> flymake-allowed-file-name-masks '<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;texify&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.tex<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span> flymake-simple-tex-init<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;[0-9]+<span style="color: #000099; font-weight: bold;">\\</span>.tex<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span>
                 flymake-master-tex-init flymake-master-cleanup<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;xml&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.xml<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span> flymake-xml-init<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.html?<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span> flymake-xml-init<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;perl&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.p[ml]<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span> flymake-perl-init<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;php&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.php[1]?<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span> flymake-php-init<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;make&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.idl<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span> flymake-simple-make-init<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.java<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span>
                 flymake-simple-make-java-init flymake-simple-java-cleanup<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.cs<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span> flymake-simple-make-init<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;make&quot;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;gcc&quot;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;g++&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>defvar flymake-makefile-filenames '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Makefile&quot;</span> <span style="color: #ff0000;">&quot;makefile&quot;</span> <span style="color: #ff0000;">&quot;GNUmakefile&quot;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #ff0000;">&quot;File names for make.&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-get-gcc-cmdline <span style="color: #66cc66;">&#40;</span>source base-dir<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>cc <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>string<span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>file-name-extension source<span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;c&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;gcc&quot;</span> <span style="color: #ff0000;">&quot;g++&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> cc
            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> <span style="color: #ff0000;">&quot;-Wall&quot;</span>
                  <span style="color: #ff0000;">&quot;-Wextra&quot;</span>
                  <span style="color: #ff0000;">&quot;-pedantic&quot;</span>
                  <span style="color: #ff0000;">&quot;-fsyntax-only&quot;</span>
                  <span style="color: #ff0000;">&quot;-I..&quot;</span>
                  <span style="color: #ff0000;">&quot;-I../include&quot;</span>
                  <span style="color: #ff0000;">&quot;-I../inc&quot;</span>
                  <span style="color: #ff0000;">&quot;-I../common&quot;</span>
                  <span style="color: #ff0000;">&quot;-I../public&quot;</span>
                  <span style="color: #ff0000;">&quot;-I../..&quot;</span>
                  <span style="color: #ff0000;">&quot;-I../../include&quot;</span>
                  <span style="color: #ff0000;">&quot;-I../../inc&quot;</span>
                  <span style="color: #ff0000;">&quot;-I../../common&quot;</span>
                  <span style="color: #ff0000;">&quot;-I../../public&quot;</span>
                  source<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;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-init-find-makfile-dir <span style="color: #66cc66;">&#40;</span>source-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #ff0000;">&quot;Find Makefile, store its dir in buffer data and return its dir, if found.&quot;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>source-dir <span style="color: #66cc66;">&#40;</span>file-name-directory source-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>buildfile-dir <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">catch</span> 'found
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">dolist</span> <span style="color: #66cc66;">&#40;</span>makefile flymake-makefile-filenames<span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>found-dir <span style="color: #66cc66;">&#40;</span>flymake-find-buildfile makefile source-dir<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> found-dir
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> buildfile-dir found-dir<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> flymake-base-dir buildfile-dir<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">throw</span> 'found t<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>
      buildfile-dir<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-simple-make-gcc-init-impl <span style="color: #66cc66;">&#40;</span>create-temp-f
                                            use-relative-base-dir
                                            use-relative-source<span style="color: #66cc66;">&#41;</span>
    <span style="color: #ff0000;">&quot;Create syntax check command line for a directly checked source file.
Use CREATE-TEMP-F for creating temp copy.&quot;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>args <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>source-file-<span style="color: #b1b100;">name</span> buffer-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>source-dir <span style="color: #66cc66;">&#40;</span>file-name-directory source-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>buildfile-dir
            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;make&quot;</span><span style="color: #66cc66;">&#41;</span>
                 <span style="color: #66cc66;">&#40;</span>flymake-init-find-makfile-dir source-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>cc <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>string<span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>file-name-extension source-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;c&quot;</span><span style="color: #66cc66;">&#41;</span>
                   <span style="color: #ff0000;">&quot;gcc&quot;</span>
                 <span style="color: #ff0000;">&quot;g++&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> buildfile-dir <span style="color: #66cc66;">&#40;</span>executable-find cc<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>temp-source-file-<span style="color: #b1b100;">name</span>
                  <span style="color: #66cc66;">&#40;</span>ignore-errors
                    <span style="color: #66cc66;">&#40;</span>flymake-init-create-temp-buffer-copy create-temp-f<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;">&#40;</span><span style="color: #b1b100;">if</span> temp-source-file-<span style="color: #b1b100;">name</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> args
                      <span style="color: #66cc66;">&#40;</span>flymake-get-syntax-check-program-args
                       temp-source-file-<span style="color: #b1b100;">name</span>
                       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> buildfile-dir buildfile-dir source-dir<span style="color: #66cc66;">&#41;</span>
                       use-relative-base-dir
                       use-relative-source
                       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> buildfile-dir
                           'flymake-get-make-cmdline
                         'flymake-get-gcc-cmdline<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span>flymake-report-fatal-status
               <span style="color: #ff0000;">&quot;TMPERR&quot;</span>
               <span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;Can't create temp file for %s&quot;</span> source-file-<span style="color: #b1b100;">name</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;">&#40;</span>flymake-report-fatal-status
         <span style="color: #ff0000;">&quot;NOMK&quot;</span> <span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;No buildfile (%s) found for %s, or can't found %s&quot;</span>
                        <span style="color: #ff0000;">&quot;Makefile&quot;</span> source-file-<span style="color: #b1b100;">name</span> cc<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      args<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-simple-make-gcc-init <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>flymake-simple-make-gcc-init-impl 'flymake-create-temp-inplace t t<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-master-make-gcc-init <span style="color: #66cc66;">&#40;</span>get-incl-dirs-f
                                       master-file-masks
                                       include-regexp<span style="color: #66cc66;">&#41;</span>
    <span style="color: #ff0000;">&quot;Create make command line for a source file
 checked via master file compilation.&quot;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>args <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>temp-master-file-<span style="color: #b1b100;">name</span>
            <span style="color: #66cc66;">&#40;</span>ignore-errors
              <span style="color: #66cc66;">&#40;</span>flymake-init-create-temp-source-and-master-buffer-copy
               get-incl-dirs-f
               'flymake-create-temp-inplace
               master-file-masks
               include-regexp<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>cc <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>string<span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>file-name-extension buffer-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;c&quot;</span><span style="color: #66cc66;">&#41;</span>
                   <span style="color: #ff0000;">&quot;gcc&quot;</span>
                 <span style="color: #ff0000;">&quot;g++&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> temp-master-file-<span style="color: #b1b100;">name</span>
          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>source-file-<span style="color: #b1b100;">name</span> buffer-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span>
                 <span style="color: #66cc66;">&#40;</span>source-dir <span style="color: #66cc66;">&#40;</span>file-name-directory source-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                 <span style="color: #66cc66;">&#40;</span>buildfile-dir
                  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;make&quot;</span><span style="color: #66cc66;">&#41;</span>
                       <span style="color: #66cc66;">&#40;</span>flymake-init-find-makfile-dir source-file-<span style="color: #b1b100;">name</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;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> buildfile-dir <span style="color: #66cc66;">&#40;</span>executable-find cc<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> args <span style="color: #66cc66;">&#40;</span>flymake-get-syntax-check-program-args
                            temp-master-file-<span style="color: #b1b100;">name</span>
                            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> buildfile-dir buildfile-dir source-dir<span style="color: #66cc66;">&#41;</span>
                            <span style="color: #b1b100;">nil</span>
                            <span style="color: #b1b100;">nil</span>
                            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> buildfile-dir
                                'flymake-get-make-cmdline
                              'flymake-get-gcc-cmdline<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span>flymake-report-fatal-status
               <span style="color: #ff0000;">&quot;NOMK&quot;</span>
               <span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;No buildfile (%s) found for %s, or can't found %s&quot;</span>
                       <span style="color: #ff0000;">&quot;Makefile&quot;</span> source-file-<span style="color: #b1b100;">name</span> cc<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;">&#40;</span>flymake-report-fatal-status
         <span style="color: #ff0000;">&quot;TMPERR&quot;</span> <span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;Can't create temp file for %s&quot;</span> source-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      args<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-master-make-gcc-header-init <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>flymake-master-make-gcc-init
     'flymake-get-include-dirs
     '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.cpp<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.c<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span><span style="color: #66cc66;">&#41;</span>
     <span style="color: #ff0000;">&quot;[ <span style="color: #000099; font-weight: bold;">\t</span>]*#[ <span style="color: #000099; font-weight: bold;">\t</span>]*include[ <span style="color: #000099; font-weight: bold;">\t</span>]*<span style="color: #000099; font-weight: bold;">\&quot;</span><span style="color: #000099; font-weight: bold;">\\</span>([[:word:]0-9/<span style="color: #000099; font-weight: bold;">\\</span>_.]*%s<span style="color: #000099; font-weight: bold;">\\</span>)<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.<span style="color: #000099; font-weight: bold;">\\</span>(?:h<span style="color: #000099; font-weight: bold;">\\</span>(?:pp<span style="color: #000099; font-weight: bold;">\\</span>)?<span style="color: #000099; font-weight: bold;">\\</span>)<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span>
                 flymake-master-make-gcc-header-init flymake-master-cleanup<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.<span style="color: #000099; font-weight: bold;">\\</span>(?:c<span style="color: #000099; font-weight: bold;">\\</span>(?:pp<span style="color: #000099; font-weight: bold;">\\</span>|xx<span style="color: #000099; font-weight: bold;">\\</span>|<span style="color: #000099; font-weight: bold;">\\</span>+<span style="color: #000099; font-weight: bold;">\\</span>+<span style="color: #000099; font-weight: bold;">\\</span>)?<span style="color: #000099; font-weight: bold;">\\</span>|CC<span style="color: #000099; font-weight: bold;">\\</span>)<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span>
                 flymake-simple-make-gcc-init<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

</div>
</div>
<div id="outline-container-5" class="outline-3">
<h3 id="sec-5"><span class="section-number-3">5</span> 检测python语法 </h3>
<div class="outline-text-3" id="text-5">
<p>
因为偶尔我也用下python，所以我也希望flymake能把python也支持了。python有三个语法检测工具，我比较之后选择了pyflakes。
</p>
<p>
装好pyflakes后，加入以下配置就可以像检测cpp那样检测py文件了：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41759code18'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4175918"><td class="code" id="p41759code18"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>executable-find <span style="color: #ff0000;">&quot;pyflakes&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> flymake-pyflakes-init <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>temp-file <span style="color: #66cc66;">&#40;</span>flymake-init-create-temp-buffer-copy
                       'flymake-create-temp-inplace<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>local-file <span style="color: #66cc66;">&#40;</span>file-relative-<span style="color: #b1b100;">name</span>
                        temp-file
                        <span style="color: #66cc66;">&#40;</span>file-name-directory buffer-file-<span style="color: #b1b100;">name</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;">&#40;</span><span style="color: #b1b100;">list</span> <span style="color: #ff0000;">&quot;pyflakes&quot;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> local-file<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;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'flymake-allowed-file-name-masks
               '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>.py<span style="color: #000099; font-weight: bold;">\\</span>'&quot;</span> flymake-pyflakes-init<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
如果是在windows下的话，可能会找不到pyflakes这个外部程序，因为C:\Python25\Scripts\pyflakes没被windows识别为可执行文件，我是在C:\Python25\Scripts\下加了个pyflakes.bat的文件，文件里写入以下内容就能正常检测了：
</p>
<pre class="example">C:\Python25\python.exe C:\Python25\Scripts\pyflakes %*
</pre>
</div>
</div>
<div id="outline-container-6" class="outline-3">
<h3 id="sec-6"><span class="section-number-3">6</span> 遗留问题 </h3>
<div class="outline-text-3" id="text-6">
<p>
有两个问题我还没解决：
</p>
<p>
一、对C++来说，找不到Makefile的时候自动改用gcc语法检测，但有时候看别人工程时会碰到有Makefile，但里面没有写check-syntax目标的问题(从网上下载的开源代码很少有在Makefile中写check-syntax目标的)。要是能配置成在Makefile中找不到check-syntax目标后也能自动改用gcc检测就好了。
</p>
<p>
二、flymake通过定时器，改变代码超过0.5秒后进行语法检测，其实我不太喜欢这种立即检测的方式，相比之下我更喜欢保存文件后进行检测。要是下个版本的flymake可以把这两种方式做成可配置就好了。
</p>
</div>
</div>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/flymake.htm' t='用flymake检测C/C++语法' d='' tag='' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>]]></content:encoded>
			<wfw:commentRss>http://emacser.com/flymake.htm/feed</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Emacs补全利器：auto-complete+gccsense</title>
		<link>http://emacser.com/emacs-gccsense.htm</link>
		<comments>http://emacser.com/emacs-gccsense.htm#comments</comments>
		<pubDate>Mon, 08 Nov 2010 03:03:02 +0000</pubDate>
		<dc:creator>ahei</dc:creator>
				<category><![CDATA[IDE]]></category>
		<category><![CDATA[中级]]></category>
		<category><![CDATA[自动补全]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41713</guid>
		<description><![CDATA[作者: Menglong Tan



1 前言 
2 简介 
3 安装 

3.1 配置auto-complete 
3.2 配置gcc-code-assist 
3.3 安装配置gccsense 


4 主要模块介绍 
5 实例 
6 附录 
7 参考 




1 前言 

搜索引擎上关于emacs代码补全的文章一大堆，大多讲的是cedet、semantic、ctags之类的。我自己也尝试过一些“主流”的组合，奈何都不来感啊。用得最长的也就auto-complete了，但是用的也仅仅是它自带的buffer内内容的补全，基本不涉及语义的补全。偶然发现了gccsense这个东西，简单配置了下，比较满意。有图有真相
我绑定的补全键到M+/，这样，遇到要补全的地方，按下M+/就出现了补全菜单，旁边是提示。




2 简介 

auto-complete提供一个补全的前端，通过不同的后端，支持ctags等。
gccsense是补全的后端，能提供符合语义的补全。因为它是直接利用gcc的代码，使用了编译器内在的分析器。它是一个独立的程序，目前通过插件可以被用到emacs和vim的补全上。因为是用的gcc的代码，理论上可以补全所有gcc支持的语言。
auto-complete和gccsense是一家出的。




3 安装 



3.1 配置auto-complete 

下载：http://cx4a.org/software/auto-complete/
配置.emacs，我的auto-complete在/mydoc/lib/emacs-plugins/下

?View Code LISP; auto complete
&#40;add-to-list 'load-path &#34;/mydoc/lib/emacs-plugins/auto-complete&#34;&#41;  
&#40;require 'auto-complete-config&#41;  
&#40;add-to-list 'ac-dictionary-directories &#34;/mydoc/lib/emacs-plugins/auto-complete/ac-dict&#34;&#41;  
&#40;ac-config-default&#41;





3.2 配置gcc-code-assist 

gcc-code-assist就是在gcc代码基础上改的，主要用来从代码中提取补全信息



下载：http://cx4a.org/software/gccsense/#Downloads
编译安装之前，准备好环境，debian系统如下：

?View Code BASHsudo apt-get install build-essential libgmp3-dev libmpfr-dev [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #0000ff;">作者: </span><a href="http://emacser.com/about.htm#crackcell" target="_blank"><span style="color: #0000ff;"><b>Menglong Tan</b></span></a></p>
<div id="table-of-contents">
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1 前言 </a></li>
<li><a href="#sec-2">2 简介 </a></li>
<li><a href="#sec-3">3 安装 </a>
<ul>
<li><a href="#sec-3_1">3.1 配置auto-complete </a></li>
<li><a href="#sec-3_2">3.2 配置gcc-code-assist </a></li>
<li><a href="#sec-3_3">3.3 安装配置gccsense </a></li>
</ul>
</li>
<li><a href="#sec-4">4 主要模块介绍 </a></li>
<li><a href="#sec-5">5 实例 </a></li>
<li><a href="#sec-6">6 附录 </a></li>
<li><a href="#sec-7">7 参考 </a></li>
</ul>
</div>
</div>
<div id="outline-container-1" class="outline-3">
<h3 id="sec-1"><span class="section-number-3">1</span> 前言 </h3>
<div class="outline-text-3" id="text-1">
<p>搜索引擎上关于emacs代码补全的文章一大堆，大多讲的是cedet、semantic、ctags之类的。我自己也尝试过一些“主流”的组合，奈何都不来感啊。用得最长的也就auto-complete了，但是用的也仅仅是它自带的buffer内内容的补全，基本不涉及语义的补全。偶然发现了gccsense这个东西，简单配置了下，比较满意。有图有真相<span id="more-41713"></span><br />
   <div class="wp-caption alignnone" style="width: 160px"><a href="https://dea.googlecode.com/svn/trunk/screenshots/emacs-gccsense.jpg" rel="lightbox"><img src="https://dea.googlecode.com/svn/trunk/screenshots/thumbs/thumbs_emacs-gccsense.jpg" height="150"/></a><p class="wp-caption-text">Emacs gccsense</p></div><br />
我绑定的补全键到M+/，这样，遇到要补全的地方，按下M+/就出现了补全菜单，旁边是提示。
</p>
</div>
</div>
<div id="outline-container-2" class="outline-3">
<h3 id="sec-2"><span class="section-number-3">2</span> 简介 </h3>
<div class="outline-text-3" id="text-2">
<p>auto-complete提供一个补全的前端，通过不同的后端，支持ctags等。<br />
gccsense是补全的后端，能提供符合语义的补全。因为它是直接利用gcc的代码，使用了编译器内在的分析器。它是一个独立的程序，目前通过插件可以被用到emacs和vim的补全上。因为是用的gcc的代码，理论上可以补全所有gcc支持的语言。<br />
auto-complete和gccsense是一家出的。
</p>
</div>
</div>
<div id="outline-container-3" class="outline-3">
<h3 id="sec-3"><span class="section-number-3">3</span> 安装 </h3>
<div class="outline-text-3" id="text-3">
</div>
<div id="outline-container-3_1" class="outline-4">
<h4 id="sec-3_1"><span class="section-number-4">3.1</span> 配置auto-complete </h4>
<div class="outline-text-4" id="text-3_1">
<p>下载：<a href="http://cx4a.org/software/auto-complete/">http://cx4a.org/software/auto-complete/</a><br />
配置.emacs，我的auto-complete在/mydoc/lib/emacs-plugins/下</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code30'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171330"><td class="code" id="p41713code30"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">; auto complete</span>
<span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'load-path <span style="color: #ff0000;">&quot;/mydoc/lib/emacs-plugins/auto-complete&quot;</span><span style="color: #66cc66;">&#41;</span>  
<span style="color: #66cc66;">&#40;</span>require 'auto-complete-config<span style="color: #66cc66;">&#41;</span>  
<span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'ac-dictionary-directories <span style="color: #ff0000;">&quot;/mydoc/lib/emacs-plugins/auto-complete/ac-dict&quot;</span><span style="color: #66cc66;">&#41;</span>  
<span style="color: #66cc66;">&#40;</span>ac-config-default<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

</p>
</div>
</div>
<div id="outline-container-3_2" class="outline-4">
<h4 id="sec-3_2"><span class="section-number-4">3.2</span> 配置gcc-code-assist </h4>
<div class="outline-text-4" id="text-3_2">
<p>gcc-code-assist就是在gcc代码基础上改的，主要用来从代码中提取补全信息
</p>
<ol>
<li>
下载：<a href="http://cx4a.org/software/gccsense/#Downloads">http://cx4a.org/software/gccsense/#Downloads</a><br />
编译安装之前，准备好环境，debian系统如下：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code31'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171331"><td class="code" id="p41713code31"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> build-essential libgmp3-dev libmpfr-dev <span style="color: #c20cb9; font-weight: bold;">flex</span> ruby rubygems libsqlite3-ruby</pre></td></tr></table></div>

<p>其它系统，如freebsd、macos请自行参考用户手册。
</li>
<li>
配置安装：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code32'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171332"><td class="code" id="p41713code32"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">tar</span> xvjf gcc-code-assist-<span style="color: #000000; font-weight: bold;">*</span>.tar.bz2  
$ <span style="color: #7a0874; font-weight: bold;">cd</span> gcc-code-assist-<span style="color: #000000; font-weight: bold;">*</span>  
$ .<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--program-suffix</span>=-code-assist <span style="color: #660033;">--enable-languages</span>=c,<span style="color: #c20cb9; font-weight: bold;">c++</span> <span style="color: #660033;">--disable-bootstrap</span> <span style="color: #660033;">--disable-multilib</span>  
$ <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #666666; font-style: italic;"># -j2  </span>
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></td></tr></table></div>

<p>安装成功之后执行下，如果有正常输出，就说明安装成功：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code33'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171333"><td class="code" id="p41713code33"><pre class="bash" style="font-family:monospace;">$ gcc-code-assist <span style="color: #660033;">--version</span>  
$ g++-code-assist <span style="color: #660033;">--version</span></pre></td></tr></table></div>

</li>
</ol>
</div>
</div>
<div id="outline-container-3_3" class="outline-4">
<h4 id="sec-3_3"><span class="section-number-4">3.3</span> 安装配置gccsense </h4>
<div class="outline-text-4" id="text-3_3">
<p>gccsense这个包包含一些辅助函数，以及编辑器的插件
</p>
<ol>
<li>
解压缩之后，执行：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code34'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171334"><td class="code" id="p41713code34"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">cd</span> gccsense-<span style="color: #000000; font-weight: bold;">*</span>
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">cp</span> bin<span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span></pre></td></tr></table></div>

</li>
<li>
执行一下命令，确保安装成功：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code35'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171335"><td class="code" id="p41713code35"><pre class="bash" style="font-family:monospace;">$ gccrec <span style="color: #660033;">--version</span> 
$ autopch <span style="color: #660033;">--version</span></pre></td></tr></table></div>

</li>
<li>
emacs的插件文件为etc/gccsense.el，放到插件目录然后，在.emacs里面加入</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code36'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171336"><td class="code" id="p41713code36"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>require 'gccsense<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>即可。<br />
由于我的gccsense.el放到了。/mydoc/lib/emacs-plugins/c下，并且把auto-complete的补全命令绑定到了M+/上，所以这部分配置如下：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code37'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171337"><td class="code" id="p41713code37"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'load-path <span style="color: #ff0000;">&quot;/mydoc/lib/emacs-plugins/c&quot;</span><span style="color: #66cc66;">&#41;</span>  
<span style="color: #66cc66;">&#40;</span>require 'gccsense<span style="color: #66cc66;">&#41;</span>  
<span style="color: #66cc66;">&#40;</span>global-set-key <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\2</span>57&quot;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">quote</span> ac-complete-gccsense<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>ok，搞定。
</li>
</ol>
</div>
</div>
</div>
<div id="outline-container-4" class="outline-3">
<h3 id="sec-4"><span class="section-number-3">4</span> 主要模块介绍 </h3>
<div class="outline-text-3" id="text-4">
<p>在介绍使用前，简单介绍下几个主要模块的作用
</p>
<ul>
<li>
gcc-code-assist<br />
gcc4.4代码基础上改的那位，用来从被补全代码中分析出补全信息
</li>
<li>
gccrec<br />
编译一个文件，往往要加上编译参数的，比如自定义的include地址。但是编辑器在补全的时候，是不知道这些的，硬生生地调用gcc-code-assist来“模拟编译”，参数补全造成的错误会扰乱补全信息的获取。<br />
gccrec就是为了解决这个问题，在使用编辑器补全之前，需要执行一次gccrec，它会将编译参数信息存到~/.gccrec这个sqlite3的数据库中。具体用法参见下一节的示例。
</li>
<li>
autopch<br />
用来启用预编译头，来提高速度。<br />
autopch的相关部分请各位看官自行参考用户手册吧，后面的示例代码简单，不需要这个东西。
</li>
</ul>
</div>
</div>
<div id="outline-container-5" class="outline-3">
<h3 id="sec-5"><span class="section-number-3">5</span> 实例 </h3>
<div class="outline-text-3" id="text-5">
<ol>
<li>
准备一个测试cpp文件，test.cpp：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code38'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171338"><td class="code" id="p41713code38"><pre class="lisp" style="font-family:monospace;">#include <span style="color: #66cc66;">&lt;</span>string<span style="color: #66cc66;">&gt;</span>  
using namespace std<span style="color: #808080; font-style: italic;">;  </span>
int main<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>  
<span style="color: #66cc66;">&#123;</span>  
    string s<span style="color: #808080; font-style: italic;">;</span>
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

</li>
<li>
使用gccrec记录编译命令</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code39'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171339"><td class="code" id="p41713code39"><pre class="bash" style="font-family:monospace;">gccrec g++-code-assist test.cpp</pre></td></tr></table></div>

<p>这里可以认为g++-code-assist就是g++，参数一样的，比如-I -l之类的。
</li>
<li>
用emacs打开test.cpp，享受补全吧<br />
在string s;后面接着输入s.，然后按M-x ac-complete-gccsense，就可以利用auto-complete和它的gccsense后端来补全了。
</li>
</ol>
</div>
</div>
<div id="outline-container-6" class="outline-3">
<h3 id="sec-6"><span class="section-number-3">6</span> 附录 </h3>
<div class="outline-text-3" id="text-6">
<p>这里贴上我的emacs相关部分的配置文件。<br />
我把补全的命令绑定到了M-/上面，<br />
gccsense.el放到了/mydoc/lib/emacs-plugins/c/下面，所以这样写：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41713code40'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4171340"><td class="code" id="p41713code40"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>add-to-<span style="color: #b1b100;">list</span> 'load-path <span style="color: #ff0000;">&quot;/mydoc/lib/emacs-plugins/c&quot;</span><span style="color: #66cc66;">&#41;</span>  
<span style="color: #66cc66;">&#40;</span>require 'gccsense<span style="color: #66cc66;">&#41;</span>  
<span style="color: #66cc66;">&#40;</span>global-set-key <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\2</span>57&quot;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">quote</span> ac-complete-gccsense<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

</p>
</div>
</div>
<div id="outline-container-7" class="outline-3">
<h3 id="sec-7"><span class="section-number-3">7</span> 参考 </h3>
<div class="outline-text-3" id="text-7">
<p>gccsense用户手册，<a href="http://cx4a.org/software/gccsense/manual.html">http://cx4a.org/software/gccsense/manual.html</a>
</p>
</div>
</div>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/emacs-gccsense.htm' t='Emacs补全利器：auto-complete+gccsense' d='' tag='' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>]]></content:encoded>
			<wfw:commentRss>http://emacser.com/emacs-gccsense.htm/feed</wfw:commentRss>
		<slash:comments>58</slash:comments>
		</item>
		<item>
		<title>在Emacs下用C/C++编程</title>
		<link>http://emacser.com/emacs-cpp-dev.htm</link>
		<comments>http://emacser.com/emacs-cpp-dev.htm#comments</comments>
		<pubDate>Mon, 25 Oct 2010 01:43:49 +0000</pubDate>
		<dc:creator>lertsau</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[中级]]></category>
		<category><![CDATA[autoload]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[CEDET]]></category>
		<category><![CDATA[control]]></category>
		<category><![CDATA[ede]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[emacser]]></category>
		<category><![CDATA[emacser.com]]></category>
		<category><![CDATA[gdb]]></category>
		<category><![CDATA[hippie-expand]]></category>
		<category><![CDATA[org]]></category>
		<category><![CDATA[screenshot]]></category>
		<category><![CDATA[semantic]]></category>
		<category><![CDATA[senator]]></category>
		<category><![CDATA[speedbar]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[行号]]></category>
		<category><![CDATA[补全]]></category>
		<category><![CDATA[配色]]></category>
		<category><![CDATA[鼠标]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41677</guid>
		<description><![CDATA[


1 参考文献 
2 序 
3 基本流程 
4 基本环境设置 

4.1 编辑环境配置 
4.2 自动补齐 


5 编译和调试程序 
6 阅读代码 




1 参考文献 


按照惯例，我写的文章在最开始处放参考文献。



hhuu @ newsmth 的《Emacs的日常生活》


emacs 的文档


emacs 相关插件的文档





2 序 


用emacs写程序也有5个年头了，深切地体会到Emacs的强大。程序员有三种，一种是用vi的，一种是用emacs的，还有一种是其他。或许有些夸张，但也颇能体现出emacs在程序员中的地位。


emacs最大的问题在于入门门槛较高。它看起来和多数人想象中的IDE相差甚远，很多人看到emacs的第一眼就觉得它是个记事本（还是个非常难用的记事本），稍微好些的往往觉得emacs也就是个ultraEditor而已，真是暴殄天物了。


我是个懒人，不喜欢记太多的快捷键，相信很多人和我一样。所以从我后面的叙述可以看出来，除了常用的命令都是快捷键外，其他命令多数都是用M-x执行或者用鼠标点菜单。这仅仅是个人风格问题，先说明一下。


我的基本编程环境是：



Debian GNU/Linux sid 操作系统


Gnome 2.10.0 桌面环境


GUN Emacs 23.0.0.1 for debian


使用 Gnu tool chains(gcc,make,gdb等等)


后面的叙述都基于上述环境。另外，本文主要针对C/C++程序开发，对其他语言有些也适用，从难度上说，本文主要针对入门者。


本文肯定会有很多错误，请指正， 谢谢。




3 基本流程 


写C++程序基本上是这么几个步骤：



编辑代码


编写Makefile


编译代码，修改编译错误


调试代码，修改逻辑错误


当然，往往还需要阅读别人的代码。


根据上述步骤，本文主要针对以下几个方面：



配置Emacs，建立便利的代码编辑环境和Makefile编写环境。


在Emacs中编译代码，并修改编译错误。


在Emacs中配合GDB调试程序。


利用cscope和ecb在emacs中阅读代码。 





4 基本环境设置 



4.1 编辑环境配置 


要写C++程序，当然要用到cc-mode插件。CC-Mode原本是支持C语言的，但现在也能支持很多语言，比如 C++，Java，Objective-C，CORBA，AWK，Pike等等。CC-Mode是gnu-emacs的标准插件。如果您要求不高，那么默认的配置或许就能满足。CC-Mode的各种行为都可以自由地定制，您可以参考这里的文档：CC-Mode参考文档


这里是我的.emacs文件中关于CC-Mode配置的部分，仅供参考：


?View Code LISP1
2
3
4
5
;;;; CC-mode配置  http://cc-mode.sourceforge.net/
&#40;require 'cc-mode&#41;
&#40;c-set-offset 'inline-open 0&#41;
&#40;c-set-offset [...]]]></description>
			<content:encoded><![CDATA[<div id="table-of-contents">
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1 参考文献 </a></li>
<li><a href="#sec-2">2 序 </a></li>
<li><a href="#sec-3">3 基本流程 </a></li>
<li><a href="#sec-4">4 基本环境设置 </a>
<ul>
<li><a href="#sec-4.1">4.1 编辑环境配置 </a></li>
<li><a href="#sec-4.2">4.2 自动补齐 </a></li>
</ul>
</li>
<li><a href="#sec-5">5 编译和调试程序 </a></li>
<li><a href="#sec-6">6 阅读代码 </a></li>
</ul>
</div>
</div>
<div id="outline-container-1" class="outline-3">
<h3 id="sec-1"><span class="section-number-3">1</span> 参考文献 </h3>
<div class="outline-text-3" id="text-1">
<p>
按照惯例，我写的文章在最开始处放参考文献。
</p>
<ul>
<li>
hhuu @ newsmth 的《Emacs的日常生活》
</li>
<li>
emacs 的文档
</li>
<li>
emacs 相关插件的文档</p>
</li>
</ul>
</div>
</div>
<div id="outline-container-2" class="outline-3">
<h3 id="sec-2"><span class="section-number-3">2</span> 序 </h3>
<div class="outline-text-3" id="text-2">
<p>
用emacs写程序也有5个年头了，深切地体会到Emacs的强大。程序员有三种，一种是用vi的，一种是用emacs的，还有一种是其他。或许有些夸张，但也颇能体现出emacs在程序员中的地位。<span id="more-41677"></span>
</p>
<p>
emacs最大的问题在于入门门槛较高。它看起来和多数人想象中的IDE相差甚远，很多人看到emacs的第一眼就觉得它是个记事本（还是个非常难用的记事本），稍微好些的往往觉得emacs也就是个ultraEditor而已，真是暴殄天物了。
</p>
<p>
我是个懒人，不喜欢记太多的快捷键，相信很多人和我一样。所以从我后面的叙述可以看出来，除了常用的命令都是快捷键外，其他命令多数都是用M-x执行或者用鼠标点菜单。这仅仅是个人风格问题，先说明一下。
</p>
<p>
我的基本编程环境是：
</p>
<ul>
<li>
Debian GNU/Linux sid 操作系统
</li>
<li>
Gnome 2.10.0 桌面环境
</li>
<li>
GUN Emacs 23.0.0.1 for debian
</li>
<li>
使用 Gnu tool chains(gcc,make,gdb等等)</p>
</li>
</ul>
<p>后面的叙述都基于上述环境。另外，本文主要针对C/C++程序开发，对其他语言有些也适用，从难度上说，本文主要针对入门者。
</p>
<p>
本文肯定会有很多错误，<a href="mailto:caole82@gmail.com">请指正</a>， 谢谢。
</p>
</div>
</div>
<div id="outline-container-3" class="outline-3">
<h3 id="sec-3"><span class="section-number-3">3</span> 基本流程 </h3>
<div class="outline-text-3" id="text-3">
<p>
写C++程序基本上是这么几个步骤：
</p>
<ol>
<li>
编辑代码
</li>
<li>
编写Makefile
</li>
<li>
编译代码，修改编译错误
</li>
<li>
调试代码，修改逻辑错误</p>
</li>
</ol>
<p>当然，往往还需要阅读别人的代码。
</p>
<p>
根据上述步骤，本文主要针对以下几个方面：
</p>
<ul>
<li>
配置Emacs，建立便利的代码编辑环境和Makefile编写环境。
</li>
<li>
在Emacs中编译代码，并修改编译错误。
</li>
<li>
在Emacs中配合GDB调试程序。
</li>
<li>
利用cscope和ecb在emacs中阅读代码。 </p>
</li>
</ul>
</div>
</div>
<div id="outline-container-4" class="outline-3">
<h3 id="sec-4"><span class="section-number-3">4</span> 基本环境设置 </h3>
<div class="outline-text-3" id="text-4">
</div>
<div id="outline-container-4.1" class="outline-4">
<h4 id="sec-4.1"><span class="section-number-4">4.1</span> 编辑环境配置 </h4>
<div class="outline-text-4" id="text-4.1">
<p>
要写C++程序，当然要用到cc-mode插件。CC-Mode原本是支持C语言的，但现在也能支持很多语言，比如 C++，Java，Objective-C，CORBA，AWK，Pike等等。CC-Mode是gnu-emacs的标准插件。如果您要求不高，那么默认的配置或许就能满足。CC-Mode的各种行为都可以自由地定制，您可以参考这里的文档：CC-Mode参考文档
</p>
<p>
这里是我的.emacs文件中关于CC-Mode配置的部分，仅供参考：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code52'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167752"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p41677code52"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;;;; CC-mode配置  http://cc-mode.sourceforge.net/</span>
<span style="color: #66cc66;">&#40;</span>require 'cc-mode<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>c-set-offset 'inline-open <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>c-set-offset 'friend '-<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>c-set-offset 'substatement-open <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code53'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167753"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p41677code53"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;;;;我的C/C++语言编辑策略</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> my-c-mode-common-hook<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> tab-width <span style="color: #cc66cc;">4</span> indent-tabs-mode <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">;;; hungry-delete and auto-newline</span>
  <span style="color: #66cc66;">&#40;</span>c-toggle-auto-hungry-state <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">;;按键定义</span>
  <span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>control \`<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'hs-toggle-hiding<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">return</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'newline-and-indent<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>f7<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'compile<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>meta \`<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'c-indent-command<span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">;;  (define-key c-mode-base-map [(tab)] 'hippie-expand)</span>
  <span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>tab<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'my-indent-or-complete<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>meta ?/<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'semantic-ia-complete-symbol-menu<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
注意一下，上面最后两行是代码自动补齐的快捷键。后面我会提到代码自动补齐。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code54'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167754"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code" id="p41677code54"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;;预处理设置</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> c-macro-shrink-window-flag t<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> c-macro-preprocessor <span style="color: #ff0000;">&quot;cpp&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> c-macro-cppflags <span style="color: #ff0000;">&quot; &quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> c-macro-prompt-flag t<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> hs-minor-mode t<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> abbrev-mode t<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>add-hook 'c-mode-common-hook 'my-c-mode-common-hook<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;;;;我的C++语言编辑策略</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> my-c++-mode-hook<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> tab-width <span style="color: #cc66cc;">4</span> indent-tabs-mode <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>c-set-style <span style="color: #ff0000;">&quot;stroustrup&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #808080; font-style: italic;">;;  (define-key c++-mode-map [f3] 'replace-regexp)</span>
<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

</p>
</div>
</div>
<div id="outline-container-4.2" class="outline-4">
<h4 id="sec-4.2"><span class="section-number-4">4.2</span> 自动补齐 </h4>
<div class="outline-text-4" id="text-4.2">
<p>
自动补齐通常用的都是hippie-expand，我也用了很长时间。不过有时候会觉得这个自动补齐“傻”了一点，常会补齐出一些毫不相干的东西，因为hippie-expand是根据你敲过的词和kill-ring等进行判断的，并不对程序语法进行分析。
</p>
<p>
所以你还需要安装一个代码分析工具，然后把它加进hippie-expand的扩展策略里去。我们可以用semantic。实际上，hippie-expand＋semantic是我所发现的最好的选择了，如果您有更好的，请您也告诉我一声:)
</p>
<p>
Semantic是<a href="http://cedet.sourceforge.net/" target="_blank">CEDET</a> 中的一个工具，CEDET是Collection of Emacs Development Environment Tools的缩写，它包含了好几个工具，都挺不错的。可惜我只会用其中两个。
</p>
<p>
您可以在.emacs中对Semantic进行配置，下面是我的.emacs相关的配置，仅供参考：
</p>
<p>
导入cedet：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code55'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167755"><td class="code" id="p41677code55"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>load-file <span style="color: #ff0000;">&quot;~/lib/emacs-lisp/cedet-1.0pre3/common/cedet.el&quot;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>配置Semantic的检索范围:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code56'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167756"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p41677code56"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> semanticdb-project-roots 
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span>
<span style="color: #66cc66;">&#40;</span>expand-file-<span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;/&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>自定义自动补齐命令，这部分是抄hhuu的，如果在单词中间就补齐，否则就是tab。
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code57'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167757"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p41677code57"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> my-indent-or-complete <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>looking-at <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>&gt;&quot;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span>hippie-expand <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>indent-for-tab-command<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>global-set-key <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>control tab<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'my-indent-or-complete<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
hippie的自动补齐策略，优先调用了senator的分析结果：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code58'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167758"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code" id="p41677code58"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>autoload 'senator-try-expand-semantic <span style="color: #ff0000;">&quot;senator&quot;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> hippie-expand-try-functions-<span style="color: #b1b100;">list</span>
      '<span style="color: #66cc66;">&#40;</span>
        senator-try-expand-semantic
        try-expand-dabbrev
        try-expand-dabbrev-visible
        try-expand-dabbrev-all-buffers
        try-expand-dabbrev-from-kill
        try-expand-<span style="color: #b1b100;">list</span>
        try-expand-list-all-buffers
        try-expand-line
        try-expand-line-all-buffers
        try-complete-file-name-partially
        try-complete-file-<span style="color: #b1b100;">name</span>
        try-expand-whole-kill
        <span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
注意一下我前面CC-Mode配置中有这么两行：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code59'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167759"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p41677code59"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>tab<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'my-indent-or-complete<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>meta ?/<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'semantic-ia-complete-symbol-menu<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
这样，我们在CC-Mode中就可以调用自定义的hippie补全了，快捷键是Tab。
</p>
<p>
另外，我还把快捷键“Alt + / ”绑定到了semantic-ia-complete-symbol-menu命令上，这是semantic的命令，它会根据分析结果弹出补齐的菜单，效果如图显示：
</p>
<div class="wp-caption alignnone" style="width: 160px"><a href="screenshots/semantic-ia.jpg" rel="lightbox"><img src="screenshots/thumbs/thumbs_semantic-ia.jpg" height="150"/></a><p class="wp-caption-text">自动补齐效果图</p></div>
<p>
CEDET中还有一个不错的工具是speedbar，你可以用它在多个文件中快速切换。在我的.emacs配置文件里，我把speedbar关联到了F5上：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code60'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167760"><td class="code" id="p41677code60"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>global-set-key <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>f5<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'speedbar<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>这样用F5就可以调出speedbar，效果如下：
</p>
<div class="wp-caption alignnone" style="width: 160px"><a href="screenshots/speedbar.jpg" rel="lightbox"><img src="screenshots/thumbs/thumbs_speedbar.jpg" height="150"/></a><p class="wp-caption-text">speedbar</p></div>
<p>
不过说实话，我自己很少用到speedbar，我通常都是用dired配合bookmark使用:)
</p>
</div>
</div>
</div>
<div id="outline-container-5" class="outline-3">
<h3 id="sec-5"><span class="section-number-3">5</span> 编译和调试程序 </h3>
<div class="outline-text-3" id="text-5">
<p>
按上面的配置，写完程序和Makefile文件后，在Emacs源代码窗口中按F7就可以进行编译。因为在my-c-mode-common-hook()函数里，有这么一行：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code61'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167761"><td class="code" id="p41677code61"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>f7<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'compile<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>默认情况下，emacs的compile命令是调用make -k，我把它改成了make。你也可以把它改成其他的，比如gcc之类的。改下面的“make”就行了。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41677code62'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4167762"><td class="code" id="p41677code62"><pre class="lisp" style="font-family:monospace;">'<span style="color: #66cc66;">&#40;</span>compile-command <span style="color: #ff0000;">&quot;make&quot;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>Emacs会划分一个窗格显示编译的消息，在编译结束后，emacs会自动将编译器的输出和程序关联起来，告诉你第几行的程序有问题。直接在出错的行号上按Enter，就可以跳转到相应文件的相应行。其实我通常都是用鼠标中键去点出错行号:)
</p>
<p>
搞定了编译错误后，接着要和逻辑错误斗争了。其实对简单的程序来说，把中间结果打印到终端是最简单好用的调试办法:)不过稍微复杂点的程序就会晕菜了，这时我们就需要拿gdb跟踪程序流程了。
</p>
<p>
你用下面的命令就可以启动gdb了。
</p>
<pre class="example">
M-x gdb
</pre>
<p>通常我喜欢进入gdb-many-windows模式，这样就会把一个Frame划分为5个窗格，同时显示：gdb命令窗口，当前局部变量，程序文本，调用栈和断点。
</p>
<p>
gdb的命令就不在这里说了，它的文档几乎到处都是。emacs把gdb的命令和快捷键做了绑定，对于常用的命令，还是输入快捷键比较方便。比如，C-c C-n是Next line，C-c C-s是step in，其实用的最多的快捷键也就是这两个。
</p>
<p>
下面是我的gdb效果图：
</p>
<div class="wp-caption alignnone" style="width: 160px"><a href="screenshots/gdb.jpg" rel="lightbox"><img src="screenshots/thumbs/thumbs_gdb.jpg" height="150"/></a><p class="wp-caption-text">GDB</p></div>
</div>
</div>
<div id="outline-container-6" class="outline-3">
<h3 id="sec-6"><span class="section-number-3">6</span> 阅读代码 </h3>
<div class="outline-text-3" id="text-6">
<p>
在emacs下读代码通常有三种工具，最简单的是etags，最复杂的是ecb（emacs code browser），位于中间的是cscope。
</p>
<p>
etags和ctags一样，只不过前者是用于emacs的，后者是用于vi的。我个人觉得etags功能稍稍显得不够用一点，当然，也可能是我用的不好:) 欢迎大牛指导。
</p>
<p>
使用tags之前要先对源代码分析建立tags文件，在代码所在目录中运行：etags -R 即可。
</p>
<p>
我常用的就这几个命令和快捷键：
</p>
<pre class="example">M-x visit-tags-table &lt;RET&gt; FILE &lt;RET&gt;   选择tags文件
M-. [TAG] &lt;RET&gt;                         访问标签
M-*                                     返回
C-u M-.                                 寻找标签的下一个定义
</pre>
<p>
ecb据说功能强大，但是太复杂了，我懒得折腾它。谁搞定了教教我吧:) 下面是一张ecb的效果图。
</p>
<p>
cscope是我感觉比较合适的一个工具。它其实是一个独立的软件，完全可以脱离vi和emacs使用。但是结合emacs的强大功能，cscope就显得更加方便了。GNU Emacs默认自带cscope的支持。在使用之前，cscope也需要对代码进行索引。在emacs中可以这样做：
</p>
<pre class="example">C-c s a             设定初始化的目录，一般是你代码的根目录
C-s s I             对目录中的相关文件建立列表并进行索引
</pre>
<p>
建完索引之后，你就可以用cscope在代码里游荡了。常用的一些命令如下：
</p>
<pre class="example">C-c s s             序找符号
C-c s g             寻找全局的定义
C-c s c             看看指定函数被哪些函数所调用
C-c s C             看看指定函数调用了哪些函数
C-c s e             寻找正则表达式
C-c s f             寻找文件
C-c s i             看看指定的文件被哪些文件include
</pre>
<p>
上面这些快捷键其实我自己也常常记不全，没关系，抬头看看上面的菜单栏，有一栏就是Cscope，这些命令里头都有:)
</p>
<p>
贴一个cscope的效果图吧:
</p>
<div class="wp-caption alignnone" style="width: 160px"><a href="screenshots/cscope.jpg" rel="lightbox"><img src="screenshots/thumbs/thumbs_cscope.jpg" height="150"/></a><p class="wp-caption-text">cscope</p></div>
<p>
写完了。希望这篇文章对您能有一些用处。有问题或建议可以和<a href="mailto:caole82@gmail.com">我</a> 联系。
</p>
</div>
</div>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/emacs-cpp-dev.htm' t='在Emacs下用C/C++编程' d='' tag='autoload,browser,C/C++,CEDET,control,ede,Emacs,emacser,emacser.com,gdb,hippie-expand,IDE,org,screenshot,semantic,senator,speedbar,windows,插件,行号,补全,配色,鼠标' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>
	<h4>相关日志</h4>
	<ul class="st-related-posts">
	<li><a href="http://emacser.com/cedet.htm" title="用CEDET浏览和编辑C++代码 (2010年03月18日)">用CEDET浏览和编辑C++代码</a> (198)</li>
	<li><a href="http://emacser.com/dea.htm" title="我的Emacs配置文件 － DEA (2009年11月11日)">我的Emacs配置文件 － DEA</a> (352)</li>
	<li><a href="http://emacser.com/built-in-cedet.htm" title="用CEDET浏览和编辑C++代码(续) &#8211; 使用Emacs 23.2内置的CEDET (2010年05月10日)">用CEDET浏览和编辑C++代码(续) &#8211; 使用Emacs 23.2内置的CEDET</a> (99)</li>
	<li><a href="http://emacser.com/from-vi-to-emacs.htm" title="我是如何从vim转向Emacs的 (2010年04月27日)">我是如何从vim转向Emacs的</a> (55)</li>
	<li><a href="http://emacser.com/emacs.htm" title="Emacs长啥样 (2009年11月5日)">Emacs长啥样</a> (16)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://emacser.com/emacs-cpp-dev.htm/feed</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>Emacs开发VC程序</title>
		<link>http://emacser.com/dev-vc.htm</link>
		<comments>http://emacser.com/dev-vc.htm#comments</comments>
		<pubDate>Fri, 17 Sep 2010 15:07:03 +0000</pubDate>
		<dc:creator>fangzhzh</dc:creator>
				<category><![CDATA[IDE]]></category>
		<category><![CDATA[中级]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[CEDET]]></category>
		<category><![CDATA[compile]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[ede]]></category>
		<category><![CDATA[edit]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[emacser]]></category>
		<category><![CDATA[emacser.com]]></category>
		<category><![CDATA[gud]]></category>
		<category><![CDATA[org]]></category>
		<category><![CDATA[progrmming]]></category>
		<category><![CDATA[snippet]]></category>
		<category><![CDATA[studio]]></category>
		<category><![CDATA[term]]></category>
		<category><![CDATA[vc]]></category>
		<category><![CDATA[Visual]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[yasnippet]]></category>
		<category><![CDATA[光标]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[补全]]></category>
		<category><![CDATA[配色]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41548</guid>
		<description><![CDATA[  vimers都说emacs慢，Eclipse, Visual Studio, Netbeans笑而不语。
                                 -- 佚名


背景

前些日子，微软宣布Visual studio 2010的EMACS扩展。此前，Visual studio 2005 6.01已然引入了Emacs的键盘模拟，这次又将Visual studio 的Emacs化更进一步，这种事发生在Microsoft这样无利不起早的企业,原因呢,你懂得。
话说，武功再高，也怕菜刀。Emacs玩的再溜，也保不齐哪天你要去开发Visual studio 程序。习惯了Emacs的高效，使用Visual studio 就是一个杯具1。这种情况，一般一颗红心，两手准备。一颗红心：cosplay，两手准备：1.Visual studio 扮Emacs 2Emacs扮Visual studio [...]]]></description>
			<content:encoded><![CDATA[<pre>  vimers都说emacs慢，Eclipse, Visual Studio, Netbeans笑而不语。
                                 -- 佚名</pre>
<p><img class="alignright" src="screenshots/microsoft_visual_studio.jpg" alt="" /></p>
<div class="outline-3">
<h3 id="sec-1">背景</h3>
<div class="outline-text-3">
<p>前些日子，<a href="http://blogs.msdn.com/b/visualstudio/archive/2010/09/01/emacs-emulation-extension-now-available.aspx" target="_blank">微软宣布Visual studio 2010的EMACS扩展</a>。此前，<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a><del>2005</del> 6.0<sup><a class="footref" name="fnr.1" href="#fn.1">1</a></sup>已然引入了<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>的键盘模拟，这次又将<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>的<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>化更进一步，这种事发生在<a href="http://www.microsoft.com/en/us/default.aspx" target="_blank">Microsoft</a>这样无利不起早的企业,原因呢,你懂得。<span id="more-41548"></span><br />
话说，武功再高，也怕菜刀。<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>玩的再溜，也保不齐哪天你要去开发<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>程序。习惯了<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>的高效，使用<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>就是一个杯具<sup><a class="footref" name="fnr.1" href="#fn.1">1</a></sup>。这种情况，一般一颗红心，两手准备。一颗红心：cosplay，两手准备：1.<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>扮<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a> 2<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>扮<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>。</p>
</div>
<div class="outline-4">
<h4 id="sec-1_1">VC扮EMACS</h4>
<div class="outline-text-4">
<ul>
<li> 非官方扩展式<a href="http://sourceforge.net/projects/visEMACS/" target="_blank">visEMACS</a></li>
<li> 官方的<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>扩展<sup><a class="footref" name="fnr.2" href="#fn.2">2</a></sup></li>
</ul>
<p>不过，我对这种方式的经验总结：享受不到<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>的周到体贴，却净受VS的大小姐脾气了。不给力啊，不给力。不过，作为出差旅行，远程登陆，客户服务时，没有<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>可用时，让<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>模拟一把<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>，也不失为一种没有办法的好办法了。</p>
<p>这个方法不是本文的重点，所以不深入。</p>
</div>
</div>
<div class="outline-4">
<h4 id="sec-1_2">EMACS扮VC</h4>
</div>
</div>
<div class="outline-3">
<h3 id="sec-2">配置EMACS为IDE</h3>
<div class="outline-text-3">
<p>一个基本的IDE，必备功能：编辑，编译，调试。</p>
</div>
<div class="outline-4">
<h4 id="sec-2_1">编辑</h4>
<div class="outline-text-4">
<p>应该很多人都很眼红<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio</a>的销魂的插件<a href="http://www.wholetomato.com/" target="_blank">visual assist x</a>吧。实时语法检查，快速打开文件，h,cpp文件，回到刚才编辑的地方，函数跳转，自动补全，插入模板。</p>
<p>可以号称操作系统的<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>怎么可能没有这些功能呢？尽管这些不在本文范围，但是稍稍提及功能在<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>中的对应，有兴趣想深入的请<a href="#www.google.com">Google</a>, <a href="#www.duckduckgo.com">Duckduckgo</a>, <a href="#www.wikipedia.com">Wikipedia</a>.</p>
<table border="2" cellspacing="0" cellpadding="6" rules="groups">
<caption> </caption>
<col align="left"></col>
<col align="left"></col>
<tbody>
<tr>
<td>VAX功能</td>
<td>EMACS对应功能</td>
</tr>
<tr>
<td>实时语法检查</td>
<td><a href="http://flymake.sourceforge.net/" target="_blank">Flymake</a> <sup><a class="footref" name="fnr.3" href="#fn.3">3</a></sup></td>
</tr>
<tr>
<td>快速打开文件</td>
<td><a href="http://ecb.sourceforge.net/" target="_blank">ECB</a>, <a href="#sec-2_1_1">快速打开文件</a></td>
</tr>
<tr>
<td>h,cpp跳转</td>
<td><a href="http://cedet.sourceforge.net/" target="_blank">CEDET</a> <sup><a class="footref" name="fnr.4" href="#fn.4">4</a></sup></td>
</tr>
<tr>
<td>回到刚才编辑的地方</td>
<td>Recent-jump<sup><a class="footref" name="fnr.5" href="#fn.5">5</a></sup></td>
</tr>
<tr>
<td>函数跳转</td>
<td><a href="http://cedet.sourceforge.net/" target="_blank">CEDET</a> <sup><a class="footref" name="fnr.4.2" href="#fn.4">4</a></sup></td>
</tr>
<tr>
<td>自动补全</td>
<td><a href="http://www.emacswiki.org/emacs/AutoComplete" target="_blank">Auto-complete</a> <sup><a class="footref" name="fnr.6" href="#fn.6">6</a></sup></td>
</tr>
<tr>
<td>插入模板</td>
<td><a href="http://code.google.com/p/yasnippet/" target="_blank">Yasnippet</a> <sup><a class="footref" name="fnr.7" href="#fn.7">7</a></sup></td>
</tr>
</tbody>
</table>
<ul>
<li>快速打开文件<br />
至于快速打开文件一项，我感觉<a href="http://ecb.sourceforge.net/" target="_blank">ECB</a>做的并不是特别好，如果C++程序的头文件和实现文件没有在一个文件夹，很难找到。所以我用了一个比较笨的方法，生成文件的列表到一个文件，使用<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>的查找功能和打开当前光标下文件的功能 find-file-at-point，我把它编定到了C-c C-f。这个过程还有两个副产物供cscope和etags用。确认你的机器上有cscope, find, etags<sup><a class="footref" name="fnr.8" href="#fn.8">8</a></sup>,将以下代码成为uptags.bat，放到系统的pathz中的某个文件夹下。</p>
<pre>%1
cd %2
rm TAGS
rm cscope.files
rm filelist.txt
rm cscope.in.out
rm cscope.out
rm cscope.po.out
if "%3" EQU "java" set PARAM=-name "*.java" -print
if "%3" EQU "c++" set PARAM=-name "*.cpp" -print -o -name "*.r" -print -o -name "*.[hcrHs]" -print -o -name "*.hpp" -print -o -name "*.lua" -print
echo %PARAM%
find . %PARAM% &gt; cscope.files
less cscope.files | xargs etags -aR
cscope -bkq -i cscope.files
cp cscope.files filelist.txt
find . -name "*.txt" -print &gt;&gt;  filelist.txt</pre>
<p>假设我们的C++工程在d:\mydocuments\workspace\cpp\，那么调用方法<sup><a class="footref" name="fnr.9" href="#fn.9">9</a></sup>为：</p>
<pre>uptags d: d:\mydocuments\workspace\cpp\ c++</pre>
<p>java工程在d:\mydocuments\workspace\java\， 那么调用方法为：</p>
<pre>uptags d: d:\mydocuments\workspace\java\ java</pre>
<p>那么打开文件helloworld.cpp的操作就是：C-x b filelist.txt , C-s helloworld.cpp, C-c C-f, RET。确实，稍显复杂，期待有更好的方法。</li>
</ul>
</div>
</div>
<div class="outline-4">
<h4 id="sec-2_2">编译</h4>
<div class="outline-text-4">
<p>编译的话基本上还是要靠<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>自带的工具：nmake<sup><a class="footref" name="fnr.10" href="#fn.10">10</a></sup>，msdev。本文主要介绍msdev。</p>
<ul>
<li>使用msdev.exe<br />
msdev.exe位于安装路径下的bin目录，如我本机使用<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>6.0，目录为&#8221;C:\Program Files\Microsoft Visual Studio\VC98\bin&#8221;。 直接调用msdev.exe，即启动<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio</a>的UI界面，同时msdev.exe也接受命令行调用。我们看其帮助。</p>
<pre>msdev /?
msdev /?
Usage:
  MSDEV [myprj.dsp|mywksp.dsw]    - load project/workspace
    []        - load source file
    /?            - display usage information
    /EX         - execute a VBScript macro
    /OUT         - redirect command line output to a file
    /USEENV            - ignore tools.options.directories settings
    /MAKE [] [...]    - build specified target(s)
          [
 -
 ]
          [[
|ALL] - [DEBUG|RELEASE|ALL]]
          /CLEAN        - delete intermediate files but don't build
          /REBUILD        - clean and build
          /NORECURSE    - don't build dependent projects</pre>
<p>假设我们有这么一个工程，路径为d:\Mydocuments\workbench\，工程目录结构，Configuration如下图<br />
<a href="http://emacser.com/uploads/sampleWorkspace.png"><img class="alignnone size-medium wp-image-41551" src="http://emacser.com/uploads/sampleWorkspace-300x268.png" alt="" width="300" height="268" /></a></li>
<li>可以通过命令msdev.exe来编译工程test2<sup><a class="footref" name="fnr.11" href="#fn.11">11</a></sup>。
<pre>C:\Program Files\Microsoft Visual Studio\VC98\bin\msdev.exe test2.dsw /Make  /NORECURSE</pre>
<p>同样，使用clean，rebuild可以清除、重编译该工程。将test2 改为test21，test23，即改变编译对象。 总这样写也很麻烦，而且为了在<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>中调用 ，我们将其写成一个批处理。</p>
<pre>d:
cd  d:\Mydocuments\workbench\
set project=%1
set target=%2
if  ==  set project=test2
if  ==  set target=/NORECURSE
msdev test2.dsw /Make  %target%</pre>
<p>保存为makTest2.bat。调用方式为：</p>
<pre>makeTest2 [工程 [目标]]</pre>
<p>默认为编译test2 的 /NORECURSE。如果要编译test23的rebuild，调用方式为：</p>
<pre>makeTest2 test23 /REBUILD</pre>
</li>
</ul>
</div>
</div>
<div class="outline-4">
<h4 id="sec-2_3">调试</h4>
<div class="outline-text-4">
<p>实际上，如果有了编辑，编译，那么调试就不需要了。因为调试器是一切罪恶他妈<sup><a class="footref" name="fnr.12" href="#fn.12">12</a></sup>。</p>
<p>哈哈，当然是开玩笑的了。作为一个有思想的程序员，要认清楚，编译器，调试器都只是恶魔，程序员本身，也就是我们，才是恶魔他妈（当然大部分是他爹^_^ ）。</p>
<p>哈哈，那么作为恶魔的产生者，我们当然要丰富自己的技能，而调试就是一个必杀技。我杀，bug闪……..</p>
<ul>
<li>cdb-gud<br />
要用<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>调试<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>的程序，首先需要一个el – <a href="http://www.emacswiki.org/emacs/grandunifieddebugger#toc5" target="_blank">cdb-gud.el</a> 。cdb-gud使用<a href="http://www.microsoft.com/en/us/default.aspx" target="_blank">Microsoft</a>的命令行调试器cdb来调试程序。 cdb-gud.el只需下载，然后在.emacs中使用下面语句，cdb-gud就随时待命了。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41548code67'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4154867"><td class="code" id="p41548code67"><pre class="lisp" style="font-family:monospace;"> +cdb <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>http<span style="color: #66cc66;">:</span>//msdn<span style="color: #66cc66;">.</span>microsoft<span style="color: #66cc66;">.</span>com/en-us/vstudio/default<span style="color: #66cc66;">.</span>aspx<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span>Visual studio <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">eq</span> system-type 'windows-nt<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>load-file <span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>调用cdb-gud: M-x cdb RET。</li>
<li><a href="http://www.microsoft.com/en/us/default.aspx" target="_blank">Microsoft</a>命令行调试器cdb.exe<br />
如果你是一个Windows程序员，Windbg听说过吗？如果没有听说过，我建议你去看看《<a href="http://book.douban.com/subject/3088353/" target="_blank">软件调试</a>》，这本书讲的非常的透彻。 注意，这是一本厚度为1000页的砖头书。如果你没有耐心去读这么厚的书，那么还有一个选择，《<a href="http://book.douban.com/subject/2302201/" target="_blank">Windows用户态程序高效排错</a>》， 内容236页，内容写的不多，但是书内提供的资源。 两本书排名不分先后。那么cdb就在Windbg的安装目录下。Windbg是Windows下的能用户态调试核心态调试的强大的图形界面的调试器。那么，简而言之，尽管不太准确<sup><a class="footref" name="fnr.13" href="#fn.13">13</a></sup>，cdb就是非图形界面的调试用户态程序的windbg。</p>
<p>简要介绍一下cdb：cdb就是一个命令行的调试器，over。</p>
<p>深入探讨一学cdb: 我想很深入的探讨一下cdb，但是实在是没有如此深厚的内功，但是我可以推荐一些内容供有兴趣的去深入。</p>
<ul>
<li> WINDBG安装目录内的debugger.chm</li>
<li> <a href="http://windbg.info/doc/1-common-cmds.html" target="_blank">windbg info</a></li>
<li> <a href="http://msdn.microsoft.com/en-us/library/ff551063.aspx" target="_blank">MSDN的帮助</a></li>
</ul>
<p>强烈推荐将<a href="http://windbg.info/doc/1-common-cmds.html" target="_blank">windbg info</a> 打印出来在手边供不时查阅之需。</p>
<p>现在，来启动cdb-gud吧：M-x cdb RET</p>
<p>Showtime<sup><a class="footref" name="fnr.14" href="#fn.14">14</a></sup>!</li>
<li>例子<br />
建立一个<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx" target="_blank">Visual studio </a>的console典型的Hello world工程（比如刚才的test2），源代码如下<sup><a class="footref" name="fnr.15" href="#fn.15">15</a></sup>：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41548code68'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4154868"><td class="code" id="p41548code68"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &quot;stdafx.h&quot;</span>
<span style="color: #339933;">#include</span>
<span style="color: #993333;">void</span> assign <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #993333;">int</span> n<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> n<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      a<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span> argv<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  assign<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #339933;">,</span> a<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>通过上边程序，我们期待打出所有0-99的数，每个数是间隔一个制表符，每十个数打出一个换行。</p>
<p>我们编译运行代码，得到结果：</p>
<pre>-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460
-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460
-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460
-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460
-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460
-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460
-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460
-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460
-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460
-858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460  -858993460</pre>
<p>有点奇怪，为什么没有得到我们需要的东西呢？？</p>
<p>从代码中貌似看不到直接的证据证明我们的代码逻辑的错误。我们就祭出cdb。</p>
<p>M-x cdb RET</p>
<p>minibuffer: cdb d:\Mydocuments\workbench\test2\debug\test2.exe 会有以下界面提示。</p>
<pre>Microsoft (R) Windows Debugger Version 6.11.0001.404 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: d:/Mydocuments/workbench/tmp/VCTest/test2/test/Debug/test.exe
Symbol search path is: C:\symbolsXpSp3;d:/Mydocuments/workbench/via/helios/coyote/Bin/MULTIMEDIA_PRO_240x320_Debug
Executable search path is:
*** WARNING: Unable to verify checksum for test.exe
ModLoad: 00400000 0042c000   test.exe
ModLoad: 7c900000 7c9b2000   ntdll.dll
ModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dll
(a90.1eb8): Break instruction exception - code 80000003 (first chance)
eax=00241eb4 ebx=7ffd9000 ecx=00000000 edx=00000001 esi=00241f48 edi=00241eb4
eip=7c90120e esp=0012fb20 ebp=0012fc94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
ntdll!DbgBreakPoint:
7c90120e cc              int     3
0:000&gt; cdb: Reading initial command 'l+*;l-s'
Source options are ffffffff:
     1/t - Step/trace by source line
     2/l - List source line at prompt
     4/s - List source code at prompt
     8/o - Only show source code at prompt
Source options are fffffffb:
     1/t - Step/trace by source line
     2/l - List source line at prompt
     8/o - Only show source code at prompt
0:000&gt;</pre>
<pre>0:000: bp main</pre>
<p>bp 表示打断点，断点的方式有几种：函数名，文件行数，内存地址。</p>
<p>但是我最喜欢的还是：当调试过程已经在运行，*在<a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a>中打开文件，走到需要打断点的行，C-x space*，断点就打到该行，很给力啊。</p>
<pre>Breakpoint 0 hit
test!main:
0040d880 55              push    ebp
0:000&gt; p
test!main+0x1e:
0040d89e 6a64            push    64h
0:000&gt; t
test!ILT+15(?assignYAXQAHHZ):
00401014 e907c80000      jmp     test!assign (0040d820)
0:000&gt; p
test!assign:
0040d820 55              push    ebp
0:000&gt; p
test!assign+0x18:
0040d838 c745fc00000000  mov     dword ptr [ebp-4],0  ss:0023:0012fd8c=cccccccc</pre>
<p>g==go，所以表示开始运行程序。</p>
<p>p 单步跟踪，不进入子函数。</p>
<p>t 单步跟踪，但是进入子函数。</p>
<p>不出意外，当你使用p或者t跟踪程序的时候，源代码窗口已经打开，同时随着跟踪，相应的代码行也会高亮。</p>
<pre>0:000&gt; dv
              a = 0x0012fdf0
              n = 100
              i = -858993460
0:000&gt; p
test!assign+0x32:
0040d852 8b55fc          mov     edx,dword ptr [ebp-4] ss:0023:0012fd8c=00000000
0:000&gt; dv
              a = 0x0012fdf0
              n = 100
              i = 0
0:000&gt; dt a[0]
Local var @ 0x12fd98 Type a[ 100]
[0] 0x0012fdf0
 -&gt; -858993460
0:000&gt; dt a[1]
Local var @ 0x12fd98 Type a[0]
[1] 0x0012fdf0
 -&gt; -858993460
0:000&gt; dt a[i]
Local var @ 0x12fd98 Type a[1]
[0] 0x0012fdf0
 -&gt; -858993460</pre>
<p>dv：显示当前的局部变量。</p>
<p>dt: 显示指定的变量。</p>
<p>当前发现为什么a数组的值怎么是负数，不是期待的0呢？</p>
<pre>0:000&gt; k
ChildEBP RetAddr
0012fd90 0040d8ac test!assign+0x32 [D:\Mydocuments\workbench\tmp\VCTest\test2\test\test.cpp @ 10]
0012ff80 00401209 test!main+0x2c [D:\Mydocuments\workbench\tmp\VCTest\test2\test\test.cpp @ 21]
0012ffc0 7c817077 test!mainCRTStartup+0xe9 [crt0.c @ 206]
WARNING: Stack unwind information not available. Following frames may be wrong.
0012fff0 00000000 kernel32!RegisterWaitForInputIdle+0x49
0:000&gt; .frame 1
01 0012ff80 00401209 test!main+0x2c [D:\Mydocuments\workbench\tmp\VCTest\test2\test\test.cpp @ 21]
0:000&gt; dv
           argc = 1
              i = -858993460
Type information missing error for a
0:000&gt;</pre>
<p>k：打印出当前的栈内容</p>
<p>.frame：跳转到栈中的第几帧，当前为第0帧。</p>
<p>在.frame 1后，我们注意到以下代码：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41548code69'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4154869"><td class="code" id="p41548code69"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>貌似a[ 100]没有初始化吧。</p>
<pre>0:000&gt; q</pre>
<p>然后修改代码后</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41548code70'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4154870"><td class="code" id="p41548code70"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &quot;stdafx.h&quot;</span>
<span style="color: #339933;">#include</span>
<span style="color: #993333;">void</span> assign <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #993333;">int</span> n<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> n<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      a<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span> argv<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  assign<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">%</span> <span style="color: #0000dd;">10</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #339933;">,</span> a<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>编译运行，结果：</p>
<pre>test\debug\test.exe

0 1 2 3 4 5 6 7 8 9
10  11  12  13  14  15  16  17  18  19
20  21  22  23  24  25  26  27  28  29
30  31  32  33  34  35  36  37  38  39
40  41  42  43  44  45  46  47  48  49
50  51  52  53  54  55  56  57  58  59
60  61  62  63  64  65  66  67  68  69
70  71  72  73  74  75  76  77  78  79
80  81  82  83  84  85  86  87  88  89
90  91  92  93  94  95  96  97  98  99</pre>
<p>那么cdb简单使用就介绍完了。</p>
<p>然而，其实很多cdb的强大功能都没有介绍到：</p>
<ul>
<li> 可以调试程序崩溃时留下的内存转储文件dump，调出其堆栈休息。</li>
<li> 可以附挂到一个正在运行的程序。</li>
<li> 远程调试</li>
<li> 显示，执行代码</li>
<li> 处理断点（支持复杂的条件断点）</li>
<li> 读写内存地址</li>
<li> 反汇编</li>
<li> 多线程调试</li>
</ul>
</li>
<li>Windows符号文件<br />
对于一般的console程序，可能这样就够了。但是在调试广大的Windows程序时，哪能不接触Windows的API啊，调试这些个玩意儿，才是让人头痛的东西呢，没有源代码！！cdb的一个机制可以让你没有源代码的情况下看到很多Windows的公开数据结构。</p>
<p>首先，先查看自己的系统的版本，在我的电脑-&gt;右键-&gt;属性，我可以看到我的系统是Microsoft Windos XP Professional Service Pace 3， 那么我就来<a href="http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx" target="_blank">这里</a>下载Windows的相应的符号文件。</p>
<p>将其安装到本机，比如：C:\symbolsXpSp3。添加环境变量：_NT_ALT_SYMBOL_PATH，设其值为安装目录。</p>
<p>经此设置，cdb在调试时就可以看到Windows API的符号文件。更多内容，还请参考帮助文档或者我推荐的两本书。</li>
</ul>
</div>
</div>
</div>
<div>
<h2 class="footnotes">Footnotes:</h2>
<div>
<p class="footnote"><sup><a class="footnum" name="fn.1" href="#fnr.1">1</a></sup> <a href="http://www.sethi.org/classes/comp270/lab_notes/lab_02_introduction_visual_cpp.html">@木鱼指出</a> 6.0中的Epsilon即为emacs模式。 <del>可查到资料中最早的是2005，</del> <a href="http://msdn.microsoft.com/en-us/library/ms165509%28VS.80%29.aspx">来源猛击我</a>。 <del>但是有可能更早，如果有资料，麻烦请留言告之.</del></p>
<p class="footnote"><sup><a class="footnum" name="fn.2" href="#fnr.2">2</a></sup> 此处没有贬低<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx">Visual studio </a>的意思，只是我中<a href="http://www.gnu.org/software/emacs/">Emacs</a>的毒已太深，用其它什么都不爽:)</p>
<p class="footnote"><sup><a class="footnum" name="fn.3" href="#fnr.3">3</a></sup> 下载链接<a href="http://visualstudiogallery.msdn.microsoft.com/en-us/09dc58c4-6f47-413a-9176-742be7463f92">Visual studio Emacs emulation addon</a></p>
<p class="footnote"><sup><a class="footnum" name="fn.4" href="#fnr.4">4</a></sup> flymake配置见<a href="http://marcelotoledo.com/2007/07/11/emacs-flymake/">http://marcelotoledo.com/2007/07/11/emacs-flymake/</a></p>
<p class="footnote"><sup><a class="footnum" name="fn.5" href="#fnr.5">5</a></sup> <a href="http://cedet.sourceforge.net/">CEDET</a>配置见<a href="http://emacser.com/c-cedet.htm">http://emacser.com/c-cedet.htm</a></p>
<p class="footnote"><sup><a class="footnum" name="fn.6" href="#fnr.6">6</a></sup> recent-jump 配置见<a href="http://liuminzhao.com/emacs/recent-jump-el-for-emacs/">http://liuminzhao.com/emacs/recent-jump-el-for-emacs/</a></p>
<p class="footnote"><sup><a class="footnum" name="fn.7" href="#fnr.7">7</a></sup> auto-complete 配置见<a href="http://emacser.com/auto-complete.htm">http://emacser.com/auto-complete.htm</a></p>
<p class="footnote"><sup><a class="footnum" name="fn.8" href="#fnr.8">8</a></sup> yasnippet主页<a href="http://code.google.com/p/yasnippet/">http://code.google.com/p/yasnippet/</a></p>
<p class="footnote"><sup><a class="footnum" name="fn.9" href="#fnr.9">9</a></sup> cygwin, mingw, msys, unixutils</p>
<p class="footnote"><sup><a class="footnum" name="fn.10" href="#fnr.10">10</a></sup> 好吧，我承认这个调用方法很蛋疼，如果你的工程比较少的话，其实可以将路径，程序类型什么的写到文件里，多整几个文件即可。upCppProject1Tags.bat, upCppProject2Tags.bat,upJavaPro1Tags.bat,upJavaPro2Tags.bat。</p>
<p class="footnote"><sup><a class="footnum" name="fn.11" href="#fnr.11">11</a></sup> <a href="http://www.gnu.org/software/emacs/windows/Developing-with-Emacs.html">此文</a> 介绍了如何使用nmake，但是恕我直言，我在<a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx">Visual studio </a>的安装目录里没有找到nmake。</p>
<p class="footnote"><sup><a class="footnum" name="fn.12" href="#fnr.12">12</a></sup> 如果不成功，请注意检查大小写和空格。</p>
<p class="footnote"><sup><a class="footnum" name="fn.13" href="#fnr.13">13</a></sup> 调试器，恶魔之母 <a href="http://stackoverflow.com/questions/602138/is-a-debugger-the-mother-of-all-evil">http://stackoverflow.com/questions/602138/is-a-debugger-the-mother-of-all-evil</a></p>
<p class="footnote"><sup><a class="footnum" name="fn.14" href="#fnr.14">14</a></sup> 其实，用户态的windbg是图形界面的cdb。</p>
<p class="footnote"><sup><a class="footnum" name="fn.15" href="#fnr.15">15</a></sup> 谨以此名纪念我经历的一个软件项目：Showtime 0.7。</p>
<p class="footnote"><sup><a class="footnum" name="fn.16" href="#fnr.16">16</a></sup> 请注意，这是实验代码，所以请忽略魔幻数，程序是否有意义等话题。</p>
</div>
</div>
<div>
<div>
<p class="footnote"><sup><a class="footnum" name="fn.15" href="#fnr.15">15</a></sup> 请注意，这是实验代码，所以请忽略魔幻数，程序是否有意义等话题。</p>
</div>
</div>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/dev-vc.htm' t='Emacs开发VC程序' d='' tag='C/C++,CEDET,compile,debug,development,eclipse,ede,edit,Emacs,emacser,emacser.com,gud,IDE,org,progrmming,snippet,studio,term,vc,Visual,windows,yasnippet,光标,插件,补全,配色' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>
	<h4>相关日志</h4>
	<ul class="st-related-posts">
	<li><a href="http://emacser.com/cedet.htm" title="用CEDET浏览和编辑C++代码 (2010年03月18日)">用CEDET浏览和编辑C++代码</a> (198)</li>
	<li><a href="http://emacser.com/emacs-beginner-must-know.htm" title="Emacs初学者必知必会 (2010年01月24日)">Emacs初学者必知必会</a> (9)</li>
	<li><a href="http://emacser.com/to-emacs-beginner.htm" title="致Emacs初学者 (2009年11月30日)">致Emacs初学者</a> (121)</li>
	<li><a href="http://emacser.com/dea.htm" title="我的Emacs配置文件 － DEA (2009年11月11日)">我的Emacs配置文件 － DEA</a> (352)</li>
	<li><a href="http://emacser.com/emacs-cpp-dev.htm" title="在Emacs下用C/C++编程 (2010年10月25日)">在Emacs下用C/C++编程</a> (37)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://emacser.com/dev-vc.htm/feed</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>使用doxymacs写标准代码注释</title>
		<link>http://emacser.com/doxymacs.htm</link>
		<comments>http://emacser.com/doxymacs.htm#comments</comments>
		<pubDate>Mon, 28 Jun 2010 01:36:33 +0000</pubDate>
		<dc:creator>fangzhzh</dc:creator>
				<category><![CDATA[IDE]]></category>
		<category><![CDATA[初级]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[doxymacs]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[org]]></category>
		<category><![CDATA[浏览器]]></category>
		<category><![CDATA[配色]]></category>
		<category><![CDATA[鼠标]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41433</guid>
		<description><![CDATA[doxymacs = doxygen+emacs。
如果你不知道doxygen，请移步这里，或者google之。
doxymacs 官网，现在版本是1.8.0。
特性：

从emacs中，查找某个符号的文档，显示在你选择的浏览器中。
在源代码中方便的插入Doxgen Style格式的注释。
可选：实用外部XML parser加速构建完整列表。
高亮Doxygen关键字。

特性1,3,4我用的比较少，重点介绍第二个。
安装
Doxymacs 依赖一下包:
W3      http://www.cs.indiana.edu/usr/local/www/elisp/w3/docs.html
tempo   http://www.lysator.liu.se/~davidk/elisp/
libxml2 http://www.libxml.org/
将doxymacs.el放到load-path路径下，在.emacs中加入下面语句

?View Code LISP&#40;require 'doxymacs&#41;

命令doxymacs-mode就可以启动，如让doxymacs-mode随着c/c++ mode自动启动，

?View Code LISP&#40;add-hook 'c-mode-common-hook 'doxymacs-mode&#41;

代码中插入doxygen注释
如果一切正常，那么在启动一个c/c++文件后，就进入了doxymacs-mode。
可以使用以下快捷键：



命令
英文解释
中文解释


C-c d ?
will look up documentation for the symbol under the point.
查找当前鼠标点下的符号的文档


C-c d r
will rescan your Doxygen tags file.
重新扫描tags文件


C-c d f
will insert a Doxygen comment for the next function.
为函数插入Doxygen注释


C-c d i
will [...]]]></description>
			<content:encoded><![CDATA[<p>doxymacs = doxygen+emacs。<br />
如果你不知道doxygen，请<a href="http://fangzhzh.admindigest.com/2010/06/generating-beautiful-document-for-ur-codes-using-doxygen/" target="_blank">移步这里</a>，或者google之。</p>
<p>doxymacs <a href="http://doxymacs.sourceforge.net/" target="_blank">官网</a>，现在版本是1.8.0。</p>
<p>特性：</p>
<ul>
<li>从emacs中，查找某个符号的文档，显示在你选择的浏览器中。</li>
<li>在源代码中方便的插入Doxgen Style格式的注释。</li>
<li>可选：实用外部XML parser加速构建完整列表。</li>
<li>高亮Doxygen关键字。</li>
</ul>
<p>特性1,3,4我用的比较少，重点介绍第二个。<span id="more-41433"></span></p>
<h3>安装</h3>
<p class="first">Doxymacs 依赖一下包:</p>
<p>W3      <a href="http://www.cs.indiana.edu/usr/local/www/elisp/w3/docs.html" target="_blank">http://www.cs.indiana.edu/usr/local/www/elisp/w3/docs.html</a></p>
<p>tempo   <a href="http://www.lysator.liu.se/~davidk/elisp/" target="_blank">http://www.lysator.liu.se/~davidk/elisp/</a></p>
<p>libxml2 <a href="http://www.libxml.org/" target="_blank">http://www.libxml.org/</a></p>
<p>将doxymacs.el放到load-path路径下，在.emacs中加入下面语句</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41433code75'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4143375"><td class="code" id="p41433code75"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>require 'doxymacs<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>命令doxymacs-mode就可以启动，如让doxymacs-mode随着c/c++ mode自动启动，</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41433code76'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4143376"><td class="code" id="p41433code76"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>add-hook 'c-mode-common-hook 'doxymacs-mode<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<h3>代码中插入doxygen注释</h3>
<p class="first">如果一切正常，那么在启动一个c/c++文件后，就进入了doxymacs-mode。<br />
可以使用以下快捷键：</p>
<table class="muse-table" border="2" cellpadding="5">
<tbody>
<tr>
<td>命令</td>
<td>英文解释</td>
<td>中文解释</td>
</tr>
<tr>
<td>C-c d ?</td>
<td>will look up documentation for the symbol under the point.</td>
<td>查找当前鼠标点下的符号的文档</td>
</tr>
<tr>
<td>C-c d r</td>
<td>will rescan your Doxygen tags file.</td>
<td>重新扫描tags文件</td>
</tr>
<tr>
<td>C-c d f</td>
<td>will insert a Doxygen comment for the next function.</td>
<td>为函数插入Doxygen注释</td>
</tr>
<tr>
<td>C-c d i</td>
<td>will insert a Doxygen comment for the current file.</td>
<td>为文件插入Doxygen注释</td>
</tr>
<tr>
<td>C-c d ;</td>
<td>will insert a Doxygen comment for the current member.</td>
<td>为当前成员插入Doxygen注释</td>
</tr>
<tr>
<td>C-c d m</td>
<td>will insert a blank multiline Doxygen comment.</td>
<td>插入多行注释</td>
</tr>
<tr>
<td>C-c d s</td>
<td>will insert a blank singleline Doxygen comment.</td>
<td>插入单行注释</td>
</tr>
<tr>
<td>C-c d @</td>
<td>will insert grouping comments around the current region.</td>
<td>插入环绕当前区域的注释</td>
</tr>
</tbody>
</table>
<p>到此，doxymacs基本就可以工作正常了。<br />
工作流程如下:</p>
<pre>

      +------------+            +------------+          +------------+
      |  coding    |-----------&gt;| commenting |---------&gt;| generating |
      |            |            |            |          | documents  |
      +------------+            +------------+          +------------+
</pre>
<h3>更改默认doxygen注释样式</h3>
<p class="first">方便的插入doxygen注释还不是最精彩的，最精彩的当然是用户自定义样式了。</p>
<h4>改变默认的doxygen注释类别</h4>
</p>
<p>这里我们首先修改变量doxymacs-doxygen-style，doxymacs默认是javaDoc，我们把它改为c++。</p>
<h4>定制doxygen的注释模板</h4>
<p class="first">doxymacs.el中有定义doxymacs-C++-file-comment-template,blablabla。顾名思义，此物就是c++-file-comment的模板。<br />
比如，根据我们公司注释的规定，我在.emacs中加入如下代码:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41433code77'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4143377"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p41433code77"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defconst doxymacs-C++-file-comment-template
 '<span style="color: #66cc66;">&#40;</span>
   <span style="color: #ff0000;">&quot;/******************************************************************************&quot;</span> <span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;* &quot;</span> <span style="color: #ff0000;">&quot;FILE NAME   :&quot;</span>
   <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>buffer-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span>
       <span style="color: #66cc66;">&#40;</span>file-name-nondirectory <span style="color: #66cc66;">&#40;</span>buffer-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
     <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #ff0000;">&quot; DESCRIPTION :&quot;</span><span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #ff0000;">&quot;    &quot;</span><span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #ff0000;">&quot; HISTORY     :&quot;</span><span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #ff0000;">&quot;    See Log at end of file&quot;</span><span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #ff0000;">&quot;Copyright (c) 2006, VIA Technologies, Inc.&quot;</span><span style="color: #66cc66;">&gt;</span> n
   <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #ff0000;">&quot;******************************************************************************/&quot;</span><span style="color: #66cc66;">&gt;</span> n<span style="color: #66cc66;">&#41;</span>
 <span style="color: #ff0000;">&quot;Default C++-style template for file documentation.&quot;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>这样，我在test.cpp文件，实用C-c d i，会生成如下代码</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41433code78'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4143378"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p41433code78"><pre class="cpp" style="font-family:monospace;"><span style="color: #ff0000; font-style: italic;">/******************************************************************************
 *
 * FILE NAME   :test.cpp
 *
 * DESCRIPTION :
 *
 *
 *
 * HISTORY     :
 *
 *    See Log at end of file
 *
 *Copyright (c) 2006, VIA Technologies, Inc.
 *******************************************************************************/</span></pre></td></tr></table></div>

<p>如果你使用c++的话，你还有下边几个变量需要定制，</p>
<table class="muse-table" border="2" cellpadding="5">
<tbody>
<tr>
<td>变量</td>
<td>作用</td>
</tr>
<tr>
<td>doxymacs-C++-function-comment-template</td>
<td>函数</td>
</tr>
<tr>
<td>doxymacs-C++-blank-multiline-comment-template</td>
<td>多行注释</td>
</tr>
<tr>
<td>doxymacs-C++-blank-singleline-comment-template</td>
<td>单行注释</td>
</tr>
</tbody>
</table>
<p>使用其他语言类同。</p>
<p>enjoy!</p>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/doxymacs.htm' t='使用doxymacs写标准代码注释' d='' tag='C/C++,doxymacs,Emacs,org,浏览器,配色,鼠标' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>
	<h4>相关日志</h4>
	<ul class="st-related-posts">
	<li><a href="http://emacser.com/cedet.htm" title="用CEDET浏览和编辑C++代码 (2010年03月18日)">用CEDET浏览和编辑C++代码</a> (198)</li>
	<li><a href="http://emacser.com/torture-emacs.htm" title="折腾Emacs (2010年08月17日)">折腾Emacs</a> (112)</li>
	<li><a href="http://emacser.com/dea.htm" title="我的Emacs配置文件 － DEA (2009年11月11日)">我的Emacs配置文件 － DEA</a> (352)</li>
	<li><a href="http://emacser.com/emacs-cpp-dev.htm" title="在Emacs下用C/C++编程 (2010年10月25日)">在Emacs下用C/C++编程</a> (37)</li>
	<li><a href="http://emacser.com/some-elisp-fun.htm" title="介绍一些Emacs功能强大的函数 (2010年06月7日)">介绍一些Emacs功能强大的函数</a> (18)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://emacser.com/doxymacs.htm/feed</wfw:commentRss>
		<slash:comments>65</slash:comments>
		</item>
		<item>
		<title>用CEDET浏览和编辑C++代码(续) &#8211; 使用Emacs 23.2内置的CEDET</title>
		<link>http://emacser.com/built-in-cedet.htm</link>
		<comments>http://emacser.com/built-in-cedet.htm#comments</comments>
		<pubDate>Sun, 09 May 2010 18:11:03 +0000</pubDate>
		<dc:creator>Meteor Liu</dc:creator>
				<category><![CDATA[CEDET]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[中级]]></category>
		<category><![CDATA[自动补全]]></category>
		<category><![CDATA[ahei]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[company-mode]]></category>
		<category><![CDATA[cursor]]></category>
		<category><![CDATA[ede]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[emacser]]></category>
		<category><![CDATA[emacser.com]]></category>
		<category><![CDATA[highlight]]></category>
		<category><![CDATA[imenu]]></category>
		<category><![CDATA[lambda]]></category>
		<category><![CDATA[meteor]]></category>
		<category><![CDATA[meteor1113]]></category>
		<category><![CDATA[org]]></category>
		<category><![CDATA[pulse]]></category>
		<category><![CDATA[putty]]></category>
		<category><![CDATA[screenshot]]></category>
		<category><![CDATA[semantic]]></category>
		<category><![CDATA[senator]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[代码折叠]]></category>
		<category><![CDATA[代码补全]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[补全]]></category>
		<category><![CDATA[配色]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41327</guid>
		<description><![CDATA[作者: Meteor Liu




1 前言 
2 semantic配置 

2.1 基本配置 
2.2 代码跳转 
2.3 代码补全 


3 EDE配置 
4 其它 

4.1 可视化书签 
4.2 pulse 
4.3 h/cpp切换 
4.4 代码折叠 






1 前言 


今天，emacs-23.2发布了，最大的改变就是集成进了CEDET，所以有了这个续， 介绍下build in CEDET和offical CEDET的区别，以及内置CEDET缺少某些功能的替代方案。
PS1：虽然现在官方release版本是1.0pre7，内置的CEDET用cedet-version命令看输入也是1.0pre7，可我总感觉内置的CEDET用起来比官方版本慢很多，我猜想内置的CEDET可能没升级到1.0pre7的release。


PS2：内置CEDET不支持emacs-lisp语言了，没想明白是为什么。




2 semantic配置 



2.1 基本配置 


官方的CEDET通过semantic-load-enable-minimum-features等几个函数来启动，而内置的CEDET增加了一个单独的minor mode，即semantic-mode，可以通过(semantic-mode)命令来Enable或Disable。


(semantic-mode)是通过semantic-default-submodes这个变量来决定启用哪些minor mode，默认的semantic-default-submodes包含了下面两个minor mode：



global-semantic-idle-scheduler-mode


global-semanticdb-minor-mode


根据(semantic-mode)的文档，semantic-default-submodes里可以设置下面这些minor mode：



global-semanticdb-minor-mode


global-semantic-idle-scheduler-mode


global-semantic-idle-summary-mode


global-semantic-idle-completions-mode


global-semantic-decoration-mode


global-semantic-highlight-func-mode


global-semantic-stickyfunc-mode


global-semantic-mru-bookmark-mode


可以根据自己的需要设置，比如我开启了下面4个minor mode：


?View Code LISP1
2
3
4
5
&#40;setq semantic-default-submodes '&#40;global-semantic-idle-scheduler-mode
            [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #0000ff;">作者: </span><a href="http://emacser.com/about.htm#meteor" target="_blank"><span style="color: #0000ff;"><b>Meteor Liu</b></span></a></p>
<p><img class="alignright" title="CEDET" src="screenshots/cedet/cedet-logo.png" width="200" height="90"/></p>
<div id="table-of-contents">
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1 前言 </a></li>
<li><a href="#sec-2">2 semantic配置 </a>
<ul>
<li><a href="#sec-2.1">2.1 基本配置 </a></li>
<li><a href="#sec-2.2">2.2 代码跳转 </a></li>
<li><a href="#sec-2.3">2.3 代码补全 </a></li>
</ul>
</li>
<li><a href="#sec-3">3 EDE配置 </a></li>
<li><a href="#sec-4">4 其它 </a>
<ul>
<li><a href="#sec-4.1">4.1 可视化书签 </a></li>
<li><a href="#sec-4.2">4.2 pulse </a></li>
<li><a href="#sec-4.3">4.3 h/cpp切换 </a></li>
<li><a href="#sec-4.4">4.4 代码折叠 </a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-1" class="outline-3">
<h3 id="sec-1">1 前言 </h3>
<div id="text-1">
<p>
今天，emacs-23.2发布了，最大的改变就是集成进了CEDET，所以有了这个续， 介绍下build in CEDET和offical CEDET的区别，以及内置CEDET缺少某些功能的替代方案。<span id="more-41327"></span></p>
<p>PS1：虽然现在官方release版本是1.0pre7，内置的CEDET用cedet-version命令看输入也是1.0pre7，可我总感觉内置的CEDET用起来比官方版本慢很多，我猜想内置的CEDET可能没升级到1.0pre7的release。
</p>
<p>
PS2：内置CEDET不支持emacs-lisp语言了，没想明白是为什么。
</p>
</div>
</div>
<div id="outline-container-2" class="outline-3">
<h3 id="sec-2">2 semantic配置 </h3>
<div id="text-2">
</div>
<div id="outline-container-2.1" class="outline-4">
<h4 id="sec-2.1">2.1 基本配置 </h4>
<div id="text-2.1">
<p>
官方的CEDET通过semantic-load-enable-minimum-features等几个函数来启动，而内置的CEDET增加了一个单独的minor mode，即semantic-mode，可以通过(semantic-mode)命令来Enable或Disable。
</p>
<p>
(semantic-mode)是通过semantic-default-submodes这个变量来决定启用哪些minor mode，默认的semantic-default-submodes包含了下面两个minor mode：
</p>
<ul>
<li>
global-semantic-idle-scheduler-mode
</li>
<li>
global-semanticdb-minor-mode</p>
</li>
</ul>
<p>根据(semantic-mode)的文档，semantic-default-submodes里可以设置下面这些minor mode：
</p>
<ul>
<li>
global-semanticdb-minor-mode
</li>
<li>
global-semantic-idle-scheduler-mode
</li>
<li>
global-semantic-idle-summary-mode
</li>
<li>
global-semantic-idle-completions-mode
</li>
<li>
global-semantic-decoration-mode
</li>
<li>
global-semantic-highlight-func-mode
</li>
<li>
global-semantic-stickyfunc-mode
</li>
<li>
global-semantic-mru-bookmark-mode</p>
</li>
</ul>
<p>可以根据自己的需要设置，比如我开启了下面4个minor mode：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code91'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4132791"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p41327code91"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> semantic-default-submodes '<span style="color: #66cc66;">&#40;</span>global-semantic-idle-scheduler-mode
                                  global-semanticdb-minor-mode
                                  global-semantic-idle-summary-mode
                                  global-semantic-mru-bookmark-mode<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>semantic-mode <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
另外，emacs-23.2的Tools菜单下下新增了&#8221;Source Code Parsers (Semantic)&#8221;菜单项，可以通过这个菜单项来Enable和Disable semantic-mode，和命令(semantic-mode)的功能是一样的。
</p>
<p>
此外，官方CEDET里还有其它一些minor mode，现在基本上都还可以用，比如我还打开了下面几个：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code92'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4132792"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p41327code92"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>global-semantic-highlight-edits-mode <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> window-system <span style="color: #cc66cc;">1</span> -<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>global-semantic-show-unmatched-syntax-mode <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>global-semantic-show-parser-state-mode <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
关于system-include-dir的设置，还和以前一样：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code93'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4132793"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p41327code93"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defconst user-include-dirs
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> <span style="color: #ff0000;">&quot;..&quot;</span> <span style="color: #ff0000;">&quot;../include&quot;</span> <span style="color: #ff0000;">&quot;../inc&quot;</span> <span style="color: #ff0000;">&quot;../common&quot;</span> <span style="color: #ff0000;">&quot;../public&quot;</span>
        <span style="color: #ff0000;">&quot;../..&quot;</span> <span style="color: #ff0000;">&quot;../../include&quot;</span> <span style="color: #ff0000;">&quot;../../inc&quot;</span> <span style="color: #ff0000;">&quot;../../common&quot;</span> <span style="color: #ff0000;">&quot;../../public&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>defconst win32-include-dirs
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">list</span> <span style="color: #ff0000;">&quot;C:/MinGW/include&quot;</span>
        <span style="color: #ff0000;">&quot;C:/MinGW/include/c++/3.4.5&quot;</span>
        <span style="color: #ff0000;">&quot;C:/MinGW/include/c++/3.4.5/mingw32&quot;</span>
        <span style="color: #ff0000;">&quot;C:/MinGW/include/c++/3.4.5/backward&quot;</span>
        <span style="color: #ff0000;">&quot;C:/MinGW/lib/gcc/mingw32/3.4.5/include&quot;</span>
        <span style="color: #ff0000;">&quot;C:/Program Files/Microsoft Visual Studio/VC98/MFC/Include&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>include-dirs user-include-dirs<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">eq</span> system-type 'windows-nt<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> include-dirs <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">append</span> include-dirs win32-include-dirs<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapc</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>dir<span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>semantic-add-system-include dir 'c++-mode<span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>semantic-add-system-include dir 'c-mode<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        include-dirs<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

</div>
</div>
<div id="outline-container-2.2" class="outline-4">
<h4 id="sec-2.2">2.2 代码跳转 </h4>
<div id="text-2.2">
<p>
代码跳转和官方版本一样还是用semantic-ia-fast-jump命令，不过在emacs-23.2里直接用这个命令可能会报下面的错误：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code94'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4132794"><td class="code" id="p41327code94"><pre class="text" style="font-family:monospace;">semantic-ia--fast-jump-helper: Symbol's function definition is void: semantic-analyze-tag-references</pre></td></tr></table></div>

<p>
这可能是emacs的bug，semantic-analyze-tag-references这个函数是定义在semantic/analyze/refs.el这个文件中的，而semantic/ia.el里写的是(eval-when-compile (require &#8217;semantic/analyze/refs))，所以运行时这个feature没被load进来，我们需要自己load一下：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code95'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4132795"><td class="code" id="p41327code95"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>require 'semantic/analyze/refs<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
另外，官方CEDET里semantic-ia-fast-jump后可以通过命令semantic-mrub-switch-tags来回到曾经跳转过的地方，不过在emacs-23.2里会提示：
</p>
<pre class="example">
Semantic Bookmark ring is currently empty
</pre>
<p>
这是因为semantic-ia-fast-jump会用函数push-mark把跳过的地方放到mark ring里去，官方CEDET通过定义push-mark的advice把它也放到了semantic-mru-bookmark-ring里去，semantic-mrub-switch-tags就是从semantic-mru-bookmark-ring来找位置的，但build in的CEDET里把push-mark的advice去掉了，所以semantic-mru-bookmark-ring总是空的，我的办法是把官方CEDET里对push-mark的device拷贝到我的.emacs中来：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code96'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4132796"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p41327code96"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defadvice push-mark <span style="color: #66cc66;">&#40;</span>around semantic-mru-bookmark activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Push a mark at LOCATION with NOMSG and ACTIVATE passed to `push-mark'.
If `semantic-mru-bookmark-mode' is active, also push a tag onto
the mru bookmark stack.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>semantic-mrub-push semantic-mru-bookmark-ring
                      <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span>
                      'mark<span style="color: #66cc66;">&#41;</span>
  ad-do-it<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
这样，我以前写的semantic-ia-fast-jump-back函数也能用了：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code97'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4132797"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p41327code97"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> semantic-ia-fast-jump-back <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>ring-empty-p <span style="color: #66cc66;">&#40;</span>oref semantic-mru-bookmark-ring ring<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">error</span> <span style="color: #ff0000;">&quot;Semantic Bookmark ring is currently empty&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>ring <span style="color: #66cc66;">&#40;</span>oref semantic-mru-bookmark-ring ring<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>alist <span style="color: #66cc66;">&#40;</span>semantic-mrub-ring-to-assoc-<span style="color: #b1b100;">list</span> ring<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>first <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">cdr</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">car</span> alist<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;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>semantic-equivalent-tag-p <span style="color: #66cc66;">&#40;</span>oref first tag<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>semantic-current-tag<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> first <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">cdr</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">car</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">cdr</span> alist<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>
    <span style="color: #66cc66;">&#40;</span>semantic-mrub-switch-tags first<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
对这个函数需要说明一下：网友<a href="http://fangzhzh.blogs.mu/" target="_blank">fangzhzh</a>提过可以用C-u C-space来跳回原来的mark，<a href="http://emacser.com/about.htm#ahei" target="_blank">ahei</a>说可以用C-x C-x来跳回，可我测试这两个按键好像跳得都有点乱，不能和semantic-ia-fast-jump的位置对应。我估计是这两个key是跳回push-mark函数mark的位置，而push-mark不光CEDET用。我的需求是只跳回semantic-ia-fast-jump曾经到过的地方，所以仍然保留了这个函数。
</p>
<p>
我的习惯还是绑定到F12上：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code98'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4132798"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p41327code98"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> semantic-ia-fast-jump-or-back <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&amp;</span>optional back<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>interactive <span style="color: #ff0000;">&quot;P&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> back
      <span style="color: #66cc66;">&#40;</span>semantic-ia-fast-jump-back<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>semantic-ia-fast-jump <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>define-key semantic-mode-map <span style="color: #66cc66;">&#91;</span>f12<span style="color: #66cc66;">&#93;</span> 'semantic-ia-fast-jump-or-back<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>define-key semantic-mode-map <span style="color: #66cc66;">&#91;</span>C-f12<span style="color: #66cc66;">&#93;</span> 'semantic-ia-fast-jump-or-back<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>define-key semantic-mode-map <span style="color: #66cc66;">&#91;</span>S-f12<span style="color: #66cc66;">&#93;</span> 'semantic-ia-fast-jump-back<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
这儿多出来个semantic-ia-fast-jump-or-back函数，是因为我有时候在putty里操作远程的emacs，putty里用不了S-f12这个key，所以我把f12绑定到semantic-ia-fast-jump-or-back上，这样我可以在putty里通过C-u f12来跳回。
</p>
<p>
以前的semantic-analyze-proto-impl-toggle命令还能用：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code99'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4132799"><td class="code" id="p41327code99"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>define-key semantic-mode-map <span style="color: #66cc66;">&#91;</span>M-S-f12<span style="color: #66cc66;">&#93;</span> 'semantic-analyze-proto-impl-toggle<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

</div>
</div>
<div id="outline-container-2.3" class="outline-4">
<h4 id="sec-2.3">2.3 代码补全 </h4>
<div id="text-2.3">
<p>
官方版本里可以用命令semantic-ia-complete-symbol-menu弹出semantic的补全菜单，不过这个命令在内置的CEDET里不存在了(可能是因为emacs官方版本认为这个命令只在GUI下能用，不够通用吧)。
</p>
<p>
不过，内置的CEDET倒是可以通过命令complete-symbol(默认绑定到ESC-TAB)在另一个buffer里显示可能补全的内容，像这样：
</p>
<div class="wp-caption alignnone" style="width: 160px"><a href="screenshots/cedet/emacs-semantic-complete-symbol.jpg" rel="lightbox"><img src="screenshots/cedet/thumbs/thumbs_emacs-semantic-complete-symbol.jpg" height="150"/></a><p class="wp-caption-text">semantic的complete-symbol</p></div>
<p>
如果还希望能使用补全菜单，可以使用其它插件，比如auto-complete或company-mode：company-mode-0.5已经可以支持emacs内置的CEDET了；auto-complete-1.2对内置CEDET的支持还有些问题，关于如何配置auto-complete-1.2让它支持内置的CEDET，我准备另外写文章介绍。
</p>
</div>
</div>
</div>
<div id="outline-container-3" class="outline-3">
<h3 id="sec-3">3 EDE配置 </h3>
<div id="text-3">
<p>
ede和官方版本没有区别，仍然用(global-ede-mode t)启用就行了；不过emacs-23.3的Tools菜单下新增了&#8221;Project support (EDE)&#8221;菜单项，可以完成global-ede-mode一样的功能。
</p>
</div>
</div>
<div id="outline-container-4" class="outline-3">
<h3 id="sec-4">4 其它 </h3>
<div id="text-4">
</div>
<div id="outline-container-4.1" class="outline-4">
<h4 id="sec-4.1">4.1 可视化书签 </h4>
<div id="text-4.1">
<p>
官方CEDET里的visual-studio-bookmarks在内置的CEDET里没有了，所以我现在使用<a href="http://www.nongnu.org/bm/" target="_blank">bm</a>了。
</p>
</div>
</div>
<div id="outline-container-4.2" class="outline-4">
<h4 id="sec-4.2">4.2 pulse </h4>
<div id="text-4.2">
<p>
pulse的功能在内置CEDET里还存在，不过官方CEDET里可以用pulse-toggle-integration-advice函数来切换pulse，在内置CEDET里这个函数消失了，现在的办法是设置pulse-command-advice-flag变量来切换：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code100'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41327100"><td class="code" id="p41327code100"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> window-system <span style="color: #cc66cc;">1</span> <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
另外，官方版本里对下面这些函数设置了pulse的device：
</p>
<ul>
<li>
goto-line
</li>
<li>
exchange-point-and-mark
</li>
<li>
find-tag
</li>
<li>
tags-search
</li>
<li>
tags-loop-continue
</li>
<li>
pop-tag-mark
</li>
<li>
imenu-default-goto-function</p>
</li>
</ul>
<p>内置版本里这些device都没了，所以我直接把官方版本里的advice拷贝过来了：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code101'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41327101"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code" id="p41327code101"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defadvice goto-line <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Cause the line that is `goto'd to pulse when the cursor gets there.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice exchange-point-and-mark <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Cause the line that is `goto'd to pulse when the cursor gets there.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span>
             <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">abs</span> <span style="color: #66cc66;">&#40;</span>- <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>mark<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">400</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice find-tag <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After going to a tag, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice tags-search <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After going to a hit, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice tags-loop-<span style="color: #b1b100;">continue</span> <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After going to a hit, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice pop-tag-mark <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After going to a hit, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice imenu-default-goto-<span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After going to a tag, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> pulse-command-advice-flag
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
另外，我还喜欢对下面这些函数定义pulse：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41327code102'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41327102"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code" id="p41327code102"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defadvice cua-exchange-point-and-mark <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Cause the line that is `goto'd to pulse when the cursor gets there.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span>
             <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">abs</span> <span style="color: #66cc66;">&#40;</span>- <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>mark<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">400</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice switch-to-buffer <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After switch-to-buffer, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice previous-buffer <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After previous-buffer, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice next-buffer <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After next-buffer, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice ido-switch-buffer <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After ido-switch-buffer, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<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;">&#40;</span>defadvice beginning-of-buffer <span style="color: #66cc66;">&#40;</span>after pulse-advice activate<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;After beginning-of-buffer, pulse the line the cursor lands on.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> pulse-command-advice-flag <span style="color: #66cc66;">&#40;</span>interactive-p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>pulse-momentary-highlight-one-line <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

</div>
</div>
<div id="outline-container-4.3" class="outline-4">
<h4 id="sec-4.3">4.3 h/cpp切换 </h4>
<div id="text-4.3">
<p>
官方CEDET里的eassist.el没有了，所以eassist-switch-h-cpp也没了，现在我用<a href="http://www.hendawi.com/emacs/sourcepair.el" target="_blank">sourcepair</a>代替，sourcepair比eassist-switch-h-cpp更好用。
</p>
</div>
</div>
<div id="outline-container-4.4" class="outline-4">
<h4 id="sec-4.4">4.4 代码折叠 </h4>
<div id="text-4.4">
<p>
semantic-tag-folding.el没有了，可我没找到其它更好的替代方案，所以我把官方CEDET里的semantic-tag-folding.el拷过来了，只需要把文件中(require &#8217;semantic-decorate-mode)替换成(require &#8217;semantic/decorate/mode)就能像以前一样用了。
</p>
<p>
以前的senator-fold-tag功能还可以使用。
</p>
<p>
最后插播个广告，我关于内置CEDET的配置(最后那部分)：<a href="http://github.com/meteor1113/dotemacs/blob/master/init-basic.el" target="_blank">http://github.com/meteor1113/dotemacs/blob/master/init-basic.el</a>
</p>
</div>
</div>
</div>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/built-in-cedet.htm' t='用CEDET浏览和编辑C++代码(续) &amp;#8211; 使用Emacs 23.2内置的CEDET' d='' tag='ahei,C/C++,CEDET,company-mode,cursor,ede,Emacs,emacser,emacser.com,highlight,imenu,lambda,meteor,meteor1113,org,pulse,putty,screenshot,semantic,senator,windows,代码折叠,代码补全,插件,补全,配色,配色' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>
	<h4>相关日志</h4>
	<ul class="st-related-posts">
	<li><a href="http://emacser.com/cedet.htm" title="用CEDET浏览和编辑C++代码 (2010年03月18日)">用CEDET浏览和编辑C++代码</a> (198)</li>
	<li><a href="http://emacser.com/emacs.htm" title="Emacs长啥样 (2009年11月5日)">Emacs长啥样</a> (16)</li>
	<li><a href="http://emacser.com/dea.htm" title="我的Emacs配置文件 － DEA (2009年11月11日)">我的Emacs配置文件 － DEA</a> (352)</li>
	<li><a href="http://emacser.com/emacs-cpp-dev.htm" title="在Emacs下用C/C++编程 (2010年10月25日)">在Emacs下用C/C++编程</a> (37)</li>
	<li><a href="http://emacser.com/auto-complete.htm" title="Emacs才是世界上最强大的IDE － 用auto-complete实现自动补全 (2009年11月11日)">Emacs才是世界上最强大的IDE － 用auto-complete实现自动补全</a> (114)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://emacser.com/built-in-cedet.htm/feed</wfw:commentRss>
		<slash:comments>99</slash:comments>
		</item>
		<item>
		<title>Emacs才是世界上最强大的IDE － 用Emaci阅读文件</title>
		<link>http://emacser.com/emaci.htm</link>
		<comments>http://emacser.com/emaci.htm#comments</comments>
		<pubDate>Mon, 12 Apr 2010 01:11:42 +0000</pubDate>
		<dc:creator>ahei</dc:creator>
				<category><![CDATA[IDE]]></category>
		<category><![CDATA[初级]]></category>
		<category><![CDATA[ahei]]></category>
		<category><![CDATA[autoload]]></category>
		<category><![CDATA[ede]]></category>
		<category><![CDATA[emaci]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[emacser]]></category>
		<category><![CDATA[emacser.com]]></category>
		<category><![CDATA[eval-after-load]]></category>
		<category><![CDATA[face]]></category>
		<category><![CDATA[gud]]></category>
		<category><![CDATA[highlight]]></category>
		<category><![CDATA[highlight-symbol]]></category>
		<category><![CDATA[keymap]]></category>
		<category><![CDATA[mode-line]]></category>
		<category><![CDATA[screenshot]]></category>
		<category><![CDATA[theme]]></category>
		<category><![CDATA[光标]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[配色]]></category>
		<category><![CDATA[颜色]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41107</guid>
		<description><![CDATA[相信有很多人平时要阅读大量文件, 而且阅读文件比编辑文件的时间要多的多, 在Emacs里编辑文件的时候, 阅读文件很不方便, 只能用C-v M-v上下滚屏. Emacs下有个view-mode专门是为阅读文件而准备的, 在view-mode里, u向上滚半屏, d向下滚半屏, SPC向下滚一屏, 阅读文件方便多了, 但是还不够, 为什么? 因为经常在阅读文件的时候, 你看到什么不对的地方需要修改, 而在view-mode下, 文件是只读的, 而且有时候, 你在编辑文件的时候, 也需要阅读文件, 那么这两种情况下, 你都要不停的切换view-mode, 非常的不方便, 而且在view-mode里面上下左右移动还得用C-n, C-p, C-f, C-b, 也是非常的不方便, 还有前进一个单词M-f, 后退一个单词M-b, 操作起来都还是很麻烦.
大家都知道vi, 它的快捷键是出名的短, 在vi的命令模式, 上下左右以字符前进是hjkl, 是vi最著名的地方了, 非常方便, 还有它的以单词前进和后退的快捷键w, b, e, 还有好多类似移动光标的命令, 都非常的方便. Emacs下有好多模拟vi的插件, vi-mode就是一个, 它是Emacs内置的, 它模拟了好多vi的特性, 简单的光标移动命令更是当然支持了. 用它来阅读文件的话, 也是不错的, 但是还是有两方面缺点, 一是在vi-mode下好多下, 好多Emacs本身的快捷键就用不了, 比如C-a, C-y等, 二是vi本身固有的缺点(个人观点), [...]]]></description>
			<content:encoded><![CDATA[<p>相信有很多人平时要阅读大量文件, 而且阅读文件比编辑文件的时间要多的多, 在Emacs里编辑文件的时候, 阅读文件很不方便, 只能用C-v M-v上下滚屏. Emacs下有个view-mode专门是为阅读文件而准备的, 在view-mode里, u向上滚半屏, d向下滚半屏, SPC向下滚一屏, 阅读文件方便多了, 但是还不够, 为什么? 因为经常在阅读文件的时候, 你看到什么不对的地方需要修改, 而在view-mode下, 文件是只读的, 而且有时候, 你在编辑文件的时候, 也需要阅读文件, 那么这两种情况下, 你都要不停的切换view-mode, 非常的不方便, 而且在view-mode里面上下左右移动还得用C-n, C-p, C-f, C-b, 也是非常的不方便, 还有前进一个单词M-f, 后退一个单词M-b, 操作起来都还是很麻烦.<span id="more-41107"></span></p>
<p>大家都知道vi, 它的快捷键是出名的短, 在vi的命令模式, 上下左右以字符前进是hjkl, 是vi最著名的地方了, 非常方便, 还有它的以单词前进和后退的快捷键w, b, e, 还有好多类似移动光标的命令, 都非常的方便. Emacs下有好多模拟vi的插件, vi-mode就是一个, 它是Emacs内置的, 它模拟了好多vi的特性, 简单的光标移动命令更是当然支持了. 用它来阅读文件的话, 也是不错的, 但是还是有两方面缺点, 一是在vi-mode下好多下, 好多Emacs本身的快捷键就用不了, 比如C-a, C-y等, 二是vi本身固有的缺点(个人观点), 那就是虽然那些快捷键比较短, 但是基本上要在命令模式下运行, 想想, 当你在编辑文件的时候, 想要上下左右移动光标, 然后继续编辑, 再来个上下半屏移动光标, 再来个编辑, 然后再搜索某个单词, 再来个编辑, 就得不停的在编辑模式和命令模式来回切换, 个人觉得非常的不方便, 所以用vi-mode来阅读文件也不是最理想的选择.</p>
<p>鉴于以上理由, 个人自己写了个minor mode, 结合Emacs的优点和部分vi的优点, 所以它的名字Emaci就是由EMACs和vI组成, Emacs占了四个字符, vi却只占了1个字符, 因为Emaci偏向于Emacs的功能更多. </p>
<p>安装好Emaci(只要(require &#8216;emaci))后, M-x emaci-mode (我把它绑定到了M-s上, 非常方便)进入emaci-mode. 由于大部分情况下打开一个文件浏览的情况比较多, 所以我写了一个函数emaci-exist-file, 这个函数的作用就是判断当前文件是否存在, 存在的话就自动打开emaci-mode, 我把这个函数加到了find-file-hook里面, 这样当你打开一个文件的时候就自动进入了emaci-mode, 打开新文件则不会进入emaci-mode.</p>
<p>进入emaci-mode后, 和vi类似, hjkl上下左右以字符单位移动光标, f, b前进和后退一个单词, I回到行首并且退出emaci-mode, A回到行尾并且退出emaci-mode. 和view-mode类似, u向上滚半屏, SPC向下滚半屏, w向上滚一屏, d向下滚一屏, &lt;和&gt;回到buffer头和buffer尾, 这个也和view-mode一样. g也是回到buffer头, J和K则是向下和向上移动7行, B执行eval-buffer, 1最大化当前window, 2把当前buffer垂直分成两半，3把当前buffer水平非常两半，q退出emaci-mode. 我的配置里，当安装了<a href="highlight-symbol.htm" target="_blank">highlight-symbol</a>后，n向前搜索当前光标处的下一个单词，p则向后搜索，非常方便。这样配置：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41107code107'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41107107"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p41107code107"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> highlight-symbol-settings-for-emaci <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;`highlight-symbol' settings for `emaci'.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>eval-when-compile <span style="color: #66cc66;">&#40;</span>require 'cl<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;;;###autoload</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> emaci-n <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #ff0000;">&quot;Command bind to key n.&quot;</span>
    <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>edebug-active<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>edebug-next-mode<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">equal</span> major-mode 'gud-mode<span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>call-interactively 'gud-next<span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#40;</span>call-interactively 'highlight-symbol-next<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
  <span style="color: #66cc66;">&#40;</span>define-key-<span style="color: #b1b100;">list</span>
    emaci-mode-map
    `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;p&quot;</span> highlight-symbol-prev<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>eval-after-load <span style="color: #ff0000;">&quot;emaci&quot;</span>
  `<span style="color: #66cc66;">&#40;</span>highlight-symbol-settings-for-emaci<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>与vi和view-mode相比最大的差异的地方也是我觉得最方便的地方, 是在emaci-mode下也可以进行一些编辑工作, 比如你在浏览某个文件的时候, 发现某一行不需要, 直接用C-k删除即可, 然后再用C-y复制一下刚才拷贝的东西, 当然同样, 可以删除一个区域, 一个单词, 一个字符, 删除字符还可以用vi中的x命令. 这些编辑操作都不需要你退出emaci-mode, 编辑完之后, 用C-x C-s保存即可. 只有当你需要敲一堆文字的时候, 因为可能会涉及到jkhl等快捷键, 这时候才需要用q退出emaci-mode. 这时候你就想了, 那是不是每次编辑之前还要看一下当前是否开了emaci-mode, 那岂不是非常麻烦? 不用担心, 开启了emaci-mode后, mode-line上会显示一个非常显眼的&#8221;Emaci&#8221;样, 我特地用白底红字标示出来, 就像这样:<br />
<div class="wp-caption alignnone" style="width: 596px"><a href="screenshots/emaci.png" rel="lightbox"><img src="screenshots/emaci.png" width="964"/></a><p class="wp-caption-text">Emaci的mode-line标记</p></div><br />
当然，这个颜色你也可以控制的，该颜色是由颜色变量emaci-mode-line-face来控制的。<br />
而且, 我一般把M-s绑定到了emaci-mode-on, M-S绑定到emaci-mode-off上面, 这样, 你想编辑的时候按下M-S, 浏览的时候按下M-s, 即使不用看那个白底红字的&#8221;Emaci&#8221;字样, 也不会出错的. 这点view-mode就不行, 它和其他的minor mode一样, 都是默认的颜色, 我一般开启了好多minor mode, 这样, 你想编辑的时候, 还得盯着mode-line看半天当前是否打开了view-mode. </p>
<p>emaci还对常用的一些mode, 比如view-mode(所以你如果不喜欢在emaci-mode里面能修改文件, 只想只读的阅读文件的话, 可以考虑view-mode, 它的配置文件在<a href="http://code.google.com/p/dea/source/browse/trunk/my-lisps/view-mode-settings.el" target="_blank">这里</a>), Man-mode, apropos, diff-mode, help-mode等定制了通用的hjkl等方便的快捷键, 这些是通过emaci-brief-key-defs变量来控制的, 这个变量是一个list, list的每一个元素是由两个元素构成的list, 第一个元素是快捷键, 快捷键的写法和kbd宏的参数一样, 第二个参数是该快捷键对应的命令, 这个变量默认值如下:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41107code108'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41107108"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code" id="p41107code108"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defcustom emaci-brief-key-defs
  `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;h&quot;</span> backward-char<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;l&quot;</span> forward-char<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;j&quot;</span> next-line<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;k&quot;</span> previous-line<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;J&quot;</span> roll-down<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;K&quot;</span> roll-up<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;b&quot;</span> backward-word<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;w&quot;</span> am-forward-word-or-to-word<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;o&quot;</span> other-window<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;G&quot;</span> end-of-buffer<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;a&quot;</span> move-beginning-of-line<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;e&quot;</span> move-end-of-line<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Key pairs used bind in modes `emaci-maps-to-bind-brief-keys'.
&nbsp;
Each element of this variable is two-elements list, and first
element is key like argument of `kbd', and second element is command.&quot;</span>
  <span style="color: #66cc66;">:</span><span style="color: #555;">type</span> '<span style="color: #b1b100;">list</span>
  <span style="color: #66cc66;">:</span><span style="color: #555;">group</span> 'emaci<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>而待绑定这些快捷键的keymap是由变量emaci-maps-to-bind-brief-keys控制的, 其默认值如下:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41107code109'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41107109"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code" id="p41107code109"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defcustom emaci-maps-to-bind-brief-keys
  `<span style="color: #66cc66;">&#40;</span>view-mode-map
    Man-mode-map
    apropos-mode-map
    completion-list-mode-map
    log-view-mode-map
    compilation-mode-map
    diff-mode-map
    help-mode-map
    <span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&gt;=</span> emacs-major-version <span style="color: #cc66cc;">21</span><span style="color: #66cc66;">&#41;</span> 'grep-mode-map<span style="color: #66cc66;">&#41;</span>
    color-theme-mode-map<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;List used for `emaci-bind-modes-keys'.
&nbsp;
Element of this list either a list whose first element is load file,
and second element is map, or a string which means load file, or a map.&quot;</span>
  <span style="color: #66cc66;">:</span><span style="color: #555;">group</span> 'emaci<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>此变量是一个keymap的list, list中的元素是keymap或者是nil。<br />
如果你修改了以上两个变量后, 执行一下M-x emaci-bind-brief-keys使你的修改生效.</p>
<p>Emaci的配置文件在<a href="http://code.google.com/p/dea/source/browse/trunk/my-lisps/emaci-settings.el" target="_blank">这里</a>，配置如下:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41107code110'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41107110"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
</pre></td><td class="code" id="p41107code110"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;; -*- Emacs-Lisp -*-</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; Time-stamp: &lt;2010-04-19 10:15:52 Monday by ahei&gt;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>require 'util<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>require 'emaci<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>apply-define-key
 global-map
 `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;M-s&quot;</span> emaci-mode-on<span style="color: #66cc66;">&#41;</span>
   <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;M-S&quot;</span> emaci-mode-off<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> emaci-settings <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;settings for `emaci'.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>eal-define-keys
   'emaci-mode-map
   `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/&quot;</span> describe-symbol-at-point<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;'&quot;</span> switch-to-other-buffer<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;L&quot;</span> count-brf-lines<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;t&quot;</span> sb-toggle-keep-buffer<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;.&quot;</span> find-symbol-at-point<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;,&quot;</span> find-symbol-go-back<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;]&quot;</span> goto-paren<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> emaci-brief-key-defs
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">append</span> emaci-brief-key-defs
                `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;]&quot;</span> goto-paren<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;">&#40;</span>emaci-bind-brief-keys<span style="color: #66cc66;">&#41;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">;;;###autoload</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> switch-major-mode-with-emaci <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #ff0000;">&quot;Run `switch-major-mode' with `emaci-mode'.&quot;</span>
    <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>emaci emaci-mode<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span>call-interactively 'switch-major-mode<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span>emaci-mode <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> emaci <span style="color: #cc66cc;">1</span> -<span style="color: #cc66cc;">1</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>
&nbsp;
  <span style="color: #66cc66;">&#40;</span>eal-define-keys-commonly
   global-map
   `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;C-x q&quot;</span> switch-major-mode-with-emaci<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>eval-after-load <span style="color: #ff0000;">&quot;emaci&quot;</span>
  `<span style="color: #66cc66;">&#40;</span>emaci-settings<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>provide 'emaci-settings<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>听完我的介绍, 怎么样, 是不是你也一直期待这样的功能呢, 那赶快试试吧. 这里下载<a href="http://code.google.com/p/dea/source/browse/trunk/my-lisps/emaci.el" target="_blank">Emaci</a>, Emaci还依赖<a href="http://code.google.com/p/dea/source/browse/trunk/my-lisps/ahei-misc.el" target="_blank">ahei-misc</a>, <a href="eval-after-load.htm" target="_blank">eval-after-load</a>两个包，读者均可在<a href="http://code.google.com/p/dea" target="_blank">DEA</a>里面下载。</p>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/emaci.htm' t='Emacs才是世界上最强大的IDE － 用Emaci阅读文件' d='' tag='ahei,autoload,ede,emaci,Emacs,emacser,emacser.com,eval-after-load,face,gud,highlight,highlight-symbol,IDE,keymap,mode-line,screenshot,theme,光标,插件,配色,颜色' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>
	<h4>相关日志</h4>
	<ul class="st-related-posts">
	<li><a href="http://emacser.com/dea.htm" title="我的Emacs配置文件 － DEA (2009年11月11日)">我的Emacs配置文件 － DEA</a> (352)</li>
	<li><a href="http://emacser.com/highlight-symbol.htm" title="Emacs才是世界上最强的IDE － 高亮光标处单词 (2009年11月27日)">Emacs才是世界上最强的IDE － 高亮光标处单词</a> (23)</li>
	<li><a href="http://emacser.com/cedet.htm" title="用CEDET浏览和编辑C++代码 (2010年03月18日)">用CEDET浏览和编辑C++代码</a> (198)</li>
	<li><a href="http://emacser.com/dea-faq.htm" title="DEA的FAQs (2010年05月6日)">DEA的FAQs</a> (62)</li>
	<li><a href="http://emacser.com/torture-emacs.htm" title="折腾Emacs (2010年08月17日)">折腾Emacs</a> (112)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://emacser.com/emaci.htm/feed</wfw:commentRss>
		<slash:comments>89</slash:comments>
		</item>
		<item>
		<title>Emacs才是世界上最强的IDE － 用linum+智能显示行号</title>
		<link>http://emacser.com/linum-plus.htm</link>
		<comments>http://emacser.com/linum-plus.htm#comments</comments>
		<pubDate>Fri, 02 Apr 2010 05:43:04 +0000</pubDate>
		<dc:creator>ahei</dc:creator>
				<category><![CDATA[IDE]]></category>
		<category><![CDATA[初级]]></category>
		<category><![CDATA[autoload]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[face]]></category>
		<category><![CDATA[linum+]]></category>
		<category><![CDATA[linum-plus]]></category>
		<category><![CDATA[org]]></category>
		<category><![CDATA[screenshot]]></category>
		<category><![CDATA[截图]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[行号]]></category>
		<category><![CDATA[鼠标]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41085</guid>
		<description><![CDATA[稍微现代点的编辑器都有行号显示功能，行号显示是在buffer的左侧一栏显示当前buffer每行的行号，比较直观，但其实在以鼠标为中心的编辑器、IDE中，其实这个行号显示功能不大，但是在以纯键盘为中心的编辑器，如vi, Emacs中这个行号显示功能就非常方便了，它可以帮助你迅速定位到某行，知道了行号，直接通过M-x goto-line到达某行，非常方便。
但是Emacs比较“土”，Emacs23之前一直没有内置的行号显示功能，但是“土”归“土”，但是它很听话，你要怎样控制它就怎样控制它，所以诞生了一堆外置的行号显示插件，比如wb-line-number, setnu, setnu-plus, display-line-number, 虽然很多，但是都有一些小bug，不是很方便。Emacs23出来后，我欣喜的看到，它已经内置了行号显示功能，用的是linum-mode，既然是内置的，当然性能比较好，bug也比较少。它每次只显示当前buffer可视区域内的行号，而且用了一个小缓存的技巧，保证了性能，即使打开大文件也没问题。它的行号显示格式是通过linum-format来控制的，该值为&#8217;dynamic的话，就会动态控制行号的宽度，比如当前buffer最大行是3位数，那么行号的宽度就是3，这个format还可以设为固定的宽度，比如设置成&#8221;%4d&#8221;，那么始终显示成4个字符宽度。一般的编辑器用的都是那个&#8217;dynamic, 动态控制行号显示的宽度。
但是这个动态显示宽度还不够智能，比如当前buffer最大行的行号是3位数，我显示前面几行行号的时候，比如从1到50，没必要也用3个字符宽度来显示，只需要用2位就可以了，所以我写了一个linum+，来弥补linum这个缺点，linum+主要是重新定义了下linum里面更新行号的函数linum-update-window，代码如下：

?View Code LISP1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
;;;###autoload
&#40;defun linum+-generate-linum-format &#40;format-type limit&#41;
  &#34;Generate line number format by FORMAT-TYPE, LIMIT is `window-end' of win.&#34;
  &#40;cond &#40;&#40;stringp format-type&#41; format-type&#41;
        &#40;&#40;or &#40;listp format-type&#41; &#40;vectorp format-type&#41;
             &#40;eq [...]]]></description>
			<content:encoded><![CDATA[<p>稍微现代点的编辑器都有行号显示功能，行号显示是在buffer的左侧一栏显示当前buffer每行的行号，比较直观，但其实在以鼠标为中心的编辑器、IDE中，其实这个行号显示功能不大，但是在以纯键盘为中心的编辑器，如vi, Emacs中这个行号显示功能就非常方便了，它可以帮助你迅速定位到某行，知道了行号，直接通过M-x goto-line到达某行，非常方便。<span id="more-41085"></span></p>
<p>但是Emacs比较“土”，Emacs23之前一直没有内置的行号显示功能，但是“土”归“土”，但是它很听话，你要怎样控制它就怎样控制它，所以诞生了一堆外置的行号显示插件，比如wb-line-number, setnu, setnu-plus, display-line-number, 虽然很多，但是都有一些小bug，不是很方便。Emacs23出来后，我欣喜的看到，它已经内置了行号显示功能，用的是linum-mode，既然是内置的，当然性能比较好，bug也比较少。它每次只显示当前buffer可视区域内的行号，而且用了一个小缓存的技巧，保证了性能，即使打开大文件也没问题。它的行号显示格式是通过linum-format来控制的，该值为&#8217;dynamic的话，就会动态控制行号的宽度，比如当前buffer最大行是3位数，那么行号的宽度就是3，这个format还可以设为固定的宽度，比如设置成&#8221;%4d&#8221;，那么始终显示成4个字符宽度。一般的编辑器用的都是那个&#8217;dynamic, 动态控制行号显示的宽度。</p>
<p>但是这个动态显示宽度还不够智能，比如当前buffer最大行的行号是3位数，我显示前面几行行号的时候，比如从1到50，没必要也用3个字符宽度来显示，只需要用2位就可以了，所以我写了一个linum+，来弥补linum这个缺点，linum+主要是重新定义了下linum里面更新行号的函数linum-update-window，代码如下：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41085code114'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41085114"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
</pre></td><td class="code" id="p41085code114"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;;;###autoload</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> linum+-generate-linum-format <span style="color: #66cc66;">&#40;</span>format-type limit<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Generate line number format by FORMAT-TYPE, LIMIT is `window-end' of win.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">cond</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>stringp format-type<span style="color: #66cc66;">&#41;</span> format-type<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">listp</span> format-type<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>vectorp format-type<span style="color: #66cc66;">&#41;</span>
             <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">eq</span> format-type 'dynamic<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">eq</span> format-type 'smart<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>dynamic-width <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span>vectorp format-type<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">eq</span> format-type 'smart<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span>old-format
                 <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">eq</span> format-type 'dynamic<span style="color: #66cc66;">&#41;</span>
                     linum+-dynamic-format
                   <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">eq</span> format-type 'smart<span style="color: #66cc66;">&#41;</span>
                       linum+-smart-format
                     format-type<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span>w <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">length</span>
                    <span style="color: #66cc66;">&#40;</span>number-to-string
                     <span style="color: #66cc66;">&#40;</span>line-number-at-pos <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> dynamic-width limit <span style="color: #66cc66;">&#40;</span>point-<span style="color: #b1b100;">max</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><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span>new-format
                 <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">listp</span> old-format<span style="color: #66cc66;">&#41;</span>
                     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">car</span> old-format<span style="color: #66cc66;">&#41;</span>
                   <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>vectorp old-format<span style="color: #66cc66;">&#41;</span>
                       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">aref</span> old-format <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
                     old-format<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;">&#40;</span>format new-format w<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>
&nbsp;
<span style="color: #808080; font-style: italic;">;;;###autoload</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> linum-update-window <span style="color: #66cc66;">&#40;</span>win<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Update line numbers for the portion visible in window WIN.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>goto-char <span style="color: #66cc66;">&#40;</span>window-start win<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>line <span style="color: #66cc66;">&#40;</span>line-number-at-pos<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>limit <span style="color: #66cc66;">&#40;</span>window-end win t<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>fmt <span style="color: #66cc66;">&#40;</span>linum+-generate-linum-format linum-format limit<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>width <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>run-hooks 'linum-before-numbering-hook<span style="color: #66cc66;">&#41;</span>
    <span style="color: #808080; font-style: italic;">;; Create an overlay (or reuse an existing one) for each</span>
    <span style="color: #808080; font-style: italic;">;; line visible in this window, if necessary.</span>
    <span style="color: #66cc66;">&#40;</span>while <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> <span style="color: #66cc66;">&#40;</span>eobp<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&lt;=</span> <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span> limit<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>str <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> fmt
                      <span style="color: #66cc66;">&#40;</span>propertize <span style="color: #66cc66;">&#40;</span>format fmt line<span style="color: #66cc66;">&#41;</span> 'face 'linum<span style="color: #66cc66;">&#41;</span>
                    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">funcall</span> linum-format line<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
             <span style="color: #66cc66;">&#40;</span>visited <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">catch</span> 'visited
                        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">dolist</span> <span style="color: #66cc66;">&#40;</span>o <span style="color: #66cc66;">&#40;</span>overlays-in <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>equal-including-properties
                                 <span style="color: #66cc66;">&#40;</span>overlay-<span style="color: #b1b100;">get</span> o 'linum-str<span style="color: #66cc66;">&#41;</span> str<span style="color: #66cc66;">&#41;</span>
                            <span style="color: #66cc66;">&#40;</span>unless <span style="color: #66cc66;">&#40;</span>memq o linum-overlays<span style="color: #66cc66;">&#41;</span>
                              <span style="color: #66cc66;">&#40;</span>push o linum-overlays<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> linum-available <span style="color: #66cc66;">&#40;</span>delq o linum-available<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">throw</span> 'visited t<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><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> width <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">max</span> width <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">length</span> str<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>unless visited
          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>ov <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">null</span> linum-available<span style="color: #66cc66;">&#41;</span>
                        <span style="color: #66cc66;">&#40;</span>make-overlay <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                      <span style="color: #66cc66;">&#40;</span>move-overlay <span style="color: #66cc66;">&#40;</span>pop linum-available<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>point<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>
            <span style="color: #66cc66;">&#40;</span>push ov linum-overlays<span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#40;</span>overlay-put ov 'before-string
                         <span style="color: #66cc66;">&#40;</span>propertize <span style="color: #ff0000;">&quot; &quot;</span> 'display `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>margin left-margin<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">,</span>str<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#40;</span>overlay-put ov 'linum-str str<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;">&#40;</span>forward-line<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> line <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>+ line<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>set-window-margins win width<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>其实这个linum-update-window改的很简单，主要是根据当前最大行号来制定一个宽度。<br />
linum+.el全文件在<a href="http://code.google.com/p/dea/source/browse/trunk/my-lisps/linum%2B.el" target="_blank">这里</a>下载。<br />
因为只有行号从n位数过度到n+1位数的时候，行号宽度才会发生改变，这种机会并不多，所以我这个linum+性能基本上和linum一样。</p>
<p>linum中, linum-format有可以有三种形式, string, &#8216;dynamic, 或者函数, 你使用了linum+以后，增加了三种形式, 分别是&#8217;smart, 含有一个字符串的list, 和含有一个字符串的vector, string和函数还和linum中的作用一样, &#8216;dynamic还是根据当前buffer最大行来控制最大的行号宽度, &#8217;smart则是智能根据当前可使范围内最大行号来控制行号显示宽度的, 如果是list的话, 则是根据list中的字符串来和当前最大行号的宽度一起作为format函数的参数来生成当前行号的格式，然后再用这个格式来显示行号，比如当前buffer显示的行数是从1到50，那么最大的行号是50，其宽度是2，list的值为&#8217;(&#8220;%%%dd|&#8221;), 那么当前buffer每行行号的显示格式就是：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41085code115'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41085115"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p41085code115"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;%%%dd|&quot;</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">=&gt;</span><span style="color: #ff0000;">&quot;%2d|&quot;</span></pre></td></tr></table></div>

<p>得到&#8221;%2d|&#8221;，然后当前buffer每行的行号显示格式就是&#8221;%2d|&#8221;了。<br />
当linum-format为vector的时候, 处理过程基本和list的一样, 唯一的差别就是行号的格式的时候, &#8220;%d&#8221;是用当前buffer最大行号的宽度去替换的, 比如当前最大行号是125, 其宽度是3, 那么当前buffer每行行号的显示格式就是:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41085code116'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41085116"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p41085code116"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>format <span style="color: #ff0000;">&quot;%%%dd|&quot;</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">=&gt;</span><span style="color: #ff0000;">&quot;%2d|&quot;</span></pre></td></tr></table></div>

<p>得到&#8221;%3d|&#8221;，然后当前buffer每行的行号显示格式就是&#8221;%2d|&#8221;了。<br />
其实, linum+内部实现时, &#8216;dynamic和&#8217;(&#8220;%%%dd|&#8221;)作用一样, &#8217;smart和["%%%dd|"]作用一样. 你不喜欢&#8217;smart后面的&#8221;|&#8221;的话, 把linum-format设置为["%%%dd"]就可以了.<br />
如果你喜欢linum中的&#8217;dynamic, 根据buffer最大的行号生成固定的宽度, 而不喜欢linum+中&#8217;smart那样动态变化的宽度, 你仍然可以把linum-format配置成&#8217;dynamic, 或者配置成list, 比如&#8217;(&#8220;%%%dd&#8221;), 这样既可以享受固定的宽度, 又可以享受可配置的格式(linum中linum-format为&#8217;dynamic, 行号的格式你是控制不了的)</p>
<p>下面是linum+的截图：</p>
<table border="0">
<tr>
<td>
      <div class="wp-caption alignnone" style="width: 160px"><a href="screenshots/linum+/linum+1.png" rel="lightbox"><img src="screenshots/linum+/thumbs/thumbs_linum+1.png" width="150" height="150" /></a><p class="wp-caption-text">用linum+智能显示行号</p></div>
    </td>
<td>
      <div class="wp-caption alignnone" style="width: 160px"><a href="screenshots/linum+/linum+2.png" rel="lightbox"><img src="screenshots/linum+/thumbs/thumbs_linum+2.png" width="150" height="150" /></a><p class="wp-caption-text">用linum+智能显示行号</p></div>
    </td>
</tr>
</table>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/linum-plus.htm' t='Emacs才是世界上最强的IDE － 用linum+智能显示行号' d='' tag='autoload,Emacs,face,IDE,linum+,linum-plus,org,screenshot,截图,插件,行号,鼠标' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>
	<h4>相关日志</h4>
	<ul class="st-related-posts">
	<li><a href="http://emacser.com/dea.htm" title="我的Emacs配置文件 － DEA (2009年11月11日)">我的Emacs配置文件 － DEA</a> (352)</li>
	<li><a href="http://emacser.com/emacs.htm" title="Emacs长啥样 (2009年11月5日)">Emacs长啥样</a> (16)</li>
	<li><a href="http://emacser.com/w3m.htm" title="Emacs才是世界上最强的IDE &#8211; 用w3m浏览网页 (2009年11月23日)">Emacs才是世界上最强的IDE &#8211; 用w3m浏览网页</a> (46)</li>
	<li><a href="http://emacser.com/emacs-cpp-dev.htm" title="在Emacs下用C/C++编程 (2010年10月25日)">在Emacs下用C/C++编程</a> (37)</li>
	<li><a href="http://emacser.com/cedet.htm" title="用CEDET浏览和编辑C++代码 (2010年03月18日)">用CEDET浏览和编辑C++代码</a> (198)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://emacser.com/linum-plus.htm/feed</wfw:commentRss>
		<slash:comments>87</slash:comments>
		</item>
		<item>
		<title>在Emacs中使用gdb调试程序</title>
		<link>http://emacser.com/emacs-gdb.htm</link>
		<comments>http://emacser.com/emacs-gdb.htm#comments</comments>
		<pubDate>Mon, 29 Mar 2010 02:18:31 +0000</pubDate>
		<dc:creator>ahei</dc:creator>
				<category><![CDATA[IDE]]></category>
		<category><![CDATA[中级]]></category>
		<category><![CDATA[ann]]></category>
		<category><![CDATA[CEDET]]></category>
		<category><![CDATA[ctrl]]></category>
		<category><![CDATA[ede]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[gdb]]></category>
		<category><![CDATA[gud]]></category>
		<category><![CDATA[lambda]]></category>
		<category><![CDATA[org]]></category>
		<category><![CDATA[screenshot]]></category>
		<category><![CDATA[speedbar]]></category>
		<category><![CDATA[text]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[光标]]></category>
		<category><![CDATA[工具栏]]></category>
		<category><![CDATA[补全]]></category>
		<category><![CDATA[配色]]></category>
		<category><![CDATA[鼠标]]></category>

		<guid isPermaLink="false">http://emacser.com/?p=41056</guid>
		<description><![CDATA[作者: Tiger Soldier




1 引言 
2 准备工作：将调试信息编译在程序中 
3 开始：开启Emacs的调试模式GUD 

3.1 运行gdb 
3.2 gdb界面 
3.3 小结 


4 调试：设置断点，控制程序流程 

4.1 设置、删除断点 
4.2 运行程序 
4.3 单步执行、运行到光标处 
4.4 继续运行程序 
4.5 小结 


5 察看变量的值 

5.1 本地变量buffer 
5.2 察看变量值 
5.3 用工具提示显示变量值 
5.4 小结 


6 输入输出 

6.1 单独的IO buffer 
6.2 输入数据 
6.3 重定向到文件 


7 按键绑定 
8 结尾 




1 引言 

Emacs除了具有强大的编辑功能，还可以作为调试工具gdb的前端，对程序进行调试。使用Emacs进行调试，可以将程序的编写与调试统一到Emacs中，并利用Emacs强大的功能辅助调试，是将Emacs作为IDE使用的一项必备功能。


本文假定读者具有基本的程序调试知识，希望知道在Emacs下进行基本调试的对应操作。水平有限，欢迎拍砖。




2 准备工作：将调试信息编译在程序中 

要使程序能被gdb调试，需要在编译时加入调试所需的信息。如果使用gcc/g++进行编译，需要使用参数-g，如：


?View Code [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #0000ff;">作者: </span><a href="about.htm#tigersoldier" target="_blank"><span style="color: #0000ff;"><b>Tiger Soldier</b></span></a></p>
<p><img class="alignright" title="CEDET" src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/archer.jpg"/></p>
<div id="table-of-contents">
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1 引言 </a></li>
<li><a href="#sec-2">2 准备工作：将调试信息编译在程序中 </a></li>
<li><a href="#sec-3">3 开始：开启Emacs的调试模式GUD </a>
<ul>
<li><a href="#sec-3.1">3.1 运行gdb </a></li>
<li><a href="#sec-3.2">3.2 gdb界面 </a></li>
<li><a href="#sec-3.3">3.3 小结 </a></li>
</ul>
</li>
<li><a href="#sec-4">4 调试：设置断点，控制程序流程 </a>
<ul>
<li><a href="#sec-4.1">4.1 设置、删除断点 </a></li>
<li><a href="#sec-4.2">4.2 运行程序 </a></li>
<li><a href="#sec-4.3">4.3 单步执行、运行到光标处 </a></li>
<li><a href="#sec-4.4">4.4 继续运行程序 </a></li>
<li><a href="#sec-4.5">4.5 小结 </a></li>
</ul>
</li>
<li><a href="#sec-5">5 察看变量的值 </a>
<ul>
<li><a href="#sec-5.1">5.1 本地变量buffer </a></li>
<li><a href="#sec-5.2">5.2 察看变量值 </a></li>
<li><a href="#sec-5.3">5.3 用工具提示显示变量值 </a></li>
<li><a href="#sec-5.4">5.4 小结 </a></li>
</ul>
</li>
<li><a href="#sec-6">6 输入输出 </a>
<ul>
<li><a href="#sec-6.1">6.1 单独的IO buffer </a></li>
<li><a href="#sec-6.2">6.2 输入数据 </a></li>
<li><a href="#sec-6.3">6.3 重定向到文件 </a></li>
</ul>
</li>
<li><a href="#sec-7">7 按键绑定 </a></li>
<li><a href="#sec-8">8 结尾 </a></li>
</ul>
</div>
</div>
<div id="outline-container-1" class="outline-2">
<h3 id="sec-1"><span class="section-number-2">1</span> 引言 </h3>
<div class="outline-text-2" id="text-1">
<p>Emacs除了具有强大的编辑功能，还可以作为调试工具gdb的前端，对程序进行调试。使用Emacs进行调试，可以将程序的编写与调试统一到Emacs中，并利用Emacs强大的功能辅助调试，是将Emacs作为IDE使用的一项必备功能。<span id="more-41056"></span>
</p>
<p>
本文假定读者具有基本的程序调试知识，希望知道在Emacs下进行基本调试的对应操作。水平有限，欢迎拍砖。
</p>
</div>
</div>
<div id="outline-container-2" class="outline-2">
<h3 id="sec-2"><span class="section-number-2">2</span> 准备工作：将调试信息编译在程序中 </h3>
<div class="outline-text-2" id="text-2">
<p>要使程序能被gdb调试，需要在编译时加入调试所需的信息。如果使用gcc/g++进行编译，需要使用参数-g，如：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41056code121'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41056121"><td class="code" id="p41056code121"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">gcc</span> prog.c <span style="color: #660033;">-g</span> <span style="color: #660033;">-o</span> prog</pre></td></tr></table></div>

<p>
如果使用 ./confiugre &amp;&amp; make 的编译流程，可以将使用如下方式引入-g参数：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41056code122'); return false;">View Code</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41056122"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p41056code122"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">CFLAGS</span>=<span style="color: #ff0000;">&quot;-g&quot;</span> .<span style="color: #000000; font-weight: bold;">/</span>configure
<span style="color: #c20cb9; font-weight: bold;">make</span></pre></td></tr></table></div>

<p>
注意：不要加入任何优化参数（例如-O、-O2），不然调试时会有很灵异的现象发生……
</p>
</div>
</div>
<div id="outline-container-3" class="outline-2">
<h3 id="sec-3"><span class="section-number-2">3</span> 开始：开启Emacs的调试模式GUD </h3>
<div class="outline-text-2" id="text-3">
</div>
<div id="outline-container-3.1" class="outline-3">
<h4 id="sec-3.1"><span class="section-number-3">3.1</span> 运行gdb </h4>
<div class="outline-text-3" id="text-3.1">
<p>在编译好程序后，就可以开始调试了。直接运行gdb命令M-x gdb RET 在minibuffer中会出现需要执行的gdb命令。例如：gdb &ndash;annotate=3 prog 如果当前目录下有可执行文件（通常恰好是需要调试的文件），gdb会在其后自动补上可执行文件，否则需要在minibuffer中补上要调试的程序文件名。
</p>
<p>
继续回车，Emacs的GUD（Grand Unified Debugger）就会关联到gdb并加载要调试的程序了。
</p>
</div>
</div>
<div id="outline-container-3.2" class="outline-3">
<h4 id="sec-3.2"><span class="section-number-3">3.2</span> gdb界面 </h4>
<div class="outline-text-3" id="text-3.2">
<p>启动gdb后，Emacs的界面会变成下面两种之一：
</p>
<table border="0">
<tr>
<td>
<div class="wp-caption alignnone" style="width: 160px"><a href="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-single-window.png" rel="lightbox"><img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/thumbs/thumbs_emacs-gdb-single-window.png" width="150" height="150" /></a><p class="wp-caption-text">GDB单窗格模式</p></div>
    </td>
<td>
<div class="wp-caption alignnone" style="width: 160px"><a href="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-many-windows.png" rel="lightbox"><img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/thumbs/thumbs_emacs-gdb-many-windows.png" width="150" height="150" /></a><p class="wp-caption-text">GDB多窗格模式</p></div>
    </td>
</tr>
</table>
<p>
可以通过gdb-many-windows来切换这两种界面布局。
</p>
<p>
如果界面被打乱了（例如，在minibuffer中使用补全，查看帮助，重新编译程序），可以使用gdb-restore-windows来恢复界面布局。
</p>
</div>
</div>
<div id="outline-container-3.3" class="outline-3">
<h4 id="sec-3.3"><span class="section-number-3">3.3</span> 小结 </h4>
<div class="outline-text-3" id="text-3.3">
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption></caption>
<colgroup>
<col align="left" />
<col align="left" />
</colgroup>
<thead>
<tr>
<th scope="col">命令</th>
<th scope="col">功能</th>
</tr>
</thead>
<tbody>
<tr>
<td>gdb</td>
<td>启动gdb进行调试</td>
</tr>
<tr>
<td>gdb-many-windows</td>
<td>切换单窗格/多窗格模式</td>
</tr>
<tr>
<td>gdb-restore-windows</td>
<td>恢复窗格布局</td>
</tr>
</tbody>
</table>
<p>
接下来就要开始调试程序了。
</p>
</div>
</div>
</div>
<div id="outline-container-4" class="outline-2">
<h3 id="sec-4"><span class="section-number-2">4</span> 调试：设置断点，控制程序流程 </h3>
<div class="outline-text-2" id="text-4">
</div>
<div id="outline-container-4.1" class="outline-3">
<h4 id="sec-4.1"><span class="section-number-3">4.1</span> 设置、删除断点 </h4>
<div class="outline-text-3" id="text-4.1">
<p>首先将断点设置在要调试的地方。有两种方法：
</p>
<p>
第一种，在要设置断点的行左边的fringe上单击一下（就是文本左边与滚动条之间空出的那一块）。隐藏了fringe的朋友可以M-x fringe-mode显示它。
</p>
<p>
第二种，使用默认快捷键C-x C-a C-b, 或者 C-x &lt;SPC&gt;。它们都关联到命令gud-break。
</p>
<p>
无论使用哪种方法，fringe上都会在设置了断点的行上显示一个红点，表示这行设了断点：
</p>
<p><img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-fringe-breakpoint.png"/></p>
<p>
同时，在断点buffer中也会显示已有的断点信息：
</p>
<div class="wp-caption alignnone" style="width: 620px"><a href="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-breakpoint-buffer.png" rel="lightbox"><img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-breakpoint-buffer.png"/></a><p class="wp-caption-text">断点buffer</p></div>
<p>
要删除断点，同样有两种对应的方法：在fringe的断点上单击一下，或者使用快捷键C-x C-a C-d（对应命令gud-remove）。
</p>
<p>
可以在断点buffer上单击某个断点切换到断点所在位置。将光标移动到断点处回车也有同样的效果。
</p>
<p>
在断点buffer上按空格键可以切换断点的激活和禁用状态。
</p>
</div>
</div>
<div id="outline-container-4.2" class="outline-3">
<h4 id="sec-4.2"><span class="section-number-3">4.2</span> 运行程序 </h4>
<div class="outline-text-3" id="text-4.2">
<p>设置好断点后就可以运行程序了。单击工具栏上的<img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-toolbar-go.png"  alt="运行"/>就开始运行了。也可以使用gud-go命令来运行。奇怪的是没有任何默认快捷键绑定。
</p>
<p>
当程序运行到断点时，程序会在断点处停下来，并自动打开停下的语句所在的代码文件。同时在fringe上在停下的语句处有三角形的指示器。
</p>
<p><img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-indicator.png"/></p>
<p>
现在，我们来一步步运行程序。
</p>
</div>
</div>
<div id="outline-container-4.3" class="outline-3">
<h4 id="sec-4.3"><span class="section-number-3">4.3</span> 单步执行、运行到光标处 </h4>
<div class="outline-text-3" id="text-4.3">
<p>在调试中最常用的功能就是单步执行了。单步执行有两种：将函数调用作为一条语句执行（Next）和遇到函数时进入函数中进行调试（Step）。
</p>
<p>
要使用第一种方式，默认快捷键是C-x C-a C-n，对应命令为gud-next。也可以单击工具栏上的 <img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-toolbar-next.png"  alt="单步运行跳过函数" /> 。
</p>
<p>
第二种方式的默认快捷键是C-x C-a C-s，对应命令为gud-step。也可以单击工具栏上的 <img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-toolbar-step.png"  alt="单步运行进入函数" /> 。
</p>
<p>
如果想跳出当前函数，可以使用命令gud-finish，默认快捷键为C-x C-a C-f，工具栏上有 <img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-toolbar-finish.png"  alt="跳出函数" /> 可用。
</p>
<p>
在Emacs中还可以运行到光标所在的行。使用命令gud-until即可，默认快捷键为C-x C-a C-u。<sup><a class="footref" name="fnr.1" href="#fn.1">1</a></sup>
</p>
<p>
也可以直接把当前语句指示器拖到任意一行，程序会运行到那一行再停下来。
</p>
</div>
</div>
<div id="outline-container-4.4" class="outline-3">
<h4 id="sec-4.4"><span class="section-number-3">4.4</span> 继续运行程序 </h4>
<div class="outline-text-3" id="text-4.4">
<p>在程序中断后要继续运行程序，依然是使用gud-go命令或 <img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-toolbar-go.png" alt="继续运行"/> ，也可以使用命令gud-cont，对应快捷键为C-x C-a C-r。
</p>
</div>
</div>
<div id="outline-container-4.5" class="outline-3">
<h4 id="sec-4.5"><span class="section-number-3">4.5</span> 小结 </h4>
<div class="outline-text-3" id="text-4.5">
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption></caption>
<colgroup>
<col align="left" />
<col align="left" />
<col align="left" />
</colgroup>
<thead>
<tr>
<th scope="col">功能</th>
<th scope="col">命令</th>
<th scope="col">默认快捷键</th>
</tr>
</thead>
<tbody>
<tr>
<td>添加断点</td>
<td>gud-break</td>
<td>C-x C-a C-b 或 C-x &lt;SPC&gt;</td>
</tr>
<tr>
<td>删除断点</td>
<td>gud-remove</td>
<td>C-x C-a C-d</td>
</tr>
<tr>
<td>运行/继续程序</td>
<td>gud-go</td>
<td>无</td>
</tr>
<tr>
<td>单步执行，无视函数</td>
<td>gud-next</td>
<td>C-x C-a C-n</td>
</tr>
<tr>
<td>单步执行，进入函数</td>
<td>gud-step</td>
<td>C-x C-a C-s</td>
</tr>
<tr>
<td>跳出当前函数</td>
<td>gud-finish</td>
<td>C-x C-a C-f</td>
</tr>
<tr>
<td>运行到光标所在语句</td>
<td>gud-until</td>
<td>C-x C-a C-u</td>
</tr>
<tr>
<td>继续运行程序</td>
<td>gud-cont</td>
<td>C-x C-a C-r</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="outline-container-5" class="outline-2">
<h3 id="sec-5"><span class="section-number-2">5</span> 察看变量的值 </h3>
<div class="outline-text-2" id="text-5">
<p>调试的过程中免不了要查看变更的值。Emacs提供了方便地功能让我们查看变量的值。
</p>
</div>
<div id="outline-container-5.1" class="outline-3">
<h4 id="sec-5.1"><span class="section-number-3">5.1</span> 本地变量buffer </h4>
<div class="outline-text-3" id="text-5.1">
<p>如果打开了gdb-many-windows，在右上角会显示Locals buffer，其中显示了当前局部变量的值。如果显示的是寄存器（Register）buffer，单击左边的Locals就可以切换到Locals　buffer了。在其中可以方便地观察到各变量的值。
</p>
<p>
如果没有打开gdb-many-windows，也可以使用gdb-display-locals-buffer来显示该buffer。
</p>
</div>
</div>
<div id="outline-container-5.2" class="outline-3">
<h4 id="sec-5.2"><span class="section-number-3">5.2</span> 察看变量值 </h4>
<div class="outline-text-3" id="text-5.2">
<p>遇到一些Locals里没有显示的变量，或者比较复杂的结构，就需要用到观察变量的功能了。
</p>
<p>
将光标停留在要观察的变量上，执行命令gud-watch，可以将变量加入观察列表中。默认的快捷键是C-x C-a C-w。也可以使用工具栏上的 <img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-toolbar-watch.png"  alt="查看变量" />。
</p>
<p>
被观察的变量将在Speedbar中显示。对于复杂结构，可以单击Speedbar上的+号将其展开或收缩。在+号上按空格键也有相同的效果。<sup><a class="footref" name="fnr.2" href="#fn.2">2</a></sup>
</p>
<p>
有时候Emacs观察的变量不是你所想要的，一般是a-&gt;b这类的情况。这时可以将要观察的部分选中，再使用上述方法即可。
</p>
<p><img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-watch-speedbar.png"/></p>
</div>
</div>
<div id="outline-container-5.3" class="outline-3">
<h4 id="sec-5.3"><span class="section-number-3">5.3</span> 用工具提示显示变量值 </h4>
<div class="outline-text-3" id="text-5.3">
<p>可以用gud-tooltip-mode开启或关闭工具提示。开启后将鼠标指针停留在变量名上时将在工具提示中显示变量的值。
</p>
<p><img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-tooltip-mode.png"/></p>
</div>
</div>
<div id="outline-container-5.4" class="outline-3">
<h4 id="sec-5.4"><span class="section-number-3">5.4</span> 小结 </h4>
<div class="outline-text-3" id="text-5.4">
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption></caption>
<colgroup>
<col align="left" />
<col align="left" />
<col align="left" />
</colgroup>
<thead>
<tr>
<th scope="col">功能</th>
<th scope="col">命令</th>
<th scope="col">默认快捷键</th>
</tr>
</thead>
<tbody>
<tr>
<td>观察变量</td>
<td>gud-watch</td>
<td>C-x C-a C-w</td>
</tr>
<tr>
<td>展开/收缩变量</td>
<td></td>
<td>&lt;SPC&gt;</td>
</tr>
<tr>
<td>开启/关闭工具提示</td>
<td>gud-tooltip-mode</td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="outline-container-6" class="outline-2">
<h3 id="sec-6"><span class="section-number-2">6</span> 输入输出 </h3>
<div class="outline-text-2" id="text-6">
<p>如果程序需要与标准输入/输出交互，那么你很可能需要用到下面要介绍的功能。
</p>
</div>
<div id="outline-container-6.1" class="outline-3">
<h4 id="sec-6.1"><span class="section-number-3">6.1</span> 单独的IO buffer </h4>
<div class="outline-text-3" id="text-6.1">
<p>默认来说，程序的输入输出是在gdb buffer里显示的。这样输出信息和gdb信息混合在一起，阅读起来非常不便。这时候，你需要把输入输出单独显示在一个buffer里，方便查看。
</p>
<p>
使用gdb-use-separate-io-buffer，可以在程序代码buffer右侧新建一个IO buffer，程序对标准输入输出的操作都会重定向到这里。再执行一次该命令则会隐藏。
</p>
<p><img src="https://dea.googlecode.com/svn/trunk/screenshots/gdb/emacs-gdb-io-buffer.png"/></p>
</div>
</div>
<div id="outline-container-6.2" class="outline-3">
<h4 id="sec-6.2"><span class="section-number-3">6.2</span> 输入数据 </h4>
<div class="outline-text-3" id="text-6.2">
<p>需要输入数据的时候，只需要在IO buffer中输入数据回车即可。已经输入的数据会被加粗，以和输出信息区分开来。
</p>
</div>
</div>
<div id="outline-container-6.3" class="outline-3">
<h4 id="sec-6.3"><span class="section-number-3">6.3</span> 重定向到文件 </h4>
<div class="outline-text-3" id="text-6.3">
<p>有时候我们已经准备好了用于输入的数据在文件中，以避免调试时烦琐的输入。这时候就需要在调试时进行输入输出重定向了。
</p>
<p>
要进行重定向，只能使用gdb自带的功能。在gdb buffer中输入 run &lt; data.in &gt; data.out 就可以将标准输入重定向到data.in，将标准输出重定向到data.out了。
</p>
</div>
</div>
</div>
<div id="outline-container-7" class="outline-2">
<h3 id="sec-7"><span class="section-number-2">7</span> 按键绑定 </h3>
<div class="outline-text-2" id="text-7">
<p>说实话，gud自带的按键绑定实在是麻烦，使用一个功能要三次组合键才行，小姆指按Ctrl都按酸了。所以一般将常用的按键绑定在方便的位置，这样才能有和另的IDE一样的快感。
</p>
<p>
以下是将F5、F7、F8分别绑定到gud-go、gud-step和gud-next的代码：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41056code123'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41056123"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p41056code123"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>add-hook 'gdb-mode-hook '<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
                            <span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>f5<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'gud-<span style="color: #b1b100;">go</span><span style="color: #66cc66;">&#41;</span>
                            <span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>f7<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'gud-step<span style="color: #66cc66;">&#41;</span>
                            <span style="color: #66cc66;">&#40;</span>define-key c-mode-base-map <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>f8<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'gud-next<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
之所以绑定到c-mode-base-map上，是因为我基本上在代码buffer中调试。如果要在gdb-buffer中使用的话，需要使用gud-mode-map。如果想在所有buffer上使用的话，可以绑定到全局按键中：
</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p41056code124'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p41056124"><td class="code" id="p41056code124"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>global-set-key <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>f5<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> 'gud-<span style="color: #b1b100;">go</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

</div>
</div>
<div id="outline-container-8" class="outline-2">
<h3 id="sec-8"><span class="section-number-2">8</span> 结尾 </h3>
<div class="outline-text-2" id="text-8">
<p>有了调试功能，Emacs作为一个IDE才算是完整了。本文介绍了在Emacs下使用gdb调试的基本方法，Emacs的调试功能还远不止这些，进一步学习可参阅 <a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/index.html">Emacs Manual</a> 的 <a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/Debuggers.html#Debuggers">Debuggers</a> 一节。
</p>
<p>
由于我也是边学边写，一定有许多不足或者错误，还请各位多多指教。
</p>
</div>
</div>
<div id="footnotes">
<h3 class="footnotes">Footnotes: </h3>
<div id="text-footnotes">
<p class="footnote"><sup><a class="footnum" name="fn.1" href="#fnr.1">1</a></sup> 注：我在使用时只有光标所在的行在当前行之后并且位于同一函数内才行，否则会跳到很奇怪的地方，还请高手指教。
</p>
<p class="footnote"><sup><a class="footnum" name="fn.2" href="#fnr.2">2</a></sup> 我在使用过程中经常出现展开没反应，或者加入新元素后才展开，运行几步才展开的情况，求高人讲解。
</p>
</div>
</div>

<script type="text/javascript" src="http://china-addthis.googlecode.com/svn/trunk/addthis.js" charset="utf-8"></script><span class='addthis_org_cn'><a u='http://emacser.com/emacs-gdb.htm' t='在Emacs中使用gdb调试程序' d='' tag='ann,CEDET,ctrl,ede,Emacs,gdb,gud,IDE,lambda,org,screenshot,speedbar,text,windows,光标,工具栏,补全,配色,鼠标' href='http://addthis.org.cn/share/' title='收藏-分享'><img src='http://emacser.com/wp-content/plugins/addthischina/a1.gif' alt='分享家:Addthis中国' align='absmiddle' /></a></span>
	<h4>相关日志</h4>
	<ul class="st-related-posts">
	<li><a href="http://emacser.com/cedet.htm" title="用CEDET浏览和编辑C++代码 (2010年03月18日)">用CEDET浏览和编辑C++代码</a> (198)</li>
	<li><a href="http://emacser.com/dea.htm" title="我的Emacs配置文件 － DEA (2009年11月11日)">我的Emacs配置文件 － DEA</a> (352)</li>
	<li><a href="http://emacser.com/emacs-cpp-dev.htm" title="在Emacs下用C/C++编程 (2010年10月25日)">在Emacs下用C/C++编程</a> (37)</li>
	<li><a href="http://emacser.com/emacs.htm" title="Emacs长啥样 (2009年11月5日)">Emacs长啥样</a> (16)</li>
	<li><a href="http://emacser.com/emacs-23-2-release.htm" title="GNU Emacs 23.2发布 (2010年05月9日)">GNU Emacs 23.2发布</a> (32)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://emacser.com/emacs-gdb.htm/feed</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
	</channel>
</rss>

