Pinvon's Blog

所见, 所闻, 所思, 所想

Elisp学习笔记

Elisp基础

程序的执行方法

  • 写完代码后, 将光标停在右括号后面, 键入 C-x C-e.
  • *scratch* 里写完代码后, 将光标停在右括号后面, 键入 C-j.

打印

(message "hi")
(message "Her age is: %d" 16)

算术表达式

Elisp使用前缀表达式.

(/ 7 2.0)  =>  3.5

判断数据类型, 在函数名后加个字母p. 如:

(integerp 3.)  =>  t
(floatp 3.)  =>  nil

数字与字符串转换:

(string-to-number "3")
(number-to-string 3)

布尔

nil和空括号()为False, 其余都是t(也就是True).

布尔函数

(and t nil)
(or t nil)
(< 3 4)
(= 3 3.000000000000000000001)  => t

注意, 不等于使用符号/=.

如果比较两个数据(包括字符串)是否相同, 一般使用 equal, 因为它会同时比较值和类型.

变量

全局变量

(setq x 1)

局部变量

(let (a b)
  (setq a 3)
  (setq b 4)
  (+ a b))  =>  7

也可以写成以下形式:

(let ((a 3) (b 4))
  (+ a b))  =>  7

使用两个双括号, 可以省去写setq.

程序控制

if-else

(if test body) (if test true_body false_body)

(if (< 3 2) 7 8)  =>  8

loop

(while test body)

(setq x 0)
(while (< x 4)
  (print (format "number is %d" x))
  (setq x (1+ x)))

语句块

(progn (body1) (body2) ...)

progn可以把多个表达式包含在一个语句块里, 类似于C的{...}.

函数

(defun myFun ()
    "test"
    (message "Yay!"))

命令

(defun myCom ()
    "test command"
    (interactive)
    (insert "Yay!"))

Elisp文本操作

光标位置

(point)  ;;  返回当前光标的位置, 从1开始.

(region-beginning)
(region-end)

(line-beginning-position)  ;;  当前行的开始位置
(line-end-position)

(point-min)  ;;  buffer的开始位置
(point-max)

移动光标

(goto-char 39)  ;;  跳到第39个位置

(forward-char 4)  ;;  前进4个位置
(backward-char 4)

(search-forward "some")  ;;  如果该代码后面有some这个单词, 则返回some结束后的位置
(search-backward "some")  ;;  如果该代码后面有some这个单词, 则返回some开始时的位置

(re-search-forward "[0-9]")  ;;  正则表达式查找
(re-search-backward "[0-9]")

(skip-chars-forward "a-z")  ;;  不查找a-z之间的字符
(skip-chars-backward "a-z")

删除、插入、修改文本

(delete-char 9)
(delete-region 3 10)
(insert "i love cates")
(setq x (buffer-substring 71 300))  ;;  获取从71-300之间的字符
(capitalize-region 70-300)  ;;  将指定区域的首字母大写

String

(length "abc")  ;;  返回字符串长度
(substring "abcdefg" 3 4)  ;;  截取字符串
(replace-regexp-in-string "[0-9]" "X" "abc123")  ;;  将第3个参数中, 符合第1个参数情况的, 替换成第2个参数

Buffer

(buffer-name)  ;;  返回当前buffer名称
(buffer-file-name)  ;;  返回当前文件的完整路径
(set-buffer "xyz")  ;;  如果有xyz这个buffer, 则跳转到该buffer
(save-buffer)
(kill-buffer "xyz")

File

(find-file "~/")  ;;  打开指定文件
(write-file path)  ;;  相当于save as
(insert-file-contents path)  ;;  插入path指定文件到当前光标位置
(append-to-file start-pos end-pos path)  ;;  将[start-pos, end-pos]指定的文本块插入path指定的文件中
(rename-file file-name new-name)
(copy-file old-name new-name)
(delete-file file-name)
(file-name-directory full-path)
(file-name-nondirectory full-path)
(file-name-extension "personal-conclude.org")  ;;  获取文件名的后缀(.org)
(file-name-sans-extension "personal-conclude.org")  ;;  获取文件名的前缀(.org前面的名字)

例子

插入文本

(defun insert-p-tag ()
  "Insert <p></p> at cursor point."
  (interactive)
  (insert "<p></p>")
  (backward-char 4))

该代码插入<p></p>, 然后将光标放在中间.

在指定区域插入文本

(defun wrap-makup-region (start end)
  "Insert a markup <b></b> around a region."
  (interactive "r")
  (save-excursion
    (goto-char end) (insert "</b>")
    (goto-char start) (insert "<b>")))

选中指定区域

选中当前单词:

(transient-mark-mode 1)
(defun select-current-word ()
  "Select the word under cursor. ``word`` here is considered any alphanumeric sequence with ``_`` or ``-``."
  (interactive)
  (let (pt)
    (skip-chars-backward "-_A-Za-z0-9")
    (setq pt (point))
    (skip-chars-forward "-_A-Za-z0-9")
    (set-mark pt)))

选中当前行:

(transient-mark-mode 1)
(defun select-current-line ()
  "Select the current line"
  (interactive)
  (end-of-line)  ;;  move to end of line
  (set-mark (line-beginning-position)))

替换区域内的文字

(defun replace-greek-region (start end)
  "Replace specific words to other words in current region."
  (interactive "r")
  (save-restriction
    (narrow-to-region start end)
    (goto-char (point-min))
    (while (search-forward "hello" nil t) (replace-match "hi" nil t))
    (goto-char (point-min))))

Comments

使用 Disqus 评论
comments powered by Disqus