关闭所有待处理的括号


14

在编写Lisp代码时,有时我会陷入一个嵌套的表达式中,而我想要的只是插入所有缺少的右括号。现在,我只是插入它们,直到获得不匹配的paren,但这并不是很有效。
是否有任何命令可以插入所有缺少的括号?

仅供参考,我正在使用smartparens自动插入匹配的paren。不过,有时候我只需要这样做。


2
FWIW,Franz Lisp(在CL之前)具有一个功能,可以]充当超级右父母,并根据您的要求关闭所有开放的父母。
2014年

2
我过去使用相同的方法。从那时起,我开始使用paredit,它可以在问题开始之前就将其停止。唯一需要注意的是,粘贴代码不会得到相同的平衡处理。
elarson

Answers:


6

这是一个用于关闭所有未闭合括号和其他匹配对的函数。它依赖于Emacs的sexp解析。它仅支持单字符匹配对,因此{-将使用}而不关闭-}。对于Lisp,这无关紧要。

(defun close-all-parentheses ()
  (interactive "*")
  (let ((closing nil))
    (save-excursion
      (while (condition-case nil
         (progn
           (backward-up-list)
           (let ((syntax (syntax-after (point))))
             (case (car syntax)
               ((4) (setq closing (cons (cdr syntax) closing)))
               ((7 8) (setq closing (cons (char-after (point)) closing)))))
           t)
           ((scan-error) nil))))
    (apply #'insert (nreverse closing))))

IIUC,这要求该点不能位于任何匹配的括号内。我给人的印象是,OQ需要从一个Lisp表达式中的某些地方开始工作,在这里,完成的括号将不匹配,而其他括号则不会。
马拉巴巴

@Malabarba这将关闭所有先前打开的括号,无论它们在点之后是否已经具有匹配的关闭括号。这就是我对问题的理解,但是目前还不清楚。根据您的解释,将在何处插入结束定界符?例如([-!-foo],您是])在点插入还是)在后面插入foo]
吉尔斯(Gillles)“所以-别再作恶了”

从我的理解,如果有([-!-foo],我会插入)之后foo]。但是我当然是错的。也许@rlazo可以详细说明。
马拉巴巴

对于我的用例,@ Gilles是正确的,我不在乎定点后是否关闭定界符,我想在定点之前关闭所有内容。
拉佐2014年

3

我发现,如果您安装了史莱姆,有一个命令可以做到这一点,称为 slime-close-all-parens-in-sexp


嗯...所以这似乎在当前行上关闭了。如果有一种方法可以关闭“当前块”,那可能会很好。这可以通过以下方式实现:转到文件末尾,然后向后移动sexp,直到找不到未关闭的内容。
Att Righ

1

一个非常原始的(几乎肯定是错误的)方法是

(defun buffer-needs-parens-fixing ()
  (save-excursion
    (condition-case nil
        (check-parens)
      (error (point)))))

(defun buffer-fix-parens ()
  (interactive)
  (while (buffer-needs-parens-fixing)
    (insert ")")))

除其他限制外,它假定所有需要插入的括号为:

  • 结束者
  • 当前位置需要

我想这可能仅对您的特定用例有用


如果括号太多,则会陷入无限循环。
EmilVikström2014年

@EmilVikström是的,这确实与我第一次声明的限制不兼容:)
Sigma
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.