diff options
| author | Eli Zaretskii | 2013-04-17 19:37:15 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-04-17 19:37:15 +0300 |
| commit | 76efa828369a583650cf661a327d5698891a7a90 (patch) | |
| tree | 514ed86d637863695c07d1125d287c11383a509c /lisp/progmodes/python.el | |
| parent | 2d0d2952da64bae2af67014b22a3b8caa9aef810 (diff) | |
| parent | 083850a6a195c5d536bd4cd344b5917b225597cc (diff) | |
| download | emacs-76efa828369a583650cf661a327d5698891a7a90.tar.gz emacs-76efa828369a583650cf661a327d5698891a7a90.zip | |
Merge from trunk.
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 100 |
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. |
| 373 | TYPE can be `comment', `string' or `paren'. It returns the start | 386 | TYPE can be `comment', `string' or `paren'. It returns the start |
| 374 | character address of the specified TYPE." | 387 | character 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. | ||
| 1197 | FN must take no arguments and could be used to set match-data. | ||
| 1198 | POSCOMPFN is a two arguments function used to compare current and | ||
| 1199 | previous point after it is moved using FN, this is normally a | ||
| 1200 | less-than or greater-than comparison. Optional argument POS is | ||
| 1201 | internally used in recursive calls and should not be explicitly | ||
| 1202 | passed." | ||
| 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. | ||
| 1220 | Uses ARG to define which function to call, and how many times | ||
| 1221 | repeat 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. | ||
| 1243 | Unlikely `python-nav-beginning-of-defun' this doesn't care about | ||
| 1244 | nested 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. | ||
| 1250 | Unlikely `python-nav-beginning-of-defun' this doesn't care about | ||
| 1251 | nested 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. |
| 2670 | The skeleton will be bound to python-skeleton-NAME and will | 2732 | The skeleton will be bound to python-skeleton-NAME and will |
| 2671 | be added to `python-mode-abbrev-table'." | 2733 | be 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. |
| 2687 | The skeleton will be bound to python-skeleton-NAME." | 2753 | The skeleton will be bound to python-skeleton-NAME." |