package solutions.tretter.githugandroid enum class GitEditorCommandKind { COMMIT_MESSAGE, REBASE_TODO, TAG_MESSAGE, } data class GitEditorInvocation( val command: String, val kind: GitEditorCommandKind, val title: String, val displayPath: String, val initialContent: String = "", ) fun parseGitEditorInvocation(command: String): GitEditorInvocation? { val tokens = GitSandboxEngine.tokenizeCommand(command) if (tokens.size < 2 || tokens[0] != "git") return null return when (tokens[1]) { "commit" -> parseGitCommitEditor(command, tokens.drop(2)) "rebase" -> parseGitRebaseEditor(command, tokens.drop(2)) "tag" -> parseGitTagEditor(command, tokens.drop(2)) else -> null } } private fun parseGitCommitEditor(command: String, arguments: List): GitEditorInvocation? { if (arguments.any { it == "--no-edit" || it == "-F" || it == "--file" || it.startsWith("--file=") }) return null if (arguments.containsMessageOption()) return null if ("-C" in arguments || "--reuse-message" in arguments || arguments.any { it.startsWith("--reuse-message=") }) return null return GitEditorInvocation( command = command, kind = GitEditorCommandKind.COMMIT_MESSAGE, title = "Edit Commit Message", displayPath = ".git/COMMIT_EDITMSG", ) } private fun parseGitRebaseEditor(command: String, arguments: List): GitEditorInvocation? { val interactive = arguments.any { it == "-i" || it == "--interactive" } if (!interactive) return null val target = arguments.lastOrNull { it != "-i" && it != "--interactive" && !it.startsWith("-") } if (target == null) return null return GitEditorInvocation( command = command, kind = GitEditorCommandKind.REBASE_TODO, title = "Edit Rebase Todo", displayPath = ".git/rebase-merge/git-rebase-todo", ) } private fun parseGitTagEditor(command: String, arguments: List): GitEditorInvocation? { val needsMessage = arguments.any { it == "-a" || it == "-s" || it == "--annotate" || it == "--sign" } if (!needsMessage) return null if (arguments.any { it == "-F" || it == "--file" || it.startsWith("--file=") }) return null if (arguments.containsMessageOption()) return null return GitEditorInvocation( command = command, kind = GitEditorCommandKind.TAG_MESSAGE, title = "Edit Tag Message", displayPath = ".git/TAG_EDITMSG", ) } private fun List.containsMessageOption(): Boolean { return any { argument -> argument == "-m" || argument == "--message" || argument.startsWith("--message=") || (argument.startsWith("-") && !argument.startsWith("--") && argument.drop(1).contains('m')) } }