Я разрабатываю плагин eclipse, который содержит специальный текстовый редактор.
Я хочу реализовать функциональность автоматических закрывающих скобок (и кавычек), что означает, что когда пользователь набирает (
, редактор должен автоматически вставить соответствующий закрывающий кронштейн )
.Как реализовать автоматическое закрытие брекета?
Мой текущий подход состоит в том, чтобы добавить IDocumentListener
в базовый IDocument
и всякий раз, когда документ был изменен, я смотрю на новый символ, и если он один, я хочу добавить символ закрытия, я добавляю его, текст документа, но это всегда бросает мое это исключение:
!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$7.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$9.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$5.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)
насколько я знаю, это потому, что я изменяю текст от слушателя, который не является хорошей идеей, поскольку само изменение notifys слушателя, который может привести к бесконечному циклу.
Однако я просто не могу придумать, как лучше реализовать эту функциональность.
Я думал о том, что эта задача может быть связана с ContentAssist, но я ничего не могу найти об этом.
Кто-нибудь знает, как правильно реализовать эту функциональность в моем плагине eclipse?
Я бы посмотрел исходный код Java-редактора JDT, чтобы увидеть, как он решает эту проблему. –
Я не нашел соответствующую информацию в источниках ... Можете ли вы дать мне подсказку, мог ли этот механизм быть реализован? – Raven
Из чтения источников, кажется, что 'BracketInserter', внутренний класс' CompilationUnitEditor' несет ответственность. Он использует 'VerifyKeyListener' для обнаружения вставок вставки. –