Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Layout Mapping and Cyrillic characters #308

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,14 @@ FILE_PICKER_CMD = "ranger --choosefile={file_path}"
MAILCAP_FILE = os.path.expanduser("~/.config/mailcap")

DOWNLOAD_DIR = os.path.expanduser("~/Downloads/") # copy file to this dir

# to map key bindings to a different language or a different keyboard layout
LAYOUT_MAPPING = {
eng: rus for (eng, rus) in zip(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
"фисвуапршолдьтщзйкыегмцчняФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ"
)
}
```

### Mailcap file
Expand Down
7 changes: 7 additions & 0 deletions tg/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@

DOWNLOAD_DIR = os.path.expanduser("~/Downloads/")

LAYOUT_MAPPING = {
eng: rus for (eng, rus) in zip(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
"фисвуапршолдьтщзйкыегмцчняФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ"
)
}

if os.path.isfile(CONFIG_FILE):
config_params = runpy.run_path(CONFIG_FILE) # type: ignore
for param, value in config_params.items():
Expand Down
18 changes: 17 additions & 1 deletion tg/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from functools import partial, wraps
from queue import Queue
from tempfile import NamedTemporaryFile
from typing import Any, Callable, Dict, List, Optional
from typing import Any, Callable, Dict, List, Optional, Set

from telegram.utils import AsyncResult

Expand Down Expand Up @@ -37,6 +37,17 @@

chat_handler: Dict[str, HandlerType] = {}
msg_handler: Dict[str, HandlerType] = {}
layout_maps: Set[str] = set()


def map_key_to_layout(key:str, lang_map: Dict[str, str]):
mapped_key = ""
for char in key:
if char in lang_map:
mapped_key += lang_map[char]
else:
mapped_key += char
return mapped_key


def bind(
Expand All @@ -61,6 +72,10 @@ def _no_repeat_factor(self: "Controller", _: bool) -> Optional[str]:
), f"Key {key} already binded to {binding[key]}"
binding[key] = fun if repeat_factor else _no_repeat_factor # type: ignore

mapped_key = map_key_to_layout(key, config.LAYOUT_MAPPING)
binding[mapped_key] = fun if repeat_factor else _no_repeat_factor
layout_maps.add(mapped_key)

return wrapper

return decorator
Expand Down Expand Up @@ -148,6 +163,7 @@ def format_help(bindings: Dict[str, HandlerType]) -> str:
return "\n".join(
f"{key}\t{fun.__name__}\t{fun.__doc__ or ''}"
for key, fun in sorted(bindings.items())
if key not in layout_maps
)

@bind(chat_handler, ["?"])
Expand Down
30 changes: 21 additions & 9 deletions tg/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
"ng",
"bp",
)
if config.LAYOUT_MAPPING:
mapped_bindings = []
for binding in MULTICHAR_KEYBINDINGS:
mapped_binding = ""
for char in binding:
mapped_binding += config.LAYOUT_MAPPING[char]
mapped_bindings.append(mapped_binding)
MULTICHAR_KEYBINDINGS = (*MULTICHAR_KEYBINDINGS, *mapped_bindings)


class Win:
Expand Down Expand Up @@ -83,15 +91,19 @@ def get_keys(self) -> Tuple[int, str]:

for _ in range(MAX_KEYBINDING_LENGTH):
ch = self.stdscr.getch()
log.info("raw ch without unctrl: %s", ch)
try:
key = curses.unctrl(ch).decode()
except Exception:
log.warning("cant uncrtl: %s", ch)
break
if key.isdigit():
repeat_factor += key
continue
if ch == 208 or ch == 209:
second_ch = self.stdscr.getch()
key = (ch.to_bytes() + second_ch.to_bytes()).decode('utf-8')
else:
log.info("raw ch without unctrl: %s", ch)
try:
key = curses.unctrl(ch).decode()
except Exception:
log.warning("cant uncrtl: %s", ch)
break
if key.isdigit():
repeat_factor += key
continue
keys += key
# if match found or there are not any shortcut matches at all
if all(
Expand Down