Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions src/main/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
<string name="status_entries_context_menu_file_history">File history</string>
<string name="status_entries_context_menu_blame_file">Blame file</string>
<string name="status_entries_context_menu_discard_file_changes">Discard file changes</string>
<string name="status_entries_context_menu_open_file_in_folder">Open file in folder</string>

<!-- Branch context menu -->
<string name="branch_context_menu_checkout_branch">Checkout branch</string>
Expand All @@ -105,6 +106,7 @@
<!-- Committed changes context menu -->
<string name="committed_changes_context_menu_blame_file">Blame file</string>
<string name="committed_changes_context_menu_file_history">File history</string>
<string name="committed_changes_context_menu_open_file_in_folder">Open file in folder</string>

<!-- Log context menu -->
<string name="log_context_menu_checkout_commit">Checkout commit</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package com.jetpackduba.gitnuro.extensions

import com.jetpackduba.gitnuro.logging.printError
import com.jetpackduba.gitnuro.system.OS
import com.jetpackduba.gitnuro.system.currentOs
import kotlinx.io.IOException
import java.awt.Desktop
import java.io.File

private const val TAG = "FileExtensions"

fun File.openDirectory(dirName: String): File {
val newDir = File(this, dirName)

Expand All @@ -10,4 +17,43 @@ fun File.openDirectory(dirName: String): File {
}

return newDir
}

fun File.openFileInFolder() {

if (!exists() || !isDirectory) {
printError(TAG, "Folder with path \"$path\" does not exist or is not a folder")
return
}

try {
if (Desktop.isDesktopSupported()) {
val desktop = Desktop.getDesktop()
if (desktop.isSupported(Desktop.Action.OPEN)) {
desktop.open(this)
return
}
}
} catch (e: Exception) {
printError(TAG, "Desktop API failed: ${e.message}")
}

// Fallback
val os = currentOs
val command = when (os) {
OS.LINUX -> listOf("xdg-open", absolutePath)
OS.MAC -> listOf("open", absolutePath)
OS.WINDOWS -> listOf("explorer", absolutePath)
else -> null
}

if (command != null) {
try {
ProcessBuilder(command).start()
} catch (ex: IOException) {
printError(TAG, "Failed to open file explorer: ${ex.message}")
}
} else {
printError(TAG, "Unsupported OS: $os")
}
}
4 changes: 4 additions & 0 deletions src/main/kotlin/com/jetpackduba/gitnuro/ui/CommitChanges.kt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ fun CommitChanges(
commitChangesStatus = commitChangesStatus,
onBlame = onBlame,
onHistory = onHistory,
onOpenFileInFolder = { commitChangesViewModel.openFileInFolder(it) },
showSearch = showSearch,
showAsTree = showAsTree,
changesListScroll = changesListScroll,
Expand Down Expand Up @@ -121,6 +122,7 @@ private fun CommitChangesView(
searchFilter: TextFieldValue,
onBlame: (String) -> Unit,
onHistory: (String) -> Unit,
onOpenFileInFolder: (String) -> Unit,
onDiffSelected: (DiffEntry) -> Unit,
onSearchFilterToggled: (Boolean) -> Unit,
onSearchFocused: () -> Unit,
Expand Down Expand Up @@ -167,6 +169,7 @@ private fun CommitChangesView(
diffEntry,
onBlame = { onBlame(diffEntry.filePath) },
onHistory = { onHistory(diffEntry.filePath) },
onOpenFileInFolder = { onOpenFileInFolder(diffEntry.parentDirectoryPath) },
)
}
)
Expand All @@ -183,6 +186,7 @@ private fun CommitChangesView(
diffEntry,
onBlame = { onBlame(diffEntry.filePath) },
onHistory = { onHistory(diffEntry.filePath) },
onOpenFileInFolder = { onOpenFileInFolder(diffEntry.parentDirectoryPath) },
)
},
onDirectoryClicked = onDirectoryClicked,
Expand Down
12 changes: 9 additions & 3 deletions src/main/kotlin/com/jetpackduba/gitnuro/ui/UncommitedChanges.kt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ fun UncommittedChanges(
onHistoryFile = onHistoryFile,
onReset = { statusViewModel.resetStaged(it) },
onDelete = { statusViewModel.deleteFile(it) },
onOpenFileInFolder = { statusViewModel.openFileInFolder(it) },
onAllAction = { statusViewModel.unstageAll() },
onAlternateShowAsTree = { statusViewModel.alternateShowAsTree() },
onTreeDirectoryClicked = { statusViewModel.stagedTreeDirectoryClicked(it) },
Expand All @@ -189,6 +190,7 @@ fun UncommittedChanges(
onHistoryFile = onHistoryFile,
onReset = { statusViewModel.resetUnstaged(it) },
onDelete = { statusViewModel.deleteFile(it) },
onOpenFileInFolder = { statusViewModel.openFileInFolder(it) },
onAllAction = { statusViewModel.stageAll() },
onAlternateShowAsTree = { statusViewModel.alternateShowAsTree() },
onTreeDirectoryClicked = { statusViewModel.stagedTreeDirectoryClicked(it) },
Expand Down Expand Up @@ -359,6 +361,7 @@ fun ColumnScope.StagedView(
onHistoryFile: (String) -> Unit,
onReset: (StatusEntry) -> Unit,
onDelete: (StatusEntry) -> Unit,
onOpenFileInFolder: (String?) -> Unit,
onAllAction: () -> Unit,
onAlternateShowAsTree: () -> Unit,
onTreeDirectoryClicked: (String) -> Unit,
Expand Down Expand Up @@ -393,6 +396,7 @@ fun ColumnScope.StagedView(
onHistoryFile = onHistoryFile,
onReset = onReset,
onDelete = onDelete,
onOpenFileInFolder = onOpenFileInFolder,
onAllAction = onAllAction,
onAlternateShowAsTree = onAlternateShowAsTree,
onTreeDirectoryClicked = onTreeDirectoryClicked,
Expand Down Expand Up @@ -431,6 +435,7 @@ fun ColumnScope.UnstagedView(
onHistoryFile: (String) -> Unit,
onReset: (StatusEntry) -> Unit,
onDelete: (StatusEntry) -> Unit,
onOpenFileInFolder: (String?) -> Unit,
onAllAction: () -> Unit,
onAlternateShowAsTree: () -> Unit,
onTreeDirectoryClicked: (String) -> Unit,
Expand Down Expand Up @@ -465,6 +470,7 @@ fun ColumnScope.UnstagedView(
onHistoryFile = onHistoryFile,
onReset = onReset,
onDelete = onDelete,
onOpenFileInFolder = onOpenFileInFolder,
onAllAction = onAllAction,
onAlternateShowAsTree = onAlternateShowAsTree,
onTreeDirectoryClicked = onTreeDirectoryClicked,
Expand Down Expand Up @@ -512,6 +518,7 @@ fun ColumnScope.NeutralView(
onHistoryFile: (String) -> Unit,
onReset: (StatusEntry) -> Unit,
onDelete: (StatusEntry) -> Unit,
onOpenFileInFolder: (String?) -> Unit,
onAllAction: () -> Unit,
onAlternateShowAsTree: () -> Unit,
onTreeDirectoryClicked: (String) -> Unit,
Expand Down Expand Up @@ -548,6 +555,7 @@ fun ColumnScope.NeutralView(
onHistory = { onHistoryFile(statusEntry.filePath) },
onReset = { onReset(statusEntry) },
onDelete = { onDelete(statusEntry) },
onOpenFileInFolder = { onOpenFileInFolder(statusEntry.parentDirectoryPath) },
)
},
onAllAction = onAllAction,
Expand Down Expand Up @@ -588,6 +596,7 @@ fun ColumnScope.NeutralView(
onHistory = { onHistoryFile(statusEntry.filePath) },
onReset = { onReset(statusEntry) },
onDelete = { onDelete(statusEntry) },
onOpenFileInFolder = { onOpenFileInFolder(statusEntry.parentDirectoryPath) },
)
},
onAllAction = onAllAction,
Expand Down Expand Up @@ -1079,8 +1088,6 @@ fun EntriesHeader(
)
}



if (showSearch) {
SearchTextField(
searchFilter = searchFilter,
Expand All @@ -1097,7 +1104,6 @@ fun EntriesHeader(
requestFocus = false
}
}

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ fun committedChangesEntriesContextMenuItems(
diffEntry: DiffEntry,
onBlame: () -> Unit,
onHistory: () -> Unit,
onOpenFileInFolder: () -> Unit,
): List<ContextMenuElement> {
return mutableListOf<ContextMenuElement>().apply {
if (diffEntry.changeType != DiffEntry.ChangeType.ADD ||
Expand All @@ -24,6 +25,12 @@ fun committedChangesEntriesContextMenuItems(
icon = { painterResource(Res.drawable.history) },
onClick = onHistory,
)

addContextMenu(
composableLabel = { stringResource(Res.string.committed_changes_context_menu_open_file_in_folder) },
icon = { painterResource(Res.drawable.folder_open) },
onClick = onOpenFileInFolder,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ fun statusEntriesContextMenuItems(
onDelete: () -> Unit = {},
onBlame: () -> Unit,
onHistory: () -> Unit,
onOpenFileInFolder: () -> Unit,
): List<ContextMenuElement> {
return mutableListOf<ContextMenuElement>().apply {
if (statusEntry.statusType != StatusType.ADDED) {
Expand Down Expand Up @@ -47,6 +48,12 @@ fun statusEntriesContextMenuItems(
onClick = onDelete,
)
}

addContextMenu(
composableLabel = { stringResource(Res.string.status_entries_context_menu_open_file_in_folder) },
icon = { painterResource(Res.drawable.folder_open) },
onClick = onOpenFileInFolder,
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ package com.jetpackduba.gitnuro.viewmodels
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.ui.text.input.TextFieldValue
import com.jetpackduba.gitnuro.extensions.delayedStateChange
import com.jetpackduba.gitnuro.extensions.filePath
import com.jetpackduba.gitnuro.extensions.fullData
import com.jetpackduba.gitnuro.extensions.lowercaseContains
import com.jetpackduba.gitnuro.extensions.*
import com.jetpackduba.gitnuro.git.CloseableView
import com.jetpackduba.gitnuro.git.RefreshType
import com.jetpackduba.gitnuro.git.TabState
Expand All @@ -19,6 +16,7 @@ import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import org.eclipse.jgit.diff.DiffEntry
import org.eclipse.jgit.revwalk.RevCommit
import java.io.File
import javax.inject.Inject

private const val MIN_TIME_IN_MS_TO_SHOW_LOAD = 300L
Expand Down Expand Up @@ -159,6 +157,15 @@ class CommitChangesViewModel @Inject constructor(
appSettingsRepository.showChangesAsTree = !appSettingsRepository.showChangesAsTree
}

fun openFileInFolder(folderPath: String?) = tabState.runOperation(
refreshType = RefreshType.NONE,
) { git ->
if (folderPath != null) {
val file = File(git.repository.workTree.absolutePath + File.separator + folderPath)
file.openFileInFolder()
}
}

fun onDirectoryClicked(directoryPath: String) {
val contractedDirectories = treeContractedDirectories.value

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@ class StatusViewModel @Inject constructor(
stageStateFiltered.unstaged,
contractedDirectories
) { it.filePath },
filteredStaged = entriesToTreeEntry(stageStateFiltered.filteredStaged, contractedDirectories) { it.filePath },
filteredStaged = entriesToTreeEntry(
stageStateFiltered.filteredStaged,
contractedDirectories
) { it.filePath },
filteredUnstaged = entriesToTreeEntry(
stageStateFiltered.filteredUnstaged,
contractedDirectories
Expand Down Expand Up @@ -510,6 +513,15 @@ class StatusViewModel @Inject constructor(
fileToDelete.deleteRecursively()
}

fun openFileInFolder(folderPath: String?) = tabState.runOperation(
refreshType = RefreshType.NONE,
) { git ->
if (folderPath != null) {
val file = File(git.repository.workTree.absolutePath + File.separator + folderPath)
file.openFileInFolder()
}
}

fun updateCommitMessage(message: String) {
savedCommitMessage = savedCommitMessage.copy(message = message)
persistMessage()
Expand Down
Loading