2016-06-02 7 views
3

Weil ichÄndern Python Einzug Menge in Emacs

(setq python-indent-offset 4) 

in meiner .emacs haben, wenn ich mit dem Code wie

def fn(): 
    foo = bar() 
    if bar1 == bar2: 
    if blah1 == blah2: 
     return yay 

und Mark-ganze-Puffer (Cx h) beginnen, gefolgt von indent-Region (CM- \), erwarte ich bin zu:

def fn(): 
    foo = bar() 
    if bar1 == bar2: 
     if blah1 == blah2: 
      return yay 

aber ich bekomme statt:

Noch Eindruck-Bereich funktioniert gut mit geschweiften Klammern-getrennte Sprachen. Gibt es einen Weg, um es mit einer Einrückung-basierten Sprache wie Python zu arbeiten?

Bitte beachten Sie:

  1. Ich bin aware von Reindent aber ich möchte in Emacs bleiben.
  2. Ich bin gut vertraut mit string-rectangle (C-x r t) and python-indent-shift-right/left (C-c >), aber weder diese noch ihre Varianten tun, was ich frage.
+1

Das Problem scheint zu sein, dass es in 'python-indent-region' eine Überprüfung gibt, ob die Zeile auf einem Blockstart steht. Wenn es sich um einen Blockstart handelt (wie in einer if-Anweisung), wird die Zeile übersprungen und die Einrückung nicht geändert. Sie sollten es als Fehler erhöhen. – Jules

Antwort

0

Alternativ können Sie das Python-Paket innerhalb von Emacs aufrufen und den Puffer ersetzen lassen.

(defun my-py-reindent() 
     "Reindent the current file with pypi's reindent." 
     (interactive) 
      (shell-command-to-string (format "reindent %s" (buffer-file-name))) 
      (revert-buffer t t t)) 

Ziemlich einfach! (doc used: http://wikemacs.org/wiki/Emacs_Lisp_Cheat_Sheet#File)

1

Ich bin mir nicht sicher, ob dies eine perfekte Lösung und als solche würde ich das nicht als Patch auf Emacs-devel schieben wollen, aber da das Problem in python-indent-region ist (ich eine Notiz für dieses als links Kommentar). Wir können versuchen, diese Funktion als solche neu zu definieren:

(defun python-indent-region (start end) 
    "Indent a Python region automagically. 

Called from a program, START and END specify the region to indent." 
    (let ((deactivate-mark nil)) 
    (save-excursion 
     (goto-char end) 
     (setq end (point-marker)) 
     (goto-char start) 
     (or (bolp) (forward-line 1)) 
     (while (< (point) end) 
     (or (and (bolp) (eolp)) 
      (when (and 
        ;; Skip if previous line is empty or a comment. 
        (save-excursion 
        (let ((line-is-comment-p 
          (python-info-current-line-comment-p))) 
         (forward-line -1) 
         (not 
         (or (and (python-info-current-line-comment-p) 
           ;; Unless this line is a comment too. 
           (not line-is-comment-p)) 
          (python-info-current-line-empty-p))))) 
        ;; Don't mess with strings, unless it's the 
        ;; enclosing set of quotes or a docstring. 
        (or (not (python-syntax-context 'string)) 
         (eq 
         (syntax-after 
         (+ (1- (point)) 
          (current-indentation) 
          (python-syntax-count-quotes (char-after) (point)))) 
         (string-to-syntax "|")) 
         (python-info-docstring-p))) 
       (python-indent-line))) 
     (forward-line 1)) 
     (move-marker end nil)))) 

Der Teil, den ich geändert wurde einfach das Kontroll entfernen, um zu sehen, wenn die Leitung ein Block ender war, DGeben oder Block-Start und läuft (python-indent-line) in all derer, Fälle.

Ich habe dies in diesem Beispiel und einige andere getestet und sie scheinen zu funktionieren. Wenn es nicht funktioniert, würde ich es gerne wissen!

+0

Hmm .. Nach Eval-Bereich, Emacs neu starten, und mit einer anderen (blutende) Version von Emacs, der Funktionsname Python-Einrückung-Region wird nicht nach M-x erkannt. Untersuchung. Ich habe auch versucht, diesen Namen zu ändern. – Calaf

+0

Es sollte nicht durch m-x sichtbar sein, sollte aber von C-M- \ aufgerufen werden, wenn Sie diesen Befehl verwenden – Jules