<?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>右舷 &#187; elisp</title>
	<atom:link href="http://www.laihj.net/tag/elisp/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.laihj.net</link>
	<description>list(linux,emacs,旅行,读书,andriod,MacOS,iOS)</description>
	<lastBuildDate>Tue, 27 Dec 2011 12:54:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>[elisp]用elisp编译解释当前的buffer</title>
		<link>http://www.laihj.net/2010/02/execute-compile-current-file/</link>
		<comments>http://www.laihj.net/2010/02/execute-compile-current-file/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 13:58:43 +0000</pubDate>
		<dc:creator>laihj</dc:creator>
				<category><![CDATA[善其事]]></category>
		<category><![CDATA[elisp]]></category>
		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://www.laihj.net/?p=650132</guid>
		<description><![CDATA[运行当前的buffer，就是说编译或解释当前的buferr。比如在编辑的是python文件&#8221;hello.py&#8221;，那么运行它的命令就是&#8221;python hello.py&#8221;，一般的python-mode用&#8221;C-c C-c&#8221;来处理这个问题，在编辑过程中可以调用这个快捷键来运行。当然你也可以使用&#8221;M-!&#8221;来打开shell command的mini buffer来输入命令。
诚然，很多语言的mode里面实际上都内置了这一功能，但我觉得，一方面不同的mode可能定义不同快捷键，造成了额外的记忆负担，另一方面并不能要求所有的mode都提供这一功能，在mode不完整的情况下你大概也需要自己定义的能力。
要做这事儿，当然是自定义一个函数。那么最直观的想法，就是在elisp里面写一行调用shell来执行命令的代码。是的，有这种东西，示例如下:

  (shell-command "python hello.py")


这一行代码的相当于在终端中执行&#8221;python hello.py&#8221;。
我们的目的是执行当前buffer,所以下一步要做的是得到当前buffer所对应的文件名。在上一篇blog中介绍过相关方法，就是&#8221;buffer-file-name&#8221;。
于是代码就变成了这样。

  (shell-command (concat "python " (buffer-file-name)))


用concat把&#8221;python &#8220;和当前buffer的文件名连起来作为要执行的命令。
至此，就完成了.py文件的执行函数，那推广之，需要对不同的文件进行编译/解释时，就需要扩展这个命令。
我们知道对.sh文件要用bash命令执行，对.py要用python，对.htm要调用firefox。现在要做的就是让机器知道这件事。很明显的，我们需要一个map，把它们对应地存下来。
完整的代码和注释如下:

(defun run-current-file ()
(interactive)
(let (ext-map file-name file-ext prog-name cmd-str
(setq ext-map
         '(
            ("py" . "python")
        [...]]]></description>
			<content:encoded><![CDATA[<p>运行当前的buffer，就是说编译或解释当前的buferr。比如在编辑的是python文件&#8221;hello.py&#8221;，那么运行它的命令就是&#8221;python hello.py&#8221;，一般的python-mode用&#8221;C-c C-c&#8221;来处理这个问题，在编辑过程中可以调用这个快捷键来运行。当然你也可以使用&#8221;M-!&#8221;来打开shell command的mini buffer来输入命令。</p>
<p>诚然，很多语言的mode里面实际上都内置了这一功能，但我觉得，一方面不同的mode可能定义不同快捷键，造成了额外的记忆负担，另一方面并不能要求所有的mode都提供这一功能，在mode不完整的情况下你大概也需要自己定义的能力。</p>
<p>要做这事儿，当然是自定义一个函数。那么最直观的想法，就是在elisp里面写一行调用shell来执行命令的代码。是的，有这种东西，示例如下:</p>
<p><pre name="code" class="py">
  (shell-command "python hello.py")
</pre>
</p>
<p>这一行代码的相当于在终端中执行&#8221;python hello.py&#8221;。</p>
<p>我们的目的是执行当前buffer,所以下一步要做的是得到当前buffer所对应的文件名。在<a href="http://www.laihj.net/2010/02/elisp-emacs-editing-basics/">上一篇blog</a>中介绍过相关方法，就是&#8221;buffer-file-name&#8221;。</p>
<p>于是代码就变成了这样。</p>
<p><pre name="code" class="py">
  (shell-command (concat "python " (buffer-file-name)))
</pre>
</p>
<p>用concat把&#8221;python &#8220;和当前buffer的文件名连起来作为要执行的命令。</p>
<p>至此，就完成了.py文件的执行函数，那推广之，需要对不同的文件进行编译/解释时，就需要扩展这个命令。</p>
<p>我们知道对.sh文件要用bash命令执行，对.py要用python，对.htm要调用firefox。现在要做的就是让机器知道这件事。很明显的，我们需要一个map，把它们对应地存下来。</p>
<p>完整的代码和注释如下:</p>
<p><pre name="code" class="py">
(defun run-current-file ()
(interactive)
(let (ext-map file-name file-ext prog-name cmd-str
(setq ext-map
         '(
            ("py" . "python")
            ("sh" . "bash")
            ("htm" . "firefox")
            )
          );定义命令－文件类型映身表.
    (setq file-name (buffer-file-name));得到当前的buffer名
    (setq file-ext (file-name-extension file-name));得到后缀
    (setq prog-name (cdr (assoc file-ext ext-map)))；根据后缀得到执行的命令，通过对ext-map的查找
    (setq cmd-str (concat prog-name " " file-name));拼出一个命令
    (shell-command cmd-str)))；执行
  </pre>
</p>
<p>完毕，为这个函数绑定一个键，在编辑相应文件的时候调用，就可以对其进行需要的操作了，不仅限于编译和解释，实际上很容易看出来，只要shell能支持的，你可以玩。当然，要有权限。</p>
<p>Have Fun!</p>
<h3>Related Posts</h3><ul><li><a href="http://www.laihj.net/2010/02/elisp-emacs-editing-basics/" title="[elisp]针对Emacs中文本编辑的编程简介 2010.02.3">[elisp]针对Emacs中文本编辑的编程简介</a>(0)</li>
<li><a href="http://www.laihj.net/2010/01/elipsemacslisp-basi/" title="[elisp]EmacsLisp 基础 2010.01.31">[elisp]EmacsLisp 基础</a>(0)</li>
<li><a href="http://www.laihj.net/2010/03/editors-learning-curves/" title="编辑器的学习曲线 2010.03.3">编辑器的学习曲线</a>(0)</li>
<li><a href="http://www.laihj.net/2010/01/emacs-orgmode-remember/" title="Emacs的orgmode [remember] 2010.01.20">Emacs的orgmode [remember]</a>(4)</li>
<li><a href="http://www.laihj.net/2010/01/emacs-orgmode-tags/" title="Emacs的orgmode [tags］ 2010.01.15">Emacs的orgmode [tags］</a>(0)</li>
<li><a href="http://www.laihj.net/2010/01/code-complete-yasnippet/" title="emacs代码补完－yasnippet 2010.01.8">emacs代码补完－yasnippet</a>(1)</li>
<li><a href="http://www.laihj.net/2010/01/emacs-orgmode-archieved/" title="Emacs的orgmode [归档］ 2010.01.2">Emacs的orgmode [归档］</a>(1)</li>
<li><a href="http://www.laihj.net/2009/12/emacs%e7%9a%84org-mode-agenda-view/" title="Emacs的org-mode [agenda view] 2009.12.29">Emacs的org-mode [agenda view]</a>(0)</li>
<li><a href="http://www.laihj.net/2009/12/emacs%e7%9a%84org-mode-%e6%97%a5%e6%9c%9f%e4%b8%8e%e6%97%b6%e9%97%b4/" title="Emacs的org-mode [日期与时间] 2009.12.26">Emacs的org-mode [日期与时间]</a>(1)</li>
<li><a href="http://www.laihj.net/2009/12/emacs%e7%9a%84org-mode%ef%bc%bbtodo%ef%bc%bd/" title="Emacs的org-mode［TODO］ 2009.12.25">Emacs的org-mode［TODO］</a>(0)</li>
</ul><h3>Recent Comments</h3><ul></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laihj.net/2010/02/execute-compile-current-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[elisp]针对Emacs中文本编辑的编程简介</title>
		<link>http://www.laihj.net/2010/02/elisp-emacs-editing-basics/</link>
		<comments>http://www.laihj.net/2010/02/elisp-emacs-editing-basics/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 11:25:05 +0000</pubDate>
		<dc:creator>laihj</dc:creator>
				<category><![CDATA[负暄琐话]]></category>
		<category><![CDATA[elisp]]></category>
		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://www.laihj.net/?p=650125</guid>
		<description><![CDATA[
Elisp是Emacs下的Lisp方言，而Emacs是一款编辑器。那么针对于Emacs，Lisp要做的很重要一部分工作当然就是对编辑的自动化支持。比如移动鼠标，输入句子，查找替换，代码高亮等等，简单地说，就是为更好更方便地支持文本编辑提供支持。而把这些函数都重合起来，就起成了Emacs mode。如我们常用的C++ mode,python mode。还有之前我一直在介绍的org-mode等，都是由Elisp拼成的。
学习Elisp，可以满足对Emacs进行定制的需求，你可以把想要的功能写在.el文件里面，让Emacs来调用。一方面可以实现一些简单的轻量级的功能，而不需要为此寻找和安装一个完整的mode。另一方面，可以修改现有的mode，使得更符合自己的习惯。这符合开源的作法，不爽即改。
Elisp函数的简单例子
光标位置

?View Code LISP ;返回当前光标的位置
  &#40;point&#41;
  ;region的头跟尾
  &#40;region-beginning&#41;
  &#40;region-end&#41;
  ;最大光标位置（即文件尾），elisp还提供最小光标位置(point-min)，不过我觉得那应该都是1吧。
  &#40;point-max&#41;
  ;返回buffer结尾的绝对位置，无视narrow-to-region
  &#40;buffer-end 1&#41;

移动光标和搜索

?View Code LISP;移动光标到392
&#40;goto-char 392&#41;
&#160;
; 向前/向后移动n字符
&#40;forward-char n&#41;
&#40;backward-char n&#41;
&#160;
; 跳过所有\n\t,即把光标移动第一个不是换行或制表符那里
; 返回移动的字符数
&#40;skip-chars-forward &#34;\n\t&#34;&#41;
&#40;skip-chars-backward &#34;\n\t&#34;&#41;
&#160;
;移动光标到myStr后面，向前和向后
;返回新的光标位置
&#40;search-forward myStr&#41;
&#40;search-backward myStr&#41;
&#160;
; 同上，但是参数是正则表达式，myRegex
; 返回新的光标位置
&#40;re-search-forward myRegex&#41;
&#40;re-search-backward myRegex&#41;

文本编辑

?View Code LISP; 删除光标后的九个字符
&#40;delete-char 9&#41;
&#160;
; 删除选中的两点之前的文本
&#40;delete-region mystartpos myendpos&#41;
&#160;
; 在当前光标位置插入一字符串
&#40;insert &#34;Forza Inter&#34;&#41;
&#160;
; 从buffer中获得一个字符串并赋给mystr
&#40;setq Mystr &#40;buffer-substring mystartpos myendpos&#41;&#41;
&#160;
; [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-650126" title="emacs" src="http://www.laihj.net/wp-content/uploads/2010/02/images.jpg" alt="emacs" width="91" height="91" /></p>
<p>Elisp是Emacs下的Lisp方言，而Emacs是一款编辑器。那么针对于Emacs，Lisp要做的很重要一部分工作当然就是对编辑的自动化支持。比如移动鼠标，输入句子，查找替换，代码高亮等等，简单地说，就是为更好更方便地支持文本编辑提供支持。而把这些函数都重合起来，就起成了Emacs mode。如我们常用的C++ mode,python mode。还有之前我一直在介绍的org-mode等，都是由Elisp拼成的。</p>
<p>学习Elisp，可以满足对Emacs进行定制的需求，你可以把想要的功能写在.el文件里面，让Emacs来调用。一方面可以实现一些简单的轻量级的功能，而不需要为此寻找和安装一个完整的mode。另一方面，可以修改现有的mode，使得更符合自己的习惯。这符合开源的作法，不爽即改。</p>
<h3>Elisp函数的简单例子</h3>
<h4>光标位置</h4>

<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('p650125code8'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p6501258"><td class="code" id="p650125code8"><pre class="lisp" style="font-family:monospace;"> <span style="color: #808080; font-style: italic;">;返回当前光标的位置</span>
  <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">;region的头跟尾</span>
  <span style="color: #66cc66;">&#40;</span>region-beginning<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>region-end<span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">;最大光标位置（即文件尾），elisp还提供最小光标位置(point-min)，不过我觉得那应该都是1吧。</span>
  <span style="color: #66cc66;">&#40;</span>point-<span style="color: #b1b100;">max</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">;返回buffer结尾的绝对位置，无视narrow-to-region</span>
  <span style="color: #66cc66;">&#40;</span>buffer-end <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<h4>移动光标和搜索</h4>

<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('p650125code9'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p6501259"><td class="code" id="p650125code9"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;移动光标到392</span>
<span style="color: #66cc66;">&#40;</span>goto-char <span style="color: #cc66cc;">392</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 向前/向后移动n字符</span>
<span style="color: #66cc66;">&#40;</span>forward-char n<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>backward-char n<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 跳过所有\n\t,即把光标移动第一个不是换行或制表符那里</span>
<span style="color: #808080; font-style: italic;">; 返回移动的字符数</span>
<span style="color: #66cc66;">&#40;</span>skip-chars-forward <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>skip-chars-backward <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;移动光标到myStr后面，向前和向后</span>
<span style="color: #808080; font-style: italic;">;返回新的光标位置</span>
<span style="color: #66cc66;">&#40;</span>search-forward myStr<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>search-backward myStr<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 同上，但是参数是正则表达式，myRegex</span>
<span style="color: #808080; font-style: italic;">; 返回新的光标位置</span>
<span style="color: #66cc66;">&#40;</span>re-search-forward myRegex<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>re-search-backward myRegex<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<h4>文本编辑</h4>

<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('p650125code10'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p65012510"><td class="code" id="p650125code10"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">; 删除光标后的九个字符</span>
<span style="color: #66cc66;">&#40;</span>delete-char <span style="color: #cc66cc;">9</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 删除选中的两点之前的文本</span>
<span style="color: #66cc66;">&#40;</span>delete-region mystartpos myendpos<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 在当前光标位置插入一字符串</span>
<span style="color: #66cc66;">&#40;</span>insert <span style="color: #ff0000;">&quot;Forza Inter&quot;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 从buffer中获得一个字符串并赋给mystr</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> Mystr <span style="color: #66cc66;">&#40;</span>buffer-substring mystartpos myendpos<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 改变字符大小写</span>
<span style="color: #808080; font-style: italic;">;这个例子是指当前光标之前的20个字符</span>
<span style="color: #66cc66;">&#40;</span>rapitalize-region <span style="color: #66cc66;">&#40;</span>- <span style="color: #66cc66;">&#40;</span>point<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">20</span><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></pre></td></tr></table></div>

<h4>字符串</h4>

<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('p650125code11'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p65012511"><td class="code" id="p650125code11"><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;">length</span> <span style="color: #ff0000;">&quot;abc&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">; returns 3</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 获取一个子串</span>
<span style="color: #66cc66;">&#40;</span>substring myStr startIndex endIndex<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 替换，以正则方式</span>
<span style="color: #66cc66;">&#40;</span>replace-regexp-in-string myRegex myReplacement myStr<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<h4>Buffers</h4>

<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('p650125code12'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p65012512"><td class="code" id="p650125code12"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">; 当前buffer的名字</span>
<span style="color: #66cc66;">&#40;</span>buffer-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 文件名（全路径)</span>
<span style="color: #66cc66;">&#40;</span>buffer-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 设定一个buffer名</span>
<span style="color: #66cc66;">&#40;</span>set-buffer myBufferName<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 保存</span>
<span style="color: #66cc66;">&#40;</span>save-buffer<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 关闭指定的buffer</span>
<span style="color: #66cc66;">&#40;</span>kill-buffer myBuffName<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 关闭当前buffer</span>
<span style="color: #66cc66;">&#40;</span>kill-this-buffer<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 临时指定一个buffer作为当前buffer</span>
<span style="color: #66cc66;">&#40;</span>with-current-buffer myBuffer
  <span style="color: #808080; font-style: italic;">; do something here ...</span>
<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<h4>Files</h4>

<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('p650125code13'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p65012513"><td class="code" id="p650125code13"><pre class="lisp" style="font-family:monospace;">  <span style="color: #808080; font-style: italic;">; 打开一个文件</span>
<span style="color: #66cc66;">&#40;</span>find-file myPath<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 另存</span>
<span style="color: #808080; font-style: italic;">; 会关闭当前的buffer，打开另存好的文件</span>
<span style="color: #66cc66;">&#40;</span>write-file myPath<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 把一个文件内容插入到当前位置</span>
<span style="color: #66cc66;">&#40;</span>insert-file-contents myPath<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 将选中的评论文本加到某个文件后面</span>
<span style="color: #66cc66;">&#40;</span>append-to-file myStartPos myEndPos myPath<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 重命名</span>
<span style="color: #66cc66;">&#40;</span>rename-file fileName newName<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 复制</span>
<span style="color: #66cc66;">&#40;</span>copy-file oldName newName<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 删除</span>
<span style="color: #66cc66;">&#40;</span>delete-file fileName<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 获取路径</span>
<span style="color: #66cc66;">&#40;</span>file-name-directory myFullPath<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 获取文件名(不含路径)</span>
<span style="color: #66cc66;">&#40;</span>file-name-nondirectory myFullPath<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 得到文件名后缀</span>
<span style="color: #66cc66;">&#40;</span>file-name-extension myFileName<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; 获得不含后缀的文件名。</span>
<span style="color: #66cc66;">&#40;</span>file-name-sans-extension <span style="color: #ff0000;">&quot;abc.htm&quot;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<h4>简单的例子</h4>

<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('p650125code14'); return false;">View Code</a> LISP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p65012514"><td class="code" id="p650125code14"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> insert-p-tag <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Insert
&nbsp;
 at cursor point.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>insert <span style="color: #ff0000;">&quot;
&nbsp;
&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>backward-char <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>在当前光标处插入一个p tag。做法是插放一个串，然后将光标移回4位。</p>
<h3>编写一个mode</h3>
<p>理论上来讲，知道上面这些东西，你就有能力编写一个mode了。但是，编写mode毕竟是一个复杂的工作，需要编写者对elisp编程具有&#8221;hello world&#8221;以上很多级的熟练度。</p>
<p>在李杀网，作者有<a href="http://xahlee.org/emacs/elisp_syntax_coloring.html">一个系列文章来讨论如何为一个编程语言编写mode</a>。</p>
<p>The End. Have fun!</p>
<h3>Related Posts</h3><ul><li><a href="http://www.laihj.net/2010/02/execute-compile-current-file/" title="[elisp]用elisp编译解释当前的buffer 2010.02.12">[elisp]用elisp编译解释当前的buffer</a>(0)</li>
<li><a href="http://www.laihj.net/2010/01/elipsemacslisp-basi/" title="[elisp]EmacsLisp 基础 2010.01.31">[elisp]EmacsLisp 基础</a>(0)</li>
<li><a href="http://www.laihj.net/2010/03/editors-learning-curves/" title="编辑器的学习曲线 2010.03.3">编辑器的学习曲线</a>(0)</li>
<li><a href="http://www.laihj.net/2010/01/emacs-orgmode-remember/" title="Emacs的orgmode [remember] 2010.01.20">Emacs的orgmode [remember]</a>(4)</li>
<li><a href="http://www.laihj.net/2010/01/emacs-orgmode-tags/" title="Emacs的orgmode [tags］ 2010.01.15">Emacs的orgmode [tags］</a>(0)</li>
<li><a href="http://www.laihj.net/2010/01/code-complete-yasnippet/" title="emacs代码补完－yasnippet 2010.01.8">emacs代码补完－yasnippet</a>(1)</li>
<li><a href="http://www.laihj.net/2010/01/emacs-orgmode-archieved/" title="Emacs的orgmode [归档］ 2010.01.2">Emacs的orgmode [归档］</a>(1)</li>
<li><a href="http://www.laihj.net/2009/12/emacs%e7%9a%84org-mode-agenda-view/" title="Emacs的org-mode [agenda view] 2009.12.29">Emacs的org-mode [agenda view]</a>(0)</li>
<li><a href="http://www.laihj.net/2009/12/emacs%e7%9a%84org-mode-%e6%97%a5%e6%9c%9f%e4%b8%8e%e6%97%b6%e9%97%b4/" title="Emacs的org-mode [日期与时间] 2009.12.26">Emacs的org-mode [日期与时间]</a>(1)</li>
<li><a href="http://www.laihj.net/2009/12/emacs%e7%9a%84org-mode%ef%bc%bbtodo%ef%bc%bd/" title="Emacs的org-mode［TODO］ 2009.12.25">Emacs的org-mode［TODO］</a>(0)</li>
</ul><h3>Recent Comments</h3><ul></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laihj.net/2010/02/elisp-emacs-editing-basics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[elisp]EmacsLisp 基础</title>
		<link>http://www.laihj.net/2010/01/elipsemacslisp-basi/</link>
		<comments>http://www.laihj.net/2010/01/elipsemacslisp-basi/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 06:48:42 +0000</pubDate>
		<dc:creator>laihj</dc:creator>
				<category><![CDATA[善其事]]></category>
		<category><![CDATA[elisp]]></category>
		<category><![CDATA[emacs]]></category>

		<guid isPermaLink="false">http://www.laihj.net/?p=650122</guid>
		<description><![CDATA[来源:李杀网
李杀网有一枚elisp教程我很喜欢，原因是它不解释太多的名词，而从实际动作方面入手，对我的胃口。
以下是相关的笔记。
运行方式：
作为一个实践的手册，第一件事当然是告诉如果运行一行代码，让你在看指南的过程中可以方便地动手尝试。

eval-last-sexp
输入后把光标移到表达式后面，如“(+ 3 4)”后面，然后输入&#8221;Alt+x eval-last-sexp&#8221;或者使用快捷键&#8221;C-x C-e&#8221;，就可以在mini buffer看到这一句的运行结果&#8221;7&#8243;。
eval-region
解释选中的区域。
ielm
打开一个交互式的elips命令行解释器。

寻找帮助:
可以使用&#8221;Alt + x describe-function&#8221;(快捷键&#8221;C-h f&#8221;)来查找一个函数的用法。也可以使用&#8221;Alt+x elisp-index-search&#8221;在手参考手册中查询。
常用函数
打印

  (message "hi")
  (message "her age is:%d" 16) ;%d 数字
  (message "her name is: %s" "Vicky") ;%s 字符串
  (message "her min init is: %c" 86) ;%c 字符

注意：你可以在*message* buffer中看到打印出来的结果。
运算函数

(+ 4 5 1 )  ;=10
(- 9 2)     ;=7
(* [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://xahlee.org/emacs/elisp_basics.html">来源:李杀网</a></p>
<p>李杀网有一枚elisp教程我很喜欢，原因是它不解释太多的名词，而从实际动作方面入手，对我的胃口。</p>
<p>以下是相关的笔记。</p>
<h4>运行方式：</h4>
<p>作为一个实践的手册，第一件事当然是告诉如果运行一行代码，让你在看指南的过程中可以方便地动手尝试。</p>
<ul>
<li>eval-last-sexp</li>
<p>输入后把光标移到表达式后面，如“(+ 3 4)”后面，然后输入&#8221;Alt+x eval-last-sexp&#8221;或者使用快捷键&#8221;C-x C-e&#8221;，就可以在mini buffer看到这一句的运行结果&#8221;7&#8243;。</p>
<li>eval-region</li>
<p>解释选中的区域。</p>
<li>ielm</li>
<p>打开一个交互式的elips命令行解释器。</p>
</ul>
<h4>寻找帮助:</h4>
<p><P>可以使用&#8221;Alt + x describe-function&#8221;(快捷键&#8221;C-h f&#8221;)来查找一个函数的用法。也可以使用&#8221;Alt+x elisp-index-search&#8221;在手参考手册中查询。</p>
<h3>常用函数</h3>
<h4>打印</h4>
<pre name="code" class="py">
  (message "hi")
  (message "her age is:%d" 16) ;%d 数字
  (message "her name is: %s" "Vicky") ;%s 字符串
  (message "her min init is: %c" 86) ;%c 字符
</pre>
<p>注意：你可以在*message* buffer中看到打印出来的结果。</p>
<h4>运算函数</h4>
<pre name="code" class="py">
(+ 4 5 1 )  ;=10
(- 9 2)     ;=7
(* 2 3)     ;=6
(* 2 3 4)   ;=24
(/ 7 2)     ;=3  结果的整数部分
(/ 7 2.0)   ;=3.5
(% 7 4)     ;=3 余数
</pre>
<p>注意，如果你的操作数是小数，必须把后面的0带上。就是说你应该写2.0，而不是2.。</p>
<pre name="code" class="py">
  (integerp 3.)  ;T
  (floatp 3.)    ;nil
  (floatp 3.0)   ;T
</pre>
<p>以字符p结尾的函数通常意味着它的返回值是True或者False。p意味着&#8221;predicate&#8221;(判定)。</p>
<h4>True和False</h4>
<p>在elisp中，标识&#8221;nil&#8221;代表false，其它的一切都是true,包括0。&#8221;nil&#8221;是空链表&#8221;()&#8221;的同义词。所以&#8221;()&#8221;也是false。</p>
<p>按惯例，标识&#8221;t&#8221;用来表示true。</p>
<pre name="code" class="py">
  (and t nil) ; nil
  (or t nil)  ; t
</pre>
<p>在elisp中没有布尔型，只需记住&#8221;nil&#8221;和&#8221;()&#8221;是false，其它一切都是true。</p>
<h4>比较函数</h4>
<p>比较数字</p>
<pre name="code" class="py">
  (< 3 4) ;小于
  (<= 3 4)  ;小于等于
  (> 3 4)  ;大于
  (>= 3 4) ;大于等于
  (= 3 3)  ;等于
</pre>
<p>比较字符串</p>
<pre name="code" class="py">
  (string= "this" "thiS")
  (string< "a" "b")
  (string< "B" "b")
</pre>
<p>在字符串比较中大小写是敏感的。比较依据是字典顺序。</p>
<p>要比较两个sysbols是否有相同的数据类型和值，使用"equal"。</p>
<pre name="code" class="py">
(equal "abc" "abc") ;t
(equal 3 3)         ;t
(equal 3 3.0)       ;nil.类型不同
(equal '(3 4 5) '(3 4 5))  ; t
(equal '(3 4 5) '(3 4 "5"))  ;nil
</pre>
<p>在Elisp中并没有"!="或者“not-equal”。判断不等，可以在对整个等式取非。</p>
<pre name="code" class="py">
  (not (= 3 4))  ;t
</pre>
<h4>全局和局部变量</h4>
<p>"setq"用于给变量赋值。格式一般为"setq 变量1 值1 变量2 值2..."</p>
<p>在lisp中，变量不需要声时，并且是全局的。</p>
<pre name="code" class="py">
  (setq a 3 b 2 c 7)  ;三个变是，a=3 b=2 c=7
</pre>
<p>定义局部变量，使用let。格式为"(let (变量1 变量2) body)"。"body"代表其它的表达式。其中最后一个表达式的取值是整个语句块的返回值。</p>
<pre name="code" class="py">
  (let (a b)
  (setq a 3)
  (setq b 4)
  (+ a b)
  )
</pre>
<p>a和b都是这个语句块的局部变量，返值是最后一个表达式"(+ a b)"的取值。</p>
<p>另一种格式是"(let ((变量1 值1)(变量2 值2)) body )"。例如：</p>
<pre name="code" class="py">
  (let ((a 3) (b 4))
  (+ a b)
  )
</pre>
<p>如果你的变量很少，并且值都是已经确定的，可以用这种方法。</p>
<h4>表达式块</h4>
<p>有时需要把一些表达式括起来。这时可以使用"progn"。</p>
<pre name="code" class="py">
  (progn (message "hi"))
</pre>
<p>它相当于</p>
<pre name="code" class="py">
  (message "hi")
</pre>
<p>"progn"类似于C语言中的"{...}"。它使用于某些需要把语句合并起来的场合，其实这跟C语言中也是一样的。比如："(if something (progn this that))"。这里，如果把progn去掉，变成"(if somethong this that"，在lisp中表示如果something,那么this,否则that。在有progn把this和that括真情 为情况下，表示的是如果something，那么执行this和that。</p>
<h4>If then else</h4>
<p>格式为"(if test then <else>)"。"else"是可选的。例：</p>
<pre name="code" class="py">
  (if (< 3 2) (message "yes")))
  (if (< 3 2) (message "yes") (message "no")))
</pre>
<h4>迭代循环</h4>
<p>使用while。</p>
<pre name="code" class="py">
  (setq x 0)
  (while (< x 4)
     (princ (format "yay %d." x))
     (setq x (+ 1 x)))
</pre>
<p>在elisp中，并没有for语句。</p>
<h4>Lists</h4>
<p>在lisp中的List是这样的：“'(x y z)”。括号前面那个单引号是很重要的。不需要太在意它的含义，把它当成句法的一部份即可。</p>
<pre name="code" class="py">
  (message "%S" '(a b c))
  (setq mylist '(a b c))  ;定义
  (let ((x 3) (y 4) (z 5))
      (message "%S" (list x y z))
  )
</pre>
<p>以下是List的一些函数：</p>
<table border="1">
<tr>
<th>Function</th>
<th>目的</th>
</tr>
<tr>
<td>(car mylist)</td>
<td>取第一个元素</td>
</tr>
<tr>
<td>(nth n mylist)</td>
<td>最第n个元素</td>
</tr>
<tr>
<td>(car (last mylist))</td>
<td>取最后一个元素</td>
</tr>
<tr>
<td>(cdr mylist)</td>
<td>从第二个到最后一个</td>
</tr>
<tr>
<td>(nthcdr n mylist)</td>
<td>从第n个到最后一个元素</td>
</tr>
<tr>
<td>(butlast mylist n)</td>
<td>不包含n到最后一个元素</td>
</tr>
</table>
<p>这里所说的n，都是从0开始的。</p>
<p>下列是一些例子。</p>
<pre name="code" class="py">
  (car (list "a" "b" "c"))
  (nth 2 (list "a" "b" "c"))
  (last (list "a" "b" "c"))
</pre>
<table border="1">
<caption>Basic List Functions</caption>
<tr>
<th>Function</th>
<th>目的</th>
</tr>
<tr>
<td>(length mylist)</td>
<td>List长度</td>
</tr>
<tr>
<td>(cons x mylist)</td>
<td>把x加到list前面</td>
</tr>
<tr>
<td>(append mylist1 mylist2)</td>
<td>连接两个List</td>
</tr>
</table>
<p>例如:</p>
<pre name="code" class="py">
  (length (list "a" "b" "c"))
</pre>
<table border="1">
<tr>
<th>Function</th>
<th>Purpose</th>
</tr>
<tr>
<td>(pop mylist)</td>
<td>删除第一个元素并返回</td>
</tr>
<tr>
<td>(nbutlast mylist n)</td>
<td>删除第n个元素，返回删除后的list.</td>
</tr>
<tr>
<td>(setcar mylist x)</td>
<td>替换第一个元素，并返回</td>
</tr>
<tr>
<td>(setcdr mylist x)</td>
<td>替换除第一个之外的所有元素 </tr>
</table>
<h4>遍历运算数组</h4>
<pre name="code" class="py">
  (mapcar '1+ '(1 2 3 4))
</pre>
<p>上例的做所是遍历list中的每一个元素，并对它进行"1+"的操作。</p>
<p>当然，也可以用while循环来完成这件事。</p>
<h4>定义函数</h4>
<p>基本的函数定义方式是"defun <name> (param) "doc" <body>"。</p>
<pre name="code" class="py">
  (defun myFunction () "testing" (message "Yay!"))
</pre>
<p>myFunction是函数名，这个函数无参，函数注释"testing"，后面是函数体。</p>
<p>可以在doctsing后面加一个"interactive"来使得函数能跟环境进行交互（在emacs中，就呆以可用"Alt + x"来调用）</p>
<p>interactive的一些常用语法:</p>
<ul>
<li>(interactive) 无参</li>
<li>(interactive "n") 一个数字参数</li>
<li>(interactive "s") 一个字符串参数</li>
</ul>
<h3>Related Posts</h3><ul><li><a href="http://www.laihj.net/2010/02/execute-compile-current-file/" title="[elisp]用elisp编译解释当前的buffer 2010.02.12">[elisp]用elisp编译解释当前的buffer</a>(0)</li>
<li><a href="http://www.laihj.net/2010/02/elisp-emacs-editing-basics/" title="[elisp]针对Emacs中文本编辑的编程简介 2010.02.3">[elisp]针对Emacs中文本编辑的编程简介</a>(0)</li>
<li><a href="http://www.laihj.net/2010/03/editors-learning-curves/" title="编辑器的学习曲线 2010.03.3">编辑器的学习曲线</a>(0)</li>
<li><a href="http://www.laihj.net/2010/01/emacs-orgmode-remember/" title="Emacs的orgmode [remember] 2010.01.20">Emacs的orgmode [remember]</a>(4)</li>
<li><a href="http://www.laihj.net/2010/01/emacs-orgmode-tags/" title="Emacs的orgmode [tags］ 2010.01.15">Emacs的orgmode [tags］</a>(0)</li>
<li><a href="http://www.laihj.net/2010/01/code-complete-yasnippet/" title="emacs代码补完－yasnippet 2010.01.8">emacs代码补完－yasnippet</a>(1)</li>
<li><a href="http://www.laihj.net/2010/01/emacs-orgmode-archieved/" title="Emacs的orgmode [归档］ 2010.01.2">Emacs的orgmode [归档］</a>(1)</li>
<li><a href="http://www.laihj.net/2009/12/emacs%e7%9a%84org-mode-agenda-view/" title="Emacs的org-mode [agenda view] 2009.12.29">Emacs的org-mode [agenda view]</a>(0)</li>
<li><a href="http://www.laihj.net/2009/12/emacs%e7%9a%84org-mode-%e6%97%a5%e6%9c%9f%e4%b8%8e%e6%97%b6%e9%97%b4/" title="Emacs的org-mode [日期与时间] 2009.12.26">Emacs的org-mode [日期与时间]</a>(1)</li>
<li><a href="http://www.laihj.net/2009/12/emacs%e7%9a%84org-mode%ef%bc%bbtodo%ef%bc%bd/" title="Emacs的org-mode［TODO］ 2009.12.25">Emacs的org-mode［TODO］</a>(0)</li>
</ul><h3>Recent Comments</h3><ul></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laihj.net/2010/01/elipsemacslisp-basi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

