Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions cli/src/main/java/com/devonfw/tools/ide/cli/CliArgument.java
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,19 @@ public String toString() {
return this.arg;
}

public static CliArgument of(int completionIdx, String... args) {
CliArgument current = END;
int last = args.length - 1;

for (int argsIdx = last; argsIdx >= 0; argsIdx--) {
String arg = args[argsIdx];
boolean completionArg = argsIdx == completionIdx;

current = new CliArgument(arg, current, completionArg);
}

return current.createStart();
}
/**
* @param args the command-line arguments (e.g. from {@code main} method).
* @return the first {@link CliArgument} of the parsed arguments or {@code null} if for empty arguments.
Expand Down
8 changes: 8 additions & 0 deletions cli/src/main/java/com/devonfw/tools/ide/cli/CliArguments.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ public class CliArguments implements Iterator<CliArgument> {

private boolean splitShortOpts;

public CliArguments(int completionIdx, String... args) {
this(CliArgument.of(completionIdx, args));
}

/**
* The constructor.
*
Expand Down Expand Up @@ -165,6 +169,10 @@ public String toString() {
return this.currentArg.getArgs();
}

public static CliArguments of(int completionIdx, String... args) {
return new CliArguments(completionIdx, args);
}

/**
* @param args the {@link CliArgument#of(String...) command line arguments}.
* @return the {@link CliArguments}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ default LocalToolCommandlet getRequiredLocalToolCommandlet(String name) {
throw new IllegalArgumentException("The commandlet " + name + " is not a LocalToolCommandlet!");
}

public abstract void collectCompletionCandidates(CliArguments arguments,
CompletionCandidateCollector collector);

/**
* @param arguments the {@link CliArguments}.
* @param collector the optional {@link CompletionCandidateCollector}. Will be {@code null} if no argument {@link CliArguments#isCompletion() completion}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,28 @@ public Commandlet getCommandletByFirstKeyword(String keyword) {
return this.firstKeywordMap.get(keyword);
}

@Override
public void collectCompletionCandidates(CliArguments arguments,
CompletionCandidateCollector collector) {
CliArgument current = arguments.current();
if (current.isStart()) {
current = current.getNext();
}
if (current.isEnd()) {
return;
}

for (Commandlet cmd : this.getCommandlets()) {
if (!cmd.isIdeHomeRequired() || this.context.getIdeHome() != null) {
for (Property<?> property : cmd.getProperties()) {
if (property instanceof KeywordProperty keyword) {
keyword.apply(arguments, this.context, cmd, collector);
}
}
}
}
}

@Override
public Iterator<Commandlet> findCommandlet(CliArguments arguments, CompletionCandidateCollector collector) {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
package com.devonfw.tools.ide.completion;

import java.util.List;

/**
* Candidate for auto-completion.
*
* @param text the text to suggest (CLI argument value).
* @param description the description of the candidate.
*/
public record CompletionCandidate(String text, String description) implements Comparable<CompletionCandidate> {
public record CompletionCandidate(List<String> entries,
String description,
boolean complete) implements Comparable<CompletionCandidate> {

@Override
public int compareTo(CompletionCandidate o) {

return this.text.compareTo(o.text);
return this.text().compareTo(o.text());
}

public String text() {
return String.join(" ", this.entries);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ public interface CompletionCandidateCollector {
* @param commandlet the {@link Commandlet} owning the {@link Property}.
* @return the {@link CompletionCandidate} for the given parameters.
*/
default CompletionCandidate createCandidate(String text, String description, Property<?> property, Commandlet commandlet) {
default CompletionCandidate createCandidate(String text, String description,
Property<?> property, Commandlet commandlet, boolean complete) {

if (description == null) {
// compute description from property + commandlet like in HelpCommandlet?
}
CompletionCandidate candidate = new CompletionCandidate(text, description);
CompletionCandidate candidate = new CompletionCandidate(Arrays.asList(text.split(" ")),
description, complete);
return candidate;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public void add(String text, String description, Property<?> property, Commandle
}
}

CompletionCandidate candidate = createCandidate(text, description, property, commandlet);
CompletionCandidate candidate = this.createCandidate(text, description, property, commandlet,
!text.endsWith("="));
this.candidates.add(candidate);
LOG.trace("Added {} for auto-completion of property {}.{}", candidate, commandlet, property);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public void complete(LineReader reader, ParsedLine commandLine, List<Candidate>
List<CompletionCandidate> completion = this.context.complete(args, true);
int i = 0;
for (CompletionCandidate candidate : completion) {
candidates.add(new Candidate(candidate.text(), candidate.text(), null, null, null, null, true, i++));
candidates.add(new Candidate(candidate.text(), candidate.text(), null, null, null, null,
candidate.complete(), i++));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1442,7 +1442,10 @@ public List<CompletionCandidate> complete(CliArguments arguments, boolean includ
property.apply(arguments, this, cc, collector);
}
}
Iterator<Commandlet> commandletIterator = this.commandletManager.findCommandlet(arguments, collector);

this.commandletManager.collectCompletionCandidates(arguments, collector);

Iterator<Commandlet> commandletIterator = this.commandletManager.findCommandlet(arguments, null);
CliArgument current = arguments.current();
if (current.isCompletion() && current.isCombinedShortOption()) {
collector.add(current.get(), null, null, null);
Expand All @@ -1461,7 +1464,7 @@ private void completeCommandlet(CliArguments arguments, Commandlet cmd, Completi

LOG.trace("Trying to match arguments for auto-completion for commandlet {}", cmd.getName());
Iterator<Property<?>> valueIterator = cmd.getValues().iterator();
valueIterator.next(); // skip first property since this is the keyword property that already matched to find the commandlet
Property<?> lastValueProperty = null;
List<Property<?>> properties = cmd.getProperties();
// we are creating our own list of options and remove them when matched to avoid duplicate suggestions
List<Property<?>> optionProperties = new ArrayList<>(properties.size());
Expand Down Expand Up @@ -1499,18 +1502,30 @@ private void completeCommandlet(CliArguments arguments, Commandlet cmd, Completi
}
}
} else {
if (currentArgument.isCompletion() && currentArgument.get().isEmpty()
&& !arguments.isEndOptions()) {
for (Property<?> option : optionProperties) {
option.apply(arguments, this, cmd, collector);
}
}

Property<?> valueProperty = null;
if (valueIterator.hasNext()) {
Property<?> valueProperty = valueIterator.next();
valueProperty = valueIterator.next();
boolean success = valueProperty.apply(arguments, this, cmd, collector);
if (!success) {
LOG.trace("Completion cannot match any further.");
return;
}
} else if (lastValueProperty != null && lastValueProperty.isMultiValued()) {
valueProperty = lastValueProperty;
} else {
LOG.trace("No value left for completion.");
return;
}
}

arguments.next();
currentArgument = arguments.current();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public Boolean parse(String valueAsString, IdeContext context) {
return result;
}

@Override
protected void completeValue(String arg, IdeContext contextual, Commandlet commandlet,
CompletionCandidateCollector collector) {}

private Boolean parse(String valueAsString) {

if (valueAsString == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.devonfw.tools.ide.property;

import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.validation.PropertyValidator;

Expand Down Expand Up @@ -41,4 +43,8 @@ public String parse(String valueAsString, IdeContext context) {

return valueAsString;
}

@Override
protected void completeValue(String arg, IdeContext contextual, Commandlet commandlet,
CompletionCandidateCollector collector) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.devonfw.tools.ide.property;

import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
import com.devonfw.tools.ide.context.IdeContext;
import java.util.List;

public class MvnArgProperty extends StringProperty {
private static final List<String> MAVEN_GOALS = List.of(
"clean",
"compile",
"dependency:list",
"dependency:tree",
"deploy",
"exec:java",
"generate-resources",
"generate-sources",
"help:effective-settings",
"install",
"integration-test",
"package",
"post-clean",
"post-integration-test",
"prepare-package",
"pre-clean",
"pre-integration-test",
"process-resources",
"process-sources",
"site",
"site-deploy",
"test",
"test-compile",
"validate",
"verify"
);

public MvnArgProperty(String name, String alias) {
super(name, true, true, alias);
}

@Override
protected void completeValue(String arg, IdeContext context, Commandlet commandlet,
CompletionCandidateCollector collector) {
for (String goal : MAVEN_GOALS) {
if (goal.startsWith(arg)) {
collector.add(goal, null, this, commandlet);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.devonfw.tools.ide.property;

import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.validation.PropertyValidator;

Expand Down Expand Up @@ -49,4 +51,7 @@ public Long parse(String valueAsString, IdeContext context) {
}
}

@Override
protected void completeValue(String arg, IdeContext contextual, Commandlet commandlet,
CompletionCandidateCollector collector) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,7 @@ protected void complete(String normalizedName, CliArgument argument, CliArgument
* @param commandlet the {@link Commandlet} owning this {@link Property}.
* @param collector the {@link CompletionCandidateCollector}.
*/
protected void completeValue(String arg, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {

}
protected abstract void completeValue(String arg, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector);

/**
* @param nameOrAlias the potential {@link #getName() name} or {@link #getAlias() alias} to match.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.devonfw.tools.ide.property;

import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.validation.PropertyValidator;

Expand Down Expand Up @@ -59,6 +61,10 @@ public String parse(String valueAsString, IdeContext context) {
return valueAsString;
}

@Override
protected void completeValue(String arg, IdeContext contextual, Commandlet commandlet,
CompletionCandidateCollector collector) {}

/**
* @return the {@link #getValue() value} as null-safe {@link String} array.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private void completeVersion(VersionIdentifier version2complete, ToolCommandlet
List<CompletionCandidate> candidates = collector.getCandidates();
Collections.reverse(candidates);
CompletionCandidate latest = collector.createCandidate(text + VersionSegment.PATTERN_MATCH_ANY_STABLE_VERSION,
"Latest stable matching version", this, commandlet);
"Latest stable matching version", this, commandlet, true);
if (candidates.isEmpty()) {
candidates.add(latest);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ public ToolCommandlet(IdeContext context, String tool, Set<Tag> tags) {
this.tags = tags;
addKeyword(tool);
this.arguments = new StringProperty("", false, true, "args");
initProperties();
}

/**
Expand Down
34 changes: 34 additions & 0 deletions cli/src/main/java/com/devonfw/tools/ide/tool/mvn/Mvn.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.devonfw.tools.ide.process.ProcessContext;
import com.devonfw.tools.ide.process.ProcessMode;
import com.devonfw.tools.ide.process.ProcessResult;
import com.devonfw.tools.ide.property.FlagProperty;
import com.devonfw.tools.ide.property.MvnArgProperty;
import com.devonfw.tools.ide.step.Step;
import com.devonfw.tools.ide.tool.LocalToolCommandlet;
import com.devonfw.tools.ide.tool.ToolCommandlet;
Expand Down Expand Up @@ -62,6 +64,20 @@ public class Mvn extends LocalToolCommandlet {

private static final VariableSyntax VARIABLE_SYNTAX = VariableSyntax.SQUARE;

private final FlagProperty alsoMake;
private final FlagProperty alsoMakeDependents;
private final FlagProperty failAtEnd;
private final FlagProperty failFast;
private final FlagProperty threads;

private final FlagProperty skipTests;
private final FlagProperty deployAtEnd;

private final FlagProperty execMainClass;
private final FlagProperty execArgs;

private final MvnArgProperty goals;

/**
* The constructor.
*
Expand All @@ -70,6 +86,24 @@ public class Mvn extends LocalToolCommandlet {
public Mvn(IdeContext context) {

super(context, "mvn", Set.of(Tag.JAVA, Tag.BUILD));

this.alsoMake = this.add(new FlagProperty("--also-make", false, "-am"));
this.alsoMakeDependents = this.add(new FlagProperty("--also-make-dependents", false, "-amd"));
this.failAtEnd = this.add(new FlagProperty("--fail-at-end", false, "-fae"));
this.failFast = this.add(new FlagProperty("--fail-fast", false, "-ff"));
this.threads = this.add(new FlagProperty("--threads", false, "-t"));

this.skipTests = this.add(new FlagProperty("--define skipTests", false, "-DskipTests"));
this.deployAtEnd = this.add(new FlagProperty("--define deployAtEnd", false, "-DdeployAtEnd"));

this.execMainClass = this.add(
new FlagProperty("--define exec.mainClass=", false, "-Dexec.mainClass=")
);
this.execArgs = this.add(
new FlagProperty("--define exec.args=", false, "-Dexec.args=")
);

this.goals = this.add(new MvnArgProperty("goals", ""));
}

@Override
Expand Down
Loading
Loading