Об'ємний відступ Emacs для Python


132

Працюючи з Python в Emacs, якщо я хочу додати спробу / крім блоку коду, я часто виявляю, що мені доводиться відступати весь блок, рядок за рядком. У Emacs, як відступити весь блок одразу.

Я не досвідчений користувач Emacs, але просто вважаю, що це найкращий інструмент для роботи через ssh. Я використовую Emacs у командному рядку (Ubuntu), а не як gui, якщо це має значення.


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

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, не завантажуючи файл init), ви побачите, що в режимі Python немає прив'язки C-c C-lабо C-c C-rдля цього.
unutbu

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-regionкартографується, щоб C-M-\зробити трюк.


3
Це жахлива порада. Відступ Python не може бути зроблений (оскільки це синтаксис!), Тому ідентифікатор-область є марною.
Сем Клірман

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-regionчи M-x python-indent-shift-rightі компанія не збирається допомогти , якщо ви вирізати і вставити наступний буквальним і потрібно , щоб бути повторно відступом розсудливо:

    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.