如何在Emacs中自定义LISP宏子表达式的缩进规则?
为自定义Emacs宏
regex-case设置自定义缩进规则 要让你的regex-case宏实现预期的缩进效果,核心是给宏绑定自定义缩进函数,通过判断代码结构来控制缩进量,具体步骤如下:
1. 定义自定义缩进函数
编写一个函数来识别regex-case内部的代码结构,计算正确的缩进值:
(defun regex-case-indent-function (indent-point state) (let ((normal-indent (current-column))) (goto-char (1+ (elt state 1))) (parse-partial-sexp (point) indent-point 0 t) (cond ;; 匹配case中的执行表达式:在正则字符串+变量列表之后的行,缩进一级 ((and (looking-at "\\s(") (not (looking-at "\\s(\"")) (eq (nth 0 state) 'string)) (+ normal-indent lisp-indent-offset)) ;; 匹配每个case的起始行(正则字符串所在行),缩进一级 ((eq (nth 0 state) 'list) (+ (current-indentation) lisp-indent-offset)) ;; 其他情况使用默认缩进 (t normal-indent))))
2. 将缩进函数绑定到宏
把上面的函数关联到regex-case宏的lisp-indent-function属性上:
(put 'regex-case 'lisp-indent-function 'regex-case-indent-function)
效果验证
设置完成后,你的regex-case代码就能按预期缩进:
(regex-case "some-string" ("name +([a-z]+) +(.+)" (arg1 arg2) (format t "~A / ~A~%" arg1 arg2)) ("A*" () (format t "all A~%")))
补充说明
- 这个自定义缩进函数的逻辑是:识别case块中,正则字符串和变量列表之后的执行表达式行,让它相对于case起始行缩进一级;同时保证每个case的起始行相对于宏本身缩进一级。
- 你提到的把正则和变量放入列表的次优方案确实能借助默认缩进规则实现类似效果,但自定义缩进函数可以保留你最初期望的语法结构,灵活性更高。
内容的提问来源于stack exchange,提问作者John Graham
相关产品推荐
相关产品推荐

