其实就是选中区域的 symbol-overlay.
是,没用过 symbol-overlay
,不知道它是否有实现,不过 multiple-cursors
的方法挺麻烦的。
而且有了第二个 region 后就可以玩起来了,比如交换两个 region 什么的。
symbol-overlay 是不用选区, 它会把整个 buffer 的同名的全部选中。
确实有拷贝处函数, 把选中函数内的局部变量重命名的场景。
那我感觉其实应该有一个类似划定选区的函数, 但是和矩形操作不一样, 仅仅只是限定 markmacro 的标记区域。
就是我上面提到的 secondary-selection-from-region
等我研究一下, 我在写 markmacro-mark-imenus
这是我糊的函数,供猫大参考一下。
代码
(defun meow--cancel-second-selection ()
(delete-overlay mouse-secondary-overlay)
(setq mouse-secondary-start (make-marker))
(move-marker mouse-secondary-start (point)))
(defun meow-grab ()
"Create secondary selection or a marker if no region available."
(interactive)
(if (region-active-p)
(secondary-selection-from-region)
(meow--cancel-second-selection))
(deactivate-mark t))
(defun markmacro-mark-all-in-region ()
(interactive)
(when-let
((sec-region-start (overlay-start mouse-secondary-overlay))
(sec-region-end (overlay-end mouse-secondary-overlay))
(target (thing-at-point 'word))
(mark-bounds '(t)))
(save-excursion
(goto-char sec-region-start)
(pop mark-bounds)
(while (search-forward target sec-region-end t)
(push (cons (match-beginning 0)
(match-end 0))
mark-bounds)))
(dolist (bound mark-bounds)
(let* ((overlay (make-overlay (car bound) (cdr bound))))
(overlay-put overlay 'face 'markmacro-mark-face)
(add-to-list 'markmacro-overlays overlay t)))
(delete-overlay mouse-secondary-overlay)
(markmacro-select-last-overlay)))
(defun test-function-1 (arg)
)
(defun test-function-2 (arg)
)
(defun test-function-3 (arg)
)
=>
(defun test-function-1 (new-arg arg)
)
(defun test-function-2 (new-arg arg)
)
(defun test-function-3 (new-arg arg)
)
-
markmacro-mark-imenus
mark all functions and start kmacro record automatically - isearch
(
character - Type
new-arg
-
markmacro-apply-all
apply kmacro to all mark functions
@zhscn 你看我这样弄, 应该是更科学的, 之所以用 imenu 而不是 tree-sitter 是因为现阶段 Emacs 的 tree-sitter 太脆弱了, 稍微复杂的编辑, 解析的位置就不准确。
大佬发一个补丁吧, 稍微把 meow 的名字改一下, secondary-selection-from-region 在局部快速重命名方面确实很有用。
思路是共同的,只要能定位到特定位置,就可以批量编辑选择的对象。
还有很多类似的脑洞,比如根据语义选择对象:可以选中一个类的私有成员批量增加前缀/后缀。选中一个函数的参数列表修改并更新函数体。
上面的例子都是用文本的修改编辑完成了部分重构的工作。其实意义不大,用对应的lsp工具更方便准确。
另一个思路则是,完成选择目标对象之后,用kmacro录制lsp重构的操作然后再应用。不过这么做实际也没啥价值。。毕竟语言中的变量和函数不像文件名那样规整,如果能做这种模式相近的批量操作的话应该首先反思一下代码是不是该重写了。。
想起来为什么要给函数批量加参数了,当时是debug,为了追踪一些状态就直接把需要的信息用参数传递了。
其实每个对象标记函数都应该对应一个真实的应用场景, 这样才能最大程度提升这种多个地方改代码的效率。
已提 PR,麻烦猫大查看一下。
考虑到 README 里 demo 的一致性,所以没更新 README ,不过用法写在函数的 docstring 里了。
已经合并了, 大佬太强了。
其实可以加到 Demo, Demo里本来已经有两种模式了, 不差第三种模式, 不冲突的。
我的意思是 git 里的 emacs 主题不一样,影响观感哈哈
哦, 这个呀, 我一会去录制gif.
其实 markmacro-mark-all-in-region 这个功能如果应用在当前 buffer 范围的话, 从功能上已经覆盖 symbol-overlay 的功能。
而且 markmacro 是支持键盘宏的, 功能应该比 symbol-overlay 更强。
默认选中的类型改成 symbol 更通用? 因为如果匹配 word 的情况, 其实也匹配 symbol . 而 symbol 是我们日常重构遇到最多的类型。
我当时考虑的情况是 foo_bar
之类的,不过我代码写的少,可能确实改成 symbol
比较好。
那需要修改一下吗?
我来改吧, 我顺便把名字重命名一下, 统一的感觉, 稍等哈, 我在录 gif
我调整了一下名字, 和正常 mark 以及 rect mark 做一个区分, 同时默认用 symbol 来标记, 更通用。