Skip to content
Merged
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
10 changes: 10 additions & 0 deletions extensions/merge-conflict/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@
"type": "boolean",
"description": "%config.autoNavigateNextConflictEnabled%",
"default": false
},
"merge-conflict.diffViewPosition": {
"type": "string",
"enum": [
"Current",
"Beside",
"Below"
],
"description": "%config.diffViewPosition%",
"default": "Current"
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion extensions/merge-conflict/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
"config.title": "Merge Conflict",
"config.autoNavigateNextConflictEnabled": "Whether to automatically navigate to the next merge conflict after resolving a merge conflict.",
"config.codeLensEnabled": "Create a Code Lens for merge conflict blocks within editor.",
"config.decoratorsEnabled": "Create decorators for merge conflict blocks within editor."
"config.decoratorsEnabled": "Create decorators for merge conflict blocks within editor.",
"config.diffViewPosition": "Controls where the diff view should be opened when comparing changes in merge conflicts."
}
42 changes: 39 additions & 3 deletions extensions/merge-conflict/src/commandHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,54 @@ export default class CommandHandler implements vscode.Disposable {
}
}

const conflicts = await this.tracker.getConflicts(editor.document);

// Still failed to find conflict, warn the user and exit
if (!conflicts) {
vscode.window.showWarningMessage(localize('cursorNotInConflict', 'Editor cursor is not within a merge conflict'));
return;
}

const scheme = editor.document.uri.scheme;
let range = conflict.current.content;
let leftRanges = conflicts.map(conflict => [conflict.current.content, conflict.range]);
let rightRanges = conflicts.map(conflict => [conflict.incoming.content, conflict.range]);

const leftUri = editor.document.uri.with({
scheme: ContentProvider.scheme,
query: JSON.stringify({ scheme, range })
query: JSON.stringify({ scheme, range: range, ranges: leftRanges })
});


range = conflict.incoming.content;
const rightUri = leftUri.with({ query: JSON.stringify({ scheme, range }) });
const rightUri = leftUri.with({ query: JSON.stringify({ scheme, ranges: rightRanges }) });

let mergeConflictLineOffsets = 0;
for (let nextconflict of conflicts) {
if (nextconflict.range.isEqual(conflict.range)) {
break;
} else {
mergeConflictLineOffsets += (nextconflict.range.end.line - nextconflict.range.start.line) - (nextconflict.incoming.content.end.line - nextconflict.incoming.content.start.line);
}
}
const selection = new vscode.Range(
conflict.range.start.line - mergeConflictLineOffsets, conflict.range.start.character,
conflict.range.start.line - mergeConflictLineOffsets, conflict.range.start.character
);

const title = localize('compareChangesTitle', '{0}: Current Changes ⟷ Incoming Changes', fileName);
vscode.commands.executeCommand('vscode.diff', leftUri, rightUri, title);
const mergeConflictConfig = vscode.workspace.getConfiguration('merge-conflict');
const openToTheSide = mergeConflictConfig.get<string>('diffViewPosition');
const opts: vscode.TextDocumentShowOptions = {
viewColumn: openToTheSide === 'Beside' ? vscode.ViewColumn.Beside : vscode.ViewColumn.Active,
selection
};

if (openToTheSide === 'Below') {
await vscode.commands.executeCommand('workbench.action.newGroupBelow');
}

await vscode.commands.executeCommand('vscode.diff', leftUri, rightUri, title, opts);
}

navigateNext(editor: vscode.TextEditor): Promise<void> {
Expand Down
22 changes: 19 additions & 3 deletions extensions/merge-conflict/src/contentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,27 @@ export default class MergeConflictContentProvider implements vscode.TextDocument

async provideTextDocumentContent(uri: vscode.Uri): Promise<string | null> {
try {
const { scheme, range } = JSON.parse(uri.query) as { scheme: string; range: { line: number, character: number }[] };
const [start, end] = range;
const { scheme, ranges } = JSON.parse(uri.query) as { scheme: string, ranges: [{ line: number, character: number }[], { line: number, character: number }[]][] };

// complete diff
const document = await vscode.workspace.openTextDocument(uri.with({ scheme, query: '' }));
const text = document.getText(new vscode.Range(start.line, start.character, end.line, end.character));

let text = '';
let lastPosition = new vscode.Position(0, 0);

ranges.forEach(rangeObj => {
let [conflictRange, fullRange] = rangeObj;
const [start, end] = conflictRange;
const [fullStart, fullEnd] = fullRange;

text += document.getText(new vscode.Range(lastPosition.line, lastPosition.character, fullStart.line, fullStart.character));
text += document.getText(new vscode.Range(start.line, start.character, end.line, end.character));
lastPosition = new vscode.Position(fullEnd.line, fullEnd.character);
});

let documentEnd = document.lineAt(document.lineCount - 1).range.end;
text += document.getText(new vscode.Range(lastPosition.line, lastPosition.character, documentEnd.line, documentEnd.character));

return text;
}
catch (ex) {
Expand Down