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:
parent
ac81db720c
commit
1983d41afb
6 changed files with 101 additions and 15 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue