多个文本插入符
多个文本插入符
介绍
在 IDEA 13. 中已经支持同时存在多个文本插入符(默认快捷键:ctrl+alt+shift+鼠标左键)。当同时存在多个文本插入符时,编辑操作会在所有的文本插入符 处生效。
如果同一个位置出现多个文本插入符 ,它们会合并成一个。
如果多个文本插入符 选择的文本范围有重叠,它们会合并成一个。
当添加多个文本插入符 时,最后添加的被设置为主文本插入符 (primary caret,只会有一个),这时候执行针对文本插入符 的操作的时候,只对首要文本插入符 起作用,例如:存在多个文本插入符 时,执行了代码补全操作,如下图:list 和 integer 后都加入文本插入符,这时候执行代码补全操作,只联想了 integer 的方法
核心功能
通过 CaretModel 接口可以获取所有的文本插入符,增加或移除文本插入符等。
通过CaretModel 和 SelectionModel对象 查询和修改文本插入符,获取选中文本的位置 等操作默认都是针对主文本插入符(primary caret) 。在CaretModel.runForEachCaret 方法里,它依赖于操作上下文.
不再存在 块选择(Block selection) 的概念,SelectionModel.hasBlockSelection() 方法永远返回false ,SelectionModel.setBlockSelection() 方法会创建一个相当于 块选择(Block selection)的多个文本插入符选择块 。SelectionModel.getBlockSelectionStarts() 和 SelectionModel.getBlockSelectionEnds() 会返回文档中所有选择块 的范围。
编辑器操作
EditorAction 和 EditorActionHandler
当调用 EditorActionHandler 时,会传递文本插入符(caret) 实例或null 。文本插入符(caret) 会在多个 Handler 之间传递。如果Handler 不需要文本插入符(caret) 实例,可以忽略它。
如果需要实现 multi-caret 的功能,需要重写 EditorActionHandler.doExecute 方法。如果只是想让你的操作在每一个文本插入符(caret) 上执行,那只需要在 EditorActionHandler 构造器里指定就行。
Editor Action 代理
可用的代理类如下:
EnterHandlerDelegate
BackspaceHandlerDelegate
JoinLinesHandlerDelegate
EditorNavigationDelegate
SmartEnterProcessor
CommentCompleteHandler
StatementUpDownMover
CodeBlockProvider
因为操作可以指定在每一个文本插入符(caret) 上执行,所以暂时不需要支持 multi-caret 功能
打字操作
TypedActionHandler, TypedHandlerDelegate
每一次输入文本都会调用一次 TypedActionHandler 和 TypedHandlerDelegate 的实现类。
EditorModificationUtil. typeInStringAtCaretHonorMultipleCarets() 方法可以在所有的文本插入符(caret) 位置上执行相同的操作(例如,插入文本) 。可以在 TypedAction 和 XmlGtTypedHandler 类里看到相关操作示例。
提示
从14版本开始,每一个文本插入符(caret) 都会自动执行 TypedHandlerDelegate。如果想要自定义multi-caret 的操作,需要提供 TypedActionHandler
代码自省操作
CodeInsightAction 的子类只会作用于 主文本插入符(primary caret) 。如果需要支持 multi-caret 功能,需要替换为 MultiCaretCodeInsightAction 。替换以后,每一个文本插入符(caret) 都会有不同的 editor 和 PSI 实例对象,所以之前的API可能失效。