/** * Return a copy of this context, as if the first {@literal nbWords} were not present */ public CompletionContext drop(int nbWords) { return new CompletionContext(new ArrayList<String>(words.subList(nbWords, words.size())), wordIndex-nbWords, position); } }
public String currentWordUpToCursor() { String currentWord = currentWord(); return currentWord != null ? currentWord.substring(0, getPosition()) : null; }
/** * Gather completion proposals given some (incomplete) input the user has already typed * in. When and how this method is invoked is implementation specific and decided by the * actual user interface. */ public List<CompletionProposal> complete(CompletionContext context) { String prefix = context.upToCursor(); List<CompletionProposal> candidates = new ArrayList<>(); candidates.addAll(commandsStartingWith(prefix)); String best = findLongestCommand(prefix); if (best != null) { CompletionContext argsContext = context.drop(best.split(" ").length); // Try to complete arguments MethodTarget methodTarget = methodTargets.get(best); Method method = methodTarget.getMethod(); List<MethodParameter> parameters = Utils.createMethodParameters(method).collect(Collectors.toList()); for (ParameterResolver resolver : parameterResolvers) { for (int index = 0; index < parameters.size(); index++) { MethodParameter parameter = parameters.get(index); if (resolver.supports(parameter)) { resolver.complete(parameter, argsContext).stream().forEach(candidates::add); } } } } return candidates; }
public String upToCursor() { String start = words.subList(0, wordIndex).stream().collect(Collectors.joining(" ")); if (wordIndex < words.size()) { if (!start.isEmpty()) { start += " "; } start += currentWord().substring(0, position); } return start; }
@Override public List<CompletionProposal> complete(MethodParameter parameter, CompletionContext context) { JCommander jCommander = createJCommander(parameter); List<String> words = context.getWords(); try { jCommander.parseWithoutValidation(words.toArray(new String[words.size()])); } catch (ParameterException ignored) { // Exception here certainly means current buffer is not parseable in full. // Better to bail out now. return Collections.emptyList(); } return streamAllJCommanderDescriptions(jCommander) .filter(p -> !p.isAssigned()) .flatMap(p -> Arrays.stream(p.getParameter().names())) .map(CompletionProposal::new) .collect(Collectors.toList()); } }
@Override public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) { CompletingParsedLine cpl = (line instanceof CompletingParsedLine) ? ((CompletingParsedLine) line) : t -> t; CompletionContext context = new CompletionContext(sanitizeInput(line.words()), line.wordIndex(), line.wordCursor()); List<CompletionProposal> proposals = shell.complete(context); proposals.stream() .map(p -> new Candidate( p.dontQuote() ? p.value() : cpl.emit(p.value()).toString(), p.displayText(), p.category(), p.description(), null, null, true) ) .forEach(candidates::add); }