Commit 83fffcff authored by Philip Makedonski's avatar Philip Makedonski
Browse files

+ improved completion, added separate kinds (values, types, all) on separate...

+ improved completion, added separate kinds (values, types, all) on separate panels, detail panel on selection, type signature hints, filtering, #255, #230
parent c923d675
Loading
Loading
Loading
Loading
+12 −0
Changes for plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/TDLtxUiModule.java: 12 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -3,8 +3,10 @@
 */
package org.etsi.mts.tdl.ui;

import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalPostProcessor;
import org.eclipse.xtext.ui.editor.contentassist.IContentAssistantFactory;
import org.eclipse.xtext.ui.editor.contentassist.IContentProposalProvider;
import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider;
import org.eclipse.xtext.ui.editor.syntaxcoloring.AbstractAntlrTokenToAttributeIdMapper;
@@ -15,6 +17,8 @@ import org.etsi.mts.tdl.ui.highlighting.TDLtxHighlightingConfiguration;
import org.etsi.mts.tdl.ui.highlighting.TDLtxTokenToAttributeIdMapper;
import org.etsi.mts.tdl.ui.hover.TDLtxHoverProvider;
import org.etsi.mts.tdl.ui.contentassist.DefaultCompletionProposalPostProcessor;
import org.etsi.mts.tdl.ui.contentassist.TDLtxContentAssistantFactory;
import org.etsi.mts.tdl.ui.contentassist.CyclingContentAssistProcessor;
/**
 * Use this class to register components to be used within the Eclipse IDE.
 */
@@ -47,6 +51,14 @@ public class TDLtxUiModule extends AbstractTDLtxUiModule {
//    	return DefaultCompletionProposalPostProcessor.class;
    }
    
    public Class<? extends IContentAssistantFactory> bindIContentAssistantFactory() {
        return TDLtxContentAssistantFactory.class;
    }
    
    public Class<? extends IContentAssistProcessor> bindIContentAssistProcessor() {
        return CyclingContentAssistProcessor.class;
    }
    
//    @Override
//    public void configure(Binder binder) {
//        super.configure(binder);
+69 −0
Changes for plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/CyclingContentAssistProcessor.java: 69 added lines, 0 removed lines.
Original line number Diff line number Diff line
package org.etsi.mts.tdl.ui.contentassist;

import java.util.Arrays;

import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ContentAssistEvent;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ICompletionListener;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal;
import org.eclipse.xtext.ui.editor.contentassist.XtextContentAssistProcessor;
import org.etsi.mts.tdl.DataInstance;
import org.etsi.mts.tdl.DataType;

public class CyclingContentAssistProcessor extends XtextContentAssistProcessor
        implements ICompletionListener {

    private enum Kind { ALL, TYPES, VALUES }
    private int iteration = 0;
    private ContentAssistant assistant;

    @Override
    public void assistSessionStarted(ContentAssistEvent e) { 
    	iteration = 0; 
        assistant = (ContentAssistant) e.assistant;
        updateStatusMessage();
 	}
    @Override
    public void assistSessionEnded(ContentAssistEvent e) { 
    	iteration = 0;
        assistant = null;
	}
    @Override
    public void selectionChanged(ICompletionProposal p, boolean smart) {}

    @Override
    public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
    	ICompletionProposal[] all = super.computeCompletionProposals(viewer, offset);
    	Kind kind = Kind.values()[iteration % Kind.values().length];
        iteration++;
        updateStatusMessage();   // now shows the kind of the *next* press
        return Arrays.stream(all)
                .filter(p -> matches(p, kind))
                .toArray(ICompletionProposal[]::new);
    }

    private boolean matches(ICompletionProposal p, Kind kind) {
        // classify using the kind you attached in step 1
        return kind == Kind.ALL || kindOf(p) == kind;
    }
	private Kind kindOf(ICompletionProposal p) {
		if (p instanceof ConfigurableCompletionProposal) {
			Object target = ((ConfigurableCompletionProposal) p).getAdditionalData(TDLtxProposalProvider.TARGET);
			if (target != null) {
				if (target instanceof DataType) {
					return Kind.TYPES;	
				} else if (target instanceof DataInstance) {
					return Kind.VALUES;
				}
			}
		}
		return Kind.ALL;
	}
	private void updateStatusMessage() {
        if (assistant == null) return;
        Kind next = Kind.values()[iteration % Kind.values().length];
        assistant.setStatusMessage("Press Ctrl+Space for " + next + " proposals");
    }
}
 No newline at end of file
+31 −0
Changes for plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/TDLtxContentAssistantFactory.java: 31 added lines, 0 removed lines.
Original line number Diff line number Diff line
package org.etsi.mts.tdl.ui.contentassist;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.xtext.ui.editor.contentassist.DefaultContentAssistantFactory;

import com.google.inject.Inject;
import com.google.inject.Provider;

public class TDLtxContentAssistantFactory extends DefaultContentAssistantFactory {
    @Inject
    private Provider<CyclingContentAssistProcessor> processorProvider;

    @Override
    public ContentAssistant createConfiguredAssistant(SourceViewerConfiguration config, ISourceViewer viewer) {
        ContentAssistant assistant = (ContentAssistant) super.createConfiguredAssistant(config, viewer);
        CyclingContentAssistProcessor processor = processorProvider.get();
        assistant.enableAutoActivation(true);
        assistant.setRepeatedInvocationMode(true);
        assistant.setStatusLineVisible(true);
        assistant.addCompletionListener(processor);
        assistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
        //TODO: indicate which is what
        assistant.setStatusMessage("Press Ctrl+Space for next proposal kind");
        // optional: custom trigger
        // assistant.setRepeatedInvocationTrigger(KeySequence.getInstance(...));
        return assistant;
    }
}
 No newline at end of file
+28 −4
Changes for plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/TDLtxProposalProvider.java: 28 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import org.etsi.mts.tdl.structuredobjectives.EventTemplateOccurrence;
 * on how to customize the content assistant.
 */
public class TDLtxProposalProvider extends AbstractTDLtxProposalProvider {
	public static final String TARGET = "target";
	public static boolean traceCompletions = false;
	public static boolean traceCompletionsInUI = false;

@@ -411,15 +412,34 @@ public class TDLtxProposalProvider extends AbstractTDLtxProposalProvider {
				if (ne instanceof SimpleDataType) {
					
				} else {
					List<String> members = Collections.emptyList();
					String usedSuffix = suffix;
					String signature = "";
					if (ne instanceof CollectionDataType) {
						usedSuffix = collectionSuffix;
						signature = "["+((CollectionDataType)ne).getItemType().getName()+"]";
					} else if (ne instanceof StructuredDataType){
						//TODO: make configurable, may slow down suggestions in large projects..
						//		or show in secondary detail window (how?) -> set additional info
						//		how is the hover provider hooked upstream?
						members = ((StructuredDataType)ne).allMembers().stream()
								.map(e-> e.getDataType().getName()+" "+e.getName())
								.toList();
						String memberNames = String.join(", ", members);
						signature = "("+memberNames+")";
					}
					if (unnamed) {
						acceptor.accept(createCompletionProposal(usedSuffix, new StyledString(usedSuffix).append(" : new anonymous instance", StyledString.DECORATIONS_STYLER), getImage(ne), 1200, "", context));
						ICompletionProposal proposal = createCompletionProposal(usedSuffix, new StyledString(usedSuffix).append(" : new anonymous instance", StyledString.DECORATIONS_STYLER), getImage(ne), 1200, "", context);
						//((ConfigurableCompletionProposal)proposal).setAdditionalProposalInfo("TODO: List types?");
						acceptor.accept(proposal);
					}
					if (named) {
						acceptor.accept(createCompletionProposal(prefix+ne.getName()+usedSuffix, new StyledString(prefix+ne.getName()+usedSuffix).append(" : new instance of type", StyledString.DECORATIONS_STYLER), getImage(ne), 1100, "", context));
						//TODO: document and push
						ICompletionProposal proposal = createCompletionProposal(prefix+ne.getName()+usedSuffix, new StyledString(prefix+ne.getName()+usedSuffix).append(" : new instance of type "+signature, StyledString.DECORATIONS_STYLER), getImage(ne), 1100, "", context);
						((ConfigurableCompletionProposal)proposal).setAdditionalProposalInfo(ne);
						((ConfigurableCompletionProposal)proposal).setAdditionalData(TARGET,ne);
						((ConfigurableCompletionProposal)proposal).setHover(getHover());
						acceptor.accept(proposal);
					}
				}
			} else if (ne instanceof Function && ((type == null) || ((Function) ne).getReturnType().conformsTo(type))) {
@@ -438,7 +458,11 @@ public class TDLtxProposalProvider extends AbstractTDLtxProposalProvider {
				}
			}
			if (accept) {
				acceptor.accept(createCompletionProposal(ne.getName(), new StyledString(ne.getName()), getImage(ne), 1000, "", context));
				ICompletionProposal proposal = createCompletionProposal(ne.getName(), new StyledString(ne.getName()), getImage(ne), 1000, "", context);
				((ConfigurableCompletionProposal)proposal).setAdditionalProposalInfo(ne);
				((ConfigurableCompletionProposal)proposal).setAdditionalData(TARGET,ne);
				((ConfigurableCompletionProposal)proposal).setHover(getHover());
				acceptor.accept(proposal);
			}
		}
	}
@@ -828,7 +852,7 @@ public class TDLtxProposalProvider extends AbstractTDLtxProposalProvider {


	public void completeDataElementUse_DataElement(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		if (model instanceof ParameterBinding || model instanceof MemberAssignment || model instanceof MemberReference || model instanceof DataReference) {
		if (model instanceof ParameterBinding || model instanceof MemberAssignment || model instanceof MemberReference || model instanceof DataReference || model instanceof Message) {
//			complete_ParameterBinding(model, ruleCall, context, acceptor);
			return;
		}