mirror of
https://github.com/Microsoft/vscode
synced 2024-08-28 05:19:39 +00:00
Update accept actions for new conflict parser
This commit is contained in:
parent
4dcf156655
commit
1535f99ffe
|
@ -52,35 +52,11 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
|
|||
}
|
||||
else if (type === interfaces.CommitType.Both) {
|
||||
// Replace [ Conflict Range ] with [ Current Content ] + \n + [ Incoming Content ]
|
||||
//
|
||||
// NOTE: Due to headers and splitters NOT covering \n (this is so newlines inserted)
|
||||
// by the user after (e.g. <<<<< HEAD do not fall into the header range but the
|
||||
// content ranges), we can't push 3x deletes, we need to replace the range with the
|
||||
// union of the content.
|
||||
|
||||
const currentContent = editor.document.getText(this.current.content);
|
||||
const incomingContent = editor.document.getText(this.incoming.content);
|
||||
|
||||
let finalContent = '';
|
||||
|
||||
if (!this.isNewlineOnly(currentContent)) {
|
||||
finalContent += currentContent;
|
||||
}
|
||||
|
||||
if (!this.isNewlineOnly(incomingContent)) {
|
||||
if (finalContent.length > 0) {
|
||||
finalContent += '\n';
|
||||
}
|
||||
|
||||
finalContent += incomingContent;
|
||||
}
|
||||
|
||||
if (finalContent.length > 0 && !this.isNewlineOnly(finalContent)) {
|
||||
finalContent += '\n';
|
||||
}
|
||||
|
||||
edit.setEndOfLine(vscode.EndOfLine.LF);
|
||||
edit.replace(this.range, finalContent);
|
||||
edit.replace(this.range, currentContent.concat(incomingContent));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,12 +66,8 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
|
|||
return;
|
||||
}
|
||||
|
||||
let updatedContent = content.concat('\n');
|
||||
edit.setEndOfLine(vscode.EndOfLine.LF);
|
||||
|
||||
// Replace [ Conflict Range ] with [ Current Content ]
|
||||
|
||||
edit.replace(this.range, updatedContent);
|
||||
edit.replace(this.range, content);
|
||||
}
|
||||
|
||||
private isNewlineOnly(text: string) {
|
||||
|
|
|
@ -8,6 +8,7 @@ export interface IMergeRegion {
|
|||
name: string;
|
||||
header: vscode.Range;
|
||||
content: vscode.Range;
|
||||
decoratorContent: vscode.Range;
|
||||
}
|
||||
|
||||
export enum CommitType {
|
||||
|
|
|
@ -6,14 +6,14 @@ import * as vscode from 'vscode';
|
|||
import * as interfaces from './interfaces';
|
||||
import { DocumentMergeConflict } from './documentMergeConflict';
|
||||
|
||||
const startMarker = '<<<<<<<';
|
||||
const startMarker = '<<<<<<< ';
|
||||
const splitterMarker = '=======';
|
||||
const endMarker = '>>>>>>>';
|
||||
const endMarker = '>>>>>>> ';
|
||||
|
||||
interface IPartialMergeConflictDescriptor {
|
||||
currentHeader: vscode.Range;
|
||||
splitter?: vscode.Range;
|
||||
incomingFooter?: vscode.Range;
|
||||
currentHeader: vscode.TextLine;
|
||||
splitter?: vscode.TextLine;
|
||||
incomingFooter?: vscode.TextLine;
|
||||
}
|
||||
|
||||
export class MergeConflictParser {
|
||||
|
@ -37,9 +37,7 @@ export class MergeConflictParser {
|
|||
break;
|
||||
}
|
||||
|
||||
currentConflict = {
|
||||
currentHeader: line.range
|
||||
};
|
||||
currentConflict = { currentHeader: line };
|
||||
}
|
||||
else if (line.text.startsWith(splitterMarker)) {
|
||||
|
||||
|
@ -47,16 +45,16 @@ export class MergeConflictParser {
|
|||
continue; // Ignore
|
||||
}
|
||||
|
||||
currentConflict.splitter = line.range;
|
||||
currentConflict.splitter = line;
|
||||
}
|
||||
else if (line.text.startsWith(endMarker)) {
|
||||
if (currentConflict === null) {
|
||||
continue; // Ignore
|
||||
}
|
||||
|
||||
currentConflict.incomingFooter = line.range;
|
||||
currentConflict.incomingFooter = line;
|
||||
|
||||
let completeDescriptor = MergeConflictParser.completePartialMergeDescriptor(currentConflict);
|
||||
let completeDescriptor = MergeConflictParser.completePartialMergeDescriptor(document, currentConflict);
|
||||
|
||||
if (completeDescriptor !== null) {
|
||||
conflictDescriptors.push(completeDescriptor);
|
||||
|
@ -71,30 +69,43 @@ export class MergeConflictParser {
|
|||
.map(descriptor => new DocumentMergeConflict(document, descriptor));
|
||||
}
|
||||
|
||||
private static completePartialMergeDescriptor(partial: IPartialMergeConflictDescriptor): interfaces.IDocumentMergeConflictDescriptor | null {
|
||||
// Assume that descriptor.current.header, descriptor.incoming.header and descriptor.spliiter
|
||||
// have valid ranges, fill in content and total ranges from these parts.
|
||||
|
||||
private static completePartialMergeDescriptor(document: vscode.TextDocument, partial: IPartialMergeConflictDescriptor): interfaces.IDocumentMergeConflictDescriptor | null {
|
||||
// Validate we have valid ranges
|
||||
if (!partial.currentHeader || !partial.splitter || !partial.incomingFooter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Assume that descriptor.current.header, descriptor.incoming.header and descriptor.spliiter
|
||||
// have valid ranges, fill in content and total ranges from these parts.
|
||||
// NOTE: We need to shift the decortator range back one character so the splitter does not end up with
|
||||
// two decoration colors (current and splitter), if we take the new line from the content into account
|
||||
// the decorator will wrap to the next line.
|
||||
return {
|
||||
current: {
|
||||
header: partial.currentHeader,
|
||||
// Current content is range between header and splitter
|
||||
content: new vscode.Range(partial.currentHeader.end, partial.splitter.start),
|
||||
name: ''
|
||||
header: partial.currentHeader.range,
|
||||
decoratorContent: new vscode.Range(
|
||||
partial.currentHeader.rangeIncludingLineBreak.end,
|
||||
MergeConflictParser.shiftBackOneCharacter(document, partial.splitter.range.start)),
|
||||
// Current content is range between header (shifted for linebreak) and splitter start
|
||||
content: new vscode.Range(
|
||||
partial.currentHeader.rangeIncludingLineBreak.end,
|
||||
partial.splitter.range.start),
|
||||
name: document.getText(partial.currentHeader.range).substring(startMarker.length)
|
||||
},
|
||||
splitter: partial.splitter,
|
||||
splitter: partial.splitter.range,
|
||||
incoming: {
|
||||
header: partial.incomingFooter,
|
||||
// Incoming content is range between splitter and footer
|
||||
content: new vscode.Range(partial.splitter.end, partial.incomingFooter.end),
|
||||
name: ''
|
||||
header: partial.incomingFooter.range,
|
||||
decoratorContent: new vscode.Range(
|
||||
partial.splitter.rangeIncludingLineBreak.end,
|
||||
MergeConflictParser.shiftBackOneCharacter(document, partial.incomingFooter.range.start)),
|
||||
// Incoming content is range between splitter (shifted for linebreak) and footer start
|
||||
content: new vscode.Range(
|
||||
partial.splitter.rangeIncludingLineBreak.end,
|
||||
partial.incomingFooter.range.start),
|
||||
name: document.getText(partial.incomingFooter.range).substring(endMarker.length)
|
||||
},
|
||||
// Entire range is between current header start and incoming header end
|
||||
range: new vscode.Range(partial.currentHeader.start, partial.incomingFooter.end)
|
||||
// Entire range is between current header start and incoming header end (including line break)
|
||||
range: new vscode.Range(partial.currentHeader.range.start, partial.incomingFooter.rangeIncludingLineBreak.end)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -103,8 +114,19 @@ export class MergeConflictParser {
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: Ask source control if the file contains a conflict
|
||||
let text = document.getText();
|
||||
return text.includes('<<<<<<<') && text.includes('>>>>>>>');
|
||||
return text.includes(startMarker) && text.includes(endMarker);
|
||||
}
|
||||
|
||||
private static shiftBackOneCharacter(document: vscode.TextDocument, range: vscode.Position): vscode.Position {
|
||||
let line = range.line;
|
||||
let character = range.character - 1;
|
||||
|
||||
if (character < 0) {
|
||||
line--;
|
||||
character = document.lineAt(line).range.end.character;
|
||||
}
|
||||
|
||||
return new vscode.Position(line, character);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import * as interfaces from './interfaces';
|
|||
import { loadMessageBundle } from 'vscode-nls';
|
||||
const localize = loadMessageBundle();
|
||||
|
||||
|
||||
export default class MergeDectorator implements vscode.Disposable {
|
||||
|
||||
private decorations: { [key: string]: vscode.TextEditorDecorationType } = {};
|
||||
|
@ -169,8 +168,8 @@ export default class MergeDectorator implements vscode.Disposable {
|
|||
|
||||
conflicts.forEach(conflict => {
|
||||
// TODO, this could be more effective, just call getMatchPositions once with a map of decoration to position
|
||||
pushDecoration('current.content', { range: conflict.current.content });
|
||||
pushDecoration('incoming.content', { range: conflict.incoming.content });
|
||||
pushDecoration('current.content', { range: conflict.current.decoratorContent });
|
||||
pushDecoration('incoming.content', { range: conflict.incoming.decoratorContent });
|
||||
|
||||
if (this.config.enableDecorations) {
|
||||
pushDecoration('current.header', { range: conflict.current.header });
|
||||
|
|
Loading…
Reference in a new issue