aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorkobarity2023-03-12 17:05:54 +0900
committerEli Zaretskii2023-03-16 16:59:06 +0200
commit5cf1de683b2414927e521c34daeee460fb7649f5 (patch)
tree8f3602006d4454ddb7be376fea41dfe15e5f3c94 /lisp/progmodes/python.el
parent7385c991dff3466b37cf50628e7685cd53e71921 (diff)
downloademacs-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.el35
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.
520TYPE can be `comment', `string' or `paren'. It returns the start 526TYPE can be `comment', `string', `single-quoted-string',
527`triple-quoted-string' or `paren'. It returns the start
521character address of the specified TYPE." 528character 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.
6052It returns the position of the third quote character of the start
6053of 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.
6048Returns the encoding as a symbol." 6067Returns the encoding as a symbol."