用于 Python 的 Emacs 批量缩进

在 Emacs 中使用 Python 时,如果我想在代码块中添加 try/other,我经常发现必须逐行缩进整个代码块。在 Emacs 中,如何一次缩进整个块。

我不是一个经验丰富的 Emacs 用户,但是我发现它是通过 ssh 工作的最佳工具。我在命令行(Ubuntu)上使用 Emacs,而不是作为一个 gui,如果这有什么不同的话。

47615 次浏览

映射到 C-M-\indent-region应该可以做到这一点。

除了默认映射到 C-M-\indent-region之外,矩形编辑命令对 Python 非常有用。那么,将一个区域标记为正常:

  • C-x r t(string-rectangle) : 将提示您输入要插入到每一行中的字符; 非常适合插入一定数量的空格
  • C-x r k(kill-rectangle) : 删除一个矩形区域; 非常适合删除缩进

您也可以使用 C-x r y(yank-rectangle) ,但是这很少有用。

如果您正在使用 Emacs 编写 Python 程序,那么您可能应该使用 Python 模式。使用 python 模式,在标记代码块之后,

C-c >C-c C-l将区域向右移动4个空格

C-c <C-c C-r将区域向左移动4个空格

如果您需要将代码移动两个级别的缩进,或者一些任意的数量,您可以在命令前面加上一个参数:

C-u 8 C-c >将区域向右移动8个空格

C-u 8 C-c <将区域向左移动8个空格

另一种选择是使用绑定到 C-x TABM-x indent-rigidly:

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个空格。

使用 Ubuntu,要使 python 模式成为所有.py 文件的默认模式,只需安装 python-mode包。

我在全世界都做这样的事

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

我一直在使用这个函数来处理缩进和取消缩进:

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

我是一个 Emacs 新手,所以这个答案可能接近于无用。

到目前为止,所提到的答案都没有涵盖像 dictlist这样的字面缩进。例如,如果你剪切粘贴了下面的文字,并且需要合理地重新缩进,那么 M-x indent-regionM-x python-indent-shift-right以及其他公司是不会帮助你的:

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

感觉好像 M-x indent-region应该在 python-mode中做一些明智的事情,但事实并非如此。

对于文字被括起来的特定情况,在有问题的行上使用 TAB 可以得到您想要的结果(因为空格不起作用)。

因此,在这种情况下,我所做的就是像 F3、 Ctrl-n (或向下箭头)、 TAB、 F4那样快速记录 键盘宏,然后重复使用 F4来应用宏可以节省几次击键。或者你可以做 C-u 10 C-x e应用它10次。

(我知道这听起来不是很多,但是尝试重新缩进100行垃圾字面值而不丢失向下箭头,然后必须向上移动5行并重复操作;)。

我使用以下代码片段。在选项卡上,当选项处于非活动状态时,它缩进当前行(正常情况下) ; 当选项处于非活动状态时,它将整个区域向右缩进。

(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. 选择要缩进的区域。
  2. C-x TAB.
  3. 使用箭头(<-->)交互式缩进。
  4. Esc三次,当您完成所需的缩进。

从我的职位复制在: 在 Emacs 中缩进几行