Repository: archlinux/archinstall

Issue:
Can not write known profile-names in the profile step
I can not write `awesome` in the profile step of the guided installer.
This is a regression in feature and I would very much like that back.

This probably got lost when we created the `top_level` profiles, which means you have to go through desktop first (which installs a bunch of stuff) just to get to awesome.

I'd very much like to be able to write *known* profiles directly in this step and bypass jumping through hoops.


Discussion:
> I can not write `awesome` in the profile step of the guided installer.
> This is a regression in feature and I would very much like that back.
> 
> This probably got lost when we created the `top_level` profiles, which means you have to go through desktop first (which installs a bunch of stuff) just to get to awesome.
> 
> I'd very much like to be able to write _known_ profiles directly in this step and bypass jumping through hoops.

I don't know if there's an easy fix for this; awesome is in a sense a child profile of desktop. A lot of the common installation stuff for desktops is handled in the desktop top level profile to keep the individual desktop profiles clean, and just installing awesome without doing the desktop and awesome profile would lead to a bad experience, probably broken because of missing xdg-utils in awesome's case.
It's odd that we can do profile: "gnome" in the config file yet this is an issue - I think this is because the generic select is validating it's in the list that is passed to it. Maybe we need a way to handle hidden values that are accepted but not displayed? It's going to be tricky.
I think we could do @SecondThundeR's trick of [printing our own list](https://github.com/archlinux/archinstall/blob/49e6cbdc545402e066bdc2daf6054abf6c1bf977/archinstall/lib/user_interaction.py#L403-L407), giving `generic_select()` a different list (that matches index wise) but call `generic_select(options, options_output=False)`. That way, we can have generic select absolut inputs validated and returned, but hidden from the output.
> I think we could do @SecondThundeR's trick of [printing our own list](https://github.com/archlinux/archinstall/blob/49e6cbdc545402e066bdc2daf6054abf6c1bf977/archinstall/lib/user_interaction.py#L403-L407), giving `generic_select()` a different list (that matches index wise) but call `generic_select(options, options_output=False)`. That way, we can have generic select absolut inputs validated and returned, but hidden from the output.

So use the filter logic to print the list, and then use the full list of profiles for validation in generic select

Resolving patch:
diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py
--- a/archinstall/lib/user_interaction.py
+++ b/archinstall/lib/user_interaction.py
@@ -17,7 +17,7 @@
 from .locale_helpers import list_keyboard_languages, verify_keyboard_layout, search_keyboard_layout
 from .networking import list_interfaces
 from .output import log
-from .profiles import Profile
+from .profiles import Profile, list_profiles
 
 
 # TODO: Some inconsistencies between the selection processes.
@@ -563,28 +563,25 @@ def select_disk(dict_o_disks):
 	raise DiskError('select_disk() requires a non-empty dictionary of disks to select from.')
 
 
-def select_profile(options):
+def select_profile():
 	"""
-	Asks the user to select a profile from the `options` dictionary parameter.
-	Usually this is combined with :ref:`archinstall.list_profiles`.
-
-	:param options: A `dict` where keys are the profile name, value should be a dict containing profile information.
-	:type options: dict
+	Asks the user to select a profile from the available profiles.
 
 	:return: The name/dictionary key of the selected profile
 	:rtype: str
 	"""
-	profiles = sorted(list(options))
+	shown_profiles = sorted(list(list_profiles(filter_top_level_profiles=True)))
+	actual_profiles_raw = shown_profiles + sorted([profile for profile in list_profiles() if profile not in shown_profiles])
 
-	if len(profiles) >= 1:
-		for index, profile in enumerate(profiles):
+	if len(shown_profiles) >= 1:
+		for index, profile in enumerate(shown_profiles):
 			print(f"{index}: {profile}")
 
 		print(' -- The above list is a set of pre-programmed profiles. --')
 		print(' -- They might make it easier to install things like desktop environments. --')
 		print(' -- (Leave blank and hit enter to skip this step and continue) --')
 
-		selected_profile = generic_select(profiles, 'Enter a pre-programmed profile name if you want to install one: ', options_output=False)
+		selected_profile = generic_select(actual_profiles_raw, 'Enter a pre-programmed profile name if you want to install one: ', options_output=False)
 		if selected_profile:
 			return Profile(None, selected_profile)
 	else:
diff --git a/examples/guided.py b/examples/guided.py
--- a/examples/guided.py
+++ b/examples/guided.py
@@ -54,13 +54,13 @@ def ask_user_questions():
 	if not archinstall.arguments.get('sys-language', None) and archinstall.arguments.get('advanced', False):
 		archinstall.arguments['sys-language'] = input("Enter a valid locale (language) for your OS, (Default: en_US): ").strip()
 		archinstall.arguments['sys-encoding'] = input("Enter a valid system default encoding for your OS, (Default: utf-8): ").strip()
+		archinstall.log("Keep in mind that if you want multiple locales, post configuration is required.", fg="yellow")
 
-		if not archinstall.arguments['sys-language']:
-			archinstall.arguments['sys-language'] = 'en_US'
-		if not archinstall.arguments['sys-encoding']:
-			archinstall.arguments['sys-encoding'] = 'utf-8'
+	if not archinstall.arguments.get('sys-language', None):
+		archinstall.arguments['sys-language'] = 'en_US'
+	if not archinstall.arguments.get('sys-encoding', None):
+		archinstall.arguments['sys-encoding'] = 'utf-8'
 
-		archinstall.log("Keep in mind that if you want multiple locales, post configuration is required.", fg="yellow")
 
 	# Ask which harddrive/block-device we will install to
 	if archinstall.arguments.get('harddrive', None):
@@ -193,7 +193,7 @@ def ask_user_questions():
 
 	# Ask for archinstall-specific profiles (such as desktop environments etc)
 	if not archinstall.arguments.get('profile', None):
-		archinstall.arguments['profile'] = archinstall.select_profile(archinstall.list_profiles(filter_top_level_profiles=True))
+		archinstall.arguments['profile'] = archinstall.select_profile()
 	else:
 		archinstall.arguments['profile'] = Profile(installer=None, path=archinstall.arguments['profile'])
 


Test patch: