diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index bbfe750876..82b81cd0b1 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -31,6 +31,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/800[#800]: Fix infinite recursion in Sonar start/stop on macOS * https://github.com/devonfw/IDEasy/issues/1716[#1716]: Add commandlet for Claude Code CLI * https://github.com/devonfw/IDEasy/issues/1844[#1844]: Fix vscode installation hanging indefinitely in WSL Linux environments +* https://github.com/devonfw/IDEasy/issues/1950[#1950]: Fix exit autocompletion The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/44?closed=1[milestone 2026.05.001]. diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java index 9667c9e269..48991a73c0 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/ShellCommandlet.java @@ -6,7 +6,6 @@ import java.util.Iterator; import org.fusesource.jansi.AnsiConsole; -import org.jline.reader.Completer; import org.jline.reader.EndOfFileException; import org.jline.reader.LineReader; import org.jline.reader.LineReaderBuilder; @@ -14,8 +13,6 @@ import org.jline.reader.Parser; import org.jline.reader.UserInterruptException; import org.jline.reader.impl.DefaultParser; -import org.jline.reader.impl.completer.AggregateCompleter; -import org.jline.reader.impl.completer.StringsCompleter; import org.jline.terminal.Terminal; import org.jline.terminal.TerminalBuilder; import org.jline.widget.AutosuggestionWidgets; @@ -43,6 +40,8 @@ public final class ShellCommandlet extends Commandlet { private static final int RC_EXIT = 987654321; + private static final String EXIT_COMMAND = "exit"; + /** * The constructor. * @@ -72,9 +71,7 @@ protected void doRun() { try { Parser parser = new DefaultParser(); try (Terminal terminal = TerminalBuilder.builder().build()) { - // initialize our own completer here and add exit as an autocompletion option - Completer completer = new AggregateCompleter( - new StringsCompleter("exit"), new IdeCompleter((AbstractIdeContext) this.context)); + IdeCompleter completer = new IdeCompleter((AbstractIdeContext) this.context); LineReader reader = LineReaderBuilder.builder().terminal(terminal).completer(completer).parser(parser) .variable(LineReader.LIST_MAX, AUTOCOMPLETER_MAX_RESULTS).build(); @@ -95,7 +92,7 @@ protected void doRun() { String prompt = context.getCwd() + "$ ide "; line = reader.readLine(prompt, rightPrompt, (MaskingCallback) null, null); line = line.trim(); - if (line.equals("exit")) { + if (EXIT_COMMAND.equals(line)) { return; } reader.getHistory().add(line); @@ -132,7 +129,7 @@ protected void doRun() { */ private int runCommand(String args) { - if ("exit".equals(args) || "quit".equals(args)) { + if (EXIT_COMMAND.equals(args) || "quit".equals(args)) { return RC_EXIT; } String[] arguments = args.split(" ", 0); diff --git a/cli/src/main/java/com/devonfw/tools/ide/completion/IdeCompleter.java b/cli/src/main/java/com/devonfw/tools/ide/completion/IdeCompleter.java index 3051cf309c..ade9d6866d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/completion/IdeCompleter.java +++ b/cli/src/main/java/com/devonfw/tools/ide/completion/IdeCompleter.java @@ -15,6 +15,8 @@ */ public class IdeCompleter implements Completer { + private static final String EXIT_COMMAND = "exit"; + private final AbstractIdeContext context; /** @@ -30,6 +32,14 @@ public IdeCompleter(AbstractIdeContext context) { @Override public void complete(LineReader reader, ParsedLine commandLine, List candidates) { + + String currentWord = commandLine.word(); + int wordIndex = commandLine.wordIndex(); + + if (wordIndex == 0 && !currentWord.isEmpty() && EXIT_COMMAND.startsWith(currentWord)) { + candidates.add(new Candidate(EXIT_COMMAND)); + } + List words = commandLine.words(); CliArguments args = CliArguments.ofCompletion(words.toArray(String[]::new)); List completion = this.context.complete(args, true);