Add autocompletion for logins in the visit prompt
parent
5b839650fe
commit
8616904350
|
@ -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]
|
|
@ -10,6 +10,7 @@ import json
|
|||
import sqlite3
|
||||
import string
|
||||
import re
|
||||
import completer
|
||||
|
||||
class CursedMenu(object):
|
||||
#TODO: name your plant
|
||||
|
@ -644,20 +645,30 @@ class CursedMenu(object):
|
|||
visitor_block = 'nobody :('
|
||||
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
|
||||
user_string = ""
|
||||
user_input = 0
|
||||
if completer:
|
||||
completer = completer(self)
|
||||
while user_input != 10:
|
||||
user_input = self.screen.getch()
|
||||
# osx and unix backspace chars...
|
||||
if user_input == 127 or user_input == 263:
|
||||
if len(user_string) > 0:
|
||||
user_string = user_string[:-1]
|
||||
if completer:
|
||||
completer.update_input(user_string)
|
||||
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)):
|
||||
user_string += chr(user_input)
|
||||
if completer:
|
||||
completer.update_input(user_string)
|
||||
self.screen.addstr(ypos, xpos, str(user_string))
|
||||
self.screen.refresh()
|
||||
return user_string
|
||||
|
@ -674,7 +685,7 @@ class CursedMenu(object):
|
|||
weekly_visitor_text = self.get_weekly_visitors()
|
||||
self.draw_info_text("this week you've been visited by: ", 6)
|
||||
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:
|
||||
self.clear_info_pane()
|
||||
return None
|
||||
|
|
Loading…
Reference in New Issue