Merge pull request #18 from Ensiss/login-autocomplete
Add autocompletion for logins in the visit promptpull/20/head
commit
a23656b1be
|
@ -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 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
|
||||||
|
|
Loading…
Reference in New Issue