/*
 * Copyright (c) 2002-2018, the original author or authors.
 *
 * This software is distributable under the BSD license. See the terms of the
 * BSD license in the documentation provided with this software.
 *
 * https://opensource.org/licenses/BSD-3-Clause
 */
package jdk.internal.org.jline.reader.impl.completer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

import jdk.internal.org.jline.reader.Candidate;
import jdk.internal.org.jline.reader.Completer;
import jdk.internal.org.jline.reader.LineReader;
import jdk.internal.org.jline.reader.ParsedLine;

A Completer implementation that invokes a child completer using the appropriate separator argument. This can be used instead of the individual completers having to know about argument parsing semantics.
Author:Marc Prud'hommeaux, Jason Dillon
Since:2.3
/** * A {@link Completer} implementation that invokes a child completer using the appropriate <i>separator</i> argument. * This can be used instead of the individual completers having to know about argument parsing semantics. * * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a> * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> * @since 2.3 */
public class ArgumentCompleter implements Completer { private final List<Completer> completers = new ArrayList<>(); private boolean strict = true;
Create a new completer.
Params:
  • completers – The embedded completers
/** * Create a new completer. * * @param completers The embedded completers */
public ArgumentCompleter(final Collection<Completer> completers) { Objects.requireNonNull(completers); this.completers.addAll(completers); }
Create a new completer.
Params:
  • completers – The embedded completers
/** * Create a new completer. * * @param completers The embedded completers */
public ArgumentCompleter(final Completer... completers) { this(Arrays.asList(completers)); }
If true, a completion at argument index N will only succeed if all the completions from 0-(N-1) also succeed.
Params:
  • strict – the strict flag
/** * If true, a completion at argument index N will only succeed * if all the completions from 0-(N-1) also succeed. * * @param strict the strict flag */
public void setStrict(final boolean strict) { this.strict = strict; }
Returns whether a completion at argument index N will success if all the completions from arguments 0-(N-1) also succeed.
Returns: True if strict.
Since:2.3
/** * Returns whether a completion at argument index N will success * if all the completions from arguments 0-(N-1) also succeed. * * @return True if strict. * @since 2.3 */
public boolean isStrict() { return this.strict; }
Returns the list of completers used inside this ArgumentCompleter.
Returns:The list of completers.
Since:2.3
/** * Returns the list of completers used inside this <code>ArgumentCompleter</code>. * @return The list of completers. * @since 2.3 */
public List<Completer> getCompleters() { return completers; } public void complete(LineReader reader, ParsedLine line, final List<Candidate> candidates) { Objects.requireNonNull(line); Objects.requireNonNull(candidates); if (line.wordIndex() < 0) { return; } List<Completer> completers = getCompleters(); Completer completer; // if we are beyond the end of the completers, just use the last one if (line.wordIndex() >= completers.size()) { completer = completers.get(completers.size() - 1); } else { completer = completers.get(line.wordIndex()); } // ensure that all the previous completers are successful before allowing this completer to pass (only if strict). for (int i = 0; isStrict() && (i < line.wordIndex()); i++) { Completer sub = completers.get(i >= completers.size() ? (completers.size() - 1) : i); List<? extends CharSequence> args = line.words(); String arg = (args == null || i >= args.size()) ? "" : args.get(i).toString(); List<Candidate> subCandidates = new LinkedList<>(); sub.complete(reader, new ArgumentLine(arg, arg.length()), subCandidates); boolean found = false; for (Candidate cand : subCandidates) { if (cand.value().equals(arg)) { found = true; break; } } if (!found) { return; } } completer.complete(reader, line, candidates); } public static class ArgumentLine implements ParsedLine { private final String word; private final int cursor; public ArgumentLine(String word, int cursor) { this.word = word; this.cursor = cursor; } @Override public String word() { return word; } @Override public int wordCursor() { return cursor; } @Override public int wordIndex() { return 0; } @Override public List<String> words() { return Collections.singletonList(word); } @Override public String line() { return word; } @Override public int cursor() { return cursor; } } }