diff options
| author | Kenichi Handa | 2012-10-06 21:55:09 +0900 |
|---|---|---|
| committer | Kenichi Handa | 2012-10-06 21:55:09 +0900 |
| commit | 16ddec7e9e6adcf615db097d9627d490ca29208c (patch) | |
| tree | 1c16b9565c9cca81ec8f5b10f0f4110340d4654a /lisp/progmodes/python.el | |
| parent | 2b89bca49d55cec1a004353354a76de2972c68f3 (diff) | |
| parent | d5acb99a199d83cde1a43482709c3e9d4ec34b2f (diff) | |
| download | emacs-16ddec7e9e6adcf615db097d9627d490ca29208c.tar.gz emacs-16ddec7e9e6adcf615db097d9627d490ca29208c.zip | |
merge trunk
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 271 |
1 files changed, 189 insertions, 82 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index e99e6bda4b8..b3b3b0181d7 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -499,17 +499,16 @@ The type returned can be `comment', `string' or `paren'." | |||
| 499 | (defconst python-syntax-propertize-function | 499 | (defconst python-syntax-propertize-function |
| 500 | (syntax-propertize-rules | 500 | (syntax-propertize-rules |
| 501 | ((rx | 501 | ((rx |
| 502 | ;; Match even number of backslashes. | 502 | (and |
| 503 | (or (not (any ?\\ ?\' ?\")) point) (* ?\\ ?\\) | 503 | ;; Match even number of backslashes. |
| 504 | ;; Match single or triple quotes of any kind. | 504 | (or (not (any ?\\ ?\' ?\")) point |
| 505 | (group (or "\"" "\"\"\"" "'" "'''"))) | 505 | ;; Quotes might be preceded by a escaped quote. |
| 506 | (1 (ignore (python-syntax-stringify)))) | 506 | (and (or (not (any ?\\)) point) ?\\ |
| 507 | ((rx | 507 | (* ?\\ ?\\) (any ?\' ?\"))) |
| 508 | ;; Match odd number of backslashes. | 508 | (* ?\\ ?\\) |
| 509 | (or (not (any ?\\)) point) ?\\ (* ?\\ ?\\) | 509 | ;; Match single or triple quotes of any kind. |
| 510 | ;; Followed by even number of equal quotes. | 510 | (group (or "\"" "\"\"\"" "'" "'''")))) |
| 511 | (group (or "\"\"" "\"\"\"\"" "''" "''''"))) | 511 | (0 (ignore (python-syntax-stringify)))))) |
| 512 | (1 (ignore (python-syntax-stringify)))))) | ||
| 513 | 512 | ||
| 514 | (defsubst python-syntax-count-quotes (quote-char &optional point limit) | 513 | (defsubst python-syntax-count-quotes (quote-char &optional point limit) |
| 515 | "Count number of quotes around point (max is 3). | 514 | "Count number of quotes around point (max is 3). |
| @@ -525,11 +524,7 @@ is used to limit the scan." | |||
| 525 | 524 | ||
| 526 | (defun python-syntax-stringify () | 525 | (defun python-syntax-stringify () |
| 527 | "Put `syntax-table' property correctly on single/triple quotes." | 526 | "Put `syntax-table' property correctly on single/triple quotes." |
| 528 | (let* ((num-quotes | 527 | (let* ((num-quotes (length (match-string-no-properties 1))) |
| 529 | (let ((n (length (match-string-no-properties 1)))) | ||
| 530 | ;; This corrects the quote count when matching odd number | ||
| 531 | ;; of backslashes followed by even number of quotes. | ||
| 532 | (or (and (= 1 (logand n 1)) n) (1- n)))) | ||
| 533 | (ppss (prog2 | 528 | (ppss (prog2 |
| 534 | (backward-char num-quotes) | 529 | (backward-char num-quotes) |
| 535 | (syntax-ppss) | 530 | (syntax-ppss) |
| @@ -1866,31 +1861,45 @@ When MSG is non-nil messages the first line of STRING." | |||
| 1866 | (string-match "\n[ \t].*\n?$" string)) | 1861 | (string-match "\n[ \t].*\n?$" string)) |
| 1867 | (comint-send-string process "\n"))))) | 1862 | (comint-send-string process "\n"))))) |
| 1868 | 1863 | ||
| 1864 | ;; Shell output catching stolen from gud-gdb | ||
| 1865 | (defvar python-shell-fetch-lines-in-progress nil) | ||
| 1866 | (defvar python-shell-fetch-lines-string nil) | ||
| 1867 | (defvar python-shell-fetched-lines nil) | ||
| 1868 | |||
| 1869 | (defun python-shell-fetch-lines-filter (string) | ||
| 1870 | "Filter used to read the list of lines output by a command. | ||
| 1871 | STRING is the output to filter." | ||
| 1872 | (setq string (concat python-shell-fetch-lines-string string)) | ||
| 1873 | (while (string-match "\n" string) | ||
| 1874 | (push (substring string 0 (match-beginning 0)) | ||
| 1875 | python-shell-fetched-lines) | ||
| 1876 | (setq string (substring string (match-end 0)))) | ||
| 1877 | (if (equal (string-match comint-prompt-regexp string) 0) | ||
| 1878 | (progn | ||
| 1879 | (setq python-shell-fetch-lines-in-progress nil) | ||
| 1880 | string) | ||
| 1881 | (progn | ||
| 1882 | (setq python-shell-fetch-lines-string string) | ||
| 1883 | ""))) | ||
| 1884 | |||
| 1869 | (defun python-shell-send-string-no-output (string &optional process msg) | 1885 | (defun python-shell-send-string-no-output (string &optional process msg) |
| 1870 | "Send STRING to PROCESS and inhibit output. | 1886 | "Send STRING to PROCESS and inhibit output. |
| 1871 | When MSG is non-nil messages the first line of STRING. Return | 1887 | When MSG is non-nil messages the first line of STRING. Return |
| 1872 | the output." | 1888 | the output." |
| 1873 | (let* ((output-buffer "") | 1889 | (let ((process (or process (python-shell-get-or-create-process))) |
| 1874 | (process (or process (python-shell-get-or-create-process))) | 1890 | (comint-preoutput-filter-functions |
| 1875 | (comint-preoutput-filter-functions | 1891 | '(python-shell-fetch-lines-filter)) |
| 1876 | (append comint-preoutput-filter-functions | 1892 | (python-shell-fetch-lines-in-progress t) |
| 1877 | '(ansi-color-filter-apply | 1893 | (inhibit-quit t)) |
| 1878 | (lambda (string) | ||
| 1879 | (setq output-buffer (concat output-buffer string)) | ||
| 1880 | "")))) | ||
| 1881 | (inhibit-quit t)) | ||
| 1882 | (or | 1894 | (or |
| 1883 | (with-local-quit | 1895 | (with-local-quit |
| 1884 | (python-shell-send-string string process msg) | 1896 | (python-shell-send-string string process msg) |
| 1885 | (accept-process-output process) | 1897 | (while python-shell-fetch-lines-in-progress |
| 1886 | (replace-regexp-in-string | 1898 | (accept-process-output process)) |
| 1887 | (if (> (length python-shell-prompt-output-regexp) 0) | 1899 | (prog1 |
| 1888 | (format "\n*%s$\\|^%s\\|\n$" | 1900 | (mapconcat #'identity |
| 1889 | python-shell-prompt-regexp | 1901 | (reverse python-shell-fetched-lines) "\n") |
| 1890 | (or python-shell-prompt-output-regexp "")) | 1902 | (setq python-shell-fetched-lines nil))) |
| 1891 | (format "\n*$\\|^%s\\|\n$" | ||
| 1892 | python-shell-prompt-regexp)) | ||
| 1893 | "" output-buffer)) | ||
| 1894 | (with-current-buffer (process-buffer process) | 1903 | (with-current-buffer (process-buffer process) |
| 1895 | (comint-interrupt-subjob))))) | 1904 | (comint-interrupt-subjob))))) |
| 1896 | 1905 | ||
| @@ -2258,32 +2267,100 @@ inferior python process is updated properly." | |||
| 2258 | This is the function used by `python-fill-paragraph-function' to | 2267 | This is the function used by `python-fill-paragraph-function' to |
| 2259 | fill comments." | 2268 | fill comments." |
| 2260 | :type 'symbol | 2269 | :type 'symbol |
| 2261 | :group 'python | 2270 | :group 'python) |
| 2262 | :safe 'symbolp) | ||
| 2263 | 2271 | ||
| 2264 | (defcustom python-fill-string-function 'python-fill-string | 2272 | (defcustom python-fill-string-function 'python-fill-string |
| 2265 | "Function to fill strings. | 2273 | "Function to fill strings. |
| 2266 | This is the function used by `python-fill-paragraph-function' to | 2274 | This is the function used by `python-fill-paragraph-function' to |
| 2267 | fill strings." | 2275 | fill strings." |
| 2268 | :type 'symbol | 2276 | :type 'symbol |
| 2269 | :group 'python | 2277 | :group 'python) |
| 2270 | :safe 'symbolp) | ||
| 2271 | 2278 | ||
| 2272 | (defcustom python-fill-decorator-function 'python-fill-decorator | 2279 | (defcustom python-fill-decorator-function 'python-fill-decorator |
| 2273 | "Function to fill decorators. | 2280 | "Function to fill decorators. |
| 2274 | This is the function used by `python-fill-paragraph-function' to | 2281 | This is the function used by `python-fill-paragraph-function' to |
| 2275 | fill decorators." | 2282 | fill decorators." |
| 2276 | :type 'symbol | 2283 | :type 'symbol |
| 2277 | :group 'python | 2284 | :group 'python) |
| 2278 | :safe 'symbolp) | ||
| 2279 | 2285 | ||
| 2280 | (defcustom python-fill-paren-function 'python-fill-paren | 2286 | (defcustom python-fill-paren-function 'python-fill-paren |
| 2281 | "Function to fill parens. | 2287 | "Function to fill parens. |
| 2282 | This is the function used by `python-fill-paragraph-function' to | 2288 | This is the function used by `python-fill-paragraph-function' to |
| 2283 | fill parens." | 2289 | fill parens." |
| 2284 | :type 'symbol | 2290 | :type 'symbol |
| 2291 | :group 'python) | ||
| 2292 | |||
| 2293 | (defcustom python-fill-docstring-style 'pep-257 | ||
| 2294 | "Style used to fill docstrings. | ||
| 2295 | This affects `python-fill-string' behavior with regards to | ||
| 2296 | triple quotes positioning. | ||
| 2297 | |||
| 2298 | Possible values are DJANGO, ONETWO, PEP-257, PEP-257-NN, | ||
| 2299 | SYMMETRIC, and NIL. A value of NIL won't care about quotes | ||
| 2300 | position and will treat docstrings a normal string, any other | ||
| 2301 | value may result in one of the following docstring styles: | ||
| 2302 | |||
| 2303 | DJANGO: | ||
| 2304 | |||
| 2305 | \"\"\" | ||
| 2306 | Process foo, return bar. | ||
| 2307 | \"\"\" | ||
| 2308 | |||
| 2309 | \"\"\" | ||
| 2310 | Process foo, return bar. | ||
| 2311 | |||
| 2312 | If processing fails throw ProcessingError. | ||
| 2313 | \"\"\" | ||
| 2314 | |||
| 2315 | ONETWO: | ||
| 2316 | |||
| 2317 | \"\"\"Process foo, return bar.\"\"\" | ||
| 2318 | |||
| 2319 | \"\"\" | ||
| 2320 | Process foo, return bar. | ||
| 2321 | |||
| 2322 | If processing fails throw ProcessingError. | ||
| 2323 | |||
| 2324 | \"\"\" | ||
| 2325 | |||
| 2326 | PEP-257: | ||
| 2327 | |||
| 2328 | \"\"\"Process foo, return bar.\"\"\" | ||
| 2329 | |||
| 2330 | \"\"\"Process foo, return bar. | ||
| 2331 | |||
| 2332 | If processing fails throw ProcessingError. | ||
| 2333 | |||
| 2334 | \"\"\" | ||
| 2335 | |||
| 2336 | PEP-257-NN: | ||
| 2337 | |||
| 2338 | \"\"\"Process foo, return bar.\"\"\" | ||
| 2339 | |||
| 2340 | \"\"\"Process foo, return bar. | ||
| 2341 | |||
| 2342 | If processing fails throw ProcessingError. | ||
| 2343 | \"\"\" | ||
| 2344 | |||
| 2345 | SYMMETRIC: | ||
| 2346 | |||
| 2347 | \"\"\"Process foo, return bar.\"\"\" | ||
| 2348 | |||
| 2349 | \"\"\" | ||
| 2350 | Process foo, return bar. | ||
| 2351 | |||
| 2352 | If processing fails throw ProcessingError. | ||
| 2353 | \"\"\"" | ||
| 2354 | :type '(choice | ||
| 2355 | (const :tag "Don't format docstrings" nil) | ||
| 2356 | (const :tag "Django's coding standards style." django) | ||
| 2357 | (const :tag "One newline and start and Two at end style." onetwo) | ||
| 2358 | (const :tag "PEP-257 with 2 newlines at end of string." pep-257) | ||
| 2359 | (const :tag "PEP-257 with 1 newline at end of string." pep-257-nn) | ||
| 2360 | (const :tag "Symmetric style." symmetric)) | ||
| 2285 | :group 'python | 2361 | :group 'python |
| 2286 | :safe 'symbolp) | 2362 | :safe (lambda (val) |
| 2363 | (memq val '(django onetwo pep-257 pep-257-nn symmetric nil)))) | ||
| 2287 | 2364 | ||
| 2288 | (defun python-fill-paragraph-function (&optional justify) | 2365 | (defun python-fill-paragraph-function (&optional justify) |
| 2289 | "`fill-paragraph-function' handling multi-line strings and possibly comments. | 2366 | "`fill-paragraph-function' handling multi-line strings and possibly comments. |
| @@ -2293,18 +2370,19 @@ the string's indentation. | |||
| 2293 | Optional argument JUSTIFY defines if the paragraph should be justified." | 2370 | Optional argument JUSTIFY defines if the paragraph should be justified." |
| 2294 | (interactive "P") | 2371 | (interactive "P") |
| 2295 | (save-excursion | 2372 | (save-excursion |
| 2296 | (back-to-indentation) | ||
| 2297 | (cond | 2373 | (cond |
| 2298 | ;; Comments | 2374 | ;; Comments |
| 2299 | ((funcall python-fill-comment-function justify)) | 2375 | ((python-syntax-context 'comment) |
| 2376 | (funcall python-fill-comment-function justify)) | ||
| 2300 | ;; Strings/Docstrings | 2377 | ;; Strings/Docstrings |
| 2301 | ((save-excursion (skip-chars-forward "\"'uUrR") | 2378 | ((save-excursion (or (python-syntax-context 'string) |
| 2302 | (python-syntax-context 'string)) | 2379 | (equal (string-to-syntax "|") |
| 2380 | (syntax-after (point))))) | ||
| 2303 | (funcall python-fill-string-function justify)) | 2381 | (funcall python-fill-string-function justify)) |
| 2304 | ;; Decorators | 2382 | ;; Decorators |
| 2305 | ((equal (char-after (save-excursion | 2383 | ((equal (char-after (save-excursion |
| 2306 | (back-to-indentation) | 2384 | (back-to-indentation) |
| 2307 | (point-marker))) ?@) | 2385 | (point))) ?@) |
| 2308 | (funcall python-fill-decorator-function justify)) | 2386 | (funcall python-fill-decorator-function justify)) |
| 2309 | ;; Parens | 2387 | ;; Parens |
| 2310 | ((or (python-syntax-context 'paren) | 2388 | ((or (python-syntax-context 'paren) |
| @@ -2323,43 +2401,72 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'." | |||
| 2323 | (defun python-fill-string (&optional justify) | 2401 | (defun python-fill-string (&optional justify) |
| 2324 | "String fill function for `python-fill-paragraph-function'. | 2402 | "String fill function for `python-fill-paragraph-function'. |
| 2325 | JUSTIFY should be used (if applicable) as in `fill-paragraph'." | 2403 | JUSTIFY should be used (if applicable) as in `fill-paragraph'." |
| 2326 | (let ((marker (point-marker)) | 2404 | (let* ((marker (point-marker)) |
| 2327 | (string-start-marker | 2405 | (str-start-pos |
| 2328 | (progn | 2406 | (let ((m (make-marker))) |
| 2329 | (skip-chars-forward "\"'uUrR") | 2407 | (setf (marker-position m) |
| 2330 | (goto-char (python-syntax-context 'string)) | 2408 | (or (python-syntax-context 'string) |
| 2331 | (skip-chars-forward "\"'uUrR") | 2409 | (and (equal (string-to-syntax "|") |
| 2332 | (point-marker))) | 2410 | (syntax-after (point))) |
| 2333 | (reg-start (line-beginning-position)) | 2411 | (point)))) m)) |
| 2334 | (string-end-marker | 2412 | (num-quotes (python-syntax-count-quotes |
| 2335 | (progn | 2413 | (char-after str-start-pos) str-start-pos)) |
| 2336 | (while (python-syntax-context 'string) | 2414 | (str-end-pos |
| 2337 | (goto-char (1+ (point-marker)))) | 2415 | (save-excursion |
| 2338 | (skip-chars-backward "\"'") | 2416 | (goto-char (+ str-start-pos num-quotes)) |
| 2339 | (point-marker))) | 2417 | (or (re-search-forward (rx (syntax string-delimiter)) nil t) |
| 2340 | (reg-end (line-end-position)) | 2418 | (goto-char (point-max))) |
| 2341 | (fill-paragraph-function)) | 2419 | (point-marker))) |
| 2420 | (multi-line-p | ||
| 2421 | ;; Docstring styles may vary for oneliners and multi-liners. | ||
| 2422 | (> (count-matches "\n" str-start-pos str-end-pos) 0)) | ||
| 2423 | (delimiters-style | ||
| 2424 | (case python-fill-docstring-style | ||
| 2425 | ;; delimiters-style is a cons cell with the form | ||
| 2426 | ;; (START-NEWLINES . END-NEWLINES). When any of the sexps | ||
| 2427 | ;; is NIL means to not add any newlines for start or end | ||
| 2428 | ;; of docstring. See `python-fill-docstring-style' for a | ||
| 2429 | ;; graphic idea of each style. | ||
| 2430 | (django (cons 1 1)) | ||
| 2431 | (onetwo (and multi-line-p (cons 1 2))) | ||
| 2432 | (pep-257 (and multi-line-p (cons nil 2))) | ||
| 2433 | (pep-257-nn (and multi-line-p (cons nil 1))) | ||
| 2434 | (symmetric (and multi-line-p (cons 1 1))))) | ||
| 2435 | (docstring-p (save-excursion | ||
| 2436 | ;; Consider docstrings those strings which | ||
| 2437 | ;; start on a line by themselves. | ||
| 2438 | (python-nav-beginning-of-statement) | ||
| 2439 | (and (= (point) str-start-pos)))) | ||
| 2440 | (fill-paragraph-function)) | ||
| 2342 | (save-restriction | 2441 | (save-restriction |
| 2343 | (narrow-to-region reg-start reg-end) | 2442 | (narrow-to-region str-start-pos str-end-pos) |
| 2344 | (save-excursion | 2443 | (fill-paragraph justify)) |
| 2345 | (goto-char string-start-marker) | 2444 | (save-excursion |
| 2346 | (delete-region (point-marker) (progn | 2445 | (when (and docstring-p python-fill-docstring-style) |
| 2347 | (skip-syntax-forward "> ") | 2446 | ;; Add the number of newlines indicated by the selected style |
| 2348 | (point-marker))) | 2447 | ;; at the start of the docstring. |
| 2349 | (goto-char string-end-marker) | 2448 | (goto-char (+ str-start-pos num-quotes)) |
| 2350 | (delete-region (point-marker) (progn | 2449 | (delete-region (point) (progn |
| 2351 | (skip-syntax-backward "> ") | 2450 | (skip-syntax-forward "> ") |
| 2352 | (point-marker))) | 2451 | (point))) |
| 2353 | (save-excursion | 2452 | (and (car delimiters-style) |
| 2354 | (goto-char marker) | 2453 | (or (newline (car delimiters-style)) t) |
| 2355 | (fill-paragraph justify)) | 2454 | ;; Indent only if a newline is added. |
| 2356 | ;; If there is a newline in the docstring lets put triple | 2455 | (indent-according-to-mode)) |
| 2357 | ;; quote in it's own line to follow pep 8 | 2456 | ;; Add the number of newlines indicated by the selected style |
| 2358 | (when (save-excursion | 2457 | ;; at the end of the docstring. |
| 2359 | (re-search-backward "\n" string-start-marker t)) | 2458 | (goto-char (if (not (= str-end-pos (point-max))) |
| 2360 | (newline) | 2459 | (- str-end-pos num-quotes) |
| 2361 | (newline-and-indent)) | 2460 | str-end-pos)) |
| 2362 | (fill-paragraph justify)))) t) | 2461 | (delete-region (point) (progn |
| 2462 | (skip-syntax-backward "> ") | ||
| 2463 | (point))) | ||
| 2464 | (and (cdr delimiters-style) | ||
| 2465 | ;; Add newlines only if string ends. | ||
| 2466 | (not (= str-end-pos (point-max))) | ||
| 2467 | (or (newline (cdr delimiters-style)) t) | ||
| 2468 | ;; Again indent only if a newline is added. | ||
| 2469 | (indent-according-to-mode))))) t) | ||
| 2363 | 2470 | ||
| 2364 | (defun python-fill-decorator (&optional justify) | 2471 | (defun python-fill-decorator (&optional justify) |
| 2365 | "Decorator fill function for `python-fill-paragraph-function'. | 2472 | "Decorator fill function for `python-fill-paragraph-function'. |