PythonのEmacsバルクインデント


132

コードのブロックにtry / exceptを追加したい場合、EmacsでPythonを使用すると、ブロック全体を1行ずつインデントする必要があることがよくあります。Emacsでは、どのようにしてブロック全体を一度にインデントするのですか?

私は経験豊富なEmacsユーザーではありませんが、sshを使用するための最良のツールであることがわかります。EmacsをGUIとしてではなく、コマンドライン(Ubuntu)で使用しています。


5
C-c >正しいです。C-c <
Thamme Gowda

回答:


213

Emacsを使用してPythonをプログラミングしている場合は、おそらくpython-modeを使用しているはずです。python-modeでは、コードのブロックをマークした後、

C-c >またはC-c C-l 領域を右に4スペースシフトします

C-c <またはC-c C-r 領域を左に4スペースシフトします

コードを2レベルのインデントまたは任意の量だけシフトする必要がある場合は、コマンドの前に引数を付けることができます。

C-u 8 C-c > 領域を右に8スペースシフトします

C-u 8 C-c < 領域を左に8スペースシフトします

別の選択肢は、にM-x indent-rigidlyバインドされているを使用することですC-x TAB

C-u 8 C-x TAB 領域を右に8スペースシフトします

C-u -8 C-x TAB 領域を左に8スペースシフトします

テキストの行ではなくテキストの長方形を操作する長方形コマンドも役立ちます。

たとえば、長方形の領域をマークした後、

C-x r o 長方形の領域を埋めるために空白スペースを挿入します(コードを効果的に右にシフトします)

C-x r k 矩形領域を削除します(コードを効果的に左にシフトします)

C-x r t長方形を置き換える文字列の入力を求めます。入力すると、C-u 8 <space>それから8にスペースを入力します。

PS。Ubuntuでは、python-modeをすべての.pyファイルのデフォルトモードにするには、python-modeパッケージをインストールするだけです。


ありがとうございます。Emacs22では、すべての.pyファイルでpythonモードが自動的に有効になっていませんか?とにかく、Cc>は問題なく動作します。
バーノン

@Vernon:C-c >python-mode.elで定義されているのでpython-mode、途中でパッケージをインストールしている必要があります。それはあなたのために働くうれしいです。
unutbu

1
Cc>は、提供されているpython.elで動作するため、python-modeをインストールしなくてもEmacs 23.2で正常に動作します
codeasone

@landstatic:情報をありがとう。そのため、上記のコマンドはすべてpython-mode.elまたはpython.elで同じように機能すると思いますか?
unutbu

2
@redobot:自分で設定したカスタムバインディングC-c C-lであるC-c C-r必要があります。emacs -q(initファイルを読み込まずにemacsを実行するために)を実行すると、PythonモードにバインドされていC-c C-lないかC-c C-r、Pythonモードでバインドされていないことがわかります。
unutbu

9

デフォルトでindent-regionマッピングされるに加えて、C-M-\四角形編集コマンドはPythonで非常に役立ちます。リージョンを通常としてマークし、次に:

  • C-x r tstring-rectangle):各行に挿入する文字の入力を求めます。特定の数のスペースを挿入するのに最適
  • C-x r kkill-rectangle):長方形領域を削除します; インデントを取り除くのに最適

C-x r yyank-rectangle)を使用することもできますが、それが役立つことはほとんどありません。


4

indent-regionマッピングされC-M-\たトリックを行う必要があります。


3
これはひどいアドバイスです。Pythonのインデントは(構文であるため)推論できないため、ident-regionは役に立ちません。
Sam Clearman、2016年

1

私はこの関数を使用してインデントとインデント解除を処理しています:

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

そして、それをキーボードショートカットに割り当てます。

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

1

私はEmacsの初心者なので、この答えはおそらく役に立たないでしょう。

これまでに述べた回答のいずれも、dictまたはのようなリテラルのインデントをカバーしていませんlist。たとえば、次のリテラルをカットアンドペーストし、それを慎重に再インデントする必要があるM-x indent-region場合M-x python-indent-shift-right、orまたはand companyは役に立ちません。

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

M-x indent-region賢明に何かをすべきであるように感じますpython-modeが、それは(まだ)そうではありません。

リテラルが括弧で囲まれている特定のケースでは、問題の行でTABを使用すると必要な結果が得られます(空白は役割を果たさないため)。

したがって、そのような場合に私がしていることは、F3、Ctrl-n(または下矢印)、TAB、F4のようにキーボードマクロをすばやく記録し、<f3> C-n TAB <f4>F4を繰り返し使用してマクロを適用すると、いくつかのキーストロークを節約できます。またはC-u 10 C-x e、10回適用することもできます。

(私はそれがそれほど聞こえないことを知っていますが、下矢印を逃さずに100行のガベージリテラルを再度インデントしてみて、次に5行上に移動して物事を繰り返す必要があります;))。


1

次のスニペットを使用します。タブ上で選択が非アクティブの場合、現在の行を(通常どおりに)インデントします。選択範囲がアクティブでない場合は、領域全体が右にインデントされます。

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

1

インタラクティブにインデントします。

  1. インデントする領域を選択します。
  2. Cx TAB
  3. インタラクティブにインデントするには、矢印(<-および->)を使用します。
  4. Esc必要なインデントが完了したら、を3回押します。

私の投稿のコピー:Emacsで数行インデント


-2

私はこのようなことを普遍的に行います

;; 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
空白はPythonの構文の一部であるため、ファイル全体のインデント領域はお勧めできません。
Daniel Stutzbach、2010
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.