make-selection 0.0.1__tar.gz → 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {make_selection-0.0.1 → make_selection-0.0.2}/PKG-INFO +1 -1
- {make_selection-0.0.1 → make_selection-0.0.2}/pyproject.toml +1 -1
- {make_selection-0.0.1 → make_selection-0.0.2}/src/make_selection/make_selection.py +55 -28
- {make_selection-0.0.1 → make_selection-0.0.2}/src/make_selection.egg-info/PKG-INFO +1 -1
- {make_selection-0.0.1 → make_selection-0.0.2}/LICENSE +0 -0
- {make_selection-0.0.1 → make_selection-0.0.2}/README.md +0 -0
- {make_selection-0.0.1 → make_selection-0.0.2}/setup.cfg +0 -0
- {make_selection-0.0.1 → make_selection-0.0.2}/src/make_selection/__init__.py +0 -0
- {make_selection-0.0.1 → make_selection-0.0.2}/src/make_selection.egg-info/SOURCES.txt +0 -0
- {make_selection-0.0.1 → make_selection-0.0.2}/src/make_selection.egg-info/dependency_links.txt +0 -0
- {make_selection-0.0.1 → make_selection-0.0.2}/src/make_selection.egg-info/top_level.txt +0 -0
|
@@ -31,19 +31,18 @@ class Menu:
|
|
|
31
31
|
def __init__(self, options: list, label: str, window_size: int=10) -> None:
|
|
32
32
|
assert options
|
|
33
33
|
assert label
|
|
34
|
-
assert 1
|
|
35
|
-
|
|
36
|
-
window_size = len(options)
|
|
34
|
+
assert 1 <= window_size
|
|
35
|
+
window_size = min((len(options)), window_size)
|
|
37
36
|
|
|
38
37
|
self.options_original = options
|
|
39
38
|
self.options_current = options
|
|
40
|
-
self.
|
|
39
|
+
self.search_indices = []
|
|
41
40
|
self.search_string = ""
|
|
42
41
|
self.label = label
|
|
43
42
|
self.selected_index = 0
|
|
44
43
|
self.window_top = 0
|
|
45
|
-
self.
|
|
46
|
-
self.
|
|
44
|
+
self.window_size_original = window_size
|
|
45
|
+
self.window_size_current = window_size
|
|
47
46
|
self.help_string = "Enter: Select, Ctl+C: Cancel"
|
|
48
47
|
|
|
49
48
|
def show(self):
|
|
@@ -65,21 +64,27 @@ class Menu:
|
|
|
65
64
|
|
|
66
65
|
# Update window
|
|
67
66
|
if something_changed:
|
|
68
|
-
bottom = self.window_top + self.
|
|
67
|
+
bottom = self.window_top + self.window_size_current
|
|
69
68
|
if self.selected_index < self.window_top:
|
|
70
69
|
self.window_top = self.selected_index
|
|
71
70
|
elif bottom <= self.selected_index:
|
|
72
|
-
self.window_top = self.selected_index - self.
|
|
73
|
-
elif self.
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
self.window_top = self.selected_index - self.window_size_current + 1
|
|
72
|
+
elif self.isSearchableChar(char):
|
|
73
|
+
char = chr(char)
|
|
74
|
+
self.search_string = f"{self.search_string}{char}".lstrip()
|
|
75
|
+
if self.search_string:
|
|
76
|
+
print(char, end="", flush=True)
|
|
77
|
+
self.search(self.options_current)
|
|
78
|
+
something_changed = True
|
|
76
79
|
elif char == BACKSPACE and 0 < len(self.search_string):
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
self.search_string = self.search_string[:-1]
|
|
81
|
+
# Move left, print space, move left again
|
|
82
|
+
print("\x1b[1D \x1b[1D", end="", flush=True)
|
|
83
|
+
self.search(self.options_original)
|
|
84
|
+
something_changed = True
|
|
85
|
+
elif char == ENTER_KEY and self.options_current:
|
|
86
|
+
self.printSelected()
|
|
87
|
+
return self.options_current[self.selected_index]
|
|
83
88
|
elif char == CTL_C:
|
|
84
89
|
self.clearMenu(clear_label=True)
|
|
85
90
|
print("cancelled")
|
|
@@ -89,11 +94,27 @@ class Menu:
|
|
|
89
94
|
self.clearMenu()
|
|
90
95
|
self.printMenu()
|
|
91
96
|
|
|
92
|
-
def
|
|
97
|
+
def search(self, search_list: list) -> None:
|
|
98
|
+
found_indices = []
|
|
99
|
+
found_options = []
|
|
100
|
+
for o in search_list:
|
|
101
|
+
found_i = str(o).lower().find(self.search_string.lower())
|
|
102
|
+
if found_i != -1:
|
|
103
|
+
found_indices.append(found_i)
|
|
104
|
+
found_options.append(o)
|
|
105
|
+
self.options_current = found_options
|
|
106
|
+
self.search_indices = found_indices
|
|
107
|
+
|
|
108
|
+
# Reset window after modifying options
|
|
109
|
+
self.window_top = 0
|
|
110
|
+
self.selected_index = 0
|
|
111
|
+
self.window_size_current = min((len(self.options_current), self.window_size_original))
|
|
112
|
+
|
|
113
|
+
def getChar(self) -> int:
|
|
93
114
|
return ord(msvcrt.getch())
|
|
94
115
|
|
|
95
|
-
def
|
|
96
|
-
return (
|
|
116
|
+
def isSearchableChar(self, char):
|
|
117
|
+
return (32 <= char and char <= 126)
|
|
97
118
|
|
|
98
119
|
def clearMenu(self, clear_label=False):
|
|
99
120
|
if clear_label:
|
|
@@ -102,13 +123,19 @@ class Menu:
|
|
|
102
123
|
print("\x1b[J")
|
|
103
124
|
|
|
104
125
|
def printMenu(self):
|
|
105
|
-
bottom = self.window_top + self.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
126
|
+
bottom = self.window_top + self.window_size_current
|
|
127
|
+
if not self.options_current:
|
|
128
|
+
print(f"{ANSI_BLUE}no matches found{ANSI_RESET}")
|
|
129
|
+
# NOTE: window size is 0 here after empty search, but we are printing 1 line
|
|
130
|
+
# so we need to set it so the footer prints correctly
|
|
131
|
+
self.window_size_current = 1
|
|
132
|
+
else:
|
|
133
|
+
for i in range(self.window_top, bottom):
|
|
134
|
+
if i == self.selected_index:
|
|
135
|
+
print(f"{ANSI_HIGHLIGHT}{self.options_current[i]}{ANSI_RESET}")
|
|
136
|
+
else:
|
|
137
|
+
print(self.options_current[i])
|
|
138
|
+
print(f"{ANSI_YELLOW}{self.help_string}{ANSI_RESET}\n{ANSI_MOVE_CURSOR.format(up=self.window_size_current + 2, right=len(self.label) + len(self.search_string) + 1)}", end="", flush=True)
|
|
112
139
|
|
|
113
140
|
def printSelected(self):
|
|
114
141
|
self.clearMenu(clear_label=True)
|
|
@@ -137,4 +164,4 @@ def makeSelection(options: list[Any], label: str, window_size: int=None) -> Any:
|
|
|
137
164
|
return Menu(options, label).show()
|
|
138
165
|
|
|
139
166
|
if __name__ == "__main__":
|
|
140
|
-
makeSelection([
|
|
167
|
+
print(f"Returns: '{makeSelection(['interactive', 'cli', 'menu'], 'make_selection')}'")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{make_selection-0.0.1 → make_selection-0.0.2}/src/make_selection.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|