Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions archinstall/applications/editor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from typing import TYPE_CHECKING

from archinstall.lib.models.application import Editor, EditorConfiguration
from archinstall.lib.output import debug

if TYPE_CHECKING:
from archinstall.lib.installer import Installer


class EditorApp:
def _get_editor_binary(self, editor: Editor) -> str:
# special handling only name that differs
return 'nvim' if editor == Editor.NEOVIM else editor.value
Copy link
Contributor

@codefiles codefiles Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The paradigm used by this repo is to add functionality like this to the enum. Consider following that convention and moving this method to Editor instead and removing the underscore(_) that designates it as intending to be private.

Here are two instances of this paradigm being used in the repo (there are more):

Copy link
Contributor

@codefiles codefiles Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this suggestion can be ignored because you are following the convention set by archinstall/lib/models/application.py and other files in archinstall/applications.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See latest commit ;)


def install(
self,
install_session: 'Installer',
editor_config: EditorConfiguration,
) -> None:
debug(f'Installing editor: {editor_config.editor.value}')

install_session.add_additional_packages([editor_config.editor.value])

editor_binary = self._get_editor_binary(editor_config.editor)
environment_path = install_session.target / 'etc' / 'environment'

debug(f'Setting EDITOR={editor_binary} in {environment_path}')

with open(environment_path, 'a') as f:
f.write(f'EDITOR={editor_binary}\n')
2 changes: 0 additions & 2 deletions archinstall/default_profiles/desktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ def __init__(self, current_selection: list[Profile] = []) -> None:
@override
def packages(self) -> list[str]:
return [
'nano',
'vim',
'openssh',
'htop',
'wget',
Expand Down
7 changes: 7 additions & 0 deletions archinstall/lib/applications/application_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from archinstall.applications.audio import AudioApp
from archinstall.applications.bluetooth import BluetoothApp
from archinstall.applications.editor import EditorApp
from archinstall.applications.firewall import FirewallApp
from archinstall.applications.power_management import PowerManagementApp
from archinstall.applications.print_service import PrintServiceApp
Expand Down Expand Up @@ -43,5 +44,11 @@ def install_applications(self, install_session: 'Installer', app_config: Applica
app_config.firewall_config,
)

if app_config.editor_config:
EditorApp().install(
install_session,
app_config.editor_config,
)


application_handler = ApplicationHandler()
37 changes: 37 additions & 0 deletions archinstall/lib/applications/application_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
Audio,
AudioConfiguration,
BluetoothConfiguration,
Editor,
EditorConfiguration,
Firewall,
FirewallConfiguration,
PowerManagement,
Expand Down Expand Up @@ -78,6 +80,12 @@ def _define_menu_options(self) -> list[MenuItem]:
preview_action=self._prev_firewall,
key='firewall_config',
),
MenuItem(
text=tr('Editor'),
action=select_editor,
preview_action=self._prev_editor,
key='editor_config',
),
]

def _prev_power_management(self, item: MenuItem) -> str | None:
Expand Down Expand Up @@ -116,6 +124,12 @@ def _prev_firewall(self, item: MenuItem) -> str | None:
return f'{tr("Firewall")}: {config.firewall.value}'
return None

def _prev_editor(self, item: MenuItem) -> str | None:
if item.value is not None:
config: EditorConfiguration = item.value
return f'{tr("Editor")}: {config.editor.value}'
return None


def select_power_management(preset: PowerManagementConfiguration | None = None) -> PowerManagementConfiguration | None:
group = MenuItemGroup.from_enum(PowerManagement)
Expand Down Expand Up @@ -240,3 +254,26 @@ def select_firewall(preset: FirewallConfiguration | None = None) -> FirewallConf
return FirewallConfiguration(firewall=result.get_value())
case ResultType.Reset:
return None


def select_editor(preset: EditorConfiguration | None = None) -> EditorConfiguration | None:
group = MenuItemGroup.from_enum(Editor)

if preset:
group.set_focus_by_value(preset.editor)

result = SelectMenu[Editor](
group,
allow_skip=True,
alignment=Alignment.CENTER,
allow_reset=True,
frame=FrameProperties.min(tr('Editor')),
).run()

match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
return EditorConfiguration(editor=result.get_value())
case ResultType.Reset:
return None
10 changes: 10 additions & 0 deletions archinstall/lib/global_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,16 @@ def _prev_applications(self, item: MenuItem) -> str | None:
output += f'{tr("Power management")}: {power_management_config.power_management.value}'
output += '\n'

if app_config.firewall_config:
firewall_config = app_config.firewall_config
output += f'{tr("Firewall")}: {firewall_config.firewall.value}'
output += '\n'

if app_config.editor_config:
editor_config = app_config.editor_config
output += f'{tr("Editor")}: {editor_config.editor.value}'
output += '\n'

return output

return None
Expand Down
37 changes: 37 additions & 0 deletions archinstall/lib/models/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ class FirewallConfigSerialization(TypedDict):
firewall: str


class Editor(StrEnum):
NANO = auto()
MICRO = auto()
VI = auto()
VIM = auto()
NEOVIM = auto()
EMACS = auto()


class EditorConfigSerialization(TypedDict):
editor: str


class ZramAlgorithm(StrEnum):
ZSTD = 'zstd'
LZO_RLE = 'lzo-rle'
Expand All @@ -52,6 +65,7 @@ class ApplicationSerialization(TypedDict):
power_management_config: NotRequired[PowerManagementConfigSerialization]
print_service_config: NotRequired[PrintServiceConfigSerialization]
firewall_config: NotRequired[FirewallConfigSerialization]
editor_config: NotRequired[EditorConfigSerialization]


@dataclass
Expand Down Expand Up @@ -126,6 +140,22 @@ def parse_arg(arg: dict[str, Any]) -> 'FirewallConfiguration':
)


@dataclass
class EditorConfiguration:
editor: Editor

def json(self) -> EditorConfigSerialization:
return {
'editor': self.editor.value,
}

@staticmethod
def parse_arg(arg: dict[str, Any]) -> 'EditorConfiguration':
return EditorConfiguration(
Editor(arg['editor']),
)


@dataclass(frozen=True)
class ZramConfiguration:
enabled: bool
Expand All @@ -148,6 +178,7 @@ class ApplicationConfiguration:
power_management_config: PowerManagementConfiguration | None = None
print_service_config: PrintServiceConfiguration | None = None
firewall_config: FirewallConfiguration | None = None
editor_config: EditorConfiguration | None = None

@staticmethod
def parse_arg(
Expand Down Expand Up @@ -175,6 +206,9 @@ def parse_arg(
if args and (firewall_config := args.get('firewall_config')) is not None:
app_config.firewall_config = FirewallConfiguration.parse_arg(firewall_config)

if args and (editor_config := args.get('editor_config')) is not None:
app_config.editor_config = EditorConfiguration.parse_arg(editor_config)

return app_config

def json(self) -> ApplicationSerialization:
Expand All @@ -195,4 +229,7 @@ def json(self) -> ApplicationSerialization:
if self.firewall_config:
config['firewall_config'] = self.firewall_config.json()

if self.editor_config:
config['editor_config'] = self.editor_config.json()

return config