From 101318e911d459a7cbe2d488eec6b6341886e8e7 Mon Sep 17 00:00:00 2001 From: Ramon Brullo Date: Mon, 13 Oct 2025 12:02:08 +0200 Subject: [PATCH 1/9] Added hard-coded open-in-editor This change adds a quick-action for opening the current repo in editor. Right now, it is hardcoded to open it in VSCodium, since that is what I have installed, but the next change should make it configurable. --- .../com/jetpackduba/gitnuro/ui/RepositoryOpen.kt | 1 + .../gitnuro/ui/dialogs/QuickActionsDialog.kt | 2 ++ .../gitnuro/viewmodels/RepositoryOpenViewModel.kt | 11 +++++++++++ 3 files changed, 14 insertions(+) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt index 1d7bf5b9..77da7754 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt @@ -94,6 +94,7 @@ fun RepositoryOpenPage( showQuickActionsDialog = false when (it) { QuickActionType.OPEN_DIR_IN_FILE_MANAGER -> repositoryOpenViewModel.openFolderInFileExplorer() + QuickActionType.OPEN_DIR_IN_EDITOR -> repositoryOpenViewModel.openFolderInEditor() QuickActionType.CLONE -> onShowCloneDialog() QuickActionType.REFRESH -> repositoryOpenViewModel.refreshAll() QuickActionType.SIGN_OFF -> showSignOffDialog = true diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/QuickActionsDialog.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/QuickActionsDialog.kt index 62f45e7f..d1c03525 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/QuickActionsDialog.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/QuickActionsDialog.kt @@ -36,6 +36,7 @@ fun QuickActionsDialog( val items = remember { listOf( QuickAction(Res.drawable.code, "Open repository in file manager", QuickActionType.OPEN_DIR_IN_FILE_MANAGER), + QuickAction(Res.drawable.code, "Open repository in editor", QuickActionType.OPEN_DIR_IN_EDITOR), QuickAction(Res.drawable.download, "Clone new repository", QuickActionType.CLONE), QuickAction(Res.drawable.refresh, "Refresh repository data", QuickActionType.REFRESH), QuickAction(Res.drawable.sign, "Signoff config", QuickActionType.SIGN_OFF), @@ -128,6 +129,7 @@ data class QuickAction(val icon: DrawableResource, val title: String, val type: enum class QuickActionType { OPEN_DIR_IN_FILE_MANAGER, + OPEN_DIR_IN_EDITOR, CLONE, REFRESH, SIGN_OFF diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt index 5733a468..aad83712 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt @@ -352,6 +352,17 @@ class RepositoryOpenViewModel @Inject constructor( Desktop.getDesktop().open(git.repository.workTree) } + fun openFolderInEditor() = tabState.runOperation( + showError = true, + refreshType = RefreshType.NONE, + ) { git -> + val dir = git.repository.workTree; + // TODO: Make editor configurable + val processBuilder = ProcessBuilder("vscodium", dir.path) + processBuilder.directory(dir) + processBuilder.start() + } + fun openUrlInBrowser(url: String) { openUrlInBrowserUseCase(url) } From 6ff41e3873101da7b3cc741bb03fc6cb715fcbf1 Mon Sep 17 00:00:00 2001 From: Ramon Brullo Date: Mon, 13 Oct 2025 13:41:15 +0200 Subject: [PATCH 2/9] Added editor settings This change adds a setting/preference for the external editor to open all projects with. This change does not yet add per-project editor settings. The setting is also not used anywhere yet. --- .../gitnuro/repositories/AppSettingsRepository.kt | 14 ++++++++++++++ .../gitnuro/ui/dialogs/settings/SettingsDialog.kt | 15 +++++++++++++++ .../gitnuro/viewmodels/SettingsViewModel.kt | 7 +++++++ 3 files changed, 36 insertions(+) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt b/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt index 3820ae2d..17155a44 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt @@ -61,6 +61,8 @@ private const val PREF_GIT_PUSH_WITH_LEASE = "gitPushWithLease" private const val PREF_VERIFY_SSL = "verifySsl" +private const val PREF_EDITOR = "editor" + private const val DEFAULT_SWAP_UNCOMMITTED_CHANGES = false private const val DEFAULT_SHOW_CHANGES_AS_TREE = false private const val DEFAULT_CACHE_CREDENTIALS_IN_MEMORY = true @@ -91,6 +93,9 @@ class AppSettingsRepository @Inject constructor() { private val _verifySslFlow = MutableStateFlow(cacheCredentialsInMemory) val verifySslFlow = _verifySslFlow.asStateFlow() + private val _editorFlow = MutableStateFlow(editor) + val editorFlow = _editorFlow.asStateFlow() + private val _defaultCloneDirFlow = MutableStateFlow(defaultCloneDir) val defaultCloneDirFlow = _defaultCloneDirFlow.asStateFlow() @@ -241,6 +246,15 @@ class AppSettingsRepository @Inject constructor() { _verifySslFlow.value = value } + var editor: String + get() { + return preferences.get(PREF_EDITOR, "") + } + set(value) { + preferences.put(PREF_EDITOR, value) + _editorFlow.value = value + } + var scaleUi: Float get() { return preferences.getFloat(PREF_UI_SCALE, DEFAULT_UI_SCALE) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/settings/SettingsDialog.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/settings/SettingsDialog.kt index 6ee0b9a1..aabe95c1 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/settings/SettingsDialog.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/dialogs/settings/SettingsDialog.kt @@ -73,6 +73,7 @@ val settings = listOf( SettingsEntry.Section("Tools"), SettingsEntry.Entry(Res.drawable.terminal, "Terminal") { Terminal(it) }, + SettingsEntry.Entry(Res.drawable.edit, "Editor") { Editor(it) }, SettingsEntry.Entry(Res.drawable.info, "Logs") { Logs(it) }, ) @@ -357,6 +358,20 @@ private fun Security(settingsViewModel: SettingsViewModel) { ) } +@Composable +fun Editor(settingsViewModel: SettingsViewModel) { + val editor by settingsViewModel.editorFlow.collectAsState() + + SettingTextInput( + title = "External editor path", + subtitle = "Configure an external editor to open the repository with", + value = editor, + onValueChanged = { value -> + settingsViewModel.editor = value + }, + ) +} + @Composable fun Terminal(settingsViewModel: SettingsViewModel) { var commitsLimit by remember { mutableStateOf(settingsViewModel.terminalPath) } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt index cf0da061..e6dc0042 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/SettingsViewModel.kt @@ -43,6 +43,7 @@ class SettingsViewModel @Inject constructor( val swapUncommittedChangesFlow = appSettingsRepository.swapUncommittedChangesFlow val cacheCredentialsInMemoryFlow = appSettingsRepository.cacheCredentialsInMemoryFlow val verifySslFlow = appSettingsRepository.verifySslFlow + val editorFlow = appSettingsRepository.editorFlow val terminalPathFlow = appSettingsRepository.terminalPathFlow val avatarProviderFlow = appSettingsRepository.avatarProviderTypeFlow val dateFormatFlow = appSettingsRepository.dateTimeFormatFlow @@ -90,6 +91,12 @@ class SettingsViewModel @Inject constructor( appSettingsRepository.verifySsl = value } + var editor: String + get() = appSettingsRepository.editor + set(value) { + appSettingsRepository.editor = value + } + var pullRebase: Boolean get() = appSettingsRepository.pullRebase set(value) { From 4ed1eda5be984201d02817149a86caa4c5a08649 Mon Sep 17 00:00:00 2001 From: Ramon Brullo Date: Mon, 13 Oct 2025 13:49:38 +0200 Subject: [PATCH 3/9] Added logic to use editor from settings We now use the editor configured through the app settings to open the repo --- .../gitnuro/viewmodels/RepositoryOpenViewModel.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt index aad83712..a2510bc1 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt @@ -16,6 +16,7 @@ import com.jetpackduba.gitnuro.managers.newErrorNow import com.jetpackduba.gitnuro.models.AuthorInfoSimple import com.jetpackduba.gitnuro.models.errorNotification import com.jetpackduba.gitnuro.models.positiveNotification +import com.jetpackduba.gitnuro.repositories.AppSettingsRepository import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase import com.jetpackduba.gitnuro.system.OpenUrlInBrowserUseCase import com.jetpackduba.gitnuro.system.PickerType @@ -68,6 +69,7 @@ class RepositoryOpenViewModel @Inject constructor( private val verticalSplitPaneConfig: VerticalSplitPaneConfig, val tabViewModelsProvider: ViewModelsProvider, private val globalMenuActionsViewModel: GlobalMenuActionsViewModel, + private val appSettings: AppSettingsRepository, sharedRepositoryStateManager: SharedRepositoryStateManager, updatesRepository: UpdatesRepository, ) : IVerticalSplitPaneConfig by verticalSplitPaneConfig, @@ -356,9 +358,14 @@ class RepositoryOpenViewModel @Inject constructor( showError = true, refreshType = RefreshType.NONE, ) { git -> + val editor = appSettings.editor; + + // TODO: Verify editor input when saving instead of here when using it + // TODO: Show some message to the user + if(editor.trim().isEmpty()) return@runOperation + val dir = git.repository.workTree; - // TODO: Make editor configurable - val processBuilder = ProcessBuilder("vscodium", dir.path) + val processBuilder = ProcessBuilder(editor, dir.path) processBuilder.directory(dir) processBuilder.start() } From 8120ba73897f448a45e0ff38303caf87b704b345 Mon Sep 17 00:00:00 2001 From: Ramon Brullo Date: Mon, 13 Oct 2025 13:55:52 +0200 Subject: [PATCH 4/9] Added error notification for unset editor We now display an error notification when no editor was set. --- .../gitnuro/viewmodels/RepositoryOpenViewModel.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt index a2510bc1..70baf2af 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt @@ -361,8 +361,12 @@ class RepositoryOpenViewModel @Inject constructor( val editor = appSettings.editor; // TODO: Verify editor input when saving instead of here when using it - // TODO: Show some message to the user - if(editor.trim().isEmpty()) return@runOperation + if (editor.trim().isEmpty()) { + errorsManager.emitNotification( + errorNotification("No editor configured") + ) + return@runOperation + } val dir = git.repository.workTree; val processBuilder = ProcessBuilder(editor, dir.path) From 78c05026125136520a7d18d529c7d65ec3c20ef8 Mon Sep 17 00:00:00 2001 From: Ramon Brullo Date: Mon, 13 Oct 2025 13:59:25 +0200 Subject: [PATCH 5/9] Refactored editor setting check The check for whether the editor setting is set was done at the usage site in RepositoryOpenViewModel until now. But this logic could be relevant in other places as well. This change moves it into a new property on the AppSettingsRepository --- .../gitnuro/repositories/AppSettingsRepository.kt | 3 +++ .../gitnuro/viewmodels/RepositoryOpenViewModel.kt | 7 ++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt b/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt index 17155a44..b44d2c8a 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt @@ -255,6 +255,9 @@ class AppSettingsRepository @Inject constructor() { _editorFlow.value = value } + val hasEditorSet: Boolean + get() = editor.isNotEmpty() + var scaleUi: Float get() { return preferences.getFloat(PREF_UI_SCALE, DEFAULT_UI_SCALE) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt index 70baf2af..6eadec0e 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt @@ -358,10 +358,7 @@ class RepositoryOpenViewModel @Inject constructor( showError = true, refreshType = RefreshType.NONE, ) { git -> - val editor = appSettings.editor; - - // TODO: Verify editor input when saving instead of here when using it - if (editor.trim().isEmpty()) { + if (!appSettings.hasEditorSet) { errorsManager.emitNotification( errorNotification("No editor configured") ) @@ -369,7 +366,7 @@ class RepositoryOpenViewModel @Inject constructor( } val dir = git.repository.workTree; - val processBuilder = ProcessBuilder(editor, dir.path) + val processBuilder = ProcessBuilder(appSettings.editor, dir.path) processBuilder.directory(dir) processBuilder.start() } From 9cab47ba868dbdadedb95d8e5647247f97d45a61 Mon Sep 17 00:00:00 2001 From: Ramon Brullo Date: Mon, 13 Oct 2025 14:06:07 +0200 Subject: [PATCH 6/9] Refactored editor starting Previously we used the Kotlin navtive API for starting the process for opening the repo in an external editor. But I just discovered the IShellManager service and assume that it is better to use this. So this change refactores to use that service. --- .../gitnuro/viewmodels/RepositoryOpenViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt index 6eadec0e..98ae30c2 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt @@ -12,6 +12,7 @@ import com.jetpackduba.gitnuro.logging.printDebug import com.jetpackduba.gitnuro.logging.printLog import com.jetpackduba.gitnuro.managers.AppStateManager import com.jetpackduba.gitnuro.managers.ErrorsManager +import com.jetpackduba.gitnuro.managers.IShellManager import com.jetpackduba.gitnuro.managers.newErrorNow import com.jetpackduba.gitnuro.models.AuthorInfoSimple import com.jetpackduba.gitnuro.models.errorNotification @@ -70,6 +71,7 @@ class RepositoryOpenViewModel @Inject constructor( val tabViewModelsProvider: ViewModelsProvider, private val globalMenuActionsViewModel: GlobalMenuActionsViewModel, private val appSettings: AppSettingsRepository, + private val shellManager: IShellManager, sharedRepositoryStateManager: SharedRepositoryStateManager, updatesRepository: UpdatesRepository, ) : IVerticalSplitPaneConfig by verticalSplitPaneConfig, @@ -366,9 +368,7 @@ class RepositoryOpenViewModel @Inject constructor( } val dir = git.repository.workTree; - val processBuilder = ProcessBuilder(appSettings.editor, dir.path) - processBuilder.directory(dir) - processBuilder.start() + shellManager.runCommandInPath(listOf(appSettings.editor, dir.path), dir.path) } fun openUrlInBrowser(url: String) { From ebc4dca0a86098ba394b5d76758b2494dadb3727 Mon Sep 17 00:00:00 2001 From: Ramon Brullo Date: Mon, 13 Oct 2025 14:21:56 +0200 Subject: [PATCH 7/9] Added open-in-editor keybind There is now a keybind for opening the repo in an external editor. For now it is set to CTRL+SHIFT+A to match GitHub Desktop --- .../com/jetpackduba/gitnuro/keybindings/Keybinding.kt | 9 +++++++++ .../kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/keybindings/Keybinding.kt b/src/main/kotlin/com/jetpackduba/gitnuro/keybindings/Keybinding.kt index ad9feba0..3d158ca6 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/keybindings/Keybinding.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/keybindings/Keybinding.kt @@ -97,6 +97,11 @@ enum class KeybindingOption { * Used to open the settings screen */ SETTINGS, + + /** + * Used to open the current repository in an external editor + */ + OPEN_EDITOR } @@ -156,6 +161,9 @@ private fun baseKeybindings() = mapOf( KeybindingOption.SETTINGS to listOf( Keybinding(key = Key.S, control = true, alt = true), ), + KeybindingOption.OPEN_EDITOR to listOf( + Keybinding(key = Key.A, control = true, shift = true), + ), ) private fun linuxKeybindings(): Map> = baseKeybindings() @@ -179,6 +187,7 @@ private fun macKeybindings(): Map> { KeybindingOption.CHANGE_CURRENT_TAB_RIGHT, KeybindingOption.CHANGE_CURRENT_TAB_LEFT, KeybindingOption.SETTINGS, + KeybindingOption.OPEN_EDITOR, ) for (key in keysToReplaceControlWithCommand) { diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt index 77da7754..174dbc8b 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/RepositoryOpen.kt @@ -166,6 +166,11 @@ fun RepositoryOpenPage( true } + it.matchesBinding(KeybindingOption.OPEN_EDITOR) -> { + repositoryOpenViewModel.openFolderInEditor() + true + } + else -> false } From 14bbcbfe3f3c8daaee5d4e996e4fd04ccb84147c Mon Sep 17 00:00:00 2001 From: Ramon Brullo Date: Mon, 13 Oct 2025 14:57:14 +0200 Subject: [PATCH 8/9] Refactored open-in-editor into use-case Until now the logic for opening the current repository using an external editor was hosted in the RepositoryOpenViewModel. I noticed that the logic for opening the repo in terminal was hosted in its own use-case object, so this change also introduces such an object for the open-in-editor action --- .../editor/OpenRepositoryInEditorUseCase.kt | 34 +++++++++++++++++++ .../repositories/AppSettingsRepository.kt | 3 -- .../viewmodels/RepositoryOpenViewModel.kt | 14 ++------ 3 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/editor/OpenRepositoryInEditorUseCase.kt diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/editor/OpenRepositoryInEditorUseCase.kt b/src/main/kotlin/com/jetpackduba/gitnuro/editor/OpenRepositoryInEditorUseCase.kt new file mode 100644 index 00000000..a0443ef3 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/editor/OpenRepositoryInEditorUseCase.kt @@ -0,0 +1,34 @@ +package com.jetpackduba.gitnuro.editor + +import com.jetpackduba.gitnuro.managers.ErrorsManager +import com.jetpackduba.gitnuro.managers.IShellManager +import com.jetpackduba.gitnuro.models.errorNotification +import com.jetpackduba.gitnuro.repositories.AppSettingsRepository +import javax.inject.Inject + +/** + * Use-case for opening the repository directory with an external editor. + */ +class OpenRepositoryInEditorUseCase @Inject constructor( + private val settings: AppSettingsRepository, + private val shellManager: IShellManager, + private val errorsManager: ErrorsManager +) { + /** + * Opens the given path in the configured external editor. + * @param path The path to open. Should be a directory. + */ + suspend operator fun invoke(path: String) { + val editor = settings.editor; + val isSet = editor.isNotEmpty(); + + if (!isSet) { + errorsManager.emitNotification( + errorNotification("No editor configured") + ) + return + } + + shellManager.runCommandInPath(listOf(editor, path), path) + } +} diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt b/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt index b44d2c8a..17155a44 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/repositories/AppSettingsRepository.kt @@ -255,9 +255,6 @@ class AppSettingsRepository @Inject constructor() { _editorFlow.value = value } - val hasEditorSet: Boolean - get() = editor.isNotEmpty() - var scaleUi: Float get() { return preferences.getFloat(PREF_UI_SCALE, DEFAULT_UI_SCALE) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt index 98ae30c2..e6c42057 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt @@ -2,6 +2,7 @@ package com.jetpackduba.gitnuro.viewmodels import com.jetpackduba.gitnuro.SharedRepositoryStateManager import com.jetpackduba.gitnuro.TaskType +import com.jetpackduba.gitnuro.editor.OpenRepositoryInEditorUseCase import com.jetpackduba.gitnuro.exceptions.codeToMessage import com.jetpackduba.gitnuro.git.* import com.jetpackduba.gitnuro.git.branches.CreateBranchUseCase @@ -64,14 +65,13 @@ class RepositoryOpenViewModel @Inject constructor( private val stashChangesUseCase: StashChangesUseCase, private val stageUntrackedFileUseCase: StageUntrackedFileUseCase, private val openFilePickerUseCase: OpenFilePickerUseCase, + private val openInEditorUseCase: OpenRepositoryInEditorUseCase, private val openUrlInBrowserUseCase: OpenUrlInBrowserUseCase, private val tabsManager: TabsManager, private val tabScope: CoroutineScope, private val verticalSplitPaneConfig: VerticalSplitPaneConfig, val tabViewModelsProvider: ViewModelsProvider, private val globalMenuActionsViewModel: GlobalMenuActionsViewModel, - private val appSettings: AppSettingsRepository, - private val shellManager: IShellManager, sharedRepositoryStateManager: SharedRepositoryStateManager, updatesRepository: UpdatesRepository, ) : IVerticalSplitPaneConfig by verticalSplitPaneConfig, @@ -360,15 +360,7 @@ class RepositoryOpenViewModel @Inject constructor( showError = true, refreshType = RefreshType.NONE, ) { git -> - if (!appSettings.hasEditorSet) { - errorsManager.emitNotification( - errorNotification("No editor configured") - ) - return@runOperation - } - - val dir = git.repository.workTree; - shellManager.runCommandInPath(listOf(appSettings.editor, dir.path), dir.path) + openInEditorUseCase(git.repository.workTree.path) } fun openUrlInBrowser(url: String) { From 70ac03f32dae1cf7c061b4866e948fe3d471fce5 Mon Sep 17 00:00:00 2001 From: Ramon Brullo Date: Mon, 13 Oct 2025 15:02:44 +0200 Subject: [PATCH 9/9] Added open-in-editor global menu action This change adds a global menu button for opening the repo in the configured external editor. --- src/main/composeResources/values/strings.xml | 2 ++ src/main/kotlin/com/jetpackduba/gitnuro/ui/Menu.kt | 9 +++++++++ .../gitnuro/viewmodels/GlobalMenuActionsViewModel.kt | 9 +++++++++ 3 files changed, 20 insertions(+) diff --git a/src/main/composeResources/values/strings.xml b/src/main/composeResources/values/strings.xml index 1fd3bd64..80b78833 100644 --- a/src/main/composeResources/values/strings.xml +++ b/src/main/composeResources/values/strings.xml @@ -37,6 +37,8 @@ Pop the last stash Terminal Open a terminal in the repository's path + Editor + Open a repository in external editor Actions Additional actions Settings diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ui/Menu.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ui/Menu.kt index 2a7d9996..f4b237c2 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ui/Menu.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ui/Menu.kt @@ -174,6 +174,15 @@ fun Menu( keybinding = null, ) + MenuButton( + modifier = Modifier.padding(end = 4.dp), + title = stringResource(Res.string.menu_editor), + icon = painterResource(Res.drawable.edit), + onClick = { menuViewModel.openEditor() }, + tooltip = stringResource(Res.string.menu_editor_tooltip), + keybinding = KeybindingOption.OPEN_EDITOR.keyBinding, + ) + MenuButton( modifier = Modifier.padding(end = 4.dp), title = stringResource(Res.string.menu_actions), diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/GlobalMenuActionsViewModel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/GlobalMenuActionsViewModel.kt index 2f99cce5..49f64946 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/GlobalMenuActionsViewModel.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/GlobalMenuActionsViewModel.kt @@ -1,6 +1,7 @@ package com.jetpackduba.gitnuro.viewmodels import com.jetpackduba.gitnuro.TaskType +import com.jetpackduba.gitnuro.editor.OpenRepositoryInEditorUseCase import com.jetpackduba.gitnuro.git.RefreshType import com.jetpackduba.gitnuro.git.TabState import com.jetpackduba.gitnuro.git.remote_operations.FetchAllRemotesUseCase @@ -23,6 +24,7 @@ interface IGlobalMenuActionsViewModel { fun stash(): Job fun popStash(): Job fun openTerminal(): Job + fun openEditor(): Job } class GlobalMenuActionsViewModel @Inject constructor( @@ -33,6 +35,7 @@ class GlobalMenuActionsViewModel @Inject constructor( private val popLastStashUseCase: PopLastStashUseCase, private val stashChangesUseCase: StashChangesUseCase, private val openRepositoryInTerminalUseCase: OpenRepositoryInTerminalUseCase, + private val openRepositoryInEditorUseCase: OpenRepositoryInEditorUseCase, ) : IGlobalMenuActionsViewModel { override fun pull(pullType: PullType) = tabState.safeProcessing( refreshType = RefreshType.ALL_DATA, @@ -100,4 +103,10 @@ class GlobalMenuActionsViewModel @Inject constructor( ) { git -> openRepositoryInTerminalUseCase(git.repository.workTree.absolutePath) } + + override fun openEditor() = tabState.runOperation( + refreshType = RefreshType.NONE + ) { git -> + openRepositoryInEditorUseCase(git.repository.workTree.absolutePath) + } } \ No newline at end of file