Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to format a complete python buffer in emacs with a key press?

I am looking for any way to have Emacs format a Python buffer by hitting a few keys. By format, I mean:

  1. Replace tabs with 4 spaces
  2. Wrap all long lines correctly at 79 chars. This includes wrapping & concatenating long strings, wrapping long comments, wrapping lists, function headers, etc.
  3. Unrelated, but when I hit enter, it'd be nice if the cursor was tabbed in automatically.

In general I'd like to just format everything according to PEP 8.

I've looked for a pretty printer / code beautifier / code formatter for Python to run the buffer through, but can't find an open source one.

My .emacs is here.

For those who are going to answer "You don't need a formatter for Python, it's beautiful by the nature of the language," I say to you that this is not correct. In real software systems, comments should be auto-wrapped for you, strings are going to be longer than 79 characters, tab levels run 3+ deep. Please just help me solve my issue directly without some philosophical discussion about the merits of formatting Python source.

like image 805
Vic Fryzel Avatar asked Oct 23 '25 06:10

Vic Fryzel


2 Answers

To change tabs into spaces and fill comments at the same time, you can use this command:

(defun my-format-python-text ()
  "untabify and wrap python comments"
  (interactive)
  (untabify (point-min) (point-max))
  (goto-char (point-min))
  (while (re-search-forward comment-start nil t)
    (call-interactively 'fill-paragraph)
    (forward-line 1)))

Which you can bind to the key of your choice, presumably like so:

(eval-after-load "python"
  '(progn
     (define-key python-mode-map (kbd "RET") 'newline-and-indent)
     (define-key python-mode-map (kbd "<f4>") 'my-format-python-text)))

Note the setting of the RET key to automatically indent.

If you wanted to all tabs with spaces with just built-in commands, this is a possible sequence:

C-x h           ;; mark-whole-buffer
M-x untabify    ;; tabs->spaces

To get the fill column and tab width to be what you want, add to your .emacs:

(setq fill-column 79)
(setq-default tab-width 4)

Arguably, the tab-width should be set to 8, depending on how other folks have indented their code in your environment (8 being a default that some other editors have). If that's the case, you could just set it to 4 in the 'python-mode-hook. It kind of depends on your environment.

like image 176
Trey Jackson Avatar answered Oct 25 '25 19:10

Trey Jackson


About your point 3:

Unrelated, but when I hit enter, it'd be nice if the cursor was tabbed in automatically.

My emacs Python mode does this by default, apparently. It's simply called python-mode...

like image 21
Eric O Lebigot Avatar answered Oct 25 '25 20:10

Eric O Lebigot