comparison .elisp/python-mode.el @ 175:4741c022c7ae

python-mode: apply patch from the python-mode list to fix triplequotes. This patch is originally by Andreas Roehler <andreas.roehler at online.de>. It was not applied because it works only in GNU Emacs based on list archives.
author Augie Fackler <durin42@gmail.com>
date Wed, 16 Dec 2009 22:59:38 -0600
parents 014e745b2d04
children
comparison
equal deleted inserted replaced
174:014e745b2d04 175:4741c022c7ae
6 ;; 1995-2002 Barry A. Warsaw 6 ;; 1995-2002 Barry A. Warsaw
7 ;; 1992-1994 Tim Peters 7 ;; 1992-1994 Tim Peters
8 ;; Maintainer: python-mode@python.org 8 ;; Maintainer: python-mode@python.org
9 ;; Created: Feb 1992 9 ;; Created: Feb 1992
10 ;; Keywords: python languages oop 10 ;; Keywords: python languages oop
11
11 12
12 (defconst py-version "5.1.0+" 13 (defconst py-version "5.1.0+"
13 "`python-mode' version number.") 14 "`python-mode' version number.")
14 15
15 ;; This file is part of python-mode.el. 16 ;; This file is part of python-mode.el.
382 (defvar py-line-number-offset 0 383 (defvar py-line-number-offset 0
383 "When an exception occurs as a result of py-execute-region, a 384 "When an exception occurs as a result of py-execute-region, a
384 subsequent py-up-exception needs the line number where the region 385 subsequent py-up-exception needs the line number where the region
385 started, in order to jump to the correct file line. This variable is 386 started, in order to jump to the correct file line. This variable is
386 set in py-execute-region and used in py-jump-to-exception.") 387 set in py-execute-region and used in py-jump-to-exception.")
388
389 ;; 2009-09-10 a.roehler@web.de changed section start
390 ;; from python.el, version "22.1"
391
392 (defconst python-font-lock-syntactic-keywords
393 ;; Make outer chars of matching triple-quote sequences into generic
394 ;; string delimiters. Fixme: Is there a better way?
395 ;; First avoid a sequence preceded by an odd number of backslashes.
396 `((,(rx (not (any ?\\))
397 ?\\ (* (and ?\\ ?\\))
398 (group (syntax string-quote))
399 (backref 1)
400 (group (backref 1)))
401 (2 ,(string-to-syntax "\""))) ; dummy
402 (,(rx (group (optional (any "uUrR"))) ; prefix gets syntax property
403 (optional (any "rR")) ; possible second prefix
404 (group (syntax string-quote)) ; maybe gets property
405 (backref 2) ; per first quote
406 (group (backref 2))) ; maybe gets property
407 (1 (python-quote-syntax 1))
408 (2 (python-quote-syntax 2))
409 (3 (python-quote-syntax 3)))
410 ;; This doesn't really help.
411 ;;; (,(rx (and ?\\ (group ?\n))) (1 " "))
412 ))
413
414 (defun python-quote-syntax (n)
415 "Put `syntax-table' property correctly on triple quote.
416 Used for syntactic keywords. N is the match number (1, 2 or 3)."
417 ;; Given a triple quote, we have to check the context to know
418 ;; whether this is an opening or closing triple or whether it's
419 ;; quoted anyhow, and should be ignored. (For that we need to do
420 ;; the same job as `syntax-ppss' to be correct and it seems to be OK
421 ;; to use it here despite initial worries.) We also have to sort
422 ;; out a possible prefix -- well, we don't _have_ to, but I think it
423 ;; should be treated as part of the string.
424
425 ;; Test cases:
426 ;; ur"""ar""" x='"' # """
427 ;; x = ''' """ ' a
428 ;; '''
429 ;; x '"""' x """ \"""" x
430 (save-excursion
431 (goto-char (match-beginning 0))
432 (cond
433 ;; Consider property for the last char if in a fenced string.
434 ((= n 3)
435 (let* ((font-lock-syntactic-keywords nil)
436 (syntax (syntax-ppss)))
437 (when (eq t (nth 3 syntax)) ; after unclosed fence
438 (goto-char (nth 8 syntax)) ; fence position
439 (skip-chars-forward "uUrR") ; skip any prefix
440 ;; Is it a matching sequence?
441 (if (eq (char-after) (char-after (match-beginning 2)))
442 (eval-when-compile (string-to-syntax "|"))))))
443 ;; Consider property for initial char, accounting for prefixes.
444 ((or (and (= n 2) ; leading quote (not prefix)
445 (= (match-beginning 1) (match-end 1))) ; prefix is null
446 (and (= n 1) ; prefix
447 (/= (match-beginning 1) (match-end 1)))) ; non-empty
448 (let ((font-lock-syntactic-keywords nil))
449 (unless (eq 'string (syntax-ppss-context (syntax-ppss)))
450 (eval-when-compile (string-to-syntax "|")))))
451 ;; Otherwise (we're in a non-matching string) the property is
452 ;; nil, which is OK.
453 )))
454
455
456 (defvar py-mode-syntax-table
457 (let ((table (make-syntax-table)))
458 ;; Give punctuation syntax to ASCII that normally has symbol
459 ;; syntax or has word syntax and isn't a letter.
460 (let ((symbol (string-to-syntax "_"))
461 (sst (standard-syntax-table)))
462 (dotimes (i 128)
463 (unless (= i ?_)
464 (if (equal symbol (aref sst i))
465 (modify-syntax-entry i "." table)))))
466 (modify-syntax-entry ?$ "." table)
467 (modify-syntax-entry ?% "." table)
468 ;; exceptions
469 (modify-syntax-entry ?# "<" table)
470 (modify-syntax-entry ?\n ">" table)
471 (modify-syntax-entry ?' "\"" table)
472 (modify-syntax-entry ?` "$" table)
473 table))
474
475 (defsubst python-in-string/comment ()
476 "Return non-nil if point is in a Python literal (a comment or string)."
477 ;; We don't need to save the match data.
478 (nth 8 (syntax-ppss)))
479
480 (defconst python-space-backslash-table
481 (let ((table (copy-syntax-table py-mode-syntax-table)))
482 (modify-syntax-entry ?\\ " " table)
483 table)
484 "`python-mode-syntax-table' with backslash given whitespace syntax.")
485
486 ;; 2009-09-10 a.roehler@web.de changed section end
387 487
388 (defconst py-emacs-features 488 (defconst py-emacs-features
389 (let (features) 489 (let (features)
390 features) 490 features)
391 "A list of features extant in the Emacs you are using. 491 "A list of features extant in the Emacs you are using.
503 1 py-pseudo-keyword-face) 603 1 py-pseudo-keyword-face)
504 ;; XXX, TODO, and FIXME tags 604 ;; XXX, TODO, and FIXME tags
505 '("XXX\\|TODO\\|FIXME" 0 py-XXX-tag-face t) 605 '("XXX\\|TODO\\|FIXME" 0 py-XXX-tag-face t)
506 )) 606 ))
507 "Additional expressions to highlight in Python mode.") 607 "Additional expressions to highlight in Python mode.")
508 (put 'python-mode 'font-lock-defaults '(python-font-lock-keywords))
509 608
510 ;; have to bind py-file-queue before installing the kill-emacs-hook 609 ;; have to bind py-file-queue before installing the kill-emacs-hook
511 (defvar py-file-queue nil 610 (defvar py-file-queue nil
512 "Queue of Python temp files awaiting execution. 611 "Queue of Python temp files awaiting execution.
513 Currently-active file is at the head of the list.") 612 Currently-active file is at the head of the list.")
725 (define-key py-shell-map [tab] 'tab-to-tab-stop) 824 (define-key py-shell-map [tab] 'tab-to-tab-stop)
726 (define-key py-shell-map "\C-c-" 'py-up-exception) 825 (define-key py-shell-map "\C-c-" 'py-up-exception)
727 (define-key py-shell-map "\C-c=" 'py-down-exception) 826 (define-key py-shell-map "\C-c=" 'py-down-exception)
728 ) 827 )
729 828
730 (defvar py-mode-syntax-table nil 829 ;; 2009-09-09 a.roehler@web.de changed section start
731 "Syntax table used in `python-mode' buffers.") 830 ;; from python.el, version "22.1"
732 (when (not py-mode-syntax-table) 831
733 (setq py-mode-syntax-table (make-syntax-table)) 832 ;; (defvar py-mode-syntax-table nil
734 (modify-syntax-entry ?\( "()" py-mode-syntax-table) 833 ;; "Syntax table used in `python-mode' buffers.")
735 (modify-syntax-entry ?\) ")(" py-mode-syntax-table) 834 ;; (when (not py-mode-syntax-table)
736 (modify-syntax-entry ?\[ "(]" py-mode-syntax-table) 835 ;; (setq py-mode-syntax-table (make-syntax-table))
737 (modify-syntax-entry ?\] ")[" py-mode-syntax-table) 836 ;; (modify-syntax-entry ?\( "()" py-mode-syntax-table)
738 (modify-syntax-entry ?\{ "(}" py-mode-syntax-table) 837 ;; (modify-syntax-entry ?\) ")(" py-mode-syntax-table)
739 (modify-syntax-entry ?\} "){" py-mode-syntax-table) 838 ;; (modify-syntax-entry ?\[ "(]" py-mode-syntax-table)
740 ;; Add operator symbols misassigned in the std table 839 ;; (modify-syntax-entry ?\] ")[" py-mode-syntax-table)
741 (modify-syntax-entry ?\$ "." py-mode-syntax-table) 840 ;; (modify-syntax-entry ?\{ "(}" py-mode-syntax-table)
742 (modify-syntax-entry ?\% "." py-mode-syntax-table) 841 ;; (modify-syntax-entry ?\} "){" py-mode-syntax-table)
743 (modify-syntax-entry ?\& "." py-mode-syntax-table) 842 ;; ;; Add operator symbols misassigned in the std table
744 (modify-syntax-entry ?\* "." py-mode-syntax-table) 843 ;; (modify-syntax-entry ?\$ "." py-mode-syntax-table)
745 (modify-syntax-entry ?\+ "." py-mode-syntax-table) 844 ;; (modify-syntax-entry ?\% "." py-mode-syntax-table)
746 (modify-syntax-entry ?\- "." py-mode-syntax-table) 845 ;; (modify-syntax-entry ?\& "." py-mode-syntax-table)
747 (modify-syntax-entry ?\/ "." py-mode-syntax-table) 846 ;; (modify-syntax-entry ?\* "." py-mode-syntax-table)
748 (modify-syntax-entry ?\< "." py-mode-syntax-table) 847 ;; (modify-syntax-entry ?\+ "." py-mode-syntax-table)
749 (modify-syntax-entry ?\= "." py-mode-syntax-table) 848 ;; (modify-syntax-entry ?\- "." py-mode-syntax-table)
750 (modify-syntax-entry ?\> "." py-mode-syntax-table) 849 ;; (modify-syntax-entry ?\/ "." py-mode-syntax-table)
751 (modify-syntax-entry ?\| "." py-mode-syntax-table) 850 ;; (modify-syntax-entry ?\< "." py-mode-syntax-table)
752 ;; For historical reasons, underscore is word class instead of 851 ;; (modify-syntax-entry ?\= "." py-mode-syntax-table)
753 ;; symbol class. GNU conventions say it should be symbol class, but 852 ;; (modify-syntax-entry ?\> "." py-mode-syntax-table)
754 ;; there's a natural conflict between what major mode authors want 853 ;; (modify-syntax-entry ?\| "." py-mode-syntax-table)
755 ;; and what users expect from `forward-word' and `backward-word'. 854 ;; ;; For historical reasons, underscore is word class instead of
756 ;; Guido and I have hashed this out and have decided to keep 855 ;; ;; symbol class. GNU conventions say it should be symbol class, but
757 ;; underscore in word class. If you're tempted to change it, try 856 ;; ;; there's a natural conflict between what major mode authors want
758 ;; binding M-f and M-b to py-forward-into-nomenclature and 857 ;; ;; and what users expect from `forward-word' and `backward-word'.
759 ;; py-backward-into-nomenclature instead. This doesn't help in all 858 ;; ;; Guido and I have hashed this out and have decided to keep
760 ;; situations where you'd want the different behavior 859 ;; ;; underscore in word class. If you're tempted to change it, try
761 ;; (e.g. backward-kill-word). 860 ;; ;; binding M-f and M-b to py-forward-into-nomenclature and
762 (modify-syntax-entry ?\_ "w" py-mode-syntax-table) 861 ;; ;; py-backward-into-nomenclature instead. This doesn't help in all
763 ;; Both single quote and double quote are string delimiters 862 ;; ;; situations where you'd want the different behavior
764 (modify-syntax-entry ?\' "\"" py-mode-syntax-table) 863 ;; ;; (e.g. backward-kill-word).
765 (modify-syntax-entry ?\" "\"" py-mode-syntax-table) 864 ;; (modify-syntax-entry ?\_ "w" py-mode-syntax-table)
766 ;; backquote is open and close paren 865 ;; ;; Both single quote and double quote are string delimiters
767 (modify-syntax-entry ?\` "$" py-mode-syntax-table) 866 ;; (modify-syntax-entry ?\' "\"" py-mode-syntax-table)
768 ;; comment delimiters 867 ;; (modify-syntax-entry ?\" "\"" py-mode-syntax-table)
769 (modify-syntax-entry ?\# "<" py-mode-syntax-table) 868 ;; ;; backquote is open and close paren
770 (modify-syntax-entry ?\n ">" py-mode-syntax-table) 869 ;; (modify-syntax-entry ?\` "$" py-mode-syntax-table)
771 ) 870 ;; ;; comment delimiters
871 ;; (modify-syntax-entry ?\# "<" py-mode-syntax-table)
872 ;; (modify-syntax-entry ?\n ">" py-mode-syntax-table)
873 ;;
874 ;; )
875 ;; 2009-09-09 a.roehler@web.de changed section end
772 876
773 ;; An auxiliary syntax table which places underscore and dot in the 877 ;; An auxiliary syntax table which places underscore and dot in the
774 ;; symbol class for simplicity 878 ;; symbol class for simplicity
775 (defvar py-dotted-expression-syntax-table nil 879 (defvar py-dotted-expression-syntax-table nil
776 "Syntax table used to identify Python dotted expressions.") 880 "Syntax table used to identify Python dotted expressions.")
1159 "Major mode for editing Python files. 1263 "Major mode for editing Python files.
1160 To submit a problem report, enter `\\[py-submit-bug-report]' from a 1264 To submit a problem report, enter `\\[py-submit-bug-report]' from a
1161 `python-mode' buffer. Do `\\[py-describe-mode]' for detailed 1265 `python-mode' buffer. Do `\\[py-describe-mode]' for detailed
1162 documentation. To see what version of `python-mode' you are running, 1266 documentation. To see what version of `python-mode' you are running,
1163 enter `\\[py-version]'. 1267 enter `\\[py-version]'.
1164
1165 This mode knows about Python indentation, tokens, comments and 1268 This mode knows about Python indentation, tokens, comments and
1166 continuation lines. Paragraphs are separated by blank lines only. 1269 continuation lines. Paragraphs are separated by blank lines only.
1167
1168 COMMANDS 1270 COMMANDS
1169 \\{py-mode-map} 1271 \\{py-mode-map}
1170 VARIABLES 1272 VARIABLES
1171
1172 py-indent-offset\t\tindentation increment 1273 py-indent-offset\t\tindentation increment
1173 py-block-comment-prefix\t\tcomment string used by `comment-region' 1274 py-block-comment-prefix\t\tcomment string used by `comment-region'
1174 py-python-command\t\tshell command to invoke Python interpreter 1275 py-python-command\t\tshell command to invoke Python interpreter
1175 py-temp-directory\t\tdirectory used for temp files (if needed) 1276 py-temp-directory\t\tdirectory used for temp files (if needed)
1176 py-beep-if-tab-change\t\tring the bell if `tab-width' is changed" 1277 py-beep-if-tab-change\t\tring the bell if `tab-width' is changed"
1177 (interactive) 1278 (interactive)
1178 ;; set up local variables 1279 ;; set up local variables
1179 (kill-all-local-variables) 1280 (kill-all-local-variables)
1180 (make-local-variable 'font-lock-defaults) 1281 ;; (make-local-variable 'font-lock-defaults)
1181 (make-local-variable 'paragraph-separate) 1282 (make-local-variable 'paragraph-separate)
1182 (make-local-variable 'paragraph-start) 1283 (make-local-variable 'paragraph-start)
1183 (make-local-variable 'require-final-newline) 1284 (make-local-variable 'require-final-newline)
1184 (make-local-variable 'comment-start) 1285 (make-local-variable 'comment-start)
1185 (make-local-variable 'comment-end) 1286 (make-local-variable 'comment-end)
1190 (make-local-variable 'indent-line-function) 1291 (make-local-variable 'indent-line-function)
1191 (make-local-variable 'add-log-current-defun-function) 1292 (make-local-variable 'add-log-current-defun-function)
1192 (make-local-variable 'fill-paragraph-function) 1293 (make-local-variable 'fill-paragraph-function)
1193 ;; 1294 ;;
1194 (set-syntax-table py-mode-syntax-table) 1295 (set-syntax-table py-mode-syntax-table)
1195 (setq major-mode 'python-mode 1296 ;; 2009-09-10 a.roehler@web.de changed section start
1196 mode-name "Python" 1297 ;; from python.el, version "22.1"
1197 local-abbrev-table python-mode-abbrev-table 1298 (set (make-local-variable 'font-lock-defaults)
1198 font-lock-defaults '(python-font-lock-keywords) 1299 '(python-font-lock-keywords nil nil nil nil
1199 paragraph-separate "^[ \t]*$" 1300 (font-lock-syntactic-keywords
1200 paragraph-start "^[ \t]*$" 1301 . python-font-lock-syntactic-keywords)))
1201 require-final-newline t 1302 ;; 2009-09-10 a.roehler@web.de changed section end
1202 comment-start "# " 1303 (setq major-mode 'python-mode
1203 comment-end "" 1304 mode-name "Python"
1204 comment-start-skip "# *" 1305 local-abbrev-table python-mode-abbrev-table
1205 comment-column 40 1306 ;; 2009-09-10 a.roehler@web.de changed section start
1307 ;; font-lock-defaults ...
1308 ;; 2009-09-10 a.roehler@web.de changed section end
1309 paragraph-separate "^[ \t]*$"
1310 paragraph-start "^[ \t]*$"
1311 require-final-newline t
1312 comment-start "# "
1313 comment-end ""
1314 comment-start-skip "# *"
1315 comment-column 40
1206 comment-indent-function 'py-comment-indent-function 1316 comment-indent-function 'py-comment-indent-function
1207 indent-region-function 'py-indent-region 1317 indent-region-function 'py-indent-region
1208 indent-line-function 'py-indent-line 1318 indent-line-function 'py-indent-line
1209 ;; tell add-log.el how to find the current function/method/variable 1319 ;; tell add-log.el how to find the current function/method/variable
1210 add-log-current-defun-function 'py-current-defun 1320 add-log-current-defun-function 'py-current-defun
1211 1321 fill-paragraph-function 'py-fill-paragraph)
1212 fill-paragraph-function 'py-fill-paragraph
1213 )
1214 (use-local-map py-mode-map) 1322 (use-local-map py-mode-map)
1215 ;; add the menu 1323 ;; add the menu
1216 (if py-menu 1324 (if py-menu
1217 (easy-menu-add py-menu)) 1325 (easy-menu-add py-menu))
1218 ;; Emacs 19 requires this 1326 ;; Emacs 19 requires this
1221 ;; Install Imenu if available 1329 ;; Install Imenu if available
1222 (when (py-safe (require 'imenu)) 1330 (when (py-safe (require 'imenu))
1223 (setq imenu-create-index-function #'py-imenu-create-index-function) 1331 (setq imenu-create-index-function #'py-imenu-create-index-function)
1224 (setq imenu-generic-expression py-imenu-generic-expression) 1332 (setq imenu-generic-expression py-imenu-generic-expression)
1225 (if (fboundp 'imenu-add-to-menubar) 1333 (if (fboundp 'imenu-add-to-menubar)
1226 (imenu-add-to-menubar (format "%s-%s" "IM" mode-name))) 1334 (imenu-add-to-menubar (format "%s-%s" "IM" mode-name))))
1227 )
1228 ;; Run the mode hook. Note that py-mode-hook is deprecated. 1335 ;; Run the mode hook. Note that py-mode-hook is deprecated.
1229 (if python-mode-hook 1336 (if python-mode-hook
1230 (run-hooks 'python-mode-hook) 1337 (run-hooks 'python-mode-hook)
1231 (run-hooks 'py-mode-hook)) 1338 (run-hooks 'py-mode-hook))
1232 ;; Now do the automagical guessing 1339 ;; Now do the automagical guessing
1233 (if py-smart-indentation 1340 (if py-smart-indentation
1234 (let ((offset py-indent-offset)) 1341 (let ((offset py-indent-offset))
1235 ;; It's okay if this fails to guess a good value 1342 ;; It's okay if this fails to guess a good value
1236 (if (and (py-safe (py-guess-indent-offset)) 1343 (if (and (py-safe (py-guess-indent-offset))
1237 (<= py-indent-offset 8) 1344 (<= py-indent-offset 8)
1238 (>= py-indent-offset 2)) 1345 (>= py-indent-offset 2))
1239 (setq offset py-indent-offset)) 1346 (setq offset py-indent-offset))
1240 (setq py-indent-offset offset) 1347 (setq py-indent-offset offset)
1241 ;; Only turn indent-tabs-mode off if tab-width != 1348 ;; Only turn indent-tabs-mode off if tab-width !=
1242 ;; py-indent-offset. Never turn it on, because the user must 1349 ;; py-indent-offset. Never turn it on, because the user must
1243 ;; have explicitly turned it off. 1350 ;; have explicitly turned it off.
1244 (if (/= tab-width py-indent-offset) 1351 (if (/= tab-width py-indent-offset)
1245 (setq indent-tabs-mode nil)) 1352 (setq indent-tabs-mode nil))))
1246 ))
1247 ;; Set the default shell if not already set 1353 ;; Set the default shell if not already set
1248 (when (null py-which-shell) 1354 (when (null py-which-shell)
1249 (py-toggle-shells (py-choose-shell)))) 1355 (py-toggle-shells (py-choose-shell))))
1250 1356
1251 1357