Index: uspace/app/nav/nav.c
===================================================================
--- uspace/app/nav/nav.c	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/app/nav/nav.c	(revision a7a16a2fd2fee7aed47cced53b3602609b317c8c)
@@ -70,7 +70,9 @@
 
 static void navigator_panel_activate_req(void *, panel_t *);
+static void navigator_panel_file_open(void *, panel_t *, const char *);
 
 static panel_cb_t navigator_panel_cb = {
-	.activate_req = navigator_panel_activate_req
+	.activate_req = navigator_panel_activate_req,
+	.file_open = navigator_panel_file_open
 };
 
@@ -328,5 +330,5 @@
 /** Open file in text editor.
  *
- * @param panel Panel
+ * @param navigator Navigator
  * @param fname File name
  *
@@ -367,4 +369,67 @@
 }
 
+/** Execute file entry.
+ *
+ * @param navigator Navigator
+ * @param fname File name
+ *
+ * @return EOK on success or an error code
+ */
+static errno_t navigator_exec_file(navigator_t *navigator, const char *fname)
+{
+	task_id_t id;
+	task_wait_t wait;
+	task_exit_t texit;
+	int retval;
+	errno_t rc;
+
+	/* Free up and clean console for the child task. */
+	rc = ui_suspend(navigator->ui);
+	if (rc != EOK)
+		return rc;
+
+	rc = task_spawnl(&id, &wait, fname, fname, NULL);
+	if (rc != EOK)
+		goto error;
+
+	rc = task_wait(&wait, &texit, &retval);
+	if ((rc != EOK) || (texit != TASK_EXIT_NORMAL))
+		goto error;
+
+	/* Resume UI operation */
+	rc = ui_resume(navigator->ui);
+	if (rc != EOK)
+		return rc;
+
+	(void) ui_paint(navigator->ui);
+	return EOK;
+error:
+	(void) ui_resume(navigator->ui);
+	(void) ui_paint(navigator->ui);
+	return rc;
+}
+
+/** Open panel file entry.
+ *
+ * Perform Open action on a file entry (based on extension).
+ *
+ * @param navigator Navigator
+ * @param fname File name
+ *
+ * @return EOK on success or an error code
+ */
+static errno_t navigator_open_file(navigator_t *navigator, const char *fname)
+{
+	const char *ext;
+
+	ext = str_rchr(fname, '.');
+	if (ext != NULL) {
+		if (str_casecmp(ext, ".txt") == 0)
+			return navigator_edit_file(navigator, fname);
+	}
+
+	return navigator_exec_file(navigator, fname);
+}
+
 /** File / Edit menu entry selected */
 static void navigator_file_edit(void *arg)
@@ -403,4 +468,18 @@
 }
 
+/** Panel callback requesting file open.
+ *
+ * @param arg Argument (navigator_t *)
+ * @param panel Panel
+ * @param fname File name
+ */
+void navigator_panel_file_open(void *arg, panel_t *panel, const char *fname)
+{
+	navigator_t *navigator = (navigator_t *)arg;
+
+	(void)panel;
+	navigator_open_file(navigator, fname);
+}
+
 /** @}
  */
Index: uspace/app/nav/panel.c
===================================================================
--- uspace/app/nav/panel.c	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/app/nav/panel.c	(revision a7a16a2fd2fee7aed47cced53b3602609b317c8c)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2023 Jiri Svoboda
+ * Copyright (c) 2025 Jiri Svoboda
  * All rights reserved.
  *
@@ -377,50 +377,4 @@
 }
 
-/** Open panel file entry.
- *
- * Perform Open action on a file entry (i.e. try running it).
- *
- * @param panel Panel
- * @param fname File name
- *
- * @return EOK on success or an error code
- */
-static errno_t panel_open_file(panel_t *panel, const char *fname)
-{
-	task_id_t id;
-	task_wait_t wait;
-	task_exit_t texit;
-	int retval;
-	errno_t rc;
-	ui_t *ui;
-
-	ui = ui_window_get_ui(panel->window);
-
-	/* Free up and clean console for the child task. */
-	rc = ui_suspend(ui);
-	if (rc != EOK)
-		return rc;
-
-	rc = task_spawnl(&id, &wait, fname, fname, NULL);
-	if (rc != EOK)
-		goto error;
-
-	rc = task_wait(&wait, &texit, &retval);
-	if ((rc != EOK) || (texit != TASK_EXIT_NORMAL))
-		goto error;
-
-	/* Resume UI operation */
-	rc = ui_resume(ui);
-	if (rc != EOK)
-		return rc;
-
-	(void) ui_paint(ui_window_get_ui(panel->window));
-	return EOK;
-error:
-	(void) ui_resume(ui);
-	(void) ui_paint(ui_window_get_ui(panel->window));
-	return rc;
-}
-
 /** File list in panel requests activation.
  *
@@ -446,5 +400,6 @@
 	panel_t *panel = (panel_t *)arg;
 
-	(void) panel_open_file(panel, fname);
+	if (panel->cb != NULL && panel->cb->file_open != NULL)
+		panel->cb->file_open(panel->cb_arg, panel, fname);
 }
 
Index: uspace/app/nav/types/panel.h
===================================================================
--- uspace/app/nav/types/panel.h	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/app/nav/types/panel.h	(revision a7a16a2fd2fee7aed47cced53b3602609b317c8c)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2025 Jiri Svoboda
  * All rights reserved.
  *
@@ -80,4 +80,6 @@
 	/** Request panel activation */
 	void (*activate_req)(void *, panel_t *);
+	/** Open file */
+	void (*file_open)(void *, panel_t *, const char *);
 } panel_cb_t;
 
