Created
September 4, 2015 14:12
-
-
Save sbp/318ecce414c00ffd17fe to your computer and use it in GitHub Desktop.
Choose from a range interactively
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# choice.py, by Sean B. Palmer | |
import sys | |
countries = ["Albania", "Andorra", "Austria", "Belarus", "Belgium", "Bulgaria", | |
"Cyprus", "Czechoslovakia", "Denmark", "Estonia", "Faeroe Islands", "Finland", | |
"France", "Germany", "Gibraltar", "Greece", "Guernsey", "Hungary", "Iceland", | |
"Ireland", "Isle of Man", "Italy", "Jan Mayen", "Jersey", "Latvia", | |
"Liechtenstein", "Lithuania", "Luxembourg", "Malta", "Moldova", "Monaco", | |
"Netherlands", "Norway", "Poland", "Portugal", "Romania", "San Marino", | |
"Spain", "Sweden", "Switzerland", "United Kingdom", "Yugoslavia"] | |
write = sys.stdout.write | |
# http://stackoverflow.com/a/21659588 | |
def _find_getch(): | |
try: import termios | |
except ImportError: | |
# Non-POSIX. Return msvcrt's (Windows') getch. | |
import msvcrt | |
return msvcrt.getch | |
# POSIX system. Create and return a getch that manipulates the tty. | |
import tty | |
def _getch(): | |
fd = sys.stdin.fileno() | |
old_settings = termios.tcgetattr(fd) | |
try: | |
tty.setraw(fd) | |
ch = sys.stdin.read(1) | |
finally: | |
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) | |
return ch | |
return _getch | |
getch = _find_getch() | |
def select(items, pattern): | |
if not pattern: | |
return items[:] | |
return [item for item in items if pattern in item] | |
def format(items, pattern, position): | |
selected = select(items, pattern) | |
try: | |
selected_item = selected[position] | |
selected[position] = "*%s*" % selected[position] | |
# selected = selected[position:] | |
except IndexError: | |
selected_item = None | |
output = pattern + ": " + ", ".join(selected) | |
if len(output) > 79: | |
output = output[:76].rstrip(", ") | |
output += "..." | |
write("\r") | |
write(output + (" " * (79 - len(output)))) | |
sys.stdout.flush() | |
return len(selected), selected_item | |
def choose(choices): | |
pattern = "" | |
position = 0 | |
count, selected = format(choices, pattern, position) | |
cancelled = False | |
while True: | |
ch = getch() | |
# print(repr(ch)) | |
if ch in {"\x03", "\x04"}: # C-c C-d | |
cancelled = True | |
break | |
elif ch in {"\n", "\r"}: | |
break | |
elif ch == "\x1b": | |
a = getch() | |
b = getch() | |
if (a == "[") and (b == "C"): # Right Arrow | |
if position < (count - 1): | |
position += 1 | |
elif (a == "[") and (b == "D"): # Left Arrow | |
if position > 0: | |
position -= 1 | |
elif ch == "\x7f": | |
if pattern: | |
pattern = pattern[:-1] | |
elif ch.isprintable(): | |
pattern += ch | |
count, selected = format(choices, pattern, position) | |
if not cancelled: | |
print() | |
return selected | |
else: | |
print() | |
return None | |
def main(): | |
selection = choose(countries) | |
print("Selection:", selection) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment