1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 14:12:10 +02:00

Bug 535428. Add indentation and bracket completion support in LSP4E-CPP

Change-Id: Ib9187a3ad28796305c47fe8e9543e1aed6a7bf58
Signed-off-by: Manish Khurana <mkmanishkhurana98@gmail.com>
This commit is contained in:
Manish Khurana 2018-08-12 02:09:31 +05:30 committed by Nathan Ridge
parent ac81db720c
commit 1983d41afb
6 changed files with 101 additions and 15 deletions

View file

@ -469,17 +469,19 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
}
}
private class ExitPolicy implements IExitPolicy {
private static class ExitPolicy implements IExitPolicy {
final char fExitCharacter;
final char fEscapeCharacter;
final Deque<BracketLevel> fStack;
final int fSize;
ISourceViewer sourceViewer;
public ExitPolicy(char exitCharacter, char escapeCharacter, Deque<BracketLevel> stack) {
public ExitPolicy(char exitCharacter, char escapeCharacter, Deque<BracketLevel> stack, ISourceViewer sViewer) {
fExitCharacter = exitCharacter;
fEscapeCharacter = escapeCharacter;
fStack = stack;
fSize = fStack.size();
sourceViewer = sViewer;
}
@Override
@ -496,7 +498,7 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
// When entering an anonymous class between the parenthesis', we don't want
// to jump after the closing parenthesis when return is pressed.
if (event.character == SWT.CR && offset > 0) {
IDocument document = getSourceViewer().getDocument();
IDocument document = sourceViewer.getDocument();
try {
if (document.getChar(offset - 1) == '{')
return new ExitFlags(ILinkedModeListener.EXIT_ALL, true);
@ -508,7 +510,7 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
}
private boolean isMasked(int offset) {
IDocument document = getSourceViewer().getDocument();
IDocument document = sourceViewer.getDocument();
try {
return fEscapeCharacter == document.getChar(offset - 1);
} catch (BadLocationException e) {
@ -603,7 +605,7 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
// }
}
private class BracketInserter implements VerifyKeyListener, ILinkedModeListener {
public static class BracketInserter implements VerifyKeyListener, ILinkedModeListener {
private boolean fCloseBrackets = true;
private boolean fCloseStrings = true;
private boolean fCloseAngularBrackets = true;
@ -611,6 +613,18 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
private final String CATEGORY = toString();
private final IPositionUpdater fUpdater = new ExclusivePositionUpdater(CATEGORY);
private final Deque<BracketLevel> fBracketLevelStack = new ArrayDeque<>();
private ISourceViewer sourceViewer;
private boolean isGenericEditor;
private TextEditor fEditor;
public BracketInserter(TextEditor editor, boolean isGenericEditor) {
fEditor = editor;
this.isGenericEditor = isGenericEditor;
}
public void setSourceViewer(ISourceViewer sViewer) {
sourceViewer = sViewer;
}
public void setCloseBracketsEnabled(boolean enabled) {
fCloseBrackets = enabled;
@ -638,7 +652,13 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
@Override
public void verifyKey(VerifyEvent event) {
// Early pruning to minimize overhead for normal typing.
if (!event.doit || getInsertMode() != SMART_INSERT)
if (!event.doit)
return;
// Need to check that it is Generic Editor or CEditor before checking "Smart Insert" mode
// because Generic Editor doesn't have a "Smart Insert" mode.
if(!isGenericEditor)
if (fEditor.getInsertMode() != SMART_INSERT)
return;
switch (event.character) {
case '(':
@ -652,7 +672,6 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
return;
}
final ISourceViewer sourceViewer = getSourceViewer();
IDocument document = sourceViewer.getDocument();
final Point selection = sourceViewer.getSelectedRange();
@ -661,7 +680,7 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
try {
IRegion startLine = document.getLineInformationOfOffset(offset);
IRegion endLine = document.getLineInformationOfOffset(offset + length);
if (startLine != endLine && isBlockSelectionModeEnabled()) {
if (startLine != endLine && fEditor.isBlockSelectionModeEnabled()) {
return;
}
@ -730,7 +749,7 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
return;
}
if (!validateEditorInputState())
if (!fEditor.validateEditorInputState())
return;
final char character = event.character;
@ -764,7 +783,7 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
level.fUI = new EditorLinkedModeUI(model, sourceViewer);
level.fUI.setSimpleMode(true);
level.fUI.setExitPolicy(new ExitPolicy(closingCharacter, getEscapeCharacter(closingCharacter), fBracketLevelStack));
level.fUI.setExitPolicy(new ExitPolicy(closingCharacter, getEscapeCharacter(closingCharacter), fBracketLevelStack, sourceViewer));
level.fUI.setExitPosition(sourceViewer, offset + 2, 0, Integer.MAX_VALUE);
level.fUI.setCyclingMode(LinkedModeUI.CYCLE_NEVER);
level.fUI.enter();
@ -821,7 +840,6 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
return;
// remove brackets
final ISourceViewer sourceViewer = getSourceViewer();
final IDocument document = sourceViewer.getDocument();
if (document instanceof IDocumentExtension) {
IDocumentExtension extension = (IDocumentExtension) document;
@ -1284,7 +1302,7 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
protected CPairMatcher fBracketMatcher = new CPairMatcher(BRACKETS);
/** The bracket inserter. */
private final BracketInserter fBracketInserter = new BracketInserter();
private final BracketInserter fBracketInserter = new BracketInserter(this, false);
/** Listener to annotation model changes that updates the error tick in the tab image */
private CEditorErrorTickUpdater fCEditorErrorTickUpdater;
@ -2535,8 +2553,10 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi
fBracketInserter.setCloseStringsEnabled(closeStrings);
ISourceViewer sourceViewer = getSourceViewer();
if (sourceViewer instanceof ITextViewerExtension)
if (sourceViewer instanceof ITextViewerExtension) {
fBracketInserter.setSourceViewer(sourceViewer);
((ITextViewerExtension) sourceViewer).prependVerifyKeyListener(fBracketInserter);
}
if (isMarkingOccurrences())
installOccurrencesFinder(false);

View file

@ -67,6 +67,11 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
private String fPartitioning;
private final ICProject fProject;
/*
* boolean to skip "Smart Insert" mode check because Generic Editor doesn't have a "Smart Insert" mode.
*/
private boolean alwaysUseSmartMode = false;
/**
* Creates a new C auto indent strategy for the given document partitioning.
*
@ -78,6 +83,11 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
fProject = project;
}
public CAutoIndentStrategy(String partitioning, ICProject project, boolean alwaysUseSmartMode) {
this(partitioning, project);
this.alwaysUseSmartMode = alwaysUseSmartMode;
}
private int getBracketCount(IDocument d, int start, int end, boolean ignoreCloseBrackets) throws BadLocationException {
int bracketcount = 0;
while (start < end) {
@ -1151,6 +1161,9 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
private boolean computeSmartMode() {
IWorkbenchPage page = CUIPlugin.getActivePage();
if (page != null) {
if (alwaysUseSmartMode) {
return true;
}
IEditorPart part = page.getActiveEditor();
if (part instanceof MultiPageEditorPart) {
part= (IEditorPart)part.getAdapter(ITextEditorExtension3.class);

View file

@ -24,4 +24,5 @@ Export-Package: org.eclipse.lsp4e.cpp.language,
org.eclipse.lsp4e.cpp.language.cquery
Bundle-Activator: org.eclipse.lsp4e.cpp.language.Activator
Bundle-ActivationPolicy: lazy
Import-Package: org.eclipse.ui.texteditor
Import-Package: org.eclipse.ui.editors.text,
org.eclipse.ui.texteditor

View file

@ -62,4 +62,11 @@
class="org.eclipse.lsp4e.cpp.language.PreferenceInitializer">
</initializer>
</extension>
<extension
point="org.eclipse.ui.genericeditor.autoEditStrategies">
<autoEditStrategy
class="org.eclipse.lsp4e.cpp.language.AutoIndentStrategyCPP"
contentType="org.eclipse.lsp4e.languages.cpp">
</autoEditStrategy>
</extension>
</plugin>

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2018 Manish Khurana , Nathan Ridge and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.lsp4e.cpp.language;
import org.eclipse.cdt.internal.ui.text.CAutoIndentStrategy;
import org.eclipse.cdt.ui.CUIPlugin;
/*
* Class to re-use existing auto-indentation support of CEditor in Generic Editor of LSP4E-CPP.
*/
@SuppressWarnings("restriction")
public class AutoIndentStrategyCPP extends CAutoIndentStrategy {
public AutoIndentStrategyCPP() {
// TODO: Pass in the project so the auto edit strategy respects the project's preferences.
super(CUIPlugin.getDefault().getTextTools().getDocumentPartitioning(), null, true);
}
}

View file

@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.model.ICLanguageKeywords;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.internal.ui.editor.CEditor.BracketInserter;
import org.eclipse.cdt.internal.ui.text.CCodeScanner;
import org.eclipse.cdt.internal.ui.text.CCommentScanner;
import org.eclipse.cdt.internal.ui.text.CPreprocessorScanner;
@ -52,8 +53,10 @@ import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.lsp4e.cpp.language.cquery.CquerySemanticHighlights;
import org.eclipse.lsp4e.cpp.language.cquery.HighlightSymbol;
import org.eclipse.lsp4j.Range;
@ -62,6 +65,8 @@ import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.TextEditor;
/**
* Hack-ish reconciler to get some colors in the generic editor using the C/C++
@ -77,6 +82,7 @@ public class PresentationReconcilerCPP extends CPresentationReconciler {
private CqueryLineBackgroundListener fLineBackgroundListener = new CqueryLineBackgroundListener();
private ITextViewer textViewer;
private TextInputListenerCPP textInputListener;
private BracketInserter fBracketInserter;
public static Set<PresentationReconcilerCPP> presentationReconcilers = ConcurrentHashMap.newKeySet();
@ -345,6 +351,19 @@ public class PresentationReconcilerCPP extends CPresentationReconciler {
StyledText textWidget = textViewer.getTextWidget();
textWidget.addLineBackgroundListener(fLineBackgroundListener);
presentationReconcilers.add(this);
// Using asyncExec() to make sure that by the time Runnable runs,
// the Editor is active and we don't get a NPE.
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
// To provide bracket auto-completion support of CEditor in Generic Editor of LSP4E-CPP
TextEditor editor = (TextEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
fBracketInserter = new BracketInserter(editor, true);
fBracketInserter.setSourceViewer((SourceViewer) textViewer);
((TextViewer) textViewer).prependVerifyKeyListener(fBracketInserter);
}});
}
@Override
@ -352,6 +371,7 @@ public class PresentationReconcilerCPP extends CPresentationReconciler {
super.uninstall();
textViewer.getTextWidget().removeLineBackgroundListener(fLineBackgroundListener);
textViewer.removeTextInputListener(textInputListener);
((TextViewer) textViewer).removeVerifyKeyListener(fBracketInserter);
presentationReconcilers.remove(this);
}
}