Merge pull request #18 from Ensiss/login-autocomplete

Add autocompletion for logins in the visit prompt
pull/20/head
Jake Funke 2018-06-19 16:39:14 -07:00 committed by GitHub
commit a23656b1be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 3 deletions

55
completer.py 100644
View File

@ -0,0 +1,55 @@
class LoginCompleter:
""" A loop-based completion system for logins """
def __init__(self, menu):
self.s = ""
self.logins = None
self.completions = []
# completion_id has a value of -1 for the base user input
# and between 0 and len(completions)-1 for completions
self.completion_id = -1
self.completion_base = ""
self.menu = menu
def initialize(self):
""" Initialise the list of completable logins """
garden = self.menu.user_data.retrieve_garden_from_db()
self.logins = set()
for plant_id in garden:
if not garden[plant_id]:
continue
entry = garden[plant_id]
if "owner" in entry:
self.logins.add(entry["owner"])
self.logins = sorted(list(self.logins))
def update_input(self, s):
""" Update the user input and reset completion base """
self.s = s
self.completion_base = self.s
self.completion_id = -1
def complete(self, direction = 1):
"""
Returns the completed string from the user input
Loops forward in the list of logins if direction is positive, and
backwards if direction is negative
"""
def loginFilter(x):
return x.startswith(self.s) & (x != self.s)
# Refresh possible completions after the user edits
if self.completion_id == -1:
if self.logins is None:
self.initialize()
self.completion_base = self.s
self.completions = list(filter(loginFilter, self.logins))
self.completion_id += direction
# Loop from the back
if self.completion_id == -2:
self.completion_id = len(self.completions) - 1
# If we are at the base input, return it
if self.completion_id == -1 or self.completion_id == len(self.completions):
self.completion_id = -1
return self.completion_base
return self.completions[self.completion_id]

View File

@ -10,6 +10,7 @@ import json
import sqlite3 import sqlite3
import string import string
import re import re
import completer
class CursedMenu(object): class CursedMenu(object):
#TODO: name your plant #TODO: name your plant
@ -668,10 +669,12 @@ class CursedMenu(object):
visitor_block = 'nobody :(' visitor_block = 'nobody :('
return visitor_block return visitor_block
def get_user_string(self, xpos=3, ypos=15, filterfunc=str.isalnum): def get_user_string(self, xpos=3, ypos=15, filterfunc=str.isalnum, completer=None):
# filter allowed characters using filterfunc, alphanumeric by default # filter allowed characters using filterfunc, alphanumeric by default
user_string = "" user_string = ""
user_input = 0 user_input = 0
if completer:
completer = completer(self)
while user_input != 10: while user_input != 10:
user_input = self.screen.getch() user_input = self.screen.getch()
self.screen_lock.acquire() self.screen_lock.acquire()
@ -679,10 +682,18 @@ class CursedMenu(object):
if user_input == 127 or user_input == 263: if user_input == 127 or user_input == 263:
if len(user_string) > 0: if len(user_string) > 0:
user_string = user_string[:-1] user_string = user_string[:-1]
if completer:
completer.update_input(user_string)
self.screen.addstr(ypos, xpos, " " * (self.maxx-xpos-1)) self.screen.addstr(ypos, xpos, " " * (self.maxx-xpos-1))
if user_input < 256 and user_input != 10: elif user_input in [ord('\t'), curses.KEY_BTAB] and completer:
direction = 1 if user_input == ord('\t') else -1
user_string = completer.complete(direction)
self.screen.addstr(ypos, xpos, " " * (self.maxx-xpos-1))
elif user_input < 256 and user_input != 10:
if filterfunc(chr(user_input)): if filterfunc(chr(user_input)):
user_string += chr(user_input) user_string += chr(user_input)
if completer:
completer.update_input(user_string)
self.screen.addstr(ypos, xpos, str(user_string)) self.screen.addstr(ypos, xpos, str(user_string))
self.screen.refresh() self.screen.refresh()
self.screen_lock.release() self.screen_lock.release()
@ -700,7 +711,7 @@ class CursedMenu(object):
weekly_visitor_text = self.get_weekly_visitors() weekly_visitor_text = self.get_weekly_visitors()
self.draw_info_text("this week you've been visited by: ", 6) self.draw_info_text("this week you've been visited by: ", 6)
self.draw_info_text(weekly_visitor_text, 7) self.draw_info_text(weekly_visitor_text, 7)
guest_garden = self.get_user_string() guest_garden = self.get_user_string(completer = completer.LoginCompleter)
if not guest_garden: if not guest_garden:
self.clear_info_pane() self.clear_info_pane()
return None return None