Refactor: Allow combining diacritics modifiers

Change the API of `KeyModifier.Map_char` to allow returning a string
instead of a single 16 bits char.

This allows to return combining diacritics.

This also gets rid of `apply_map_or_dead_char`, maps can have their own
fallback.
This commit is contained in:
Jules Aguillon 2023-08-20 00:44:22 +02:00
parent cd5ca56226
commit 40498e7b4c
2 changed files with 327 additions and 328 deletions

View File

@ -39,17 +39,17 @@ class KeyModifier
case META: return turn_into_keyevent(k); case META: return turn_into_keyevent(k);
case FN: return apply_fn(k); case FN: return apply_fn(k);
case SHIFT: return apply_shift(k); case SHIFT: return apply_shift(k);
case GRAVE: return apply_map_or_dead_char(k, map_char_grave, '\u02CB'); case GRAVE: return apply_map_char(k, map_char_grave);
case AIGU: return apply_map_or_dead_char(k, map_char_aigu, '\u00B4'); case AIGU: return apply_map_char(k, map_char_aigu);
case CIRCONFLEXE: return apply_map_or_dead_char(k, map_char_circonflexe, '\u02C6'); case CIRCONFLEXE: return apply_map_char(k, map_char_circonflexe);
case TILDE: return apply_map_or_dead_char(k, map_char_tilde, '\u02DC'); case TILDE: return apply_map_char(k, map_char_tilde);
case CEDILLE: return apply_map_or_dead_char(k, map_char_cedille, '\u00B8'); case CEDILLE: return apply_map_char(k, map_char_cedille);
case TREMA: return apply_map_or_dead_char(k, map_char_trema, '\u00A8'); case TREMA: return apply_map_char(k, map_char_trema);
case CARON: return apply_map_or_dead_char(k, map_char_caron, '\u02C7'); case CARON: return apply_map_char(k, map_char_caron);
case RING: return apply_map_or_dead_char(k, map_char_ring, '\u02DA'); case RING: return apply_map_char(k, map_char_ring);
case MACRON: return apply_map_or_dead_char(k, map_char_macron, '\u00AF'); case MACRON: return apply_map_char(k, map_char_macron);
case OGONEK: return apply_map_or_dead_char(k, map_char_ogonek, '\u02DB'); case OGONEK: return apply_map_char(k, map_char_ogonek);
case DOT_ABOVE: return apply_map_or_dead_char(k, map_char_dot_above, '\u02D9'); case DOT_ABOVE: return apply_map_char(k, map_char_dot_above);
case BREVE: return apply_dead_char(k, '\u02D8'); case BREVE: return apply_dead_char(k, '\u02D8');
case DOUBLE_AIGU: return apply_map_char(k, map_char_double_aigu); case DOUBLE_AIGU: return apply_map_char(k, map_char_double_aigu);
case ORDINAL: return apply_map_char(k, map_char_ordinal); case ORDINAL: return apply_map_char(k, map_char_ordinal);
@ -89,8 +89,10 @@ class KeyModifier
{ {
case Char: case Char:
char kc = k.getChar(); char kc = k.getChar();
char c = map.apply(kc); String modified = map.apply(kc);
return (kc == c) ? k : k.withChar(c); if (modified == null)
return k;
return KeyValue.makeStringKey(modified, k.getFlags());
default: return k; default: return k;
} }
} }
@ -107,27 +109,13 @@ class KeyModifier
} }
} }
/** Apply a [Map_char] or fallback to [apply_dead_char]. */
private static KeyValue apply_map_or_dead_char(KeyValue k, Map_char map, char dead_char)
{
switch (k.getKind())
{
case Char:
char kc = k.getChar();
char c = map.apply(kc);
if (kc == c)
return apply_dead_char(k, dead_char);
return k.withChar(c);
default: return k;
}
}
private static KeyValue apply_combining(KeyValue k, String combining) private static KeyValue apply_combining(KeyValue k, String combining)
{ {
switch (k.getKind()) switch (k.getKind())
{ {
case Char: case Char:
return k.withString(String.valueOf(k.getChar()) + combining); String s = String.valueOf(k.getChar()) + combining;
return KeyValue.makeStringKey(s, k.getFlags());
default: return k; default: return k;
} }
} }
@ -143,7 +131,7 @@ class KeyModifier
c = Character.toUpperCase(kc); c = Character.toUpperCase(kc);
return (kc == c) ? k : k.withChar(c); return (kc == c) ? k : k.withChar(c);
case String: case String:
return k.withString(k.getString().toUpperCase()); return KeyValue.makeStringKey(k.getString().toUpperCase(), k.getFlags());
default: return k; default: return k;
} }
} }
@ -464,7 +452,9 @@ class KeyModifier
private static abstract class Map_char private static abstract class Map_char
{ {
public abstract char apply(char c); /** Modify a char or return [null] if the modifier do not apply. Return a
[String] that can contains combining diacritics. */
public abstract String apply(char c);
} }
private static char map_char_shift(char c) private static char map_char_shift(char c)
@ -500,469 +490,477 @@ class KeyModifier
} }
} }
/** Return [null] if the dead char do not apply. */
private static String map_dead_char(char c, char dead_char)
{
char modified = (char)KeyCharacterMap.getDeadChar(dead_char, c);
return (modified == 0 || modified == c) ? null : String.valueOf(modified);
}
private static final Map_char map_char_aigu = private static final Map_char map_char_aigu =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
// Composite characters: '' // Composite characters: ''
case 'a': return 'á'; case 'a': return "á";
case 'e': return 'é'; case 'e': return "é";
case 'i': return 'í'; case 'i': return "í";
case 'l': return 'ĺ'; case 'l': return "ĺ";
case 'o': return 'ó'; case 'o': return "ó";
case 'r': return 'ŕ'; case 'r': return "ŕ";
case 's': return 'ś'; case 's': return "ś";
case 'u': return 'ú'; case 'u': return "ú";
case 'y': return 'ý'; case 'y': return "ý";
default: return c; default: return map_dead_char(c, '\u00B4');
} }
} }
}; };
private static final Map_char map_char_caron = private static final Map_char map_char_caron =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'c': return 'č'; case 'c': return "č";
case 'd': return 'ď'; case 'd': return "ď";
case 'e': return 'ě'; case 'e': return "ě";
case 'l': return 'ľ'; case 'l': return "ľ";
case 'n': return 'ň'; case 'n': return "ň";
case 'r': return 'ř'; case 'r': return "ř";
case 's': return 'š'; case 's': return "š";
case 't': return 'ť'; case 't': return "ť";
case 'z': return 'ž'; case 'z': return "ž";
default: return c; default: return map_dead_char(c, '\u02C7');
} }
} }
}; };
private static final Map_char map_char_cedille = private static final Map_char map_char_cedille =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'c': return 'ç'; case 'c': return "ç";
case 's': return 'ş'; case 's': return "ş";
case 'g': return 'ģ'; case 'g': return "ģ";
default: return c; default: return map_dead_char(c, '\u00B8');
} }
} }
}; };
private static final Map_char map_char_circonflexe = private static final Map_char map_char_circonflexe =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'â'; case 'a': return "â";
case 'e': return 'ê'; case 'e': return "ê";
case 'i': return 'î'; case 'i': return "î";
case 'o': return 'ô'; case 'o': return "ô";
case 'u': return 'û'; case 'u': return "û";
default: return c; default: return map_dead_char(c, '\u02C6');
} }
} }
}; };
private static final Map_char map_char_dot_above = private static final Map_char map_char_dot_above =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'ė': return 'ė'; case 'ė': return "ė";
default: return c; default: return map_dead_char(c, '\u02D9');
} }
} }
}; };
private static final Map_char map_char_grave = private static final Map_char map_char_grave =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'à'; case 'a': return "à";
case 'e': return 'è'; case 'e': return "è";
case 'i': return 'ì'; case 'i': return "ì";
case 'o': return 'ò'; case 'o': return "ò";
case 'u': return 'ù'; case 'u': return "ù";
default: return c; default: return map_dead_char(c, '\u02CB');
} }
} }
}; };
private static final Map_char map_char_macron = private static final Map_char map_char_macron =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'ā'; case 'a': return "ā";
case 'e': return 'ē'; case 'e': return "ē";
case 'i': return 'ī'; case 'i': return "ī";
case 'u': return 'ū'; case 'u': return "ū";
default: return c; default: return map_dead_char(c, '\u00AF');
} }
} }
}; };
private static final Map_char map_char_ogonek = private static final Map_char map_char_ogonek =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'ą'; case 'a': return "ą";
case 'e': return 'ę'; case 'e': return "ę";
case 'i': return 'į'; case 'i': return "į";
case 'k': return 'ķ'; case 'k': return "ķ";
case 'l': return 'ļ'; case 'l': return "ļ";
case 'n': return 'ņ'; case 'n': return "ņ";
case 'u': return 'ų'; case 'u': return "ų";
default: return c; default: return map_dead_char(c, '\u02DB');
} }
} }
}; };
private static final Map_char map_char_ring = private static final Map_char map_char_ring =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'å'; case 'a': return "å";
case 'u': return 'ů'; case 'u': return "ů";
default: return c; default: return map_dead_char(c, '\u02DA');
} }
} }
}; };
private static final Map_char map_char_tilde = private static final Map_char map_char_tilde =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'ã'; case 'a': return "ã";
case 'o': return 'õ'; case 'o': return "õ";
case 'n': return 'ñ'; case 'n': return "ñ";
default: return c; default: return map_dead_char(c, '\u02DC');
} }
} }
}; };
private static final Map_char map_char_trema = private static final Map_char map_char_trema =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'ä'; case 'a': return "ä";
case 'e': return 'ë'; case 'e': return "ë";
case 'i': return 'ï'; case 'i': return "ï";
case 'o': return 'ö'; case 'o': return "ö";
case 'u': return 'ü'; case 'u': return "ü";
case 'y': return 'ÿ'; case 'y': return "ÿ";
default: return c; default: return map_dead_char(c, '\u00A8');
} }
} }
}; };
private static final Map_char map_char_double_aigu = private static final Map_char map_char_double_aigu =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
// Composite characters: ӳ // Composite characters: ӳ
case 'o': return 'ő'; case 'o': return "ő";
case 'u': return 'ű'; case 'u': return "ű";
case ' ': return '˝'; case ' ': return "˝";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_ordinal = private static final Map_char map_char_ordinal =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'ª'; case 'a': return "ª";
case 'o': return 'º'; case 'o': return "º";
case '1': return 'ª'; case '1': return "ª";
case '2': return 'º'; case '2': return "º";
case '3': return 'ⁿ'; case '3': return "";
case '4': return 'ᵈ'; case '4': return "";
case '5': return 'ᵉ'; case '5': return "";
case '6': return 'ʳ'; case '6': return "ʳ";
case '7': return 'ˢ'; case '7': return "ˢ";
case '8': return 'ᵗ'; case '8': return "";
case '9': return 'ʰ'; case '9': return "ʰ";
case '*': return '°'; case '*': return "°";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_superscript = private static final Map_char map_char_superscript =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case '1': return '¹'; case '1': return "¹";
case '2': return '²'; case '2': return "²";
case '3': return '³'; case '3': return "³";
case '4': return '⁴'; case '4': return "";
case '5': return '⁵'; case '5': return "";
case '6': return '⁶'; case '6': return "";
case '7': return '⁷'; case '7': return "";
case '8': return '⁸'; case '8': return "";
case '9': return '⁹'; case '9': return "";
case '0': return '⁰'; case '0': return "";
case '+': return '⁺'; case '+': return "";
case '-': return '⁻'; case '-': return "";
case '=': return '⁼'; case '=': return "";
case '(': return '⁽'; case '(': return "";
case ')': return '⁾'; case ')': return "";
case 'a': return 'ᵃ'; case 'a': return "";
case 'b': return 'ᵇ'; case 'b': return "";
case 'c': return 'ᶜ'; case 'c': return "";
case 'd': return 'ᵈ'; case 'd': return "";
case 'e': return 'ᵉ'; case 'e': return "";
case 'f': return 'ᶠ'; case 'f': return "";
case 'g': return 'ᵍ'; case 'g': return "";
case 'h': return 'ʰ'; case 'h': return "ʰ";
case 'i': return 'ⁱ'; case 'i': return "";
case 'j': return 'ʲ'; case 'j': return "ʲ";
case 'k': return 'ᵏ'; case 'k': return "";
case 'l': return 'ˡ'; case 'l': return "ˡ";
case 'm': return 'ᵐ'; case 'm': return "";
case 'n': return 'ⁿ'; case 'n': return "";
case 'o': return 'ᵒ'; case 'o': return "";
case 'p': return 'ᵖ'; case 'p': return "";
case 'r': return 'ʳ'; case 'r': return "ʳ";
case 's': return 'ˢ'; case 's': return "ˢ";
case 't': return 'ᵗ'; case 't': return "";
case 'u': return 'ᵘ'; case 'u': return "";
case 'v': return 'ᵛ'; case 'v': return "";
case 'w': return 'ʷ'; case 'w': return "ʷ";
case 'x': return 'ˣ'; case 'x': return "ˣ";
case 'y': return 'ʸ'; case 'y': return "ʸ";
case 'z': return 'ᶻ'; case 'z': return "";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_subscript = private static final Map_char map_char_subscript =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case '1': return '₁'; case '1': return "";
case '2': return '₂'; case '2': return "";
case '3': return '₃'; case '3': return "";
case '4': return '₄'; case '4': return "";
case '5': return '₅'; case '5': return "";
case '6': return '₆'; case '6': return "";
case '7': return '₇'; case '7': return "";
case '8': return '₈'; case '8': return "";
case '9': return '₉'; case '9': return "";
case '0': return '₀'; case '0': return "";
case '+': return '₊'; case '+': return "";
case '-': return '₋'; case '-': return "";
case '=': return '₌'; case '=': return "";
case '(': return '₍'; case '(': return "";
case ')': return '₎'; case ')': return "";
case 'a': return 'ₐ'; case 'a': return "";
case 'e': return 'ₑ'; case 'e': return "";
case 'h': return 'ₕ'; case 'h': return "";
case 'i': return 'ᵢ'; case 'i': return "";
case 'j': return 'ⱼ'; case 'j': return "";
case 'k': return 'ₖ'; case 'k': return "";
case 'l': return 'ₗ'; case 'l': return "";
case 'm': return 'ₘ'; case 'm': return "";
case 'n': return 'ₙ'; case 'n': return "";
case 'o': return 'ₒ'; case 'o': return "";
case 'p': return 'ₚ'; case 'p': return "";
case 'r': return 'ᵣ'; case 'r': return "";
case 's': return 'ₛ'; case 's': return "";
case 't': return 'ₜ'; case 't': return "";
case 'u': return 'ᵤ'; case 'u': return "";
case 'v': return 'ᵥ'; case 'v': return "";
case 'x': return 'ₓ'; case 'x': return "";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_arrows = private static final Map_char map_char_arrows =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case '1': return '↙'; case '1': return "";
case '2': return '↓'; case '2': return "";
case '3': return '↘'; case '3': return "";
case '4': return '←'; case '4': return "";
case '6': return '→'; case '6': return "";
case '7': return '↖'; case '7': return "";
case '8': return '↑'; case '8': return "";
case '9': return '↗'; case '9': return "";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_box = private static final Map_char map_char_box =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case '1': return '└'; case '1': return "";
case '2': return '┴'; case '2': return "";
case '3': return '┘'; case '3': return "";
case '4': return '├'; case '4': return "";
case '5': return '┼'; case '5': return "";
case '6': return '┤'; case '6': return "";
case '7': return '┌'; case '7': return "";
case '8': return '┬'; case '8': return "";
case '9': return '┐'; case '9': return "";
case '0': return '─'; case '0': return "";
case '.': return '│'; case '.': return "";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_slash = private static final Map_char map_char_slash =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'ⱥ'; case 'a': return "";
case 'b': return '␢'; case 'b': return "";
case 'c': return 'ȼ'; case 'c': return "ȼ";
case 'e': return 'ɇ'; case 'e': return "ɇ";
case 'g': return 'ꞡ'; case 'g': return "";
case 'k': return 'ꝃ'; case 'k': return "";
case 'l': return 'ł'; case 'l': return "ł";
case 'n': return 'ꞥ'; case 'n': return "";
case 'o': return 'ø'; case 'o': return "ø";
case 'r': return 'ꞧ'; case 'r': return "";
case 's': return 'ꞩ'; case 's': return "";
case 't': return 'ⱦ'; case 't': return "";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_bar = private static final Map_char map_char_bar =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'b': return 'ƀ'; case 'b': return "ƀ";
case 'c': return 'ꞓ'; case 'c': return "";
case 'd': return 'đ'; case 'd': return "đ";
case 'g': return 'ǥ'; case 'g': return "ǥ";
case 'i': return 'ɨ'; case 'i': return "ɨ";
case 'j': return 'ɉ'; case 'j': return "ɉ";
case 'k': return 'ꝁ'; case 'k': return "";
case 'l': return 'ƚ'; case 'l': return "ƚ";
case 'o': return 'ɵ'; case 'o': return "ɵ";
case 'p': return 'ᵽ'; case 'p': return "";
case 'q': return 'ꝗ'; case 'q': return "";
case 'r': return 'ɍ'; case 'r': return "ɍ";
case 't': return 'ŧ'; case 't': return "ŧ";
case 'u': return 'ʉ'; case 'u': return "ʉ";
case 'y': return 'ɏ'; case 'y': return "ɏ";
case 'z': return 'ƶ'; case 'z': return "ƶ";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_dot_below = private static final Map_char map_char_dot_below =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'ạ'; case 'a': return "";
case 'ă': return 'ặ'; case 'ă': return "";
case 'â': return 'ậ'; case 'â': return "";
case 'e': return 'ẹ'; case 'e': return "";
case 'ê': return 'ệ'; case 'ê': return "";
case 'i': return 'ị'; case 'i': return "";
case 'o': return 'ọ'; case 'o': return "";
case 'ô': return 'ộ'; case 'ô': return "";
case 'ơ': return 'ợ'; case 'ơ': return "";
case 'u': return 'ụ'; case 'u': return "";
case 'ư': return 'ự'; case 'ư': return "";
case 'y': return 'ỵ'; case 'y': return "";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_horn = private static final Map_char map_char_horn =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'o': return 'ơ'; case 'o': return "ơ";
case 'ó': return 'ớ'; case 'ó': return "";
case 'ò': return 'ờ'; case 'ò': return "";
case 'ỏ': return 'ở'; case 'ỏ': return "";
case 'õ': return 'ỡ'; case 'õ': return "";
case 'ọ': return 'ợ'; case 'ọ': return "";
case 'u': return 'ư'; case 'u': return "ư";
case 'ú': return 'ứ'; case 'ú': return "";
case 'ù': return 'ừ'; case 'ù': return "";
case 'ủ': return 'ử'; case 'ủ': return "";
case 'ũ': return 'ữ'; case 'ũ': return "";
case 'ụ': return 'ự'; case 'ụ': return "";
default: return c; default: return null;
} }
} }
}; };
private static final Map_char map_char_hook_above = private static final Map_char map_char_hook_above =
new Map_char() { new Map_char() {
public char apply(char c) public String apply(char c)
{ {
switch (c) switch (c)
{ {
case 'a': return 'ả'; case 'a': return "";
case 'ă': return 'ẳ'; case 'ă': return "";
case 'â': return 'ẩ'; case 'â': return "";
case 'e': return 'ẻ'; case 'e': return "";
case 'ê': return 'ể'; case 'ê': return "";
case 'i': return 'ỉ'; case 'i': return "";
case 'o': return 'ỏ'; case 'o': return "";
case 'ô': return 'ổ'; case 'ô': return "";
case 'ơ': return 'ở'; case 'ơ': return "";
case 'u': return 'ủ'; case 'u': return "";
case 'ư': return 'ử'; case 'ư': return "";
case 'y': return 'ỷ'; case 'y': return "";
default: return c; default: return null;
} }
} }
}; };

View File

@ -182,11 +182,6 @@ final class KeyValue
return new KeyValue(String.valueOf(c), Kind.Char, c, getFlags()); return new KeyValue(String.valueOf(c), Kind.Char, c, getFlags());
} }
public KeyValue withString(String s)
{
return new KeyValue(s, Kind.String, 0, getFlags());
}
public KeyValue withSymbol(String s) public KeyValue withSymbol(String s)
{ {
return new KeyValue(s, (_code & KIND_BITS), (_code & VALUE_BITS), getFlags()); return new KeyValue(s, (_code & KIND_BITS), (_code & VALUE_BITS), getFlags());
@ -302,13 +297,19 @@ final class KeyValue
return new KeyValue("", Kind.Placeholder, id.ordinal(), 0); return new KeyValue("", Kind.Placeholder, id.ordinal(), 0);
} }
/** Make a key that types a string. */
public static KeyValue makeStringKey(String str) public static KeyValue makeStringKey(String str)
{
return makeStringKey(str, 0);
}
/** Make a key that types a string. A char key is returned for a string of
length 1. */
public static KeyValue makeStringKey(String str, int flags)
{ {
if (str.length() == 1) if (str.length() == 1)
return new KeyValue(str, Kind.Char, str.charAt(0), 0); return new KeyValue(str, Kind.Char, str.charAt(0), flags);
else else
return new KeyValue(str, Kind.String, 0, FLAG_SMALLER_FONT); return new KeyValue(str, Kind.String, 0, flags | FLAG_SMALLER_FONT);
} }
public static KeyValue getKeyByName(String name) public static KeyValue getKeyByName(String name)