Skip to content

Commit 12b2441

Browse files
authored
#1147: Add support for completion suggestions for camel.jbang properties (#1161)
1 parent b35d5dc commit 12b2441

5 files changed

Lines changed: 79 additions & 15 deletions

File tree

src/main/java/com/github/cameltooling/idea/completion/property/CamelPropertyKeyCompletion.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.apache.camel.tooling.model.BaseOptionModel;
4747
import org.apache.camel.tooling.model.ComponentModel;
4848
import org.apache.camel.tooling.model.DataFormatModel;
49+
import org.apache.camel.tooling.model.JBangModel;
4950
import org.apache.camel.tooling.model.JsonMapper;
5051
import org.apache.camel.tooling.model.LanguageModel;
5152
import org.apache.camel.tooling.model.MainModel;
@@ -68,6 +69,14 @@ abstract class CamelPropertyKeyCompletion extends CompletionProvider<CompletionP
6869
* The prefix of all camel keys corresponding to the configuration of a language.
6970
*/
7071
static final String LANGUAGE_KEY_PREFIX = "camel.language";
72+
/**
73+
* The prefix of all camel keys corresponding to the configuration of a main.
74+
*/
75+
static final String MAIN_KEY_PREFIX = "camel.main";
76+
/**
77+
* The prefix of all camel keys corresponding to the configuration of a jbang.
78+
*/
79+
static final String JBANG_KEY_PREFIX = "camel.jbang";
7180
/**
7281
* The second part of the prefix of all camel keys corresponding to the configuration of a given component.
7382
*/
@@ -80,6 +89,14 @@ abstract class CamelPropertyKeyCompletion extends CompletionProvider<CompletionP
8089
* The second part of the prefix of all camel keys corresponding to the configuration of a given language.
8190
*/
8291
private static final String LANGUAGE_KEY_NAME = "language";
92+
/**
93+
* The second part of the prefix of all camel keys corresponding to the configuration of main options.
94+
*/
95+
private static final String MAIN_KEY_NAME = "main";
96+
/**
97+
* The second part of the prefix of all camel keys corresponding to the configuration of jbang options.
98+
*/
99+
private static final String JBANG_KEY_NAME = "jbang";
83100

84101
@Override
85102
protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context,
@@ -184,6 +201,8 @@ private List<LookupElement> getSuggestions(final PsiElement element) {
184201
return suggest(context, this::suggestDataFormats, this::suggestDataFormatOptions);
185202
case LANGUAGE_KEY_NAME:
186203
return suggest(context, this::suggestLanguages, this::suggestLanguageOptions);
204+
case JBANG_KEY_NAME:
205+
return suggestJBangOptions(context);
187206
default:
188207
return suggestMainOptions(context);
189208
}
@@ -221,6 +240,21 @@ private List<LookupElement> getSuggestions(final PsiElement element) {
221240
.collect(Collectors.toList());
222241
}
223242

243+
/**
244+
* @param context the context of the suggestion.
245+
* @return the suggestion of possible jbang options that could be extracted from the metadata.
246+
*/
247+
private @NotNull List<LookupElement> suggestJBangOptions(final SuggestionContext context) {
248+
final JBangModel jbangModel = context.getCamelCatalog().jbangModel();
249+
if (jbangModel == null) {
250+
return List.of();
251+
}
252+
return jbangModel.getOptions()
253+
.stream()
254+
.map(option -> asOptionNameSuggestion(context, option))
255+
.collect(Collectors.toList());
256+
}
257+
224258
/**
225259
* @param context the context of the suggestion.
226260
* @param name the name of the component/data format/language for which the options are expected.
@@ -398,6 +432,7 @@ private <T extends ArtifactModel<O>, O extends BaseOptionModel> List<LookupEleme
398432
.stream()
399433
.map(option -> asPrefixSuggestion(context, option))
400434
.forEach(result::add);
435+
result.add(asPrefixSuggestion(context, JBANG_KEY_PREFIX, () -> "Camel JBang"));
401436
return result;
402437
}
403438

src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<ul>
1414
<li>Only IDEA 2025 onwards is supported</li>
1515
<li>Upgraded to Camel 4.14.0</li>
16+
<li>Completion suggestion now supports camel.jbang properties</li>
1617
</ul>
1718
]]>
1819
</change-notes>

src/test/java/com/github/cameltooling/idea/completion/PropertiesPropertyKeyCompletionTestIT.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,18 @@ public void testMainOptionSuggestionFiltered() {
226226
assertDoesntContain(strings, "camel.main.configurations = ", "camel.main.auto-startup = ");
227227
}
228228

229+
/**
230+
* Ensures that jbang option suggestions can properly be proposed filtered.
231+
*/
232+
public void testJBangOptionSuggestionFiltered() {
233+
myFixture.configureByFiles(getFileName("jbang-options-filtered"));
234+
myFixture.completeBasic();
235+
List<String> strings = myFixture.getLookupElementStrings();
236+
assertNotNull(strings);
237+
assertContainsElements(strings, "camel.jbang.maven-central-enabled = ");
238+
assertDoesntContain(strings, "camel.jbang.console", "camel.jbang.repos");
239+
}
240+
229241
/**
230242
* Ensures that component name suggestions can properly be proposed non filtered.
231243
*/
@@ -490,7 +502,7 @@ private void testSuggestionWhenEmptyKey(String fileNamePrefix) {
490502
myFixture.completeBasic();
491503
List<String> strings = myFixture.getLookupElementStrings();
492504
assertNotNull(strings);
493-
assertContainsElements(strings, "camel.main.", "camel.component.", "camel.language.", "camel.dataformat.");
505+
assertContainsElements(strings, "camel.main.", "camel.component.", "camel.language.", "camel.dataformat.", "camel.jbang.");
494506
}
495507

496508
private String getFileName(String fileNamePrefix) {

src/test/java/com/github/cameltooling/idea/completion/YamlPropertyKeyCompletionTestIT.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,21 @@ public void testGroupNameSuggestionInstancesOfSimpleSuggestion() {
204204
);
205205
}
206206

207+
/**
208+
* Ensures that group name suggestions are only instances of {@link SimpleSuggestion}.
209+
*/
210+
public void testGroupNameSuggestionInstancesOfSimpleSuggestionJBang() {
211+
myFixture.configureByFiles(getFileName("full-first-key-with-separator"));
212+
myFixture.completeBasic();
213+
myFixture.type("jbang");
214+
LookupElement[] suggestions = myFixture.getLookupElements();
215+
assertNotNull(suggestions);
216+
assertTrue(
217+
"Only instances of SimpleSuggestion are expected",
218+
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof SimpleSuggestion)
219+
);
220+
}
221+
207222
/**
208223
* Ensures that main option suggestions can properly be proposed non filtered.
209224
*/
@@ -224,8 +239,8 @@ public void testMainOptionInstancesOfOptionSuggestion() {
224239
LookupElement[] suggestions = myFixture.getLookupElements();
225240
assertNotNull(suggestions);
226241
assertTrue(
227-
"Only instances of OptionSuggestion are expected",
228-
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof OptionSuggestion)
242+
"Only instances of OptionSuggestion are expected",
243+
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof OptionSuggestion)
229244
);
230245
}
231246

@@ -261,8 +276,8 @@ public void testComponentNameSuggestionInstancesOfSimpleSuggestion() {
261276
LookupElement[] suggestions = myFixture.getLookupElements();
262277
assertNotNull(suggestions);
263278
assertTrue(
264-
"Only instances of SimpleSuggestion are expected",
265-
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof SimpleSuggestion)
279+
"Only instances of SimpleSuggestion are expected",
280+
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof SimpleSuggestion)
266281
);
267282
}
268283

@@ -298,8 +313,8 @@ public void testComponentOptionSuggestionInstancesOfOptionSuggestion() {
298313
LookupElement[] suggestions = myFixture.getLookupElements();
299314
assertNotNull(suggestions);
300315
assertTrue(
301-
"Only instances of OptionSuggestion are expected",
302-
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof OptionSuggestion)
316+
"Only instances of OptionSuggestion are expected",
317+
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof OptionSuggestion)
303318
);
304319
}
305320

@@ -335,8 +350,8 @@ public void testLanguageNameSuggestionInstancesOfSimpleSuggestion() {
335350
LookupElement[] suggestions = myFixture.getLookupElements();
336351
assertNotNull(suggestions);
337352
assertTrue(
338-
"Only instances of SimpleSuggestion are expected",
339-
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof SimpleSuggestion)
353+
"Only instances of SimpleSuggestion are expected",
354+
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof SimpleSuggestion)
340355
);
341356
}
342357

@@ -374,8 +389,8 @@ public void testLanguageOptionSuggestionInstancesOfOptionSuggestion() {
374389
LookupElement[] suggestions = myFixture.getLookupElements();
375390
assertNotNull(suggestions);
376391
assertTrue(
377-
"Only instances of OptionSuggestion are expected",
378-
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof OptionSuggestion)
392+
"Only instances of OptionSuggestion are expected",
393+
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof OptionSuggestion)
379394
);
380395
}
381396

@@ -412,8 +427,8 @@ public void testDataFormatNameSuggestionInstancesOfSimpleSuggestion() {
412427
LookupElement[] suggestions = myFixture.getLookupElements();
413428
assertNotNull(suggestions);
414429
assertTrue(
415-
"Only instances of SimpleSuggestion are expected",
416-
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof SimpleSuggestion)
430+
"Only instances of SimpleSuggestion are expected",
431+
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof SimpleSuggestion)
417432
);
418433
}
419434

@@ -451,8 +466,8 @@ public void testDataFormatOptionSuggestionInstancesOfOptionSuggestion() {
451466
LookupElement[] suggestions = myFixture.getLookupElements();
452467
assertNotNull(suggestions);
453468
assertTrue(
454-
"Only instances of OptionSuggestion are expected",
455-
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof OptionSuggestion)
469+
"Only instances of OptionSuggestion are expected",
470+
Arrays.stream(suggestions).map(LookupElement::getObject).anyMatch(o -> o instanceof OptionSuggestion)
456471
);
457472
}
458473

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
camel.jbang.mav<caret>

0 commit comments

Comments
 (0)