I am attempting to derive a new emacs mode from python.el (the current official gnu one) for Boo and I am having trouble with altering the indentation. Does anyone have any suggestions about how to best handle this? I do not need to change anything drastically, just add some new block forms and stuff.
For example, since this is for Boo, the try/except syntax uses "ensure" instead of "finally". I can change this easily enough in python.el by changing the block-start def of python-rx-constituents. However, I can't seem to be able to override this in a derived mode because python-rx-constituents is being then used by a macro, python-rx, and I guess once those two things are defined when python.el loads (as it has to, since I am deriving from it), I can no longer override it after-load or in a hook? Because I've definitely changed it in memory and in a hook after python.el loads and in an after-load statement and none of them work. While directly altering python.el works fine.
Here is the code in question from 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))))))
I would like to change python-rx-constituents so that block-start includes "ensure" instead of finally.
As commented already, employing derived-mode is not suitable here: you can't back-change a macro. Also re-defining it isn't recommendable: the order of loading/evaluation than will decide which one is in effect - at a larger scale that means running into a mess.
Copy the file, store as boo.el, replace the prefix by "boo-", reload and edit the stuff which needs changing.
Your concern expressed IMO isn't justified, as permitting copying, changing and re-release of the changed code is the core of the GPL.