Emacs bulk indent for Python

45,848

Solution 1

If you are programming Python using Emacs, then you should probably be using python-mode. With python-mode, after marking the block of code,

C-c > or C-c C-l shifts the region 4 spaces to the right

C-c < or C-c C-r shifts the region 4 spaces to the left

If you need to shift code by two levels of indention, or some arbitary amount you can prefix the command with an argument:

C-u 8 C-c > shifts the region 8 spaces to the right

C-u 8 C-c < shifts the region 8 spaces to the left

Another alternative is to use M-x indent-rigidly which is bound to C-x TAB:

C-u 8 C-x TAB shifts the region 8 spaces to the right

C-u -8 C-x TAB shifts the region 8 spaces to the left

Also useful are the rectangle commands that operate on rectangles of text instead of lines of text.

For example, after marking a rectangular region,

C-x r o inserts blank space to fill the rectangular region (effectively shifting code to the right)

C-x r k kills the rectangular region (effectively shifting code to the left)

C-x r t prompts for a string to replace the rectangle with. Entering C-u 8 <space> will then enter 8 spaces.

PS. With Ubuntu, to make python-mode the default mode for all .py files, simply install the python-mode package.

Solution 2

In addition to indent-region, which is mapped to C-M-\ by default, the rectangle edit commands are very useful for Python. Mark a region as normal, then:

  • C-x r t (string-rectangle): will prompt you for characters you'd like to insert into each line; great for inserting a certain number of spaces
  • C-x r k (kill-rectangle): remove a rectangle region; great for removing indentation

You can also C-x r y (yank-rectangle), but that's only rarely useful.

Solution 3

indent-region mapped to C-M-\ should do the trick.

Solution 4

I'm an Emacs newb, so this answer it probably bordering on useless.

None of the answers mentioned so far cover re-indentation of literals like dict or list. E.g. M-x indent-region or M-x python-indent-shift-right and company aren't going to help if you've cut-and-pasted the following literal and need it to be re-indented sensibly:

    foo = {
  'bar' : [
     1,
    2,
        3 ],
      'baz' : {
     'asdf' : {
        'banana' : 1,
        'apple' : 2 } } }

It feels like M-x indent-region should do something sensibly in python-mode, but that's not (yet) the case.

For the specific case where your literals are bracketed, using TAB on the lines in question gets what you want (because whitespace doesn't play a role).

So what I've been doing in such cases is quickly recording a keyboard macro like <f3> C-n TAB <f4> as in F3, Ctrl-n (or down arrow), TAB, F4, and then using F4 repeatedly to apply the macro can save a couple of keystrokes. Or you can do C-u 10 C-x e to apply it 10 times.

(I know it doesn't sound like much, but try re-indenting 100 lines of garbage literal without missing down-arrow, and then having to go up 5 lines and repeat things ;) ).

Solution 5

I use the following snippet. On tab when the selection is inactive, it indents the current line (as it normally does); when the selection is inactive, it indents the whole region to the right.

(defun my-python-tab-command (&optional _)
  "If the region is active, shift to the right; otherwise, indent current line."
  (interactive)
  (if (not (region-active-p))
      (indent-for-tab-command)
    (let ((lo (min (region-beginning) (region-end)))
          (hi (max (region-beginning) (region-end))))
      (goto-char lo)
      (beginning-of-line)
      (set-mark (point))
      (goto-char hi)
      (end-of-line)
      (python-indent-shift-right (mark) (point)))))
(define-key python-mode-map [remap indent-for-tab-command] 'my-python-tab-command)
Share:
45,848
Vernon
Author by

Vernon

Updated on September 01, 2020

Comments

  • Vernon
    Vernon over 3 years

    Working with Python in Emacs if I want to add a try/except to a block of code, I often find that I am having to indent the whole block, line by line. In Emacs, how do you indent the whole block at once.

    I am not an experienced Emacs user, but just find it is the best tool for working through ssh. I am using Emacs on the command line(Ubuntu), not as a gui, if that makes any difference.

  • Vernon
    Vernon about 14 years
    Thanks that works perfectly. with Emacs22 isn't python-mode automatically enabled with all .py files? Anyway, the C-c > works just fine.
  • unutbu
    unutbu about 14 years
    @Vernon: C-c > is defined in python-mode.el, so I think you must have installed the python-mode package somewhere along the way. Glad it works for you.
  • Daniel Stutzbach
    Daniel Stutzbach about 14 years
    Since whitespace is part of the syntax in Python, indent-region on the whole file is a bad idea.
  • codeasone
    codeasone over 13 years
    C-c > works fine in Emacs 23.2 without installing python-mode as it works with the provided python.el
  • unutbu
    unutbu over 13 years
    @landstatic: Thanks for the information. That makes me think perhaps all the commands listed above work the same for python-mode.el or python.el?
  • rkachach
    rkachach over 8 years
    Just to add that the C-c > and C-c > are also bind to C-c C-l and C-C-c C-r (left and right). IMHO these are much easier to type. Please, could you update the answer the reflect this? (thanks)
  • unutbu
    unutbu over 8 years
    @redobot: C-c C-l and C-c C-r must be custom bindings you've set up yourself. If you run emacs -q (to run emacs without loading an init file) you'll see there is no binding for C-c C-l or C-c C-r in Python mode.
  • rkachach
    rkachach over 8 years
    No, probably hey are only available in the latest version of the mode. If you take a look to the file github.com/emacsmirror/python-mode/blob/master/python-mode.e‌​l you can find them (just look for py-shift-left and py-shift-right)
  • Sam Clearman
    Sam Clearman over 8 years
    This is terrible advice. Python indentation cannot be inferred (since it is syntax!) so ident-region is useless.
  • stanri
    stanri over 7 years
    As an aside, emacs is my editor of choice for python code purely because of python-mode. I've never encountered a indent syntax error using it.
  • alper
    alper over 3 years
    Can I do C-c < and < followed by < to continue indention? @unutbu