// How an operation of the op log reads: a friendlier label, its kind, and // the codicon and colour the Operations view gives it (see style.ts). export interface OperationLook { /** What happened, in words: a commit's subject, "Pushed to earth". */ label: string; /** The kind, shown beside it: "commit", "push". */ kind: string; icon: string; color: string; } /** The first line of a quoted `-m` message in an operation's command. */ function message(command: string): string | undefined { const m = /-m\s+"((?:[^"\\]|\\.)*)"/.exec(command); if (!m) return undefined; const text = m[1].replace(/\\n/g, "\n").replace(/\\"/g, '"').replace(/\\\\/g, "\\"); return text.split("\n")[0].trim() || undefined; } /** How an operation of the op log looks, from its command. */ export function operationLook(command: string, snapshot: boolean): OperationLook { const cmd = command.replace(/^oxy\s+/, "").replace(/\s*\((?:snapshot|merged with a concurrent operation)\)\s*/g, " ").trim(); const words = cmd.split(/\s+/); const [verb, sub] = words; const arg = (i: number) => (words[i] ?? "").replace(/^"|"$/g, ""); if (snapshot) { return { label: `Snapshot for ${verb}`, kind: "snapshot", icon: "circle-small", color: "descriptionForeground" }; } switch (verb) { case "commit": return { label: message(cmd) ?? "Committed", kind: "commit", icon: "git-commit", color: "oxygen.commit" }; case "amend": case "split": case "squash": case "describe": return { label: message(cmd) ?? `${verb[0].toUpperCase()}${verb.slice(1)}ed`, kind: verb, icon: "edit", color: "oxygen.commit" }; case "push": return { label: sub ? `Pushed to ${sub}` : "Pushed", kind: "push", icon: "cloud-upload", color: "oxygen.push" }; case "pull": return { label: sub ? `Pulled from ${sub}` : "Pulled", kind: "pull", icon: "cloud-download", color: "oxygen.pull" }; case "fetch": return { label: sub ? `Fetched ${sub}` : "Fetched", kind: "fetch", icon: "sync", color: "oxygen.pull" }; case "clone": case "init": return { label: verb === "init" ? "Repository created" : "Cloned", kind: verb, icon: "repo-clone", color: "oxygen.pull" }; case "merge": return { label: sub ? `Merged ${sub}` : "Merged", kind: "merge", icon: "git-merge", color: "oxygen.merge" }; case "rebase": case "resolve": return { label: message(cmd) ?? `${verb[0].toUpperCase()}${verb.slice(1)}d`, kind: verb, icon: "git-pull-request", color: "oxygen.merge" }; case "checkout": return { label: "Checked out", kind: "checkout", icon: "arrow-swap", color: "oxygen.switch" }; case "bookmark": case "tag": { const name = arg(2); if (sub === "switch") return { label: `Switched to ${name}`, kind: "switch", icon: "arrow-swap", color: "oxygen.switch" }; const done: Record = { create: "created", set: "moved", delete: "deleted", move: "moved" }; return { label: `${verb === "tag" ? "Tag" : "Bookmark"} ${name} ${done[sub] ?? sub}`.trim(), kind: verb, icon: verb === "tag" ? "tag" : "bookmark", color: "oxygen.bookmark" }; } case "undo": case "discard": case "abandon": case "restore": return { label: `${verb[0].toUpperCase()}${verb.slice(1)}`, kind: verb, icon: "discard", color: "oxygen.undo" }; case "seal": case "sign": case "policy": return { label: cmd, kind: verb, icon: "shield", color: "oxygen.key" }; case "submodule": return { label: `Subrepos ${sub ?? ""}`.trim(), kind: "subrepo", icon: "repo", color: "oxygen.subrepo" }; default: return { label: cmd, kind: verb ?? "", icon: "circle-outline", color: "descriptionForeground" }; } }