简体   繁体   English

用于Python的Emacs批量缩进

[英]Emacs bulk indent for Python

Working with Python in Emacs if I want to add a try/except to a block of code, I often find that I am having to indent the whole block, line by line. 在Emacs中使用Python,如果我想在一段代码中添加try / except,我经常发现我必须逐行缩进整个块。 In Emacs, how do you indent the whole block at once. 在Emacs中,你如何一次缩进整个块。

I am not an experienced Emacs user, but just find it is the best tool for working through ssh. 我不是一个经验丰富的Emacs用户,但只是发现它是通过ssh工作的最佳工具。 I am using Emacs on the command line(Ubuntu), not as a gui, if that makes any difference. 我在命令行(Ubuntu)上使用Emacs,而不是作为gui,如果这有任何区别。

If you are programming Python using Emacs, then you should probably be using python-mode. 如果您使用Emacs编写Python,那么您可能应该使用python-mode。 With python-mode, after marking the block of code, 使用python-mode,在标记代码块之后,

Cc > or Cc Cl shifts the region 4 spaces to the right Cc >Cc Cl将区域向右移动4个空格

Cc < or Cc Cr shifts the region 4 spaces to the left Cc <Cc Cr将区域向左移动4个空格

If you need to shift code by two levels of indention, or some arbitary amount you can prefix the command with an argument: 如果您需要将代码转换两个级别的缩进或一些仲裁数量,您可以在命令前加一个参数:

Cu 8 Cc > shifts the region 8 spaces to the right Cu 8 Cc >将区域向左移动8个空格

Cu 8 Cc < shifts the region 8 spaces to the left Cu 8 Cc <将区域向左移动8个空格

Another alternative is to use Mx indent-rigidly which is bound to Cx TAB : 另一种方法是使用绑定到Cx TAB Mx indent-rigidly

Cu 8 Cx TAB shifts the region 8 spaces to the right Cu 8 Cx TAB将区域向左移动8个空格

Cu -8 Cx TAB shifts the region 8 spaces to the left Cu -8 Cx TAB将区域向左移动8个空格

Also useful are the rectangle commands that operate on rectangles of text instead of lines of text. 同样有用的是矩形命令 ,它们对文本的矩形而不是文本行进行操作。

For example, after marking a rectangular region, 例如,在标记矩形区域之后,

Cx ro inserts blank space to fill the rectangular region (effectively shifting code to the right) Cx ro插入空白区域以填充矩形区域(有效地将代码移到右侧)

Cx rk kills the rectangular region (effectively shifting code to the left) Cx rk杀死矩形区域(有效地将代码移到左侧)

Cx rt prompts for a string to replace the rectangle with. Cx rt提示输入一个字符串来替换矩形。 Entering Cu 8 <space> will then enter 8 spaces. 输入Cu 8 <space>将输入8个空格。

PS. PS。 With Ubuntu, to make python-mode the default mode for all .py files, simply install the python-mode package. 使用Ubuntu,要使python-mode成为所有.py文件的默认模式,只需安装python-mode包即可。

In addition to indent-region , which is mapped to CM-\\ by default, the rectangle edit commands are very useful for Python. 除了默认情况下映射到CM-\\indent-region ,矩形编辑命令对Python非常有用。 Mark a region as normal, then: 将区域标记为正常,然后:

  • Cx rt ( string-rectangle ): will prompt you for characters you'd like to insert into each line; Cx rtstring-rectangle ):将提示您要插入每行的字符; great for inserting a certain number of spaces 非常适合插入一定数量的空格
  • Cx rk ( kill-rectangle ): remove a rectangle region; Cx rkkill-rectangle ):删除一个矩形区域; great for removing indentation 非常适合删除缩进

You can also Cx ry ( yank-rectangle ), but that's only rarely useful. 你也可以Cx ryyank-rectangle ),但这很少有用。

映射到CM-\\ indent-region应该可以解决问题。

I've been using this function to handle my indenting and unindenting: 我一直在使用这个函数来处理我的缩进和unindenting:

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

And then I assign it to a keyboard shortcut: 然后我将它分配给键盘快捷键:

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

I'm an Emacs newb, so this answer it probably bordering on useless. 我是一个Emacs newb,所以这个答案很可能接近无用。

None of the answers mentioned so far cover re-indentation of literals like dict or list . 到目前为止提到的答案都没有涵盖像dictlist这样的文字的重新缩进。 Eg Mx indent-region or Mx python-indent-shift-right and company aren't going to help if you've cut-and-pasted the following literal and need it to be re-indented sensibly: 例如, Mx indent-regionMx python-indent-shift-right和公司如果您剪切并粘贴以下文字并且需要将其重新缩进,则无法提供帮助:

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

It feels like Mx indent-region should do something sensibly in python-mode , but that's not (yet) the case. 感觉就像Mx indent-region应该在python-mode做一些明智的事情,但那不是(还)的情况。

For the specific case where your literals are bracketed, using TAB on the lines in question gets what you want (because whitespace doesn't play a role). 对于文字被括起来的特定情况,在相关行上使用TAB可以得到你想要的东西(因为空格不起作用)。

So what I've been doing in such cases is quickly recording a keyboard macro like <f3> Cn TAB <f4> as in F3, Ctrl-n (or down arrow), TAB, F4, and then using F4 repeatedly to apply the macro can save a couple of keystrokes. 所以我在这种情况下一直在做的是快速录制键盘宏,<f3> Cn TAB <f4>如F3,Ctrl-n(或向下箭头),TAB,F4,然后重复使用F4应用宏可以节省几个按键。 Or you can do Cu 10 Cx e to apply it 10 times. 或者你可以做Cu 10 Cx e来应用它10次。

(I know it doesn't sound like much, but try re-indenting 100 lines of garbage literal without missing down-arrow, and then having to go up 5 lines and repeat things ;) ). (我知道它听起来不是很多,但尝试重新缩进100行垃圾文字而不会丢失向下箭头,然后不得不上升5行并重复一些事情;))。

I use the following snippet. 我使用以下代码段。 On tab when the selection is inactive, it indents the current line (as it normally does); 在选项卡处于非活动状态时的选项卡上,它会缩进当前行(正常情况下); when the selection is inactive, it indents the whole region to the right. 当选择处于非活动状态时,它会将整个区域向右缩进。

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

Do indentation interactively. 以交互方式进行缩进。

  1. Select the region to be indented. 选择要缩进的区域。
  2. Cx TAB . Cx TAB
  3. Use arrows ( <- and -> ) to indent interactively. 使用箭头( < -- > )以交互方式缩进。
  4. Press Esc three times when you are done with the required indentation. 完成所需的缩进后,按Esc三次。

Copied from my post in: Indent several lines in Emacs 复制自我的帖子: 缩进Emacs中的几行

I do something like this universally 我普遍做这样的事情

;; intent whole buffer 
(defun iwb ()
  "indent whole buffer"
  (interactive)
  ;;(delete-trailing-whitespace)
  (indent-region (point-min) (point-max) nil)
  (untabify (point-min) (point-max)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM