网站 公司形象建站工作室源码
elisp 从简单实例开始.
我们怎样用elisp 与电脑交互,先从简单实例开始, 逐渐掌握它的几个对象.
 与电脑交互,总要有输入,输出,先看两个简单例子. 输入从minibuffer,输出可以是minibuffer 或者缓冲区.
 一: 从minibuffer 中输入, 在指定缓冲中插入文字(insert)x
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; 函数1:
 ;; 定义一个函数 greet_you_from_me.
 ;; 其输入参数是me, coder的名字,从函数调用传人(熟悉一下interactive调用参数)
 ;; 从minibuffer 中读入你的名字
 ;; 打开一个buffer 叫 *test*
 ;; 在buffer中显示字符串, 字符串为: 你好,xxx, 我是yyy.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (defun greet_you_from_me (me)
   (interactive "sme's name:") ; interactive 的调用参数是s,C-h f 查找其它说明
 (let ((your-name (read-from-minibuffer "Enter your name: "))); let 语句块,从minibuffer读字符串,付给变量your-name
 (switch-to-buffer-other-window "*test*"); 开启新缓冲,新窗口
 (erase-buffer); 清缓冲区
 (insert (format "Hello %s!\n\nI am %s." your-name me)) ; 构建文字,插入文字
 (other-window 1))); 跳回原来的窗口
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; 函数2:
 ;; 编写一个函数,在当前缓冲中输入一行代码,例如:
 int pArray = malloc( 5 * sizeof(int))
 其中类型int 是可变的, pArray 是可变的, 5 是可变的,都要从minibuffer 输入
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun my_malloc()
   (interactive)
   (let ((name (read-string "name:"))
   (size (read-string "size:"));; 为简单期间全部使用string 类型
   (type (read-string "type:")))
     (switch-to-buffer-other-window "*test*")
     (erase-buffer)
     (insert (format "%s %s = malloc( %s * sizeof(%s));" type name size type))
     (other-window 1)))
 函数列表:
 (interactive)
 (insert)
 (format)
 (read-string)
 (read-from-minibuffer)
 (switch-to-buffer-other-window)
 (erase-buffer)
 (other-window)
 (defun)
 (let)
 二: 数学运算
 阶乘运算, 需要从minibuffer 输入一个正整数,计算其阶乘
 (defun factorial (num)
   (interactive "ninput a num:")
   (let ((total 1))
   (while (> num 0)
     (setq total (* total num))
     (setq num (- num 1)))
   (message "total is %d" total)))
 ;;函数列表
 (while)
 (>)
 (-)
 (message)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 三. 在文件中查找关键字 search-forward (向前查找)
 假定有一个文件,名称为"world.txt",如下:
 $cat world.txt
 **@#一个兔子洞#@********@#又
 一个兔子洞#@****************
 **** @# 这也是一个兔子洞 #@*
假想在这片土地上有很多兔子洞,其中@#是入口,#@是出口
 现在要写一个elisp 函数,
 找出所有关键字@#, #@的位置.
 代码如下:
 (defun test-search-forward ()
 (setq hole-entrance "@#")
 (setq hole-exit "#@")
 (progn
   (find-file "world.txt")
   (make-local-variable 'hole-entrance)
   (make-local-variable 'hole-exit)
   (goto-char (point-min))
   (let (@extrance @exit)
     (while (progn
              (setq @entrance (search-forward hole-entrance nil t))
              (setq @exit (search-forward hole-exit nil t)))
       (print (format "兔子洞 (%d %d)" @entrance @exit))))))
(test-search-forward)
 函数列表:
 (find-file)
 (make-local-variable)
 (goto-char)
 (search-forward)
 (format)
 (print)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 四. 使用list , mapcar 用法(参数为函数), 查找与替换,修改文本属性,正则查找
  
(defun hello (name)
             (insert (format "Hello %s!\n" name)))
(progn
 ;; 我们将一些名字存到列表中:
 (setq list-of-names '("张三" "李四" "王五"))
 ;; 用 `push'把名字添加到列表的开头:
 (push "赵六" list-of-names)
 (switch-to-buffer-other-window "*test*")
 (erase-buffer)
 ;; 我们来对`list-of-names'列表中的每一个元素都使用hello函数:
 (mapcar 'hello list-of-names)
;; 记得我们之前定义的 `hello' 函数吗? 这个函数接受一个参数,名字。
 ;; `mapcar' 调用 `hello', 并将`list-of-names'作为参数先后传给`hello'
 (other-window 1)
 )
;; 现在我们对显示的buffer中的内容进行一些更改:
 ;; 查找与替换功能
 (defun replace-hello-by-bonjour ()
     (switch-to-buffer-other-window "*test*")
     (goto-char (point-min))
 ;;    (while (search-forward "Hello")
     (while (search-forward "Hello" nil t)      
       (replace-match "Bonjour"))
     (other-window 1))
;; (goto-char (point-min)) 将光标移到buffer的开始
 ;; (search-forward "Hello") 查找字符串"Hello"
 ;; (while x y) 当x返回某个值时执行y这个s式
 ;; 当x返回`nil' (空), 退出循环
(replace-hello-by-bonjour)
;; 你会看到所有在*test* buffer中出现的"Hello"字样都被换成了"Bonjour"
 ;; 你也会得到以下错误提示: "Search failed: Hello".
 ;; 如果要避免这个错误, 你需要告诉 `search-forward' 这个命令是否在
 ;; buffer的某个地方停止查找, 并且在什么都没找到时是否应该不给出错误提示
 ;; (search-forward "Hello" nil t) 可以达到这个要求:
 ;; `nil' 参数的意思是 : 查找并不限于某个范围内
 ;; `t' 参数的意思是: 当什么都没找到时,不给出错误提示
 ;; 在下面的函数中,我们用到了s式,并且不给出任何错误提示:
;; 给这些名字上个色:
 (defun boldify-names ()
     (switch-to-buffer-other-window "*test*")
     (goto-char (point-min))
     (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
       (add-text-properties (match-beginning 1)
                            (match-end 1)
                            (list 'face 'bold)))
     (other-window 1))
(boldify-names)
;; 这个函数使用了 `re-search-forward': 正则表达式查找
 ;; 和查找一个字符串不同,你用这个命令可以查找一个模式,即正则表达式
 ;; 正则表达式 "Bonjour \\(.+\\)!" 的意思是:
 ;; 字符串 "Bonjour ", 之后跟着
 ;; 一组           |  \\( ... \\) 结构
 ;; 任意字符       |  . 的含义
 ;; 有可能重复的   |  + 的含义
 ;; 之后跟着 "!" 这个字符串
 ;; `add-text-properties' 可以添加文字属性, 比如文字样式
 ;; 好的,我们成功了!
 函数列表
 (mapcar)
 (goto-char)
 (search-forward)
 (re-search-forward)
 (add-text-properties)
 (match-beginning)
 (match-end)
