private async provideDocumentContent()

in src/view/treeNodes/pullRequestNode.ts [298:411]


	private async provideDocumentContent(uri: vscode.Uri): Promise<string> {
		const params = fromPRUri(uri);
		if (!params) {
			return '';
		}

		const fileChange = (await this.getFileChanges()).find(
			contentChange => contentChange.fileName === params.fileName,
		);
		if (!fileChange) {
			Logger.appendLine(`PR> can not find content for document ${uri.toString()}`);
			return '';
		}

		if (
			(params.isBase && fileChange.status === GitChangeType.ADD) ||
			(!params.isBase && fileChange.status === GitChangeType.DELETE)
		) {
			return '';
		}

		if (fileChange instanceof RemoteFileChangeNode || fileChange.isPartial) {
			try {
				if (params.isBase) {
					return this.pullRequestModel.getFile(
						fileChange.previousFileName || fileChange.fileName,
						params.baseCommit,
					);
				} else {
					return this.pullRequestModel.getFile(fileChange.fileName, params.headCommit);
				}
			} catch (e) {
				Logger.appendLine(`PR> Fetching file content failed: ${e}`);
				vscode.window
					.showWarningMessage(
						'Opening this file locally failed. Would you like to view it on GitHub?',
						'Open on GitHub',
					)
					.then(result => {
						if ((result === 'Open on GitHub') && fileChange.blobUrl) {
							vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(fileChange.blobUrl));
						}
					});
				return '';
			}
		}

		if (fileChange instanceof InMemFileChangeNode) {
			const readContentFromDiffHunk =
				fileChange.status === GitChangeType.ADD || fileChange.status === GitChangeType.DELETE;

			if (readContentFromDiffHunk) {
				if (params.isBase) {
					// left
					const left: string[] = [];
					const diffHunks = await fileChange.diffHunks();
					for (let i = 0; i < diffHunks.length; i++) {
						for (let j = 0; j < diffHunks[i].diffLines.length; j++) {
							const diffLine = diffHunks[i].diffLines[j];
							if (diffLine.type === DiffChangeType.Add) {
								// nothing
							} else if (diffLine.type === DiffChangeType.Delete) {
								left.push(diffLine.text);
							} else if (diffLine.type === DiffChangeType.Control) {
								// nothing
							} else {
								left.push(diffLine.text);
							}
						}
					}

					return left.join('\n');
				} else {
					const right: string[] = [];
					const diffHunks = await fileChange.diffHunks();
					for (let i = 0; i < diffHunks.length; i++) {
						for (let j = 0; j < diffHunks[i].diffLines.length; j++) {
							const diffLine = diffHunks[i].diffLines[j];
							if (diffLine.type === DiffChangeType.Add) {
								right.push(diffLine.text);
							} else if (diffLine.type === DiffChangeType.Delete) {
								// nothing
							} else if (diffLine.type === DiffChangeType.Control) {
								// nothing
							} else {
								right.push(diffLine.text);
							}
						}
					}

					return right.join('\n');
				}
			} else {
				const originalFileName =
					fileChange.status === GitChangeType.RENAME ? fileChange.previousFileName : fileChange.fileName;
				const originalFilePath = vscode.Uri.joinPath(
					this._folderReposManager.repository.rootUri,
					originalFileName!,
				);
				const originalContent = await this._folderReposManager.repository.show(
					params.baseCommit,
					originalFilePath.fsPath,
				);

				if (params.isBase) {
					return originalContent;
				} else {
					return getModifiedContentFromDiffHunk(originalContent, fileChange.patch);
				}
			}
		}

		return '';
	}