diff options
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 694 |
1 files changed, 305 insertions, 389 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 462445f3d71..c866486ea52 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; python.el --- silly walks for Python | 1 | ;;; python.el --- silly walks for Python -*- coding: iso-8859-1 -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Dave Love <fx@gnu.org> | 5 | ;; Author: Dave Love <fx@gnu.org> |
| 6 | ;; Maintainer: FSF | 6 | ;; Maintainer: FSF |
| @@ -11,7 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | ;; GNU Emacs is free software; you can redistribute it and/or modify | 12 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
| 13 | ;; it under the terms of the GNU General Public License as published by | 13 | ;; it under the terms of the GNU General Public License as published by |
| 14 | ;; the Free Software Foundation; either version 3, or (at your option) | 14 | ;; the Free Software Foundation; either version 2, or (at your option) |
| 15 | ;; any later version. | 15 | ;; any later version. |
| 16 | 16 | ||
| 17 | ;; GNU Emacs is distributed in the hope that it will be useful, | 17 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| @@ -65,10 +65,10 @@ | |||
| 65 | ;;; Code: | 65 | ;;; Code: |
| 66 | 66 | ||
| 67 | (eval-when-compile | 67 | (eval-when-compile |
| 68 | (require 'cl) | ||
| 69 | (require 'compile) | 68 | (require 'compile) |
| 70 | (require 'comint) | 69 | (require 'comint) |
| 71 | (require 'hippie-exp)) | 70 | (autoload 'font-lock-fontify-region "font-lock") |
| 71 | (autoload 'info-lookup-maybe-add-help "info-look")) | ||
| 72 | 72 | ||
| 73 | (autoload 'comint-mode "comint") | 73 | (autoload 'comint-mode "comint") |
| 74 | 74 | ||
| @@ -84,22 +84,21 @@ | |||
| 84 | (add-to-list 'interpreter-mode-alist '("python" . python-mode)) | 84 | (add-to-list 'interpreter-mode-alist '("python" . python-mode)) |
| 85 | ;;;###autoload | 85 | ;;;###autoload |
| 86 | (add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode)) | 86 | (add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode)) |
| 87 | (add-to-list 'same-window-buffer-names "*Python*") | ||
| 87 | 88 | ||
| 88 | ;;;; Font lock | 89 | ;;;; Font lock |
| 89 | 90 | ||
| 90 | (defvar python-font-lock-keywords | 91 | (defvar python-font-lock-keywords |
| 91 | `(,(rx symbol-start | 92 | `(,(rx symbol-start |
| 92 | ;; From v 2.4 reference. | 93 | ;; From v 2.5 reference, § keywords. |
| 93 | ;; def and class dealt with separately below | 94 | ;; def and class dealt with separately below |
| 94 | (or "and" "assert" "break" "continue" "del" "elif" "else" | 95 | (or "and" "as" "assert" "break" "continue" "del" "elif" "else" |
| 95 | "except" "exec" "finally" "for" "from" "global" "if" | 96 | "except" "exec" "finally" "for" "from" "global" "if" |
| 96 | "import" "in" "is" "lambda" "not" "or" "pass" "print" | 97 | "import" "in" "is" "lambda" "not" "or" "pass" "print" |
| 97 | "raise" "return" "try" "while" "yield" | 98 | "raise" "return" "try" "while" "with" "yield") |
| 98 | ;; Future keywords | ||
| 99 | "as" "None" "with" | ||
| 100 | ;; Not real keywords, but close enough to be fontified as such | ||
| 101 | "self" "True" "False") | ||
| 102 | symbol-end) | 99 | symbol-end) |
| 100 | (,(rx symbol-start "None" symbol-end) ; see § Keywords in 2.5 manual | ||
| 101 | . font-lock-constant-face) | ||
| 103 | ;; Definitions | 102 | ;; Definitions |
| 104 | (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_)))) | 103 | (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_)))) |
| 105 | (1 font-lock-keyword-face) (2 font-lock-type-face)) | 104 | (1 font-lock-keyword-face) (2 font-lock-type-face)) |
| @@ -151,7 +150,8 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." | |||
| 151 | (cond | 150 | (cond |
| 152 | ;; Consider property for the last char if in a fenced string. | 151 | ;; Consider property for the last char if in a fenced string. |
| 153 | ((= n 3) | 152 | ((= n 3) |
| 154 | (let ((syntax (syntax-ppss))) | 153 | (let* ((font-lock-syntactic-keywords nil) |
| 154 | (syntax (syntax-ppss))) | ||
| 155 | (when (eq t (nth 3 syntax)) ; after unclosed fence | 155 | (when (eq t (nth 3 syntax)) ; after unclosed fence |
| 156 | (goto-char (nth 8 syntax)) ; fence position | 156 | (goto-char (nth 8 syntax)) ; fence position |
| 157 | (skip-chars-forward "uUrR") ; skip any prefix | 157 | (skip-chars-forward "uUrR") ; skip any prefix |
| @@ -163,8 +163,9 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." | |||
| 163 | (= (match-beginning 1) (match-end 1))) ; prefix is null | 163 | (= (match-beginning 1) (match-end 1))) ; prefix is null |
| 164 | (and (= n 1) ; prefix | 164 | (and (= n 1) ; prefix |
| 165 | (/= (match-beginning 1) (match-end 1)))) ; non-empty | 165 | (/= (match-beginning 1) (match-end 1)))) ; non-empty |
| 166 | (unless (nth 3 (syntax-ppss)) | 166 | (let ((font-lock-syntactic-keywords nil)) |
| 167 | (eval-when-compile (string-to-syntax "|")))) | 167 | (unless (eq 'string (syntax-ppss-context (syntax-ppss))) |
| 168 | (eval-when-compile (string-to-syntax "|"))))) | ||
| 168 | ;; Otherwise (we're in a non-matching string) the property is | 169 | ;; Otherwise (we're in a non-matching string) the property is |
| 169 | ;; nil, which is OK. | 170 | ;; nil, which is OK. |
| 170 | ))) | 171 | ))) |
| @@ -192,6 +193,8 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." | |||
| 192 | 193 | ||
| 193 | ;;;; Keymap and syntax | 194 | ;;;; Keymap and syntax |
| 194 | 195 | ||
| 196 | (autoload 'symbol-complete "sym-comp" nil t) | ||
| 197 | |||
| 195 | (defvar python-mode-map | 198 | (defvar python-mode-map |
| 196 | (let ((map (make-sparse-keymap))) | 199 | (let ((map (make-sparse-keymap))) |
| 197 | ;; Mostly taken from python-mode.el. | 200 | ;; Mostly taken from python-mode.el. |
| @@ -214,7 +217,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." | |||
| 214 | (define-key map "\C-c\C-z" 'python-switch-to-python) | 217 | (define-key map "\C-c\C-z" 'python-switch-to-python) |
| 215 | (define-key map "\C-c\C-m" 'python-load-file) | 218 | (define-key map "\C-c\C-m" 'python-load-file) |
| 216 | (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme | 219 | (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme |
| 217 | (substitute-key-definition 'complete-symbol 'python-complete-symbol | 220 | (substitute-key-definition 'complete-symbol 'symbol-complete |
| 218 | map global-map) | 221 | map global-map) |
| 219 | (define-key map "\C-c\C-i" 'python-find-imports) | 222 | (define-key map "\C-c\C-i" 'python-find-imports) |
| 220 | (define-key map "\C-c\C-t" 'python-expand-template) | 223 | (define-key map "\C-c\C-t" 'python-expand-template) |
| @@ -267,7 +270,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." | |||
| 267 | "-" | 270 | "-" |
| 268 | ["Help on symbol" python-describe-symbol | 271 | ["Help on symbol" python-describe-symbol |
| 269 | :help "Use pydoc on symbol at point"] | 272 | :help "Use pydoc on symbol at point"] |
| 270 | ["Complete symbol" python-complete-symbol | 273 | ["Complete symbol" symbol-complete |
| 271 | :help "Complete (qualified) symbol before point"] | 274 | :help "Complete (qualified) symbol before point"] |
| 272 | ["Update imports" python-find-imports | 275 | ["Update imports" python-find-imports |
| 273 | :help "Update list of top-level imports for completion"])) | 276 | :help "Update list of top-level imports for completion"])) |
| @@ -348,7 +351,7 @@ comments and strings, or that point is within brackets/parens." | |||
| 348 | (error nil)))))))) | 351 | (error nil)))))))) |
| 349 | 352 | ||
| 350 | (defun python-comment-line-p () | 353 | (defun python-comment-line-p () |
| 351 | "Return non-nil if current line has only a comment." | 354 | "Return non-nil iff current line has only a comment." |
| 352 | (save-excursion | 355 | (save-excursion |
| 353 | (end-of-line) | 356 | (end-of-line) |
| 354 | (when (eq 'comment (syntax-ppss-context (syntax-ppss))) | 357 | (when (eq 'comment (syntax-ppss-context (syntax-ppss))) |
| @@ -356,7 +359,7 @@ comments and strings, or that point is within brackets/parens." | |||
| 356 | (looking-at (rx (or (syntax comment-start) line-end)))))) | 359 | (looking-at (rx (or (syntax comment-start) line-end)))))) |
| 357 | 360 | ||
| 358 | (defun python-blank-line-p () | 361 | (defun python-blank-line-p () |
| 359 | "Return non-nil if current line is blank." | 362 | "Return non-nil iff current line is blank." |
| 360 | (save-excursion | 363 | (save-excursion |
| 361 | (beginning-of-line) | 364 | (beginning-of-line) |
| 362 | (looking-at "\\s-*$"))) | 365 | (looking-at "\\s-*$"))) |
| @@ -374,7 +377,7 @@ BOS non-nil means point is known to be at beginning of statement." | |||
| 374 | (save-excursion | 377 | (save-excursion |
| 375 | (unless bos (python-beginning-of-statement)) | 378 | (unless bos (python-beginning-of-statement)) |
| 376 | (looking-at (rx (and (or "if" "else" "elif" "while" "for" "def" | 379 | (looking-at (rx (and (or "if" "else" "elif" "while" "for" "def" |
| 377 | "class" "try" "except" "finally" "with") | 380 | "class" "try" "except" "finally") |
| 378 | symbol-end))))) | 381 | symbol-end))))) |
| 379 | 382 | ||
| 380 | (defun python-close-block-statement-p (&optional bos) | 383 | (defun python-close-block-statement-p (&optional bos) |
| @@ -404,19 +407,18 @@ The criteria are that the line isn't a comment or in string and | |||
| 404 | ;;;; Indentation. | 407 | ;;;; Indentation. |
| 405 | 408 | ||
| 406 | (defcustom python-indent 4 | 409 | (defcustom python-indent 4 |
| 407 | "Number of columns for a unit of indentation in Python mode. | 410 | "*Number of columns for a unit of indentation in Python mode. |
| 408 | See also `\\[python-guess-indent]'" | 411 | See also `\\[python-guess-indent]'" |
| 409 | :group 'python | 412 | :group 'python |
| 410 | :type 'integer) | 413 | :type 'integer) |
| 411 | (put 'python-indent 'safe-local-variable 'integerp) | ||
| 412 | 414 | ||
| 413 | (defcustom python-guess-indent t | 415 | (defcustom python-guess-indent t |
| 414 | "Non-nil means Python mode guesses `python-indent' for the buffer." | 416 | "*Non-nil means Python mode guesses `python-indent' for the buffer." |
| 415 | :type 'boolean | 417 | :type 'boolean |
| 416 | :group 'python) | 418 | :group 'python) |
| 417 | 419 | ||
| 418 | (defcustom python-indent-string-contents t | 420 | (defcustom python-indent-string-contents t |
| 419 | "Non-nil means indent contents of multi-line strings together. | 421 | "*Non-nil means indent contents of multi-line strings together. |
| 420 | This means indent them the same as the preceding non-blank line. | 422 | This means indent them the same as the preceding non-blank line. |
| 421 | Otherwise preserve their indentation. | 423 | Otherwise preserve their indentation. |
| 422 | 424 | ||
| @@ -435,7 +437,7 @@ are always indented in lines with preceding comments." | |||
| 435 | :group 'python) | 437 | :group 'python) |
| 436 | 438 | ||
| 437 | (defcustom python-continuation-offset 4 | 439 | (defcustom python-continuation-offset 4 |
| 438 | "Number of columns of additional indentation for continuation lines. | 440 | "*Number of columns of additional indentation for continuation lines. |
| 439 | Continuation lines follow a backslash-terminated line starting a | 441 | Continuation lines follow a backslash-terminated line starting a |
| 440 | statement." | 442 | statement." |
| 441 | :group 'python | 443 | :group 'python |
| @@ -461,7 +463,7 @@ Set `python-indent' locally to the value guessed." | |||
| 461 | (let ((initial (current-indentation))) | 463 | (let ((initial (current-indentation))) |
| 462 | (if (zerop (python-next-statement)) | 464 | (if (zerop (python-next-statement)) |
| 463 | (setq indent (- (current-indentation) initial))) | 465 | (setq indent (- (current-indentation) initial))) |
| 464 | (if (and indent (>= indent 2) (<= indent 8)) ; sanity check | 466 | (if (and (>= indent 2) (<= indent 8)) ; sanity check |
| 465 | (setq done t)))))) | 467 | (setq done t)))))) |
| 466 | (when done | 468 | (when done |
| 467 | (when (/= indent (default-value 'python-indent)) | 469 | (when (/= indent (default-value 'python-indent)) |
| @@ -552,39 +554,40 @@ Set `python-indent' locally to the value guessed." | |||
| 552 | ((looking-at (rx (0+ space) (syntax comment-start) | 554 | ((looking-at (rx (0+ space) (syntax comment-start) |
| 553 | (not (any " \t\n")))) ; non-indentable comment | 555 | (not (any " \t\n")))) ; non-indentable comment |
| 554 | (current-indentation)) | 556 | (current-indentation)) |
| 555 | (t (if python-honour-comment-indentation | 557 | (t (let ((point (point))) |
| 556 | ;; Back over whitespace, newlines, non-indentable comments. | 558 | (if python-honour-comment-indentation |
| 557 | (catch 'done | 559 | ;; Back over whitespace, newlines, non-indentable comments. |
| 558 | (while t | 560 | (catch 'done |
| 559 | (if (cond ((bobp)) | 561 | (while t |
| 560 | ;; not at comment start | 562 | (if (cond ((bobp)) |
| 561 | ((not (forward-comment -1)) | 563 | ;; not at comment start |
| 562 | (python-beginning-of-statement) | 564 | ((not (forward-comment -1)) |
| 563 | t) | 565 | (python-beginning-of-statement) |
| 564 | ;; trailing comment | 566 | t) |
| 565 | ((/= (current-column) (current-indentation)) | 567 | ;; trailing comment |
| 566 | (python-beginning-of-statement) | 568 | ((/= (current-column) (current-indentation)) |
| 567 | t) | 569 | (python-beginning-of-statement) |
| 568 | ;; indentable comment like python-mode.el | 570 | t) |
| 569 | ((and (looking-at (rx (syntax comment-start) | 571 | ;; indentable comment like python-mode.el |
| 570 | (or space line-end))) | 572 | ((and (looking-at (rx (syntax comment-start) |
| 571 | (/= 0 (current-column))))) | 573 | (or space line-end))) |
| 572 | (throw 'done t))))) | 574 | (/= 0 (current-column))))) |
| 573 | (python-indentation-levels) | 575 | (throw 'done t))))) |
| 574 | ;; Prefer to indent comments with an immediately-following | 576 | (python-indentation-levels) |
| 575 | ;; statement, e.g. | 577 | ;; Prefer to indent comments with an immediately-following |
| 576 | ;; ... | 578 | ;; statement, e.g. |
| 577 | ;; # ... | 579 | ;; ... |
| 578 | ;; def ... | 580 | ;; # ... |
| 579 | (when (and (> python-indent-list-length 1) | 581 | ;; def ... |
| 580 | (python-comment-line-p)) | 582 | (when (and (> python-indent-list-length 1) |
| 581 | (forward-line) | 583 | (python-comment-line-p)) |
| 582 | (unless (python-comment-line-p) | 584 | (forward-line) |
| 583 | (let ((elt (assq (current-indentation) python-indent-list))) | 585 | (unless (python-comment-line-p) |
| 584 | (setq python-indent-list | 586 | (let ((elt (assq (current-indentation) python-indent-list))) |
| 585 | (nconc (delete elt python-indent-list) | 587 | (setq python-indent-list |
| 586 | (list elt)))))) | 588 | (nconc (delete elt python-indent-list) |
| 587 | (caar (last python-indent-list))))))) | 589 | (list elt)))))) |
| 590 | (caar (last python-indent-list)))))))) | ||
| 588 | 591 | ||
| 589 | ;;;; Cycling through the possible indentations with successive TABs. | 592 | ;;;; Cycling through the possible indentations with successive TABs. |
| 590 | 593 | ||
| @@ -759,13 +762,13 @@ reached start of buffer." | |||
| 759 | (let ((ci (current-indentation)) | 762 | (let ((ci (current-indentation)) |
| 760 | (def-re (rx line-start (0+ space) (or "def" "class") (1+ space) | 763 | (def-re (rx line-start (0+ space) (or "def" "class") (1+ space) |
| 761 | (group (1+ (or word (syntax symbol)))))) | 764 | (group (1+ (or word (syntax symbol)))))) |
| 762 | found lep) ;; def-line | 765 | found lep def-line) |
| 763 | (if (python-comment-line-p) | 766 | (if (python-comment-line-p) |
| 764 | (setq ci most-positive-fixnum)) | 767 | (setq ci most-positive-fixnum)) |
| 765 | (while (and (not (bobp)) (not found)) | 768 | (while (and (not (bobp)) (not found)) |
| 766 | ;; Treat bol at beginning of function as outside function so | 769 | ;; Treat bol at beginning of function as outside function so |
| 767 | ;; that successive C-M-a makes progress backwards. | 770 | ;; that successive C-M-a makes progress backwards. |
| 768 | ;;(setq def-line (looking-at def-re)) | 771 | (setq def-line (looking-at def-re)) |
| 769 | (unless (bolp) (end-of-line)) | 772 | (unless (bolp) (end-of-line)) |
| 770 | (setq lep (line-end-position)) | 773 | (setq lep (line-end-position)) |
| 771 | (if (and (re-search-backward def-re nil 'move) | 774 | (if (and (re-search-backward def-re nil 'move) |
| @@ -777,7 +780,7 @@ reached start of buffer." | |||
| 777 | ;; Not sure why it was like this -- fails in case of | 780 | ;; Not sure why it was like this -- fails in case of |
| 778 | ;; last internal function followed by first | 781 | ;; last internal function followed by first |
| 779 | ;; non-def statement of the main body. | 782 | ;; non-def statement of the main body. |
| 780 | ;;(and def-line (= in ci)) | 783 | ;; (and def-line (= in ci)) |
| 781 | (= in ci) | 784 | (= in ci) |
| 782 | (< in ci))) | 785 | (< in ci))) |
| 783 | (not (python-in-string/comment))) | 786 | (not (python-in-string/comment))) |
| @@ -850,7 +853,7 @@ multi-line bracketed expressions." | |||
| 850 | "Skip out of any nested brackets. | 853 | "Skip out of any nested brackets. |
| 851 | Skip forward if FORWARD is non-nil, else backward. | 854 | Skip forward if FORWARD is non-nil, else backward. |
| 852 | If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point. | 855 | If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point. |
| 853 | Return non-nil if skipping was done." | 856 | Return non-nil iff skipping was done." |
| 854 | (let ((depth (syntax-ppss-depth (or syntax (syntax-ppss)))) | 857 | (let ((depth (syntax-ppss-depth (or syntax (syntax-ppss)))) |
| 855 | (forward (if forward -1 1))) | 858 | (forward (if forward -1 1))) |
| 856 | (unless (zerop depth) | 859 | (unless (zerop depth) |
| @@ -883,13 +886,10 @@ On a comment line, go to end of line." | |||
| 883 | nil) | 886 | nil) |
| 884 | ((eq 'string (syntax-ppss-context s)) | 887 | ((eq 'string (syntax-ppss-context s)) |
| 885 | ;; Go to start of string and skip it. | 888 | ;; Go to start of string and skip it. |
| 886 | (let ((pos (point))) | 889 | (goto-char (nth 8 s)) |
| 887 | (goto-char (nth 8 s)) | 890 | (condition-case () ; beware invalid syntax |
| 888 | (condition-case () ; beware invalid syntax | 891 | (progn (forward-sexp) t) |
| 889 | (progn (forward-sexp) t) | 892 | (error (end-of-line)))) |
| 890 | ;; If there's a mismatched string, make sure | ||
| 891 | ;; we still overall move *forward*. | ||
| 892 | (error (goto-char pos) (end-of-line))))) | ||
| 893 | ((python-skip-out t s)))) | 893 | ((python-skip-out t s)))) |
| 894 | (end-of-line)) | 894 | (end-of-line)) |
| 895 | (unless comment | 895 | (unless comment |
| @@ -988,7 +988,7 @@ don't move and return nil. Otherwise return t." | |||
| 988 | (if (and (zerop ci) (not open)) | 988 | (if (and (zerop ci) (not open)) |
| 989 | (not (goto-char point)) | 989 | (not (goto-char point)) |
| 990 | (catch 'done | 990 | (catch 'done |
| 991 | (while (zerop (python-next-statement)) | 991 | (while (zerop (python-next-statement)) |
| 992 | (when (or (and open (<= (current-indentation) ci)) | 992 | (when (or (and open (<= (current-indentation) ci)) |
| 993 | (< (current-indentation) ci)) | 993 | (< (current-indentation) ci)) |
| 994 | (python-skip-comments/blanks t) | 994 | (python-skip-comments/blanks t) |
| @@ -996,16 +996,7 @@ don't move and return nil. Otherwise return t." | |||
| 996 | (throw 'done t))))))) | 996 | (throw 'done t))))))) |
| 997 | (setq arg (1- arg))) | 997 | (setq arg (1- arg))) |
| 998 | (zerop arg))) | 998 | (zerop arg))) |
| 999 | 999 | ||
| 1000 | (defvar python-which-func-length-limit 40 | ||
| 1001 | "Non-strict length limit for `python-which-func' output.") | ||
| 1002 | |||
| 1003 | (defun python-which-func () | ||
| 1004 | (let ((function-name (python-current-defun python-which-func-length-limit))) | ||
| 1005 | (set-text-properties 0 (length function-name) nil function-name) | ||
| 1006 | function-name)) | ||
| 1007 | |||
| 1008 | |||
| 1009 | ;;;; Imenu. | 1000 | ;;;; Imenu. |
| 1010 | 1001 | ||
| 1011 | (defvar python-recursing) | 1002 | (defvar python-recursing) |
| @@ -1025,10 +1016,8 @@ precede it)." | |||
| 1025 | ;; _with_ this, imenu doesn't immediately work; I can't figure out | 1016 | ;; _with_ this, imenu doesn't immediately work; I can't figure out |
| 1026 | ;; what's going on, but it must be something to do with timers in | 1017 | ;; what's going on, but it must be something to do with timers in |
| 1027 | ;; font-lock. | 1018 | ;; font-lock. |
| 1028 | ;; This can't be right, especially not when jit-lock is not used. --Stef | 1019 | (unless (get-text-property (1- (point-max)) 'fontified) |
| 1029 | ;; (unless (get-text-property (1- (point-max)) 'fontified) | 1020 | (font-lock-fontify-region (point-min) (point-max)))) |
| 1030 | ;; (font-lock-fontify-region (point-min) (point-max))) | ||
| 1031 | ) | ||
| 1032 | (let (index-alist) ; accumulated value to return | 1021 | (let (index-alist) ; accumulated value to return |
| 1033 | (while (re-search-forward | 1022 | (while (re-search-forward |
| 1034 | (rx line-start (0+ space) ; leading space | 1023 | (rx line-start (0+ space) ; leading space |
| @@ -1083,13 +1072,15 @@ just insert a single colon." | |||
| 1083 | 1072 | ||
| 1084 | (defun python-backspace (arg) | 1073 | (defun python-backspace (arg) |
| 1085 | "Maybe delete a level of indentation on the current line. | 1074 | "Maybe delete a level of indentation on the current line. |
| 1086 | Do so if point is at the end of the line's indentation. | 1075 | Do so if point is at the end of the line's indentation outside |
| 1076 | strings and comments. | ||
| 1087 | Otherwise just call `backward-delete-char-untabify'. | 1077 | Otherwise just call `backward-delete-char-untabify'. |
| 1088 | Repeat ARG times." | 1078 | Repeat ARG times." |
| 1089 | (interactive "*p") | 1079 | (interactive "*p") |
| 1090 | (if (or (/= (current-indentation) (current-column)) | 1080 | (if (or (/= (current-indentation) (current-column)) |
| 1091 | (bolp) | 1081 | (bolp) |
| 1092 | (python-continuation-line-p)) | 1082 | (python-continuation-line-p) |
| 1083 | (python-in-string/comment)) | ||
| 1093 | (backward-delete-char-untabify arg) | 1084 | (backward-delete-char-untabify arg) |
| 1094 | ;; Look for the largest valid indentation which is smaller than | 1085 | ;; Look for the largest valid indentation which is smaller than |
| 1095 | ;; the current indentation. | 1086 | ;; the current indentation. |
| @@ -1110,7 +1101,7 @@ Repeat ARG times." | |||
| 1110 | ;;;; pychecker | 1101 | ;;;; pychecker |
| 1111 | 1102 | ||
| 1112 | (defcustom python-check-command "pychecker --stdlib" | 1103 | (defcustom python-check-command "pychecker --stdlib" |
| 1113 | "Command used to check a Python file." | 1104 | "*Command used to check a Python file." |
| 1114 | :type 'string | 1105 | :type 'string |
| 1115 | :group 'python) | 1106 | :group 'python) |
| 1116 | 1107 | ||
| @@ -1142,7 +1133,7 @@ See `python-check-command' for the default." | |||
| 1142 | ;; Fixme: Make sure we can work with IPython. | 1133 | ;; Fixme: Make sure we can work with IPython. |
| 1143 | 1134 | ||
| 1144 | (defcustom python-python-command "python" | 1135 | (defcustom python-python-command "python" |
| 1145 | "Shell command to run Python interpreter. | 1136 | "*Shell command to run Python interpreter. |
| 1146 | Any arguments can't contain whitespace. | 1137 | Any arguments can't contain whitespace. |
| 1147 | Note that IPython may not work properly; it must at least be used | 1138 | Note that IPython may not work properly; it must at least be used |
| 1148 | with the `-cl' flag, i.e. use `ipython -cl'." | 1139 | with the `-cl' flag, i.e. use `ipython -cl'." |
| @@ -1150,7 +1141,7 @@ with the `-cl' flag, i.e. use `ipython -cl'." | |||
| 1150 | :type 'string) | 1141 | :type 'string) |
| 1151 | 1142 | ||
| 1152 | (defcustom python-jython-command "jython" | 1143 | (defcustom python-jython-command "jython" |
| 1153 | "Shell command to run Jython interpreter. | 1144 | "*Shell command to run Jython interpreter. |
| 1154 | Any arguments can't contain whitespace." | 1145 | Any arguments can't contain whitespace." |
| 1155 | :group 'python | 1146 | :group 'python |
| 1156 | :type 'string) | 1147 | :type 'string) |
| @@ -1162,7 +1153,7 @@ modified by the user. Additional arguments are added when the command | |||
| 1162 | is used by `run-python' et al.") | 1153 | is used by `run-python' et al.") |
| 1163 | 1154 | ||
| 1164 | (defvar python-buffer nil | 1155 | (defvar python-buffer nil |
| 1165 | "*The current Python process buffer. | 1156 | "*The current python process buffer. |
| 1166 | 1157 | ||
| 1167 | Commands that send text from source buffers to Python processes have | 1158 | Commands that send text from source buffers to Python processes have |
| 1168 | to choose a process to send to. This is determined by buffer-local | 1159 | to choose a process to send to. This is determined by buffer-local |
| @@ -1190,6 +1181,10 @@ local value.") | |||
| 1190 | 1 2) | 1181 | 1 2) |
| 1191 | (,(rx " in file " (group (1+ not-newline)) " on line " | 1182 | (,(rx " in file " (group (1+ not-newline)) " on line " |
| 1192 | (group (1+ digit))) | 1183 | (group (1+ digit))) |
| 1184 | 1 2) | ||
| 1185 | ;; pdb stack trace | ||
| 1186 | (,(rx line-start "> " (group (1+ (not (any "(\"<")))) | ||
| 1187 | "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()") | ||
| 1193 | 1 2)) | 1188 | 1 2)) |
| 1194 | "`compilation-error-regexp-alist' for inferior Python.") | 1189 | "`compilation-error-regexp-alist' for inferior Python.") |
| 1195 | 1190 | ||
| @@ -1199,7 +1194,7 @@ local value.") | |||
| 1199 | (define-key map "\C-c\C-l" 'python-load-file) | 1194 | (define-key map "\C-c\C-l" 'python-load-file) |
| 1200 | (define-key map "\C-c\C-v" 'python-check) | 1195 | (define-key map "\C-c\C-v" 'python-check) |
| 1201 | ;; Note that we _can_ still use these commands which send to the | 1196 | ;; Note that we _can_ still use these commands which send to the |
| 1202 | ;; Python process even at the prompt provided we have a normal prompt, | 1197 | ;; Python process even at the prompt iff we have a normal prompt, |
| 1203 | ;; i.e. '>>> ' and not '... '. See the comment before | 1198 | ;; i.e. '>>> ' and not '... '. See the comment before |
| 1204 | ;; python-send-region. Fixme: uncomment these if we address that. | 1199 | ;; python-send-region. Fixme: uncomment these if we address that. |
| 1205 | 1200 | ||
| @@ -1245,13 +1240,13 @@ For running multiple processes in multiple buffers, see `run-python' and | |||
| 1245 | ;; Still required by `comint-redirect-send-command', for instance | 1240 | ;; Still required by `comint-redirect-send-command', for instance |
| 1246 | ;; (and we need to match things like `>>> ... >>> '): | 1241 | ;; (and we need to match things like `>>> ... >>> '): |
| 1247 | (set (make-local-variable 'comint-prompt-regexp) | 1242 | (set (make-local-variable 'comint-prompt-regexp) |
| 1248 | (rx line-start (1+ (and (repeat 3 (any ">.")) " ")))) | 1243 | (rx line-start (1+ (and (or (repeat 3 (any ">.")) "(Pdb)") " ")))) |
| 1249 | (set (make-local-variable 'compilation-error-regexp-alist) | 1244 | (set (make-local-variable 'compilation-error-regexp-alist) |
| 1250 | python-compilation-regexp-alist) | 1245 | python-compilation-regexp-alist) |
| 1251 | (compilation-shell-minor-mode 1)) | 1246 | (compilation-shell-minor-mode 1)) |
| 1252 | 1247 | ||
| 1253 | (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" | 1248 | (defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" |
| 1254 | "Input matching this regexp is not saved on the history list. | 1249 | "*Input matching this regexp is not saved on the history list. |
| 1255 | Default ignores all inputs of 0, 1, or 2 non-blank characters." | 1250 | Default ignores all inputs of 0, 1, or 2 non-blank characters." |
| 1256 | :type 'regexp | 1251 | :type 'regexp |
| 1257 | :group 'python) | 1252 | :group 'python) |
| @@ -1274,57 +1269,46 @@ Don't save anything for STR matching `inferior-python-filter-regexp'." | |||
| 1274 | (defvar python-preoutput-result nil | 1269 | (defvar python-preoutput-result nil |
| 1275 | "Data from last `_emacs_out' line seen by the preoutput filter.") | 1270 | "Data from last `_emacs_out' line seen by the preoutput filter.") |
| 1276 | 1271 | ||
| 1272 | (defvar python-preoutput-continuation nil | ||
| 1273 | "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.") | ||
| 1274 | |||
| 1277 | (defvar python-preoutput-leftover nil) | 1275 | (defvar python-preoutput-leftover nil) |
| 1278 | (defvar python-preoutput-skip-next-prompt nil) | ||
| 1279 | 1276 | ||
| 1280 | ;; Using this stops us getting lines in the buffer like | 1277 | ;; Using this stops us getting lines in the buffer like |
| 1281 | ;; >>> ... ... >>> | 1278 | ;; >>> ... ... >>> |
| 1279 | ;; Also look for (and delete) an `_emacs_ok' string and call | ||
| 1280 | ;; `python-preoutput-continuation' if we get it. | ||
| 1282 | (defun python-preoutput-filter (s) | 1281 | (defun python-preoutput-filter (s) |
| 1283 | "`comint-preoutput-filter-functions' function: ignore prompts not at bol." | 1282 | "`comint-preoutput-filter-functions' function: ignore prompts not at bol." |
| 1284 | (when python-preoutput-leftover | 1283 | (when python-preoutput-leftover |
| 1285 | (setq s (concat python-preoutput-leftover s)) | 1284 | (setq s (concat python-preoutput-leftover s)) |
| 1286 | (setq python-preoutput-leftover nil)) | 1285 | (setq python-preoutput-leftover nil)) |
| 1287 | (let ((start 0) | 1286 | (cond ((and (string-match (rx string-start (repeat 3 (any ".>")) |
| 1288 | (res "")) | 1287 | " " string-end) |
| 1289 | ;; First process whole lines. | 1288 | s) |
| 1290 | (while (string-match "\n" s start) | 1289 | (/= (let ((inhibit-field-text-motion t)) |
| 1291 | (let ((line (substring s start (setq start (match-end 0))))) | 1290 | (line-beginning-position)) |
| 1292 | ;; Skip prompt if needed. | 1291 | (point))) |
| 1293 | (when (and python-preoutput-skip-next-prompt | 1292 | ;; The need for this seems to be system-dependent: |
| 1294 | (string-match comint-prompt-regexp line)) | 1293 | (if (and (eq ?. (aref s 0))) |
| 1295 | (setq python-preoutput-skip-next-prompt nil) | 1294 | (accept-process-output (get-buffer-process (current-buffer)) 1)) |
| 1296 | (setq line (substring line (match-end 0)))) | 1295 | "") |
| 1297 | ;; Recognize special _emacs_out lines. | 1296 | ((string= s "_emacs_ok\n") |
| 1298 | (if (and (string-match "\\`_emacs_out \\(.*\\)\n\\'" line) | 1297 | (when python-preoutput-continuation |
| 1299 | (local-variable-p 'python-preoutput-result)) | 1298 | (funcall python-preoutput-continuation) |
| 1300 | (progn | 1299 | (setq python-preoutput-continuation nil)) |
| 1301 | (setq python-preoutput-result (match-string 1 line)) | 1300 | "") |
| 1302 | (set (make-local-variable 'python-preoutput-skip-next-prompt) t)) | 1301 | ((string-match "_emacs_out \\(.*\\)\n" s) |
| 1303 | (setq res (concat res line))))) | 1302 | (setq python-preoutput-result (match-string 1 s)) |
| 1304 | ;; Then process the remaining partial line. | 1303 | "") |
| 1305 | (unless (zerop start) (setq s (substring s start))) | 1304 | ((string-match ".*\n" s) |
| 1306 | (cond ((and (string-match comint-prompt-regexp s) | 1305 | s) |
| 1307 | ;; Drop this prompt if it follows an _emacs_out... | 1306 | ((or (eq t (compare-strings s nil nil "_emacs_ok\n" nil (length s))) |
| 1308 | (or python-preoutput-skip-next-prompt | 1307 | (let ((end (min (length "_emacs_out ") (length s)))) |
| 1309 | ;; ... or if it's not gonna be inserted at BOL. | 1308 | (eq t (compare-strings s nil end "_emacs_out " nil end)))) |
| 1310 | ;; Maybe we could be more selective here. | 1309 | (setq python-preoutput-leftover s) |
| 1311 | (if (zerop (length res)) | 1310 | "") |
| 1312 | (not (bolp)) | 1311 | (t s))) |
| 1313 | (string-match ".\\'" res)))) | ||
| 1314 | ;; The need for this seems to be system-dependent: | ||
| 1315 | ;; What is this all about, exactly? --Stef | ||
| 1316 | ;; (if (and (eq ?. (aref s 0))) | ||
| 1317 | ;; (accept-process-output (get-buffer-process (current-buffer)) 1)) | ||
| 1318 | (setq python-preoutput-skip-next-prompt nil) | ||
| 1319 | res) | ||
| 1320 | ((let ((end (min (length "_emacs_out ") (length s)))) | ||
| 1321 | (eq t (compare-strings s nil end "_emacs_out " nil end))) | ||
| 1322 | ;; The leftover string is a prefix of _emacs_out so we don't know | ||
| 1323 | ;; yet whether it's an _emacs_out or something else: wait until we | ||
| 1324 | ;; get more output so we can resolve this ambiguity. | ||
| 1325 | (set (make-local-variable 'python-preoutput-leftover) s) | ||
| 1326 | res) | ||
| 1327 | (t (concat res s))))) | ||
| 1328 | 1312 | ||
| 1329 | (autoload 'comint-check-proc "comint") | 1313 | (autoload 'comint-check-proc "comint") |
| 1330 | 1314 | ||
| @@ -1354,59 +1338,48 @@ buffer for a list of commands.)" | |||
| 1354 | ;; (not a name) in Python buffers from which `run-python' &c is | 1338 | ;; (not a name) in Python buffers from which `run-python' &c is |
| 1355 | ;; invoked. Would support multiple processes better. | 1339 | ;; invoked. Would support multiple processes better. |
| 1356 | (when (or new (not (comint-check-proc python-buffer))) | 1340 | (when (or new (not (comint-check-proc python-buffer))) |
| 1357 | (with-current-buffer | 1341 | (save-current-buffer |
| 1358 | (let* ((cmdlist (append (python-args-to-list cmd) '("-i"))) | 1342 | (let* ((cmdlist (append (python-args-to-list cmd) '("-i"))) |
| 1359 | (path (getenv "PYTHONPATH")) | 1343 | (path (getenv "PYTHONPATH")) |
| 1360 | (process-environment ; to import emacs.py | 1344 | (process-environment ; to import emacs.py |
| 1361 | (cons (concat "PYTHONPATH=" data-directory | 1345 | (cons (concat "PYTHONPATH=" data-directory |
| 1362 | (if path (concat path-separator path))) | 1346 | (if path (concat ":" path))) |
| 1363 | process-environment))) | 1347 | process-environment))) |
| 1364 | (apply 'make-comint-in-buffer "Python" | 1348 | (set-buffer (apply 'make-comint-in-buffer "Python" |
| 1365 | (if new (generate-new-buffer "*Python*") "*Python*") | 1349 | (generate-new-buffer "*Python*") |
| 1366 | (car cmdlist) nil (cdr cmdlist))) | 1350 | (car cmdlist) nil (cdr cmdlist))) |
| 1367 | (setq-default python-buffer (current-buffer)) | 1351 | (setq-default python-buffer (current-buffer)) |
| 1368 | (setq python-buffer (current-buffer)) | 1352 | (setq python-buffer (current-buffer))) |
| 1369 | (accept-process-output (get-buffer-process python-buffer) 5) | 1353 | (accept-process-output (get-buffer-process python-buffer) 5) |
| 1370 | (inferior-python-mode) | 1354 | (inferior-python-mode))) |
| 1371 | ;; Load function definitions we need. | 1355 | (if (eq 'python-mode major-mode) |
| 1372 | ;; Before the preoutput function was used, this was done via -c in | ||
| 1373 | ;; cmdlist, but that loses the banner and doesn't run the startup | ||
| 1374 | ;; file. The code might be inline here, but there's enough that it | ||
| 1375 | ;; seems worth putting in a separate file, and it's probably cleaner | ||
| 1376 | ;; to put it in a module. | ||
| 1377 | ;; Ensure we're at a prompt before doing anything else. | ||
| 1378 | (python-send-receive "import emacs; print '_emacs_out ()'"))) | ||
| 1379 | (if (derived-mode-p 'python-mode) | ||
| 1380 | (setq python-buffer (default-value 'python-buffer))) ; buffer-local | 1356 | (setq python-buffer (default-value 'python-buffer))) ; buffer-local |
| 1357 | ;; Load function definitions we need. | ||
| 1358 | ;; Before the preoutput function was used, this was done via -c in | ||
| 1359 | ;; cmdlist, but that loses the banner and doesn't run the startup | ||
| 1360 | ;; file. The code might be inline here, but there's enough that it | ||
| 1361 | ;; seems worth putting in a separate file, and it's probably cleaner | ||
| 1362 | ;; to put it in a module. | ||
| 1363 | (python-send-string "import emacs") | ||
| 1364 | ;; Ensure we're at a prompt before doing anything else. | ||
| 1365 | (python-send-receive "print '_emacs_out ()'") | ||
| 1381 | ;; Without this, help output goes into the inferior python buffer if | 1366 | ;; Without this, help output goes into the inferior python buffer if |
| 1382 | ;; the process isn't already running. | 1367 | ;; the process isn't already running. |
| 1383 | (sit-for 1 t) ;Should we use accept-process-output instead? --Stef | 1368 | (sit-for 1 nil t) |
| 1384 | (unless noshow (pop-to-buffer python-buffer t))) | 1369 | (unless noshow (pop-to-buffer python-buffer t))) |
| 1385 | 1370 | ||
| 1386 | ;; Fixme: We typically lose if the inferior isn't in the normal REPL, | ||
| 1387 | ;; e.g. prompt is `help> '. Probably raise an error if the form of | ||
| 1388 | ;; the prompt is unexpected. Actually, it needs to be `>>> ', not | ||
| 1389 | ;; `... ', i.e. we're not inputting a block &c. However, this may not | ||
| 1390 | ;; be the place to check it, e.g. we might actually want to send | ||
| 1391 | ;; commands having set up such a state. | ||
| 1392 | |||
| 1393 | (defun python-send-command (command) | 1371 | (defun python-send-command (command) |
| 1394 | "Like `python-send-string' but resets `compilation-shell-minor-mode'. | 1372 | "Like `python-send-string' but resets `compilation-shell-minor-mode'." |
| 1395 | COMMAND should be a single statement." | 1373 | (when (python-check-comint-prompt) |
| 1396 | ;; (assert (not (string-match "\n" command))) | 1374 | (let ((end (marker-position (process-mark (python-proc))))) |
| 1397 | ;; (let ((end (marker-position (process-mark (python-proc))))) | 1375 | (with-current-buffer python-buffer (goto-char (point-max))) |
| 1398 | (with-current-buffer (process-buffer (python-proc)) | 1376 | (compilation-forget-errors) |
| 1399 | (goto-char (point-max)) | 1377 | (python-send-string command) |
| 1400 | (compilation-forget-errors) | 1378 | ;; Must wait until this has completed before re-setting variables below. |
| 1401 | (python-send-string command) | 1379 | (python-send-receive "print '_emacs_out ()'") |
| 1402 | (setq compilation-last-buffer (current-buffer))) | 1380 | (with-current-buffer python-buffer |
| 1403 | ;; No idea what this is for but it breaks the call to | 1381 | (set-marker compilation-parsing-end end) |
| 1404 | ;; compilation-fake-loc in python-send-region. -- Stef | 1382 | (setq compilation-last-buffer (current-buffer)))))) |
| 1405 | ;; Must wait until this has completed before re-setting variables below. | ||
| 1406 | ;; (python-send-receive "print '_emacs_out ()'") | ||
| 1407 | ;; (with-current-buffer python-buffer | ||
| 1408 | ;; (set-marker compilation-parsing-end end)) | ||
| 1409 | ) ;;) | ||
| 1410 | 1383 | ||
| 1411 | (defun python-send-region (start end) | 1384 | (defun python-send-region (start end) |
| 1412 | "Send the region to the inferior Python process." | 1385 | "Send the region to the inferior Python process." |
| @@ -1448,13 +1421,7 @@ COMMAND should be a single statement." | |||
| 1448 | "Evaluate STRING in inferior Python process." | 1421 | "Evaluate STRING in inferior Python process." |
| 1449 | (interactive "sPython command: ") | 1422 | (interactive "sPython command: ") |
| 1450 | (comint-send-string (python-proc) string) | 1423 | (comint-send-string (python-proc) string) |
| 1451 | (unless (string-match "\n\\'" string) | 1424 | (comint-send-string (python-proc) "\n\n")) |
| 1452 | ;; Make sure the text is properly LF-terminated. | ||
| 1453 | (comint-send-string (python-proc) "\n")) | ||
| 1454 | (when (string-match "\n[ \t].*\n?\\'" string) | ||
| 1455 | ;; If the string contains a final indented line, add a second newline so | ||
| 1456 | ;; as to make sure we terminate the multiline instruction. | ||
| 1457 | (comint-send-string (python-proc) "\n"))) | ||
| 1458 | 1425 | ||
| 1459 | (defun python-send-buffer () | 1426 | (defun python-send-buffer () |
| 1460 | "Send the current buffer to the inferior Python process." | 1427 | "Send the current buffer to the inferior Python process." |
| @@ -1486,7 +1453,7 @@ Then switch to the process buffer." | |||
| 1486 | (python-switch-to-python t)) | 1453 | (python-switch-to-python t)) |
| 1487 | 1454 | ||
| 1488 | (defcustom python-source-modes '(python-mode jython-mode) | 1455 | (defcustom python-source-modes '(python-mode jython-mode) |
| 1489 | "Used to determine if a buffer contains Python source code. | 1456 | "*Used to determine if a buffer contains Python source code. |
| 1490 | If a file is loaded into a buffer that is in one of these major modes, | 1457 | If a file is loaded into a buffer that is in one of these major modes, |
| 1491 | it is considered Python source by `python-load-file', which uses the | 1458 | it is considered Python source by `python-load-file', which uses the |
| 1492 | value to determine defaults." | 1459 | value to determine defaults." |
| @@ -1529,9 +1496,9 @@ See variable `python-buffer'. Starts a new process if necessary." | |||
| 1529 | ;; isn't one for `python-buffer'. | 1496 | ;; isn't one for `python-buffer'. |
| 1530 | (unless (comint-check-proc python-buffer) | 1497 | (unless (comint-check-proc python-buffer) |
| 1531 | (run-python nil t)) | 1498 | (run-python nil t)) |
| 1532 | (get-buffer-process (if (derived-mode-p 'inferior-python-mode) | 1499 | (get-buffer-process (or (if (eq major-mode 'inferior-python-mode) |
| 1533 | (current-buffer) | 1500 | (current-buffer) |
| 1534 | python-buffer))) | 1501 | python-buffer)))) |
| 1535 | 1502 | ||
| 1536 | (defun python-set-proc () | 1503 | (defun python-set-proc () |
| 1537 | "Set the default value of `python-buffer' to correspond to this buffer. | 1504 | "Set the default value of `python-buffer' to correspond to this buffer. |
| @@ -1547,15 +1514,14 @@ in a buffer that doesn't have a local value of `python-buffer'." | |||
| 1547 | ;;;; Context-sensitive help. | 1514 | ;;;; Context-sensitive help. |
| 1548 | 1515 | ||
| 1549 | (defconst python-dotty-syntax-table | 1516 | (defconst python-dotty-syntax-table |
| 1550 | (let ((table (make-syntax-table))) | 1517 | (let ((table (copy-syntax-table python-mode-syntax-table))) |
| 1551 | (set-char-table-parent table python-mode-syntax-table) | ||
| 1552 | (modify-syntax-entry ?. "_" table) | 1518 | (modify-syntax-entry ?. "_" table) |
| 1553 | table) | 1519 | table) |
| 1554 | "Syntax table giving `.' symbol syntax. | 1520 | "Syntax table giving `.' symbol syntax. |
| 1555 | Otherwise inherits from `python-mode-syntax-table'.") | 1521 | Otherwise inherits from `python-mode-syntax-table'.") |
| 1556 | 1522 | ||
| 1557 | (defvar view-return-to-alist) | 1523 | (defvar view-return-to-alist) |
| 1558 | (eval-when-compile (autoload 'help-buffer "help-fns")) | 1524 | (autoload 'help-buffer "help-fns") |
| 1559 | 1525 | ||
| 1560 | (defvar python-imports) ; forward declaration | 1526 | (defvar python-imports) ; forward declaration |
| 1561 | 1527 | ||
| @@ -1606,16 +1572,31 @@ will." | |||
| 1606 | 1572 | ||
| 1607 | (defun python-send-receive (string) | 1573 | (defun python-send-receive (string) |
| 1608 | "Send STRING to inferior Python (if any) and return result. | 1574 | "Send STRING to inferior Python (if any) and return result. |
| 1609 | The result is what follows `_emacs_out' in the output." | 1575 | The result is what follows `_emacs_out' in the output (or nil). |
| 1610 | (python-send-string string) | 1576 | This is a no-op if `python-check-comint-prompt' returns ni." |
| 1611 | (let ((proc (python-proc))) | 1577 | (let ((proc (python-proc))) |
| 1612 | (with-current-buffer (process-buffer proc) | 1578 | (when (python-check-comint-prompt proc) |
| 1613 | (set (make-local-variable 'python-preoutput-result) nil) | 1579 | ;; We typically lose if the inferior isn't in the normal REPL, |
| 1580 | ;; e.g. prompt is `help> ' or `(Pdb)'. It actually needs to be | ||
| 1581 | ;; `>>> ', not `... ', i.e. we're not inputting a block &c. | ||
| 1582 | ;; This may not be the place to check it, e.g. we might actually | ||
| 1583 | ;; want to send commands having set up such a state, but | ||
| 1584 | ;; currently it's OK for all uses. | ||
| 1585 | (python-send-string string) | ||
| 1586 | (setq python-preoutput-result nil) | ||
| 1614 | (while (progn | 1587 | (while (progn |
| 1615 | (accept-process-output proc 5) | 1588 | (accept-process-output proc 5) |
| 1616 | (null python-preoutput-result))) | 1589 | python-preoutput-leftover)) |
| 1617 | (prog1 python-preoutput-result | 1590 | python-preoutput-result))) |
| 1618 | (kill-local-variable 'python-preoutput-result))))) | 1591 | |
| 1592 | (defun python-check-comint-prompt (&optional proc) | ||
| 1593 | "Return non-nil iff there's a normal prompt in the inferior buffer. | ||
| 1594 | If there isn't, it's probably not appropriate to send input to return | ||
| 1595 | Eldoc information etc. If PROC is non-nil, check the buffer for that | ||
| 1596 | process." | ||
| 1597 | (with-current-buffer (process-buffer (or proc (python-proc))) | ||
| 1598 | (save-excursion | ||
| 1599 | (save-match-data (re-search-backward ">>> \\=" nil t))))) | ||
| 1619 | 1600 | ||
| 1620 | ;; Fixme: Is there anything reasonable we can do with random methods? | 1601 | ;; Fixme: Is there anything reasonable we can do with random methods? |
| 1621 | ;; (Currently only works with functions.) | 1602 | ;; (Currently only works with functions.) |
| @@ -1625,29 +1606,30 @@ Only works when point is in a function name, not its arg list, for | |||
| 1625 | instance. Assumes an inferior Python is running." | 1606 | instance. Assumes an inferior Python is running." |
| 1626 | (let ((symbol (with-syntax-table python-dotty-syntax-table | 1607 | (let ((symbol (with-syntax-table python-dotty-syntax-table |
| 1627 | (current-word)))) | 1608 | (current-word)))) |
| 1628 | ;; This is run from timers, so inhibit-quit tends to be set. | 1609 | ;; First try the symbol we're on. |
| 1629 | (with-local-quit | 1610 | (or (and symbol |
| 1630 | ;; First try the symbol we're on. | 1611 | (python-send-receive (format "emacs.eargs(%S, %s)" |
| 1631 | (or (and symbol | 1612 | symbol python-imports))) |
| 1632 | (python-send-receive (format "emacs.eargs(%S, %s)" | 1613 | ;; Try moving to symbol before enclosing parens. |
| 1633 | symbol python-imports))) | 1614 | (let ((s (syntax-ppss))) |
| 1634 | ;; Try moving to symbol before enclosing parens. | 1615 | (unless (zerop (car s)) |
| 1635 | (let ((s (syntax-ppss))) | 1616 | (when (eq ?\( (char-after (nth 1 s))) |
| 1636 | (unless (zerop (car s)) | 1617 | (save-excursion |
| 1637 | (when (eq ?\( (char-after (nth 1 s))) | 1618 | (goto-char (nth 1 s)) |
| 1638 | (save-excursion | 1619 | (skip-syntax-backward "-") |
| 1639 | (goto-char (nth 1 s)) | 1620 | (let ((point (point))) |
| 1640 | (skip-syntax-backward "-") | 1621 | (skip-chars-backward "a-zA-Z._") |
| 1641 | (let ((point (point))) | 1622 | (if (< (point) point) |
| 1642 | (skip-chars-backward "a-zA-Z._") | 1623 | (python-send-receive |
| 1643 | (if (< (point) point) | 1624 | (format "emacs.eargs(%S, %s)" |
| 1644 | (python-send-receive | 1625 | (buffer-substring-no-properties (point) point) |
| 1645 | (format "emacs.eargs(%S, %s)" | 1626 | python-imports))))))))))) |
| 1646 | (buffer-substring-no-properties (point) point) | ||
| 1647 | python-imports)))))))))))) | ||
| 1648 | 1627 | ||
| 1649 | ;;;; Info-look functionality. | 1628 | ;;;; Info-look functionality. |
| 1650 | 1629 | ||
| 1630 | (eval-when-compile | ||
| 1631 | (autoload 'Info-goto-node "info")) | ||
| 1632 | |||
| 1651 | (defun python-after-info-look () | 1633 | (defun python-after-info-look () |
| 1652 | "Set up info-look for Python. | 1634 | "Set up info-look for Python. |
| 1653 | Used with `eval-after-load'." | 1635 | Used with `eval-after-load'." |
| @@ -1658,13 +1640,12 @@ Used with `eval-after-load'." | |||
| 1658 | ;; Whether info files have a Python version suffix, e.g. in Debian. | 1640 | ;; Whether info files have a Python version suffix, e.g. in Debian. |
| 1659 | (versioned | 1641 | (versioned |
| 1660 | (with-temp-buffer | 1642 | (with-temp-buffer |
| 1661 | (with-no-warnings (Info-mode)) | 1643 | (Info-mode) |
| 1662 | (condition-case () | 1644 | (condition-case () |
| 1663 | ;; Don't use `info' because it would pop-up a *info* buffer. | 1645 | ;; Don't use `info' because it would pop-up a *info* buffer. |
| 1664 | (with-no-warnings | 1646 | (progn (Info-goto-node (format "(python%s-lib)Miscellaneous Index" |
| 1665 | (Info-goto-node (format "(python%s-lib)Miscellaneous Index" | 1647 | version)) |
| 1666 | version)) | 1648 | t) |
| 1667 | t) | ||
| 1668 | (error nil))))) | 1649 | (error nil))))) |
| 1669 | (info-lookup-maybe-add-help | 1650 | (info-lookup-maybe-add-help |
| 1670 | :mode 'python-mode | 1651 | :mode 'python-mode |
| @@ -1737,47 +1718,57 @@ The criterion is either a match for `jython-mode' via | |||
| 1737 | (jython-mode))))))) | 1718 | (jython-mode))))))) |
| 1738 | 1719 | ||
| 1739 | (defun python-fill-paragraph (&optional justify) | 1720 | (defun python-fill-paragraph (&optional justify) |
| 1740 | "`fill-paragraph-function' handling comments and multi-line strings. | 1721 | "`fill-paragraph-function' handling multi-line strings and possibly comments. |
| 1741 | If any of the current line is a comment, fill the comment or the | 1722 | If any of the current line is in or at the end of a multi-line string, |
| 1742 | paragraph of it that point is in, preserving the comment's | 1723 | fill the string or the paragraph of it that point is in, preserving |
| 1743 | indentation and initial comment characters. Similarly if the end | 1724 | the strings's indentation." |
| 1744 | of the current line is in or at the end of a multi-line string. | ||
| 1745 | Otherwise, do nothing." | ||
| 1746 | (interactive "P") | 1725 | (interactive "P") |
| 1747 | (or (fill-comment-paragraph justify) | 1726 | (or (fill-comment-paragraph justify) |
| 1748 | ;; The `paragraph-start' and `paragraph-separate' variables | ||
| 1749 | ;; don't allow us to delimit the last paragraph in a multi-line | ||
| 1750 | ;; string properly, so narrow to the string and then fill around | ||
| 1751 | ;; (the end of) the current line. | ||
| 1752 | (save-excursion | 1727 | (save-excursion |
| 1753 | (end-of-line) | 1728 | (end-of-line) |
| 1754 | (let* ((syntax (syntax-ppss)) | 1729 | (let* ((syntax (syntax-ppss)) |
| 1755 | (orig (point)) | 1730 | (orig (point)) |
| 1756 | (start (nth 8 syntax)) | 1731 | start end) |
| 1757 | end) | 1732 | (cond ((nth 4 syntax) ; comment. fixme: loses with trailing one |
| 1758 | (cond ((eq t (nth 3 syntax)) ; in fenced string | 1733 | (let (fill-paragraph-function) |
| 1759 | (goto-char (nth 8 syntax)) ; string start | 1734 | (fill-paragraph justify))) |
| 1760 | (setq end (condition-case () ; for unbalanced quotes | 1735 | ;; The `paragraph-start' and `paragraph-separate' |
| 1761 | (progn (forward-sexp) (point)) | 1736 | ;; variables don't allow us to delimit the last |
| 1762 | (error (point-max))))) | 1737 | ;; paragraph in a multi-line string properly, so narrow |
| 1763 | ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced | 1738 | ;; to the string and then fill around (the end of) the |
| 1764 | ; string | 1739 | ;; current line. |
| 1740 | ((eq t (nth 3 syntax)) ; in fenced string | ||
| 1741 | (goto-char (nth 8 syntax)) ; string start | ||
| 1742 | (setq start (line-beginning-position)) | ||
| 1743 | (condition-case () ; for unbalanced quotes | ||
| 1744 | (progn (forward-sexp) | ||
| 1745 | (setq end (- (point) 3))) | ||
| 1746 | (error (setq end (point-max))))) | ||
| 1747 | ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced string | ||
| 1765 | (forward-char) | 1748 | (forward-char) |
| 1766 | (setq end (point)) | 1749 | (setq end (point)) |
| 1767 | (condition-case () | 1750 | (condition-case () |
| 1768 | (progn (backward-sexp) | 1751 | (progn (backward-sexp) |
| 1769 | (setq start (point))) | 1752 | (setq start (line-beginning-position))) |
| 1770 | (error (setq end nil))))) | 1753 | (error nil)))) |
| 1771 | (when end | 1754 | (when end |
| 1772 | (save-restriction | 1755 | (save-restriction |
| 1773 | (narrow-to-region start end) | 1756 | (narrow-to-region start end) |
| 1774 | (goto-char orig) | 1757 | (goto-char orig) |
| 1775 | (let ((paragraph-separate | 1758 | ;; Avoid losing leading and trailing newlines in doc |
| 1776 | ;; Make sure that fenced-string delimiters that stand | 1759 | ;; strings written like: |
| 1777 | ;; on their own line stay there. | 1760 | ;; """ |
| 1778 | (concat "[ \t]*['\"]+[ \t]*$\\|" paragraph-separate))) | 1761 | ;; ... |
| 1779 | (fill-paragraph justify)))))) | 1762 | ;; """ |
| 1780 | t)) | 1763 | (let* ((paragraph-separate |
| 1764 | (concat ".*\\s|\"\"$" ; newline after opening quotes | ||
| 1765 | "\\|\\(?:" paragraph-separate "\\)")) | ||
| 1766 | (paragraph-start | ||
| 1767 | (concat ".*\\s|\"\"[ \t]*[^ \t].*" ; not newline after | ||
| 1768 | ; opening quotes | ||
| 1769 | "\\|\\(?:" paragraph-separate "\\)")) | ||
| 1770 | (fill-paragraph-function)) | ||
| 1771 | (fill-paragraph justify))))))) t) | ||
| 1781 | 1772 | ||
| 1782 | (defun python-shift-left (start end &optional count) | 1773 | (defun python-shift-left (start end &optional count) |
| 1783 | "Shift lines in region COUNT (the prefix arg) columns to the left. | 1774 | "Shift lines in region COUNT (the prefix arg) columns to the left. |
| @@ -1823,34 +1814,22 @@ of current line." | |||
| 1823 | (1+ (/ (current-indentation) python-indent))) | 1814 | (1+ (/ (current-indentation) python-indent))) |
| 1824 | 1815 | ||
| 1825 | ;; Fixme: Consider top-level assignments, imports, &c. | 1816 | ;; Fixme: Consider top-level assignments, imports, &c. |
| 1826 | (defun python-current-defun (&optional length-limit) | 1817 | (defun python-current-defun () |
| 1827 | "`add-log-current-defun-function' for Python." | 1818 | "`add-log-current-defun-function' for Python." |
| 1828 | (save-excursion | 1819 | (save-excursion |
| 1829 | ;; Move up the tree of nested `class' and `def' blocks until we | 1820 | ;; Move up the tree of nested `class' and `def' blocks until we |
| 1830 | ;; get to zero indentation, accumulating the defined names. | 1821 | ;; get to zero indentation, accumulating the defined names. |
| 1831 | (let ((accum) | 1822 | (let ((start t) |
| 1832 | (length -1)) | 1823 | accum) |
| 1833 | (catch 'done | 1824 | (while (or start (> (current-indentation) 0)) |
| 1834 | (while (or (null length-limit) | 1825 | (setq start nil) |
| 1835 | (null (cdr accum)) | 1826 | (python-beginning-of-block) |
| 1836 | (< length length-limit)) | 1827 | (end-of-line) |
| 1837 | (setq start nil) | 1828 | (beginning-of-defun) |
| 1838 | (let ((started-from (point))) | 1829 | (if (looking-at (rx (0+ space) (or "def" "class") (1+ space) |
| 1839 | (python-beginning-of-block) | 1830 | (group (1+ (or word (syntax symbol)))))) |
| 1840 | (end-of-line) | 1831 | (push (match-string 1) accum))) |
| 1841 | (beginning-of-defun) | 1832 | (if accum (mapconcat 'identity accum "."))))) |
| 1842 | (when (= (point) started-from) | ||
| 1843 | (throw 'done nil))) | ||
| 1844 | (when (looking-at (rx (0+ space) (or "def" "class") (1+ space) | ||
| 1845 | (group (1+ (or word (syntax symbol)))))) | ||
| 1846 | (push (match-string 1) accum) | ||
| 1847 | (setq length (+ length 1 (length (car accum))))) | ||
| 1848 | (when (= (current-indentation) 0) | ||
| 1849 | (throw 'done nil)))) | ||
| 1850 | (when accum | ||
| 1851 | (when (and length-limit (> length length-limit)) | ||
| 1852 | (setcar accum "..")) | ||
| 1853 | (mapconcat 'identity accum "."))))) | ||
| 1854 | 1833 | ||
| 1855 | (defun python-mark-block () | 1834 | (defun python-mark-block () |
| 1856 | "Mark the block around point. | 1835 | "Mark the block around point. |
| @@ -1939,60 +1918,6 @@ Uses `python-imports' to load modules against which to complete." | |||
| 1939 | nil t) | 1918 | nil t) |
| 1940 | (match-beginning 1))))) | 1919 | (match-beginning 1))))) |
| 1941 | (if start (buffer-substring-no-properties start end)))) | 1920 | (if start (buffer-substring-no-properties start end)))) |
| 1942 | |||
| 1943 | (defun python-complete-symbol () | ||
| 1944 | "Perform completion on the Python symbol preceding point. | ||
| 1945 | Repeating the command scrolls the completion window." | ||
| 1946 | (interactive) | ||
| 1947 | (let ((window (get-buffer-window "*Completions*"))) | ||
| 1948 | (if (and (eq last-command this-command) | ||
| 1949 | (window-live-p window) (window-buffer window) | ||
| 1950 | (buffer-name (window-buffer window))) | ||
| 1951 | (with-current-buffer (window-buffer window) | ||
| 1952 | (if (pos-visible-in-window-p (point-max) window) | ||
| 1953 | (set-window-start window (point-min)) | ||
| 1954 | (save-selected-window | ||
| 1955 | (select-window window) | ||
| 1956 | (scroll-up)))) | ||
| 1957 | ;; Do completion. | ||
| 1958 | (let* ((end (point)) | ||
| 1959 | (symbol (python-partial-symbol)) | ||
| 1960 | (completions (python-symbol-completions symbol)) | ||
| 1961 | (completion (if completions | ||
| 1962 | (try-completion symbol completions)))) | ||
| 1963 | (when symbol | ||
| 1964 | (cond ((eq completion t)) | ||
| 1965 | ((null completion) | ||
| 1966 | (message "Can't find completion for \"%s\"" symbol) | ||
| 1967 | (ding)) | ||
| 1968 | ((not (string= symbol completion)) | ||
| 1969 | (delete-region (- end (length symbol)) end) | ||
| 1970 | (insert completion)) | ||
| 1971 | (t | ||
| 1972 | (message "Making completion list...") | ||
| 1973 | (with-output-to-temp-buffer "*Completions*" | ||
| 1974 | (display-completion-list completions symbol)) | ||
| 1975 | (message "Making completion list...%s" "done")))))))) | ||
| 1976 | |||
| 1977 | (defun python-try-complete (old) | ||
| 1978 | "Completion function for Python for use with `hippie-expand'." | ||
| 1979 | (when (derived-mode-p 'python-mode) ; though we only add it locally | ||
| 1980 | (unless old | ||
| 1981 | (let ((symbol (python-partial-symbol))) | ||
| 1982 | (he-init-string (- (point) (length symbol)) (point)) | ||
| 1983 | (if (not (he-string-member he-search-string he-tried-table)) | ||
| 1984 | (push he-search-string he-tried-table)) | ||
| 1985 | (setq he-expand-list | ||
| 1986 | (and symbol (python-symbol-completions symbol))))) | ||
| 1987 | (while (and he-expand-list | ||
| 1988 | (he-string-member (car he-expand-list) he-tried-table)) | ||
| 1989 | (pop he-expand-list)) | ||
| 1990 | (if he-expand-list | ||
| 1991 | (progn | ||
| 1992 | (he-substitute-string (pop he-expand-list)) | ||
| 1993 | t) | ||
| 1994 | (if old (he-reset-string)) | ||
| 1995 | nil))) | ||
| 1996 | 1921 | ||
| 1997 | ;;;; FFAP support | 1922 | ;;;; FFAP support |
| 1998 | 1923 | ||
| @@ -2005,13 +1930,6 @@ Repeating the command scrolls the completion window." | |||
| 2005 | 1930 | ||
| 2006 | ;;;; Skeletons | 1931 | ;;;; Skeletons |
| 2007 | 1932 | ||
| 2008 | (defcustom python-use-skeletons nil | ||
| 2009 | "Non-nil means template skeletons will be automagically inserted. | ||
| 2010 | This happens when pressing \"if<SPACE>\", for example, to prompt for | ||
| 2011 | the if condition." | ||
| 2012 | :type 'boolean | ||
| 2013 | :group 'python) | ||
| 2014 | |||
| 2015 | (defvar python-skeletons nil | 1933 | (defvar python-skeletons nil |
| 2016 | "Alist of named skeletons for Python mode. | 1934 | "Alist of named skeletons for Python mode. |
| 2017 | Elements are of the form (NAME . EXPANDER-FUNCTION).") | 1935 | Elements are of the form (NAME . EXPANDER-FUNCTION).") |
| @@ -2029,8 +1947,7 @@ The default contents correspond to the elements of `python-skeletons'.") | |||
| 2029 | (function (intern (concat "python-insert-" name)))) | 1947 | (function (intern (concat "python-insert-" name)))) |
| 2030 | `(progn | 1948 | `(progn |
| 2031 | (add-to-list 'python-skeletons ',(cons name function)) | 1949 | (add-to-list 'python-skeletons ',(cons name function)) |
| 2032 | (if python-use-skeletons | 1950 | (define-abbrev python-mode-abbrev-table ,name "" ',function nil t) |
| 2033 | (define-abbrev python-mode-abbrev-table ,name "" ',function nil t)) | ||
| 2034 | (define-skeleton ,function | 1951 | (define-skeleton ,function |
| 2035 | ,(format "Insert Python \"%s\" template." name) | 1952 | ,(format "Insert Python \"%s\" template." name) |
| 2036 | ,@elements))))) | 1953 | ,@elements))))) |
| @@ -2112,7 +2029,7 @@ The default contents correspond to the elements of `python-skeletons'.") | |||
| 2112 | > _ \n) | 2029 | > _ \n) |
| 2113 | 2030 | ||
| 2114 | (defvar python-default-template "if" | 2031 | (defvar python-default-template "if" |
| 2115 | "Default template to expand by `python-expand-template'. | 2032 | "Default template to expand by `python-insert-template'. |
| 2116 | Updated on each expansion.") | 2033 | Updated on each expansion.") |
| 2117 | 2034 | ||
| 2118 | (defun python-expand-template (name) | 2035 | (defun python-expand-template (name) |
| @@ -2151,40 +2068,41 @@ without confirmation." | |||
| 2151 | (pymacs-load "bikeemacs" "brm-") ; first line of normal recipe | 2068 | (pymacs-load "bikeemacs" "brm-") ; first line of normal recipe |
| 2152 | (let ((py-mode-map (make-sparse-keymap)) ; it assumes this | 2069 | (let ((py-mode-map (make-sparse-keymap)) ; it assumes this |
| 2153 | (features (cons 'python-mode features))) ; and requires this | 2070 | (features (cons 'python-mode features))) ; and requires this |
| 2154 | (brm-init)) ; second line of normal recipe | 2071 | (brm-init) ; second line of normal recipe |
| 2155 | (remove-hook 'python-mode-hook ; undo this from `brm-init' | 2072 | (remove-hook 'python-mode-hook ; undo this from `brm-init' |
| 2156 | '(lambda () (easy-menu-add brm-menu))) | 2073 | '(lambda () (easy-menu-add brm-menu))) |
| 2157 | (easy-menu-define | 2074 | (easy-menu-define |
| 2158 | python-brm-menu python-mode-map | 2075 | python-brm-menu python-mode-map |
| 2159 | "Bicycle Repair Man" | 2076 | "Bicycle Repair Man" |
| 2160 | '("BicycleRepairMan" | 2077 | '("BicycleRepairMan" |
| 2161 | :help "Interface to navigation and refactoring tool" | 2078 | :help "Interface to navigation and refactoring tool" |
| 2162 | "Queries" | 2079 | "Queries" |
| 2163 | ["Find References" brm-find-references | 2080 | ["Find References" brm-find-references |
| 2164 | :help "Find references to name at point in compilation buffer"] | 2081 | :help "Find references to name at point in compilation buffer"] |
| 2165 | ["Find Definition" brm-find-definition | 2082 | ["Find Definition" brm-find-definition |
| 2166 | :help "Find definition of name at point"] | 2083 | :help "Find definition of name at point"] |
| 2167 | "-" | 2084 | "-" |
| 2168 | "Refactoring" | 2085 | "Refactoring" |
| 2169 | ["Rename" brm-rename | 2086 | ["Rename" brm-rename |
| 2170 | :help "Replace name at point with a new name everywhere"] | 2087 | :help "Replace name at point with a new name everywhere"] |
| 2171 | ["Extract Method" brm-extract-method | 2088 | ["Extract Method" brm-extract-method |
| 2172 | :active (and mark-active (not buffer-read-only)) | 2089 | :active (and mark-active (not buffer-read-only)) |
| 2173 | :help "Replace statements in region with a method"] | 2090 | :help "Replace statements in region with a method"] |
| 2174 | ["Extract Local Variable" brm-extract-local-variable | 2091 | ["Extract Local Variable" brm-extract-local-variable |
| 2175 | :active (and mark-active (not buffer-read-only)) | 2092 | :active (and mark-active (not buffer-read-only)) |
| 2176 | :help "Replace expression in region with an assignment"] | 2093 | :help "Replace expression in region with an assignment"] |
| 2177 | ["Inline Local Variable" brm-inline-local-variable | 2094 | ["Inline Local Variable" brm-inline-local-variable |
| 2178 | :help | 2095 | :help |
| 2179 | "Substitute uses of variable at point with its definition"] | 2096 | "Substitute uses of variable at point with its definition"] |
| 2180 | ;; Fixme: Should check for anything to revert. | 2097 | ;; Fixme: Should check for anything to revert. |
| 2181 | ["Undo Last Refactoring" brm-undo :help ""]))) | 2098 | ["Undo Last Refactoring" brm-undo :help ""])))) |
| 2182 | (error (error "Bicyclerepairman setup failed: %s" data)))) | 2099 | (error (error "Bicyclerepairman setup failed: %s" data)))) |
| 2183 | 2100 | ||
| 2184 | ;;;; Modes. | 2101 | ;;;; Modes. |
| 2185 | 2102 | ||
| 2186 | (defvar outline-heading-end-regexp) | 2103 | (defvar outline-heading-end-regexp) |
| 2187 | (defvar eldoc-documentation-function) | 2104 | (defvar eldoc-documentation-function) |
| 2105 | (autoload 'symbol-completion-try-complete "sym-comp") | ||
| 2188 | 2106 | ||
| 2189 | ;; Stuff to allow expanding abbrevs with non-word constituents. | 2107 | ;; Stuff to allow expanding abbrevs with non-word constituents. |
| 2190 | (defun python-abbrev-pc-hook () | 2108 | (defun python-abbrev-pc-hook () |
| @@ -2202,12 +2120,11 @@ without confirmation." | |||
| 2202 | (add-hook 'post-command-hook 'python-abbrev-pc-hook nil t)) | 2120 | (add-hook 'post-command-hook 'python-abbrev-pc-hook nil t)) |
| 2203 | (modify-syntax-entry ?/ "w" python-abbrev-syntax-table) | 2121 | (modify-syntax-entry ?/ "w" python-abbrev-syntax-table) |
| 2204 | 2122 | ||
| 2205 | (defvar python-mode-running) ;Dynamically scoped var. | ||
| 2206 | |||
| 2207 | ;;;###autoload | 2123 | ;;;###autoload |
| 2208 | (define-derived-mode python-mode fundamental-mode "Python" | 2124 | (define-derived-mode python-mode fundamental-mode "Python" |
| 2209 | "Major mode for editing Python files. | 2125 | "Major mode for editing Python files. |
| 2210 | Font Lock mode is currently required for correct parsing of the source. | 2126 | Turns on Font Lock mode unconditionally since it is currently required |
| 2127 | for correct parsing of the source. | ||
| 2211 | See also `jython-mode', which is actually invoked if the buffer appears to | 2128 | See also `jython-mode', which is actually invoked if the buffer appears to |
| 2212 | contain Jython code. See also `run-python' and associated Python mode | 2129 | contain Jython code. See also `run-python' and associated Python mode |
| 2213 | commands for running Python under Emacs. | 2130 | commands for running Python under Emacs. |
| @@ -2249,7 +2166,6 @@ with skeleton expansions for compound statement templates. | |||
| 2249 | ;; . python-font-lock-syntactic-face-function) | 2166 | ;; . python-font-lock-syntactic-face-function) |
| 2250 | )) | 2167 | )) |
| 2251 | (set (make-local-variable 'parse-sexp-lookup-properties) t) | 2168 | (set (make-local-variable 'parse-sexp-lookup-properties) t) |
| 2252 | (set (make-local-variable 'parse-sexp-ignore-comments) t) | ||
| 2253 | (set (make-local-variable 'comment-start) "# ") | 2169 | (set (make-local-variable 'comment-start) "# ") |
| 2254 | (set (make-local-variable 'indent-line-function) #'python-indent-line) | 2170 | (set (make-local-variable 'indent-line-function) #'python-indent-line) |
| 2255 | (set (make-local-variable 'indent-region-function) #'python-indent-region) | 2171 | (set (make-local-variable 'indent-region-function) #'python-indent-region) |
| @@ -2260,7 +2176,7 @@ with skeleton expansions for compound statement templates. | |||
| 2260 | #'python-current-defun) | 2176 | #'python-current-defun) |
| 2261 | (set (make-local-variable 'outline-regexp) | 2177 | (set (make-local-variable 'outline-regexp) |
| 2262 | (rx (* space) (or "class" "def" "elif" "else" "except" "finally" | 2178 | (rx (* space) (or "class" "def" "elif" "else" "except" "finally" |
| 2263 | "for" "if" "try" "while" "with") | 2179 | "for" "if" "try" "while") |
| 2264 | symbol-end)) | 2180 | symbol-end)) |
| 2265 | (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n") | 2181 | (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n") |
| 2266 | (set (make-local-variable 'outline-level) #'python-outline-level) | 2182 | (set (make-local-variable 'outline-level) #'python-outline-level) |
| @@ -2269,18 +2185,21 @@ with skeleton expansions for compound statement templates. | |||
| 2269 | (set (make-local-variable 'beginning-of-defun-function) | 2185 | (set (make-local-variable 'beginning-of-defun-function) |
| 2270 | 'python-beginning-of-defun) | 2186 | 'python-beginning-of-defun) |
| 2271 | (set (make-local-variable 'end-of-defun-function) 'python-end-of-defun) | 2187 | (set (make-local-variable 'end-of-defun-function) 'python-end-of-defun) |
| 2272 | (add-hook 'which-func-functions 'python-which-func nil t) | ||
| 2273 | (setq imenu-create-index-function #'python-imenu-create-index) | 2188 | (setq imenu-create-index-function #'python-imenu-create-index) |
| 2274 | (set (make-local-variable 'eldoc-documentation-function) | 2189 | (set (make-local-variable 'eldoc-documentation-function) |
| 2275 | #'python-eldoc-function) | 2190 | #'python-eldoc-function) |
| 2276 | (add-hook 'eldoc-mode-hook | 2191 | (add-hook 'eldoc-mode-hook |
| 2277 | (lambda () (run-python nil t)) ; need it running | 2192 | '(lambda () (run-python nil t)) ; need it running |
| 2278 | nil t) | 2193 | nil t) |
| 2194 | (set (make-local-variable 'symbol-completion-symbol-function) | ||
| 2195 | 'python-partial-symbol) | ||
| 2196 | (set (make-local-variable 'symbol-completion-completions-function) | ||
| 2197 | 'python-symbol-completions) | ||
| 2279 | ;; Fixme: should be in hideshow. This seems to be of limited use | 2198 | ;; Fixme: should be in hideshow. This seems to be of limited use |
| 2280 | ;; since it isn't (can't be) indentation-based. Also hide-level | 2199 | ;; since it isn't (can't be) indentation-based. Also hide-level |
| 2281 | ;; doesn't seem to work properly. | 2200 | ;; doesn't seem to work properly. |
| 2282 | (add-to-list 'hs-special-modes-alist | 2201 | (add-to-list 'hs-special-modes-alist |
| 2283 | `(python-mode "^\\s-*def\\>" nil "#" | 2202 | `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#" |
| 2284 | ,(lambda (arg) | 2203 | ,(lambda (arg) |
| 2285 | (python-end-of-defun) | 2204 | (python-end-of-defun) |
| 2286 | (skip-chars-backward " \t\n")) | 2205 | (skip-chars-backward " \t\n")) |
| @@ -2292,13 +2211,10 @@ with skeleton expansions for compound statement templates. | |||
| 2292 | (add-hook 'pre-abbrev-expand-hook 'python-pea-hook nil t) | 2211 | (add-hook 'pre-abbrev-expand-hook 'python-pea-hook nil t) |
| 2293 | (if (featurep 'hippie-exp) | 2212 | (if (featurep 'hippie-exp) |
| 2294 | (set (make-local-variable 'hippie-expand-try-functions-list) | 2213 | (set (make-local-variable 'hippie-expand-try-functions-list) |
| 2295 | (cons 'python-try-complete hippie-expand-try-functions-list))) | 2214 | (cons 'symbol-completion-try-complete |
| 2296 | ;; Python defines TABs as being 8-char wide. | 2215 | hippie-expand-try-functions-list))) |
| 2297 | (set (make-local-variable 'tab-width) 8) | 2216 | (unless font-lock-mode (font-lock-mode 1)) |
| 2298 | (when python-guess-indent (python-guess-indent)) | 2217 | (when python-guess-indent (python-guess-indent)) |
| 2299 | ;; Let's make it harder for the user to shoot himself in the foot. | ||
| 2300 | (unless (= tab-width python-indent) | ||
| 2301 | (setq indent-tabs-mode nil)) | ||
| 2302 | (set (make-local-variable 'python-command) python-python-command) | 2218 | (set (make-local-variable 'python-command) python-python-command) |
| 2303 | (python-find-imports) | 2219 | (python-find-imports) |
| 2304 | (unless (boundp 'python-mode-running) ; kill the recursion from jython-mode | 2220 | (unless (boundp 'python-mode-running) ; kill the recursion from jython-mode |
| @@ -2307,9 +2223,9 @@ with skeleton expansions for compound statement templates. | |||
| 2307 | 2223 | ||
| 2308 | (custom-add-option 'python-mode-hook 'imenu-add-menubar-index) | 2224 | (custom-add-option 'python-mode-hook 'imenu-add-menubar-index) |
| 2309 | (custom-add-option 'python-mode-hook | 2225 | (custom-add-option 'python-mode-hook |
| 2310 | (lambda () | 2226 | '(lambda () |
| 2311 | "Turn off Indent Tabs mode." | 2227 | "Turn off Indent Tabs mode." |
| 2312 | (set (make-local-variable 'indent-tabs-mode) nil))) | 2228 | (set (make-local-variable 'indent-tabs-mode) nil))) |
| 2313 | (custom-add-option 'python-mode-hook 'turn-on-eldoc-mode) | 2229 | (custom-add-option 'python-mode-hook 'turn-on-eldoc-mode) |
| 2314 | (custom-add-option 'python-mode-hook 'abbrev-mode) | 2230 | (custom-add-option 'python-mode-hook 'abbrev-mode) |
| 2315 | (custom-add-option 'python-mode-hook 'python-setup-brm) | 2231 | (custom-add-option 'python-mode-hook 'python-setup-brm) |