diff options
| author | Daniel Colascione | 2012-10-07 14:31:58 -0800 |
|---|---|---|
| committer | Daniel Colascione | 2012-10-07 14:31:58 -0800 |
| commit | 36a305a723c63fd345be65c536c52fe9765c14be (patch) | |
| tree | fb89d9e103552863214c60297a65320917109357 /lisp/progmodes/python.el | |
| parent | 2ab329f3b5d52a39f0a45c3d9c129f1c19560142 (diff) | |
| parent | 795b1482a9e314cda32d62ac2988f573d359366e (diff) | |
| download | emacs-36a305a723c63fd345be65c536c52fe9765c14be.tar.gz emacs-36a305a723c63fd345be65c536c52fe9765c14be.zip | |
Merge from trunk
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 442 |
1 files changed, 301 insertions, 141 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index ffc6c1ac885..ffb2e66ca9d 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -497,52 +497,63 @@ 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 | (and |
| 506 | "\\(?:\\('\\)'\\('\\)\\|\\(?2:\"\\)\"\\(?3:\"\\)\\)") | 503 | ;; Match even number of backslashes. |
| 507 | (3 (ignore (python-quote-syntax)))))) | 504 | (or (not (any ?\\ ?\' ?\")) point |
| 508 | 505 | ;; Quotes might be preceded by a escaped quote. | |
| 509 | (defun python-quote-syntax () | 506 | (and (or (not (any ?\\)) point) ?\\ |
| 510 | "Put `syntax-table' property correctly on triple quote. | 507 | (* ?\\ ?\\) (any ?\' ?\"))) |
| 511 | Used for syntactic keywords. N is the match number (1, 2 or 3)." | 508 | (* ?\\ ?\\) |
| 512 | ;; Given a triple quote, we have to check the context to know | 509 | ;; Match single or triple quotes of any kind. |
| 513 | ;; whether this is an opening or closing triple or whether it's | 510 | (group (or "\"" "\"\"\"" "'" "'''")))) |
| 514 | ;; quoted anyhow, and should be ignored. (For that we need to do | 511 | (0 (ignore (python-syntax-stringify)))))) |
| 515 | ;; the same job as `syntax-ppss' to be correct and it seems to be OK | 512 | |
| 516 | ;; to use it here despite initial worries.) We also have to sort | 513 | (defsubst python-syntax-count-quotes (quote-char &optional point limit) |
| 517 | ;; out a possible prefix -- well, we don't _have_ to, but I think it | 514 | "Count number of quotes around point (max is 3). |
| 518 | ;; should be treated as part of the string. | 515 | QUOTE-CHAR is the quote char to count. Optional argument POINT is |
| 519 | 516 | the point where scan starts (defaults to current point) and LIMIT | |
| 520 | ;; Test cases: | 517 | is used to limit the scan." |
| 521 | ;; ur"""ar""" x='"' # """ | 518 | (let ((i 0)) |
| 522 | ;; x = ''' """ ' a | 519 | (while (and (< i 3) |
| 523 | ;; ''' | 520 | (or (not limit) (< (+ point i) limit)) |
| 524 | ;; x '"""' x """ \"""" x | 521 | (eq (char-after (+ point i)) quote-char)) |
| 525 | (save-excursion | 522 | (incf i)) |
| 526 | (goto-char (match-beginning 0)) | 523 | i)) |
| 527 | (let ((syntax (save-match-data (syntax-ppss)))) | 524 | |
| 528 | (cond | 525 | (defun python-syntax-stringify () |
| 529 | ((eq t (nth 3 syntax)) ; after unclosed fence | 526 | "Put `syntax-table' property correctly on single/triple quotes." |
| 530 | ;; Consider property for the last char if in a fenced string. | 527 | (let* ((num-quotes (length (match-string-no-properties 1))) |
| 531 | (goto-char (nth 8 syntax)) ; fence position | 528 | (ppss (prog2 |
| 532 | (skip-chars-forward "uUrR") ; skip any prefix | 529 | (backward-char num-quotes) |
| 533 | ;; Is it a matching sequence? | 530 | (syntax-ppss) |
| 534 | (if (eq (char-after) (char-after (match-beginning 2))) | 531 | (forward-char num-quotes))) |
| 535 | (put-text-property (match-beginning 3) (match-end 3) | 532 | (string-start (and (not (nth 4 ppss)) (nth 8 ppss))) |
| 536 | 'syntax-table (string-to-syntax "|")))) | 533 | (quote-starting-pos (- (point) num-quotes)) |
| 537 | ((match-end 1) | 534 | (quote-ending-pos (point)) |
| 538 | ;; Consider property for initial char, accounting for prefixes. | 535 | (num-closing-quotes |
| 539 | (put-text-property (match-beginning 1) (match-end 1) | 536 | (and string-start |
| 540 | 'syntax-table (string-to-syntax "|"))) | 537 | (python-syntax-count-quotes |
| 541 | (t | 538 | (char-before) string-start quote-starting-pos)))) |
| 542 | ;; Consider property for initial char, accounting for prefixes. | 539 | (cond ((and string-start (= num-closing-quotes 0)) |
| 543 | (put-text-property (match-beginning 2) (match-end 2) | 540 | ;; This set of quotes doesn't match the string starting |
| 544 | 'syntax-table (string-to-syntax "|")))) | 541 | ;; kind. Do nothing. |
| 545 | ))) | 542 | nil) |
| 543 | ((not string-start) | ||
| 544 | ;; This set of quotes delimit the start of a string. | ||
| 545 | (put-text-property quote-starting-pos (1+ quote-starting-pos) | ||
| 546 | 'syntax-table (string-to-syntax "|"))) | ||
| 547 | ((= num-quotes num-closing-quotes) | ||
| 548 | ;; This set of quotes delimit the end of a string. | ||
| 549 | (put-text-property (1- quote-ending-pos) quote-ending-pos | ||
| 550 | 'syntax-table (string-to-syntax "|"))) | ||
| 551 | ((> num-quotes num-closing-quotes) | ||
| 552 | ;; This may only happen whenever a triple quote is closing | ||
| 553 | ;; a single quoted string. Add string delimiter syntax to | ||
| 554 | ;; all three quotes. | ||
| 555 | (put-text-property quote-starting-pos quote-ending-pos | ||
| 556 | 'syntax-table (string-to-syntax "|")))))) | ||
| 546 | 557 | ||
| 547 | (defvar python-mode-syntax-table | 558 | (defvar python-mode-syntax-table |
| 548 | (let ((table (make-syntax-table))) | 559 | (let ((table (make-syntax-table))) |
| @@ -665,12 +676,12 @@ START is the buffer position where the sexp starts." | |||
| 665 | (goto-char (line-beginning-position)) | 676 | (goto-char (line-beginning-position)) |
| 666 | (bobp)) | 677 | (bobp)) |
| 667 | 'no-indent) | 678 | 'no-indent) |
| 668 | ;; Inside a paren | ||
| 669 | ((setq start (python-syntax-context 'paren ppss)) | ||
| 670 | 'inside-paren) | ||
| 671 | ;; Inside string | 679 | ;; Inside string |
| 672 | ((setq start (python-syntax-context 'string ppss)) | 680 | ((setq start (python-syntax-context 'string ppss)) |
| 673 | 'inside-string) | 681 | 'inside-string) |
| 682 | ;; Inside a paren | ||
| 683 | ((setq start (python-syntax-context 'paren ppss)) | ||
| 684 | 'inside-paren) | ||
| 674 | ;; After backslash | 685 | ;; After backslash |
| 675 | ((setq start (when (not (or (python-syntax-context 'string ppss) | 686 | ((setq start (when (not (or (python-syntax-context 'string ppss) |
| 676 | (python-syntax-context 'comment ppss))) | 687 | (python-syntax-context 'comment ppss))) |
| @@ -699,7 +710,7 @@ START is the buffer position where the sexp starts." | |||
| 699 | ;; After normal line | 710 | ;; After normal line |
| 700 | ((setq start (save-excursion | 711 | ((setq start (save-excursion |
| 701 | (back-to-indentation) | 712 | (back-to-indentation) |
| 702 | (python-util-forward-comment -1) | 713 | (skip-chars-backward (rx (or whitespace ?\n))) |
| 703 | (python-nav-beginning-of-statement) | 714 | (python-nav-beginning-of-statement) |
| 704 | (point-marker))) | 715 | (point-marker))) |
| 705 | 'after-line) | 716 | 'after-line) |
| @@ -897,16 +908,27 @@ possible indentation levels and saves it in the variable | |||
| 897 | `python-indent-levels'. Afterwards it sets the variable | 908 | `python-indent-levels'. Afterwards it sets the variable |
| 898 | `python-indent-current-level' correctly so offset is equal | 909 | `python-indent-current-level' correctly so offset is equal |
| 899 | to (`nth' `python-indent-current-level' `python-indent-levels')" | 910 | to (`nth' `python-indent-current-level' `python-indent-levels')" |
| 900 | (if (or (and (eq this-command 'indent-for-tab-command) | 911 | (or |
| 901 | (eq last-command this-command)) | 912 | (and (or (and (eq this-command 'indent-for-tab-command) |
| 902 | force-toggle) | 913 | (eq last-command this-command)) |
| 903 | (if (not (equal python-indent-levels '(0))) | 914 | force-toggle) |
| 904 | (python-indent-toggle-levels) | 915 | (not (equal python-indent-levels '(0))) |
| 905 | (python-indent-calculate-levels)) | 916 | (or (python-indent-toggle-levels) t)) |
| 906 | (python-indent-calculate-levels)) | 917 | (python-indent-calculate-levels)) |
| 907 | (beginning-of-line) | 918 | (let* ((starting-pos (point-marker)) |
| 908 | (delete-horizontal-space) | 919 | (indent-ending-position |
| 909 | (indent-to (nth python-indent-current-level python-indent-levels)) | 920 | (+ (line-beginning-position) (current-indentation))) |
| 921 | (follow-indentation-p | ||
| 922 | (or (bolp) | ||
| 923 | (and (<= (line-beginning-position) starting-pos) | ||
| 924 | (>= indent-ending-position starting-pos)))) | ||
| 925 | (next-indent (nth python-indent-current-level python-indent-levels))) | ||
| 926 | (unless (= next-indent (current-indentation)) | ||
| 927 | (beginning-of-line) | ||
| 928 | (delete-horizontal-space) | ||
| 929 | (indent-to next-indent) | ||
| 930 | (goto-char starting-pos)) | ||
| 931 | (and follow-indentation-p (back-to-indentation))) | ||
| 910 | (python-info-closing-block-message)) | 932 | (python-info-closing-block-message)) |
| 911 | 933 | ||
| 912 | (defun python-indent-line-function () | 934 | (defun python-indent-line-function () |
| @@ -951,7 +973,16 @@ Called from a program, START and END specify the region to indent." | |||
| 951 | (back-to-indentation) | 973 | (back-to-indentation) |
| 952 | (setq word (current-word)) | 974 | (setq word (current-word)) |
| 953 | (forward-line 1) | 975 | (forward-line 1) |
| 954 | (when word | 976 | (when (and word |
| 977 | ;; Don't mess with strings, unless it's the | ||
| 978 | ;; enclosing set of quotes. | ||
| 979 | (or (not (python-syntax-context 'string)) | ||
| 980 | (eq | ||
| 981 | (syntax-after | ||
| 982 | (+ (1- (point)) | ||
| 983 | (current-indentation) | ||
| 984 | (python-syntax-count-quotes (char-after) (point)))) | ||
| 985 | (string-to-syntax "|")))) | ||
| 955 | (beginning-of-line) | 986 | (beginning-of-line) |
| 956 | (delete-horizontal-space) | 987 | (delete-horizontal-space) |
| 957 | (indent-to (python-indent-calculate-indentation))))) | 988 | (indent-to (python-indent-calculate-indentation))))) |
| @@ -1621,6 +1652,8 @@ uniqueness for different types of configurations." | |||
| 1621 | OUTPUT is a string with the contents of the buffer." | 1652 | OUTPUT is a string with the contents of the buffer." |
| 1622 | (ansi-color-filter-apply output)) | 1653 | (ansi-color-filter-apply output)) |
| 1623 | 1654 | ||
| 1655 | (defvar python-shell--parent-buffer nil) | ||
| 1656 | |||
| 1624 | (define-derived-mode inferior-python-mode comint-mode "Inferior Python" | 1657 | (define-derived-mode inferior-python-mode comint-mode "Inferior Python" |
| 1625 | "Major mode for Python inferior process. | 1658 | "Major mode for Python inferior process. |
| 1626 | Runs a Python interpreter as a subprocess of Emacs, with Python | 1659 | Runs a Python interpreter as a subprocess of Emacs, with Python |
| @@ -1643,12 +1676,14 @@ initialization of the interpreter via `python-shell-setup-codes' | |||
| 1643 | variable. | 1676 | variable. |
| 1644 | 1677 | ||
| 1645 | \(Type \\[describe-mode] in the process buffer for a list of commands.)" | 1678 | \(Type \\[describe-mode] in the process buffer for a list of commands.)" |
| 1646 | (set-syntax-table python-mode-syntax-table) | 1679 | (and python-shell--parent-buffer |
| 1647 | (setq mode-line-process '(":%s")) | 1680 | (python-util-clone-local-variables python-shell--parent-buffer)) |
| 1648 | (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)" | 1681 | (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)" |
| 1649 | python-shell-prompt-regexp | 1682 | python-shell-prompt-regexp |
| 1650 | python-shell-prompt-block-regexp | 1683 | python-shell-prompt-block-regexp |
| 1651 | python-shell-prompt-pdb-regexp)) | 1684 | python-shell-prompt-pdb-regexp)) |
| 1685 | (set-syntax-table python-mode-syntax-table) | ||
| 1686 | (setq mode-line-process '(":%s")) | ||
| 1652 | (make-local-variable 'comint-output-filter-functions) | 1687 | (make-local-variable 'comint-output-filter-functions) |
| 1653 | (add-hook 'comint-output-filter-functions | 1688 | (add-hook 'comint-output-filter-functions |
| 1654 | 'python-comint-output-filter-function) | 1689 | 'python-comint-output-filter-function) |
| @@ -1694,11 +1729,10 @@ killed." | |||
| 1694 | (let* ((cmdlist (split-string-and-unquote cmd)) | 1729 | (let* ((cmdlist (split-string-and-unquote cmd)) |
| 1695 | (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name | 1730 | (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name |
| 1696 | (car cmdlist) nil (cdr cmdlist))) | 1731 | (car cmdlist) nil (cdr cmdlist))) |
| 1697 | (current-buffer (current-buffer)) | 1732 | (python-shell--parent-buffer (current-buffer)) |
| 1698 | (process (get-buffer-process buffer))) | 1733 | (process (get-buffer-process buffer))) |
| 1699 | (with-current-buffer buffer | 1734 | (with-current-buffer buffer |
| 1700 | (inferior-python-mode) | 1735 | (inferior-python-mode)) |
| 1701 | (python-util-clone-local-variables current-buffer)) | ||
| 1702 | (accept-process-output process) | 1736 | (accept-process-output process) |
| 1703 | (and pop (pop-to-buffer buffer t)) | 1737 | (and pop (pop-to-buffer buffer t)) |
| 1704 | (and internal (set-process-query-on-exit-flag process nil)))) | 1738 | (and internal (set-process-query-on-exit-flag process nil)))) |
| @@ -1839,31 +1873,60 @@ When MSG is non-nil messages the first line of STRING." | |||
| 1839 | (string-match "\n[ \t].*\n?$" string)) | 1873 | (string-match "\n[ \t].*\n?$" string)) |
| 1840 | (comint-send-string process "\n"))))) | 1874 | (comint-send-string process "\n"))))) |
| 1841 | 1875 | ||
| 1876 | (defvar python-shell-output-filter-in-progress nil) | ||
| 1877 | (defvar python-shell-output-filter-buffer nil) | ||
| 1878 | |||
| 1879 | (defun python-shell-output-filter (string) | ||
| 1880 | "Filter used in `python-shell-send-string-no-output' to grab output. | ||
| 1881 | STRING is the output received to this point from the process. | ||
| 1882 | This filter saves received output from the process in | ||
| 1883 | `python-shell-output-filter-buffer' and stops receiving it after | ||
| 1884 | detecting a prompt at the end of the buffer." | ||
| 1885 | (setq | ||
| 1886 | string (ansi-color-filter-apply string) | ||
| 1887 | python-shell-output-filter-buffer | ||
| 1888 | (concat python-shell-output-filter-buffer string)) | ||
| 1889 | (when (string-match | ||
| 1890 | (format "\n\\(?:%s\\|%s\\|%s\\)$" | ||
| 1891 | python-shell-prompt-regexp | ||
| 1892 | python-shell-prompt-block-regexp | ||
| 1893 | python-shell-prompt-pdb-regexp) | ||
| 1894 | python-shell-output-filter-buffer) | ||
| 1895 | ;; Output ends when `python-shell-output-filter-buffer' contains | ||
| 1896 | ;; the prompt attached at the end of it. | ||
| 1897 | (setq python-shell-output-filter-in-progress nil | ||
| 1898 | python-shell-output-filter-buffer | ||
| 1899 | (substring python-shell-output-filter-buffer | ||
| 1900 | 0 (match-beginning 0))) | ||
| 1901 | (when (and (> (length python-shell-prompt-output-regexp) 0) | ||
| 1902 | (string-match (concat "^" python-shell-prompt-output-regexp) | ||
| 1903 | python-shell-output-filter-buffer)) | ||
| 1904 | ;; Some shells, like iPython might append a prompt before the | ||
| 1905 | ;; output, clean that. | ||
| 1906 | (setq python-shell-output-filter-buffer | ||
| 1907 | (substring python-shell-output-filter-buffer (match-end 0))))) | ||
| 1908 | "") | ||
| 1909 | |||
| 1842 | (defun python-shell-send-string-no-output (string &optional process msg) | 1910 | (defun python-shell-send-string-no-output (string &optional process msg) |
| 1843 | "Send STRING to PROCESS and inhibit output. | 1911 | "Send STRING to PROCESS and inhibit output. |
| 1844 | When MSG is non-nil messages the first line of STRING. Return | 1912 | When MSG is non-nil messages the first line of STRING. Return |
| 1845 | the output." | 1913 | the output." |
| 1846 | (let* ((output-buffer "") | 1914 | (let ((process (or process (python-shell-get-or-create-process))) |
| 1847 | (process (or process (python-shell-get-or-create-process))) | 1915 | (comint-preoutput-filter-functions |
| 1848 | (comint-preoutput-filter-functions | 1916 | '(python-shell-output-filter)) |
| 1849 | (append comint-preoutput-filter-functions | 1917 | (python-shell-output-filter-in-progress t) |
| 1850 | '(ansi-color-filter-apply | 1918 | (inhibit-quit t)) |
| 1851 | (lambda (string) | ||
| 1852 | (setq output-buffer (concat output-buffer string)) | ||
| 1853 | "")))) | ||
| 1854 | (inhibit-quit t)) | ||
| 1855 | (or | 1919 | (or |
| 1856 | (with-local-quit | 1920 | (with-local-quit |
| 1857 | (python-shell-send-string string process msg) | 1921 | (python-shell-send-string string process msg) |
| 1858 | (accept-process-output process) | 1922 | (while python-shell-output-filter-in-progress |
| 1859 | (replace-regexp-in-string | 1923 | ;; `python-shell-output-filter' takes care of setting |
| 1860 | (if (> (length python-shell-prompt-output-regexp) 0) | 1924 | ;; `python-shell-output-filter-in-progress' to NIL after it |
| 1861 | (format "\n*%s$\\|^%s\\|\n$" | 1925 | ;; detects end of output. |
| 1862 | python-shell-prompt-regexp | 1926 | (accept-process-output process)) |
| 1863 | (or python-shell-prompt-output-regexp "")) | 1927 | (prog1 |
| 1864 | (format "\n*$\\|^%s\\|\n$" | 1928 | python-shell-output-filter-buffer |
| 1865 | python-shell-prompt-regexp)) | 1929 | (setq python-shell-output-filter-buffer nil))) |
| 1866 | "" output-buffer)) | ||
| 1867 | (with-current-buffer (process-buffer process) | 1930 | (with-current-buffer (process-buffer process) |
| 1868 | (comint-interrupt-subjob))))) | 1931 | (comint-interrupt-subjob))))) |
| 1869 | 1932 | ||
| @@ -1892,19 +1955,18 @@ Returns the output. See `python-shell-send-string-no-output'." | |||
| 1892 | 1955 | ||
| 1893 | (defun python-shell-send-buffer (&optional arg) | 1956 | (defun python-shell-send-buffer (&optional arg) |
| 1894 | "Send the entire buffer to inferior Python process. | 1957 | "Send the entire buffer to inferior Python process. |
| 1895 | 1958 | With prefix ARG allow execution of code inside blocks delimited | |
| 1896 | With prefix ARG include lines surrounded by \"if __name__ == '__main__':\"" | 1959 | by \"if __name__== '__main__':\"" |
| 1897 | (interactive "P") | 1960 | (interactive "P") |
| 1898 | (save-restriction | 1961 | (save-restriction |
| 1899 | (widen) | 1962 | (widen) |
| 1900 | (python-shell-send-region | 1963 | (let ((str (buffer-substring (point-min) (point-max)))) |
| 1901 | (point-min) | 1964 | (and |
| 1902 | (or (and | 1965 | (not arg) |
| 1903 | (not arg) | 1966 | (setq str (replace-regexp-in-string |
| 1904 | (save-excursion | 1967 | (python-rx if-name-main) |
| 1905 | (re-search-forward (python-rx if-name-main) nil t)) | 1968 | "if __name__ == '__main__ ':" str))) |
| 1906 | (match-beginning 0)) | 1969 | (python-shell-send-string str)))) |
| 1907 | (point-max))))) | ||
| 1908 | 1970 | ||
| 1909 | (defun python-shell-send-defun (arg) | 1971 | (defun python-shell-send-defun (arg) |
| 1910 | "Send the current defun to inferior Python process. | 1972 | "Send the current defun to inferior Python process. |
| @@ -2232,32 +2294,100 @@ inferior python process is updated properly." | |||
| 2232 | This is the function used by `python-fill-paragraph-function' to | 2294 | This is the function used by `python-fill-paragraph-function' to |
| 2233 | fill comments." | 2295 | fill comments." |
| 2234 | :type 'symbol | 2296 | :type 'symbol |
| 2235 | :group 'python | 2297 | :group 'python) |
| 2236 | :safe 'symbolp) | ||
| 2237 | 2298 | ||
| 2238 | (defcustom python-fill-string-function 'python-fill-string | 2299 | (defcustom python-fill-string-function 'python-fill-string |
| 2239 | "Function to fill strings. | 2300 | "Function to fill strings. |
| 2240 | This is the function used by `python-fill-paragraph-function' to | 2301 | This is the function used by `python-fill-paragraph-function' to |
| 2241 | fill strings." | 2302 | fill strings." |
| 2242 | :type 'symbol | 2303 | :type 'symbol |
| 2243 | :group 'python | 2304 | :group 'python) |
| 2244 | :safe 'symbolp) | ||
| 2245 | 2305 | ||
| 2246 | (defcustom python-fill-decorator-function 'python-fill-decorator | 2306 | (defcustom python-fill-decorator-function 'python-fill-decorator |
| 2247 | "Function to fill decorators. | 2307 | "Function to fill decorators. |
| 2248 | This is the function used by `python-fill-paragraph-function' to | 2308 | This is the function used by `python-fill-paragraph-function' to |
| 2249 | fill decorators." | 2309 | fill decorators." |
| 2250 | :type 'symbol | 2310 | :type 'symbol |
| 2251 | :group 'python | 2311 | :group 'python) |
| 2252 | :safe 'symbolp) | ||
| 2253 | 2312 | ||
| 2254 | (defcustom python-fill-paren-function 'python-fill-paren | 2313 | (defcustom python-fill-paren-function 'python-fill-paren |
| 2255 | "Function to fill parens. | 2314 | "Function to fill parens. |
| 2256 | This is the function used by `python-fill-paragraph-function' to | 2315 | This is the function used by `python-fill-paragraph-function' to |
| 2257 | fill parens." | 2316 | fill parens." |
| 2258 | :type 'symbol | 2317 | :type 'symbol |
| 2318 | :group 'python) | ||
| 2319 | |||
| 2320 | (defcustom python-fill-docstring-style 'pep-257 | ||
| 2321 | "Style used to fill docstrings. | ||
| 2322 | This affects `python-fill-string' behavior with regards to | ||
| 2323 | triple quotes positioning. | ||
| 2324 | |||
| 2325 | Possible values are DJANGO, ONETWO, PEP-257, PEP-257-NN, | ||
| 2326 | SYMMETRIC, and NIL. A value of NIL won't care about quotes | ||
| 2327 | position and will treat docstrings a normal string, any other | ||
| 2328 | value may result in one of the following docstring styles: | ||
| 2329 | |||
| 2330 | DJANGO: | ||
| 2331 | |||
| 2332 | \"\"\" | ||
| 2333 | Process foo, return bar. | ||
| 2334 | \"\"\" | ||
| 2335 | |||
| 2336 | \"\"\" | ||
| 2337 | Process foo, return bar. | ||
| 2338 | |||
| 2339 | If processing fails throw ProcessingError. | ||
| 2340 | \"\"\" | ||
| 2341 | |||
| 2342 | ONETWO: | ||
| 2343 | |||
| 2344 | \"\"\"Process foo, return bar.\"\"\" | ||
| 2345 | |||
| 2346 | \"\"\" | ||
| 2347 | Process foo, return bar. | ||
| 2348 | |||
| 2349 | If processing fails throw ProcessingError. | ||
| 2350 | |||
| 2351 | \"\"\" | ||
| 2352 | |||
| 2353 | PEP-257: | ||
| 2354 | |||
| 2355 | \"\"\"Process foo, return bar.\"\"\" | ||
| 2356 | |||
| 2357 | \"\"\"Process foo, return bar. | ||
| 2358 | |||
| 2359 | If processing fails throw ProcessingError. | ||
| 2360 | |||
| 2361 | \"\"\" | ||
| 2362 | |||
| 2363 | PEP-257-NN: | ||
| 2364 | |||
| 2365 | \"\"\"Process foo, return bar.\"\"\" | ||
| 2366 | |||
| 2367 | \"\"\"Process foo, return bar. | ||
| 2368 | |||
| 2369 | If processing fails throw ProcessingError. | ||
| 2370 | \"\"\" | ||
| 2371 | |||
| 2372 | SYMMETRIC: | ||
| 2373 | |||
| 2374 | \"\"\"Process foo, return bar.\"\"\" | ||
| 2375 | |||
| 2376 | \"\"\" | ||
| 2377 | Process foo, return bar. | ||
| 2378 | |||
| 2379 | If processing fails throw ProcessingError. | ||
| 2380 | \"\"\"" | ||
| 2381 | :type '(choice | ||
| 2382 | (const :tag "Don't format docstrings" nil) | ||
| 2383 | (const :tag "Django's coding standards style." django) | ||
| 2384 | (const :tag "One newline and start and Two at end style." onetwo) | ||
| 2385 | (const :tag "PEP-257 with 2 newlines at end of string." pep-257) | ||
| 2386 | (const :tag "PEP-257 with 1 newline at end of string." pep-257-nn) | ||
| 2387 | (const :tag "Symmetric style." symmetric)) | ||
| 2259 | :group 'python | 2388 | :group 'python |
| 2260 | :safe 'symbolp) | 2389 | :safe (lambda (val) |
| 2390 | (memq val '(django onetwo pep-257 pep-257-nn symmetric nil)))) | ||
| 2261 | 2391 | ||
| 2262 | (defun python-fill-paragraph-function (&optional justify) | 2392 | (defun python-fill-paragraph-function (&optional justify) |
| 2263 | "`fill-paragraph-function' handling multi-line strings and possibly comments. | 2393 | "`fill-paragraph-function' handling multi-line strings and possibly comments. |
| @@ -2267,18 +2397,19 @@ the string's indentation. | |||
| 2267 | Optional argument JUSTIFY defines if the paragraph should be justified." | 2397 | Optional argument JUSTIFY defines if the paragraph should be justified." |
| 2268 | (interactive "P") | 2398 | (interactive "P") |
| 2269 | (save-excursion | 2399 | (save-excursion |
| 2270 | (back-to-indentation) | ||
| 2271 | (cond | 2400 | (cond |
| 2272 | ;; Comments | 2401 | ;; Comments |
| 2273 | ((funcall python-fill-comment-function justify)) | 2402 | ((python-syntax-context 'comment) |
| 2403 | (funcall python-fill-comment-function justify)) | ||
| 2274 | ;; Strings/Docstrings | 2404 | ;; Strings/Docstrings |
| 2275 | ((save-excursion (skip-chars-forward "\"'uUrR") | 2405 | ((save-excursion (or (python-syntax-context 'string) |
| 2276 | (python-syntax-context 'string)) | 2406 | (equal (string-to-syntax "|") |
| 2407 | (syntax-after (point))))) | ||
| 2277 | (funcall python-fill-string-function justify)) | 2408 | (funcall python-fill-string-function justify)) |
| 2278 | ;; Decorators | 2409 | ;; Decorators |
| 2279 | ((equal (char-after (save-excursion | 2410 | ((equal (char-after (save-excursion |
| 2280 | (back-to-indentation) | 2411 | (back-to-indentation) |
| 2281 | (point-marker))) ?@) | 2412 | (point))) ?@) |
| 2282 | (funcall python-fill-decorator-function justify)) | 2413 | (funcall python-fill-decorator-function justify)) |
| 2283 | ;; Parens | 2414 | ;; Parens |
| 2284 | ((or (python-syntax-context 'paren) | 2415 | ((or (python-syntax-context 'paren) |
| @@ -2297,43 +2428,72 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'." | |||
| 2297 | (defun python-fill-string (&optional justify) | 2428 | (defun python-fill-string (&optional justify) |
| 2298 | "String fill function for `python-fill-paragraph-function'. | 2429 | "String fill function for `python-fill-paragraph-function'. |
| 2299 | JUSTIFY should be used (if applicable) as in `fill-paragraph'." | 2430 | JUSTIFY should be used (if applicable) as in `fill-paragraph'." |
| 2300 | (let ((marker (point-marker)) | 2431 | (let* ((marker (point-marker)) |
| 2301 | (string-start-marker | 2432 | (str-start-pos |
| 2302 | (progn | 2433 | (let ((m (make-marker))) |
| 2303 | (skip-chars-forward "\"'uUrR") | 2434 | (setf (marker-position m) |
| 2304 | (goto-char (python-syntax-context 'string)) | 2435 | (or (python-syntax-context 'string) |
| 2305 | (skip-chars-forward "\"'uUrR") | 2436 | (and (equal (string-to-syntax "|") |
| 2306 | (point-marker))) | 2437 | (syntax-after (point))) |
| 2307 | (reg-start (line-beginning-position)) | 2438 | (point)))) m)) |
| 2308 | (string-end-marker | 2439 | (num-quotes (python-syntax-count-quotes |
| 2309 | (progn | 2440 | (char-after str-start-pos) str-start-pos)) |
| 2310 | (while (python-syntax-context 'string) | 2441 | (str-end-pos |
| 2311 | (goto-char (1+ (point-marker)))) | 2442 | (save-excursion |
| 2312 | (skip-chars-backward "\"'") | 2443 | (goto-char (+ str-start-pos num-quotes)) |
| 2313 | (point-marker))) | 2444 | (or (re-search-forward (rx (syntax string-delimiter)) nil t) |
| 2314 | (reg-end (line-end-position)) | 2445 | (goto-char (point-max))) |
| 2315 | (fill-paragraph-function)) | 2446 | (point-marker))) |
| 2447 | (multi-line-p | ||
| 2448 | ;; Docstring styles may vary for oneliners and multi-liners. | ||
| 2449 | (> (count-matches "\n" str-start-pos str-end-pos) 0)) | ||
| 2450 | (delimiters-style | ||
| 2451 | (case python-fill-docstring-style | ||
| 2452 | ;; delimiters-style is a cons cell with the form | ||
| 2453 | ;; (START-NEWLINES . END-NEWLINES). When any of the sexps | ||
| 2454 | ;; is NIL means to not add any newlines for start or end | ||
| 2455 | ;; of docstring. See `python-fill-docstring-style' for a | ||
| 2456 | ;; graphic idea of each style. | ||
| 2457 | (django (cons 1 1)) | ||
| 2458 | (onetwo (and multi-line-p (cons 1 2))) | ||
| 2459 | (pep-257 (and multi-line-p (cons nil 2))) | ||
| 2460 | (pep-257-nn (and multi-line-p (cons nil 1))) | ||
| 2461 | (symmetric (and multi-line-p (cons 1 1))))) | ||
| 2462 | (docstring-p (save-excursion | ||
| 2463 | ;; Consider docstrings those strings which | ||
| 2464 | ;; start on a line by themselves. | ||
| 2465 | (python-nav-beginning-of-statement) | ||
| 2466 | (and (= (point) str-start-pos)))) | ||
| 2467 | (fill-paragraph-function)) | ||
| 2316 | (save-restriction | 2468 | (save-restriction |
| 2317 | (narrow-to-region reg-start reg-end) | 2469 | (narrow-to-region str-start-pos str-end-pos) |
| 2318 | (save-excursion | 2470 | (fill-paragraph justify)) |
| 2319 | (goto-char string-start-marker) | 2471 | (save-excursion |
| 2320 | (delete-region (point-marker) (progn | 2472 | (when (and docstring-p python-fill-docstring-style) |
| 2321 | (skip-syntax-forward "> ") | 2473 | ;; Add the number of newlines indicated by the selected style |
| 2322 | (point-marker))) | 2474 | ;; at the start of the docstring. |
| 2323 | (goto-char string-end-marker) | 2475 | (goto-char (+ str-start-pos num-quotes)) |
| 2324 | (delete-region (point-marker) (progn | 2476 | (delete-region (point) (progn |
| 2325 | (skip-syntax-backward "> ") | 2477 | (skip-syntax-forward "> ") |
| 2326 | (point-marker))) | 2478 | (point))) |
| 2327 | (save-excursion | 2479 | (and (car delimiters-style) |
| 2328 | (goto-char marker) | 2480 | (or (newline (car delimiters-style)) t) |
| 2329 | (fill-paragraph justify)) | 2481 | ;; Indent only if a newline is added. |
| 2330 | ;; If there is a newline in the docstring lets put triple | 2482 | (indent-according-to-mode)) |
| 2331 | ;; quote in it's own line to follow pep 8 | 2483 | ;; Add the number of newlines indicated by the selected style |
| 2332 | (when (save-excursion | 2484 | ;; at the end of the docstring. |
| 2333 | (re-search-backward "\n" string-start-marker t)) | 2485 | (goto-char (if (not (= str-end-pos (point-max))) |
| 2334 | (newline) | 2486 | (- str-end-pos num-quotes) |
| 2335 | (newline-and-indent)) | 2487 | str-end-pos)) |
| 2336 | (fill-paragraph justify)))) t) | 2488 | (delete-region (point) (progn |
| 2489 | (skip-syntax-backward "> ") | ||
| 2490 | (point))) | ||
| 2491 | (and (cdr delimiters-style) | ||
| 2492 | ;; Add newlines only if string ends. | ||
| 2493 | (not (= str-end-pos (point-max))) | ||
| 2494 | (or (newline (cdr delimiters-style)) t) | ||
| 2495 | ;; Again indent only if a newline is added. | ||
| 2496 | (indent-according-to-mode))))) t) | ||
| 2337 | 2497 | ||
| 2338 | (defun python-fill-decorator (&optional justify) | 2498 | (defun python-fill-decorator (&optional justify) |
| 2339 | "Decorator fill function for `python-fill-paragraph-function'. | 2499 | "Decorator fill function for `python-fill-paragraph-function'. |