针对Emacs中文本编辑的编程简介
作者: laihj

Elisp是Emacs下的Lisp方言,而Emacs是一款编辑器。那么针对于Emacs,Lisp要做的很重要一部分工作当然就是对编辑的自动化支持。比如移动鼠标,输入句子,查找替换,代码高亮等等,简单地说,就是为更好更方便地支持文本编辑提供支持。而把这些函数都重合起来,就起成了Emacs mode。如我们常用的C++ mode,python mode。还有之前我一直在介绍的org-mode等,都是由Elisp拼成的。
学习Elisp,可以满足对Emacs进行定制的需求,你可以把想要的功能写在.el文件里面,让Emacs来调用。一方面可以实现一些简单的轻量级的功能,而不需要为此寻找和安装一个完整的mode。另一方面,可以修改现有的mode,使得更符合自己的习惯。这符合开源的作法,不爽即改。
Elisp函数的简单例子
光标位置
1 2 3 4 5 6 7 8 9 | ;; 返回当前光标的位置 (point) ;; region的头跟尾 (region-beginning) (region-end) ;; 最大光标位置(即文件尾),elisp还提供最小光标位置(point-min),不过我觉得那应该都是1吧。 (point-max) ;; 返回buffer结尾的绝对位置,无视narrow-to-region (buffer-end 1) |
移动光标和搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ;移动光标到392 (goto-char 392) ; 向前/向后移动n字符 (forward-char n) (backward-char n) ; 跳过所有\n\t,即把光标移动第一个不是换行或制表符那里 ; 返回移动的字符数 (skip-chars-forward "\n\t") (skip-chars-backward "\n\t") ; 移动光标到myStr后面,向前和向后 ; 返回新的光标位置 (search-forward myStr) (search-backward myStr) ; 同上,但是参数是正则表达式,myRegex ; 返回新的光标位置 (re-search-forward myRegex) (re-search-backward myRegex) |
文本编辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ; 删除光标后的九个字符 (delete-char 9) ; 删除选中的两点之前的文本 (delete-region mystartpos myendpos) ; 在当前光标位置插入一字符串 (insert "Forza Inter") ; 从buffer中获得一个字符串并赋给mystr (setq Mystr (buffer-substring mystartpos myendpos)) ; 改变字符大小写 ;这个例子是指当前光标之前的20个字符 (rapitalize-region (- (point) 20) (point)) |
字符串
1 2 3 4 5 6 7 8 | ; 长度 (length "abc") ; returns 3 ; 获取一个子串 (substring myStr startIndex endIndex) ; 替换,以正则方式 (replace-regexp-in-string myRegex myReplacement myStr) |
Buffers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ; 当前buffer的名字 (buffer-name) ; 文件名(全路径) (buffer-file-name) ; 设定一个buffer名 (set-buffer myBufferName) ; 保存 (save-buffer) ; 关闭指定的buffer (kill-buffer myBuffName) ; 关闭当前buffer (kill-this-buffer) ; 临时指定一个buffer作为当前buffer (with-current-buffer myBuffer ;; do something here ... ) |
Files
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 | ; 打开一个文件 (find-file myPath) ; 另存 ; 会关闭当前的buffer,打开另存好的文件 (write-file myPath) ; 把一个文件内容插入到当前位置 (insert-file-contents myPath) ; 将选中的评论文本加到某个文件后面 (append-to-file myStartPos myEndPos myPath) ; 重命名 (rename-file fileName newName) ; 复制 (copy-file oldName newName) ; 删除 (delete-file fileName) ; 获取路径 (file-name-directory myFullPath) ; 获取文件名(不含路径) (file-name-nondirectory myFullPath) ; 得到文件名后缀 (file-name-extension myFileName) ; 获得不含后缀的文件名。 (file-name-sans-extension "abc.htm") |
简单的例子
1 2 3 4 5 | (defun insert-p-tag () "Insert <p></p> at cursor point." (interactive) (insert "<p></p>") (backward-char 4)) |
在当前光标处插入一个p tag。做法是插放一个串,然后将光标移回4位。
编写一个mode
理论上来讲,知道上面这些东西,你就有能力编写一个mode了。但是,编写mode毕竟是一个复杂的工作,需要编写者对elisp编程具有”hello world”以上很多级的熟练度。
在李杀网,作者有一个系列文章来讨论如何为一个编程语言编写mode。
The End. Have fun!

GD Star Rating
loading...
标签:C/C++, cursor, Emacs, laihj, org, python, screenshot, 光标, 配色, 鼠标loading...
嘿,你也来写了!
[回复]
ahei 回复:
三月 6th, 2010 at 2:29 下午
@happybabe, 哈哈,原来大家都认识啊
[回复]
文本编辑,嘿,占个位置问个问题哈
我现在有一个函数,是用来copy当光标前所在位置的单词,现在我想把它用在”此处”,但却没能解决
Mark Set之后移动光标,会高亮显示经过的字符,此时使用alt+w可以copy高亮部分,以后进行黏贴
我想如果没有高亮显示的部分,那么alt+w就copy当前所在位置的单词,因为如果没有高亮显示的部分时
使用alt+w 复制的是之前的mark set等部分,如果光标不在原来的位置,使用此操作会感觉莫名奇妙,特别是使用ctrl+w时(ctrl+w和alt+w类似)
所以想设置为一个自定义函数,但现在就是判断不好,我是想根据mark等标记对比当前point等等,但是没能实现,有什么好的建议吗,我对elisp了解还太少了 : )
[回复]
ahei 回复:
五月 29th, 2011 at 12:49 下午
@klt, …..好绕
[回复]
请问如何读取一个文件中的内容保存到字符串
我想要写的代码如下.就只知道这些方法.望多指教.
(message (concat
“curl -d \”title=”
(concat (file-name-sans-extension b) “&”)
(concat “content=” (insert-file-1 (concat “cat ~/org/html/” (concat (file-name-sans-extension b) “.html&”)) ))
“YN=1&”
(concat “tabs=” tabs “\”")
” http://0.0.0.0:3000/addblog”
))
[回复]