]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLCompletionProposal.java
Fixed SCLCompletionProposal.validate to allow complete matches as well
[simantics/platform.git] / bundles / org.simantics.scl.ui / src / org / simantics / scl / ui / editor / completion / SCLCompletionProposal.java
1 package org.simantics.scl.ui.editor.completion;
2
3 import org.eclipse.core.runtime.IProgressMonitor;
4 import org.eclipse.jface.text.BadLocationException;
5 import org.eclipse.jface.text.DefaultInformationControl;
6 import org.eclipse.jface.text.DocumentEvent;
7 import org.eclipse.jface.text.IDocument;
8 import org.eclipse.jface.text.IInformationControl;
9 import org.eclipse.jface.text.IInformationControlCreator;
10 import org.eclipse.jface.text.ITextViewer;
11 import org.eclipse.jface.text.contentassist.ICompletionProposal;
12 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension;
13 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
14 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension3;
15 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;
16 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5;
17 import org.eclipse.jface.text.contentassist.IContextInformation;
18 import org.eclipse.swt.graphics.Image;
19 import org.eclipse.swt.graphics.Point;
20 import org.eclipse.swt.widgets.Shell;
21 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
22 import org.simantics.scl.ui.Activator;
23
24 public class SCLCompletionProposal implements ICompletionProposal, ICompletionProposalExtension, ICompletionProposalExtension2, ICompletionProposalExtension3, ICompletionProposalExtension4, ICompletionProposalExtension5 {
25     
26     private static final Image PRIVATE = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/private_co.gif").createImage();
27     private static final Image PUBLIC = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/public_co.gif").createImage();
28     private static final Image CONST = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/container_obj.gif").createImage();
29     private static final Image TYPE = Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/typedef_obj.gif").createImage();
30     
31     private final String content;
32     private final String name;
33     private final String module;
34     private final String documentation;
35     private int replacementOffset;
36     private String prefix;
37     private final SCLCompletionType completionType;
38     
39     public SCLCompletionProposal(SCLValue value, int replacementOffset, String prefix) {
40         String tempName = value.getName().name;
41         String tempModule = value.getName().module;
42         int p = tempName.lastIndexOf('.');
43         if(p >= 0) {
44             tempModule = tempModule + "." + tempName.substring(0, p);
45             tempName = tempName.substring(p+1);
46         }
47         this.name = tempName;
48         this.module = tempModule;
49         this.documentation = value.getDocumentation();
50         this.content = name + " :: " + value.getType() + "  (" + module + ")";
51         this.replacementOffset = replacementOffset;
52         this.prefix = prefix;
53 //        System.out.println(prefix);
54         if (value.isPrivate())
55             this.completionType = SCLCompletionType.PRIVATE;
56         else
57             this.completionType = SCLCompletionType.PUBLIC;
58     }
59
60     public SCLCompletionProposal(String name, String module, SCLCompletionType completionType, int replacementOffset, String prefix) {
61         this.name = name;
62         this.module = module;
63         this.content = name + " (" + module + ")";
64         this.documentation = null;
65         this.replacementOffset = replacementOffset;
66         this.prefix = prefix;
67         this.completionType = completionType;
68     }
69
70     @Override
71     public void apply(IDocument document) {
72
73     }
74
75     @Override
76     public Point getSelection(IDocument document) {
77         return new Point(replacementOffset + getName().length(), 0);
78     }
79
80     @Override
81     public String getAdditionalProposalInfo() {
82         return documentation;
83     }
84
85     @Override
86     public String getDisplayString() {
87         return content;
88     }
89
90     @Override
91     public Image getImage() {
92         switch (completionType) {
93         case PRIVATE:
94             return PRIVATE;
95         case PUBLIC:
96             return PUBLIC;
97         case CONST:
98             return CONST;
99         case TYPE:
100             return TYPE;
101         default:
102             return null;
103         }
104     }
105
106     @Override
107     public IContextInformation getContextInformation() {
108         return null;
109     }
110
111     @Override
112     public void apply(IDocument document, char trigger, int offset) {
113     }
114
115     @Override
116     public boolean isValidFor(IDocument document, int offset) {
117         return validate(document, offset, null);
118     }
119
120     @Override
121     public char[] getTriggerCharacters() {
122         return null;
123     }
124
125     @Override
126     public int getContextInformationPosition() {
127         return 0;
128     }
129
130     @Override
131     public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
132         try {
133 //            String replacement = getName().substring(offset - replacementOffset);
134             IDocument doc = viewer.getDocument();
135             Point p = viewer.getSelectedRange();
136 //            System.out.println("selectedRange : " + p);
137 //            System.out.println("prefix : " + prefix);
138 //            int start = offset - prefix.length();
139 //            int end = prefix.length();
140 //            System.out.println("start : " + start + ", end : " + end);
141 //            String sadd = doc.get(start, end);
142 //            System.out.println("toReplace : " + sadd);
143             if (p.y > 0) {
144                 doc.replace(p.x, p.y, "");
145                 doc.replace(offset, 0, getName());
146             } else {
147                 String currentText = doc.get(offset - prefix.length(), prefix.length());
148                 if (currentText.equals(getName()))
149                     return;
150                 doc.replace(offset - prefix.length(), prefix.length(), "");
151                 doc.replace(offset - prefix.length(), 0, getName());
152             }
153         } catch (BadLocationException x) {
154             x.printStackTrace();
155         }
156     }
157
158     @Override
159     public void selected(ITextViewer viewer, boolean smartToggle) {
160     }
161
162     @Override
163     public void unselected(ITextViewer viewer) {
164     }
165
166     @Override
167     public boolean validate(IDocument document, int offset, DocumentEvent event) {
168         try {
169             String n = getName();
170             //System.out.println(n + " (" + n.length() + ") " + replacementOffset + " " + offset);
171             boolean a = offset >= replacementOffset;
172             boolean b = offset <= replacementOffset + n.length();
173             String s = document.get(replacementOffset, offset - replacementOffset);
174             prefix = s;
175             //System.out.println("prefix: " + s + " - " + prefix);
176             boolean c = n.toLowerCase().startsWith(s.toLowerCase());
177             //System.out.println("matches: " + a + " " + b + " " + c);
178             return a && b && c;
179         } catch (BadLocationException x) {
180             //x.printStackTrace();
181             return false;
182         }
183     }
184
185     @Override
186     public IInformationControlCreator getInformationControlCreator() {
187         return CREATOR;
188     }
189     
190     private static final IInformationControlCreator CREATOR = new IInformationControlCreator() {
191         
192         @Override
193         public IInformationControl createInformationControl(Shell parent) {
194             return new DefaultInformationControl(parent);
195         }
196     };
197
198     @Override
199     public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
200         return getName();
201     }
202
203     @Override
204     public int getPrefixCompletionStart(IDocument document, int completionOffset) {
205         return replacementOffset - prefix.length();
206     }
207
208     @Override
209     public boolean isAutoInsertable() {
210         return true;
211     }
212
213     @Override
214     public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
215         return documentation;
216     }
217
218     public String getName() {
219         return name;
220     }
221     
222     public boolean isPrivate() {
223         return SCLCompletionType.PRIVATE == completionType;
224     }
225
226     public String getModule() {
227         return module;
228     }
229 }