KeyMap { public static String translate(String str) { int i; if (!str.isEmpty()) { char c = str.charAt(0); if ((c == '\'' || c == '"') && str.charAt(str.length() - 1) == c) { str = str.substring(1, str.length() - 1); } } StringBuilder keySeq = new StringBuilder(); for (i = 0; i < str.length(); i++) { char c = str.charAt(i); if (c == '\\') { if (++i >= str.length()) { break; } c = str.charAt(i); switch (c) { case 'a': c = 0x07; break; case 'b': c = '\b'; break; case 'd': c = 0x7f; break; case 'e': case 'E': c = 0x1b; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = 0x0b; break; case '\\': c = '\\'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c = 0; for (int j = 0; j < 3; j++, i++) { if (i >= str.length()) { break; } int k = Character.digit(str.charAt(i), 8); if (k < 0) { break; } c = (char) (c * 8 + k); } i--; c &= 0xFF; break; case 'x': i++; c = 0; for (int j = 0; j < 2; j++, i++) { if (i >= str.length()) { break; } int k = Character.digit(str.charAt(i), 16); if (k < 0) { break; } c = (char) (c * 16 + k); } i--; c &= 0xFF; break; case 'u': i++; c = 0; for (int j = 0; j < 4; j++, i++) { if (i >= str.length()) { break; } int k = Character.digit(str.charAt(i), 16); if (k < 0) { break; } c = (char) (c * 16 + k); } break; case 'C': if (++i >= str.length()) { break; } c = str.charAt(i); if (c == '-') { if (++i >= str.length()) { break; } c = str.charAt(i); } c = c == '?' ? 0x7f : (char) (Character.toUpperCase(c) & 0x1f); break; } } else if (c == '^') { if (++i >= str.length()) { break; } c = str.charAt(i); if (c != '^') { c = c == '?' ? 0x7f : (char) (Character.toUpperCase(c) & 0x1f); } } keySeq.append(c); } return keySeq.toString(); }  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 testTranslate() { assertEquals("\\\u0007\b\u001b\u001b\f\n\r\t\u000b\u0053\u0045\u2345", translate("\\\\\\a\\b\\e\\E\\f\\n\\r\\t\\v\\123\\x45\\u2345")); assertEquals("\u0001\u0001\u0002\u0002\u0003\u0003\u007f^", translate("\\Ca\\CA\\C-B\\C-b^c^C^?^^")); assertEquals("\u001b3", translate("'\\e3'")); assertEquals("\u001b3", translate("\"\\e3\"")); }