thing-edit新功能介绍

有朋友在微信群里面提了这样一个问题:

evi-mode 中,ciw (删除一个text-object),能否只删除不拷贝?

比如,我经常的操作:
================
先复制一块,然后找到需要粘贴的地方,比如(...)中,

可是用了 ciw, 虽然删除了()里面的内容,
但是我原先的粘贴板的内容也变掉了,不得不回到原来的位置重新拷贝一下

有什么好的方法?

我想了想,其实我有也有相同的需求。我之前写过一个小函数专门来做这个事情。

(defun peng-replace-current-symbol-with-kill-ring ()
  (interactive)
  (let* ((begin (progn
                  (beginning-of-thing 'symbol)
                  (point)))
         (end (progn
                (end-of-thing 'symbol)
                (point))))

    (progn
      (beginning-of-thing 'symbol)
      (delete-char (- end begin))
      (yank))
    ))

函数功能很简单,其实就是替换当前光标下的symbol为kill-ring里面的东西。

在没有这个函数前,我如果需要把一个symbolA替换成symbolB。需要做下面的操作(先拷贝,再替换):

  1. 移动到symbolB,copy symbolB。
  2. 移动到symbolA,删除symbolA。
  3. yank symbolB。

这样可能的问题是,在删除symbolA的时候,如果调用一些功能函数来删(比如这位朋友在evil中的ciw操作),可能又把symbolA复制到kill-ring里面去了(或者是其它地方,反正就是把之前复制的东西给覆盖掉了)。 这时执行第三步可能就比较麻烦,可能需要两次C-y,或者其它麻烦的操作。

当然,可以改一下执行顺序:

  1. 移动到symbolA,删除symbolA。
  2. 移动到symbolB,copy symbolB。
  3. 移动到symbolA,yank symbolB。

但是,这样又会多一次移动。 而且说实话,当我们有这种需求的时候,比较多的情况就是先拷贝好内容,然后到要修改的地方用刚拷贝的内容替换掉原来的内容。

所以我写了一个这样的小函数,流程就成了:

  1. 移动到symbolB,copy symbolB。
  2. 移动到symbolA,执行小函数。

本来这是一个小函数,但是我现在发现,每天我使用它的次数竟然多得吓人! 以至于我把它绑定到command模式下的2键,只需要按一次就执行。

但是,它只是针对symbol而言的。 如果有其它复杂点的,比如想针对括号内的内容来做此类操作就没有办法了。

之前使用 EmacsWiki: thing-edit.el 。 底层使用 ThingAtPoint 。它几乎可以涵盖所有我需要的copy动作。 我想能不能把这个小功能也加入到里面去呢?这样针对不同的"thing",我都可以两步完成这类操作。

其实不麻烦,完成后的代码 thing-edit

我新增了几个thing-replace-xxx函数。比如我想现在想把一个文件中的函数A换成另一个文件中的函数B。现在需要的操作就是:

  1. 移动到函数B,使用thing-copy-defun拷贝函数B。
  2. 移动到函数A,使用thing-replace-defun直接就完成了。

其它对应的thing都是一样的操作。比较有用的是:

这些函数都有对应的replace。操作是一样的。

最后可以为它定义一个map:

(defvar peng-thing-edit-map (make-sparse-keymap)
  "Keybinding for `thing-edit'")

;; Copy.
(define-key peng-thing-edit-map (kbd "w") 'thing-copy-word)
(define-key peng-thing-edit-map (kbd "s") 'thing-copy-symbol)
(define-key peng-thing-edit-map (kbd "m") 'thing-copy-email)
(define-key peng-thing-edit-map (kbd "f") 'thing-copy-filename)
(define-key peng-thing-edit-map (kbd "u") 'thing-copy-url)
(define-key peng-thing-edit-map (kbd "x") 'thing-copy-sexp)
(define-key peng-thing-edit-map (kbd "t") 'thing-copy-page)
(define-key peng-thing-edit-map (kbd "g") 'thing-copy-sentence)
(define-key peng-thing-edit-map (kbd "o") 'thing-copy-whitespace)
(define-key peng-thing-edit-map (kbd "i") 'thing-copy-list)
(define-key peng-thing-edit-map (kbd "c") 'thing-copy-comment)
(define-key peng-thing-edit-map (kbd "h") 'thing-copy-defun)
(define-key peng-thing-edit-map (kbd "p") 'thing-copy-parentheses)
(define-key peng-thing-edit-map (kbd "a") 'thing-copy-to-line-beginning)
(define-key peng-thing-edit-map (kbd "e") 'thing-copy-to-line-end)

;; Replace
(define-key peng-thing-edit-map (kbd "W") 'thing-replace-word)
(define-key peng-thing-edit-map (kbd "S") 'thing-replace-symbol)
(define-key peng-thing-edit-map (kbd "M") 'thing-replace-email)
(define-key peng-thing-edit-map (kbd "F") 'thing-replace-filename)
(define-key peng-thing-edit-map (kbd "U") 'thing-replace-url)
(define-key peng-thing-edit-map (kbd "X") 'thing-replace-sexp)
(define-key peng-thing-edit-map (kbd "T") 'thing-replace-page)
(define-key peng-thing-edit-map (kbd "G") 'thing-replace-sentence)
(define-key peng-thing-edit-map (kbd "O") 'thing-replace-whitespace)
(define-key peng-thing-edit-map (kbd "I") 'thing-replace-list)
(define-key peng-thing-edit-map (kbd "C") 'thing-replace-comment)
(define-key peng-thing-edit-map (kbd "H") 'thing-replace-defun)
(define-key peng-thing-edit-map (kbd "P") 'thing-replace-parentheses)

然后为它绑定一个按键:

(global-set-key (kbd "your-keys") peng-thing-edit-map)

如果你觉得本文不错,欢迎 donate