Как сделать отступ кода в Emacs в режиме python?

Я запускаю Emacs с python-mode.el для кодирования на Python. Я надеюсь узнать, как сделать область кода с хорошим отступом автоматически.

Следующий код не имеет отступа.

while match != None:

        if match.group(1):
            titles.append(match.group(1))

        if match.group(2):
            if match.group(2) != '':
                pns.append(int(match.group(2)))
            else:
                pns.append('')
        else:
            pns.append('')

        if match.group(3):
            closings.append(len(''.join(match.group(3).split())))
        else:
            closings.append(0)

    match = pat.search(match.group(4))

Если я выберу регион и нажму M-x indent-region, это станет совершенно неправильным:

while match != None:

    if match.group(1):
        titles.append(match.group(1))

        if match.group(2):
            if match.group(2) != '':
                pns.append(int(match.group(2)))
            else:
                pns.append('')
        else:
            pns.append('')

            if match.group(3):
                closings.append(len(''.join(match.group(3).split())))
            else:
                closings.append(0)

                match = pat.search(match.group(4))

Идеал должен быть:

while match != None:

    if match.group(1):
        titles.append(match.group(1))

    if match.group(2):
        if match.group(2) != '':
            pns.append(int(match.group(2)))
        else:
            pns.append('')
    else:
        pns.append('')

    if match.group(3):
        closings.append(len(''.join(match.group(3).split())))
    else:
        closings.append(0)

    match = pat.search(match.group(4))
  1. Почему M-x indent-region неправильно понимает отношение отступов между строками кода? Это потому, что мой код неоднозначен?
  2. Что мне делать тогда?

Спасибо.


person Tim    schedule 13.09.2014    source источник


Ответы (2)


Проблема в том, что emacs не знает, где должен заканчиваться блок if. И ваш желаемый код, и код, создаваемый областью отступа, являются допустимыми для python. В C-подобных языках это не проблема из-за фигурных скобок, определяющих длину блоков. Для python, поскольку emacs не может знать наверняка, он предполагает, что каждая строка кода все еще является частью предыдущего блока.

Возможно, вы захотите взглянуть на python-indent-left (привязанный к «C-c ‹») и python-indent-right («C-c >»). Чтобы исправить ваш пример, вы бы выделили все, кроме первой строки, и запустили python-indent-left.

person Jamie Nicol    schedule 13.09.2014

Как уже говорилось, в Python вы не можете надежно автоматически устанавливать отступы для больших разделов.

Тем не менее, есть способ ускорить выполнение этого построчно. Это используется здесь:

(defun indent-and-forward ()
  "Indent current line and go forward one line. "
  (interactive "*")
  (if (empty-line-p)
      (fixup-whitespace)
      (indent-according-to-mode))
  (if (eobp)
      (newline-and-indent)
    (forward-line 1))
  (back-to-indentation))

Кстати, он должен работать и с другими режимами, а не только с Python. Ключи здесь

(global-set-key [(super i)] 'indent-and-forward)

Нажав эти клавиши, вы можете перемещаться по большим участкам - просто следите за тем, чтобы он все еще делал то, что вы хотите. Если нет - используйте клавишу TAB только для этой строки и переходите к следующей.

person Andreas Röhler    schedule 13.09.2014