Created
December 5, 2013 16:48
-
-
Save kragen/7808958 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; This pretty much works. A couple of remaining quibbles: | |
;; | |
;; - it’s possible for the region to not include a single Python | |
;; expression, in which case the code transformation will be | |
;; invalid. | |
;; - it should error out if called interactively when | |
;; transient-mark-mode is active and the mark is inactive, but it | |
;; doesn’t, because I don't know how to do that. | |
;; - it would be nice to highlight the other occurrences of the | |
;; expression, if any, and provide a key (maybe the same key?) to | |
;; replace them too, since most commonly you extract a local | |
;; variable when the same expression occurs more than once. Maybe | |
;; using overlays? How does highlight-regexp from hi-lock work? | |
;; - Inside a lambda or other binding construct (like a genex), it can | |
;; make invalid transformations. | |
(defun py-extract-variable (start end) | |
"Simple extract-variable refactoring for Python. | |
The idea is that you set the region to the expression to | |
extract (probably with \\[mark-sexp], whose more usual convenient | |
keybinding is C-M-SPC) and put the variable name before it. So | |
to turn something into a variable \"foo\", you go before it, type | |
\"foo\", \\[mark-sexp] a few times, and then | |
\\[py-extract-variable]. | |
" | |
(interactive "r") | |
(save-excursion | |
(let ((expression (buffer-substring start end))) | |
(delete-region start end) | |
(goto-char start) | |
(delete-horizontal-space) ; in case there was whitespace | |
(let ((variable-end (point))) | |
(backward-sexp) ; find the beginning of the variable | |
(let ((variable (buffer-substring (point) variable-end))) | |
(python-previous-statement 0) | |
;; I can’t get (indent-region) and (indent-for-tab-command) | |
;; to work properly, so I’ll just brute-force inserting the | |
;; same indent. | |
(let ((end-of-indent (point))) | |
(move-beginning-of-line 1) | |
(let ((indent (buffer-substring (point) end-of-indent))) | |
(open-line 1) | |
(insert indent) | |
(insert variable) | |
(insert " = ") | |
(insert expression)))))))) | |
(require 'python) | |
(define-key python-mode-map [f6] 'py-extract-variable) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment