ShellCommandCompleter implements Completer { @Override public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) { boolean allparsed; Set<Candidate> result = new TreeSet<>(); try { Result pr = ShellCommandParser.parse(line.line(), excludedCommands); if (pr.getFirstCommand() == HelpCommand.class || pr.getFirstCommand() == ShellHelpCommand.class) { pr = ShellCommandParser.parse(pr.getRemainingArgs(), excludedCommands); } if (pr.getRemainingArgs().length > 1) { } else { OptionGroup<ID> options; if (pr.getLastCommand() == null) { options = OptionIntrospector.introspect(CSLTool.class, AdditionalShellCommands.class); } else { options = OptionIntrospector.introspect(pr.getLastCommand()); } String[] ra = pr.getRemainingArgs(); allparsed = (ra == null || ra.length == 0); for (Option<ID> o : options.getCommands()) { Class<? extends Command> cmd = OptionIntrospector.getCommand(o.getId()); if (excludedCommands.contains(cmd)) { continue; } if (allparsed || o.getLongName().startsWith(ra[0])) { result.add(new Candidate(o.getLongName())); } } } if (pr.getLastCommand() != null && Completer.class.isAssignableFrom(pr.getLastCommand())) { Completer cc; try { cc = (Completer)pr.getLastCommand().newInstance(); } catch (Exception e) { throw new RuntimeException(e); } ParsedLine pl = new DefaultParser().new ArgumentList(line.line(), Arrays.asList(pr.getRemainingArgs()), pr.getRemainingArgs().length - 1, 0, 0, null, 0, 0); List<Candidate> ccl = new ArrayList<>(); cc.complete(reader, pl, ccl); result.addAll(ccl); } } catch (InvalidOptionException e) { } catch (IntrospectionException e) { throw new RuntimeException("Could not inspect command", e); } List<Candidate> resultList = new ArrayList<>(result); Collections.sort(resultList); candidates.addAll(resultList); } ShellCommandCompleter();  ShellCommandCompleter(List<Class<? extends Command>> excludedCommands); @Override void complete(LineReader reader, ParsedLine line, List<Candidate> candidates);  }
@Test public void topLevel() throws Exception { ArrayList<CharSequence> r = new ArrayList<>(); complete("", r); OptionGroup<ID> options = OptionIntrospector.introspect(CSLTool.class); OptionGroup<ID> optionsAdditional = OptionIntrospector.introspect( AdditionalShellCommands.class); int numCommands = options.getCommands().size() + optionsAdditional.getCommands().size() - 1; assertEquals(numCommands, r.size()); for (Option<ID> o : options.getCommands()) { assertTrue(r.contains(o.getLongName())); } for (Option<ID> o : optionsAdditional.getCommands()) { assertTrue(r.contains(o.getLongName())); } r = new ArrayList<>(); complete(" ", r); assertEquals(numCommands, r.size()); r = new ArrayList<>(); complete(" ", r); assertEquals(numCommands, r.size()); r = new ArrayList<>(); complete("bibl", r); assertEquals(1, r.size()); assertEquals("bibliography", r.get(0)); r = new ArrayList<>(); complete(" bibl", r); assertEquals(1, r.size()); assertEquals("bibliography", r.get(0)); r = new ArrayList<>(); complete("ge", r); assertEquals(1, r.size()); assertEquals("get", r.get(0)); r = new ArrayList<>(); complete("bla", r); assertEquals(0, r.size()); }
@Test public void subcommand() throws Exception { ArrayList<CharSequence> r = new ArrayList<>(); complete("get", r); OptionGroup<ID> options = OptionIntrospector.introspect( ShellGetCommand.class); assertEquals(options.getCommands().size(), r.size()); for (Option<ID> o : options.getCommands()) { assertTrue(r.contains(o.getLongName())); } r = new ArrayList<>(); complete("get ", r); assertEquals(options.getCommands().size(), r.size()); r = new ArrayList<>(); complete("get st", r); assertEquals(1, r.size()); assertEquals("style", r.get(0)); r = new ArrayList<>(); complete("get st", r); assertEquals(1, r.size()); assertEquals("style", r.get(0)); r = new ArrayList<>(); complete("get style", r); assertEquals(0, r.size()); r = new ArrayList<>(); complete("get bla", r); assertEquals(0, r.size()); }
@Test public void unknownAttributes() { ArrayList<CharSequence> r = new ArrayList<>(); complete("get style test", r); assertEquals(0, r.size()); r = new ArrayList<>(); complete("get style test test2", r); assertEquals(0, r.size()); }
@Test public void excludedCommands() throws Exception { List<Class<? extends Command>> cmds = new ArrayList<>(); cmds.add(ShellGetCommand.class); OptionGroup<ID> options = OptionIntrospector.introspect(CSLTool.class); OptionGroup<ID> optionsAdditional = OptionIntrospector.introspect( AdditionalShellCommands.class); int numCommands = options.getCommands().size() + optionsAdditional.getCommands().size() - 1; --numCommands; ArrayList<CharSequence> r = new ArrayList<>(); complete("", r, cmds); assertEquals(numCommands, r.size()); }
@Test public void help() throws Exception { ArrayList<CharSequence> r = new ArrayList<>(); complete("hel", r); assertEquals(1, r.size()); assertEquals("help", r.get(0)); r = new ArrayList<>(); complete("help ge", r); assertEquals(1, r.size()); assertEquals("get", r.get(0)); r = new ArrayList<>(); complete("help get st", r); assertEquals(1, r.size()); assertEquals("style", r.get(0)); r = new ArrayList<>(); complete("help get", r); OptionGroup<ID> options = OptionIntrospector.introspect(ShellGetCommand.class); assertEquals(options.getCommands().size(), r.size()); for (Option<ID> cmd : options.getCommands()) { assertTrue(r.contains(cmd.getLongName())); } r = new ArrayList<>(); complete("help", r); options = OptionIntrospector.introspect(CSLTool.class); OptionGroup<ID> optionsAdditional = OptionIntrospector.introspect( AdditionalShellCommands.class); int numCommands = options.getCommands().size() + optionsAdditional.getCommands().size() - 1; assertEquals(numCommands, r.size()); }
@Test public void completeFormats() { ArrayList<CharSequence> r = new ArrayList<>(); complete("set format h", r); assertEquals(1, r.size()); assertEquals("html", r.get(0)); r = new ArrayList<>(); complete("set format", r); assertEquals(5, r.size()); }