2010-04-06 5 views
109

Trabajando con Python en Emacs si quiero agregar un try/except a un bloque de código, a menudo me parece que tengo que aplicar sangría al bloque completo, línea por línea. En Emacs, ¿cómo sangra todo el bloque de una vez?Incrustación masiva de Emacs para Python

No soy un usuario experimentado de Emacs, pero solo encuentro que es la mejor herramienta para trabajar a través de ssh. Estoy usando Emacs en la línea de comandos (Ubuntu), no como una GUI, si eso hace alguna diferencia.

+3

'C-c>' para la derecha. 'C-c <' para la izquierda –

Respuesta

169

Si está programando Python usando Emacs, entonces probablemente debería estar usando el modo python. Con pitón modo, después de marcar el bloque de código,

C-c > o C-c C-l desplaza la región de 4 espacios a la derecha

C-c < o C-c C-r desplaza la región 4 espacios a la izquierda

Si necesita cambiar el código de dos niveles de sangría, o una cierta cantidad arbitraria se puede anteponer el comando con un argumento:

C-u 8 C-c > turnos de la región 8 espacios a la derecha

C-u 8 C-c < turnos de la región 8 espacios a la izquierda

Otra alternativa es utilizar M-x indent-rigidly que está unido a C-x TAB:

C-u 8 C-x TAB turnos de la región 8 espacios a la derecha

C-u -8 C-x TAB turnos de la región 8 espacios a la izquierda

También son útiles los rectangle commands que operan en rectángulos de texto en lugar de líneas de texto.

Por ejemplo, después de marcar una región rectangular,

C-x r o insertos espacio en blanco para llenar la región rectangular (cambiando efectivamente código a la derecha)

C-x r k mata la región rectangular (cambiando efectivamente código a la izquierda)

C-x r t solicita una cadena para reemplazar el rectángulo. Ingresando C-u 8 <space> entrará a 8 espacios.

PS. Con Ubuntu, para hacer que python-mode sea el modo predeterminado para todos los archivos .py, simplemente instale el paquete python-mode.

+0

¡Soy un gran admirador de los comandos rectangulares! –

+0

Gracias que funciona a la perfección. con Emacs22 no se habilita automáticamente el modo python con todos los archivos .py? De todos modos, el C-c> funciona bien. – Vernon

+0

@Vernon: 'C-c>' se define en modo python.el, así que creo que debes haber instalado el paquete 'python-mode' en algún punto del camino. Me alegra que funcione para ti. – unutbu

4

indent-region mapeado a C-M-\ debería hacer el truco.

+0

Este es un consejo terrible. La indentación de Python no se puede inferir (¡ya que es una sintaxis!), Por lo que ident-region es inútil. –

8

Además de indent-region, que se asigna a C-M-\ de forma predeterminada, los comandos de edición de rectángulo son muy útiles para Python. Marcar una región como normal, entonces:

  • C-x r t (string-rectangle): Se le pedirá caracteres que desea insertar en cada línea; ideal para insertar un cierto número de espacios
  • C-x r k (kill-rectangle): eliminar una región rectangular; ideal para eliminar la indentación

También puede C-x r y (yank-rectangle), pero eso rara vez es útil.

-2

que hacer algo como esto 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

Dado que el espacio en blanco es parte de la sintaxis en Python, indent-region en todo el archivo es una mala idea. –

1

He estado usando esta función para manejar mi sangría y su ausencia lo:

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

Y luego asignarle una combinación de teclas:

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

Soy un newb de Emacs, por lo que esta respuesta probablemente bordea lo inútil.

Ninguna de las respuestas mencionadas hasta ahora cubre la redención de literales como dict o list. P.ej. M-x indent-region o M-x python-indent-shift-right y compañía no se va a ayudar si se ha de cortar y pegar el siguiente literal y lo necesita ser re-sangría con sensatez:

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

Se siente como M-x indent-region debería hacer algo con sensatez en python-mode , pero ese no es (todavía) el caso.

Para el caso específico donde sus literales están entre corchetes, usar TAB en las líneas en cuestión obtiene lo que desea (porque el espacio en blanco no desempeña ningún papel).

Así que lo que he estado haciendo en estos casos es rápidamente la grabación de un keyboard macro como <f3> C-n TAB <f4> como en F3, Ctrl-N (o flecha hacia abajo), TAB, F4, y luego usando F4 varias veces para aplicar la macro puede ahorrar un par de teclas. O puede hacer C-u 10 C-x e para aplicarlo 10 veces.

(Sé que no parece mucho, pero intenta volver a indentificar 100 líneas de basura literal sin perder la flecha hacia abajo, y luego tener que subir 5 líneas y repetir las cosas;)).

1

Uso el siguiente fragmento. En la pestaña cuando la selección está inactiva, sangra la línea actual (como normalmente lo hace); cuando la selección está inactiva, sangra toda la región a la derecha.

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