1;;; python.el --- silly walks for Python 2 3;; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 4 5;; Author: Dave Love <fx@gnu.org> 6;; Maintainer: FSF 7;; Created: Nov 2003 8;; Keywords: languages 9 10;; This file is part of GNU Emacs. 11 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 14;; the Free Software Foundation; either version 2, or (at your option) 15;; any later version. 16 17;; GNU Emacs is distributed in the hope that it will be useful, 18;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20;; GNU General Public License for more details. 21 22;; You should have received a copy of the GNU General Public License 23;; along with GNU Emacs; see the file COPYING. If not, write to the 24;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 25;; Boston, MA 02110-1301, USA. 26 27;;; Commentary: 28 29;; Major mode for editing Python, with support for inferior processes. 30 31;; There is another Python mode, python-mode.el, used by XEmacs and 32;; maintained with Python. That isn't covered by an FSF copyright 33;; assignment, unlike this code, and seems not to be well-maintained 34;; for Emacs (though I've submitted fixes). This mode is rather 35;; simpler and is better in other ways. In particular, using the 36;; syntax functions with text properties maintained by font-lock makes 37;; it more correct with arbitrary string and comment contents. 38 39;; This doesn't implement all the facilities of python-mode.el. Some 40;; just need doing, e.g. catching exceptions in the inferior Python 41;; buffer (but see M-x pdb for debugging). [Actually, the use of 42;; `compilation-shell-minor-mode' now is probably enough for that.] 43;; Others don't seem appropriate. For instance, 44;; `forward-into-nomenclature' should be done separately, since it's 45;; not specific to Python, and I've installed a minor mode to do the 46;; job properly in Emacs 23. [CC mode 5.31 contains an incompatible 47;; feature, `c-subword-mode' which is intended to have a similar 48;; effect, but actually only affects word-oriented keybindings.] 49 50;; Other things seem more natural or canonical here, e.g. the 51;; {beginning,end}-of-defun implementation dealing with nested 52;; definitions, and the inferior mode following `cmuscheme'. (The 53;; inferior mode can find the source of errors from 54;; `python-send-region' & al via `compilation-shell-minor-mode'.) 55;; There is (limited) symbol completion using lookup in Python and 56;; Eldoc support also using the inferior process. Successive TABs 57;; cycle between possible indentations for the line. 58 59;; Even where it has similar facilities, this mode is incompatible 60;; with python-mode.el in some respects. For instance, various key 61;; bindings are changed to obey Emacs conventions. 62 63;; TODO: See various Fixmes below. 64 65;;; Code: 66 67(eval-when-compile 68 (require 'cl) 69 (require 'compile) 70 (require 'comint) 71 (require 'hippie-exp)) 72 73(autoload 'comint-mode "comint") 74 75(defgroup python nil 76 "Silly walks in the Python language." 77 :group 'languages 78 :version "22.1" 79 :link '(emacs-commentary-link "python")) 80 81;;;###autoload 82(add-to-list 'interpreter-mode-alist '("jython" . jython-mode)) 83;;;###autoload 84(add-to-list 'interpreter-mode-alist '("python" . python-mode)) 85;;;###autoload 86(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode)) 87 88;;;; Font lock 89 90(defvar python-font-lock-keywords 91 `(,(rx symbol-start 92 ;; From v 2.4 reference. 93 ;; def and class dealt with separately below 94 (or "and" "assert" "break" "continue" "del" "elif" "else" 95 "except" "exec" "finally" "for" "from" "global" "if" 96 "import" "in" "is" "lambda" "not" "or" "pass" "print" 97 "raise" "return" "try" "while" "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) 103 ;; Definitions 104 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_)))) 105 (1 font-lock-keyword-face) (2 font-lock-type-face)) 106 (,(rx symbol-start (group "def") (1+ space) (group (1+ (or word ?_)))) 107 (1 font-lock-keyword-face) (2 font-lock-function-name-face)) 108 ;; Top-level assignments are worth highlighting. 109 (,(rx line-start (group (1+ (or word ?_))) (0+ space) "=") 110 (1 font-lock-variable-name-face)) 111 (,(rx "@" (1+ (or word ?_))) ; decorators 112 (0 font-lock-preprocessor-face)))) 113 114(defconst python-font-lock-syntactic-keywords 115 ;; Make outer chars of matching triple-quote sequences into generic 116 ;; string delimiters. Fixme: Is there a better way? 117 `((,(rx (or line-start buffer-start 118 (not (syntax escape))) ; avoid escaped leading quote 119 (group (optional (any "uUrR"))) ; prefix gets syntax property 120 (optional (any "rR")) ; possible second prefix 121 (group (syntax string-quote)) ; maybe gets property 122 (backref 2) ; per first quote 123 (group (backref 2))) ; maybe gets property 124 (1 (python-quote-syntax 1)) 125 (2 (python-quote-syntax 2)) 126 (3 (python-quote-syntax 3))) 127 ;; This doesn't really help. 128;;; (,(rx (and ?\\ (group ?\n))) (1 " ")) 129 )) 130 131(defun python-quote-syntax (n) 132 "Put `syntax-table' property correctly on triple quote. 133Used for syntactic keywords. N is the match number (1, 2 or 3)." 134 ;; Given a triple quote, we have to check the context to know 135 ;; whether this is an opening or closing triple or whether it's 136 ;; quoted anyhow, and should be ignored. (For that we need to do 137 ;; the same job as `syntax-ppss' to be correct and it seems to be OK 138 ;; to use it here despite initial worries.) We also have to sort 139 ;; out a possible prefix -- well, we don't _have_ to, but I think it 140 ;; should be treated as part of the string. 141 142 ;; Test cases: 143 ;; ur"""ar""" x='"' # """ 144 ;; x = ''' """ ' a 145 ;; ''' 146 ;; x '"""' x """ \"""" x 147 ;; Fixme: """""" goes wrong (due to syntax-ppss not getting the string 148 ;; fence context). 149 (save-excursion 150 (goto-char (match-beginning 0)) 151 (cond 152 ;; Consider property for the last char if in a fenced string. 153 ((= n 3) 154 (let ((syntax (syntax-ppss))) 155 (when (eq t (nth 3 syntax)) ; after unclosed fence 156 (goto-char (nth 8 syntax)) ; fence position 157 (skip-chars-forward "uUrR") ; skip any prefix 158 ;; Is it a matching sequence? 159 (if (eq (char-after) (char-after (match-beginning 2))) 160 (eval-when-compile (string-to-syntax "|")))))) 161 ;; Consider property for initial char, accounting for prefixes. 162 ((or (and (= n 2) ; leading quote (not prefix) 163 (= (match-beginning 1) (match-end 1))) ; prefix is null 164 (and (= n 1) ; prefix 165 (/= (match-beginning 1) (match-end 1)))) ; non-empty 166 (unless (nth 3 (syntax-ppss)) 167 (eval-when-compile (string-to-syntax "|")))) 168 ;; Otherwise (we're in a non-matching string) the property is 169 ;; nil, which is OK. 170 ))) 171 172;; This isn't currently in `font-lock-defaults' as probably not worth 173;; it -- we basically only mess with a few normally-symbol characters. 174 175;; (defun python-font-lock-syntactic-face-function (state) 176;; "`font-lock-syntactic-face-function' for Python mode. 177;; Returns the string or comment face as usual, with side effect of putting 178;; a `syntax-table' property on the inside of the string or comment which is 179;; the standard syntax table." 180;; (if (nth 3 state) 181;; (save-excursion 182;; (goto-char (nth 8 state)) 183;; (condition-case nil 184;; (forward-sexp) 185;; (error nil)) 186;; (put-text-property (1+ (nth 8 state)) (1- (point)) 187;; 'syntax-table (standard-syntax-table)) 188;; 'font-lock-string-face) 189;; (put-text-property (1+ (nth 8 state)) (line-end-position) 190;; 'syntax-table (standard-syntax-table)) 191;; 'font-lock-comment-face)) 192 193;;;; Keymap and syntax 194 195(defvar python-mode-map 196 (let ((map (make-sparse-keymap))) 197 ;; Mostly taken from python-mode.el. 198 (define-key map ":" 'python-electric-colon) 199 (define-key map "\177" 'python-backspace) 200 (define-key map "\C-c<" 'python-shift-left) 201 (define-key map "\C-c>" 'python-shift-right) 202 (define-key map "\C-c\C-k" 'python-mark-block) 203 (define-key map "\C-c\C-n" 'python-next-statement) 204 (define-key map "\C-c\C-p" 'python-previous-statement) 205 (define-key map "\C-c\C-u" 'python-beginning-of-block) 206 (define-key map "\C-c\C-f" 'python-describe-symbol) 207 (define-key map "\C-c\C-w" 'python-check) 208 (define-key map "\C-c\C-v" 'python-check) ; a la sgml-mode 209 (define-key map "\C-c\C-s" 'python-send-string) 210 (define-key map [?\C-\M-x] 'python-send-defun) 211 (define-key map "\C-c\C-r" 'python-send-region) 212 (define-key map "\C-c\M-r" 'python-send-region-and-go) 213 (define-key map "\C-c\C-c" 'python-send-buffer) 214 (define-key map "\C-c\C-z" 'python-switch-to-python) 215 (define-key map "\C-c\C-m" 'python-load-file) 216 (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme 217 (substitute-key-definition 'complete-symbol 'python-complete-symbol 218 map global-map) 219 (define-key map "\C-c\C-i" 'python-find-imports) 220 (define-key map "\C-c\C-t" 'python-expand-template) 221 (easy-menu-define python-menu map "Python Mode menu" 222 `("Python" 223 :help "Python-specific Features" 224 ["Shift region left" python-shift-left :active mark-active 225 :help "Shift by a single indentation step"] 226 ["Shift region right" python-shift-right :active mark-active 227 :help "Shift by a single indentation step"] 228 "-" 229 ["Mark block" python-mark-block 230 :help "Mark innermost block around point"] 231 ["Mark def/class" mark-defun 232 :help "Mark innermost definition around point"] 233 "-" 234 ["Start of block" python-beginning-of-block 235 :help "Go to start of innermost definition around point"] 236 ["End of block" python-end-of-block 237 :help "Go to end of innermost definition around point"] 238 ["Start of def/class" beginning-of-defun 239 :help "Go to start of innermost definition around point"] 240 ["End of def/class" end-of-defun 241 :help "Go to end of innermost definition around point"] 242 "-" 243 ("Templates..." 244 :help "Expand templates for compound statements" 245 :filter (lambda (&rest junk) 246 (mapcar (lambda (elt) 247 (vector (car elt) (cdr elt) t)) 248 python-skeletons))) ; defined later 249 "-" 250 ["Start interpreter" run-python 251 :help "Run `inferior' Python in separate buffer"] 252 ["Import/reload file" python-load-file 253 :help "Load into inferior Python session"] 254 ["Eval buffer" python-send-buffer 255 :help "Evaluate buffer en bloc in inferior Python session"] 256 ["Eval region" python-send-region :active mark-active 257 :help "Evaluate region en bloc in inferior Python session"] 258 ["Eval def/class" python-send-defun 259 :help "Evaluate current definition in inferior Python session"] 260 ["Switch to interpreter" python-switch-to-python 261 :help "Switch to inferior Python buffer"] 262 ["Set default process" python-set-proc 263 :help "Make buffer's inferior process the default" 264 :active (buffer-live-p python-buffer)] 265 ["Check file" python-check :help "Run pychecker"] 266 ["Debugger" pdb :help "Run pdb under GUD"] 267 "-" 268 ["Help on symbol" python-describe-symbol 269 :help "Use pydoc on symbol at point"] 270 ["Complete symbol" python-complete-symbol 271 :help "Complete (qualified) symbol before point"] 272 ["Update imports" python-find-imports 273 :help "Update list of top-level imports for completion"])) 274 map)) 275;; Fixme: add toolbar stuff for useful things like symbol help, send 276;; region, at least. (Shouldn't be specific to Python, obviously.) 277;; eric has items including: (un)indent, (un)comment, restart script, 278;; run script, debug script; also things for profiling, unit testing. 279 280(defvar python-mode-syntax-table 281 (let ((table (make-syntax-table))) 282 ;; Give punctuation syntax to ASCII that normally has symbol 283 ;; syntax or has word syntax and isn't a letter. 284 (let ((symbol (string-to-syntax "_")) 285 (sst (standard-syntax-table))) 286 (dotimes (i 128) 287 (unless (= i ?_) 288 (if (equal symbol (aref sst i)) 289 (modify-syntax-entry i "." table))))) 290 (modify-syntax-entry ?$ "." table) 291 (modify-syntax-entry ?% "." table) 292 ;; exceptions 293 (modify-syntax-entry ?# "<" table) 294 (modify-syntax-entry ?\n ">" table) 295 (modify-syntax-entry ?' "\"" table) 296 (modify-syntax-entry ?` "$" table) 297 table)) 298 299;;;; Utility stuff 300 301(defsubst python-in-string/comment () 302 "Return non-nil if point is in a Python literal (a comment or string)." 303 ;; We don't need to save the match data. 304 (nth 8 (syntax-ppss))) 305 306(defconst python-space-backslash-table 307 (let ((table (copy-syntax-table python-mode-syntax-table))) 308 (modify-syntax-entry ?\\ " " table) 309 table) 310 "`python-mode-syntax-table' with backslash given whitespace syntax.") 311 312(defun python-skip-comments/blanks (&optional backward) 313 "Skip comments and blank lines. 314BACKWARD non-nil means go backwards, otherwise go forwards. 315Backslash is treated as whitespace so that continued blank lines 316are skipped. Doesn't move out of comments -- should be outside 317or at end of line." 318 (let ((arg (if backward 319 ;; If we're in a comment (including on the trailing 320 ;; newline), forward-comment doesn't move backwards out 321 ;; of it. Don't set the syntax table round this bit! 322 (let ((syntax (syntax-ppss))) 323 (if (nth 4 syntax) 324 (goto-char (nth 8 syntax))) 325 (- (point-max))) 326 (point-max)))) 327 (with-syntax-table python-space-backslash-table 328 (forward-comment arg)))) 329 330(defun python-backslash-continuation-line-p () 331 "Non-nil if preceding line ends with backslash that is not in a comment." 332 (and (eq ?\\ (char-before (line-end-position 0))) 333 (not (syntax-ppss-context (syntax-ppss))))) 334 335(defun python-continuation-line-p () 336 "Return non-nil if current line continues a previous one. 337The criteria are that the previous line ends in a backslash outside 338comments and strings, or that point is within brackets/parens." 339 (or (python-backslash-continuation-line-p) 340 (let ((depth (syntax-ppss-depth 341 (save-excursion ; syntax-ppss with arg changes point 342 (syntax-ppss (line-beginning-position)))))) 343 (or (> depth 0) 344 (if (< depth 0) ; Unbalanced brackets -- act locally 345 (save-excursion 346 (condition-case () 347 (progn (backward-up-list) t) ; actually within brackets 348 (error nil)))))))) 349 350(defun python-comment-line-p () 351 "Return non-nil iff current line has only a comment." 352 (save-excursion 353 (end-of-line) 354 (when (eq 'comment (syntax-ppss-context (syntax-ppss))) 355 (back-to-indentation) 356 (looking-at (rx (or (syntax comment-start) line-end)))))) 357 358(defun python-blank-line-p () 359 "Return non-nil iff current line is blank." 360 (save-excursion 361 (beginning-of-line) 362 (looking-at "\\s-*$"))) 363 364(defun python-beginning-of-string () 365 "Go to beginning of string around point. 366Do nothing if not in string." 367 (let ((state (syntax-ppss))) 368 (when (eq 'string (syntax-ppss-context state)) 369 (goto-char (nth 8 state))))) 370 371(defun python-open-block-statement-p (&optional bos) 372 "Return non-nil if statement at point opens a block. 373BOS non-nil means point is known to be at beginning of statement." 374 (save-excursion 375 (unless bos (python-beginning-of-statement)) 376 (looking-at (rx (and (or "if" "else" "elif" "while" "for" "def" 377 "class" "try" "except" "finally" "with") 378 symbol-end))))) 379 380(defun python-close-block-statement-p (&optional bos) 381 "Return non-nil if current line is a statement closing a block. 382BOS non-nil means point is at beginning of statement. 383The criteria are that the line isn't a comment or in string and 384 starts with keyword `raise', `break', `continue' or `pass'." 385 (save-excursion 386 (unless bos (python-beginning-of-statement)) 387 (back-to-indentation) 388 (looking-at (rx (or "return" "raise" "break" "continue" "pass") 389 symbol-end)))) 390 391(defun python-outdent-p () 392 "Return non-nil if current line should outdent a level." 393 (save-excursion 394 (back-to-indentation) 395 (and (looking-at (rx (and (or "else" "finally" "except" "elif") 396 symbol-end))) 397 (not (python-in-string/comment)) 398 ;; Ensure there's a previous statement and move to it. 399 (zerop (python-previous-statement)) 400 (not (python-close-block-statement-p t)) 401 ;; Fixme: check this 402 (not (python-open-block-statement-p))))) 403 404;;;; Indentation. 405 406(defcustom python-indent 4 407 "Number of columns for a unit of indentation in Python mode. 408See also `\\[python-guess-indent]'" 409 :group 'python 410 :type 'integer) 411(put 'python-indent 'safe-local-variable 'integerp) 412 413(defcustom python-guess-indent t 414 "Non-nil means Python mode guesses `python-indent' for the buffer." 415 :type 'boolean 416 :group 'python) 417 418(defcustom python-indent-string-contents t 419 "Non-nil means indent contents of multi-line strings together. 420This means indent them the same as the preceding non-blank line. 421Otherwise preserve their indentation. 422 423This only applies to `doc' strings, i.e. those that form statements; 424the indentation is preserved in others." 425 :type '(choice (const :tag "Align with preceding" t) 426 (const :tag "Preserve indentation" nil)) 427 :group 'python) 428 429(defcustom python-honour-comment-indentation nil 430 "Non-nil means indent relative to preceding comment line. 431Only do this for comments where the leading comment character is 432followed by space. This doesn't apply to comment lines, which 433are always indented in lines with preceding comments." 434 :type 'boolean 435 :group 'python) 436 437(defcustom python-continuation-offset 4 438 "Number of columns of additional indentation for continuation lines. 439Continuation lines follow a backslash-terminated line starting a 440statement." 441 :group 'python 442 :type 'integer) 443 444(defun python-guess-indent () 445 "Guess step for indentation of current buffer. 446Set `python-indent' locally to the value guessed." 447 (interactive) 448 (save-excursion 449 (save-restriction 450 (widen) 451 (goto-char (point-min)) 452 (let (done indent) 453 (while (and (not done) (not (eobp))) 454 (when (and (re-search-forward (rx ?: (0+ space) 455 (or (syntax comment-start) 456 line-end)) 457 nil 'move) 458 (python-open-block-statement-p)) 459 (save-excursion 460 (python-beginning-of-statement) 461 (let ((initial (current-indentation))) 462 (if (zerop (python-next-statement)) 463 (setq indent (- (current-indentation) initial))) 464 (if (and indent (>= indent 2) (<= indent 8)) ; sanity check 465 (setq done t)))))) 466 (when done 467 (when (/= indent (default-value 'python-indent)) 468 (set (make-local-variable 'python-indent) indent) 469 (unless (= tab-width python-indent) 470 (setq indent-tabs-mode nil))) 471 indent))))) 472 473;; Alist of possible indentations and start of statement they would 474;; close. Used in indentation cycling (below). 475(defvar python-indent-list nil 476 "Internal use.") 477;; Length of the above 478(defvar python-indent-list-length nil 479 "Internal use.") 480;; Current index into the alist. 481(defvar python-indent-index nil 482 "Internal use.") 483 484(defun python-calculate-indentation () 485 "Calculate Python indentation for line at point." 486 (setq python-indent-list nil 487 python-indent-list-length 1) 488 (save-excursion 489 (beginning-of-line) 490 (let ((syntax (syntax-ppss)) 491 start) 492 (cond 493 ((eq 'string (syntax-ppss-context syntax)) ; multi-line string 494 (if (not python-indent-string-contents) 495 (current-indentation) 496 ;; Only respect `python-indent-string-contents' in doc 497 ;; strings (defined as those which form statements). 498 (if (not (save-excursion 499 (python-beginning-of-statement) 500 (looking-at (rx (or (syntax string-delimiter) 501 (syntax string-quote)))))) 502 (current-indentation) 503 ;; Find indentation of preceding non-blank line within string. 504 (setq start (nth 8 syntax)) 505 (forward-line -1) 506 (while (and (< start (point)) (looking-at "\\s-*$")) 507 (forward-line -1)) 508 (current-indentation)))) 509 ((python-continuation-line-p) ; after backslash, or bracketed 510 (let ((point (point)) 511 (open-start (cadr syntax)) 512 (backslash (python-backslash-continuation-line-p)) 513 (colon (eq ?: (char-before (1- (line-beginning-position)))))) 514 (if open-start 515 ;; Inside bracketed expression. 516 (progn 517 (goto-char (1+ open-start)) 518 ;; Look for first item in list (preceding point) and 519 ;; align with it, if found. 520 (if (with-syntax-table python-space-backslash-table 521 (let ((parse-sexp-ignore-comments t)) 522 (condition-case () 523 (progn (forward-sexp) 524 (backward-sexp) 525 (< (point) point)) 526 (error nil)))) 527 ;; Extra level if we're backslash-continued or 528 ;; following a key. 529 (if (or backslash colon) 530 (+ python-indent (current-column)) 531 (current-column)) 532 ;; Otherwise indent relative to statement start, one 533 ;; level per bracketing level. 534 (goto-char (1+ open-start)) 535 (python-beginning-of-statement) 536 (+ (current-indentation) (* (car syntax) python-indent)))) 537 ;; Otherwise backslash-continued. 538 (forward-line -1) 539 (if (python-continuation-line-p) 540 ;; We're past first continuation line. Align with 541 ;; previous line. 542 (current-indentation) 543 ;; First continuation line. Indent one step, with an 544 ;; extra one if statement opens a block. 545 (python-beginning-of-statement) 546 (+ (current-indentation) python-continuation-offset 547 (if (python-open-block-statement-p t) 548 python-indent 549 0)))))) 550 ((bobp) 0) 551 ;; Fixme: Like python-mode.el; not convinced by this. 552 ((looking-at (rx (0+ space) (syntax comment-start) 553 (not (any " \t\n")))) ; non-indentable comment 554 (current-indentation)) 555 (t (if python-honour-comment-indentation 556 ;; Back over whitespace, newlines, non-indentable comments. 557 (catch 'done 558 (while t 559 (if (cond ((bobp)) 560 ;; not at comment start 561 ((not (forward-comment -1)) 562 (python-beginning-of-statement) 563 t) 564 ;; trailing comment 565 ((/= (current-column) (current-indentation)) 566 (python-beginning-of-statement) 567 t) 568 ;; indentable comment like python-mode.el 569 ((and (looking-at (rx (syntax comment-start) 570 (or space line-end))) 571 (/= 0 (current-column))))) 572 (throw 'done t))))) 573 (python-indentation-levels) 574 ;; Prefer to indent comments with an immediately-following 575 ;; statement, e.g. 576 ;; ... 577 ;; # ... 578 ;; def ... 579 (when (and (> python-indent-list-length 1) 580 (python-comment-line-p)) 581 (forward-line) 582 (unless (python-comment-line-p) 583 (let ((elt (assq (current-indentation) python-indent-list))) 584 (setq python-indent-list 585 (nconc (delete elt python-indent-list) 586 (list elt)))))) 587 (caar (last python-indent-list))))))) 588 589;;;; Cycling through the possible indentations with successive TABs. 590 591;; These don't need to be buffer-local since they're only relevant 592;; during a cycle. 593 594(defun python-initial-text () 595 "Text of line following indentation and ignoring any trailing comment." 596 (save-excursion 597 (buffer-substring (progn 598 (back-to-indentation) 599 (point)) 600 (progn 601 (end-of-line) 602 (forward-comment -1) 603 (point))))) 604 605(defconst python-block-pairs 606 '(("else" "if" "elif" "while" "for" "try" "except") 607 ("elif" "if" "elif") 608 ("except" "try" "except") 609 ("finally" "try")) 610 "Alist of keyword matches. 611The car of an element is a keyword introducing a statement which 612can close a block opened by a keyword in the cdr.") 613 614(defun python-first-word () 615 "Return first word (actually symbol) on the line." 616 (save-excursion 617 (back-to-indentation) 618 (current-word t))) 619 620(defun python-indentation-levels () 621 "Return a list of possible indentations for this line. 622It is assumed not to be a continuation line or in a multi-line string. 623Includes the default indentation and those which would close all 624enclosing blocks. Elements of the list are actually pairs: 625\(INDENTATION . TEXT), where TEXT is the initial text of the 626corresponding block opening (or nil)." 627 (save-excursion 628 (let ((initial "") 629 levels indent) 630 ;; Only one possibility immediately following a block open 631 ;; statement, assuming it doesn't have a `suite' on the same line. 632 (cond 633 ((save-excursion (and (python-previous-statement) 634 (python-open-block-statement-p t) 635 (setq indent (current-indentation)) 636 ;; Check we don't have something like: 637 ;; if ...: ... 638 (if (progn (python-end-of-statement) 639 (python-skip-comments/blanks t) 640 (eq ?: (char-before))) 641 (setq indent (+ python-indent indent))))) 642 (push (cons indent initial) levels)) 643 ;; Only one possibility for comment line immediately following 644 ;; another. 645 ((save-excursion 646 (when (python-comment-line-p) 647 (forward-line -1) 648 (if (python-comment-line-p) 649 (push (cons (current-indentation) initial) levels))))) 650 ;; Fixme: Maybe have a case here which indents (only) first 651 ;; line after a lambda. 652 (t 653 (let ((start (car (assoc (python-first-word) python-block-pairs)))) 654 (python-previous-statement) 655 ;; Is this a valid indentation for the line of interest? 656 (unless (or (if start ; potentially only outdentable 657 ;; Check for things like: 658 ;; if ...: ... 659 ;; else ...: 660 ;; where the second line need not be outdented. 661 (not (member (python-first-word) 662 (cdr (assoc start 663 python-block-pairs))))) 664 ;; Not sensible to indent to the same level as 665 ;; previous `return' &c. 666 (python-close-block-statement-p)) 667 (push (cons (current-indentation) (python-initial-text)) 668 levels)) 669 (while (python-beginning-of-block) 670 (when (or (not start) 671 (member (python-first-word) 672 (cdr (assoc start python-block-pairs)))) 673 (push (cons (current-indentation) (python-initial-text)) 674 levels)))))) 675 (prog1 (or levels (setq levels '((0 . "")))) 676 (setq python-indent-list levels 677 python-indent-list-length (length python-indent-list)))))) 678 679;; This is basically what `python-indent-line' would be if we didn't 680;; do the cycling. 681(defun python-indent-line-1 (&optional leave) 682 "Subroutine of `python-indent-line'. 683Does non-repeated indentation. LEAVE non-nil means leave 684indentation if it is valid, i.e. one of the positions returned by 685`python-calculate-indentation'." 686 (let ((target (python-calculate-indentation)) 687 (pos (- (point-max) (point)))) 688 (if (or (= target (current-indentation)) 689 ;; Maybe keep a valid indentation. 690 (and leave python-indent-list 691 (assq (current-indentation) python-indent-list))) 692 (if (< (current-column) (current-indentation)) 693 (back-to-indentation)) 694 (beginning-of-line) 695 (delete-horizontal-space) 696 (indent-to target) 697 (if (> (- (point-max) pos) (point)) 698 (goto-char (- (point-max) pos)))))) 699 700(defun python-indent-line () 701 "Indent current line as Python code. 702When invoked via `indent-for-tab-command', cycle through possible 703indentations for current line. The cycle is broken by a command 704different from `indent-for-tab-command', i.e. successive TABs do 705the cycling." 706 (interactive) 707 (if (and (eq this-command 'indent-for-tab-command) 708 (eq last-command this-command)) 709 (if (= 1 python-indent-list-length) 710 (message "Sole indentation") 711 (progn (setq python-indent-index 712 (% (1+ python-indent-index) python-indent-list-length)) 713 (beginning-of-line) 714 (delete-horizontal-space) 715 (indent-to (car (nth python-indent-index python-indent-list))) 716 (if (python-block-end-p) 717 (let ((text (cdr (nth python-indent-index 718 python-indent-list)))) 719 (if text 720 (message "Closes: %s" text)))))) 721 (python-indent-line-1) 722 (setq python-indent-index (1- python-indent-list-length)))) 723 724(defun python-indent-region (start end) 725 "`indent-region-function' for Python. 726Leaves validly-indented lines alone, i.e. doesn't indent to 727another valid position." 728 (save-excursion 729 (goto-char end) 730 (setq end (point-marker)) 731 (goto-char start) 732 (or (bolp) (forward-line 1)) 733 (while (< (point) end) 734 (or (and (bolp) (eolp)) 735 (python-indent-line-1 t)) 736 (forward-line 1)) 737 (move-marker end nil))) 738 739(defun python-block-end-p () 740 "Non-nil if this is a line in a statement closing a block, 741or a blank line indented to where it would close a block." 742 (and (not (python-comment-line-p)) 743 (or (python-close-block-statement-p t) 744 (< (current-indentation) 745 (save-excursion 746 (python-previous-statement) 747 (current-indentation)))))) 748 749;;;; Movement. 750 751;; Fixme: Define {for,back}ward-sexp-function? Maybe skip units like 752;; block, statement, depending on context. 753 754(defun python-beginning-of-defun () 755 "`beginning-of-defun-function' for Python. 756Finds beginning of innermost nested class or method definition. 757Returns the name of the definition found at the end, or nil if 758reached start of buffer." 759 (let ((ci (current-indentation)) 760 (def-re (rx line-start (0+ space) (or "def" "class") (1+ space) 761 (group (1+ (or word (syntax symbol)))))) 762 found lep) ;; def-line 763 (if (python-comment-line-p) 764 (setq ci most-positive-fixnum)) 765 (while (and (not (bobp)) (not found)) 766 ;; Treat bol at beginning of function as outside function so 767 ;; that successive C-M-a makes progress backwards. 768 ;;(setq def-line (looking-at def-re)) 769 (unless (bolp) (end-of-line)) 770 (setq lep (line-end-position)) 771 (if (and (re-search-backward def-re nil 'move) 772 ;; Must be less indented or matching top level, or 773 ;; equally indented if we started on a definition line. 774 (let ((in (current-indentation))) 775 (or (and (zerop ci) (zerop in)) 776 (= lep (line-end-position)) ; on initial line 777 ;; Not sure why it was like this -- fails in case of 778 ;; last internal function followed by first 779 ;; non-def statement of the main body. 780 ;;(and def-line (= in ci)) 781 (= in ci) 782 (< in ci))) 783 (not (python-in-string/comment))) 784 (setq found t))))) 785 786(defun python-end-of-defun () 787 "`end-of-defun-function' for Python. 788Finds end of innermost nested class or method definition." 789 (let ((orig (point)) 790 (pattern (rx line-start (0+ space) (or "def" "class") space))) 791 ;; Go to start of current block and check whether it's at top 792 ;; level. If it is, and not a block start, look forward for 793 ;; definition statement. 794 (when (python-comment-line-p) 795 (end-of-line) 796 (forward-comment most-positive-fixnum)) 797 (if (not (python-open-block-statement-p)) 798 (python-beginning-of-block)) 799 (if (zerop (current-indentation)) 800 (unless (python-open-block-statement-p) 801 (while (and (re-search-forward pattern nil 'move) 802 (python-in-string/comment))) ; just loop 803 (unless (eobp) 804 (beginning-of-line))) 805 ;; Don't move before top-level statement that would end defun. 806 (end-of-line) 807 (python-beginning-of-defun)) 808 ;; If we got to the start of buffer, look forward for 809 ;; definition statement. 810 (if (and (bobp) (not (looking-at "def\\|class"))) 811 (while (and (not (eobp)) 812 (re-search-forward pattern nil 'move) 813 (python-in-string/comment)))) ; just loop 814 ;; We're at a definition statement (or end-of-buffer). 815 (unless (eobp) 816 (python-end-of-block) 817 ;; Count trailing space in defun (but not trailing comments). 818 (skip-syntax-forward " >") 819 (unless (eobp) ; e.g. missing final newline 820 (beginning-of-line))) 821 ;; Catch pathological cases like this, where the beginning-of-defun 822 ;; skips to a definition we're not in: 823 ;; if ...: 824 ;; ... 825 ;; else: 826 ;; ... # point here 827 ;; ... 828 ;; def ... 829 (if (< (point) orig) 830 (goto-char (point-max))))) 831 832(defun python-beginning-of-statement () 833 "Go to start of current statement. 834Accounts for continuation lines, multi-line strings, and 835multi-line bracketed expressions." 836 (beginning-of-line) 837 (python-beginning-of-string) 838 (while (python-continuation-line-p) 839 (beginning-of-line) 840 (if (python-backslash-continuation-line-p) 841 (progn 842 (forward-line -1) 843 (while (python-backslash-continuation-line-p) 844 (forward-line -1))) 845 (python-beginning-of-string) 846 (python-skip-out))) 847 (back-to-indentation)) 848 849(defun python-skip-out (&optional forward syntax) 850 "Skip out of any nested brackets. 851Skip forward if FORWARD is non-nil, else backward. 852If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point. 853Return non-nil iff skipping was done." 854 (let ((depth (syntax-ppss-depth (or syntax (syntax-ppss)))) 855 (forward (if forward -1 1))) 856 (unless (zerop depth) 857 (if (> depth 0) 858 ;; Skip forward out of nested brackets. 859 (condition-case () ; beware invalid syntax 860 (progn (backward-up-list (* forward depth)) t) 861 (error nil)) 862 ;; Invalid syntax (too many closed brackets). 863 ;; Skip out of as many as possible. 864 (let (done) 865 (while (condition-case () 866 (progn (backward-up-list forward) 867 (setq done t)) 868 (error nil))) 869 done))))) 870 871(defun python-end-of-statement () 872 "Go to the end of the current statement and return point. 873Usually this is the start of the next line, but if this is a 874multi-line statement we need to skip over the continuation lines. 875On a comment line, go to end of line." 876 (end-of-line) 877 (while (let (comment) 878 ;; Move past any enclosing strings and sexps, or stop if 879 ;; we're in a comment. 880 (while (let ((s (syntax-ppss))) 881 (cond ((eq 'comment (syntax-ppss-context s)) 882 (setq comment t) 883 nil) 884 ((eq 'string (syntax-ppss-context s)) 885 ;; Go to start of string and skip it. 886 (goto-char (nth 8 s)) 887 (condition-case () ; beware invalid syntax 888 (progn (forward-sexp) t) 889 (error (end-of-line)))) 890 ((python-skip-out t s)))) 891 (end-of-line)) 892 (unless comment 893 (eq ?\\ (char-before)))) ; Line continued? 894 (end-of-line 2)) ; Try next line. 895 (point)) 896 897(defun python-previous-statement (&optional count) 898 "Go to start of previous statement. 899With argument COUNT, do it COUNT times. Stop at beginning of buffer. 900Return count of statements left to move." 901 (interactive "p") 902 (unless count (setq count 1)) 903 (if (< count 0) 904 (python-next-statement (- count)) 905 (python-beginning-of-statement) 906 (while (and (> count 0) (not (bobp))) 907 (python-skip-comments/blanks t) 908 (python-beginning-of-statement) 909 (unless (bobp) (setq count (1- count)))) 910 count)) 911 912(defun python-next-statement (&optional count) 913 "Go to start of next statement. 914With argument COUNT, do it COUNT times. Stop at end of buffer. 915Return count of statements left to move." 916 (interactive "p") 917 (unless count (setq count 1)) 918 (if (< count 0) 919 (python-previous-statement (- count)) 920 (beginning-of-line) 921 (while (and (> count 0) (not (eobp))) 922 (python-end-of-statement) 923 (python-skip-comments/blanks) 924 (unless (eobp) 925 (setq count (1- count)))) 926 count)) 927 928(defun python-beginning-of-block (&optional arg) 929 "Go to start of current block. 930With numeric arg, do it that many times. If ARG is negative, call 931`python-end-of-block' instead. 932If point is on the first line of a block, use its outer block. 933If current statement is in column zero, don't move and return nil. 934Otherwise return non-nil." 935 (interactive "p") 936 (unless arg (setq arg 1)) 937 (cond 938 ((zerop arg)) 939 ((< arg 0) (python-end-of-block (- arg))) 940 (t 941 (let ((point (point))) 942 (if (or (python-comment-line-p) 943 (python-blank-line-p)) 944 (python-skip-comments/blanks t)) 945 (python-beginning-of-statement) 946 (let ((ci (current-indentation))) 947 (if (zerop ci) 948 (not (goto-char point)) ; return nil 949 ;; Look upwards for less indented statement. 950 (if (catch 'done 951;;; This is slower than the below. 952;;; (while (zerop (python-previous-statement)) 953;;; (when (and (< (current-indentation) ci) 954;;; (python-open-block-statement-p t)) 955;;; (beginning-of-line) 956;;; (throw 'done t))) 957 (while (and (zerop (forward-line -1))) 958 (when (and (< (current-indentation) ci) 959 (not (python-comment-line-p)) 960 ;; Move to beginning to save effort in case 961 ;; this is in string. 962 (progn (python-beginning-of-statement) t) 963 (python-open-block-statement-p t)) 964 (beginning-of-line) 965 (throw 'done t))) 966 (not (goto-char point))) ; Failed -- return nil 967 (python-beginning-of-block (1- arg))))))))) 968 969(defun python-end-of-block (&optional arg) 970 "Go to end of current block. 971With numeric arg, do it that many times. If ARG is negative, 972call `python-beginning-of-block' instead. 973If current statement is in column zero and doesn't open a block, 974don't move and return nil. Otherwise return t." 975 (interactive "p") 976 (unless arg (setq arg 1)) 977 (if (< arg 0) 978 (python-beginning-of-block (- arg)) 979 (while (and (> arg 0) 980 (let* ((point (point)) 981 (_ (if (python-comment-line-p) 982 (python-skip-comments/blanks t))) 983 (ci (current-indentation)) 984 (open (python-open-block-statement-p)) 985 opoint) 986 (if (and (zerop ci) (not open)) 987 (not (goto-char point)) 988 (catch 'done 989 (setq opoint (point)) 990 (while (and (zerop (python-next-statement)) 991 (not (= opoint (point)))) 992 (setq opoint (point)) 993 (when (or (and open (<= (current-indentation) ci)) 994 (< (current-indentation) ci)) 995 (python-skip-comments/blanks t) 996 (beginning-of-line 2) 997 (throw 'done t))))))) 998 (setq arg (1- arg))) 999 (zerop arg))) 1000 1001;;;; Imenu. 1002 1003(defvar python-recursing) 1004(defun python-imenu-create-index () 1005 "`imenu-create-index-function' for Python. 1006 1007Makes nested Imenu menus from nested `class' and `def' statements. 1008The nested menus are headed by an item referencing the outer 1009definition; it has a space prepended to the name so that it sorts 1010first with `imenu--sort-by-name' (though, unfortunately, sub-menus 1011precede it)." 1012 (unless (boundp 'python-recursing) ; dynamically bound below 1013 ;; Normal call from Imenu. 1014 (goto-char (point-min)) 1015 ;; Without this, we can get an infloop if the buffer isn't all 1016 ;; fontified. I guess this is really a bug in syntax.el. OTOH, 1017 ;; _with_ this, imenu doesn't immediately work; I can't figure out 1018 ;; what's going on, but it must be something to do with timers in 1019 ;; font-lock. 1020 ;; This can't be right, especially not when jit-lock is not used. --Stef 1021 ;; (unless (get-text-property (1- (point-max)) 'fontified) 1022 ;; (font-lock-fontify-region (point-min) (point-max))) 1023 ) 1024 (let (index-alist) ; accumulated value to return 1025 (while (re-search-forward 1026 (rx line-start (0+ space) ; leading space 1027 (or (group "def") (group "class")) ; type 1028 (1+ space) (group (1+ (or word ?_)))) ; name 1029 nil t) 1030 (unless (python-in-string/comment) 1031 (let ((pos (match-beginning 0)) 1032 (name (match-string-no-properties 3))) 1033 (if (match-beginning 2) ; def or class? 1034 (setq name (concat "class " name))) 1035 (save-restriction 1036 (narrow-to-defun) 1037 (let* ((python-recursing t) 1038 (sublist (python-imenu-create-index))) 1039 (if sublist 1040 (progn (push (cons (concat " " name) pos) sublist) 1041 (push (cons name sublist) index-alist)) 1042 (push (cons name pos) index-alist))))))) 1043 (unless (boundp 'python-recursing) 1044 ;; Look for module variables. 1045 (let (vars) 1046 (goto-char (point-min)) 1047 (while (re-search-forward 1048 (rx line-start (group (1+ (or word ?_))) (0+ space) "=") 1049 nil t) 1050 (unless (python-in-string/comment) 1051 (push (cons (match-string 1) (match-beginning 1)) 1052 vars))) 1053 (setq index-alist (nreverse index-alist)) 1054 (if vars 1055 (push (cons "Module variables" 1056 (nreverse vars)) 1057 index-alist)))) 1058 index-alist)) 1059 1060;;;; `Electric' commands. 1061 1062(defun python-electric-colon (arg) 1063 "Insert a colon and maybe outdent the line if it is a statement like `else'. 1064With numeric ARG, just insert that many colons. With \\[universal-argument], 1065just insert a single colon." 1066 (interactive "*P") 1067 (self-insert-command (if (not (integerp arg)) 1 arg)) 1068 (and (not arg) 1069 (eolp) 1070 (python-outdent-p) 1071 (not (python-in-string/comment)) 1072 (> (current-indentation) (python-calculate-indentation)) 1073 (python-indent-line))) ; OK, do it 1074(put 'python-electric-colon 'delete-selection t) 1075 1076(defun python-backspace (arg) 1077 "Maybe delete a level of indentation on the current line. 1078Do so if point is at the end of the line's indentation. 1079Otherwise just call `backward-delete-char-untabify'. 1080Repeat ARG times." 1081 (interactive "*p") 1082 (if (or (/= (current-indentation) (current-column)) 1083 (bolp) 1084 (python-continuation-line-p)) 1085 (backward-delete-char-untabify arg) 1086 ;; Look for the largest valid indentation which is smaller than 1087 ;; the current indentation. 1088 (let ((indent 0) 1089 (ci (current-indentation)) 1090 (indents (python-indentation-levels)) 1091 initial) 1092 (dolist (x indents) 1093 (if (< (car x) ci) 1094 (setq indent (max indent (car x))))) 1095 (setq initial (cdr (assq indent indents))) 1096 (if (> (length initial) 0) 1097 (message "Closes %s" initial)) 1098 (delete-horizontal-space) 1099 (indent-to indent)))) 1100(put 'python-backspace 'delete-selection 'supersede) 1101 1102;;;; pychecker 1103 1104(defcustom python-check-command "pychecker --stdlib" 1105 "Command used to check a Python file." 1106 :type 'string 1107 :group 'python) 1108 1109(defvar python-saved-check-command nil 1110 "Internal use.") 1111 1112;; After `sgml-validate-command'. 1113(defun python-check (command) 1114 "Check a Python file (default current buffer's file). 1115Runs COMMAND, a shell command, as if by `compile'. 1116See `python-check-command' for the default." 1117 (interactive 1118 (list (read-string "Checker command: " 1119 (or python-saved-check-command 1120 (concat python-check-command " " 1121 (let ((name (buffer-file-name))) 1122 (if name 1123 (file-name-nondirectory name)))))))) 1124 (setq python-saved-check-command command) 1125 (require 'compile) ;To define compilation-* variables. 1126 (save-some-buffers (not compilation-ask-about-save) nil) 1127 (let ((compilation-error-regexp-alist 1128 (cons '("(\\([^,]+\\), line \\([0-9]+\\))" 1 2) 1129 compilation-error-regexp-alist))) 1130 (compilation-start command))) 1131 1132;;;; Inferior mode stuff (following cmuscheme). 1133 1134;; Fixme: Make sure we can work with IPython. 1135 1136(defcustom python-python-command "python" 1137 "Shell command to run Python interpreter. 1138Any arguments can't contain whitespace. 1139Note that IPython may not work properly; it must at least be used 1140with the `-cl' flag, i.e. use `ipython -cl'." 1141 :group 'python 1142 :type 'string) 1143 1144(defcustom python-jython-command "jython" 1145 "Shell command to run Jython interpreter. 1146Any arguments can't contain whitespace." 1147 :group 'python 1148 :type 'string) 1149 1150(defvar python-command python-python-command 1151 "Actual command used to run Python. 1152May be `python-python-command' or `python-jython-command', possibly 1153modified by the user. Additional arguments are added when the command 1154is used by `run-python' et al.") 1155 1156(defvar python-buffer nil 1157 "*The current Python process buffer. 1158 1159Commands that send text from source buffers to Python processes have 1160to choose a process to send to. This is determined by buffer-local 1161value of `python-buffer'. If its value in the current buffer, 1162i.e. both any local value and the default one, is nil, `run-python' 1163and commands that send to the Python process will start a new process. 1164 1165Whenever \\[run-python] starts a new process, it resets the default 1166value of `python-buffer' to be the new process's buffer and sets the 1167buffer-local value similarly if the current buffer is in Python mode 1168or Inferior Python mode, so that source buffer stays associated with a 1169specific sub-process. 1170 1171Use \\[python-set-proc] to set the default value from a buffer with a 1172local value.") 1173(make-variable-buffer-local 'python-buffer) 1174 1175(defconst python-compilation-regexp-alist 1176 ;; FIXME: maybe these should move to compilation-error-regexp-alist-alist. 1177 ;; The first already is (for CAML), but the second isn't. Anyhow, 1178 ;; these are specific to the inferior buffer. -- fx 1179 `((,(rx line-start (1+ (any " \t")) "File \"" 1180 (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c 1181 "\", line " (group (1+ digit))) 1182 1 2) 1183 (,(rx " in file " (group (1+ not-newline)) " on line " 1184 (group (1+ digit))) 1185 1 2)) 1186 "`compilation-error-regexp-alist' for inferior Python.") 1187 1188(defvar inferior-python-mode-map 1189 (let ((map (make-sparse-keymap))) 1190 ;; This will inherit from comint-mode-map. 1191 (define-key map "\C-c\C-l" 'python-load-file) 1192 (define-key map "\C-c\C-v" 'python-check) 1193 ;; Note that we _can_ still use these commands which send to the 1194 ;; Python process even at the prompt iff we have a normal prompt, 1195 ;; i.e. '>>> ' and not '... '. See the comment before 1196 ;; python-send-region. Fixme: uncomment these if we address that. 1197 1198 ;; (define-key map [(meta ?\t)] 'python-complete-symbol) 1199 ;; (define-key map "\C-c\C-f" 'python-describe-symbol) 1200 map)) 1201 1202(defvar inferior-python-mode-syntax-table 1203 (let ((st (make-syntax-table python-mode-syntax-table))) 1204 ;; Don't get confused by apostrophes in the process's output (e.g. if 1205 ;; you execute "help(os)"). 1206 (modify-syntax-entry ?\' "." st) 1207 ;; Maybe we should do the same for double quotes? 1208 ;; (modify-syntax-entry ?\" "." st) 1209 st)) 1210 1211;; Fixme: This should inherit some stuff from `python-mode', but I'm 1212;; not sure how much: at least some keybindings, like C-c C-f; 1213;; syntax?; font-locking, e.g. for triple-quoted strings? 1214(define-derived-mode inferior-python-mode comint-mode "Inferior Python" 1215 "Major mode for interacting with an inferior Python process. 1216A Python process can be started with \\[run-python]. 1217 1218Hooks `comint-mode-hook' and `inferior-python-mode-hook' are run in 1219that order. 1220 1221You can send text to the inferior Python process from other buffers 1222containing Python source. 1223 * \\[python-switch-to-python] switches the current buffer to the Python 1224 process buffer. 1225 * \\[python-send-region] sends the current region to the Python process. 1226 * \\[python-send-region-and-go] switches to the Python process buffer 1227 after sending the text. 1228For running multiple processes in multiple buffers, see `run-python' and 1229`python-buffer'. 1230 1231\\{inferior-python-mode-map}" 1232 :group 'python 1233 (setq mode-line-process '(":%s")) 1234 (set (make-local-variable 'comint-input-filter) 'python-input-filter) 1235 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter 1236 nil t) 1237 ;; Still required by `comint-redirect-send-command', for instance 1238 ;; (and we need to match things like `>>> ... >>> '): 1239 (set (make-local-variable 'comint-prompt-regexp) 1240 (rx line-start (1+ (and (repeat 3 (any ">.")) " ")))) 1241 (set (make-local-variable 'compilation-error-regexp-alist) 1242 python-compilation-regexp-alist) 1243 (compilation-shell-minor-mode 1)) 1244 1245(defcustom inferior-python-filter-regexp "\\`\\s-*\\S-?\\S-?\\s-*\\'" 1246 "Input matching this regexp is not saved on the history list. 1247Default ignores all inputs of 0, 1, or 2 non-blank characters." 1248 :type 'regexp 1249 :group 'python) 1250 1251(defun python-input-filter (str) 1252 "`comint-input-filter' function for inferior Python. 1253Don't save anything for STR matching `inferior-python-filter-regexp'." 1254 (not (string-match inferior-python-filter-regexp str))) 1255 1256;; Fixme: Loses with quoted whitespace. 1257(defun python-args-to-list (string) 1258 (let ((where (string-match "[ \t]" string))) 1259 (cond ((null where) (list string)) 1260 ((not (= where 0)) 1261 (cons (substring string 0 where) 1262 (python-args-to-list (substring string (+ 1 where))))) 1263 (t (let ((pos (string-match "[^ \t]" string))) 1264 (if pos (python-args-to-list (substring string pos)))))))) 1265 1266(defvar python-preoutput-result nil 1267 "Data from last `_emacs_out' line seen by the preoutput filter.") 1268 1269(defvar python-preoutput-leftover nil) 1270(defvar python-preoutput-skip-next-prompt nil) 1271 1272;; Using this stops us getting lines in the buffer like 1273;; >>> ... ... >>> 1274(defun python-preoutput-filter (s) 1275 "`comint-preoutput-filter-functions' function: ignore prompts not at bol." 1276 (when python-preoutput-leftover 1277 (setq s (concat python-preoutput-leftover s)) 1278 (setq python-preoutput-leftover nil)) 1279 (let ((start 0) 1280 (res "")) 1281 ;; First process whole lines. 1282 (while (string-match "\n" s start) 1283 (let ((line (substring s start (setq start (match-end 0))))) 1284 ;; Skip prompt if needed. 1285 (when (and python-preoutput-skip-next-prompt 1286 (string-match comint-prompt-regexp line)) 1287 (setq python-preoutput-skip-next-prompt nil) 1288 (setq line (substring line (match-end 0)))) 1289 ;; Recognize special _emacs_out lines. 1290 (if (and (string-match "\\`_emacs_out \\(.*\\)\n\\'" line) 1291 (local-variable-p 'python-preoutput-result)) 1292 (progn 1293 (setq python-preoutput-result (match-string 1 line)) 1294 (set (make-local-variable 'python-preoutput-skip-next-prompt) t)) 1295 (setq res (concat res line))))) 1296 ;; Then process the remaining partial line. 1297 (unless (zerop start) (setq s (substring s start))) 1298 (cond ((and (string-match comint-prompt-regexp s) 1299 ;; Drop this prompt if it follows an _emacs_out... 1300 (or python-preoutput-skip-next-prompt 1301 ;; ... or if it's not gonna be inserted at BOL. 1302 ;; Maybe we could be more selective here. 1303 (if (zerop (length res)) 1304 (not (bolp)) 1305 (string-match ".\\'" res)))) 1306 ;; The need for this seems to be system-dependent: 1307 ;; What is this all about, exactly? --Stef 1308 ;; (if (and (eq ?. (aref s 0))) 1309 ;; (accept-process-output (get-buffer-process (current-buffer)) 1)) 1310 (setq python-preoutput-skip-next-prompt nil) 1311 res) 1312 ((let ((end (min (length "_emacs_out ") (length s)))) 1313 (eq t (compare-strings s nil end "_emacs_out " nil end))) 1314 ;; The leftover string is a prefix of _emacs_out so we don't know 1315 ;; yet whether it's an _emacs_out or something else: wait until we 1316 ;; get more output so we can resolve this ambiguity. 1317 (set (make-local-variable 'python-preoutput-leftover) s) 1318 res) 1319 (t (concat res s))))) 1320 1321(autoload 'comint-check-proc "comint") 1322 1323;;;###autoload 1324(defun run-python (&optional cmd noshow new) 1325 "Run an inferior Python process, input and output via buffer *Python*. 1326CMD is the Python command to run. NOSHOW non-nil means don't show the 1327buffer automatically. 1328 1329Normally, if there is a process already running in `python-buffer', 1330switch to that buffer. Interactively, a prefix arg allows you to edit 1331the initial command line (default is `python-command'); `-i' etc. args 1332will be added to this as appropriate. A new process is started if: 1333one isn't running attached to `python-buffer', or interactively the 1334default `python-command', or argument NEW is non-nil. See also the 1335documentation for `python-buffer'. 1336 1337Runs the hook `inferior-python-mode-hook' \(after the 1338`comint-mode-hook' is run). \(Type \\[describe-mode] in the process 1339buffer for a list of commands.)" 1340 (interactive (if current-prefix-arg 1341 (list (read-string "Run Python: " python-command) nil t) 1342 (list python-command))) 1343 (unless cmd (setq cmd python-python-command)) 1344 (setq python-command cmd) 1345 ;; Fixme: Consider making `python-buffer' buffer-local as a buffer 1346 ;; (not a name) in Python buffers from which `run-python' &c is 1347 ;; invoked. Would support multiple processes better. 1348 (when (or new (not (comint-check-proc python-buffer))) 1349 (with-current-buffer 1350 (let* ((cmdlist 1351 (append (python-args-to-list cmd) 1352 '("-i" "-c" "import sys; sys.path.remove('')"))) 1353 (path (getenv "PYTHONPATH")) 1354 (process-environment ; to import emacs.py 1355 (cons (concat "PYTHONPATH=" data-directory 1356 (if path (concat ":" path))) 1357 process-environment))) 1358 (apply 'make-comint-in-buffer "Python" 1359 (if new (generate-new-buffer "*Python*") "*Python*") 1360 (car cmdlist) nil (cdr cmdlist))) 1361 (setq-default python-buffer (current-buffer)) 1362 (setq python-buffer (current-buffer)) 1363 (accept-process-output (get-buffer-process python-buffer) 5) 1364 (inferior-python-mode) 1365 ;; Load function definitions we need. 1366 ;; Before the preoutput function was used, this was done via -c in 1367 ;; cmdlist, but that loses the banner and doesn't run the startup 1368 ;; file. The code might be inline here, but there's enough that it 1369 ;; seems worth putting in a separate file, and it's probably cleaner 1370 ;; to put it in a module. 1371 ;; Ensure we're at a prompt before doing anything else. 1372 (python-send-receive "import emacs; print '_emacs_out ()'"))) 1373 (if (derived-mode-p 'python-mode) 1374 (setq python-buffer (default-value 'python-buffer))) ; buffer-local 1375 ;; Without this, help output goes into the inferior python buffer if 1376 ;; the process isn't already running. 1377 (sit-for 1 t) ;Should we use accept-process-output instead? --Stef 1378 (unless noshow (pop-to-buffer python-buffer t))) 1379 1380;; Fixme: We typically lose if the inferior isn't in the normal REPL, 1381;; e.g. prompt is `help> '. Probably raise an error if the form of 1382;; the prompt is unexpected. Actually, it needs to be `>>> ', not 1383;; `... ', i.e. we're not inputting a block &c. However, this may not 1384;; be the place to check it, e.g. we might actually want to send 1385;; commands having set up such a state. 1386 1387(defun python-send-command (command) 1388 "Like `python-send-string' but resets `compilation-shell-minor-mode'. 1389COMMAND should be a single statement." 1390 ;; (assert (not (string-match "\n" command))) 1391 ;; (let ((end (marker-position (process-mark (python-proc))))) 1392 (with-current-buffer (process-buffer (python-proc)) 1393 (goto-char (point-max)) 1394 (compilation-forget-errors) 1395 (python-send-string command) 1396 (setq compilation-last-buffer (current-buffer))) 1397 ;; No idea what this is for but it breaks the call to 1398 ;; compilation-fake-loc in python-send-region. -- Stef 1399 ;; Must wait until this has completed before re-setting variables below. 1400 ;; (python-send-receive "print '_emacs_out ()'") 1401 ;; (with-current-buffer python-buffer 1402 ;; (set-marker compilation-parsing-end end)) 1403 ) ;;) 1404 1405(defun python-send-region (start end) 1406 "Send the region to the inferior Python process." 1407 ;; The region is evaluated from a temporary file. This avoids 1408 ;; problems with blank lines, which have different semantics 1409 ;; interactively and in files. It also saves the inferior process 1410 ;; buffer filling up with interpreter prompts. We need a Python 1411 ;; function to remove the temporary file when it has been evaluated 1412 ;; (though we could probably do it in Lisp with a Comint output 1413 ;; filter). This function also catches exceptions and truncates 1414 ;; tracebacks not to mention the frame of the function itself. 1415 ;; 1416 ;; The `compilation-shell-minor-mode' parsing takes care of relating 1417 ;; the reference to the temporary file to the source. 1418 ;; 1419 ;; Fixme: Write a `coding' header to the temp file if the region is 1420 ;; non-ASCII. 1421 (interactive "r") 1422 (let* ((f (make-temp-file "py")) 1423 (command (format "emacs.eexecfile(%S)" f)) 1424 (orig-start (copy-marker start))) 1425 (when (save-excursion 1426 (goto-char start) 1427 (/= 0 (current-indentation))) ; need dummy block 1428 (save-excursion 1429 (goto-char orig-start) 1430 ;; Wrong if we had indented code at buffer start. 1431 (set-marker orig-start (line-beginning-position 0))) 1432 (write-region "if True:\n" nil f nil 'nomsg)) 1433 (write-region start end f t 'nomsg) 1434 (python-send-command command) 1435 (with-current-buffer (process-buffer (python-proc)) 1436 ;; Tell compile.el to redirect error locations in file `f' to 1437 ;; positions past marker `orig-start'. It has to be done *after* 1438 ;; `python-send-command''s call to `compilation-forget-errors'. 1439 (compilation-fake-loc orig-start f)))) 1440 1441(defun python-send-string (string) 1442 "Evaluate STRING in inferior Python process." 1443 (interactive "sPython command: ") 1444 (comint-send-string (python-proc) string) 1445 (unless (string-match "\n\\'" string) 1446 ;; Make sure the text is properly LF-terminated. 1447 (comint-send-string (python-proc) "\n")) 1448 (when (string-match "\n[ \t].*\n?\\'" string) 1449 ;; If the string contains a final indented line, add a second newline so 1450 ;; as to make sure we terminate the multiline instruction. 1451 (comint-send-string (python-proc) "\n"))) 1452 1453(defun python-send-buffer () 1454 "Send the current buffer to the inferior Python process." 1455 (interactive) 1456 (python-send-region (point-min) (point-max))) 1457 1458;; Fixme: Try to define the function or class within the relevant 1459;; module, not just at top level. 1460(defun python-send-defun () 1461 "Send the current defun (class or method) to the inferior Python process." 1462 (interactive) 1463 (save-excursion (python-send-region (progn (beginning-of-defun) (point)) 1464 (progn (end-of-defun) (point))))) 1465 1466(defun python-switch-to-python (eob-p) 1467 "Switch to the Python process buffer, maybe starting new process. 1468With prefix arg, position cursor at end of buffer." 1469 (interactive "P") 1470 (pop-to-buffer (process-buffer (python-proc)) t) ;Runs python if needed. 1471 (when eob-p 1472 (push-mark) 1473 (goto-char (point-max)))) 1474 1475(defun python-send-region-and-go (start end) 1476 "Send the region to the inferior Python process. 1477Then switch to the process buffer." 1478 (interactive "r") 1479 (python-send-region start end) 1480 (python-switch-to-python t)) 1481 1482(defcustom python-source-modes '(python-mode jython-mode) 1483 "Used to determine if a buffer contains Python source code. 1484If a file is loaded into a buffer that is in one of these major modes, 1485it is considered Python source by `python-load-file', which uses the 1486value to determine defaults." 1487 :type '(repeat function) 1488 :group 'python) 1489 1490(defvar python-prev-dir/file nil 1491 "Caches (directory . file) pair used in the last `python-load-file' command. 1492Used for determining the default in the next one.") 1493 1494(autoload 'comint-get-source "comint") 1495 1496(defun python-load-file (file-name) 1497 "Load a Python file FILE-NAME into the inferior Python process. 1498If the file has extension `.py' import or reload it as a module. 1499Treating it as a module keeps the global namespace clean, provides 1500function location information for debugging, and supports users of 1501module-qualified names." 1502 (interactive (comint-get-source "Load Python file: " python-prev-dir/file 1503 python-source-modes 1504 t)) ; because execfile needs exact name 1505 (comint-check-source file-name) ; Check to see if buffer needs saving. 1506 (setq python-prev-dir/file (cons (file-name-directory file-name) 1507 (file-name-nondirectory file-name))) 1508 (with-current-buffer (process-buffer (python-proc)) ;Runs python if needed. 1509 ;; Fixme: I'm not convinced by this logic from python-mode.el. 1510 (python-send-command 1511 (if (string-match "\\.py\\'" file-name) 1512 (let ((module (file-name-sans-extension 1513 (file-name-nondirectory file-name)))) 1514 (format "emacs.eimport(%S,%S)" 1515 module (file-name-directory file-name))) 1516 (format "execfile(%S)" file-name))) 1517 (message "%s loaded" file-name))) 1518 1519(defun python-proc () 1520 "Return the current Python process. 1521See variable `python-buffer'. Starts a new process if necessary." 1522 ;; Fixme: Maybe should look for another active process if there 1523 ;; isn't one for `python-buffer'. 1524 (unless (comint-check-proc python-buffer) 1525 (run-python nil t)) 1526 (get-buffer-process (if (derived-mode-p 'inferior-python-mode) 1527 (current-buffer) 1528 python-buffer))) 1529 1530(defun python-set-proc () 1531 "Set the default value of `python-buffer' to correspond to this buffer. 1532If the current buffer has a local value of `python-buffer', set the 1533default (global) value to that. The associated Python process is 1534the one that gets input from \\[python-send-region] et al when used 1535in a buffer that doesn't have a local value of `python-buffer'." 1536 (interactive) 1537 (if (local-variable-p 'python-buffer) 1538 (setq-default python-buffer python-buffer) 1539 (error "No local value of `python-buffer'"))) 1540 1541;;;; Context-sensitive help. 1542 1543(defconst python-dotty-syntax-table 1544 (let ((table (make-syntax-table))) 1545 (set-char-table-parent table python-mode-syntax-table) 1546 (modify-syntax-entry ?. "_" table) 1547 table) 1548 "Syntax table giving `.' symbol syntax. 1549Otherwise inherits from `python-mode-syntax-table'.") 1550 1551(defvar view-return-to-alist) 1552(eval-when-compile (autoload 'help-buffer "help-fns")) 1553 1554(defvar python-imports) ; forward declaration 1555 1556;; Fixme: Should this actually be used instead of info-look, i.e. be 1557;; bound to C-h S? [Probably not, since info-look may work in cases 1558;; where this doesn't.] 1559(defun python-describe-symbol (symbol) 1560 "Get help on SYMBOL using `help'. 1561Interactively, prompt for symbol. 1562 1563Symbol may be anything recognized by the interpreter's `help' 1564command -- e.g. `CALLS' -- not just variables in scope in the 1565interpreter. This only works for Python version 2.2 or newer 1566since earlier interpreters don't support `help'. 1567 1568In some cases where this doesn't find documentation, \\[info-lookup-symbol] 1569will." 1570 ;; Note that we do this in the inferior process, not a separate one, to 1571 ;; ensure the environment is appropriate. 1572 (interactive 1573 (let ((symbol (with-syntax-table python-dotty-syntax-table 1574 (current-word))) 1575 (enable-recursive-minibuffers t)) 1576 (list (read-string (if symbol 1577 (format "Describe symbol (default %s): " symbol) 1578 "Describe symbol: ") 1579 nil nil symbol)))) 1580 (if (equal symbol "") (error "No symbol")) 1581 ;; Ensure we have a suitable help buffer. 1582 ;; Fixme: Maybe process `Related help topics' a la help xrefs and 1583 ;; allow C-c C-f in help buffer. 1584 (let ((temp-buffer-show-hook ; avoid xref stuff 1585 (lambda () 1586 (toggle-read-only 1) 1587 (setq view-return-to-alist 1588 (list (cons (selected-window) help-return-method)))))) 1589 (with-output-to-temp-buffer (help-buffer) 1590 (with-current-buffer standard-output 1591 ;; Fixme: Is this actually useful? 1592 (help-setup-xref (list 'python-describe-symbol symbol) (interactive-p)) 1593 (set (make-local-variable 'comint-redirect-subvert-readonly) t) 1594 (print-help-return-message)))) 1595 (comint-redirect-send-command-to-process (format "emacs.ehelp(%S, %s)" 1596 symbol python-imports) 1597 "*Help*" (python-proc) nil nil)) 1598 1599(add-to-list 'debug-ignored-errors "^No symbol") 1600 1601(defun python-send-receive (string) 1602 "Send STRING to inferior Python (if any) and return result. 1603The result is what follows `_emacs_out' in the output." 1604 (python-send-string string) 1605 (let ((proc (python-proc))) 1606 (with-current-buffer (process-buffer proc) 1607 (set (make-local-variable 'python-preoutput-result) nil) 1608 (while (progn 1609 (accept-process-output proc 5) 1610 (null python-preoutput-result))) 1611 (prog1 python-preoutput-result 1612 (kill-local-variable 'python-preoutput-result))))) 1613 1614;; Fixme: Is there anything reasonable we can do with random methods? 1615;; (Currently only works with functions.) 1616(defun python-eldoc-function () 1617 "`eldoc-print-current-symbol-info' for Python. 1618Only works when point is in a function name, not its arg list, for 1619instance. Assumes an inferior Python is running." 1620 (let ((symbol (with-syntax-table python-dotty-syntax-table 1621 (current-word)))) 1622 ;; This is run from timers, so inhibit-quit tends to be set. 1623 (with-local-quit 1624 ;; First try the symbol we're on. 1625 (or (and symbol 1626 (python-send-receive (format "emacs.eargs(%S, %s)" 1627 symbol python-imports))) 1628 ;; Try moving to symbol before enclosing parens. 1629 (let ((s (syntax-ppss))) 1630 (unless (zerop (car s)) 1631 (when (eq ?\( (char-after (nth 1 s))) 1632 (save-excursion 1633 (goto-char (nth 1 s)) 1634 (skip-syntax-backward "-") 1635 (let ((point (point))) 1636 (skip-chars-backward "a-zA-Z._") 1637 (if (< (point) point) 1638 (python-send-receive 1639 (format "emacs.eargs(%S, %s)" 1640 (buffer-substring-no-properties (point) point) 1641 python-imports)))))))))))) 1642 1643;;;; Info-look functionality. 1644 1645(defun python-after-info-look () 1646 "Set up info-look for Python. 1647Used with `eval-after-load'." 1648 (let* ((version (let ((s (shell-command-to-string (concat python-command 1649 " -V")))) 1650 (string-match "^Python \\([0-9]+\\.[0-9]+\\>\\)" s) 1651 (match-string 1 s))) 1652 ;; Whether info files have a Python version suffix, e.g. in Debian. 1653 (versioned 1654 (with-temp-buffer 1655 (with-no-warnings (Info-mode)) 1656 (condition-case () 1657 ;; Don't use `info' because it would pop-up a *info* buffer. 1658 (with-no-warnings 1659 (Info-goto-node (format "(python%s-lib)Miscellaneous Index" 1660 version)) 1661 t) 1662 (error nil))))) 1663 (info-lookup-maybe-add-help 1664 :mode 'python-mode 1665 :regexp "[[:alnum:]_]+" 1666 :doc-spec 1667 ;; Fixme: Can this reasonably be made specific to indices with 1668 ;; different rules? Is the order of indices optimal? 1669 ;; (Miscellaneous in -ref first prefers lookup of keywords, for 1670 ;; instance.) 1671 (if versioned 1672 ;; The empty prefix just gets us highlighted terms. 1673 `((,(concat "(python" version "-ref)Miscellaneous Index") nil "") 1674 (,(concat "(python" version "-ref)Module Index" nil "")) 1675 (,(concat "(python" version "-ref)Function-Method-Variable Index" 1676 nil "")) 1677 (,(concat "(python" version "-ref)Class-Exception-Object Index" 1678 nil "")) 1679 (,(concat "(python" version "-lib)Module Index" nil "")) 1680 (,(concat "(python" version "-lib)Class-Exception-Object Index" 1681 nil "")) 1682 (,(concat "(python" version "-lib)Function-Method-Variable Index" 1683 nil "")) 1684 (,(concat "(python" version "-lib)Miscellaneous Index" nil ""))) 1685 '(("(python-ref)Miscellaneous Index" nil "") 1686 ("(python-ref)Module Index" nil "") 1687 ("(python-ref)Function-Method-Variable Index" nil "") 1688 ("(python-ref)Class-Exception-Object Index" nil "") 1689 ("(python-lib)Module Index" nil "") 1690 ("(python-lib)Class-Exception-Object Index" nil "") 1691 ("(python-lib)Function-Method-Variable Index" nil "") 1692 ("(python-lib)Miscellaneous Index" nil "")))))) 1693(eval-after-load "info-look" '(python-after-info-look)) 1694 1695;;;; Miscellany. 1696 1697(defcustom python-jython-packages '("java" "javax" "org" "com") 1698 "Packages implying `jython-mode'. 1699If these are imported near the beginning of the buffer, `python-mode' 1700actually punts to `jython-mode'." 1701 :type '(repeat string) 1702 :group 'python) 1703 1704;; Called from `python-mode', this causes a recursive call of the 1705;; mode. See logic there to break out of the recursion. 1706(defun python-maybe-jython () 1707 "Invoke `jython-mode' if the buffer appears to contain Jython code. 1708The criterion is either a match for `jython-mode' via 1709`interpreter-mode-alist' or an import of a module from the list 1710`python-jython-packages'." 1711 ;; The logic is taken from python-mode.el. 1712 (save-excursion 1713 (save-restriction 1714 (widen) 1715 (goto-char (point-min)) 1716 (let ((interpreter (if (looking-at auto-mode-interpreter-regexp) 1717 (match-string 2)))) 1718 (if (and interpreter (eq 'jython-mode 1719 (cdr (assoc (file-name-nondirectory 1720 interpreter) 1721 interpreter-mode-alist)))) 1722 (jython-mode) 1723 (if (catch 'done 1724 (while (re-search-forward 1725 (rx line-start (or "import" "from") (1+ space) 1726 (group (1+ (not (any " \t\n."))))) 1727 (+ (point-min) 10000) ; Probably not worth customizing. 1728 t) 1729 (if (member (match-string 1) python-jython-packages) 1730 (throw 'done t)))) 1731 (jython-mode))))))) 1732 1733(defun python-fill-paragraph (&optional justify) 1734 "`fill-paragraph-function' handling comments and multi-line strings. 1735If any of the current line is a comment, fill the comment or the 1736paragraph of it that point is in, preserving the comment's 1737indentation and initial comment characters. Similarly if the end 1738of the current line is in or at the end of a multi-line string. 1739Otherwise, do nothing." 1740 (interactive "P") 1741 (or (fill-comment-paragraph justify) 1742 ;; The `paragraph-start' and `paragraph-separate' variables 1743 ;; don't allow us to delimit the last paragraph in a multi-line 1744 ;; string properly, so narrow to the string and then fill around 1745 ;; (the end of) the current line. 1746 (save-excursion 1747 (end-of-line) 1748 (let* ((syntax (syntax-ppss)) 1749 (orig (point)) 1750 (start (nth 8 syntax)) 1751 end) 1752 (cond ((eq t (nth 3 syntax)) ; in fenced string 1753 (goto-char (nth 8 syntax)) ; string start 1754 (setq end (condition-case () ; for unbalanced quotes 1755 (progn (forward-sexp) (point)) 1756 (error (point-max))))) 1757 ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced 1758 ; string 1759 (forward-char) 1760 (setq end (point)) 1761 (condition-case () 1762 (progn (backward-sexp) 1763 (setq start (point))) 1764 (error (setq end nil))))) 1765 (when end 1766 (save-restriction 1767 (narrow-to-region start end) 1768 (goto-char orig) 1769 (let ((paragraph-separate 1770 ;; Make sure that fenced-string delimiters that stand 1771 ;; on their own line stay there. 1772 (concat "[ \t]*['\"]+[ \t]*$\\|" paragraph-separate))) 1773 (fill-paragraph justify)))))) 1774 t)) 1775 1776(defun python-shift-left (start end &optional count) 1777 "Shift lines in region COUNT (the prefix arg) columns to the left. 1778COUNT defaults to `python-indent'. If region isn't active, just shift 1779current line. The region shifted includes the lines in which START and 1780END lie. It is an error if any lines in the region are indented less than 1781COUNT columns." 1782 (interactive (if mark-active 1783 (list (region-beginning) (region-end) current-prefix-arg) 1784 (list (point) (point) current-prefix-arg))) 1785 (if count 1786 (setq count (prefix-numeric-value count)) 1787 (setq count python-indent)) 1788 (when (> count 0) 1789 (save-excursion 1790 (goto-char start) 1791 (while (< (point) end) 1792 (if (and (< (current-indentation) count) 1793 (not (looking-at "[ \t]*$"))) 1794 (error "Can't shift all lines enough")) 1795 (forward-line)) 1796 (indent-rigidly start end (- count))))) 1797 1798(add-to-list 'debug-ignored-errors "^Can't shift all lines enough") 1799 1800(defun python-shift-right (start end &optional count) 1801 "Shift lines in region COUNT (the prefix arg) columns to the right. 1802COUNT defaults to `python-indent'. If region isn't active, just shift 1803current line. The region shifted includes the lines in which START and 1804END lie." 1805 (interactive (if mark-active 1806 (list (region-beginning) (region-end) current-prefix-arg) 1807 (list (point) (point) current-prefix-arg))) 1808 (if count 1809 (setq count (prefix-numeric-value count)) 1810 (setq count python-indent)) 1811 (indent-rigidly start end count)) 1812 1813(defun python-outline-level () 1814 "`outline-level' function for Python mode. 1815The level is the number of `python-indent' steps of indentation 1816of current line." 1817 (1+ (/ (current-indentation) python-indent))) 1818 1819;; Fixme: Consider top-level assignments, imports, &c. 1820(defun python-current-defun () 1821 "`add-log-current-defun-function' for Python." 1822 (save-excursion 1823 ;; Move up the tree of nested `class' and `def' blocks until we 1824 ;; get to zero indentation, accumulating the defined names. 1825 (let ((start t) 1826 accum) 1827 (while (or start (> (current-indentation) 0)) 1828 (setq start nil) 1829 (python-beginning-of-block) 1830 (end-of-line) 1831 (beginning-of-defun) 1832 (if (looking-at (rx (0+ space) (or "def" "class") (1+ space) 1833 (group (1+ (or word (syntax symbol)))))) 1834 (push (match-string 1) accum))) 1835 (if accum (mapconcat 'identity accum "."))))) 1836 1837(defun python-mark-block () 1838 "Mark the block around point. 1839Uses `python-beginning-of-block', `python-end-of-block'." 1840 (interactive) 1841 (push-mark) 1842 (python-beginning-of-block) 1843 (push-mark (point) nil t) 1844 (python-end-of-block) 1845 (exchange-point-and-mark)) 1846 1847;; Fixme: Provide a find-function-like command to find source of a 1848;; definition (separate from BicycleRepairMan). Complicated by 1849;; finding the right qualified name. 1850 1851;;;; Completion. 1852 1853(defvar python-imports nil 1854 "String of top-level import statements updated by `python-find-imports'.") 1855(make-variable-buffer-local 'python-imports) 1856 1857;; Fixme: Should font-lock try to run this when it deals with an import? 1858;; Maybe not a good idea if it gets run multiple times when the 1859;; statement is being edited, and is more likely to end up with 1860;; something syntactically incorrect. 1861;; However, what we should do is to trundle up the block tree from point 1862;; to extract imports that appear to be in scope, and add those. 1863(defun python-find-imports () 1864 "Find top-level imports, updating `python-imports'." 1865 (interactive) 1866 (save-excursion 1867 (let (lines) 1868 (goto-char (point-min)) 1869 (while (re-search-forward "^import\\>\\|^from\\>" nil t) 1870 (unless (syntax-ppss-context (syntax-ppss)) 1871 (push (buffer-substring (line-beginning-position) 1872 (line-beginning-position 2)) 1873 lines))) 1874 (setq python-imports 1875 (if lines 1876 (apply #'concat 1877;; This is probably best left out since you're unlikely to need the 1878;; doc for a function in the buffer and the import will lose if the 1879;; Python sub-process' working directory isn't the same as the 1880;; buffer's. 1881;; (if buffer-file-name 1882;; (concat 1883;; "import " 1884;; (file-name-sans-extension 1885;; (file-name-nondirectory buffer-file-name)))) 1886 (nreverse lines)) 1887 "None")) 1888 (when lines 1889 (set-text-properties 0 (length python-imports) nil python-imports) 1890 ;; The output ends up in the wrong place if the string we 1891 ;; send contains newlines (from the imports). 1892 (setq python-imports 1893 (replace-regexp-in-string "\n" "\\n" 1894 (format "%S" python-imports) t t)))))) 1895 1896;; Fixme: This fails the first time if the sub-process isn't already 1897;; running. Presumably a timing issue with i/o to the process. 1898(defun python-symbol-completions (symbol) 1899 "Return a list of completions of the string SYMBOL from Python process. 1900The list is sorted. 1901Uses `python-imports' to load modules against which to complete." 1902 (when symbol 1903 (let ((completions 1904 (condition-case () 1905 (car (read-from-string 1906 (python-send-receive 1907 (format "emacs.complete(%S,%s)" symbol python-imports)))) 1908 (error nil)))) 1909 (sort 1910 ;; We can get duplicates from the above -- don't know why. 1911 (delete-dups completions) 1912 #'string<)))) 1913 1914(defun python-partial-symbol () 1915 "Return the partial symbol before point (for completion)." 1916 (let ((end (point)) 1917 (start (save-excursion 1918 (and (re-search-backward 1919 (rx (or buffer-start (regexp "[^[:alnum:]._]")) 1920 (group (1+ (regexp "[[:alnum:]._]"))) point) 1921 nil t) 1922 (match-beginning 1))))) 1923 (if start (buffer-substring-no-properties start end)))) 1924 1925(defun python-complete-symbol () 1926 "Perform completion on the Python symbol preceding point. 1927Repeating the command scrolls the completion window." 1928 (interactive) 1929 (let ((window (get-buffer-window "*Completions*"))) 1930 (if (and (eq last-command this-command) 1931 window (window-live-p window) (window-buffer window) 1932 (buffer-name (window-buffer window))) 1933 (with-current-buffer (window-buffer window) 1934 (if (pos-visible-in-window-p (point-max) window) 1935 (set-window-start window (point-min)) 1936 (save-selected-window 1937 (select-window window) 1938 (scroll-up)))) 1939 ;; Do completion. 1940 (let* ((end (point)) 1941 (symbol (python-partial-symbol)) 1942 (completions (python-symbol-completions symbol)) 1943 (completion (if completions 1944 (try-completion symbol completions)))) 1945 (when symbol 1946 (cond ((eq completion t)) 1947 ((null completion) 1948 (message "Can't find completion for \"%s\"" symbol) 1949 (ding)) 1950 ((not (string= symbol completion)) 1951 (delete-region (- end (length symbol)) end) 1952 (insert completion)) 1953 (t 1954 (message "Making completion list...") 1955 (with-output-to-temp-buffer "*Completions*" 1956 (display-completion-list completions symbol)) 1957 (message "Making completion list...%s" "done")))))))) 1958 1959(defun python-try-complete (old) 1960 "Completion function for Python for use with `hippie-expand'." 1961 (when (derived-mode-p 'python-mode) ; though we only add it locally 1962 (unless old 1963 (let ((symbol (python-partial-symbol))) 1964 (he-init-string (- (point) (length symbol)) (point)) 1965 (if (not (he-string-member he-search-string he-tried-table)) 1966 (push he-search-string he-tried-table)) 1967 (setq he-expand-list 1968 (and symbol (python-symbol-completions symbol))))) 1969 (while (and he-expand-list 1970 (he-string-member (car he-expand-list) he-tried-table)) 1971 (pop he-expand-list)) 1972 (if he-expand-list 1973 (progn 1974 (he-substitute-string (pop he-expand-list)) 1975 t) 1976 (if old (he-reset-string)) 1977 nil))) 1978 1979;;;; FFAP support 1980 1981(defun python-module-path (module) 1982 "Function for `ffap-alist' to return path to MODULE." 1983 (python-send-receive (format "emacs.modpath (%S)" module))) 1984 1985(eval-after-load "ffap" 1986 '(push '(python-mode . python-module-path) ffap-alist)) 1987 1988;;;; Skeletons 1989 1990(defcustom python-use-skeletons nil 1991 "Non-nil means template skeletons will be automagically inserted. 1992This happens when pressing \"if<SPACE>\", for example, to prompt for 1993the if condition." 1994 :type 'boolean 1995 :group 'python) 1996 1997(defvar python-skeletons nil 1998 "Alist of named skeletons for Python mode. 1999Elements are of the form (NAME . EXPANDER-FUNCTION).") 2000 2001(defvar python-mode-abbrev-table nil 2002 "Abbrev table for Python mode. 2003The default contents correspond to the elements of `python-skeletons'.") 2004(define-abbrev-table 'python-mode-abbrev-table ()) 2005 2006(eval-when-compile 2007 ;; Define a user-level skeleton and add it to `python-skeletons' and 2008 ;; the abbrev table. 2009(defmacro def-python-skeleton (name &rest elements) 2010 (let* ((name (symbol-name name)) 2011 (function (intern (concat "python-insert-" name)))) 2012 `(progn 2013 (add-to-list 'python-skeletons ',(cons name function)) 2014 (if python-use-skeletons 2015 (define-abbrev python-mode-abbrev-table ,name "" ',function nil t)) 2016 (define-skeleton ,function 2017 ,(format "Insert Python \"%s\" template." name) 2018 ,@elements))))) 2019(put 'def-python-skeleton 'lisp-indent-function 2) 2020 2021;; From `skeleton-further-elements': 2022;; `<': outdent a level; 2023;; `^': delete indentation on current line and also previous newline. 2024;; Not quote like `delete-indentation'. Assumes point is at 2025;; beginning of indentation. 2026 2027(def-python-skeleton if 2028 "Condition: " 2029 "if " str ":" \n 2030 > _ \n 2031 ("other condition, %s: " 2032 < ; Avoid wrong indentation after block opening. 2033 "elif " str ":" \n 2034 > _ \n nil) 2035 (python-else) | ^) 2036 2037(define-skeleton python-else 2038 "Auxiliary skeleton." 2039 nil 2040 (unless (eq ?y (read-char "Add `else' clause? (y for yes or RET for no) ")) 2041 (signal 'quit t)) 2042 < "else:" \n 2043 > _ \n) 2044 2045(def-python-skeleton while 2046 "Condition: " 2047 "while " str ":" \n 2048 > _ \n 2049 (python-else) | ^) 2050 2051(def-python-skeleton for 2052 "Target, %s: " 2053 "for " str " in " (skeleton-read "Expression, %s: ") ":" \n 2054 > _ \n 2055 (python-else) | ^) 2056 2057(def-python-skeleton try/except 2058 nil 2059 "try:" \n 2060 > _ \n 2061 ("Exception, %s: " 2062 < "except " str (python-target) ":" \n 2063 > _ \n nil) 2064 < "except:" \n 2065 > _ \n 2066 (python-else) | ^) 2067 2068(define-skeleton python-target 2069 "Auxiliary skeleton." 2070 "Target, %s: " ", " str | -2) 2071 2072(def-python-skeleton try/finally 2073 nil 2074 "try:" \n 2075 > _ \n 2076 < "finally:" \n 2077 > _ \n) 2078 2079(def-python-skeleton def 2080 "Name: " 2081 "def " str " (" ("Parameter, %s: " (unless (equal ?\( (char-before)) ", ") 2082 str) "):" \n 2083 "\"\"\"" @ " \"\"\"" \n ; Fixme: syntaxification wrong for """""" 2084 > _ \n) 2085 2086(def-python-skeleton class 2087 "Name: " 2088 "class " str " (" ("Inheritance, %s: " 2089 (unless (equal ?\( (char-before)) ", ") 2090 str) 2091 & ")" | -2 ; close list or remove opening 2092 ":" \n 2093 "\"\"\"" @ " \"\"\"" \n 2094 > _ \n) 2095 2096(defvar python-default-template "if" 2097 "Default template to expand by `python-expand-template'. 2098Updated on each expansion.") 2099 2100(defun python-expand-template (name) 2101 "Expand template named NAME. 2102Interactively, prompt for the name with completion." 2103 (interactive 2104 (list (completing-read (format "Template to expand (default %s): " 2105 python-default-template) 2106 python-skeletons nil t))) 2107 (if (equal "" name) 2108 (setq name python-default-template) 2109 (setq python-default-template name)) 2110 (let ((func (cdr (assoc name python-skeletons)))) 2111 (if func 2112 (funcall func) 2113 (error "Undefined template: %s" name)))) 2114 2115;;;; Bicycle Repair Man support 2116 2117(autoload 'pymacs-load "pymacs" nil t) 2118(autoload 'brm-init "bikemacs") 2119 2120;; I'm not sure how useful BRM really is, and it's certainly dangerous 2121;; the way it modifies files outside Emacs... Also note that the 2122;; current BRM loses with tabs used for indentation -- I submitted a 2123;; fix <URL:http://www.loveshack.ukfsn.org/emacs/bikeemacs.py.diff>. 2124(defun python-setup-brm () 2125 "Set up Bicycle Repair Man refactoring tool (if available). 2126 2127Note that the `refactoring' features change files independently of 2128Emacs and may modify and save the contents of the current buffer 2129without confirmation." 2130 (interactive) 2131 (condition-case data 2132 (unless (fboundp 'brm-rename) 2133 (pymacs-load "bikeemacs" "brm-") ; first line of normal recipe 2134 (let ((py-mode-map (make-sparse-keymap)) ; it assumes this 2135 (features (cons 'python-mode features))) ; and requires this 2136 (brm-init)) ; second line of normal recipe 2137 (remove-hook 'python-mode-hook ; undo this from `brm-init' 2138 '(lambda () (easy-menu-add brm-menu))) 2139 (easy-menu-define 2140 python-brm-menu python-mode-map 2141 "Bicycle Repair Man" 2142 '("BicycleRepairMan" 2143 :help "Interface to navigation and refactoring tool" 2144 "Queries" 2145 ["Find References" brm-find-references 2146 :help "Find references to name at point in compilation buffer"] 2147 ["Find Definition" brm-find-definition 2148 :help "Find definition of name at point"] 2149 "-" 2150 "Refactoring" 2151 ["Rename" brm-rename 2152 :help "Replace name at point with a new name everywhere"] 2153 ["Extract Method" brm-extract-method 2154 :active (and mark-active (not buffer-read-only)) 2155 :help "Replace statements in region with a method"] 2156 ["Extract Local Variable" brm-extract-local-variable 2157 :active (and mark-active (not buffer-read-only)) 2158 :help "Replace expression in region with an assignment"] 2159 ["Inline Local Variable" brm-inline-local-variable 2160 :help 2161 "Substitute uses of variable at point with its definition"] 2162 ;; Fixme: Should check for anything to revert. 2163 ["Undo Last Refactoring" brm-undo :help ""]))) 2164 (error (error "Bicyclerepairman setup failed: %s" data)))) 2165 2166;;;; Modes. 2167 2168(defvar outline-heading-end-regexp) 2169(defvar eldoc-documentation-function) 2170 2171;; Stuff to allow expanding abbrevs with non-word constituents. 2172(defun python-abbrev-pc-hook () 2173 "Set the syntax table before possibly expanding abbrevs." 2174 (remove-hook 'post-command-hook 'python-abbrev-pc-hook t) 2175 (set-syntax-table python-mode-syntax-table)) 2176 2177(defvar python-abbrev-syntax-table 2178 (copy-syntax-table python-mode-syntax-table) 2179 "Syntax table used when expanding abbrevs.") 2180 2181(defun python-pea-hook () 2182 "Reset the syntax table after possibly expanding abbrevs." 2183 (set-syntax-table python-abbrev-syntax-table) 2184 (add-hook 'post-command-hook 'python-abbrev-pc-hook nil t)) 2185(modify-syntax-entry ?/ "w" python-abbrev-syntax-table) 2186 2187(defvar python-mode-running) ;Dynamically scoped var. 2188 2189;;;###autoload 2190(define-derived-mode python-mode fundamental-mode "Python" 2191 "Major mode for editing Python files. 2192Font Lock mode is currently required for correct parsing of the source. 2193See also `jython-mode', which is actually invoked if the buffer appears to 2194contain Jython code. See also `run-python' and associated Python mode 2195commands for running Python under Emacs. 2196 2197The Emacs commands which work with `defun's, e.g. \\[beginning-of-defun], deal 2198with nested `def' and `class' blocks. They take the innermost one as 2199current without distinguishing method and class definitions. Used multiple 2200times, they move over others at the same indentation level until they reach 2201the end of definitions at that level, when they move up a level. 2202\\<python-mode-map> 2203Colon is electric: it outdents the line if appropriate, e.g. for 2204an else statement. \\[python-backspace] at the beginning of an indented statement 2205deletes a level of indentation to close the current block; otherwise it 2206deletes a character backward. TAB indents the current line relative to 2207the preceding code. Successive TABs, with no intervening command, cycle 2208through the possibilities for indentation on the basis of enclosing blocks. 2209 2210\\[fill-paragraph] fills comments and multi-line strings appropriately, but has no 2211effect outside them. 2212 2213Supports Eldoc mode (only for functions, using a Python process), 2214Info-Look and Imenu. In Outline minor mode, `class' and `def' 2215lines count as headers. Symbol completion is available in the 2216same way as in the Python shell using the `rlcompleter' module 2217and this is added to the Hippie Expand functions locally if 2218Hippie Expand mode is turned on. Completion of symbols of the 2219form x.y only works if the components are literal 2220module/attribute names, not variables. An abbrev table is set up 2221with skeleton expansions for compound statement templates. 2222 2223\\{python-mode-map}" 2224 :group 'python 2225 (set (make-local-variable 'font-lock-defaults) 2226 '(python-font-lock-keywords nil nil nil nil 2227 (font-lock-syntactic-keywords 2228 . python-font-lock-syntactic-keywords) 2229 ;; This probably isn't worth it. 2230 ;; (font-lock-syntactic-face-function 2231 ;; . python-font-lock-syntactic-face-function) 2232 )) 2233 (set (make-local-variable 'parse-sexp-lookup-properties) t) 2234 (set (make-local-variable 'parse-sexp-ignore-comments) t) 2235 (set (make-local-variable 'comment-start) "# ") 2236 (set (make-local-variable 'indent-line-function) #'python-indent-line) 2237 (set (make-local-variable 'indent-region-function) #'python-indent-region) 2238 (set (make-local-variable 'paragraph-start) "\\s-*$") 2239 (set (make-local-variable 'fill-paragraph-function) 'python-fill-paragraph) 2240 (set (make-local-variable 'require-final-newline) mode-require-final-newline) 2241 (set (make-local-variable 'add-log-current-defun-function) 2242 #'python-current-defun) 2243 (set (make-local-variable 'outline-regexp) 2244 (rx (* space) (or "class" "def" "elif" "else" "except" "finally" 2245 "for" "if" "try" "while" "with") 2246 symbol-end)) 2247 (set (make-local-variable 'outline-heading-end-regexp) ":\\s-*\n") 2248 (set (make-local-variable 'outline-level) #'python-outline-level) 2249 (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil) 2250 (make-local-variable 'python-saved-check-command) 2251 (set (make-local-variable 'beginning-of-defun-function) 2252 'python-beginning-of-defun) 2253 (set (make-local-variable 'end-of-defun-function) 'python-end-of-defun) 2254 (setq imenu-create-index-function #'python-imenu-create-index) 2255 (set (make-local-variable 'eldoc-documentation-function) 2256 #'python-eldoc-function) 2257 (add-hook 'eldoc-mode-hook 2258 (lambda () (run-python nil t)) ; need it running 2259 nil t) 2260 ;; Fixme: should be in hideshow. This seems to be of limited use 2261 ;; since it isn't (can't be) indentation-based. Also hide-level 2262 ;; doesn't seem to work properly. 2263 (add-to-list 'hs-special-modes-alist 2264 `(python-mode "^\\s-*def\\>" nil "#" 2265 ,(lambda (arg) 2266 (python-end-of-defun) 2267 (skip-chars-backward " \t\n")) 2268 nil)) 2269 (set (make-local-variable 'skeleton-further-elements) 2270 '((< '(backward-delete-char-untabify (min python-indent 2271 (current-column)))) 2272 (^ '(- (1+ (current-indentation)))))) 2273 (add-hook 'pre-abbrev-expand-hook 'python-pea-hook nil t) 2274 (if (featurep 'hippie-exp) 2275 (set (make-local-variable 'hippie-expand-try-functions-list) 2276 (cons 'python-try-complete hippie-expand-try-functions-list))) 2277 ;; Python defines TABs as being 8-char wide. 2278 (set (make-local-variable 'tab-width) 8) 2279 (when python-guess-indent (python-guess-indent)) 2280 ;; Let's make it harder for the user to shoot himself in the foot. 2281 (unless (= tab-width python-indent) 2282 (setq indent-tabs-mode nil)) 2283 (set (make-local-variable 'python-command) python-python-command) 2284 (python-find-imports) 2285 (unless (boundp 'python-mode-running) ; kill the recursion from jython-mode 2286 (let ((python-mode-running t)) 2287 (python-maybe-jython)))) 2288 2289(custom-add-option 'python-mode-hook 'imenu-add-menubar-index) 2290(custom-add-option 'python-mode-hook 2291 (lambda () 2292 "Turn off Indent Tabs mode." 2293 (set (make-local-variable 'indent-tabs-mode) nil))) 2294(custom-add-option 'python-mode-hook 'turn-on-eldoc-mode) 2295(custom-add-option 'python-mode-hook 'abbrev-mode) 2296(custom-add-option 'python-mode-hook 'python-setup-brm) 2297 2298;;;###autoload 2299(define-derived-mode jython-mode python-mode "Jython" 2300 "Major mode for editing Jython files. 2301Like `python-mode', but sets up parameters for Jython subprocesses. 2302Runs `jython-mode-hook' after `python-mode-hook'." 2303 :group 'python 2304 (set (make-local-variable 'python-command) python-jython-command)) 2305 2306(provide 'python) 2307(provide 'python-21) 2308;; arch-tag: 6fce1d99-a704-4de9-ba19-c6e4912b0554 2309;;; python.el ends here 2310