2010-04-06 4 views
109

Lavorando con Python in Emacs se voglio aggiungere un try/tranne per un blocco di codice, trovo spesso che sto facendo rientrare l'intero blocco, riga per riga. In Emacs, come si fa a indentare l'intero blocco in una sola volta.Emacs bulk indent per Python

Non sono un utente esperto di Emacs, ma trovo che sia lo strumento migliore per lavorare con ssh. Sto usando Emacs sulla riga di comando (Ubuntu), non come gui, se questo fa alcuna differenza.

+3

'C-c>' per diritto. 'C-c <' per sinistra –

risposta

169

Se stai programmando Python usando Emacs, probabilmente dovresti usare Python-mode. Con python-mode, dopo aver segnato il blocco di codice,

C-c > o C-c C-l sposta la regione 4 spazi a destra

C-c < o C-c C-r Sposta la regione 4 spazi a sinistra

Se è necessario spostare il codice da due livelli di rientro, o di una certa quantità arbitraria si può precedere il comando con un argomento:

C-u 8 C-c > sposta la regione 8 spazi a destra

C-u 8 C-c < Sposta la regione 8 spazi a sinistra

Un'altra alternativa è quella di utilizzare M-x indent-rigidly che è destinato a C-x TAB:

C-u 8 C-x TAB Sposta la regione 8 spazi a destra

C-u -8 C-x TAB Sposta la regione 8 spazi a sinistra

Sono anche utili gli rectangle commands che operano su rettangoli di testo anziché su righe di testo.

Ad esempio, dopo aver segnato una regione rettangolare,

C-x r o inserti spazio vuoto per riempire la regione rettangolare (spostamento efficacemente codice a destra)

C-x r k uccide la regione rettangolare (spostamento efficacemente codice a fianco

C-x r t richiede una stringa per sostituire il rettangolo con. Immettendo C-u 8 <space> si inseriranno quindi 8 spazi.

PS. Con Ubuntu, per rendere Python-mode la modalità predefinita per tutti i file .py, basta installare il pacchetto python-mode.

+0

Sono un grande fan dei comandi del rettangolo! –

+0

Grazie che funziona perfettamente. con Emacs22 la modalità Python non è abilitata automaticamente con tutti i file .py? Ad ogni modo, C-c> funziona bene. – Vernon

+0

@Vernon: 'C-c>' è definito in python-mode.el, quindi penso che tu abbia installato il pacchetto 'python-mode' da qualche parte lungo la strada. Felice che funzioni per te. – unutbu

4

indent-region mappato a C-M-\ dovrebbe fare il trucco.

+0

Questo è un consiglio terribile. Il rientro di Python non può essere dedotto (poiché è la sintassi!), Quindi l'ident-region è inutile. –

8

Oltre a indent-region, che è mappato su C-M-\ per impostazione predefinita, i comandi di modifica del rettangolo sono molto utili per Python. Tracciare una regione normale, quindi:

  • C-x r t (string-rectangle): vi verrà chiesto per i caratteri che desideri inserire in ogni riga; ottimo per inserire un certo numero di spazi
  • C-x r k (kill-rectangle): rimuovere una regione di rettangolo; ottimo per rimuovere il rientro

È inoltre possibile C-x r y (yank-rectangle), ma è solo raramente utile.

-2

faccio qualcosa di simile universalmente

;; 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

Poiché lo spazio bianco fa parte della sintassi in Python, la rientranza sull'intero file è una cattiva idea. –

1

ho usato questa funzione per gestire il mio rientro e rimozione dell'indentazione:

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

E poi assegnarlo ad una scorciatoia da tastiera:

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

Sono un newb Emacs, quindi questa risposta probabilmente confinante inutile.

Nessuna delle risposte citate finora copre rientranze di valori letterali come dict o list. Per esempio. M-x indent-region o M-x python-indent-shift-right e società non stanno andando ad aiutare se hai tagliato e incollato il seguente letterale e ha bisogno di essere ri-rientrato sensibilmente:

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

Ci si sente come M-x indent-region dovrebbe fare qualcosa di sensato in python-mode , ma non è (ancora) il caso.

Per il caso specifico in cui i valori letterali sono tra parentesi, utilizzando TAB sulle linee in questione ottiene ciò che si desidera (perché gli spazi non svolgono alcun ruolo).

Quindi quello che ho fatto in questi casi sta rapidamente la registrazione di un keyboard macro come <f3> C-n TAB <f4> come in F3, Ctrl-n (o freccia giù), TAB, F4, F4 e quindi utilizzando più volte per applicare la macro può risparmiare un un paio di sequenze di tasti. Oppure puoi fare C-u 10 C-x e per applicarlo 10 volte.

(So che non suona molto, ma prova a ri-indentare 100 righe di letterale spazzatura senza perdere la freccia in giù, e poi dover risalire 5 righe e ripetere le cose;)).

1

Io uso il seguente frammento. Nella scheda quando la selezione è inattiva, fa rientrare la riga corrente (come avviene normalmente); quando la selezione è inattiva, fa rientrare l'intera area a destra.

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