请教如何提升编辑效率:复制粘贴小片段代码

道友们好,最近因为重构,我需要频繁地在代码里复制粘贴,而且并不是大片段式的,而是小片段代码。我把我经常需要选取复制的模式用下图红色高亮来演示。能提取到的特征有

  1. 单行和多行都有
  2. 很多时候并不是行首开始,行尾结束
  3. 段落前后会有空格或者括号(并不会拆分一个word)

目前我是用鼠标来交互的,拖拽选取。痛点在于先大致的拖拽下,到最后几个字母的时候就需要放慢手速,开始拖到某个想要的地方。平时我用触摸板感觉更不舒服。

我想到或许用vim模式来解决(我平时并不开启evil),我能想到的是,先把cursor跳转到开始(通过ace-jump?),然后visual模式的移动光标,选取。可是我觉得往往也去要按键多次。对比感觉并没有比拖拽省事。

不知道道友们有没有这样的编辑需求,希望大伙能给点建议。

我比较关心的点分为两个,一个是如何高效的跳转光标(ace-jump我觉得不错,如果有其他的也可以推荐下),一个是如何高效的选取(这个暂时除了vim的传统visual模式,然后用hjkl移动之外其他没啥想法,expand-region的话似乎只能捕捉一些structural的代码,没有太多的灵活性)。

后续补充

一般是重复性的逻辑,有点细小的变动,但是片段代码有极大的相似性。比如实现某个函数,case analysis一个Animal类,Dog和Cat的的某种逻辑有极大的相似程度,我写完Dog就直接写Cat了,就想要把Dog的片段代码复制到Cat下。 (至于为什么不在语言中多换行来方便复制粘贴,因为使用的编程语言规范对换行比较敏感。)

更具体的例子是

case animal of
   Dog => someLogic1
          someLogic2 a
          someLogic3 a b c; someLogic4 c d
   Cat => | *cursor*

在写Cat的时候我想复制的是下面这一串文本。

someLogic1
someLogic2 a
someLogic3 a b c

大部分要复制的代码往往就在上面,不需要太多搜索,只需要移动光标即可。如果是整行复制然后删减,感觉效率不比鼠标拖拽高。

有例子吗,比如什么样的数据?

可以看看

2 个赞

没太理解,按照你发的图中这种文本,我一般是整段复制,然后把不需要的地方删掉,或者先复制到 scratch 里面,编辑完成之后再复制出来,要么就每个片段都复制一下,让这些片段内容进入 kill ring, 需要粘贴的时候再用 M-y 打开 kill ring 列表,然后从列表里面选择要粘贴的内容。

以上操作都不需要用到鼠标的,定位的话可以用C-s直接匹配文本字符串,比鼠标快多了。

1 个赞

哇这个很赞

有例子吗,比如什么样的数据? @Doerthous

同时回复下,一般是重复性的逻辑,有点细小的变动,但是片段代码有极大的相似性。比如实现某个函数,case analysis一个Animal类,Dog和Cat的的某种逻辑有极大的相似程度,我写完Dog就直接写Cat了,就想要把Dog的片段代码复制到Cat下。 (至于为什么不在语言中多换行来方便复制粘贴,因为使用的编程语言规范对换行比较敏感。)

更具体的例子是

case animal of
   Dog => someLogic1
          someLogic2 a
          someLogic3 a b c; someLogic4 c d
   Cat => | *cursor*

在写Cat的时候我想复制的是下面这一串文本。

someLogic1
someLogic2 a
someLogic3 a b c

大部分要复制的代码往往就在上面,不需要太多搜索,只需要移动光标即可。如果是整行复制然后删减,感觉效率不比鼠标拖拽高。

如果是用 meow 的话,只需要 w e 5 就行了。

Untitled

2 个赞

这个看着好酷啊,麻烦可以把光标放到Cat箭头后面位置,演示一下从最开始演示一下如何复制这串代码并且粘贴到Cat下面吗。

case animal of
   Dog => someLogic1
          someLogic2 a
          someLogic3 a b c; someLogic4 c d
   Cat => 
          ^ 光标放着
  1. 既然是重构,首先,比较安全和方便的是直接复制需要重构的代码整个代码单元(以函数为例), 然后重命名该函数名,并修改调用方中的函数名为新的命名。
  2. 其次,参照 kholin 很好的做法,但可以按行集来拷贝

avy goto 跳到开始,选中,再avy goto 跳到结束,copy。然后跳到目的地,粘贴。

你现在的操作是什么样的?

如果什么包都不用的话:C-r > C-r C-S-n C-S-n C-S-e基本上就可以选中。

Untitled

如果行比较靠上,还可以通过 avy 快速到对应的位置,这里行数较少,就一下下移过去的。

2 个赞

:joy: 我用鼠标移动拖拽+键盘复制粘贴(重新绑定到了cmd-c/v)

1 个赞

用 avy 的话就是 C-; s a w e 5 M-w C-y 就好了

Untitled

1 个赞

就是视觉上感觉有点眼花缭乱。evil 用户可以试试这样:

3k # 向上跳 3 行
y/;<enter> # 复制到;,很符合直觉
`. # 跳回退出插入模式的地方
p # 粘贴

假如固定粘贴到一个位置的话,CUA 有个 global-mark

C-S-SPC (+ 鼠标选中 M-w) C-S-SPC

批量零散会比较好用,鼠标选中 M-w,然后下一块继续 鼠标选中 M-w,结束后 C-S-SPC

文档在这: https://www.gnu.org/software/emacs/manual/html_node/emacs/CUA-Bindings.html#:~:text=CUA%20mode%20also,pressing%20RET.