[KARAF-2805] Fix completion in console so that the CommandLine is actually useful
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/e2bf5cec Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/e2bf5cec Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/e2bf5cec Branch: refs/heads/master Commit: e2bf5cecae23ea514588f802c6dffac81074939c Parents: 09be4b1 Author: Guillaume Nodet <[email protected]> Authored: Thu Mar 6 17:50:46 2014 +0100 Committer: Guillaume Nodet <[email protected]> Committed: Thu Mar 6 17:50:46 2014 +0100 ---------------------------------------------------------------------- .../impl/action/command/ArgumentCompleter.java | 46 +-------------- .../shell/impl/console/CommandsCompleter.java | 59 +++++++++++++++++-- .../impl/console/commands/help/HelpCommand.java | 41 +------------ .../support/completers/ArgumentCommandLine.java | 61 ++++++++++++++++++++ .../support/completers/StringsCompleter.java | 6 +- 5 files changed, 123 insertions(+), 90 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/e2bf5cec/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java ---------------------------------------------------------------------- diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java index 2868e6f..2e8fca3 100644 --- a/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java +++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java @@ -35,6 +35,7 @@ import org.apache.karaf.shell.api.action.Option; import org.apache.karaf.shell.api.console.CommandLine; import org.apache.karaf.shell.api.console.Completer; import org.apache.karaf.shell.api.console.Session; +import org.apache.karaf.shell.support.completers.ArgumentCommandLine; import org.apache.karaf.shell.support.completers.FileCompleter; import org.apache.karaf.shell.support.completers.NullCompleter; import org.apache.karaf.shell.support.completers.StringsCompleter; @@ -275,14 +276,12 @@ public class ArgumentCompleter implements Completer { comp = argsCompleters.get(indexArg >= argsCompleters.size() ? argsCompleters.size() - 1 : indexArg); } - int ret = comp.complete(session, new ArgumentCommandLine(list.getCursorArgument(), argpos), candidates); + int pos = comp.complete(session, list, candidates); - if (ret == -1) { + if (pos == -1) { return -1; } - int pos = ret + (list.getBufferPosition() - argpos); - /** * Special case: when completing in the middle of a line, and the * area under the cursor is a delimiter, then trim any delimiters @@ -343,43 +342,4 @@ public class ArgumentCompleter implements Completer { return Character.isWhitespace(buffer.charAt(pos)); } - static class ArgumentCommandLine implements CommandLine { - private final String argument; - private final int position; - - ArgumentCommandLine(String argument, int position) { - this.argument = argument; - this.position = position; - } - - @Override - public int getCursorArgumentIndex() { - return 0; - } - - @Override - public String getCursorArgument() { - return argument; - } - - @Override - public int getArgumentPosition() { - return position; - } - - @Override - public String[] getArguments() { - return new String[] { argument }; - } - - @Override - public int getBufferPosition() { - return position; - } - - @Override - public String getBuffer() { - return argument; - } - } } http://git-wip-us.apache.org/repos/asf/karaf/blob/e2bf5cec/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java ---------------------------------------------------------------------- diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java index d73af34..2a513cb 100644 --- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java +++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java @@ -36,6 +36,7 @@ import org.apache.karaf.shell.api.console.Completer; import org.apache.karaf.shell.api.console.Session; import org.apache.karaf.shell.api.console.SessionFactory; import org.apache.karaf.shell.support.completers.AggregateCompleter; +import org.apache.karaf.shell.support.completers.ArgumentCommandLine; import org.apache.karaf.shell.support.completers.StringsCompleter; /** @@ -46,6 +47,12 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers private final SessionFactory factory; private final Map<String, Completer> globalCompleters = new HashMap<String, Completer>(); private final Map<String, Completer> localCompleters = new HashMap<String, Completer>(); + private final Completer aliasesCompleter = new SimpleCommandCompleter() { + @Override + protected Collection<String> getNames(Session session) { + return getAliases(session); + } + }; private final List<Command> commands = new ArrayList<Command>(); public CommandsCompleter(SessionFactory factory) { @@ -95,7 +102,7 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers } } List<Completer> compl = new ArrayList<Completer>(); - compl.add(new StringsCompleter(getAliases(session))); + compl.add(aliasesCompleter); compl.addAll(allCompleters[0].values()); int res = new AggregateCompleter(compl).complete(session, commandLine, candidates); Collections.sort(candidates); @@ -103,7 +110,7 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers } List<Completer> compl = new ArrayList<Completer>(); - compl.add(new StringsCompleter(getAliases(session))); + compl.add(aliasesCompleter); compl.addAll(allCompleters[0].values()); int res = new AggregateCompleter(compl).complete(session, commandLine, candidates); Collections.sort(candidates); @@ -205,13 +212,13 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers Completer cl = command.getCompleter(true); if (cg == null) { if (Session.SCOPE_GLOBAL.equals(command.getScope())) { - cg = new StringsCompleter(new String[] { command.getName() }); + cg = new FixedSimpleCommandCompleter(Arrays.asList(command.getName())); } else { - cg = new StringsCompleter(new String[] { key, command.getName() }); + cg = new FixedSimpleCommandCompleter(Arrays.asList(key, command.getName())); } } if (cl == null) { - cl = new StringsCompleter(new String[] { command.getName() }); + cl = new FixedSimpleCommandCompleter(Arrays.asList(command.getName())); } global.put(key, cg); local.put(key, cl); @@ -252,5 +259,47 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers return aliases; } + static abstract class SimpleCommandCompleter implements Completer { + + @Override + public int complete(Session session, CommandLine commandLine, List<String> candidates) { + String[] args = commandLine.getArguments(); + int argIndex = commandLine.getCursorArgumentIndex(); + StringsCompleter completer = new StringsCompleter(getNames(session)); + if (argIndex == 0) { + int res = completer.complete(session, new ArgumentCommandLine(args[argIndex], commandLine.getArgumentPosition()), candidates); + if (res > -1) { + res += commandLine.getBufferPosition() - commandLine.getArgumentPosition(); + } + return res; + } else if (!verifyCompleter(session, completer, args[0])) { + return -1; + } + return 0; + } + + protected abstract Collection<String> getNames(Session session); + + private boolean verifyCompleter(Session session, Completer completer, String argument) { + List<String> candidates = new ArrayList<String>(); + return completer.complete(session, new ArgumentCommandLine(argument, argument.length()), candidates) != -1 && !candidates.isEmpty(); + } + + } + + static class FixedSimpleCommandCompleter extends SimpleCommandCompleter { + + private final Collection<String> names; + + FixedSimpleCommandCompleter(Collection<String> names) { + this.names = names; + } + + @Override + protected Collection<String> getNames(Session session) { + return names; + } + } + } http://git-wip-us.apache.org/repos/asf/karaf/blob/e2bf5cec/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java ---------------------------------------------------------------------- diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java index 4afa149..3b9ae33 100644 --- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java +++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/HelpCommand.java @@ -33,6 +33,7 @@ import org.apache.karaf.shell.api.console.Registry; import org.apache.karaf.shell.api.console.Session; import org.apache.karaf.shell.api.console.SessionFactory; import org.apache.karaf.shell.support.CommandException; +import org.apache.karaf.shell.support.completers.ArgumentCommandLine; import org.apache.karaf.shell.support.completers.StringsCompleter; import static org.apache.karaf.shell.support.ansi.SimpleAnsi.COLOR_DEFAULT; @@ -182,44 +183,4 @@ public class HelpCommand implements Command { return help; } - static class ArgumentCommandLine implements CommandLine { - private final String argument; - private final int position; - - ArgumentCommandLine(String argument, int position) { - this.argument = argument; - this.position = position; - } - - @Override - public int getCursorArgumentIndex() { - return 0; - } - - @Override - public String getCursorArgument() { - return argument; - } - - @Override - public int getArgumentPosition() { - return position; - } - - @Override - public String[] getArguments() { - return new String[] { argument }; - } - - @Override - public int getBufferPosition() { - return position; - } - - @Override - public String getBuffer() { - return argument; - } - } - } http://git-wip-us.apache.org/repos/asf/karaf/blob/e2bf5cec/shell/core/src/main/java/org/apache/karaf/shell/support/completers/ArgumentCommandLine.java ---------------------------------------------------------------------- diff --git a/shell/core/src/main/java/org/apache/karaf/shell/support/completers/ArgumentCommandLine.java b/shell/core/src/main/java/org/apache/karaf/shell/support/completers/ArgumentCommandLine.java new file mode 100644 index 0000000..663601a --- /dev/null +++ b/shell/core/src/main/java/org/apache/karaf/shell/support/completers/ArgumentCommandLine.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.karaf.shell.support.completers; + +import org.apache.karaf.shell.api.console.CommandLine; + +public class ArgumentCommandLine implements CommandLine { + private final String argument; + private final int position; + + public ArgumentCommandLine(String argument, int position) { + this.argument = argument; + this.position = position; + } + + @Override + public int getCursorArgumentIndex() { + return 0; + } + + @Override + public String getCursorArgument() { + return argument; + } + + @Override + public int getArgumentPosition() { + return position; + } + + @Override + public String[] getArguments() { + return new String[] { argument }; + } + + @Override + public int getBufferPosition() { + return position; + } + + @Override + public String getBuffer() { + return argument; + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/e2bf5cec/shell/core/src/main/java/org/apache/karaf/shell/support/completers/StringsCompleter.java ---------------------------------------------------------------------- diff --git a/shell/core/src/main/java/org/apache/karaf/shell/support/completers/StringsCompleter.java b/shell/core/src/main/java/org/apache/karaf/shell/support/completers/StringsCompleter.java index 1317095..85b4fdf 100644 --- a/shell/core/src/main/java/org/apache/karaf/shell/support/completers/StringsCompleter.java +++ b/shell/core/src/main/java/org/apache/karaf/shell/support/completers/StringsCompleter.java @@ -82,9 +82,11 @@ public class StringsCompleter // buffer could be null assert candidates != null; - String buffer = commandLine.getBuffer(); + String buffer = commandLine.getCursorArgument(); if (buffer == null) { buffer = ""; + } else { + buffer = buffer.substring(0, commandLine.getArgumentPosition()); } if (!caseSensitive) { buffer = buffer.toLowerCase(); @@ -108,6 +110,6 @@ public class StringsCompleter candidates.set(0, candidates.get(0) + " "); } - return candidates.isEmpty() ? -1 : 0; + return candidates.isEmpty() ? -1 : commandLine.getBufferPosition() - commandLine.getArgumentPosition(); } }
