Add autocompletion for logins in the visit prompt

This commit is contained in:
Ensis 2018-06-10 12:05:17 +02:00
parent 5b839650fe
commit 8616904350
2 changed files with 69 additions and 3 deletions

55
completer.py Normal file
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 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