在编辑clojure代码时,Emacs关闭了paren跳到已经存在的close-paren

时间:2012-03-10 13:02:47

标签: emacs clojure lisp

如果在emacs缓冲区中有这段代码:

(if (> x 5
    true
    false))

当我尝试编辑它以修复括号时,会发生一些非常烦人的事情!当我尝试在if条件中添加一个右括号时,emacs使光标跳转到'false'后的右括号,而不是在5之后添加一个新的括号。

这是某种模式的一部分,也许是clojure模式?你知道我怎么解决这个问题?这对什么有用?

3 个答案:

答案 0 :(得分:4)

听起来你正在使用paredit。您是否像project page上推荐的那样安装了它?

关于它有什么好处?这对编辑列表很有用。但你必须买 进入整个系统,或你最终会感到困惑。查看wiki 页。

您的~/.emacs.el中是否有此部分?只需删除它。

;; (require 'paredit) if you didn't install via package.el
(defun turn-on-paredit () (paredit-mode 1))
(add-hook 'clojure-mode-hook 'turn-on-paredit)

答案 1 :(得分:2)

是的,paredit是“不同的”。它将始终确保您的括号平衡。请参阅http://www.emacswiki.org/emacs/PareditCheatsheet

对于您的代码,将光标放在第一个右括号下方,然后按C-left。重复练习,它将移动到您想要的位置。

剪切和粘贴(使用emacs术语中的kill& yank)也允许您手动拧紧平衡括号,因此在您习惯了它之前,它可能更容易使用。祝你好运!

答案 2 :(得分:1)

如何验证paredit是罪犯

您可以在Lisp缓冲区中键入C-h k )以查看)绑定的内容。如果它被绑定到paredit-close-round那么肯定是paredit是罪犯。

当你不知道是什么触发它时,如何禁用paredit

尝试auramo's answer in another thread

或者如果不起作用,请尝试:

(eval-after-load 'paredit
  '(defalias 'paredit-mode 'ignore))

如果您对Emacs中触发paredit-mode的内容感到好奇,请使用M-x debug-on-entry RET paredit-mode RET

学习与paredit一起生活

但我仍然必须鼓励你继续使用paredit。让我们继续使用paredit,让我们看看你提出的问题的解决方案。你问“你知道我怎么解决这个问题?”我只是假设你问如何修复表格。 Marius Kjeldahl为您提供了使用paredit-forward-barf-sexp的解决方案,现在一般情况下,如果您有一些Lisp代码,其中您看到某些parens位于错误的位置并且您想要修复它,您可以简单地暂时禁用paredit-mode缓冲区(通过键入M-x paredit-mode)然后修复代码,然后再次启用paredit-mode(再次键入M-x paredit-mode)。另一件需要考虑的事情是Emacs已撤消,因此如果您通过某个操作到达(if (> x 5 true false)),则可以撤消该操作并重新开始。如果您使用CUA模式,撤消将绑定到C-z

你仍然可能发现C-left,C-right的绑定很奇怪,所以你可能想要使用以下设置:

(eval-after-load 'paredit
  '(progn
     ;; paredit-forward-barf-sexp is usually bound to <C-left>, C-}.
     ;; here we unbind it from <C-left>
     ;; so that one can continue to use <C-left> for movement.
     (define-key paredit-mode-map (kbd "<C-left>") nil)

     ;; paredit-forward-slurp-sexp is usually bound to <C-right>, C-).
     ;; here we unbind it from <C-right>
     ;; so that one can continue to use <C-right> for movement.
     (define-key paredit-mode-map (kbd "<C-right>") nil)

     ;; paredit-backward-kill-word is bound to M-DEL but not to <C-backspace>.
     ;; here we bind it to <C-backspace> as well
     ;; because most people prefer <C-backspace> to M-DEL.
     (define-key paredit-mode-map (kbd "<C-backspace>") 'paredit-backward-kill-word)))

你问“这有什么用?”你可能会问两件事:

    1. 为什么paredit-close-round有用?
    1. 为什么paredit必须将paredit-close-round绑定到)才能将其绑定到更好的密钥?

考虑paredit-close-round的最佳方式是将其视为C-M-u的对应方式。在以下代码中将点移至|并尝试多次按C-M-u以查看发生的情况,然后再次将指针移至|并尝试按C-M-- C-M-u(即键入{ {1}}当Control和Alt打开时,几次看看会发生什么。

-u

(when t (when t (blah) (blah)) (when t (blah | blah) (blah)) (when t (blah) (blah))) 对于选择表达式很有用;要选择一个或多个封闭表单,请按C-M-u几次,然后按C-M-u几次。 C-M-SPC对于评估封闭表单很有用;您按C-M-- C-M-u几次,然后按C-M-- C-M-u以评估附件表格。

C-x C-e基本上执行paredit-close-round所做的事情。

为什么paredit将C-M-- C-M-u绑定到一个除了简单地插入一个紧密的paren之外的命令之外的命令是一件好事?因为您不应该自己插入右括号。无论何时插入打开的paren,都会自动插入关闭的paren。如果您想将)更改为(blah) (blah),只需选择两个等级表单,然后按((blah) (blah))