* Python fill-paragraph
@ 2012-10-04 15:32 Fabian Ezequiel Gallina
2012-10-04 16:25 ` Stefan Monnier
0 siblings, 1 reply; 3+ messages in thread
From: Fabian Ezequiel Gallina @ 2012-10-04 15:32 UTC (permalink / raw)
To: Emacs-Devel devel
Now that we are on feature freeze I happen to step into a bug[0] into
the fill paragraph machinery we have on python.el.
As I see it, the good way to solve it is to give the user the
possibility to indicate how he wants his docstrings formatted. For
this I created a patch (ChangeLog not included yet) that adds this
feature while it fixes this bug.
Is it possible for me to install it into the trunk?
[0] https://github.com/fgallina/python.el/issues/107
=== modified file 'lisp/progmodes/python.el'
--- lisp/progmodes/python.el 2012-10-03 21:53:09 +0000
+++ lisp/progmodes/python.el 2012-10-04 15:24:50 +0000
@@ -2267,32 +2267,82 @@
This is the function used by `python-fill-paragraph-function' to
fill comments."
:type 'symbol
- :group 'python
- :safe 'symbolp)
+ :group 'python)
(defcustom python-fill-string-function 'python-fill-string
"Function to fill strings.
This is the function used by `python-fill-paragraph-function' to
fill strings."
:type 'symbol
- :group 'python
- :safe 'symbolp)
+ :group 'python)
(defcustom python-fill-decorator-function 'python-fill-decorator
"Function to fill decorators.
This is the function used by `python-fill-paragraph-function' to
fill decorators."
:type 'symbol
- :group 'python
- :safe 'symbolp)
+ :group 'python)
(defcustom python-fill-paren-function 'python-fill-paren
"Function to fill parens.
This is the function used by `python-fill-paragraph-function' to
fill parens."
:type 'symbol
+ :group 'python)
+
+(defcustom python-fill-string-style 'pep-257
+ "Style used to fill docstrings.
+This affects `python-fill-string' behavior with regards to
+triple quotes positioning.
+
+Possible values are DJANGO, PEP-257, PEP-257-NN, SYMMETRIC and
+NIL. A value of NIL won't care about quotes position, will do
+what `fill-paragraph' does, any other value may result in one of
+the following docstring styles:
+
+DJANGO:
+
+ \"\"\"
+ Process foo, return bar.
+ \"\"\"
+
+ \"\"\"
+ Process foo, return bar.
+
+ If processing fails throw ProcessingError.
+ \"\"\"
+
+PEP-257:
+
+ \"\"\"Process foo, return bar.\"\"\"
+
+ \"\"\"Process foo, return bar.
+
+ If processing fails throw ProcessingError.
+
+ \"\"\"
+
+PEP-257-NN:
+
+ \"\"\"Process foo, return bar.\"\"\"
+
+ \"\"\"Process foo, return bar.
+
+ If processing fails throw ProcessingError.
+ \"\"\"
+
+SYMMETRIC:
+
+ \"\"\"Process foo, return bar.\"\"\"
+
+ \"\"\"
+ Process foo, return bar.
+
+ If processing fails throw ProcessingError.
+ \"\"\""
+ :type 'symbol
:group 'python
- :safe 'symbolp)
+ :safe (lambda (val) (memq val '(django pep-257 pep-257-nn symmetric nil))))
(defun python-fill-paragraph-function (&optional justify)
"`fill-paragraph-function' handling multi-line strings and possibly comments.
@@ -2302,18 +2352,19 @@
Optional argument JUSTIFY defines if the paragraph should be justified."
(interactive "P")
(save-excursion
- (back-to-indentation)
(cond
;; Comments
- ((funcall python-fill-comment-function justify))
+ ((python-syntax-context 'comment)
+ (funcall python-fill-comment-function justify))
;; Strings/Docstrings
- ((save-excursion (skip-chars-forward "\"'uUrR")
- (python-syntax-context 'string))
+ ((save-excursion (or (python-syntax-context 'string)
+ (equal (string-to-syntax "|")
+ (syntax-after (point)))))
(funcall python-fill-string-function justify))
;; Decorators
((equal (char-after (save-excursion
(back-to-indentation)
- (point-marker))) ?@)
+ (point))) ?@)
(funcall python-fill-decorator-function justify))
;; Parens
((or (python-syntax-context 'paren)
@@ -2332,43 +2383,72 @@
(defun python-fill-string (&optional justify)
"String fill function for `python-fill-paragraph-function'.
JUSTIFY should be used (if applicable) as in `fill-paragraph'."
- (let ((marker (point-marker))
- (string-start-marker
- (progn
- (skip-chars-forward "\"'uUrR")
- (goto-char (python-syntax-context 'string))
- (skip-chars-forward "\"'uUrR")
- (point-marker)))
- (reg-start (line-beginning-position))
- (string-end-marker
- (progn
- (while (python-syntax-context 'string)
- (goto-char (1+ (point-marker))))
- (skip-chars-backward "\"'")
- (point-marker)))
- (reg-end (line-end-position))
- (fill-paragraph-function))
+ (let* ((marker (point-marker))
+ (str-start-pos
+ (let ((m (make-marker)))
+ (setf (marker-position m)
+ (or (python-syntax-context 'string)
+ (and (equal (string-to-syntax "|")
+ (syntax-after (point)))
+ (point)))) m))
+ (num-quotes (python-syntax-count-quotes
+ (char-after str-start-pos) str-start-pos))
+ (str-end-pos
+ (save-excursion
+ (goto-char (+ str-start-pos num-quotes))
+ (or (re-search-forward (rx (syntax string-delimiter)) nil t)
+ (goto-char (point-max)))
+ (point-marker)))
+ (multi-line-p
+ ;; Docstring styles may vary for oneliners and multi-liners.
+ (> (count-matches "\n" str-start-pos str-end-pos) 0))
+ (delimiters-style
+ (case python-fill-string-style
+ ;; delimiters-style is a cons cell with the form
+ ;; (START-NEWLINES . END-NEWLINES). When any of the sexps
+ ;; is NIL means to not add any newlines for start or end
+ ;; of docstring. See `python-fill-string-style' for a
+ ;; graphic idea of each style.
+ (pep-257 (and multi-line-p (cons nil 2)))
+ (pep-257-nn (and multi-line-p (cons nil 1)))
+ (django (cons 1 1))
+ (symmetric (and multi-line-p (cons 1 1)))))
+ (docstring-p (save-excursion
+ ;; Consider docstrings those strings which
+ ;; start on a line by themselves.
+ (goto-char str-start-pos)
+ (skip-chars-backward (rx whitespace))
+ (= (point) (line-beginning-position))))
+ (fill-paragraph-function))
(save-restriction
- (narrow-to-region reg-start reg-end)
- (save-excursion
- (goto-char string-start-marker)
- (delete-region (point-marker) (progn
- (skip-syntax-forward "> ")
- (point-marker)))
- (goto-char string-end-marker)
- (delete-region (point-marker) (progn
- (skip-syntax-backward "> ")
- (point-marker)))
- (save-excursion
- (goto-char marker)
- (fill-paragraph justify))
- ;; If there is a newline in the docstring lets put triple
- ;; quote in it's own line to follow pep 8
- (when (save-excursion
- (re-search-backward "\n" string-start-marker t))
- (newline)
- (newline-and-indent))
- (fill-paragraph justify)))) t)
+ (narrow-to-region str-start-pos str-end-pos)
+ (fill-paragraph justify))
+ (save-excursion
+ (when (and docstring-p python-fill-string-style)
+ ;; Add the number of newlines indicated by the selected style
+ ;; at the start of the docstring.
+ (goto-char (+ str-start-pos num-quotes))
+ (delete-region (point) (progn
+ (skip-syntax-forward "> ")
+ (point)))
+ (and (car delimiters-style)
+ (or (newline (car delimiters-style)) t)
+ ;; Indent only if a newline is added.
+ (indent-according-to-mode))
+ ;; Add the number of newlines indicated by the selected style
+ ;; at the end of the docstring.
+ (goto-char (if (not (= str-end-pos (point-max)))
+ (- str-end-pos num-quotes)
+ str-end-pos))
+ (delete-region (point) (progn
+ (skip-syntax-backward "> ")
+ (point)))
+ (and (cdr delimiters-style)
+ ;; Add newlines only if string ends.
+ (not (= str-end-pos (point-max)))
+ (or (newline (cdr delimiters-style)) t)
+ ;; Again indent only if a newline is added.
+ (indent-according-to-mode))))) t)
(defun python-fill-decorator (&optional justify)
"Decorator fill function for `python-fill-paragraph-function'.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Python fill-paragraph
2012-10-04 15:32 Python fill-paragraph Fabian Ezequiel Gallina
@ 2012-10-04 16:25 ` Stefan Monnier
2012-10-04 16:47 ` Fabian Ezequiel Gallina
0 siblings, 1 reply; 3+ messages in thread
From: Stefan Monnier @ 2012-10-04 16:25 UTC (permalink / raw)
To: Fabian Ezequiel Gallina; +Cc: Emacs-Devel devel
> Now that we are on feature freeze I happen to step into a bug[0] into
> the fill paragraph machinery we have on python.el.
Remember it's a *feature* freeze, so bug-fixes are still very welcome
(actually the purpose of a feature freeze is to encourage people to
focus on fixing bugs).
> - :group 'python
> - :safe 'symbolp)
> + :group 'python)
These are urgent, indeed.
Stefan
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Python fill-paragraph
2012-10-04 16:25 ` Stefan Monnier
@ 2012-10-04 16:47 ` Fabian Ezequiel Gallina
0 siblings, 0 replies; 3+ messages in thread
From: Fabian Ezequiel Gallina @ 2012-10-04 16:47 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Emacs-Devel devel
2012/10/4 Stefan Monnier <monnier@iro.umontreal.ca>:
>> Now that we are on feature freeze I happen to step into a bug[0] into
>> the fill paragraph machinery we have on python.el.
>
> Remember it's a *feature* freeze, so bug-fixes are still very welcome
> (actually the purpose of a feature freeze is to encourage people to
> focus on fixing bugs).
>
>> - :group 'python
>> - :safe 'symbolp)
>> + :group 'python)
>
> These are urgent, indeed.
>
>
> Stefan
Perfect, installed in revno 110361.
Regards,
Fabián E. Gallina
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-10-04 16:47 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-04 15:32 Python fill-paragraph Fabian Ezequiel Gallina
2012-10-04 16:25 ` Stefan Monnier
2012-10-04 16:47 ` Fabian Ezequiel Gallina
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).