diff options
| author | kobarity | 2023-03-12 17:05:54 +0900 |
|---|---|---|
| committer | Eli Zaretskii | 2023-03-16 16:59:06 +0200 |
| commit | 5cf1de683b2414927e521c34daeee460fb7649f5 (patch) | |
| tree | 8f3602006d4454ddb7be376fea41dfe15e5f3c94 /lisp/progmodes/python.el | |
| parent | 7385c991dff3466b37cf50628e7685cd53e71921 (diff) | |
| download | emacs-5cf1de683b2414927e521c34daeee460fb7649f5.tar.gz emacs-5cf1de683b2414927e521c34daeee460fb7649f5.zip | |
Fix python-fill-paragraph problems on filling strings (bug#62142)
* lisp/progmodes/python.el (python-syntax--context-compiler-macro)
(python-syntax-context): Add single-quoted-string and
triple-quoted-string as TYPE argument.
(python-info-triple-quoted-string-p): New helper function.
(python-fill-paragraph)
(python-fill-string): Use it.
* test/lisp/progmodes/python-tests.el (python-syntax-context-1)
(python-fill-paragraph-single-quoted-string-1)
(python-fill-paragraph-single-quoted-string-2)
(python-fill-paragraph-triple-quoted-string-1)
(python-info-triple-quoted-string-p-1)
(python-info-triple-quoted-string-p-2)
(python-info-triple-quoted-string-p-3): New tests.
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 8793fdc6458..2fe88323c35 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -511,19 +511,28 @@ This variant of `rx' supports common Python named REGEXPS." | |||
| 511 | (''string | 511 | (''string |
| 512 | `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) | 512 | `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) |
| 513 | (and (nth 3 ppss) (nth 8 ppss)))) | 513 | (and (nth 3 ppss) (nth 8 ppss)))) |
| 514 | (''single-quoted-string | ||
| 515 | `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) | ||
| 516 | (and (characterp (nth 3 ppss)) (nth 8 ppss)))) | ||
| 517 | (''triple-quoted-string | ||
| 518 | `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) | ||
| 519 | (and (eq t (nth 3 ppss)) (nth 8 ppss)))) | ||
| 514 | (''paren | 520 | (''paren |
| 515 | `(nth 1 (or ,syntax-ppss (syntax-ppss)))) | 521 | `(nth 1 (or ,syntax-ppss (syntax-ppss)))) |
| 516 | (_ form)))) | 522 | (_ form)))) |
| 517 | 523 | ||
| 518 | (defun python-syntax-context (type &optional syntax-ppss) | 524 | (defun python-syntax-context (type &optional syntax-ppss) |
| 519 | "Return non-nil if point is on TYPE using SYNTAX-PPSS. | 525 | "Return non-nil if point is on TYPE using SYNTAX-PPSS. |
| 520 | TYPE can be `comment', `string' or `paren'. It returns the start | 526 | TYPE can be `comment', `string', `single-quoted-string', |
| 527 | `triple-quoted-string' or `paren'. It returns the start | ||
| 521 | character address of the specified TYPE." | 528 | character address of the specified TYPE." |
| 522 | (declare (compiler-macro python-syntax--context-compiler-macro)) | 529 | (declare (compiler-macro python-syntax--context-compiler-macro)) |
| 523 | (let ((ppss (or syntax-ppss (syntax-ppss)))) | 530 | (let ((ppss (or syntax-ppss (syntax-ppss)))) |
| 524 | (pcase type | 531 | (pcase type |
| 525 | ('comment (and (nth 4 ppss) (nth 8 ppss))) | 532 | ('comment (and (nth 4 ppss) (nth 8 ppss))) |
| 526 | ('string (and (nth 3 ppss) (nth 8 ppss))) | 533 | ('string (and (nth 3 ppss) (nth 8 ppss))) |
| 534 | ('single-quoted-string (and (characterp (nth 3 ppss)) (nth 8 ppss))) | ||
| 535 | ('triple-quoted-string (and (eq t (nth 3 ppss)) (nth 8 ppss))) | ||
| 527 | ('paren (nth 1 ppss)) | 536 | ('paren (nth 1 ppss)) |
| 528 | (_ nil)))) | 537 | (_ nil)))) |
| 529 | 538 | ||
| @@ -4805,9 +4814,7 @@ Optional argument JUSTIFY defines if the paragraph should be justified." | |||
| 4805 | ((python-syntax-context 'comment) | 4814 | ((python-syntax-context 'comment) |
| 4806 | (funcall python-fill-comment-function justify)) | 4815 | (funcall python-fill-comment-function justify)) |
| 4807 | ;; Strings/Docstrings | 4816 | ;; Strings/Docstrings |
| 4808 | ((save-excursion (or (python-syntax-context 'string) | 4817 | ((python-info-triple-quoted-string-p) |
| 4809 | (equal (string-to-syntax "|") | ||
| 4810 | (syntax-after (point))))) | ||
| 4811 | (funcall python-fill-string-function justify)) | 4818 | (funcall python-fill-string-function justify)) |
| 4812 | ;; Decorators | 4819 | ;; Decorators |
| 4813 | ((equal (char-after (save-excursion | 4820 | ((equal (char-after (save-excursion |
| @@ -4833,10 +4840,7 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'." | |||
| 4833 | (let* ((str-start-pos | 4840 | (let* ((str-start-pos |
| 4834 | (set-marker | 4841 | (set-marker |
| 4835 | (make-marker) | 4842 | (make-marker) |
| 4836 | (or (python-syntax-context 'string) | 4843 | (python-info-triple-quoted-string-p))) |
| 4837 | (and (equal (string-to-syntax "|") | ||
| 4838 | (syntax-after (point))) | ||
| 4839 | (point))))) | ||
| 4840 | ;; JT@2021-09-21: Since bug#49518's fix this will always be 1 | 4844 | ;; JT@2021-09-21: Since bug#49518's fix this will always be 1 |
| 4841 | (num-quotes (python-syntax-count-quotes | 4845 | (num-quotes (python-syntax-count-quotes |
| 4842 | (char-after str-start-pos) str-start-pos)) | 4846 | (char-after str-start-pos) str-start-pos)) |
| @@ -6043,6 +6047,21 @@ point's current `syntax-ppss'." | |||
| 6043 | ((python-info-looking-at-beginning-of-defun)) | 6047 | ((python-info-looking-at-beginning-of-defun)) |
| 6044 | (t nil)))))) | 6048 | (t nil)))))) |
| 6045 | 6049 | ||
| 6050 | (defun python-info-triple-quoted-string-p () | ||
| 6051 | "Check if point is in a triple quoted string including quotes. | ||
| 6052 | It returns the position of the third quote character of the start | ||
| 6053 | of the string." | ||
| 6054 | (save-excursion | ||
| 6055 | (let ((pos (point))) | ||
| 6056 | (cl-loop | ||
| 6057 | for offset in '(0 3 -2 2 -1 1) | ||
| 6058 | if (let ((check-pos (+ pos offset))) | ||
| 6059 | (and (>= check-pos (point-min)) | ||
| 6060 | (<= check-pos (point-max)) | ||
| 6061 | (python-syntax-context | ||
| 6062 | 'triple-quoted-string (syntax-ppss check-pos)))) | ||
| 6063 | return it)))) | ||
| 6064 | |||
| 6046 | (defun python-info-encoding-from-cookie () | 6065 | (defun python-info-encoding-from-cookie () |
| 6047 | "Detect current buffer's encoding from its coding cookie. | 6066 | "Detect current buffer's encoding from its coding cookie. |
| 6048 | Returns the encoding as a symbol." | 6067 | Returns the encoding as a symbol." |