分页: 1 / 1

Emacs括号自动补全

发表于 : 2012-02-14 14:00
老蒋
输入'('可以自动补全')',并且将光标放置到括号中间。支持多种符号匹配。理论可以匹配任意字符。
通过内置的skeleton.el来实现。

原理是编辑skeleton-pair-alist,把想要配对的符号列进去。
再使用skeleton-pair-insert-maybe函数进行相应的匹配。

[lisp]
;; 填入大中小括号,双单引号的匹配
;; 详细格式可以参照C-h f skeleton-pair-alist
(setq skeleton-pair-alist
'((?\" _ "\"" >)
(?\' _ "\'" >)
(?\( _ ")" >)
(?\[ _ "]" >)
(?\{ _ "}" >)))

(setq skeleton-pair t)

;; 绑定全局键值
;; 也可以绑定单独到某个mode,比如cc-mode (define-key cc-mode-map (kbd "(") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "(") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "{") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "\'") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "\"") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "[") 'skeleton-pair-insert-maybe)
[/lisp]

Re: Emacs括号自动补全

发表于 : 2012-02-18 10:41
xep007
很好!网上许多.emacs配置都是抄来抄去的。我开始也我照抄了一段,可是无法自动补全',后来摸索才发现是少了个\.

Re: Emacs括号自动补全

发表于 : 2012-02-24 22:24
reverland
虽然很喜欢lisp,可惜连lisp都是用vim

Re: Emacs括号自动补全

发表于 : 2013-01-08 22:14
fenghelong
怎么没有skeleton-pair-alist 这个函数

Re: Emacs括号自动补全

发表于 : 2013-01-12 9:31
jobinson99
我是用的emacs24内建的electric-pair-mode:

代码: 全选

;;系统本身内置的智能自动补全括号
(electric-pair-mode t)
那个electric很好用

代码: 全选

;;使用易码肆24内嵌的功能:
(require 'electric)
;;编辑时智能缩进,类似于C-j的效果——这个C-j中,zencoding和electric-pair-mode冲突
(electric-indent-mode t)
;;系统本身内置的智能自动补全括号
(electric-pair-mode t)
;;特定条件下插入新行
;(electric-layout-mode t)

Re: Emacs括号自动补全

发表于 : 2013-01-14 22:34
kardinal
[lisp]
(defvar skeleton-pair-cond-alist)
(setq skeleton-pair-cond-alist
'(
;; 前面有 = ,花括号不换行
((char-bf ?=) . (?\{ _ "}"))
((or (char-bf ?/)(char-bf ?=)) . (?\[ n _ n "]"))
;; 行首是/ ,扩展为块注释
((bolp) . (?/ "*" n _ n "*/"))
(t . (?/))
;; 前面是 = , .变为->
((char-bf ?=) . (?. -1 "->"))
(t . (?.))
))

(defadvice skeleton-pair-insert-maybe (around xxx activate)
(let ((skeleton-pair-alist skeleton-pair-alist)
(x skeleton-pair-cond-alist))
(while
(and
x
(null
(if (and
(eq last-command-event (cadr (car x)))
(eval (caar x)))
(setq skeleton-pair-alist (list (cdar x)))
nil)))
(setq x (cdr x)))
ad-do-it))
(defun char-bf (x)
(let ((x (if (listp x) x (list x))))
(save-excursion
(skip-chars-backward " \t")
(memq (char-before (point)) x))))

;;;###autoload
(defun skeleton-pair-alist-update ()
(interactive)
(mapcar
(lambda(x)
(define-key (current-local-map)
(eval `(kbd ,(char-to-string (cadr x))))
'skeleton-pair-insert-maybe))
skeleton-pair-cond-alist))
;; (skeleton-pair-alist-update)
[/lisp]
这段代码的不同之处在于,你只要维护 skeleton-pair-cond-alist,而不需要自己去绑定里面的按键,执行(skeleton-pair-alist-update)后会自动在列表中找到相应的按键进行绑定
skeleton-pair-cond-alist中像cond一样,可以设置条件来决定是否补全,如何补全及补全规则的优先级