diff options
| author | Kenichi Handa | 2012-09-30 23:39:46 +0900 |
|---|---|---|
| committer | Kenichi Handa | 2012-09-30 23:39:46 +0900 |
| commit | c194970e15b6d6efa07697679a25dfab3aa76442 (patch) | |
| tree | 49aec8be9d2dcc74ad3c81f562e48308d8e27b75 /lisp/progmodes/python.el | |
| parent | 95402d5faa114a311cabfb8c64cf22a93787a066 (diff) | |
| parent | dd946752ab8810149a66a3eff469eb128709972d (diff) | |
| download | emacs-c194970e15b6d6efa07697679a25dfab3aa76442.tar.gz emacs-c194970e15b6d6efa07697679a25dfab3aa76442.zip | |
merge trunk
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 156 |
1 files changed, 91 insertions, 65 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index ffc6c1ac885..e99e6bda4b8 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -497,52 +497,68 @@ The type returned can be `comment', `string' or `paren'." | |||
| 497 | (1 font-lock-variable-name-face nil nil)))) | 497 | (1 font-lock-variable-name-face nil nil)))) |
| 498 | 498 | ||
| 499 | (defconst python-syntax-propertize-function | 499 | (defconst python-syntax-propertize-function |
| 500 | ;; Make outer chars of matching triple-quote sequences into generic | ||
| 501 | ;; string delimiters. Fixme: Is there a better way? | ||
| 502 | ;; First avoid a sequence preceded by an odd number of backslashes. | ||
| 503 | (syntax-propertize-rules | 500 | (syntax-propertize-rules |
| 504 | (;; ¡Backrefs don't work in syntax-propertize-rules! | 501 | ((rx |
| 505 | (concat "\\(?:\\([RUru]\\)[Rr]?\\|^\\|[^\\]\\(?:\\\\.\\)*\\)" ;Prefix. | 502 | ;; Match even number of backslashes. |
| 506 | "\\(?:\\('\\)'\\('\\)\\|\\(?2:\"\\)\"\\(?3:\"\\)\\)") | 503 | (or (not (any ?\\ ?\' ?\")) point) (* ?\\ ?\\) |
| 507 | (3 (ignore (python-quote-syntax)))))) | 504 | ;; Match single or triple quotes of any kind. |
| 508 | 505 | (group (or "\"" "\"\"\"" "'" "'''"))) | |
| 509 | (defun python-quote-syntax () | 506 | (1 (ignore (python-syntax-stringify)))) |
| 510 | "Put `syntax-table' property correctly on triple quote. | 507 | ((rx |
| 511 | Used for syntactic keywords. N is the match number (1, 2 or 3)." | 508 | ;; Match odd number of backslashes. |
| 512 | ;; Given a triple quote, we have to check the context to know | 509 | (or (not (any ?\\)) point) ?\\ (* ?\\ ?\\) |
| 513 | ;; whether this is an opening or closing triple or whether it's | 510 | ;; Followed by even number of equal quotes. |
| 514 | ;; quoted anyhow, and should be ignored. (For that we need to do | 511 | (group (or "\"\"" "\"\"\"\"" "''" "''''"))) |
| 515 | ;; the same job as `syntax-ppss' to be correct and it seems to be OK | 512 | (1 (ignore (python-syntax-stringify)))))) |
| 516 | ;; to use it here despite initial worries.) We also have to sort | 513 | |
| 517 | ;; out a possible prefix -- well, we don't _have_ to, but I think it | 514 | (defsubst python-syntax-count-quotes (quote-char &optional point limit) |
| 518 | ;; should be treated as part of the string. | 515 | "Count number of quotes around point (max is 3). |
| 519 | 516 | QUOTE-CHAR is the quote char to count. Optional argument POINT is | |
| 520 | ;; Test cases: | 517 | the point where scan starts (defaults to current point) and LIMIT |
| 521 | ;; ur"""ar""" x='"' # """ | 518 | is used to limit the scan." |
| 522 | ;; x = ''' """ ' a | 519 | (let ((i 0)) |
| 523 | ;; ''' | 520 | (while (and (< i 3) |
| 524 | ;; x '"""' x """ \"""" x | 521 | (or (not limit) (< (+ point i) limit)) |
| 525 | (save-excursion | 522 | (eq (char-after (+ point i)) quote-char)) |
| 526 | (goto-char (match-beginning 0)) | 523 | (incf i)) |
| 527 | (let ((syntax (save-match-data (syntax-ppss)))) | 524 | i)) |
| 528 | (cond | 525 | |
| 529 | ((eq t (nth 3 syntax)) ; after unclosed fence | 526 | (defun python-syntax-stringify () |
| 530 | ;; Consider property for the last char if in a fenced string. | 527 | "Put `syntax-table' property correctly on single/triple quotes." |
| 531 | (goto-char (nth 8 syntax)) ; fence position | 528 | (let* ((num-quotes |
| 532 | (skip-chars-forward "uUrR") ; skip any prefix | 529 | (let ((n (length (match-string-no-properties 1)))) |
| 533 | ;; Is it a matching sequence? | 530 | ;; This corrects the quote count when matching odd number |
| 534 | (if (eq (char-after) (char-after (match-beginning 2))) | 531 | ;; of backslashes followed by even number of quotes. |
| 535 | (put-text-property (match-beginning 3) (match-end 3) | 532 | (or (and (= 1 (logand n 1)) n) (1- n)))) |
| 536 | 'syntax-table (string-to-syntax "|")))) | 533 | (ppss (prog2 |
| 537 | ((match-end 1) | 534 | (backward-char num-quotes) |
| 538 | ;; Consider property for initial char, accounting for prefixes. | 535 | (syntax-ppss) |
| 539 | (put-text-property (match-beginning 1) (match-end 1) | 536 | (forward-char num-quotes))) |
| 540 | 'syntax-table (string-to-syntax "|"))) | 537 | (string-start (and (not (nth 4 ppss)) (nth 8 ppss))) |
| 541 | (t | 538 | (quote-starting-pos (- (point) num-quotes)) |
| 542 | ;; Consider property for initial char, accounting for prefixes. | 539 | (quote-ending-pos (point)) |
| 543 | (put-text-property (match-beginning 2) (match-end 2) | 540 | (num-closing-quotes |
| 544 | 'syntax-table (string-to-syntax "|")))) | 541 | (and string-start |
| 545 | ))) | 542 | (python-syntax-count-quotes |
| 543 | (char-before) string-start quote-starting-pos)))) | ||
| 544 | (cond ((and string-start (= num-closing-quotes 0)) | ||
| 545 | ;; This set of quotes doesn't match the string starting | ||
| 546 | ;; kind. Do nothing. | ||
| 547 | nil) | ||
| 548 | ((not string-start) | ||
| 549 | ;; This set of quotes delimit the start of a string. | ||
| 550 | (put-text-property quote-starting-pos (1+ quote-starting-pos) | ||
| 551 | 'syntax-table (string-to-syntax "|"))) | ||
| 552 | ((= num-quotes num-closing-quotes) | ||
| 553 | ;; This set of quotes delimit the end of a string. | ||
| 554 | (put-text-property (1- quote-ending-pos) quote-ending-pos | ||
| 555 | 'syntax-table (string-to-syntax "|"))) | ||
| 556 | ((> num-quotes num-closing-quotes) | ||
| 557 | ;; This may only happen whenever a triple quote is closing | ||
| 558 | ;; a single quoted string. Add string delimiter syntax to | ||
| 559 | ;; all three quotes. | ||
| 560 | (put-text-property quote-starting-pos quote-ending-pos | ||
| 561 | 'syntax-table (string-to-syntax "|")))))) | ||
| 546 | 562 | ||
| 547 | (defvar python-mode-syntax-table | 563 | (defvar python-mode-syntax-table |
| 548 | (let ((table (make-syntax-table))) | 564 | (let ((table (make-syntax-table))) |
| @@ -897,16 +913,27 @@ possible indentation levels and saves it in the variable | |||
| 897 | `python-indent-levels'. Afterwards it sets the variable | 913 | `python-indent-levels'. Afterwards it sets the variable |
| 898 | `python-indent-current-level' correctly so offset is equal | 914 | `python-indent-current-level' correctly so offset is equal |
| 899 | to (`nth' `python-indent-current-level' `python-indent-levels')" | 915 | to (`nth' `python-indent-current-level' `python-indent-levels')" |
| 900 | (if (or (and (eq this-command 'indent-for-tab-command) | 916 | (or |
| 901 | (eq last-command this-command)) | 917 | (and (or (and (eq this-command 'indent-for-tab-command) |
| 902 | force-toggle) | 918 | (eq last-command this-command)) |
| 903 | (if (not (equal python-indent-levels '(0))) | 919 | force-toggle) |
| 904 | (python-indent-toggle-levels) | 920 | (not (equal python-indent-levels '(0))) |
| 905 | (python-indent-calculate-levels)) | 921 | (or (python-indent-toggle-levels) t)) |
| 906 | (python-indent-calculate-levels)) | 922 | (python-indent-calculate-levels)) |
| 907 | (beginning-of-line) | 923 | (let* ((starting-pos (point-marker)) |
| 908 | (delete-horizontal-space) | 924 | (indent-ending-position |
| 909 | (indent-to (nth python-indent-current-level python-indent-levels)) | 925 | (+ (line-beginning-position) (current-indentation))) |
| 926 | (follow-indentation-p | ||
| 927 | (or (bolp) | ||
| 928 | (and (<= (line-beginning-position) starting-pos) | ||
| 929 | (>= indent-ending-position starting-pos)))) | ||
| 930 | (next-indent (nth python-indent-current-level python-indent-levels))) | ||
| 931 | (unless (= next-indent (current-indentation)) | ||
| 932 | (beginning-of-line) | ||
| 933 | (delete-horizontal-space) | ||
| 934 | (indent-to next-indent) | ||
| 935 | (goto-char starting-pos)) | ||
| 936 | (and follow-indentation-p (back-to-indentation))) | ||
| 910 | (python-info-closing-block-message)) | 937 | (python-info-closing-block-message)) |
| 911 | 938 | ||
| 912 | (defun python-indent-line-function () | 939 | (defun python-indent-line-function () |
| @@ -1892,19 +1919,18 @@ Returns the output. See `python-shell-send-string-no-output'." | |||
| 1892 | 1919 | ||
| 1893 | (defun python-shell-send-buffer (&optional arg) | 1920 | (defun python-shell-send-buffer (&optional arg) |
| 1894 | "Send the entire buffer to inferior Python process. | 1921 | "Send the entire buffer to inferior Python process. |
| 1895 | 1922 | With prefix ARG allow execution of code inside blocks delimited | |
| 1896 | With prefix ARG include lines surrounded by \"if __name__ == '__main__':\"" | 1923 | by \"if __name__== '__main__':\"" |
| 1897 | (interactive "P") | 1924 | (interactive "P") |
| 1898 | (save-restriction | 1925 | (save-restriction |
| 1899 | (widen) | 1926 | (widen) |
| 1900 | (python-shell-send-region | 1927 | (let ((str (buffer-substring (point-min) (point-max)))) |
| 1901 | (point-min) | 1928 | (and |
| 1902 | (or (and | 1929 | (not arg) |
| 1903 | (not arg) | 1930 | (setq str (replace-regexp-in-string |
| 1904 | (save-excursion | 1931 | (python-rx if-name-main) |
| 1905 | (re-search-forward (python-rx if-name-main) nil t)) | 1932 | "if __name__ == '__main__ ':" str))) |
| 1906 | (match-beginning 0)) | 1933 | (python-shell-send-string str)))) |
| 1907 | (point-max))))) | ||
| 1908 | 1934 | ||
| 1909 | (defun python-shell-send-defun (arg) | 1935 | (defun python-shell-send-defun (arg) |
| 1910 | "Send the current defun to inferior Python process. | 1936 | "Send the current defun to inferior Python process. |