Commit e2803784 authored by Fabián Ezequiel Gallina's avatar Fabián Ezequiel Gallina Committed by Fabián Ezequiel Gallina
Browse files

Implemented Skeletons after GNU/Emacs python.el

6 basic skeletons are defined: class, def, for, if, try and while.

While these skeletons are strongly based on GNU/Emacs' current
python.el a better definition macro, a generic template for
try/except/finally/else blocks and a cool menu display is included.
parent 67845102
......@@ -68,6 +68,13 @@
;; the shell completion in background so you should run
;; `python-shell-send-buffer' from time to time to get better results.
;; Skeletons: 6 skeletons are provided for simple inserting of class,
;; def, for, if, try and while. These skeletons are integrated with
;; dabbrev. If you have `dabbrev-mode' activated and
;; `python-skeleton-autoinsert' is set to t, then whenever you type
;; the name of any of those defined and hit SPC, they will be
;; automatically expanded.
;; FFAP: You can find the filename for a given module when using ffap
;; out of the box. This feature needs an inferior python shell
;; running.
......@@ -110,8 +117,6 @@
;; Review code and cleanup
;; (Perhaps) some skeletons (I never use them because of yasnippet)
;;; Code:
(require 'comint)
......@@ -145,6 +150,13 @@
(define-key map "\C-c<" 'python-indent-shift-left)
(define-key map "\C-c>" 'python-indent-shift-right)
(define-key map ":" 'python-indent-electric-colon)
;; Skeletons
(define-key map "\C-c\C-tc" 'python-skeleton-class)
(define-key map "\C-c\C-td" 'python-skeleton-def)
(define-key map "\C-c\C-tf" 'python-skeleton-for)
(define-key map "\C-c\C-ti" 'python-skeleton-if)
(define-key map "\C-c\C-tt" 'python-skeleton-try)
(define-key map "\C-c\C-tw" 'python-skeleton-while)
;; Shell interaction
(define-key map "\C-c\C-s" 'python-shell-send-string)
(define-key map "\C-c\C-r" 'python-shell-send-region)
......@@ -176,6 +188,8 @@
["End of def/class" end-of-defun
:help "Go to end of definition around point"]
"-"
("Skeletons")
"-"
["Start interpreter" run-python
:help "Run inferior Python process in a separate buffer"]
["Switch to shell" python-shell-switch-to-shell
......@@ -1491,6 +1505,138 @@ Optional argument JUSTIFY defines if the paragraph should be justified."
(t t))))
;;; Skeletons
(defcustom python-skeleton-autoinsert nil
"Non-nil means template skeletons will be automagically inserted.
This happens when pressing \"if<SPACE>\", for example, to prompt for
the if condition."
:type 'boolean
:group 'python)
(defvar python-skeleton-available '()
"Internal list of available skeletons.")
(make-variable-buffer-local 'inferior-python-mode-current-file)
(define-abbrev-table 'python-mode-abbrev-table ()
"Abbrev table for Python mode."
:case-fixed t
;; Allow / inside abbrevs.
:regexp "\\(?:^\\|[^/]\\)\\<\\([[:word:]/]+\\)\\W*"
;; Only expand in code.
:enable-function (lambda ()
(message "ppss %s" (not (nth 8 (syntax-ppss))))
(message "autoinsert %s" python-skeleton-autoinsert)
(and
(not (nth 8 (syntax-ppss)))
python-skeleton-autoinsert)))
(defmacro python-skeleton-define (name doc &rest skel)
"Define a `python-mode' skeleton using NAME DOC and SKEL.
The skeleton will be bound to python-skeleton-NAME and will
be added to `python-mode-abbrev-table'."
(let* ((name (symbol-name name))
(function-name (intern (concat "python-skeleton-" name))))
(define-abbrev python-mode-abbrev-table name "" function-name)
(setq python-skeleton-available
(cons function-name python-skeleton-available))
`(define-skeleton ,function-name
,(or doc
(format "Insert %s statement." name))
,@skel)))
(put 'python-skeleton-define 'lisp-indent-function 2)
(defmacro python-define-auxiliary-skeleton (name doc &optional &rest skel)
"Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL.
The skeleton will be bound to python-skeleton-NAME."
(let* ((name (symbol-name name))
(function-name (intern (concat "python-skeleton--" name)))
(msg (format
"Add '%s' clause? " name)))
(when (not skel)
(setq skel
`(< ,(format "%s:" name) \n \n
> _ \n)))
`(define-skeleton ,function-name
,(or doc
(format "Auxiliary skeleton for %s statement." name))
nil
(unless (y-or-n-p ,msg)
(signal 'quit t))
,@skel)))
(put 'python-define-auxiliary-skeleton 'lisp-indent-function 2)
(python-define-auxiliary-skeleton else nil)
(python-define-auxiliary-skeleton except nil)
(python-define-auxiliary-skeleton finally nil)
(python-skeleton-define if nil
"Condition: "
"if " str ":" \n
_ \n
("other condition, %s: "
<
"elif " str ":" \n
> _ \n nil)
'(python-skeleton--else) | ^)
(python-skeleton-define while nil
"Condition: "
"while " str ":" \n
> _ \n
'(python-skeleton--else) | ^)
(python-skeleton-define for nil
"Iteration spec: "
"for " str ":" \n
> _ \n
'(python-skeleton--else) | ^)
(python-skeleton-define try nil
nil
"try:" \n
> _ \n
("Exception, %s: "
<
"except " str ":" \n
> _ \n nil)
resume:
'(python-skeleton--except)
'(python-skeleton--else)
'(python-skeleton--finally) | ^)
(python-skeleton-define def nil
"Function name: "
"def " str " (" ("Parameter, %s: "
(unless (equal ?\( (char-before)) ", ")
str) "):" \n
"\"\"\"" - "\"\"\"" \n
> _ \n)
(python-skeleton-define class nil
"Class name: "
"class " str " (" ("Inheritance, %s: "
(unless (equal ?\( (char-before)) ", ")
str)
& ")" | -2
":" \n
"\"\"\"" - "\"\"\"" \n
> _ \n)
(defun python-skeleton-add-menu-items ()
"Add menu items to Python->Skeletons menu."
(let ((skeletons (sort python-skeleton-available 'string<))
(items))
(dolist (skeleton skeletons)
(easy-menu-add-item
nil '("Python" "Skeletons")
`[,(format
"Insert %s" (caddr (split-string (symbol-name skeleton) "-")))
,skeleton t]))))
;;; FFAP
(defvar python-ffap-setup-code
......@@ -1822,6 +1968,12 @@ not inside a defun."
(set (make-local-variable 'add-log-current-defun-function)
#'python-info-current-defun)
(set (make-local-variable 'skeleton-further-elements)
'((abbrev-mode nil)
(< '(backward-delete-char-untabify (min python-indent-offset
(current-column))))
(^ '(- (1+ (current-indentation))))))
(set (make-local-variable 'eldoc-documentation-function)
#'python-eldoc-function)
......@@ -1838,6 +1990,8 @@ not inside a defun."
"`outline-level' function for Python mode."
(1+ (/ (current-indentation) python-indent-offset))))
(python-skeleton-add-menu-items)
(when python-indent-guess-indent-offset
(python-indent-guess-indent-offset)))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment