Skip to content

Commit

Permalink
Improve Ctrl key labels for Serbian Cyrillic layout
Browse files Browse the repository at this point in the history
Add the ':char' syntax for defining character keys with a different
symbol.
This new kind of keys is used to implement Ctrl combinations in the
Serbian Cyrillic layout without showing latin letters while the Ctrl
modifier is activated.
  • Loading branch information
Julow committed Sep 29, 2024
1 parent fb93d84 commit 700ec23
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 49 deletions.
20 changes: 17 additions & 3 deletions doc/Possible-key-values.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ Where `<kind>` is one of the kinds documented below and `<attributes>` is a
space separated list of attributes. `<payload>` depends on the `<kind>`.

Attributes are:
- `symbol='Sym'` is the symbol to be shown on the keyboard.
- `flags='<flags>'` is a collection of flags that change the behavior of the key.
- `symbol='Sym'` specifies the symbol to be shown on the keyboard.
- `flags='<flags>'` changes the behavior of the key.
`<flags>` is a coma separated list of:
+ `dim`: Make the symbol dimmer.
+ `small`: Make the symbol smaller.
Expand All @@ -172,4 +172,18 @@ Attributes are:
Defines a key that outputs an arbitrary string. `<payload>` is a string wrapped
in single-quotes (`'`), escaping of other single quotes is allowed with `\'`.

For example: `:str symbol='Sym':'Output string'`
For example:
- `:str:'Arbitrary string with a \' inside'`
- `:str symbol='Symbol':'Output string'`

### Kind `char`

Defines a key that outputs a single character. `<payload>` is the character to
output, unquoted.
This kind of key can be used to define a character key with a different symbol
on it. `char` keys can be modified by `ctrl` and other modifiers, unlike `str`
keys.

For example:
- `:char symbol='q':љ`, which is used to implement `ctrl` shortcuts in cyrillic
layouts.
9 changes: 8 additions & 1 deletion srcs/juloo.keyboard2/KeyValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,14 @@ public static KeyValue makeStringKey(String str)

public static KeyValue makeCharKey(char c)
{
return new KeyValue(String.valueOf(c), Kind.Char, c, 0);
return makeCharKey(c, null, 0);
}

public static KeyValue makeCharKey(char c, String symbol, int flags)
{
if (symbol == null)
symbol = String.valueOf(c);
return new KeyValue(symbol, Kind.Char, c, flags);
}

public static KeyValue makeComposePending(String symbol, int state, int flags)
Expand Down
34 changes: 16 additions & 18 deletions srcs/juloo.keyboard2/KeyValueParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,7 @@
- If [str] doesn't start with a [:] character, it is interpreted as an
arbitrary string key.
[(kind)] specifies the kind of the key, it can be:
- [str]: An arbitrary string key. The payload is the string to output when
typed and is quoted by single quotes ([']). The payload can contain single
quotes if they are escaped with a backslash ([\']).
The [(attributes)] part is a space-separated list of attributes, all optional,
of the form: [attrname='attrvalue'].
Attributes can be:
- [flags]: Add flags that change the behavior of the key.
Value is a coma separated list of:
- [dim]: Make the symbol dimmer on the keyboard.
- [small]: Make the symbol smaller on the keyboard.
- [symbol]: Specify the symbol that is rendered on the keyboard.
It can contain single quotes if they are escaped: ([\']).
For the different kinds and attributes, see doc/Possible-key-values.md.
Examples:
- [:str flags=dim,small symbol='MyKey':'My arbitrary string'].
Expand All @@ -36,6 +22,7 @@ public final class KeyValueParser
static Pattern ATTR_PAT;
static Pattern QUOTED_PAT;
static Pattern PAYLOAD_START_PAT;
static Pattern SINGLE_CHAR_PAT;

static public KeyValue parse(String str) throws ParseError
{
Expand Down Expand Up @@ -73,11 +60,14 @@ static public KeyValue parse(String str) throws ParseError
switch (kind)
{
case "str":
String payload = parseSingleQuotedString(m);
String str_payload = parseSingleQuotedString(m);
if (symbol == null)
return KeyValue.makeStringKey(payload, flags);
return KeyValue.makeStringKeyWithSymbol(payload, symbol, flags);
return KeyValue.makeStringKey(str_payload, flags);
return KeyValue.makeStringKeyWithSymbol(str_payload, symbol, flags);

case "char":
char char_payload = parseOneChar(m);
return KeyValue.makeCharKey(char_payload, symbol, flags);
default: break;
}
parseError("Unknown kind '"+kind+"'", m, 1);
Expand All @@ -91,6 +81,13 @@ static String parseSingleQuotedString(Matcher m) throws ParseError
return m.group(1).replace("\\'", "'");
}

static char parseOneChar(Matcher m) throws ParseError
{
if (!match(m, SINGLE_CHAR_PAT))
parseError("Expected a character", m);
return m.group(0).charAt(0);
}

static int parseFlags(String s, Matcher m) throws ParseError
{
int flags = 0;
Expand Down Expand Up @@ -121,6 +118,7 @@ static void init()
ATTR_PAT = Pattern.compile("\\s*(\\w+)\\s*=");
QUOTED_PAT = Pattern.compile("'(([^'\\\\]+|\\\\')*)'");
PAYLOAD_START_PAT = Pattern.compile("\\s*:");
SINGLE_CHAR_PAT = Pattern.compile(".");
}

static void parseError(String msg, Matcher m) throws ParseError
Expand Down
52 changes: 26 additions & 26 deletions srcs/layouts/cyrl_lynyertz_sr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@
<fn a="у" b="у̂" />
<fn a="cursor_left" b="home" />
<fn a="cursor_right" b="end" />
<ctrl a="љ" b="q" />
<ctrl a="њ" b="w" />
<ctrl a="е" b="e" />
<ctrl a="р" b="r" />
<ctrl a="т" b="t" />
<ctrl a="ж" b="y" />
<ctrl a="у" b="u" />
<ctrl a="и" b="i" />
<ctrl a="о" b="o" />
<ctrl a="п" b="p" />
<ctrl a="а" b="a" />
<ctrl a="с" b="s" />
<ctrl a="д" b="d" />
<ctrl a="ф" b="f" />
<ctrl a="г" b="g" />
<ctrl a="х" b="h" />
<ctrl a="ј" b="j" />
<ctrl a="к" b="k" />
<ctrl a="л" b="l" />
<ctrl a="з" b="z" />
<ctrl a="џ" b="x" />
<ctrl a="ц" b="c" />
<ctrl a="в" b="v" />
<ctrl a="б" b="b" />
<ctrl a="н" b="n" />
<ctrl a="м" b="m" />
<ctrl a="љ" b=":char symbol='љ':q" />
<ctrl a="њ" b=":char symbol='њ':w" />
<ctrl a="е" b=":char symbol='е':e" />
<ctrl a="р" b=":char symbol='р':r" />
<ctrl a="т" b=":char symbol='т':t" />
<ctrl a="ж" b=":char symbol='ж':y" />
<ctrl a="у" b=":char symbol='у':u" />
<ctrl a="и" b=":char symbol='и':i" />
<ctrl a="о" b=":char symbol='о':o" />
<ctrl a="п" b=":char symbol='п':p" />
<ctrl a="а" b=":char symbol='а':a" />
<ctrl a="с" b=":char symbol='с':s" />
<ctrl a="д" b=":char symbol='д':d" />
<ctrl a="ф" b=":char symbol='ф':f" />
<ctrl a="г" b=":char symbol='г':g" />
<ctrl a="х" b=":char symbol='х':h" />
<ctrl a="ј" b=":char symbol='ј':j" />
<ctrl a="к" b=":char symbol='к':k" />
<ctrl a="л" b=":char symbol='л':l" />
<ctrl a="з" b=":char symbol='з':z" />
<ctrl a="џ" b=":char symbol='џ':x" />
<ctrl a="ц" b=":char symbol='ц':c" />
<ctrl a="в" b=":char symbol='в':v" />
<ctrl a="б" b=":char symbol='б':b" />
<ctrl a="н" b=":char symbol='н':n" />
<ctrl a="м" b=":char symbol='м':m" />
</modmap>
<row>
<key key0="љ" ne="1" se="loc esc"/>
Expand Down
9 changes: 8 additions & 1 deletion test/juloo.keyboard2/KeyValueParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class KeyValueParserTest
public KeyValueParserTest() {}

@Test
public void parse() throws Exception
public void parseStr() throws Exception
{
Utils.parse(":str:'Foo'", KeyValue.makeStringKey("Foo"));
Utils.parse(":str flags='dim':'Foo'", KeyValue.makeStringKey("Foo", KeyValue.FLAG_SECONDARY));
Expand All @@ -34,6 +34,13 @@ public void parse() throws Exception
Utils.expect_error(":str flags='':'");
}

@Test
public void parseChar() throws Exception
{
Utils.parse(":char symbol='a':b", KeyValue.makeCharKey('b', "a", 0));
Utils.parse(":char:b", KeyValue.makeCharKey('b', "b", 0));
}

/** JUnit removes these functions from stacktraces. */
static class Utils
{
Expand Down

0 comments on commit 700ec23

Please sign in to comment.