src/jdk.internal.le/share/classes/jdk/internal/jline/console/completer/AggregateCompleter.java
branchJDK-8200758-branch
changeset 57072 29604aafa0fc
parent 57071 94e9270166f0
parent 52979 7384e00d5860
child 57076 687505381ca4
equal deleted inserted replaced
57071:94e9270166f0 57072:29604aafa0fc
     1 /*
       
     2  * Copyright (c) 2002-2016, the original author or authors.
       
     3  *
       
     4  * This software is distributable under the BSD license. See the terms of the
       
     5  * BSD license in the documentation provided with this software.
       
     6  *
       
     7  * http://www.opensource.org/licenses/bsd-license.php
       
     8  */
       
     9 package jdk.internal.jline.console.completer;
       
    10 
       
    11 import java.util.ArrayList;
       
    12 import java.util.Arrays;
       
    13 import java.util.Collection;
       
    14 import java.util.LinkedList;
       
    15 import java.util.List;
       
    16 
       
    17 import static jdk.internal.jline.internal.Preconditions.checkNotNull;
       
    18 
       
    19 /**
       
    20  * Completer which contains multiple completers and aggregates them together.
       
    21  *
       
    22  * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
       
    23  * @since 2.3
       
    24  */
       
    25 public class AggregateCompleter
       
    26     implements Completer
       
    27 {
       
    28     private final List<Completer> completers = new ArrayList<Completer>();
       
    29 
       
    30     public AggregateCompleter() {
       
    31         // empty
       
    32     }
       
    33 
       
    34     /**
       
    35      * Construct an AggregateCompleter with the given collection of completers.
       
    36      * The completers will be used in the iteration order of the collection.
       
    37      *
       
    38      * @param completers the collection of completers
       
    39      */
       
    40     public AggregateCompleter(final Collection<Completer> completers) {
       
    41         checkNotNull(completers);
       
    42         this.completers.addAll(completers);
       
    43     }
       
    44 
       
    45     /**
       
    46      * Construct an AggregateCompleter with the given completers.
       
    47      * The completers will be used in the order given.
       
    48      *
       
    49      * @param completers the completers
       
    50      */
       
    51     public AggregateCompleter(final Completer... completers) {
       
    52         this(Arrays.asList(completers));
       
    53     }
       
    54 
       
    55     /**
       
    56      * Retrieve the collection of completers currently being aggregated.
       
    57      *
       
    58      * @return the aggregated completers
       
    59      */
       
    60     public Collection<Completer> getCompleters() {
       
    61         return completers;
       
    62     }
       
    63 
       
    64     /**
       
    65      * Perform a completion operation across all aggregated completers.
       
    66      *
       
    67      * @see Completer#complete(String, int, java.util.List)
       
    68      * @return the highest completion return value from all completers
       
    69      */
       
    70     public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
       
    71         // buffer could be null
       
    72         checkNotNull(candidates);
       
    73 
       
    74         List<Completion> completions = new ArrayList<Completion>(completers.size());
       
    75 
       
    76         // Run each completer, saving its completion results
       
    77         int max = -1;
       
    78         for (Completer completer : completers) {
       
    79             Completion completion = new Completion(candidates);
       
    80             completion.complete(completer, buffer, cursor);
       
    81 
       
    82             // Compute the max cursor position
       
    83             max = Math.max(max, completion.cursor);
       
    84 
       
    85             completions.add(completion);
       
    86         }
       
    87 
       
    88         // Append candidates from completions which have the same cursor position as max
       
    89         for (Completion completion : completions) {
       
    90             if (completion.cursor == max) {
       
    91                 candidates.addAll(completion.candidates);
       
    92             }
       
    93         }
       
    94 
       
    95         return max;
       
    96     }
       
    97 
       
    98     /**
       
    99      * @return a string representing the aggregated completers
       
   100      */
       
   101     @Override
       
   102     public String toString() {
       
   103         return getClass().getSimpleName() + "{" +
       
   104             "completers=" + completers +
       
   105             '}';
       
   106     }
       
   107 
       
   108     private class Completion
       
   109     {
       
   110         public final List<CharSequence> candidates;
       
   111 
       
   112         public int cursor;
       
   113 
       
   114         public Completion(final List<CharSequence> candidates) {
       
   115             checkNotNull(candidates);
       
   116             this.candidates = new LinkedList<CharSequence>(candidates);
       
   117         }
       
   118 
       
   119         public void complete(final Completer completer, final String buffer, final int cursor) {
       
   120             checkNotNull(completer);
       
   121             this.cursor = completer.complete(buffer, cursor, candidates);
       
   122         }
       
   123     }
       
   124 }