Emacs:在派生模式下更改python.el缩进

Emacs:在派生模式下更改python.el缩进,python,emacs,elisp,boo,python.el,Python,Emacs,Elisp,Boo,Python.el,我正试图从python.el(当前官方的gnu模式)中为Boo派生一个新的emacs模式,但在修改缩进时遇到了麻烦。有人对如何最好地处理这个问题有什么建议吗?我不需要彻底改变任何东西,只需要添加一些新的块形式和东西 例如,由于这是针对Boo的,try/except语法使用“sure”而不是“finally”。在python.el中,通过更改python的block start def,我可以很容易地更改这一点。然而,我似乎无法在派生模式中重写它,因为python rx组件随后被宏python r

我正试图从python.el(当前官方的gnu模式)中为Boo派生一个新的emacs模式,但在修改缩进时遇到了麻烦。有人对如何最好地处理这个问题有什么建议吗?我不需要彻底改变任何东西,只需要添加一些新的块形式和东西

例如,由于这是针对Boo的,try/except语法使用“sure”而不是“finally”。在python.el中,通过更改python的block start def,我可以很容易地更改这一点。然而,我似乎无法在派生模式中重写它,因为python rx组件随后被宏python rx使用,我猜一旦在python.el加载时定义了这两个东西(因为它必须,因为我是从它派生的),我就不能在加载后或在钩子中重写它了?因为我已经在python.el加载后的内存和钩子中以及在after-load语句中对其进行了更改,但它们都不起作用。而直接修改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))))))
(编译时求值)
(defconst)
`((块启动),(接收符号启动
(或“def”“class”“if”“elif”“else”“try”
除了“最终”之外,为“而”为“带”
)
符号结束)
(装饰器),(rx行开始(*空格)@(任何字母?)
(*(任何单词?))
(定义),(接收符号开始(或“定义”类)符号结束)
(如果名称为main.,(接收行开始“如果”(+空格)”\uuuuu名称
(+空格)“==”(+空格)
(任何?“?\”)“\uuuu main\uuuuuuu”(任何?“?\”)
(*空格)?:))
(符号名称),(rx(任何字母?)(*(任何单词?))
(未结项)(rx(或“{”[”(”))
(收盘价),(rx(或“}”]“”)
(简单运算符.,(rx(任意?+?-?/?&?^?~?|?*?<?>?=?%))
;FIXME:rx应该支持(而不是简单的操作员)。
(不是简单的操作员,,(rx
(不是
(任何?+?-?/?&^?~?|?*?<?>?=?%))
;FIXME:使用regexp opt。
(运算符.,(rx(或“+”-“/”&“^”~“|”*”)
“=”“%”“**/”“=”“不是”))
;FIXME:使用regexp opt。
(赋值运算符.,(rx(或“=”+=”-=“*=”/=”/=“%=”***=”)

“>>=”如前所述,在这里使用派生模式不合适:您不能反向更改宏。也不建议重新定义宏:加载/求值的顺序将决定哪一个有效-在更大的范围内,这意味着陷入混乱

复制文件,存储为boo.el,将前缀替换为“boo-”,重新加载并编辑需要更改的内容


您在IMO上表达的担忧是没有道理的,因为允许复制、更改和重新发布更改后的代码是GPL的核心。

复制文件确实是个坏主意,因为它会让跟踪python.el的发展变得很痛苦。 派生也不是一个好主意,因为Boo实际上不是Python的扩展或变体,所以您可能希望重用它的一些缩进机制和代码来理解重要的缩进,但仅此而已


您可能希望联系python.el的作者(使用Cc-to-emacs-devel)查看python.el是否可以调整以使您的生活更轻松。例如,可能将公共代码提取到一个辅助文件中,以便在两者之间共享。理想情况下,此文件可以用于脚本模式,也可以用于Haskell模式。

派生模式似乎不适合此处。为什么不直接复制该文件,存储为boo.el,替换前缀为“boo-”,重新加载并编辑需要更改的内容?安德烈亚斯,这正是我第一次尝试时所做的,效果很好。不过,我想“清理它”"因此,我可以发布它的源代码,我认为从现有模式派生将是更好的版权和属性等方式。现在我只是不明白为什么当我重写变量和宏时,似乎什么都没有发生。值发生了变化,但没有明显的效果。实际问题是在com
python.el
正则表达式由
python rx
-宏生成,然后直接作为字符串合并到源代码中。实际缩进在
python indent calculate indentation
中计算。在
python indent con>中检测块开始后的状态
文本
,在那里可以直接调用宏
(python rx块启动)
在函数定义中。
python rx compile
的变量定义也被封装在
eval when compile
中。Tobias,谢谢!如果我不编译代码而是使用解释代码呢?我想
eval when compile
将转换为
progn
,然后宏可以被重写den,以便在调用
python缩进上下文时,它将使用新的
python rx
宏。我想我对宏的求值时间感到困惑。你是对的。
progn
在解释时。也适用于
加载库