【发布时间】:2014-02-15 17:08:03
【问题描述】:
我正在尝试从 python.el(当前的官方 gnu one)为 Boo 派生一个新的 emacs 模式,但我在更改缩进时遇到了麻烦。有人对如何最好地处理这个问题有任何建议吗?我不需要彻底改变任何东西,只需添加一些新的块形式和东西。
例如,由于这是针对 Boo,try/except 语法使用“ensure”而不是“finally”。我可以通过更改 python-rx-constituents 的 block-start def 在 python.el 中轻松更改这一点。但是,我似乎无法在派生模式下覆盖它,因为 python-rx-constituents 正在被宏 python-rx 使用,我猜一旦在 python.el 加载时定义了这两个东西(因为它必须,因为我是从它派生的),我不能再在加载后或在钩子中覆盖它?因为我肯定在 python.el 加载后的内存和钩子中以及在加载后的语句中更改了它,但它们都不起作用。虽然直接改变 python.el 工作正常。
这是来自 python.el 的代码:
(eval-when-compile
(defconst python-rx-constituents
`((block-start . ,(rx symbol-start
(or "def" "class" "if" "elif" "else" "try"
"except" "finally" "for" "while" "with"
)
symbol-end))
(decorator . ,(rx line-start (* space) ?@ (any letter ?_)
(* (any word ?_))))
(defun . ,(rx symbol-start (or "def" "class") symbol-end))
(if-name-main . ,(rx line-start "if" (+ space) "__name__"
(+ space) "==" (+ space)
(any ?' ?\") "__main__" (any ?' ?\")
(* space) ?:))
(symbol-name . ,(rx (any letter ?_) (* (any word ?_))))
(open-paren . ,(rx (or "{" "[" "(")))
(close-paren . ,(rx (or "}" "]" ")")))
(simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%)))
;; FIXME: rx should support (not simple-operator).
(not-simple-operator . ,(rx
(not
(any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%))))
;; FIXME: Use regexp-opt.
(operator . ,(rx (or "+" "-" "/" "&" "^" "~" "|" "*" "<" ">"
"=" "%" "**" "//" "<<" ">>" "<=" "!="
"==" ">=" "is" "not")))
;; FIXME: Use regexp-opt.
(assignment-operator . ,(rx (or "=" "+=" "-=" "*=" "/=" "//=" "%=" "**="
">>=" "<<=" "&=" "^=" "|=")))
(string-delimiter . ,(rx (and
;; Match even number of backslashes.
(or (not (any ?\\ ?\' ?\")) point
;; Quotes might be preceded by a escaped quote.
(and (or (not (any ?\\)) point) ?\\
(* ?\\ ?\\) (any ?\' ?\")))
(* ?\\ ?\\)
;; Match single or triple quotes of any kind.
(group (or "\"" "\"\"\"" "'" "'''"))))))
"Additional Python specific sexps for `python-rx'")
(defmacro python-rx (&rest regexps)
"Python mode specialized rx macro.
This variant of `rx' supports common python named REGEXPS."
(let ((rx-constituents (append python-rx-constituents rx-constituents)))
(cond ((null regexps)
(error "No regexp"))
((cdr regexps)
(rx-to-string `(and ,@regexps) t))
(t
(rx-to-string (car regexps) t))))))
我想更改 python-rx-constituents 以便 block-start 包含“ensure”而不是 finally。
【问题讨论】:
-
派生模式似乎不适合这里。为什么不直接复制文件,存储为 boo.el,将前缀替换为“boo-”,重新加载并编辑需要更改的内容?
-
这实际上正是我在第一次尝试时所做的,Andreas,它运行良好。但是,我想“清理它”以便我可以发布它的源代码,并且我认为从现有模式派生将是版权和归属等更好的方式。现在我只是很困惑为什么当我覆盖变量和宏时似乎什么都没有发生。值已更改,但没有明显效果。
-
实际的问题是在编译
python.el的过程中,正则表达式是由python-rx-macro生成的,然后直接作为字符串合并到源代码中。实际缩进在python-indent-calculate-indentation中计算。在python-indent-context中检测到状态after-beginning-of-block,您可以在函数定义中直接调用(python-rx block-start)。python-rx-constituents的变量定义也封装在eval-when-compile中。 -
托拜厄斯,谢谢!如果我不编译代码而是使用它解释怎么办?我认为
eval-when-compile将转换为progn,然后可以稍后覆盖宏,这样当调用python-indent-context时,它将使用新的python-rx宏。我想我对何时评估宏感到困惑。 -
你是对的。
progn解释。也适用于load-library。
标签: python emacs elisp boo python.el