Recuo em massa do Emacs para Python

132

Trabalhando com Python no Emacs, se eu quiser adicionar uma tentativa / exceto a um bloco de código, geralmente acho que estou tendo que recuar todo o bloco, linha por linha. No Emacs, como você recua todo o bloco de uma só vez.

Não sou um usuário experiente do Emacs, mas acho que é a melhor ferramenta para trabalhar com o ssh. Estou usando o Emacs na linha de comando (Ubuntu), não como uma GUI, se isso faz alguma diferença.

Vernon
fonte
5
C-c >por certo. C-c <para a esquerda
Thamme Gowda

Respostas:

213

Se você estiver programando Python usando o Emacs, provavelmente deverá usar o modo python. Com o modo python, depois de marcar o bloco de código,

C-c >ou C-c C-l desloca a região 4 espaços para a direita

C-c <ou C-c C-r desloca a região 4 espaços para a esquerda

Se você precisar alterar o código em dois níveis de indentação ou em alguma quantia arbitrária, poderá prefixar o comando com um argumento:

C-u 8 C-c > desloca a região 8 espaços para a direita

C-u 8 C-c < desloca a região 8 espaços para a esquerda

Outra alternativa é usar o M-x indent-rigidlyque está vinculado a C-x TAB:

C-u 8 C-x TAB desloca a região 8 espaços para a direita

C-u -8 C-x TAB desloca a região 8 espaços para a esquerda

Também são úteis os comandos de retângulo que operam em retângulos de texto em vez de linhas de texto.

Por exemplo, depois de marcar uma região retangular,

C-x r o insere espaço em branco para preencher a região retangular (deslocando efetivamente o código para a direita)

C-x r k mata a região retangular (deslocando efetivamente o código para a esquerda)

C-x r tsolicita uma sequência para substituir o retângulo. Entrar C-u 8 <space>entrará em 8 espaços.

PS. Com o Ubuntu, para tornar o modo python o modo padrão para todos os arquivos .py, basta instalar o python-modepacote.

unutbu
fonte
Obrigado que funciona perfeitamente. com o Emacs22 o modo python não é ativado automaticamente com todos os arquivos .py? De qualquer forma, o Cc> funciona muito bem.
Vernon
@ Vernon: C-c >é definido em python-mode.el, então acho que você deve ter instalado o python-modepacote em algum lugar ao longo do caminho. Que bom que funciona para você.
Unutbu 06/04/10
1
Cc> funciona bem no Emacs 23.2 sem instalar-mode python como ele funciona com o python.el fornecido
codeasone
@landstatic: Obrigado pela informação. Isso me faz pensar que talvez todos os comandos listados acima funcionem da mesma forma para python-mode.el ou python.el?
unutbu 27/09/10
2
@redobot: C-c C-le C-c C-rdeve ser uma ligação personalizada que você mesmo configurou. Se você executar emacs -q(para executar o emacs sem carregar um arquivo init), verá que não há ligação para C-c C-lou C-c C-rno modo Python.
unutbu
9

Além de indent-region, que é mapeado C-M-\por padrão, os comandos de edição de retângulo são muito úteis para Python. Marque uma região como normal e, em seguida:

  • C-x r t( string-rectangle): solicita os caracteres que você deseja inserir em cada linha; ótimo para inserir um certo número de espaços
  • C-x r k( kill-rectangle): remova uma região retangular; ótimo para remover recuo

Você também pode C-x r y( yank-rectangle), mas isso raramente é útil.

Daniel Stutzbach
fonte
4

indent-regionmapeado para C-M-\deve fazer o truque.

Łukasz
fonte
3
Este é um conselho terrível. A indentação do Python não pode ser inferida (uma vez que é sintaxe!), Portanto, a região ident é inútil.
precisa saber é o seguinte
1

Eu tenho usado essa função para lidar com meu recuo e recuo:

(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 então atribuí-lo a um atalho de teclado:

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

Eu sou um novato do Emacs, então essa resposta provavelmente está próxima de inútil.

Nenhuma das respostas mencionadas até agora abrange a re-indentação de literais como dictou list. Por exemplo, M-x indent-regionou M-x python-indent-shift-righte empresa não ajudarão se você recortou e colou o seguinte literal e precisa que ele seja recuado de forma sensata:

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

Parece que M-x indent-regiondevemos fazer algo sensatamente python-mode, mas esse ainda não é o caso.

No caso específico em que seus literais estão entre colchetes, o uso de TAB nas linhas em questão obtém o que você deseja (porque o espaço em branco não desempenha um papel).

Então, o que eu venho fazendo, nesses casos, está rapidamente a gravação de uma macro de teclado como <f3> C-n TAB <f4>como na F3, Ctrl-n (ou seta para baixo), TAB, F4 e, em seguida, usando F4 várias vezes para aplicar a macro pode salvar um par de teclas. Ou você pode fazer C-u 10 C-x epara aplicá-lo 10 vezes.

(Eu sei que não parece muito, mas tente reentrar 100 linhas de literal de lixo sem perder a seta para baixo e depois precisar subir 5 linhas e repetir as coisas;)).

Roubar
fonte
1

Eu uso o seguinte trecho. Na guia quando a seleção está inativa, recua a linha atual (como normalmente faz); quando a seleção está inativa, recua toda a região para a direita.

(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
fonte
1

Faça o recuo interativamente.

  1. Selecione a região a ser recuada.
  2. Cx TAB.
  3. Use as setas ( <-e ->) para recuar interativamente.
  4. Pressione Esctrês vezes quando terminar com o recuo necessário.

Copiado da minha postagem em: Recuar várias linhas no Emacs

vineeshvs
fonte
-2

Eu faço algo assim 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)))
hpavc
fonte
2
Como o espaço em branco faz parte da sintaxe do Python, a região de indentação em todo o arquivo é uma má ideia.
Daniel Stutzbach 06/04