簡體   English   中英

如何實現自動括弧關閉?

[英]How to implement auto bracket-closing?

我正在開發一個包含自定義文本編輯器的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)

據我所知,這是因為我正在更改偵聽器中的文本,這不是一個好主意,因為更改本身會通知偵聽器,這可能導致無限循環。
但是我只是想不出一個更好的主意來實現此功能。

我考慮過這種任務可能與ContentAssist相關聯,但是我找不到任何相關信息。

有人知道如何在我的eclipse插件中正確實現此功能嗎?

在查看org.eclipse.jdt.ui插件的sourceCode之后,我發現他們使用編輯器SourceViewer上的VerifyKeyListener創建了此功能。 它捕獲所有關鍵輸入,並可以通過該事件訪問相應的文本。

但是,要在編輯器之后創建它來創建編輯器的SourceViewer卻非常棘手,因此在編輯器的構造函數中調用getSourceViewer()方法時返回null
關鍵是要覆蓋在AbstractDecoratedTextEditor聲明的編輯器類中的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在其中我要查找配對字符(例如VerifyKeyListern括號和verifyKey()括號),然后在verifyKey() - verifyKey()內部使用如下所示的verifyKey()

StyledText text = (StyledText) event.getSource();

text.insert(String.valueOf(<pairingCharacter>));

無論如何,只要將鍵入的字符(開始字符)插入到文本中,我就只能通過insert()方法添加相應的結束字符-該方法具有很好的效果,之后我的光標位於這兩個字符之間

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM