дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
The result pane starts from the base and every change, conflicting or not, gets Accept / Ignore next to its side; accepting one side of a conflict still lets the other side be appended, and the modifier key resolves using that side directly. Adds Resolve Simple Conflicts (word-level), Apply Non-Conflicting Changes from the left, right or both (optionally on opening), Revert Conflict Resolution, Accept Yours / Accept Theirs / Cancel / Apply, Compare Contents between any two versions, and undo back to the conflicted state. CRLF and UTF-16 files are written back exactly, deleted sides and binary files are handled, and the commands are registered as merge.* actions. Refs #826 Co-authored-by: ntbang0901 <[email protected]>
77 рядки
2.8 KiB
TypeScript
77 рядки
2.8 KiB
TypeScript
/** Commands target the merge editor that opened a toolbar menu or Find Action. */
|
|
import { registerActions, type Action } from "@/platform/actions";
|
|
import { setContext } from "@/platform/context";
|
|
|
|
const COMMANDS = [
|
|
["applyLeft", "Apply Non-Conflicting Changes from the Left Side", "diff-apply-left"],
|
|
["applyAll", "Apply All Non-Conflicting Changes", "diff-apply-all"],
|
|
["applyRight", "Apply Non-Conflicting Changes from the Right Side", "diff-apply-right"],
|
|
["resolveSimple", "Resolve Simple Conflicts", "diff-magic-toolbar"],
|
|
["revert", "Revert Conflict Resolution", "diff-revert"],
|
|
["acceptYours", "Accept Yours"],
|
|
["acceptTheirs", "Accept Theirs"],
|
|
["apply", "Apply Merge Result"],
|
|
["cancel", "Cancel Merge"],
|
|
["reload", "Reload from Disk", "refresh"],
|
|
["compare", "Compare Contents", "diff"],
|
|
["settings", "Merge Settings", "settings"],
|
|
["autoApply", "Automatically Apply Non-Conflicting Changes"],
|
|
["compareYoursResult", "Yours and Result"],
|
|
["compareResultTheirs", "Result and Theirs"],
|
|
["compareYoursTheirs", "Yours and Theirs"],
|
|
["compareBaseYours", "Base and Yours"],
|
|
["compareBaseResult", "Base and Result"],
|
|
["compareBaseTheirs", "Base and Theirs"],
|
|
["accept", "Accept"],
|
|
["resolveUsingYours", "Resolve Using Yours"],
|
|
["resolveUsingTheirs", "Resolve Using Theirs"],
|
|
["ignore", "Ignore", "diff-remove"],
|
|
["resolveAutomatically", "Resolve Automatically", "diff-magic"],
|
|
["annotate", "Annotate with Git Blame", "changelist"],
|
|
["cut", "Cut"],
|
|
["copy", "Copy", "copy"],
|
|
["paste", "Paste"],
|
|
["selectAll", "Select All"],
|
|
["change", "Resolve Merge Change"],
|
|
] as const;
|
|
|
|
export type MergeCommand = (typeof COMMANDS)[number][0];
|
|
|
|
export interface MergeActionHost {
|
|
enabled(command: MergeCommand): boolean;
|
|
run(command: MergeCommand, arg?: unknown): void | Promise<void>;
|
|
autoApply(): boolean;
|
|
}
|
|
|
|
let focused: MergeActionHost | null = null;
|
|
|
|
export function setFocusedMergeEditor(host: MergeActionHost | null) {
|
|
focused = host;
|
|
setContext("mergeEditorFocus", !!host);
|
|
for (const [command] of COMMANDS) setContext(`merge.${command}`, host?.enabled(command) ?? false);
|
|
}
|
|
|
|
export function refreshMergeActions(host: MergeActionHost) {
|
|
if (focused === host) setFocusedMergeEditor(host);
|
|
}
|
|
|
|
export function clearFocusedMergeEditor(host: MergeActionHost) {
|
|
if (focused === host) setFocusedMergeEditor(null);
|
|
}
|
|
|
|
export function registerMergeActions(): () => void {
|
|
return registerActions(
|
|
COMMANDS.map(([command, title, icon]): Action => ({
|
|
id: `merge.${command}`,
|
|
title,
|
|
icon,
|
|
category: "Merge",
|
|
when: `mergeEditorFocus && merge.${command}`,
|
|
keywords: ["merge", "conflict"],
|
|
hidden: command === "change",
|
|
toggled: command === "autoApply" ? () => focused?.autoApply() ?? false : undefined,
|
|
run: ({ arg }) => focused?.run(command, arg),
|
|
})),
|
|
);
|
|
}
|