added gg, 4j, 3k keybinding support

This commit is contained in:
Alexander Zveruk 2020-05-03 19:04:15 +03:00
parent 23ab03bd65
commit e88793bff6
4 changed files with 72 additions and 46 deletions

View file

@ -35,7 +35,7 @@ class Controller:
while True: while True:
key = self.view.get_key(self.view.chats.h, self.view.chats.w) repeat_factor, key = self.view.get_key(self.view.chats.h, self.view.chats.w)
log.info('Pressed key: %s', key) log.info('Pressed key: %s', key)
if key == 'q': if key == 'q':
return 'QUIT' return 'QUIT'
@ -52,10 +52,10 @@ class Controller:
if self.model.jump_prev_msg(): if self.model.jump_prev_msg():
self.refresh_msgs() self.refresh_msgs()
elif key in ('j', '^B'): elif key in ('j', '^B'):
if self.model.next_msg(): if self.model.next_msg(repeat_factor):
self.refresh_msgs() self.refresh_msgs()
elif key in ('k', '^C'): elif key in ('k', '^C'):
if self.model.prev_msg(): if self.model.prev_msg(repeat_factor):
self.refresh_msgs() self.refresh_msgs()
elif key == 'G': elif key == 'G':
if self.model.jump_bottom(): if self.model.jump_bottom():
@ -99,7 +99,7 @@ class Controller:
self.refresh_chats() self.refresh_chats()
while True: while True:
key = self.view.get_key(self.view.chats.h, self.view.chats.w) repeat_factor, key = self.view.get_key(self.view.chats.h, self.view.chats.w)
log.info('Pressed key: %s', key) log.info('Pressed key: %s', key)
if key == 'q': if key == 'q':
return return
@ -112,12 +112,17 @@ class Controller:
self.refresh_chats() self.refresh_chats()
elif key in ('j', '^B'): elif key in ('j', '^B'):
is_changed = self.model.next_chat() is_changed = self.model.next_chat(repeat_factor)
if is_changed: if is_changed:
self.refresh_chats() self.refresh_chats()
elif key in ('k', '^C'): elif key in ('k', '^C'):
is_changed = self.model.prev_chat() is_changed = self.model.prev_chat(repeat_factor)
if is_changed:
self.refresh_chats()
elif key == 'gg':
is_changed = self.model.first_chat()
if is_changed: if is_changed:
self.refresh_chats() self.refresh_chats()

View file

@ -33,25 +33,32 @@ class Model:
chat_id = self.chats.chat_ids[self.current_chat] chat_id = self.chats.chat_ids[self.current_chat]
return self.msgs.jump_bottom(chat_id) return self.msgs.jump_bottom(chat_id)
def next_chat(self): def next_chat(self, step=1):
if self.current_chat < len(self.chats.chats): new_idx = self.current_chat + step
self.current_chat += 1 if new_idx < len(self.chats.chats):
self.current_chat = new_idx
return True return True
return False return False
def prev_chat(self): def prev_chat(self, step=1):
if self.current_chat > 0: if self.current_chat == 0:
self.current_chat -= 1 return False
self.current_chat = max(0, self.current_chat - step)
return True
def first_chat(self):
if self.current_chat != 0:
self.current_chat = 0
return True return True
return False return False
def next_msg(self): def next_msg(self, step=1):
chat_id = self.chats.chat_ids[self.current_chat] chat_id = self.chats.chat_ids[self.current_chat]
return self.msgs.next_msg(chat_id) return self.msgs.next_msg(chat_id, step)
def prev_msg(self): def prev_msg(self, step=1):
chat_id = self.chats.chat_ids[self.current_chat] chat_id = self.chats.chat_ids[self.current_chat]
return self.msgs.prev_msg(chat_id) return self.msgs.prev_msg(chat_id, step)
def jump_next_msg(self): def jump_next_msg(self):
chat_id = self.chats.chat_ids[self.current_chat] chat_id = self.chats.chat_ids[self.current_chat]
@ -156,11 +163,12 @@ class MsgModel:
self.msgs = defaultdict(list) # Dict[int, list] self.msgs = defaultdict(list) # Dict[int, list]
self.current_msgs = defaultdict(int) self.current_msgs = defaultdict(int)
def next_msg(self, chat_id): def next_msg(self, chat_id, step=1):
if self.current_msgs[chat_id] > 0: current_msgs = self.current_msgs[chat_id]
self.current_msgs[chat_id] -= 1 if current_msgs == 0:
return True return False
return False self.current_msgs[chat_id] = max(0, current_msgs - step)
return True
def jump_bottom(self, chat_id): def jump_bottom(self, chat_id):
if self.current_msgs[chat_id] == 0: if self.current_msgs[chat_id] == 0:
@ -169,21 +177,15 @@ class MsgModel:
return True return True
def jump_next_msg(self, chat_id): def jump_next_msg(self, chat_id):
if self.current_msgs[chat_id] - 10 > 0: return self.next_msg(chat_id, step=10)
self.current_msgs[chat_id] -= 10
else:
self.current_msgs[chat_id] = 0
return True
def jump_prev_msg(self, chat_id): def jump_prev_msg(self, chat_id):
if self.current_msgs[chat_id] + 10 < len(self.msgs[chat_id]): return self.prev_msg(chat_id, step=10)
self.current_msgs[chat_id] += 10
return True
return False
def prev_msg(self, chat_id): def prev_msg(self, chat_id, step=1):
if self.current_msgs[chat_id] < len(self.msgs[chat_id]): new_idx = self.current_msgs[chat_id] + step
self.current_msgs[chat_id] += 1 if new_idx < len(self.msgs[chat_id]):
self.current_msgs[chat_id] = new_idx
return True return True
return False return False

View file

@ -4,6 +4,13 @@ import os
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def num(value, default=None):
try:
return int(value)
except ValueError:
return default
def notify(msg, subtitle='New message', title='Telegram'): def notify(msg, subtitle='New message', title='Telegram'):
msg = '-message {!r}'.format(msg) msg = '-message {!r}'.format(msg)
subtitle = '-subtitle {!r}'.format(subtitle) subtitle = '-subtitle {!r}'.format(subtitle)

View file

@ -4,8 +4,13 @@ import math
import re import re
from datetime import datetime from datetime import datetime
from utils import num
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
MAX_KEYBINDING_LENGTH = 5
MULTICHAR_KEYBINDINGS = ("gg",)
class View: class View:
@ -49,21 +54,28 @@ class View:
self.msgs.draw(current, msgs) self.msgs.draw(current, msgs)
def get_key(self, y, x): def get_key(self, y, x):
# return self.stdscr.getkey() keys = repeat_factor = ''
ch = self.stdscr.getch(y, x) for _ in range(MAX_KEYBINDING_LENGTH):
log.info('raw ch without unctrl: %s', ch) ch = self.stdscr.getch(y, x)
try: log.info('raw ch without unctrl: %s', ch)
return curses.unctrl(ch).decode() try:
except UnicodeDecodeError: key = curses.unctrl(ch).decode()
log.warning('cant uncrtl: %s', ch) except UnicodeDecodeError:
return 'UNKNOWN' 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(
p == keys or not p.startswith(keys)
for p in MULTICHAR_KEYBINDINGS
):
break
def get_key_input(self, y, x): return num(repeat_factor, default=1), keys or 'UNKNOWN'
ch = self.msgs.win.getch(y, x)
log.info('raw ch without unctrl in msgs: %s', ch)
return ch
# return curses.unctrl(ch).decode()
def get_input(self): def get_input(self):
return self.status.get_input() return self.status.get_input()