Vim 的 dd,o,O 的 Emacs 等价物

Posted

技术标签:

【中文标题】Vim 的 dd,o,O 的 Emacs 等价物【英文标题】:Emacs equivalents of Vim's dd,o,O 【发布时间】:2011-01-11 12:19:20 【问题描述】:

我目前正在使用 emacs,并且对大多数概念感到满意。但我真的很喜欢这三个 vim 命令的便利性:dd,o,O 希望你能告诉我如何在 emacs 中镜像它们:)

dd - 删除整行,包括换行符,无论光标在哪里。

我发现了类似的方法:

C-a C-k C-k

C-a 将光标移动到行首时,第一个C-k 删除文本,第二个删除换行符。唯一的问题是这不适用于空行,我只需要输入 C-k 这很不方便,因为我必须为同一任务使用不同的命令:杀死一行。

o / O - 在光标下方/上方创建一个新的空行并将光标移动到新行,缩进正确

嗯,C-a C-oO 差不多,只是缺少概念。 C-e C-o 在当前行下方创建一个空行,但不移动光标。

有没有更好的解决方案来解决我的问题,还是我必须学习 Lisp 并定义新的命令来满足我的需求?

【问题讨论】:

我认为换行的最佳方法是 superuser.com/a/331661 (C-e C-j) 【参考方案1】:

对于oO,下面是我多年前写的几个函数:

(defun vi-open-line-above ()
  "Insert a newline above the current line and put point at beginning."
  (interactive)
  (unless (bolp)
    (beginning-of-line))
  (newline)
  (forward-line -1)
  (indent-according-to-mode))

(defun vi-open-line-below ()
  "Insert a newline below the current line and put point at beginning."
  (interactive)
  (unless (eolp)
    (end-of-line))
  (newline-and-indent))

(defun vi-open-line (&optional abovep)
  "Insert a newline below the current line and put point at beginning.
With a prefix argument, insert a newline above the current line."
  (interactive "P")
  (if abovep
      (vi-open-line-above)
    (vi-open-line-below)))

您可以将vi-open-line 绑定到例如M-insert,如下所示:

(define-key global-map [(meta insert)] 'vi-open-line)

对于dd,如果你想让被杀死的线进入杀死环,你可以使用这个包裹kill-line的函数:

(defun kill-current-line (&optional n)
  (interactive "p")
  (save-excursion
    (beginning-of-line)
    (let ((kill-whole-line t))
      (kill-line n))))

为了完整起见,它接受一个前缀参数并将其应用于kill-line,因此它可以杀死比“当前”行更多的内容。

您还可以查看viper-mode 的源代码,了解它如何实现等效的ddoO 命令。

【讨论】:

哇,太好了,谢谢。像魅力一样工作:) 只是vi-open-line-above 不缩进。有什么想法吗? 我在vi-open-line-above 下方的(forward-line -1) 中添加了(indent-according-to-mode)。这就是诀窍:) 有趣的是,当你注意到你找到了解决方案时,我正在再次编辑它。如您所知,这是我不经常使用的旧代码。我是在第一次学习 Emacs Lisp 时写的。这个问题给了我一个刷新它的借口。【参考方案2】:
C+e C+j

根据the emacs manual docs。这会给你一个新的行和缩进。

【讨论】:

如果你在一个句子或一行的中间,而c+j 它将把该行的其余部分放在新行上。这就像在线路中间点击return。我们想在当前光标位置下方添加一个空行。【参考方案3】:

对于dd,使用“kill-whole-line”,在最近的Emacs版本中默认绑定到“C-S-backspace”。

我应该补充一点,我自己更频繁地使用whole-line-or-region.el,因为C-wC-S-backspace 更容易输入。

【讨论】:

【参考方案4】:

您可以创建macro 和bind it to a key sequence。还不需要学习任何 emacslisp。

【讨论】:

【参考方案5】:

以下是我如何解决 Emacs 缺少类似 vi 的“O”命令的问题:

(defadvice open-line (around vi-style-open-line activate)
  "Make open-line behave more like vi."
  (beginning-of-line)
  ad-do-it
  (indent-according-to-mode))

有了这个,我从来没有真正觉得需要相应版本的 vi 的“o”命令。 C-n C-o 可以解决问题。

至于“dd”命令,一开始有点讨厌,但我最终还是接受了 Emacs 的处理方式。无论如何,当我想一次删除几行时(通常是这种情况),我只是使用区域(C-a C-SPC,转到我要删除的文本的另一端,C-w)。或者,如果我可以看到我想删除的行数,我会这样做。 M-9 C-k 一次删除九行。

【讨论】:

【参考方案6】:

我知道,这个回复并不直截了当,但是就像 vim 用户一样,我发现 Spacemacs 是从 vim 迁移到 emacs 的最实用的 emacs 入门包。您可以将其配置为类似 vim、类似 emacs 或混合。

http://spacemacs.org/

试一试。

【讨论】:

【参考方案7】:

只需使用Viper-mode、Vimpulse 或Vim Mode,Emacs 键绑定就是不符合人体工程学。

【讨论】:

这对我来说听起来很尴尬。如果我想使用 vim,那么我使用 vim 而不是 emacs。 Emacs 的键绑定可能(!)不符合人体工程学,但至少对我来说,vi 的模态**** 让我的大脑感到厌烦。 @eteubert 一点也不尴尬。只需将 emacs 视为第 3(或第 4)模式。一旦你拿起了 emacs,一切都在 emacs 中,这实际上感觉很自然。

以上是关于Vim 的 dd,o,O 的 Emacs 等价物的主要内容,如果未能解决你的问题,请参考以下文章

Vim学习

vim简单操作---学习随笔

通过 Emacs 中的 shell 命令过滤文本

Vim编辑器

Vi/Vim的快捷方式

vim基础命令