Объемный отступ Emacs для Python


132

Работая с Python в Emacs, если я хочу добавить try / except к блоку кода, я часто обнаруживаю, что мне приходится делать отступ для всего блока построчно. Как в Emacs сделать отступ сразу для всего блока?

Я не опытный пользователь Emacs, но считаю, что это лучший инструмент для работы через ssh. Я использую Emacs в командной строке (Ubuntu), а не как графический интерфейс, если это имеет значение.


5
C-c >правильно. C-c <слева
Thamme Gowda

Ответы:


213

Если вы программируете Python с помощью Emacs, вам, вероятно, следует использовать режим python. В режиме python после разметки блока кода

C-c >или C-c C-l сдвигает область на 4 пробела вправо

C-c <или C-c C-r сдвигает область на 4 пробела влево

Если вам нужно сдвинуть код на два уровня отступа или на произвольную величину, вы можете префикс команды с аргументом:

C-u 8 C-c > сдвигает область на 8 делений вправо

C-u 8 C-c < сдвигает область на 8 делений влево

Другой альтернативой является использование, M-x indent-rigidlyкоторое связано с C-x TAB:

C-u 8 C-x TAB сдвигает область на 8 делений вправо

C-u -8 C-x TAB сдвигает область на 8 делений влево

Также полезны команды прямоугольника, которые работают с прямоугольниками текста вместо строк текста.

Например, отметив прямоугольную область,

C-x r o вставляет пустое пространство для заполнения прямоугольной области (эффективно сдвигая код вправо)

C-x r k убивает прямоугольную область (эффективно сдвигая код влево)

C-x r tзапрашивает строку, которой нужно заменить прямоугольник. При C-u 8 <space>вводе будет введено 8 пробелов.

PS. В Ubuntu, чтобы сделать режим Python режимом по умолчанию для всех файлов .py, просто установите python-modeпакет.


Спасибо, что отлично работает. с Emacs22 не включается ли автоматически режим python для всех файлов .py? В любом случае, Cc> работает нормально.
Вернон

@Vernon: C-c >определен в python-mode.el, поэтому я думаю, вы должны были установить python-modeпакет где-то по пути. Рад, что это работает для вас.
unutbu 06

1
Cc> отлично работает в Emacs 23.2 без установки режима python, так как он работает с предоставленным python.el
codeasone

@landstatic: Спасибо за информацию. Это заставляет меня думать, что, возможно, все перечисленные выше команды работают одинаково для python-mode.el или python.el?
unutbu

2
@redobot: C-c C-lи это C-c C-rдолжны быть пользовательские привязки, которые вы установили самостоятельно. Если вы запустите emacs -q(чтобы запустить emacs без загрузки файла инициализации), вы увидите, что нет привязки для режима Python C-c C-lили C-c C-rв нем.
Унтбу

9

В дополнение к indent-region, которое отображается C-M-\по умолчанию, команды редактирования прямоугольника очень полезны для Python. Отметьте регион как нормальный, затем:

  • C-x r t( string-rectangle): запросит символы, которые вы хотите вставить в каждую строку; отлично подходит для вставки определенного количества пробелов
  • C-x r k( kill-rectangle): удалить область прямоугольника; отлично подходит для удаления вмятин

Вы также можете C-x r y( yank-rectangle), но это редко бывает полезно.


4

indent-regionmapped to C-M-\должен помочь.


3
Это ужасный совет. Отступ Python не может быть выведен (так как это синтаксис!), Поэтому идентификатор-регион бесполезен.
Sam Clearman 05

1

Я использовал эту функцию для обработки отступов и отмены отступов:

(defun unindent-dwim (&optional count-arg)
  "Keeps relative spacing in the region.  Unindents to the next multiple of the current tab-width"
  (interactive)
  (let ((deactivate-mark nil)
        (beg (or (and mark-active (region-beginning)) (line-beginning-position)))
        (end (or (and mark-active (region-end)) (line-end-position)))
        (min-indentation)
        (count (or count-arg 1)))
    (save-excursion
      (goto-char beg)
      (while (< (point) end)
        (add-to-list 'min-indentation (current-indentation))
        (forward-line)))
    (if (< 0 count)
        (if (not (< 0 (apply 'min min-indentation)))
            (error "Can't indent any more.  Try `indent-rigidly` with a negative arg.")))
    (if (> 0 count)
        (indent-rigidly beg end (* (- 0 tab-width) count))
      (let (
            (indent-amount
             (apply 'min (mapcar (lambda (x) (- 0 (mod x tab-width))) min-indentation))))
        (indent-rigidly beg end (or
                                 (and (< indent-amount 0) indent-amount)
                                 (* (or count 1) (- 0 tab-width))))))))

А потом назначаю это сочетанию клавиш:

(global-set-key (kbd "s-[") 'unindent-dwim)
(global-set-key (kbd "s-]") (lambda () (interactive) (unindent-dwim -1)))

1

Я новичок в Emacs, поэтому этот ответ, вероятно, бесполезен.

Ни один из ответов, упомянутых до сих пор, не касается повторного отступа литералов, таких как dictили list. Например, M-x indent-regionor M-x python-indent-shift-rightand company не помогут, если вы вырезали и вставили следующий литерал и нуждаетесь в разумном изменении отступа:

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

Кажется, что M-x indent-regionнужно делать что-то разумное python-mode, но это (пока) не так.

В конкретном случае, когда ваши литералы заключены в квадратные скобки, использование TAB в соответствующих строках дает то, что вы хотите (потому что пробелы не играют роли).

Поэтому в таких случаях я быстро записывал макрос клавиатуры, например, <f3> C-n TAB <f4>F3, Ctrl-n (или стрелка вниз), TAB, F4, а затем многократное использование F4 для применения макроса может сэкономить пару нажатий клавиш. Или можно вообще C-u 10 C-x eнанести 10 раз.

(Я знаю, что это звучит не так уж и много, но попробуйте изменить отступ на 100 строк буквального мусора, не пропуская стрелку вниз, а затем нужно подняться на 5 строк и повторить что-то;)).


1

Я использую следующий фрагмент. На вкладке, когда выделение неактивно, текущая строка отступает (как обычно); когда выделение неактивно, вся область сдвигается вправо.

(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)

1

Делайте отступы в интерактивном режиме.

  1. Выберите область для отступа.
  2. Сх TAB.
  3. Используйте стрелки ( <-и ->) для интерактивного отступа.
  4. Нажмите Escтри раза, когда закончите с необходимым отступом.

Скопировано из моего сообщения в: Отступ на несколько строк в Emacs


-2

Я делаю что-то подобное повсеместно

;; intent whole buffer 
(defun iwb ()
  "indent whole buffer"
  (interactive)
  ;;(delete-trailing-whitespace)
  (indent-region (point-min) (point-max) nil)
  (untabify (point-min) (point-max)))

2
Поскольку пробелы являются частью синтаксиса Python, область с отступом во всем файле - плохая идея.
Даниэль Штутцбах
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.