mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)
* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 * disable strict null check
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
"description": "%description%",
|
||||
"icon": "resources/icons/merge-conflict.png",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
|
||||
"engines": {
|
||||
"vscode": "^1.5.0"
|
||||
@@ -114,6 +115,21 @@
|
||||
"type": "boolean",
|
||||
"description": "%config.autoNavigateNextConflictEnabled%",
|
||||
"default": false
|
||||
},
|
||||
"merge-conflict.diffViewPosition": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Current",
|
||||
"Beside",
|
||||
"Below"
|
||||
],
|
||||
"description": "%config.diffViewPosition%",
|
||||
"enumDescriptions": [
|
||||
"%config.diffViewPosition.current%",
|
||||
"%config.diffViewPosition.beside%",
|
||||
"%config.diffViewPosition.below%"
|
||||
],
|
||||
"default": "Current"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,6 +138,6 @@
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "8.0.33"
|
||||
"@types/node": "^10.14.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,5 +15,9 @@
|
||||
"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.",
|
||||
"config.diffViewPosition.current": "Open the diff view in the current editor group.",
|
||||
"config.diffViewPosition.beside": "Open the diff view next to the current editor group.",
|
||||
"config.diffViewPosition.below": "Open the diff view below the current editor group."
|
||||
}
|
||||
@@ -34,8 +34,8 @@ export default class CommandHandler implements vscode.Disposable {
|
||||
this.registerTextEditorCommand('merge-conflict.accept.incoming', this.acceptIncoming),
|
||||
this.registerTextEditorCommand('merge-conflict.accept.selection', this.acceptSelection),
|
||||
this.registerTextEditorCommand('merge-conflict.accept.both', this.acceptBoth),
|
||||
this.registerTextEditorCommand('merge-conflict.accept.all-current', this.acceptAllCurrent),
|
||||
this.registerTextEditorCommand('merge-conflict.accept.all-incoming', this.acceptAllIncoming),
|
||||
this.registerTextEditorCommand('merge-conflict.accept.all-current', this.acceptAllCurrent, this.acceptAllCurrentResources),
|
||||
this.registerTextEditorCommand('merge-conflict.accept.all-incoming', this.acceptAllIncoming, this.acceptAllIncomingResources),
|
||||
this.registerTextEditorCommand('merge-conflict.accept.all-both', this.acceptAllBoth),
|
||||
this.registerTextEditorCommand('merge-conflict.next', this.navigateNext),
|
||||
this.registerTextEditorCommand('merge-conflict.previous', this.navigatePrevious),
|
||||
@@ -43,8 +43,11 @@ export default class CommandHandler implements vscode.Disposable {
|
||||
);
|
||||
}
|
||||
|
||||
private registerTextEditorCommand(command: string, cb: (editor: vscode.TextEditor, ...args: any[]) => Promise<void>) {
|
||||
private registerTextEditorCommand(command: string, cb: (editor: vscode.TextEditor, ...args: any[]) => Promise<void>, resourceCB?: (uris: vscode.Uri[]) => Promise<void>) {
|
||||
return vscode.commands.registerCommand(command, (...args) => {
|
||||
if (resourceCB && args.length && args.every(arg => arg && arg.resourceUri)) {
|
||||
return resourceCB.call(this, args.map(arg => arg.resourceUri));
|
||||
}
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
return editor && cb.call(this, editor, ...args);
|
||||
});
|
||||
@@ -70,6 +73,14 @@ export default class CommandHandler implements vscode.Disposable {
|
||||
return this.acceptAll(interfaces.CommitType.Incoming, editor);
|
||||
}
|
||||
|
||||
acceptAllCurrentResources(resources: vscode.Uri[]): Promise<void> {
|
||||
return this.acceptAllResources(interfaces.CommitType.Current, resources);
|
||||
}
|
||||
|
||||
acceptAllIncomingResources(resources: vscode.Uri[]): Promise<void> {
|
||||
return this.acceptAllResources(interfaces.CommitType.Incoming, resources);
|
||||
}
|
||||
|
||||
acceptAllBoth(editor: vscode.TextEditor): Promise<void> {
|
||||
return this.acceptAll(interfaces.CommitType.Both, editor);
|
||||
}
|
||||
@@ -88,18 +99,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> {
|
||||
@@ -223,10 +270,31 @@ export default class CommandHandler implements vscode.Disposable {
|
||||
|
||||
// Apply all changes as one edit
|
||||
await editor.edit((edit) => conflicts.forEach(conflict => {
|
||||
conflict.applyEdit(type, editor, edit);
|
||||
conflict.applyEdit(type, editor.document, edit);
|
||||
}));
|
||||
}
|
||||
|
||||
private async acceptAllResources(type: interfaces.CommitType, resources: vscode.Uri[]): Promise<void> {
|
||||
const documents = await Promise.all(resources.map(resource => vscode.workspace.openTextDocument(resource)));
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
for (const document of documents) {
|
||||
const conflicts = await this.tracker.getConflicts(document);
|
||||
|
||||
if (!conflicts || conflicts.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For get the current state of the document, as we know we are doing to do a large edit
|
||||
this.tracker.forget(document);
|
||||
|
||||
// Apply all changes as one edit
|
||||
conflicts.forEach(conflict => {
|
||||
conflict.applyEdit(type, document, { replace: (range, newText) => edit.replace(document.uri, range, newText) });
|
||||
});
|
||||
}
|
||||
vscode.workspace.applyEdit(edit);
|
||||
}
|
||||
|
||||
private async findConflictContainingSelection(editor: vscode.TextEditor, conflicts?: interfaces.IDocumentMergeConflict[]): Promise<interfaces.IDocumentMergeConflict | null> {
|
||||
|
||||
if (!conflicts) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -25,14 +25,14 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
|
||||
|
||||
if (edit) {
|
||||
|
||||
this.applyEdit(type, editor, edit);
|
||||
this.applyEdit(type, editor.document, edit);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
return editor.edit((edit) => this.applyEdit(type, editor, edit));
|
||||
return editor.edit((edit) => this.applyEdit(type, editor.document, edit));
|
||||
}
|
||||
|
||||
public applyEdit(type: interfaces.CommitType, editor: vscode.TextEditor, edit: vscode.TextEditorEdit): void {
|
||||
public applyEdit(type: interfaces.CommitType, document: vscode.TextDocument, edit: { replace(range: vscode.Range, newText: string): void; }): void {
|
||||
|
||||
// Each conflict is a set of ranges as follows, note placements or newlines
|
||||
// which may not in in spans
|
||||
@@ -45,24 +45,24 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
|
||||
// ]
|
||||
if (type === interfaces.CommitType.Current) {
|
||||
// Replace [ Conflict Range ] with [ Current Content ]
|
||||
let content = editor.document.getText(this.current.content);
|
||||
let content = document.getText(this.current.content);
|
||||
this.replaceRangeWithContent(content, edit);
|
||||
}
|
||||
else if (type === interfaces.CommitType.Incoming) {
|
||||
let content = editor.document.getText(this.incoming.content);
|
||||
let content = document.getText(this.incoming.content);
|
||||
this.replaceRangeWithContent(content, edit);
|
||||
}
|
||||
else if (type === interfaces.CommitType.Both) {
|
||||
// Replace [ Conflict Range ] with [ Current Content ] + \n + [ Incoming Content ]
|
||||
|
||||
const currentContent = editor.document.getText(this.current.content);
|
||||
const incomingContent = editor.document.getText(this.incoming.content);
|
||||
const currentContent = document.getText(this.current.content);
|
||||
const incomingContent = document.getText(this.incoming.content);
|
||||
|
||||
edit.replace(this.range, currentContent.concat(incomingContent));
|
||||
}
|
||||
}
|
||||
|
||||
private replaceRangeWithContent(content: string, edit: vscode.TextEditorEdit) {
|
||||
private replaceRangeWithContent(content: string, edit: { replace(range: vscode.Range, newText: string): void; }) {
|
||||
if (this.isNewlineOnly(content)) {
|
||||
edit.replace(this.range, '');
|
||||
return;
|
||||
|
||||
@@ -25,7 +25,7 @@ export interface IExtensionConfiguration {
|
||||
|
||||
export interface IDocumentMergeConflict extends IDocumentMergeConflictDescriptor {
|
||||
commitEdit(type: CommitType, editor: vscode.TextEditor, edit?: vscode.TextEditorEdit): Thenable<boolean>;
|
||||
applyEdit(type: CommitType, editor: vscode.TextEditor, edit: vscode.TextEditorEdit): void;
|
||||
applyEdit(type: CommitType, document: vscode.TextDocument, edit: { replace(range: vscode.Range, newText: string): void; }): void;
|
||||
}
|
||||
|
||||
export interface IDocumentMergeConflictDescriptor {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@8.0.33":
|
||||
version "8.0.33"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.33.tgz#1126e94374014e54478092830704f6ea89df04cd"
|
||||
integrity sha512-vmCdO8Bm1ExT+FWfC9sd9r4jwqM7o97gGy2WBshkkXbf/2nLAJQUrZfIhw27yVOtLUev6kSZc4cav/46KbDd8A==
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
|
||||
integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
|
||||
|
||||
vscode-nls@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
||||
Reference in New Issue
Block a user