如果第一行和最后一行不够长,如何在 Emacs 中删除一个矩形文本?
Posted
技术标签:
【中文标题】如果第一行和最后一行不够长,如何在 Emacs 中删除一个矩形文本?【英文标题】:How can I kill a rectangle of text in Emacs if the first and last lines are not long enough? 【发布时间】:2011-12-07 04:31:11 【问题描述】:在 Emacs 中,我有时想删除或复制一个矩形文本,例如:
XX first line
XX second line is longer
XX 3rd line short
我想复制三行,每行都没有前导“XX”。但是,不可能标记所需矩形的两个角,因为第一行和第三行没有到达我所追求的矩形的右边缘。那么如何在emacs中复制上面没有前导“XX”的三行呢?
【问题讨论】:
【参考方案1】:从第一行开始标记矩形,当您位于 3d 行的末尾时,只需键入空格,直到行足够长。这是我通常做的。
复制后可以输入M-\
(delete-horizontal-space
) 删除添加的空格。
【讨论】:
如果删除选择模式打开,则在标记矩形开始后按 C-g。这会取消突出显示,但标记仍处于活动状态,因此进一步的步骤将按照说明进行。 是的,你是对的,标记将保持活动状态,因此取消选择仍然有效 您不能总是这样做(例如,当缓冲区为只读时)。不过,看起来rectangle-mark-mode
将是fixed in Emacs 25。【参考方案2】:
我看到两个选项跳出来。
首先是使用M-x Artist-mode, 这将让您移动到您想要的第一行/最后一行的位置。 此时你剪切矩形C-x r k,然后粘贴 随心所欲。不要忘记输入 C-c C-c 退出artist mode。
第二个是使用常规 C-w 将所有三行剪切掉
然后在粘贴时,删除行首XX
s 的矩形。
【讨论】:
您无需输入artist-mode
即可使用C-x r k
。只需标记所需矩形的左上角和右下角即可。至于展开到第三行,按空格键。
@jeremiahd - 使用artist-mode
可以替代按空格键,您只需使用移动绑定即可。
是的,我知道。我只是指出问题中要求的行为没有必要。
@jeremiahd 是的,也不需要按空格(您的答案),这就是我们有两个不同答案的原因。您会注意到我的回答不需要用户删除水平空格。
对,这就是我发表评论而不是答案的原因;这是一个旁白,而不是更正【参考方案3】:
你可以看看cua-selection-mode(M-x cua-selection-mode)。
它允许你做你想做的事,但只能在图形化的 emacs 中(而不是在终端中)。键绑定有点不同:您使用 C-RET(而不是 C-SPC)开始区域,然后使用 C-w/C-y(不使用矩形命令)简单地剪切/拉出矩形。
你可以在this blog找到一个例子。
要永久启用该模式,只需添加
(cua-selection-mode t)
到您的 .emacs。
附:完整的 cua 模式还将更改进一步的键绑定。没有必要使用它。
【讨论】:
这种情况下矩形选择有点尴尬,但是如果你从左上角开始,移动到最长行的末尾,然后向下移动到最后一行,就可以了。跨度> 【参考方案4】:对 inbulit defuns 的简单修改。 kill-right-rectangle
函数做你想做的事。
我相信会有更好的方法来做到这一点。尽管如此,它仍然有效。
关于以下代码的两点。 - 由于这个想法是让文本到达行尾,因此您甚至不需要指定最后一列。只需在第一行标记(在您的示例中指向“f”)并向下到第三行以“3”调用该函数。 (我们只需要一列,所以不需要向右移动光标) - 如果缓冲区是只读的,这将不起作用。它只是没有实现。
(defun end-column (POINT)
"returns end column"
(save-excursion
(goto-char POINT)
(move-end-of-line 1)
(current-column)))
(defun apply-on-right-rectangle (function start end &rest args)
(let (startcol startpt endcol endpt final-point)
(save-excursion
(goto-char start)
(setq startcol (current-column))
(beginning-of-line)
(setq startpt (point))
(goto-char end)
(setq endcol (current-column))
(forward-line 1)
(setq endpt (point-marker))
;; ensure the start column is the left one.
(if (< endcol startcol)
(let ((col startcol))
(setq startcol endcol endcol col)))
;; start looping over lines
(goto-char startpt)
(while (< (point) endpt)
(setq endcol (end-column (point)))
(apply function startcol endcol args)
(setq final-point (point))
(forward-line 1)))
final-point))
(defun delete-extract-right-rectangle (start end &optional fill)
(let ((lines (list nil)))
(apply-on-right-rectangle 'delete-extract-rectangle-line start end lines fill)
(nreverse (cdr lines))))
(defun kill-right-rectangle (start end &optional fill)
(interactive "r\nP")
(condition-case nil
(setq killed-rectangle (delete-extract-right-rectangle start end fill))
((buffer-read-only text-read-only)
(setq killed-rectangle (extract-rectangle start end))
(if kill-read-only-ok
(progn (message "Read only text copied to kill ring") nil)
(barf-if-buffer-read-only)
(signal 'text-read-only (list (current-buffer)))))))
【讨论】:
以上是关于如果第一行和最后一行不够长,如何在 Emacs 中删除一个矩形文本?的主要内容,如果未能解决你的问题,请参考以下文章