回乡絮语
每年回家过年只有一个感觉,人去楼空,一年一年也习惯了。
回来几天,就是被不同的亲戚叫来叫去吃饭,作为有战斗力的人型饭桶。
每年回家最爱的一碗菜就是清蒸虾,只放一点点姜,在北京吃不到的美味,就是也很贵。
家乡完全要以用十室九空来形容,没有青壮年,有的只是妇孺,青壮年只都在美利坚。于是家乡被称为桥乡,华桥的桥。
我上大学的时候,回来过年,还能招呼着踢一两场球,现在怕是连羽毛球都招呼不起了。
我娘前几天还思路很清晰地跟我说:你其实不明白出国(务工)这件事害了多少人。我觉得我是知道的,就是知道得没有他们那一辈清楚。出国与去大城市当民工主要区别有二:赚钱更多,多好多倍,回家更少,少很多倍。我外婆过世只时只有大舅舅和两个姨妈在家,她老人家生了七个。
我娘跟我说,如果大家都不出国,她也不出国,都是出国的人多了,觉得自己的生活实在比不过人家。
小时候家里过年,是舞龙,显神和放鞭炮,现在是放鞭炮。小时候过中秋是烧塔,现在什么也没有。因为没有人了。
今年回家,发现福州三套推出一档叫攀讲的节目。攀讲在福州话中是聊天的意思。这个节目的主打就是完全使用福州话,前两天还用福州话给新龙门客栈配音。据说原因是现在能讲福州话的福州人越来越少了。早知如此,何必当初。
[elisp]用elisp编译解释当前的buffer
运行当前的buffer,就是说编译或解释当前的buferr。比如在编辑的是python文件”hello.py”,那么运行它的命令就是”python hello.py”,一般的python-mode用”C-c C-c”来处理这个问题,在编辑过程中可以调用这个快捷键来运行。当然你也可以使用”M-!”来打开shell command的mini buffer来输入命令。
诚然,很多语言的mode里面实际上都内置了这一功能,但我觉得,一方面不同的mode可能定义不同快捷键,造成了额外的记忆负担,另一方面并不能要求所有的mode都提供这一功能,在mode不完整的情况下你大概也需要自己定义的能力。
要做这事儿,当然是自定义一个函数。那么最直观的想法,就是在elisp里面写一行调用shell来执行命令的代码。是的,有这种东西,示例如下:
(shell-command "python hello.py")
这一行代码的相当于在终端中执行”python hello.py”。
我们的目的是执行当前buffer,所以下一步要做的是得到当前buffer所对应的文件名。在上一篇blog中介绍过相关方法,就是”buffer-file-name”。
于是代码就变成了这样。
(shell-command (concat "python " (buffer-file-name)))
用concat把”python “和当前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")
("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)));执行
完毕,为这个函数绑定一个键,在编辑相应文件的时候调用,就可以对其进行需要的操作了,不仅限于编译和解释,实际上很容易看出来,只要shell能支持的,你可以玩。当然,要有权限。
Have Fun!
[elisp]针对Emacs中文本编辑的编程简介

Elisp是Emacs下的Lisp方言,而Emacs是一款编辑器。那么针对于Emacs,Lisp要做的很重要一部分工作当然就是对编辑的自动化支持。比如移动鼠标,输入句子,查找替换,代码高亮等等,简单地说,就是为更好更方便地支持文本编辑提供支持。而把这些函数都重合起来,就起成了Emacs mode。如我们常用的C++ mode,python mode。还有之前我一直在介绍的org-mode等,都是由Elisp拼成的。
学习Elisp,可以满足对Emacs进行定制的需求,你可以把想要的功能写在.el文件里面,让Emacs来调用。一方面可以实现一些简单的轻量级的功能,而不需要为此寻找和安装一个完整的mode。另一方面,可以修改现有的mode,使得更符合自己的习惯。这符合开源的作法,不爽即改。
Elisp函数的简单例子
光标位置
;返回当前光标的位置 (point) ;region的头跟尾 (region-beginning) (region-end) ;最大光标位置(即文件尾),elisp还提供最小光标位置(point-min),不过我觉得那应该都是1吧。 (point-max) ;返回buffer结尾的绝对位置,无视narrow-to-region (buffer-end 1) |
移动光标和搜索
;移动光标到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) |
文本编辑
; 删除光标后的九个字符 (delete-char 9) ; 删除选中的两点之前的文本 (delete-region mystartpos myendpos) ; 在当前光标位置插入一字符串 (insert "Forza Inter") ; 从buffer中获得一个字符串并赋给mystr (setq Mystr (buffer-substring mystartpos myendpos)) ; 改变字符大小写 ;这个例子是指当前光标之前的20个字符 (rapitalize-region (- (point) 20) (point)) |
字符串
; 长度 (length "abc") ; returns 3 ; 获取一个子串 (substring myStr startIndex endIndex) ; 替换,以正则方式 (replace-regexp-in-string myRegex myReplacement myStr) |
Buffers
; 当前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
; 打开一个文件 (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") |
简单的例子
(defun insert-p-tag () "Insert at cursor point." (interactive) (insert " ") (backward-char 4)) |
在当前光标处插入一个p tag。做法是插放一个串,然后将光标移回4位。
编写一个mode
理论上来讲,知道上面这些东西,你就有能力编写一个mode了。但是,编写mode毕竟是一个复杂的工作,需要编写者对elisp编程具有”hello world”以上很多级的熟练度。
在李杀网,作者有一个系列文章来讨论如何为一个编程语言编写mode。
The End. Have fun!
页面
Categories
- 92383 (1)
- lonely planet (25)
- Uncategorized (1)
- 一些故事 (3)
- 利其器 (10)
- 善其事 (62)
- 小说翻译 (2)
- 负暄琐话 (74)
laihj


