【问题标题】:Creating emacs mode: defining indentation创建emacs模式:定义缩进
【发布时间】:2014-05-24 06:19:48
【问题描述】:

我正在为类似 Lisp 的语言编写一个简单的模式,但在设置缩进时遇到了问题。我一直在关注emacswiki mode tutorial

但是,我不知道如何根据我的需要调整他们的示例缩进,因为他们不进行任何形式的计数。

基本上,每次看到{( 时,我只需要在缩进计数中添加 2 个空格,即使在同一行上有多个空格,当我看到上面的闭包时减去 2 个空格.我是 elisp 的新手;如何调整他们的示例来计算大括号和括号?

为方便起见,这里是他们使用的代码(对于非括号语言):

(defun wpdl-indent-line ()
  "Indent current line as WPDL code"
  (interactive)
  (beginning-of-line)
  (if (bobp)  ; Check for rule 1
      (indent-line-to 0)
    (let ((not-indented t) cur-indent)
      (if (looking-at "^[ \t]*END_") ; Check for rule 2
      (progn
        (save-excursion
          (forward-line -1)
          (setq cur-indent (- (current-indentation) default-tab-width)))
        (if (< cur-indent 0)
        (setq cur-indent 0)))
        (save-excursion 
          (while not-indented
            (forward-line -1)
            (if (looking-at "^[ \t]*END_") ; Check for rule 3
                (progn
                  (setq cur-indent (current-indentation))
                  (setq not-indented nil))
                    ; Check for rule 4
              (if (looking-at "^[ \t]*\\(PARTICIPANT\\|MODEL\\|APPLICATION\\|WORKFLOW\\|ACTIVITY\\|DATA\\|TOOL_LIST\\|TRANSITION\\)")
                  (progn
                    (setq cur-indent (+ (current-indentation) default-tab-width))
                    (setq not-indented nil))
                (if (bobp) ; Check for rule 5
                    (setq not-indented nil)))))))
      (if cur-indent
          (indent-line-to cur-indent)
        (indent-line-to 0))))) ; If we didn't see an indentation hint, then allow no indentation

我怎样才能实现类似 lisp 的缩进(也可以使用花括号)?

【问题讨论】:

  • 为什么不直接看lisp-indent-function的出处?
  • abo-abo,我找不到该函数的未编译定义。
  • 从源代码安装 emacs,然后您可以使用 describe-function 轻松找到定义。
  • 据我所知,lisp-indent-functionlisp-mode.el 中一系列复杂缩进函数的一部分,我不知道如何处理它们......
  • 你不必完全理解它就可以使用它。实际上,您可能无需修改即可使用它。

标签: emacs programming-languages lisp indentation mode


【解决方案1】:

如果你想要一些简单的 Lisp 风格的语言,我建议你从 (syntax-ppss) 开始,它会返回“解析状态”。该状态的第一个元素是当前的父嵌套深度。虽然我使用了“paren”这个词,但这并没有真正计算paren,而是计算语法表定义为类paren的那些字符,所以如果你设置你的语法表使得{和}被声明为类paren ,那么这些也会被计算在内。

所以你可以从类似的东西开始

(defun foo-indent-function ()
  (save-excursion
    (beginning-of-line)
    (indent-line-to (* 2 (car (syntax-ppss))))))

不要将其定义为交互式,因为使用它的方式是通过添加

(set (make-local-variable 'indent-line-function) #'foo-indent-function)

在您的主模式函数中。

但也许更好的选择是简单地做:

(require 'smie)
...
(define-derived-mode foo-mode "Foo"
  ...
  (smie-setup nil #'ignore)
  ...)

这将使用 4 的缩进步长(在 smie-indent-basic 中配置)。

【讨论】:

  • 这几乎是完美的!我使用前一个功能很棒。您会添加有关如何定义/扩展语法-ppss 的链接或简要说明吗?另外,我注意到我的右花括号仍然缩进在这里,当我希望它向左对齐时。有什么建议吗?
  • 扩展 syntax-ppss 并不是一个真正的选择。从这个意义上说,使用 SMIE 是更可取的,因为它意味着扩展。默认情况下,SMIE 还应为您处理“右大括号应为左对齐”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 2011-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
相关资源
最近更新 更多