如何实现自动括号关闭?
How to implement auto bracket-closing?
我正在开发一个包含自定义文本编辑器的 eclipse 插件。
我想实现自动右括号(和引号)的功能,这意味着当用户键入 (
时,编辑器应该自动插入相应的右括号 )
。
我目前的方法是在基础 IDocument
中添加一个 IDocumentListener
,每当文档发生变化时,我都会查看新字符,如果是新字符,我想添加一个结束字符,我通过设置文档的文本来添加它,但这总是抛出我的这个异常:
!SESSION 2015-12-22 15:03:53.517 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.8.0_45
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=de_DE
Framework arguments: -product org.eclipse.sdk.ide
Command-line arguments: -product org.eclipse.sdk.ide -data C:\Users\Robert Adam\Documents\eclipse.mars.pluginDev\workspace/../runtime-EclipseApplication(1) -dev file:C:/Users/Robert Adam/Documents/eclipse.mars.pluginDev/workspace/.metadata/.plugins/org.eclipse.pde.core/Eclipse Application (1)/dev.properties -os win32 -ws win32 -arch x86_64 -consoleLog
!ENTRY org.eclipse.text 4 2 2015-12-22 15:04:23.611
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.text".
!STACK 0
org.eclipse.core.runtime.AssertionFailedException: assertion failed:
at org.eclipse.core.runtime.Assert.isTrue(Assert.java:110)
at org.eclipse.core.runtime.Assert.isTrue(Assert.java:96)
at org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer.handleAboutToBeChanged(DocumentLineDiffer.java:816)
at org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer.documentAboutToBeChanged(DocumentLineDiffer.java:785)
at org.eclipse.jface.text.AbstractDocument.fireDocumentAboutToBeChanged(AbstractDocument.java:665)
at org.eclipse.jface.text.AbstractDocument.set(AbstractDocument.java:1228)
at org.eclipse.jface.text.AbstractDocument.set(AbstractDocument.java:1217)
at raven.sqdev.editors.sqfeditor.SQFDocumentListener.handleAddition(SQFDocumentListener.java:61)
at raven.sqdev.editors.sqfeditor.SQFDocumentListener.documentChanged(SQFDocumentListener.java:33)
at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged2(AbstractDocument.java:769)
at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged(AbstractDocument.java:736)
at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged(AbstractDocument.java:721)
at org.eclipse.jface.text.AbstractDocument.fireDocumentChanged(AbstractDocument.java:796)
at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1191)
at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1210)
at org.eclipse.jface.text.DefaultDocumentAdapter.replaceTextRange(DefaultDocumentAdapter.java:248)
at org.eclipse.swt.custom.StyledText.modifyContent(StyledText.java:7268)
at org.eclipse.swt.custom.StyledText.sendKeyEvent(StyledText.java:8111)
at org.eclipse.swt.custom.StyledText.doContent(StyledText.java:2481)
at org.eclipse.swt.custom.StyledText.handleKey(StyledText.java:5955)
at org.eclipse.swt.custom.StyledText.handleKeyDown(StyledText.java:5986)
at org.eclipse.swt.custom.StyledText.handleEvent(StyledText.java:5663)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4353)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1061)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1085)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1070)
at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1112)
at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1108)
at org.eclipse.swt.widgets.Widget.wmChar(Widget.java:1529)
at org.eclipse.swt.widgets.Control.WM_CHAR(Control.java:4722)
at org.eclipse.swt.widgets.Canvas.WM_CHAR(Canvas.java:343)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4610)
at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:339)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5023)
at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2549)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3759)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1151)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1032)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:148)
at org.eclipse.ui.internal.Workbench.run(Workbench.java:636)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:579)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:135)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:380)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:235)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:648)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:603)
at org.eclipse.equinox.launcher.Main.run(Main.java:1465)
at org.eclipse.equinox.launcher.Main.main(Main.java:1438)
据我所知,这是因为我正在更改来自侦听器的文本,这不是一个好主意,因为更改本身会通知侦听器,这可能会导致无限循环。
但是,我只是想不出一个更好的主意来实现这个功能。
我想过这种任务可能与 ContentAssist 有关,但我找不到任何相关信息。
有人知道如何在我的 eclipse 插件中正确实现此功能吗?
查看 org.eclipse.jdt.ui
插件的源代码后,我发现他们使用编辑器 SourceViewer
上的 VerifyKeyListener
创建了此功能。它捕获所有关键输入并通过事件访问相应的文本。
然而,要进入我的编辑器的 SourceViewer
非常棘手,因为它是在我的编辑器之后创建的,因此方法 getSourceViewer()
在调用时返回 null
我的编辑器的构造函数。
关键是在 AbstractDecoratedTextEditor
.
中声明的编辑器 class 中覆盖 createSourceViewer()
在那里我做了这样的事情:
@Override
public ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
ISourceViewer viewer = super.createSourceViewer(parent, ruler, styles);
if(viewer instanceof ITextViewerExtension) {
((ITextViewerExtension) viewer).appendVerifyKeyListener(<Listener>);
}
return viewer;
}
我实现了自己的 VerifyKeyListern
,我在其中处理查找配对字符(如左括号和右括号),然后在 verifyKey()
方法中使用了类似的内容:
StyledText text = (StyledText) event.getSource();
text.insert(String.valueOf(<pairingCharacter>));
由于输入的字符(开始字符)无论如何都被插入到文本中,所以我只通过 insert()
方法添加相应的结束字符,该方法具有很好的效果,之后我的光标位于这些字符之间两个字符
我正在开发一个包含自定义文本编辑器的 eclipse 插件。
我想实现自动右括号(和引号)的功能,这意味着当用户键入 (
时,编辑器应该自动插入相应的右括号 )
。
我目前的方法是在基础 IDocument
中添加一个 IDocumentListener
,每当文档发生变化时,我都会查看新字符,如果是新字符,我想添加一个结束字符,我通过设置文档的文本来添加它,但这总是抛出我的这个异常:
!SESSION 2015-12-22 15:03:53.517 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.8.0_45
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=de_DE
Framework arguments: -product org.eclipse.sdk.ide
Command-line arguments: -product org.eclipse.sdk.ide -data C:\Users\Robert Adam\Documents\eclipse.mars.pluginDev\workspace/../runtime-EclipseApplication(1) -dev file:C:/Users/Robert Adam/Documents/eclipse.mars.pluginDev/workspace/.metadata/.plugins/org.eclipse.pde.core/Eclipse Application (1)/dev.properties -os win32 -ws win32 -arch x86_64 -consoleLog
!ENTRY org.eclipse.text 4 2 2015-12-22 15:04:23.611
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.text".
!STACK 0
org.eclipse.core.runtime.AssertionFailedException: assertion failed:
at org.eclipse.core.runtime.Assert.isTrue(Assert.java:110)
at org.eclipse.core.runtime.Assert.isTrue(Assert.java:96)
at org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer.handleAboutToBeChanged(DocumentLineDiffer.java:816)
at org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer.documentAboutToBeChanged(DocumentLineDiffer.java:785)
at org.eclipse.jface.text.AbstractDocument.fireDocumentAboutToBeChanged(AbstractDocument.java:665)
at org.eclipse.jface.text.AbstractDocument.set(AbstractDocument.java:1228)
at org.eclipse.jface.text.AbstractDocument.set(AbstractDocument.java:1217)
at raven.sqdev.editors.sqfeditor.SQFDocumentListener.handleAddition(SQFDocumentListener.java:61)
at raven.sqdev.editors.sqfeditor.SQFDocumentListener.documentChanged(SQFDocumentListener.java:33)
at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged2(AbstractDocument.java:769)
at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged(AbstractDocument.java:736)
at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged(AbstractDocument.java:721)
at org.eclipse.jface.text.AbstractDocument.fireDocumentChanged(AbstractDocument.java:796)
at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1191)
at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1210)
at org.eclipse.jface.text.DefaultDocumentAdapter.replaceTextRange(DefaultDocumentAdapter.java:248)
at org.eclipse.swt.custom.StyledText.modifyContent(StyledText.java:7268)
at org.eclipse.swt.custom.StyledText.sendKeyEvent(StyledText.java:8111)
at org.eclipse.swt.custom.StyledText.doContent(StyledText.java:2481)
at org.eclipse.swt.custom.StyledText.handleKey(StyledText.java:5955)
at org.eclipse.swt.custom.StyledText.handleKeyDown(StyledText.java:5986)
at org.eclipse.swt.custom.StyledText.handleEvent(StyledText.java:5663)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4353)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1061)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1085)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1070)
at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1112)
at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1108)
at org.eclipse.swt.widgets.Widget.wmChar(Widget.java:1529)
at org.eclipse.swt.widgets.Control.WM_CHAR(Control.java:4722)
at org.eclipse.swt.widgets.Canvas.WM_CHAR(Canvas.java:343)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4610)
at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:339)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5023)
at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2549)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3759)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1151)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1032)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:148)
at org.eclipse.ui.internal.Workbench.run(Workbench.java:636)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:579)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:135)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:380)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:235)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:648)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:603)
at org.eclipse.equinox.launcher.Main.run(Main.java:1465)
at org.eclipse.equinox.launcher.Main.main(Main.java:1438)
据我所知,这是因为我正在更改来自侦听器的文本,这不是一个好主意,因为更改本身会通知侦听器,这可能会导致无限循环。
但是,我只是想不出一个更好的主意来实现这个功能。
我想过这种任务可能与 ContentAssist 有关,但我找不到任何相关信息。
有人知道如何在我的 eclipse 插件中正确实现此功能吗?
查看 org.eclipse.jdt.ui
插件的源代码后,我发现他们使用编辑器 SourceViewer
上的 VerifyKeyListener
创建了此功能。它捕获所有关键输入并通过事件访问相应的文本。
然而,要进入我的编辑器的 SourceViewer
非常棘手,因为它是在我的编辑器之后创建的,因此方法 getSourceViewer()
在调用时返回 null
我的编辑器的构造函数。
关键是在 AbstractDecoratedTextEditor
.
中声明的编辑器 class 中覆盖 createSourceViewer()
在那里我做了这样的事情:
@Override
public ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
ISourceViewer viewer = super.createSourceViewer(parent, ruler, styles);
if(viewer instanceof ITextViewerExtension) {
((ITextViewerExtension) viewer).appendVerifyKeyListener(<Listener>);
}
return viewer;
}
我实现了自己的 VerifyKeyListern
,我在其中处理查找配对字符(如左括号和右括号),然后在 verifyKey()
方法中使用了类似的内容:
StyledText text = (StyledText) event.getSource();
text.insert(String.valueOf(<pairingCharacter>));
由于输入的字符(开始字符)无论如何都被插入到文本中,所以我只通过 insert()
方法添加相应的结束字符,该方法具有很好的效果,之后我的光标位于这些字符之间两个字符