KeyMap { public static Collection<String> range(String range) { String[] keys = range.split("-"); if (keys.length != 2) { return null; } keys[0] = translate(keys[0]); keys[1] = translate(keys[1]); if (keys[0].length() != keys[1].length()) { return null; } String pfx; if (keys[0].length() > 1) { pfx = keys[0].substring(0, keys[0].length() - 1); if (!keys[1].startsWith(pfx)) { return null; } } else { pfx = ""; } char c0 = keys[0].charAt(keys[0].length() - 1); char c1 = keys[1].charAt(keys[1].length() - 1); if (c0 > c1) { return null; } Collection<String> seqs = new ArrayList<>(); for (char c = c0; c <= c1; c++) { seqs.add(pfx + c); } return seqs; }  static String display(String key); static String translate(String str); static Collection<String> range(String range); static String esc(); static String alt(char c); static String alt(String c); static String del(); static String ctrl(char key); static String key(Terminal terminal, Capability capability); T getUnicode(); void setUnicode(T unicode); T getNomatch(); void setNomatch(T nomatch); long getAmbiguousTimeout(); void setAmbiguousTimeout(long ambiguousTimeout); T getAnotherKey(); Map<String, T> getBoundKeys(); @SuppressWarnings("unchecked") T getBound(CharSequence keySeq, int[] remaining); T getBound(CharSequence keySeq); void bindIfNotBound(T function, CharSequence keySeq); void bind(T function, CharSequence... keySeqs); void bind(T function, Iterable<? extends CharSequence> keySeqs); void bind(T function, CharSequence keySeq); void unbind(CharSequence... keySeqs); void unbind(CharSequence keySeq); static final int KEYMAP_LENGTH; static final long DEFAULT_AMBIGUOUS_TIMEOUT; static final Comparator<String> KEYSEQ_COMPARATOR; }
@Test public void testRange() { Collection<String> range = range("a^A-a^D"); assertEquals(Arrays.asList(translate("a^A"), translate("a^B"), translate("a^C"), translate("a^D")), range); }