blob: 0c65eab3550415835cfc07ee6bc9f11ef5d41f2f [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2009, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.ui.editors;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension6;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.ltk.ui.sourceediting.assist.SimpleCompletionProposal;
import org.eclipse.statet.r.core.RSymbolComparator;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.r.ui.sourceediting.RAssistInvocationContext;
@NonNullByDefault
public class RSimpleCompletionProposal extends SimpleCompletionProposal {
public static class RHelpTopicCompletionProposal extends RSimpleCompletionProposal
implements ICompletionProposalExtension6 {
private final int relevance;
private final String packages;
public RHelpTopicCompletionProposal(final RAssistInvocationContext context,
final String replacementString, final String packages, final int replacementOffset,
final int relevance) {
super(context, replacementString, replacementOffset);
this.relevance= relevance;
this.packages= packages;
}
@Override
public int getRelevance() {
return this.relevance;
}
@Override
public Image getImage() {
return RUI.getImage(RUI.IMG_OBJ_R_HELP_TOPIC);
}
@Override
public StyledString getStyledDisplayString() {
final StyledString s= new StyledString(getReplacementString());
if (this.packages != null) {
s.append(QUALIFIER_SEPARATOR, StyledString.QUALIFIER_STYLER);
s.append(this.packages, StyledString.QUALIFIER_STYLER);
}
return s;
}
}
public RSimpleCompletionProposal(final RAssistInvocationContext context,
final String replacementString, final int replacementOffset) {
super(context, replacementString, replacementOffset);
}
@Override
protected String getPluginId() {
return RUI.BUNDLE_ID;
}
@Override
protected int computeReplacementLength(final int replacementOffset, final Point selection, final int caretOffset, final boolean overwrite) {
// keep in synch with RElementCompletionProposal
final int end= Math.max(caretOffset, selection.x + selection.y);
if (overwrite) {
final RElementCompletionProposal.ApplyData data= new RElementCompletionProposal.ApplyData(
(RAssistInvocationContext) getInvocationContext() );
final RHeuristicTokenScanner scanner= data.getScanner();
scanner.configure(data.getDocument());
final IRegion word= scanner.findRWord(end, false, true);
if (word != null) {
return (word.getOffset() + word.getLength() - replacementOffset);
}
}
return (end - replacementOffset);
}
@Override
public boolean isAutoInsertable() {
return false;
}
@Override
public boolean validate(final IDocument document, final int offset, final DocumentEvent event) {
// keep in synch with RElementCompletionProposal
try {
int start= getReplacementOffset();
int length= offset - getReplacementOffset();
if (length > 0 && document.getChar(start) == '`') {
start++;
length--;
}
if (length > 0 && document.getChar(start+length-1) == '`') {
length--;
}
final String prefix= document.get(start, length);
final String replacement= getReplacementString();
if (new RSymbolComparator.PrefixPattern(prefix).matches(replacement)) {
return true;
}
}
catch (final BadLocationException e) {
// ignore concurrently modified document
}
return false;
}
}