Emacs Bulk-Einzug für Python

132

Wenn ich mit Python in Emacs arbeite, wenn ich einem Codeblock einen Versuch / außer hinzufügen möchte, stelle ich häufig fest, dass ich den gesamten Block Zeile für Zeile einrücken muss. Wie rücken Sie in Emacs den gesamten Block auf einmal ein?

Ich bin kein erfahrener Emacs-Benutzer, finde aber, dass es das beste Werkzeug für die Bearbeitung von ssh ist. Ich benutze Emacs in der Kommandozeile (Ubuntu), nicht als GUI, wenn das einen Unterschied macht.

Vernon
quelle
5
C-c >für richtig. C-c <für links
Thamme Gowda

Antworten:

213

Wenn Sie Python mit Emacs programmieren, sollten Sie wahrscheinlich den Python-Modus verwenden. Im Python-Modus wird nach dem Markieren des Codeblocks

C-c >oder C-c C-l verschiebt den Bereich um 4 Felder nach rechts

C-c <oder C-c C-r verschiebt den Bereich um 4 Felder nach links

Wenn Sie den Code um zwei Einrückungsstufen oder einen beliebigen Betrag verschieben müssen, können Sie dem Befehl ein Argument voranstellen:

C-u 8 C-c > verschiebt die Region um 8 Felder nach rechts

C-u 8 C-c < verschiebt den Bereich um 8 Felder nach links

Eine andere Alternative ist die Verwendung, M-x indent-rigidlydie gebunden ist an C-x TAB:

C-u 8 C-x TAB verschiebt die Region um 8 Felder nach rechts

C-u -8 C-x TAB verschiebt den Bereich um 8 Felder nach links

Ebenfalls nützlich sind die Rechteckbefehle , die Textrechtecke anstelle von Textzeilen bearbeiten.

Zum Beispiel nach dem Markieren eines rechteckigen Bereichs,

C-x r o Fügt eine Leerstelle ein, um den rechteckigen Bereich zu füllen (Code wird effektiv nach rechts verschoben).

C-x r k tötet den rechteckigen Bereich (verschiebt den Code effektiv nach links)

C-x r tfordert zur Eingabe einer Zeichenfolge auf, durch die das Rechteck ersetzt werden soll. Bei der Eingabe C-u 8 <space>werden dann 8 Leerzeichen eingegeben.

PS. Um mit Ubuntu den Python-Modus zum Standardmodus für alle .py-Dateien zu machen, installieren Sie einfach das python-modePaket.

unutbu
quelle
Danke, das funktioniert perfekt. mit Emacs22 wird der Python-Modus nicht automatisch für alle .py-Dateien aktiviert? Wie auch immer, das Cc> funktioniert einwandfrei.
Vernon
@Vernon: C-c >ist in python-mode.el definiert, daher denke ich, dass Sie das python-modePaket irgendwo auf dem Weg installiert haben müssen . Ich bin froh, dass es für dich funktioniert.
Unutbu
1
Cc> funktioniert gut in Emacs 23.2 ohne Installation des Python-Modus, da es mit der bereitgestellten python.el
Codeasone
@landstatic: Danke für die Information. Das lässt mich denken, dass vielleicht alle oben aufgeführten Befehle für python-mode.el oder python.el gleich funktionieren?
Unutbu
2
@redobot: C-c C-lund C-c C-rmüssen benutzerdefinierte Bindungen sein, die Sie selbst eingerichtet haben. Wenn Sie ausführen emacs -q(um Emacs auszuführen, ohne eine Init-Datei zu laden), sehen Sie, dass für C-c C-loder C-c C-rim Python-Modus keine Bindung besteht .
Unutbu
9

Zusätzlich indent-region, die C-M-\standardmäßig zugeordnet sind, sind die Rechteckbearbeitungsbefehle für Python sehr nützlich. Markieren Sie eine Region als normal und dann:

  • C-x r t( string-rectangle): fordert Sie zur Eingabe von Zeichen auf, die Sie in jede Zeile einfügen möchten; ideal zum Einfügen einer bestimmten Anzahl von Leerzeichen
  • C-x r k( kill-rectangle): Entfernen Sie einen Rechteckbereich. ideal zum Entfernen von Einkerbungen

Sie können auch C-x r y( yank-rectangle), aber das ist nur selten nützlich.

Daniel Stutzbach
quelle
4

indent-regionzugeordnet zu C-M-\sollte sollte den Trick tun.

Łukasz
quelle
3
Das ist ein schrecklicher Rat. Python-Einrückungen können nicht abgeleitet werden (da es sich um Syntax handelt!), Daher ist ident-region nutzlos.
Sam Clearman
1

Ich habe diese Funktion verwendet, um das Ein- und Einrücken zu behandeln:

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

Und dann ordne ich es einer Tastenkombination zu:

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

Ich bin ein Emacs-Neuling, daher grenzt diese Antwort wahrscheinlich an nutzlos.

Keine der bisher genannten Antworten bezieht sich auf das erneute Einrücken von Literalen wie dictoder list. ZB M-x indent-regionoder M-x python-indent-shift-rightund Unternehmen helfen nicht weiter, wenn Sie das folgende Literal ausgeschnitten und eingefügt haben und es sinnvoll neu eingerückt werden müssen:

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

Es fühlt sich an, als M-x indent-regionsollte man etwas Vernünftiges tun python-mode, aber das ist (noch) nicht der Fall.

Für den speziellen Fall, in dem Ihre Literale in Klammern stehen, wird durch die Verwendung von TAB in den betreffenden Zeilen das erreicht, was Sie möchten (da Leerzeichen keine Rolle spielen).

In solchen Fällen habe ich also schnell ein Tastaturmakro wie <f3> C-n TAB <f4>F3, Strg-n (oder Abwärtspfeil), TAB, F4 aufgenommen und dann F4 wiederholt zum Anwenden des Makros verwendet, um einige Tastenanschläge zu sparen. Oder Sie können C-u 10 C-x ees 10 Mal anwenden.

(Ich weiß, dass es nicht nach viel klingt, aber versuchen Sie, 100 Zeilen Müllliteral erneut einzurücken, ohne den Abwärtspfeil zu verpassen, und dann 5 Zeilen nach oben zu gehen und Dinge zu wiederholen;)).

rauben
quelle
1

Ich benutze das folgende Snippet. Wenn die Auswahl auf der Registerkarte inaktiv ist, wird die aktuelle Zeile eingerückt (wie normalerweise). Wenn die Auswahl inaktiv ist, wird die gesamte Region nach rechts eingerückt.

(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)
mookid
quelle
1

Machen Sie die Einrückung interaktiv.

  1. Wählen Sie die Region aus, die eingerückt werden soll.
  2. Cx TAB.
  3. Verwenden Sie die Pfeile ( <-und ->), um interaktiv einzurücken.
  4. Drücken Sie Escdreimal, wenn Sie mit der gewünschten Einrückung fertig sind.

Von meinem Beitrag in kopiert : Mehrere Zeilen in Emacs einrücken

Vineeshvs
quelle
-2

Ich mache so etwas universell

;; intent whole buffer 
(defun iwb ()
  "indent whole buffer"
  (interactive)
  ;;(delete-trailing-whitespace)
  (indent-region (point-min) (point-max) nil)
  (untabify (point-min) (point-max)))
hpavc
quelle
2
Da Leerzeichen Teil der Syntax in Python sind, ist die Einrückungsregion für die gesamte Datei eine schlechte Idee.
Daniel Stutzbach