X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.ui%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fui%2Feditor%2Fcompletion%2FSCLCompletionProposal.java;fp=bundles%2Forg.simantics.scl.ui%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fui%2Feditor%2Fcompletion%2FSCLCompletionProposal.java;h=1fe100699a5561ff50109682e05e4f81d4c70506;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLCompletionProposal.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLCompletionProposal.java new file mode 100644 index 000000000..1fe100699 --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLCompletionProposal.java @@ -0,0 +1,221 @@ +package org.simantics.scl.ui.editor.completion; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.ICompletionProposalExtension; +import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2; +import org.eclipse.jface.text.contentassist.ICompletionProposalExtension3; +import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4; +import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Shell; +import org.simantics.scl.compiler.elaboration.modules.SCLValue; +import org.simantics.scl.ui.Activator; + +public class SCLCompletionProposal implements ICompletionProposal, ICompletionProposalExtension, ICompletionProposalExtension2, ICompletionProposalExtension3, ICompletionProposalExtension4, ICompletionProposalExtension5 { + + private static final Image PRIVATE = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/private_co.gif").createImage(); + private static final Image PUBLIC = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/public_co.gif").createImage(); + private static final Image CONST = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/container_obj.gif").createImage(); + private static final Image TYPE = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/typedef_obj.gif").createImage(); + + private final String content; + private final String name; + private final String module; + private final String documentation; + private int replacementOffset; + private String prefix; + private final SCLCompletionType completionType; + + public SCLCompletionProposal(SCLValue value, int replacementOffset, String prefix) { + this.name = value.getName().name; + this.module = value.getName().module; + this.documentation = value.getDocumentation(); + this.content = name + " :: " + value.getType() + " (" + module + ")"; + this.replacementOffset = replacementOffset; + this.prefix = prefix; +// System.out.println(prefix); + if (value.isPrivate()) + this.completionType = SCLCompletionType.PRIVATE; + else + this.completionType = SCLCompletionType.PUBLIC; + } + + public SCLCompletionProposal(String name, String module, SCLCompletionType completionType, int replacementOffset, String prefix) { + this.name = name; + this.module = module; + this.content = name + " (" + module + ")"; + this.documentation = null; + this.replacementOffset = replacementOffset; + this.prefix = prefix; + this.completionType = completionType; + } + + @Override + public void apply(IDocument document) { + + } + + @Override + public Point getSelection(IDocument document) { + return new Point(replacementOffset + getName().length(), 0); + } + + @Override + public String getAdditionalProposalInfo() { + return documentation; + } + + @Override + public String getDisplayString() { + return content; + } + + @Override + public Image getImage() { + switch (completionType) { + case PRIVATE: + return PRIVATE; + case PUBLIC: + return PUBLIC; + case CONST: + return CONST; + case TYPE: + return TYPE; + default: + return null; + } + } + + @Override + public IContextInformation getContextInformation() { + return null; + } + + @Override + public void apply(IDocument document, char trigger, int offset) { + } + + @Override + public boolean isValidFor(IDocument document, int offset) { + return validate(document, offset, null); + } + + @Override + public char[] getTriggerCharacters() { + return null; + } + + @Override + public int getContextInformationPosition() { + return 0; + } + + @Override + public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { + try { +// String replacement = getName().substring(offset - replacementOffset); + IDocument doc = viewer.getDocument(); + Point p = viewer.getSelectedRange(); +// System.out.println("selectedRange : " + p); +// System.out.println("prefix : " + prefix); +// int start = offset - prefix.length(); +// int end = prefix.length(); +// System.out.println("start : " + start + ", end : " + end); +// String sadd = doc.get(start, end); +// System.out.println("toReplace : " + sadd); + if (p.y > 0) { + doc.replace(p.x, p.y, ""); + doc.replace(offset, 0, getName()); + } else { + String currentText = doc.get(offset - prefix.length(), prefix.length()); + if (currentText.equals(getName())) + return; + doc.replace(offset - prefix.length(), prefix.length(), ""); + doc.replace(offset - prefix.length(), 0, getName()); + } + } catch (BadLocationException x) { + x.printStackTrace(); + } + } + + @Override + public void selected(ITextViewer viewer, boolean smartToggle) { + } + + @Override + public void unselected(ITextViewer viewer) { + } + + @Override + public boolean validate(IDocument document, int offset, DocumentEvent event) { + try { +// System.out.println("replacementOffset : " + replacementOffset); +// System.out.println("offset : " + offset); + boolean a = offset >= replacementOffset; + boolean b = offset < replacementOffset + getName().length(); + String s = document.get(replacementOffset, offset - replacementOffset); + prefix = s; + String d = getName();//.substring(0, offset - prefixStart); + boolean c = d.toLowerCase().startsWith(s.toLowerCase()); + return a && b && c; + } catch (BadLocationException x) { + //x.printStackTrace(); + return false; + } + } + + @Override + public IInformationControlCreator getInformationControlCreator() { + return CREATOR; + } + + private static final IInformationControlCreator CREATOR = new IInformationControlCreator() { + + @Override + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent); + } + }; + + @Override + public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) { + return getName(); + } + + @Override + public int getPrefixCompletionStart(IDocument document, int completionOffset) { + return replacementOffset - prefix.length(); + } + + @Override + public boolean isAutoInsertable() { + return true; + } + + @Override + public Object getAdditionalProposalInfo(IProgressMonitor monitor) { + return documentation; + } + + public String getName() { + return name; + } + + public boolean isPrivate() { + return SCLCompletionType.PRIVATE == completionType; + } + + public String getModule() { + return module; + } +}