Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib/menu/simple_menu.py
diff options
context:
space:
mode:
authorDaniel <blackrabbit256@gmail.com>2022-04-12 19:46:55 +1000
committerGitHub <noreply@github.com>2022-04-12 11:46:55 +0200
commit4f899e3866d81d0e7fec5d496578a0fe81617e72 (patch)
treea643ac193e4ea03ccc3bdcc06ffc4add80a38d9a /archinstall/lib/menu/simple_menu.py
parentf644022e0cbcb13069ea8caff4d5791db3925911 (diff)
Downstream new simple menu feature (#1055)
* Downstream new simple menu feature * Fix flake8 * Update * Fix flake8 Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
Diffstat (limited to 'archinstall/lib/menu/simple_menu.py')
-rw-r--r--archinstall/lib/menu/simple_menu.py74
1 files changed, 54 insertions, 20 deletions
diff --git a/archinstall/lib/menu/simple_menu.py b/archinstall/lib/menu/simple_menu.py
index a9d6d7ec..a0a241bd 100644
--- a/archinstall/lib/menu/simple_menu.py
+++ b/archinstall/lib/menu/simple_menu.py
@@ -298,6 +298,7 @@ class TerminalMenu:
selection: "TerminalMenu.Selection",
viewport: "TerminalMenu.Viewport",
cycle_cursor: bool = True,
+ skip_indices: List[int] = [],
):
self._menu_entries = list(menu_entries)
self._search = search
@@ -305,6 +306,7 @@ class TerminalMenu:
self._viewport = viewport
self._cycle_cursor = cycle_cursor
self._active_displayed_index = None # type: Optional[int]
+ self._skip_indices = skip_indices
self.update_view()
def update_view(self) -> None:
@@ -328,6 +330,9 @@ class TerminalMenu:
self._active_displayed_index = 0
self._viewport.keep_visible(self._active_displayed_index)
+ if self._active_displayed_index in self._skip_indices:
+ self.increment_active_index()
+
def decrement_active_index(self) -> None:
if self._active_displayed_index is not None:
if self._active_displayed_index > 0:
@@ -336,6 +341,9 @@ class TerminalMenu:
self._active_displayed_index = len(self._displayed_index_to_menu_index) - 1
self._viewport.keep_visible(self._active_displayed_index)
+ if self._active_displayed_index in self._skip_indices:
+ self.decrement_active_index()
+
def is_visible(self, menu_index: int) -> bool:
return menu_index in self._menu_index_to_displayed_index and (
self._viewport.lower_index
@@ -584,6 +592,7 @@ class TerminalMenu:
show_search_hint_text: Optional[str] = None,
show_shortcut_hints: bool = DEFAULT_SHOW_SHORTCUT_HINTS,
show_shortcut_hints_in_status_bar: bool = DEFAULT_SHOW_SHORTCUT_HINTS_IN_STATUS_BAR,
+ skip_empty_entries: bool = False,
status_bar: Optional[Union[str, Iterable[str], Callable[[str], str]]] = None,
status_bar_below_preview: bool = DEFAULT_STATUS_BAR_BELOW_PREVIEW,
status_bar_style: Optional[Iterable[str]] = DEFAULT_STATUS_BAR_STYLE,
@@ -591,24 +600,35 @@ class TerminalMenu:
):
def extract_shortcuts_menu_entries_and_preview_arguments(
entries: Iterable[str],
- ) -> Tuple[List[str], List[str], List[str]]:
+ ) -> Tuple[List[str], List[Optional[str]], List[Optional[str]], List[int]]:
separator_pattern = re.compile(r"([^\\])\|")
escaped_separator_pattern = re.compile(r"\\\|")
menu_entry_pattern = re.compile(r"^(?:\[(\S)\]\s*)?([^\x1F]+)(?:\x1F([^\x1F]*))?")
- shortcut_keys = []
- menu_entries = []
- preview_arguments = []
- for entry in entries:
- unit_separated_entry = escaped_separator_pattern.sub("|", separator_pattern.sub("\\1\x1F", entry))
- match_obj = menu_entry_pattern.match(unit_separated_entry)
- assert match_obj is not None
- shortcut_key = match_obj.group(1)
- display_text = match_obj.group(2)
- preview_argument = match_obj.group(3)
- shortcut_keys.append(shortcut_key)
- menu_entries.append(display_text)
- preview_arguments.append(preview_argument)
- return menu_entries, shortcut_keys, preview_arguments
+ shortcut_keys = [] # type: List[Optional[str]]
+ menu_entries = [] # type: List[str]
+ preview_arguments = [] # type: List[Optional[str]]
+ skip_indices = [] # type: List[int]
+
+ for idx, entry in enumerate(entries):
+ if entry is None or (entry == "" and skip_empty_entries):
+ shortcut_keys.append(None)
+ menu_entries.append("")
+ preview_arguments.append(None)
+ skip_indices.append(idx)
+ else:
+ unit_separated_entry = escaped_separator_pattern.sub("|", separator_pattern.sub("\\1\x1F", entry))
+ match_obj = menu_entry_pattern.match(unit_separated_entry)
+ # this is none in case the entry was an emtpy string which
+ # will be interpreted as a separator
+ assert match_obj is not None
+ shortcut_key = match_obj.group(1)
+ display_text = match_obj.group(2)
+ preview_argument = match_obj.group(3)
+ shortcut_keys.append(shortcut_key)
+ menu_entries.append(display_text)
+ preview_arguments.append(preview_argument)
+
+ return menu_entries, shortcut_keys, preview_arguments, skip_indices
def convert_preselected_entries_to_indices(
preselected_indices_or_entries: Iterable[Union[str, int]]
@@ -641,7 +661,7 @@ class TerminalMenu:
title_or_status_bar: Optional[Union[str, Iterable[str]]],
show_shortcut_hints: bool,
menu_entries: Iterable[str],
- shortcut_keys: Iterable[str],
+ shortcut_keys: Iterable[Optional[str]],
shortcut_hints_in_parentheses: bool,
) -> Tuple[str, ...]:
if title_or_status_bar is None:
@@ -662,6 +682,7 @@ class TerminalMenu:
self._menu_entries,
self._shortcut_keys,
self._preview_arguments,
+ self._skip_indices,
) = extract_shortcuts_menu_entries_and_preview_arguments(menu_entries)
self._shortcuts_defined = any(key is not None for key in self._shortcut_keys)
self._accept_keys = tuple(accept_keys)
@@ -749,7 +770,9 @@ class TerminalMenu:
0,
0,
)
- self._view = self.View(self._menu_entries, self._search, self._selection, self._viewport, self._cycle_cursor)
+ self._view = self.View(
+ self._menu_entries, self._search, self._selection, self._viewport, self._cycle_cursor, self._skip_indices
+ )
if cursor_index and 0 < cursor_index < len(self._menu_entries):
self._view.active_menu_index = cursor_index
self._search.change_callback = self._view.update_view
@@ -767,7 +790,7 @@ class TerminalMenu:
@staticmethod
def _get_shortcut_hints_line(
menu_entries: Iterable[str],
- shortcut_keys: Iterable[str],
+ shortcut_keys: Iterable[Optional[str]],
shortcut_hints_in_parentheses: bool,
) -> Optional[str]:
shortcut_hints_line = ", ".join(
@@ -1139,7 +1162,7 @@ class TerminalMenu:
e.stderr.decode(encoding=self._user_locale, errors="replace").strip()
) from e
else:
- preview_string = self._preview_command(preview_argument)
+ preview_string = self._preview_command(preview_argument) if preview_argument is not None else ""
return preview_string
@static_variables(
@@ -1336,7 +1359,9 @@ class TerminalMenu:
displayed_index = 0
for displayed_index, _, _ in self._view:
self._tty_out.write("\r" + cursor_width * self._codename_to_terminal_code["cursor_right"])
- if displayed_index in displayed_selected_indices:
+ if displayed_index in self._skip_indices:
+ self._tty_out.write("")
+ elif displayed_index in displayed_selected_indices:
self._tty_out.write(checked_multi_select_cursor)
else:
self._tty_out.write(unchecked_multi_select_cursor)
@@ -1780,6 +1805,12 @@ def get_argumentparser() -> argparse.ArgumentParser:
help="show shortcut hints in the menu title",
)
parser.add_argument(
+ "--skip-empty-entries",
+ action="store_true",
+ dest="skip_empty_entries",
+ help="Interpret an empty string in menu entries as an empty menu entry",
+ )
+ parser.add_argument(
"-b",
"--status-bar",
action="store",
@@ -1837,6 +1868,8 @@ def parse_arguments() -> AttributeDict:
args = AttributeDict({key: value for key, value in vars(parser.parse_args()).items()})
if not args.print_version and not args.entries:
raise NoMenuEntriesError("No menu entries given!")
+ if args.skip_empty_entries:
+ args.entries = [entry if entry != "None" else None for entry in args.entries]
if args.cursor_style != "":
args.cursor_style = tuple(args.cursor_style.split(","))
else:
@@ -1933,6 +1966,7 @@ def main() -> None:
show_search_hint_text=args.show_search_hint_text,
show_shortcut_hints=args.show_shortcut_hints,
show_shortcut_hints_in_status_bar=args.show_shortcut_hints_in_status_bar,
+ skip_empty_entries=args.skip_empty_entries,
status_bar=args.status_bar,
status_bar_below_preview=args.status_bar_below_preview,
status_bar_style=args.status_bar_style,