Customize lisp program

来源:互联网 发布:java soap 框架 编辑:程序博客网 时间:2024/06/08 07:05

Defining Functions

keep track of the number of words in a paper or story you are writing. Emacs has no built-in way of counting the number of words in a buffer, so we'll write a Lisp function that does the job,也就是现在我们想自定义一个函数能够实现计算当前buffer里面的单词个数

(defun count-words-buffer ( )   (let ((count 0))     (save-excursion       (goto-char (point-min))       (while (< (point) (point-max))         (forward-word 1) (setq count (1+ count)))       (message "buffer contains %d words." count))))    Ctrl+jcount-words-buffer(count-words-buffer)                                                         Ctrl+j "buffer contains 82 words."
对于上面的内置函数都可以通过C-h f来查看

(save-excursion &rest BODY) The values of point, mark and the current buffer are restored even in case of abnormal exit (throw or error). 看得不是太明白

(goto-char Position) :Set point to POSITION, a number or marker. Beginning of buffer is position (point-min), end is (point-max).


Turning Lisp Functions into Emacs Commands

这个的想法就是使我们的函数也能够通过M-x 方式来调用。现在如果仅仅上面的方式定义完以后,你输入M-x count-words-buffer Enter,你会得到一个错误信息说[No match],You get this error message because you need to "register" a function with Emacs to make it available for interactive use.也就是现在你还没有对它进行登记,别人都不知道,那还怎么进行交互。这个时候就需要interactive函数来实现,它的格式:(interactive "prompt-string")


Interactive statement should be the first in a function, that is, right after the line containing the defun and the documentation string (which we will cover shortly). Using interactive causes Emacs to register the function as a command and to prompt the user for the arguments declared in the defun statement. The prompt string is optional.Interactive 语句必须放在函数定义最开始的位置,位于defun和documentation的后面,通过interactive语句我们可以使它成为一个命令,并且提示用户传进来在defun中声明的参数。这个提示语句是可选择性的。


The prompt string has a special format: for each argument you want to prompt the user for, you provide a section of prompt string. The sections are separated by newlines (\n). The first letter of each section is a code for the type of argument you want. There are many choices; 提示串具有一定的格式,每一个参数你都需要提供一段提示信息,两个提示参数的语句之间用\n隔开。每一个提示段的第一个字母都对应一定的形式。每一个提示段,除了第一个字母外都是会展现到minibuffer里面。第一个字母功能具体如下面所示:


下面对interactive的一段测试

(defun replace-string (from to)  (interactive "sReplace string: \nsReplace string %s with: "))
第一次提示"Replace string:" 假设你输入first的话,当你输入enter以后它会提示 "Replace stringfirst with: "然后再等待你输入,等你输入完以后敲入enter,也就完成了对from to两个参数的赋值。
这里面要注意的就是第一个s输入的值给from,当碰见\n的话,它会在前面的输入完成以后再显示,第二个s接受输入的值给to,而其中%s 是前面接受的显示形式,你如果前面接受了3个的话,你只写两个%s.它只会提示前两个。


Final Version

因为这个函数不需要参数,所以interactive中就不要提示信息段了,并且我们知道它的它有两个功能,另一个就是可以让系统知道当我们输入M-x count-words-buffer能够认识。document的作用是 shown by online help facilities such as describe-function (C-h f).

(defun count-words-buffer ( )  "Count the number of words in the current buffer; print a message in the minibuffer with the result."  (interactive)  (save-excursion    (let ((count 0))      (goto-char (point-min))      (while (< (point) (point-max))        (forward-word 1)        (setq count (1+ count)))      (message "buffer contains %d words." count))))

设置函数goto-percent that allows you to go to a place in the current buffer expressed as a percentage of the text in the buffer.
(defun goto-percent (pct)  (interactive "nPercent: ")  (goto-char (/ (* pct (point-max)) 100)))




原创粉丝点击