++Python - Emacs functions to expand shorthand
Preston Landers
mithy at my-deja.com
Tue Jul 6 17:20:23 EDT 1999
Hello Everyone,
I'm pleased to release a small set of Emacs functions I wrote to
assist lazy Pythoneers like myself.
It hooks into the standard python-mode and gives you two new commands;
py-shorthand-line-expand -- bound to C-z -- works only on the
current line.
py-shorthand-buffer-expand -- bound to C-c C-z -- works on the whole
buffer.
These keys expand shorthand expressions. A couple of examples:
foo += bar ---> foo = foo + bar
++foo.bar ---> foo.bar = foo.bar + 1
I know what you're thinking, and yes, I do have entirely too much free
time on my hands. I also think that maybe Python 2 should incorporate
this syntactic sugar, but until such time, I give you these Emacs
macros to ease your carpal tunnel syndrome. [1]
I've tested them with FSF Emacs 20.3.2 and Xemacs 20.4. Nothing has
exploded yet.
I do realize that C-z is normally bound to suspend-or-iconify, but I
personally never use that and C-z just seemed convenient. *Feel free*
to change the key bindings at the end of the lisp file that follows.
The "homepage" for this absurdity will soon be somewhere on
http://askpreston.com/projects/ though there's nothing there at the
moment.
Comments, criticisms, job offers, flames, and live nude girls to:
---Preston Landers <preston at askpreston.com>
[1] Naturally, Emacs itself is known to be a major factor in this
tragic affliction. Press Control-Meta-Hyper-Shift-H to learn more.
py-shorthand.el follows. Installation instructions contained therein.
---cut-here-------------------------------------------
;; py-shorthand.el --- version 1.0 -- July 5th, 1999
;;
;; Some functions to expand certain shorthand expressions into legal
;; Python for the terminally lazy.
;; For instance, 'foo += bar' is expanded to 'foo = foo + bar'
;;
;; Copyleft (C) 1999 Preston Landers <preston at askpreston.com>
;; Distributed under the GNU General Public License
;;
;; By default, expanding the current line is bound to C-z (which is
;; normally reserved for iconify / suspend, which I never use.) Feel
;; free to change it (it's at the bottom of this file.) Expanding
;; shorthand in the entire buffer is bound to C-c C-z which isn't
;; otherwise bound to anything in my Xemacs 20.4.
;;
;; To install, just make sure this file is in your lisp load path
;; somewhere, and put the following in your .emacs file:
;;
;; (load "py-shorthand")
;;
;; If you don't know what a lisp load path is, make a directory in your
;; home directory called lisp and copy this file to that directory, then
;; put this in your .emacs file instead:
;;
;; (setq load-path (append load-path (list "~/lisp")))
;; (load "py-shorthand")
;;
;; Known bugs: 'foo .= bar' is expanded to 'foo = foo . bar' but should
;; be 'foo = foo + bar'. Suggestions?
;;
;; An exact list of the types of shorthand expressions recognized
;; follows (with identifying regular expressions.)
;;
;; foo.bar +=
;; \\(\\s-*\\)\\([A-Za-z_0-9\\.\\-]+\\)\\(\\s-*\\)\\([-\\+\\.\\*\\\]\\)=
;; ...becomes...
;; foo.bar = foo.bar +
;; \\1\\2\\3=\\3\\2 \\4
;; ++foo.bar (or --foo.bar)
;; \\(\\s-*\\)\\(\\+\\|-\\)\\2\\([A-Za-z_\\-0-9\\.]+\\)
;; ...becomes...
;; foo.bar = foo.bar + 1
;; \\1\\3 = \\3 \\2 1
;; foo.bar++ (or foo.bar--)
;; \\(\\s-*\\)\\([A-Za-z_\\-0-9\\.]+\\)\\(\\+\\|-\\)\\3
;; ...becomes...
;; foo.bar = foo.bar + 1
;; \\1\\2 = \\2 \\3 1
(defvar py-shorthand-statement-regexp
"\\(\\s-*\\)\\([A-Za-z_0-9\\.-]+\\)\\(\\s-*\\)\\([-\\+\\.\\*\\\]\\)="
"Regexp for recognizing foo += bar (or -= *= \=).")
(defvar py-shorthand-statement-replace
"\\1\\2\\3=\\3\\2 \\4"
"Replacement string for foo += bar; becomes foo = foo + bar.")
(defvar py-shorthand-precrement-regexp
"\\(\\s-*\\)\\(\\+\\|-\\)\\2\\([A-Za-z_\\-0-9\\.]+\\)"
"Regexp for recognizing --foo or ++foo.")
(defvar py-shorthand-precrement-replace
"\\1\\3 = \\3 \\2 1"
"Replacement string for ++foo; becomes foo = foo + 1.")
(defvar py-shorthand-postcrement-regexp
"\\(\\s-*\\)\\([A-Za-z_\\-0-9\\.]+\\)\\(\\+\\|-\\)\\3"
"Regexp for recognizing foo++ or foo--.")
(defvar py-shorthand-postcrement-replace
"\\1\\2 = \\2 \\3 1"
"Replacement string for foo++; becomes foo = foo + 1.")
(defun py-shorthand-current-end-point ()
"Internal function to find current end of line."
(save-excursion
(end-of-line)
(point)
))
(defun py-shorthand-line-expand ()
"Expands shorthand notation such as += on the current line into valid
Python."
(interactive)
(save-excursion
(let ((end-pos (save-excursion (end-of-line) (point))))
(beginning-of-line)
(while (re-search-forward py-shorthand-statement-regexp
(py-shorthand-current-end-point) t 1)
(replace-match py-shorthand-statement-replace)
(beginning-of-line))
(beginning-of-line)
(while (re-search-forward py-shorthand-precrement-regexp
(py-shorthand-current-end-point) t 1)
(replace-match py-shorthand-precrement-replace)
(beginning-of-line))
(beginning-of-line)
(while (re-search-forward py-shorthand-postcrement-regexp
(py-shorthand-current-end-point) t 1)
(replace-match py-shorthand-postcrement-replace)
(beginning-of-line)))))
(defun py-shorthand-buffer-expand ()
"Expands shorthand notation such as += in the entire buffer into valid
Python."
(interactive)
(save-excursion
(goto-char (point-min))
(while (re-search-forward py-shorthand-statement-regexp nil t)
(replace-match py-shorthand-statement-replace))
(goto-char (point-min))
(while (re-search-forward py-shorthand-precrement-regexp nil t)
(replace-match py-shorthand-precrement-replace))
(goto-char (point-min))
(while (re-search-forward py-shorthand-postcrement-regexp nil t)
(replace-match py-shorthand-postcrement-replace))))
(add-hook 'python-mode-hook
(lambda ()
(define-key py-mode-map "\C-z" 'py-shorthand-line-expand)
(define-key py-mode-map "\C-c\C-z" 'py-shorthand-buffer-expand)
))
--
|| Preston Landers <preston at askpreston.com> ||
|| http://askpreston.com ||
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
More information about the Python-list
mailing list