aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorEli Zaretskii2013-04-17 19:37:15 +0300
committerEli Zaretskii2013-04-17 19:37:15 +0300
commit76efa828369a583650cf661a327d5698891a7a90 (patch)
tree514ed86d637863695c07d1125d287c11383a509c /lisp/progmodes/python.el
parent2d0d2952da64bae2af67014b22a3b8caa9aef810 (diff)
parent083850a6a195c5d536bd4cd344b5917b225597cc (diff)
downloademacs-76efa828369a583650cf661a327d5698891a7a90.tar.gz
emacs-76efa828369a583650cf661a327d5698891a7a90.zip
Merge from trunk.
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el100
1 files changed, 83 insertions, 17 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index d1009534e49..1d7cf02ca5a 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -368,22 +368,24 @@ This variant of `rx' supports common python named REGEXPS."
368 368
369;;; Font-lock and syntax 369;;; Font-lock and syntax
370 370
371(eval-when-compile
372 (defun python-syntax--context-compiler-macro (form type &optional syntax-ppss)
373 (pcase type
374 (`'comment
375 `(let ((ppss (or ,syntax-ppss (syntax-ppss))))
376 (and (nth 4 ppss) (nth 8 ppss))))
377 (`'string
378 `(let ((ppss (or ,syntax-ppss (syntax-ppss))))
379 (and (nth 3 ppss) (nth 8 ppss))))
380 (`'paren
381 `(nth 1 (or ,syntax-ppss (syntax-ppss))))
382 (_ form))))
383
371(defun python-syntax-context (type &optional syntax-ppss) 384(defun python-syntax-context (type &optional syntax-ppss)
372 "Return non-nil if point is on TYPE using SYNTAX-PPSS. 385 "Return non-nil if point is on TYPE using SYNTAX-PPSS.
373TYPE can be `comment', `string' or `paren'. It returns the start 386TYPE can be `comment', `string' or `paren'. It returns the start
374character address of the specified TYPE." 387character address of the specified TYPE."
375 (declare (compiler-macro 388 (declare (compiler-macro python-syntax--context-compiler-macro))
376 (lambda (form)
377 (pcase type
378 (`'comment
379 `(let ((ppss (or ,syntax-ppss (syntax-ppss))))
380 (and (nth 4 ppss) (nth 8 ppss))))
381 (`'string
382 `(let ((ppss (or ,syntax-ppss (syntax-ppss))))
383 (and (nth 3 ppss) (nth 8 ppss))))
384 (`'paren
385 `(nth 1 (or ,syntax-ppss (syntax-ppss))))
386 (_ form)))))
387 (let ((ppss (or syntax-ppss (syntax-ppss)))) 389 (let ((ppss (or syntax-ppss (syntax-ppss))))
388 (pcase type 390 (pcase type
389 (`comment (and (nth 4 ppss) (nth 8 ppss))) 391 (`comment (and (nth 4 ppss) (nth 8 ppss)))
@@ -1190,6 +1192,66 @@ Returns nil if point is not in a def or class."
1190 ;; Ensure point moves forward. 1192 ;; Ensure point moves forward.
1191 (and (> beg-pos (point)) (goto-char beg-pos))))) 1193 (and (> beg-pos (point)) (goto-char beg-pos)))))
1192 1194
1195(defun python-nav--syntactically (fn poscompfn &optional pos)
1196 "Move to point using FN ignoring non-code or paren context.
1197FN must take no arguments and could be used to set match-data.
1198POSCOMPFN is a two arguments function used to compare current and
1199previous point after it is moved using FN, this is normally a
1200less-than or greater-than comparison. Optional argument POS is
1201internally used in recursive calls and should not be explicitly
1202passed."
1203 (let* ((newpos
1204 (and (funcall fn)
1205 (save-match-data
1206 (and
1207 (not (python-syntax-context-type))
1208 (point-marker)))))
1209 (current-match-data (match-data)))
1210 (cond ((or (and (not pos) newpos)
1211 (and pos newpos (funcall poscompfn newpos pos)))
1212 (set-match-data current-match-data)
1213 (point-marker))
1214 ((and (not pos) (not newpos)) nil)
1215 (t (python-nav--syntactically
1216 fn poscompfn (point-marker))))))
1217
1218(defun python-nav--forward-defun (arg)
1219 "Internal implementation of python-nav-{backward,forward}-defun.
1220Uses ARG to define which function to call, and how many times
1221repeat it."
1222 (let ((found))
1223 (while (and (> arg 0)
1224 (setq found
1225 (python-nav--syntactically
1226 (lambda ()
1227 (re-search-forward
1228 python-nav-beginning-of-defun-regexp nil t))
1229 '>)))
1230 (setq arg (1- arg)))
1231 (while (and (< arg 0)
1232 (setq found
1233 (python-nav--syntactically
1234 (lambda ()
1235 (re-search-backward
1236 python-nav-beginning-of-defun-regexp nil t))
1237 '<)))
1238 (setq arg (1+ arg)))
1239 found))
1240
1241(defun python-nav-backward-defun (&optional arg)
1242 "Navigate to closer defun backward ARG times.
1243Unlikely `python-nav-beginning-of-defun' this doesn't care about
1244nested definitions."
1245 (interactive "^p")
1246 (python-nav--forward-defun (- (or arg 1))))
1247
1248(defun python-nav-forward-defun (&optional arg)
1249 "Navigate to closer defun forward ARG times.
1250Unlikely `python-nav-beginning-of-defun' this doesn't care about
1251nested definitions."
1252 (interactive "^p")
1253 (python-nav--forward-defun (or arg 1)))
1254
1193(defun python-nav-beginning-of-statement () 1255(defun python-nav-beginning-of-statement ()
1194 "Move to start of current statement." 1256 "Move to start of current statement."
1195 (interactive "^") 1257 (interactive "^")
@@ -2654,8 +2716,8 @@ the if condition."
2654(defvar python-skeleton-available '() 2716(defvar python-skeleton-available '()
2655 "Internal list of available skeletons.") 2717 "Internal list of available skeletons.")
2656 2718
2657(define-abbrev-table 'python-mode-abbrev-table () 2719(define-abbrev-table 'python-mode-skeleton-abbrev-table ()
2658 "Abbrev table for Python mode." 2720 "Abbrev table for Python mode skeletons."
2659 :case-fixed t 2721 :case-fixed t
2660 ;; Allow / inside abbrevs. 2722 ;; Allow / inside abbrevs.
2661 :regexp "\\(?:^\\|[^/]\\)\\<\\([[:word:]/]+\\)\\W*" 2723 :regexp "\\(?:^\\|[^/]\\)\\<\\([[:word:]/]+\\)\\W*"
@@ -2668,13 +2730,13 @@ the if condition."
2668(defmacro python-skeleton-define (name doc &rest skel) 2730(defmacro python-skeleton-define (name doc &rest skel)
2669 "Define a `python-mode' skeleton using NAME DOC and SKEL. 2731 "Define a `python-mode' skeleton using NAME DOC and SKEL.
2670The skeleton will be bound to python-skeleton-NAME and will 2732The skeleton will be bound to python-skeleton-NAME and will
2671be added to `python-mode-abbrev-table'." 2733be added to `python-mode-skeleton-abbrev-table'."
2672 (declare (indent 2)) 2734 (declare (indent 2))
2673 (let* ((name (symbol-name name)) 2735 (let* ((name (symbol-name name))
2674 (function-name (intern (concat "python-skeleton-" name)))) 2736 (function-name (intern (concat "python-skeleton-" name))))
2675 `(progn 2737 `(progn
2676 (define-abbrev python-mode-abbrev-table ,name "" ',function-name 2738 (define-abbrev python-mode-skeleton-abbrev-table
2677 :system t) 2739 ,name "" ',function-name :system t)
2678 (setq python-skeleton-available 2740 (setq python-skeleton-available
2679 (cons ',function-name python-skeleton-available)) 2741 (cons ',function-name python-skeleton-available))
2680 (define-skeleton ,function-name 2742 (define-skeleton ,function-name
@@ -2682,6 +2744,10 @@ be added to `python-mode-abbrev-table'."
2682 (format "Insert %s statement." name)) 2744 (format "Insert %s statement." name))
2683 ,@skel)))) 2745 ,@skel))))
2684 2746
2747(define-abbrev-table 'python-mode-abbrev-table ()
2748 "Abbrev table for Python mode."
2749 :parents (list python-mode-skeleton-abbrev-table))
2750
2685(defmacro python-define-auxiliary-skeleton (name doc &optional &rest skel) 2751(defmacro python-define-auxiliary-skeleton (name doc &optional &rest skel)
2686 "Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL. 2752 "Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL.
2687The skeleton will be bound to python-skeleton-NAME." 2753The skeleton will be bound to python-skeleton-NAME."