All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dflib.jjava.jupyter.kernel.util.SimpleAutoCompleter Maven / Gradle / Ivy

The newest version!
package org.dflib.jjava.jupyter.kernel.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * A utility class to implement a prefix based auto completion algorithm. It
 * is a good basic implementation for completing keywords or identifiers that
 * have already been parsed or are in the current cell.
 */
public class SimpleAutoCompleter {

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private Collection keywords;
        private boolean caseSensitive = true;
        private Comparator resultsSorter = null;

        private Builder() {
            this.keywords = new ArrayList<>();
        }

        public Builder withKeywords(String... keywords) {
            Collections.addAll(this.keywords, keywords);
            return this;
        }

        public Builder withKeywords(Collection keywords) {
            this.keywords.addAll(keywords);
            return this;
        }

        public Builder caseSensitive() {
            this.caseSensitive = true;
            return this;
        }

        public Builder caseInsensitive() {
            this.caseSensitive = false;
            return this;
        }

        private void addSorter(Comparator comparator) {
            this.resultsSorter = this.resultsSorter == null ? comparator : this.resultsSorter.thenComparing(comparator);
        }

        public Builder preferShort() {
            addSorter(SHORTER_BETTER);
            return this;
        }

        public Builder preferLong() {
            addSorter(LONGER_BETTER);
            return this;
        }

        public Builder preferSmallerChars() {
            addSorter(this.caseSensitive ? LOWER_ALPHA_BETTER_CASE : LOWER_ALPHA_BETTER_NO_CASE);
            return this;
        }

        public Builder preferLargerChars() {
            addSorter(this.caseSensitive ? HIGHER_ALPHA_BETTER_CASE : HIGHER_ALPHA_BETTER_NO_CASE);
            return this;
        }

        public SimpleAutoCompleter build() {
            return new SimpleAutoCompleter(
                    this.keywords,
                    this.caseSensitive,
                    this.resultsSorter
            );
        }
    }

    private static final Comparator SHORTER_BETTER = Comparator.comparingInt(String::length);
    private static final Comparator LONGER_BETTER = SHORTER_BETTER.reversed();

    private static final Comparator LOWER_ALPHA_BETTER_CASE = String::compareTo;
    private static final Comparator HIGHER_ALPHA_BETTER_CASE = LOWER_ALPHA_BETTER_CASE.reversed();

    private static final Comparator LOWER_ALPHA_BETTER_NO_CASE = String::compareToIgnoreCase;
    private static final Comparator HIGHER_ALPHA_BETTER_NO_CASE = LOWER_ALPHA_BETTER_NO_CASE.reversed();

    protected final SortedSet keywords;
    protected final Comparator resultsSorter;

    public SimpleAutoCompleter(Collection keywords, boolean caseSensitive, Comparator resultsSorter) {
        this.keywords = new TreeSet<>(caseSensitive ? String::compareTo : String::compareToIgnoreCase);
        this.keywords.addAll(keywords);
        this.resultsSorter = resultsSorter;
    }

    public List autocomplete(String prefix) {
        SortedSet results = keywords.subSet(prefix, prefix + Character.MAX_VALUE);
        List sortedResults = new ArrayList<>(results.size());
        sortedResults.addAll(results);
        if (this.resultsSorter != null && sortedResults.size() > 1)
            sortedResults.sort(this.resultsSorter);
        return sortedResults;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy