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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: make_selection
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: Package for interactive command line menu
5
5
  Author-email: Steven Frazee <stevefrazee123@gmail.com>
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "make_selection"
3
- version = "0.0.1"
3
+ version = "0.0.2"
4
4
  authors = [
5
5
  { name="Steven Frazee", email="stevefrazee123@gmail.com" },
6
6
  ]
@@ -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 < window_size
35
- if len(options) < window_size:
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.indices = []
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.window_original_size = window_size
46
- self.window_current_size = window_size
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.window_current_size
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.window_current_size + 1
73
- elif self.isAscii(char) or (char == SPACEBAR and 0 < len(self.search_string)):
74
- # TODO: search string
75
- pass
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
- # TODO: search string
78
- pass
79
- elif char == ENTER_KEY:
80
- if self.options_current:
81
- self.printSelected()
82
- return self.options_original[self.selected_index]
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 getChar(self):
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 isAscii(self, char):
96
- return (33 <= char and char <= 126)
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.window_current_size
106
- for i in range(self.window_top, bottom):
107
- if i == self.selected_index:
108
- print(f"{ANSI_HIGHLIGHT}{self.options_current[i]}{ANSI_RESET}")
109
- else:
110
- print(self.options_current[i])
111
- print(f"{ANSI_YELLOW}{self.help_string}{ANSI_RESET}\n{ANSI_MOVE_CURSOR.format(up=self.window_current_size + 2, right=len(self.label) + len(self.search_string) + 1)}", end="", flush=True)
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(["interactive", "cli", "menu"], "make_selection")
167
+ print(f"Returns: '{makeSelection(['interactive', 'cli', 'menu'], 'make_selection')}'")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: make_selection
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: Package for interactive command line menu
5
5
  Author-email: Steven Frazee <stevefrazee123@gmail.com>
6
6
  Classifier: License :: OSI Approved :: MIT License
File without changes
File without changes
File without changes