Skip to content

Commit 2aad36f

Browse files
committed
auto_completion added using tree
1 parent 3ee2402 commit 2aad36f

6 files changed

Lines changed: 555 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.pde.internal.ui.editor.p2inf;
15+
16+
import org.eclipse.osgi.util.NLS;
17+
18+
public class Messages extends NLS {
19+
private static final String BUNDLE_NAME = Messages.class.getPackageName() + ".messages"; //$NON-NLS-1$
20+
public static String P2InfHeader_provides;
21+
public static String P2InfHeader_requires;
22+
public static String P2InfHeader_metaRequirements;
23+
public static String P2InfHeader_properties;
24+
public static String P2InfHeader_update;
25+
public static String P2InfHeader_instructions;
26+
public static String P2InfHeader_units;
27+
28+
public static String P2InfHeader_filter;
29+
public static String P2InfHeader_greedy;
30+
public static String P2InfHeader_matchExp;
31+
public static String P2InfHeader_multiple;
32+
public static String P2InfHeader_name;
33+
public static String P2InfHeader_namespace;
34+
public static String P2InfHeader_optional;
35+
public static String P2InfHeader_range;
36+
public static String P2InfHeader_version;
37+
static {
38+
// initialize resource bundle
39+
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
40+
}
41+
42+
private Messages() {
43+
}
44+
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.pde.internal.ui.editor.p2inf;
15+
16+
import java.util.ArrayList;
17+
import java.util.List;
18+
19+
import org.eclipse.jface.text.BadLocationException;
20+
import org.eclipse.jface.text.IDocument;
21+
import org.eclipse.jface.text.ITextViewer;
22+
import org.eclipse.jface.text.contentassist.ICompletionProposal;
23+
import org.eclipse.pde.internal.ui.editor.PDESourcePage;
24+
import org.eclipse.pde.internal.ui.editor.contentassist.TypeCompletionProposal;
25+
import org.eclipse.pde.internal.ui.editor.contentassist.TypePackageCompletionProcessor;
26+
27+
public class P2InfContentAssistProcessor extends TypePackageCompletionProcessor {
28+
29+
protected PDESourcePage fSourcePage;
30+
private SuggestionNode root;
31+
private static final String[] COMMON_PARTS = { Messages.P2InfHeader_namespace, Messages.P2InfHeader_name,
32+
Messages.P2InfHeader_version, Messages.P2InfHeader_range, Messages.P2InfHeader_matchExp,
33+
Messages.P2InfHeader_greedy, Messages.P2InfHeader_optional, Messages.P2InfHeader_multiple,
34+
Messages.P2InfHeader_filter };
35+
36+
public P2InfContentAssistProcessor(PDESourcePage sourcePage) {
37+
fSourcePage = sourcePage;
38+
buildSuggestionTree();
39+
}
40+
41+
private static class SuggestionNode {
42+
String key;
43+
boolean index;
44+
boolean terminal;
45+
List<SuggestionNode> children = new ArrayList<>();
46+
SuggestionNode(String key) {
47+
this.key = key;
48+
}
49+
SuggestionNode index() {
50+
this.index = true;
51+
return this;
52+
}
53+
SuggestionNode terminal() {
54+
this.terminal = true;
55+
return this;
56+
}
57+
SuggestionNode addChild(SuggestionNode node) {
58+
children.add(node);
59+
return this;
60+
}
61+
}
62+
63+
// Build Suggestion Tree
64+
private void buildSuggestionTree() {
65+
root = new SuggestionNode("root"); //$NON-NLS-1$
66+
67+
SuggestionNode provides = new SuggestionNode(Messages.P2InfHeader_provides);
68+
SuggestionNode requires = new SuggestionNode(Messages.P2InfHeader_requires);
69+
SuggestionNode metaReq = new SuggestionNode(Messages.P2InfHeader_metaRequirements);
70+
SuggestionNode properties = new SuggestionNode(Messages.P2InfHeader_properties);
71+
SuggestionNode update = new SuggestionNode(Messages.P2InfHeader_update);
72+
SuggestionNode instructions = new SuggestionNode(Messages.P2InfHeader_instructions);
73+
SuggestionNode units = new SuggestionNode(Messages.P2InfHeader_units);
74+
75+
root.addChild(provides).addChild(requires).addChild(metaReq).addChild(properties).addChild(update)
76+
.addChild(instructions).addChild(units);
77+
78+
// Level-1 structures
79+
addIndexedParts(provides);
80+
addIndexedParts(requires);
81+
addIndexedParts(metaReq);
82+
addIndexedParts(properties);
83+
addIndexedParts(update);
84+
addIndexedParts(instructions);
85+
86+
// units.{#}
87+
SuggestionNode unitsIndex = new SuggestionNode("{#}").index(); //$NON-NLS-1$
88+
units.addChild(unitsIndex);
89+
SuggestionNode unitRequires = new SuggestionNode(Messages.P2InfHeader_requires);
90+
SuggestionNode unitProvides = new SuggestionNode(Messages.P2InfHeader_provides);
91+
SuggestionNode unitProperties = new SuggestionNode(Messages.P2InfHeader_properties);
92+
SuggestionNode unitMetaRed = new SuggestionNode(Messages.P2InfHeader_metaRequirements);
93+
SuggestionNode unitUpdate = new SuggestionNode(Messages.P2InfHeader_update);
94+
SuggestionNode unitInstructions = new SuggestionNode(Messages.P2InfHeader_instructions);
95+
unitsIndex.addChild(unitRequires);
96+
unitsIndex.addChild(unitProvides);
97+
unitsIndex.addChild(unitProperties);
98+
unitsIndex.addChild(unitMetaRed);
99+
unitsIndex.addChild(unitUpdate);
100+
unitsIndex.addChild(unitInstructions);
101+
102+
addIndexedParts(unitRequires);
103+
addIndexedParts(unitProvides);
104+
addIndexedParts(unitProperties);
105+
addIndexedParts(unitMetaRed);
106+
addIndexedParts(unitUpdate);
107+
addIndexedParts(unitInstructions);
108+
}
109+
110+
private void addIndexedParts(SuggestionNode parent) {
111+
SuggestionNode indexNode = new SuggestionNode("{#}").index(); //$NON-NLS-1$
112+
parent.addChild(indexNode);
113+
for (String p : COMMON_PARTS) {
114+
indexNode.addChild(new SuggestionNode(p).terminal());
115+
}
116+
}
117+
118+
@Override
119+
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
120+
IDocument doc = fSourcePage.getDocumentProvider().getDocument(fSourcePage.getInputContext().getInput());
121+
try {
122+
int lineNum = doc.getLineOfOffset(offset);
123+
int lineStart = doc.getLineOffset(lineNum);
124+
String value = doc.get(lineStart, offset - lineStart).trim();
125+
List<TypeCompletionProposal> completions = new ArrayList<>();
126+
List<SuggestionNode> suggestions = getSuggestions(value);
127+
for (SuggestionNode node : suggestions) {
128+
String proposalText;
129+
if (node.index) {
130+
proposalText = value + "0."; //$NON-NLS-1$
131+
} else if (node.terminal) {
132+
proposalText = value + node.key;
133+
} else {
134+
proposalText = value + node.key + "."; //$NON-NLS-1$
135+
}
136+
completions
137+
.add(new TypeCompletionProposal(proposalText, null, proposalText, lineStart, value.length()));
138+
}
139+
return completions.toArray(ICompletionProposal[]::new);
140+
} catch (BadLocationException e) {
141+
e.printStackTrace();
142+
}
143+
return null;
144+
}
145+
146+
private List<SuggestionNode> getSuggestions(String line) {
147+
if (line.isEmpty()) {
148+
return root.children;
149+
}
150+
String[] tokens = line.split("\\."); //$NON-NLS-1$
151+
SuggestionNode current = root;
152+
for (String token : tokens) {
153+
if (token.isEmpty())
154+
continue;
155+
SuggestionNode next = null;
156+
for (SuggestionNode child : current.children) {
157+
if (child.index && token.matches("\\d+")) { //$NON-NLS-1$
158+
next = child;
159+
break;
160+
}
161+
if (!child.index && child.key.equals(token)) {
162+
next = child;
163+
break;
164+
}
165+
}
166+
if (next == null)
167+
return new ArrayList<>();
168+
current = next;
169+
}
170+
return current.children;
171+
}
172+
}
173+

ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/p2inf/P2InfSourcePage.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,16 @@
1313
*******************************************************************************/
1414
package org.eclipse.pde.internal.ui.editor.p2inf;
1515

16+
import org.eclipse.jdt.ui.PreferenceConstants;
17+
import org.eclipse.jface.preference.IPreferenceStore;
1618
import org.eclipse.jface.viewers.ILabelProvider;
1719
import org.eclipse.jface.viewers.ITreeContentProvider;
1820
import org.eclipse.pde.internal.ui.editor.KeyValueSourcePage;
1921
import org.eclipse.pde.internal.ui.editor.PDEFormEditor;
22+
import org.eclipse.pde.internal.ui.editor.text.ChangeAwareSourceViewerConfiguration;
23+
import org.eclipse.pde.internal.ui.editor.text.IColorManager;
24+
import org.eclipse.ui.editors.text.EditorsUI;
25+
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
2026

2127
public class P2InfSourcePage extends KeyValueSourcePage {
2228

@@ -38,4 +44,13 @@ public ITreeContentProvider createOutlineContentProvider() {
3844
public void updateSelection(Object object) {
3945
}
4046

47+
@Override
48+
protected ChangeAwareSourceViewerConfiguration createSourceViewerConfiguration(IColorManager colorManager) {
49+
IPreferenceStore store = PreferenceConstants.getPreferenceStore();
50+
IPreferenceStore generalTextStore = EditorsUI.getPreferenceStore();
51+
IPreferenceStore combinedStore = new ChainedPreferenceStore(new IPreferenceStore[] { store, generalTextStore });
52+
this.setPreferenceStore(combinedStore);
53+
return new P2infViewerConfiguration(colorManager, combinedStore, this);
54+
}
55+
4156
}

0 commit comments

Comments
 (0)