/// <inheritdoc/> public async Task <IDifferenceViewer> OpenDiff(IPullRequestSession session, string relativePath, string headSha, bool scrollToFirstDiff) { Guard.ArgumentNotNull(session, nameof(session)); Guard.ArgumentNotEmptyString(relativePath, nameof(relativePath)); try { var workingDirectory = headSha == null; var file = await session.GetFile(relativePath, headSha ?? "HEAD"); var mergeBase = await pullRequestService.GetMergeBase(session.LocalRepository, session.PullRequest); var encoding = pullRequestService.GetEncoding(session.LocalRepository, file.RelativePath); var rightFile = workingDirectory ? Path.Combine(session.LocalRepository.LocalPath, relativePath) : await pullRequestService.ExtractToTempFile( session.LocalRepository, session.PullRequest, relativePath, file.CommitSha, encoding); var diffViewer = FocusExistingDiffViewer(session, mergeBase, rightFile); if (diffViewer != null) { return(diffViewer); } var leftFile = await pullRequestService.ExtractToTempFile( session.LocalRepository, session.PullRequest, relativePath, mergeBase, encoding); var leftPath = await GetBaseFileName(session, file); var rightPath = file.RelativePath; var leftLabel = $"{leftPath};{session.GetBaseBranchDisplay()}"; var rightLabel = workingDirectory ? rightPath : $"{rightPath};PR {session.PullRequest.Number}"; var caption = $"Diff - {Path.GetFileName(file.RelativePath)}"; var options = __VSDIFFSERVICEOPTIONS.VSDIFFOPT_DetectBinaryFiles | __VSDIFFSERVICEOPTIONS.VSDIFFOPT_LeftFileIsTemporary; if (!workingDirectory) { options |= __VSDIFFSERVICEOPTIONS.VSDIFFOPT_RightFileIsTemporary; } IVsWindowFrame frame; using (OpenWithOption(DifferenceViewerOptions.ScrollToFirstDiffName, scrollToFirstDiff)) using (OpenInProvisionalTab()) { var tooltip = $"{leftLabel}\nvs.\n{rightLabel}"; // Diff window will open in provisional (right hand) tab until document is touched. frame = VisualStudio.Services.DifferenceService.OpenComparisonWindow2( leftFile, rightFile, caption, tooltip, leftLabel, rightLabel, string.Empty, string.Empty, (uint)options); } diffViewer = GetDiffViewer(frame); var leftText = diffViewer.LeftView.TextBuffer.CurrentSnapshot.GetText(); var rightText = diffViewer.RightView.TextBuffer.CurrentSnapshot.GetText(); if (leftText == string.Empty) { // Don't show LeftView when empty. diffViewer.ViewMode = DifferenceViewMode.RightViewOnly; } else if (rightText == string.Empty) { // Don't show RightView when empty. diffViewer.ViewMode = DifferenceViewMode.LeftViewOnly; } else if (leftText == rightText) { // Don't show LeftView when no changes. diffViewer.ViewMode = DifferenceViewMode.RightViewOnly; } AddBufferTag(diffViewer.LeftView.TextBuffer, session, leftPath, mergeBase, DiffSide.Left); if (!workingDirectory) { AddBufferTag(diffViewer.RightView.TextBuffer, session, rightPath, file.CommitSha, DiffSide.Right); EnableNavigateToEditor(diffViewer.LeftView, session); EnableNavigateToEditor(diffViewer.RightView, session); EnableNavigateToEditor(diffViewer.InlineView, session); } if (workingDirectory) { await usageTracker.IncrementCounter(x => x.NumberOfPRDetailsCompareWithSolution); } else { await usageTracker.IncrementCounter(x => x.NumberOfPRDetailsViewChanges); } return(diffViewer); } catch (Exception e) { ShowErrorInStatusBar("Error opening file", e); return(null); } }
/// <inheritdoc/> public async Task <IDifferenceViewer> OpenDiff(IPullRequestSession session, string relativePath, string headSha, bool scrollToFirstDraftOrDiff) { Guard.ArgumentNotNull(session, nameof(session)); Guard.ArgumentNotEmptyString(relativePath, nameof(relativePath)); try { var workingDirectory = headSha == null; var file = await session.GetFile(relativePath, headSha ?? "HEAD"); var mergeBase = await pullRequestService.GetMergeBase(session.LocalRepository, session.PullRequest); var encoding = pullRequestService.GetEncoding(session.LocalRepository, file.RelativePath); var rightFile = workingDirectory ? Path.Combine(session.LocalRepository.LocalPath, relativePath) : await pullRequestService.ExtractToTempFile( session.LocalRepository, session.PullRequest, relativePath, file.CommitSha, encoding); var diffViewer = FocusExistingDiffViewer(session, mergeBase, rightFile); if (diffViewer != null) { return(diffViewer); } var leftFile = await pullRequestService.ExtractToTempFile( session.LocalRepository, session.PullRequest, relativePath, mergeBase, encoding); var leftPath = await GetBaseFileName(session, file); var rightPath = file.RelativePath; var leftLabel = $"{leftPath};{session.GetBaseBranchDisplay()}"; var rightLabel = workingDirectory ? rightPath : $"{rightPath};PR {session.PullRequest.Number}"; var caption = $"Diff - {Path.GetFileName(file.RelativePath)}"; var options = __VSDIFFSERVICEOPTIONS.VSDIFFOPT_DetectBinaryFiles | __VSDIFFSERVICEOPTIONS.VSDIFFOPT_LeftFileIsTemporary; var openThread = (line : -1, side : DiffSide.Left); var scrollToFirstDiff = false; if (!workingDirectory) { options |= __VSDIFFSERVICEOPTIONS.VSDIFFOPT_RightFileIsTemporary; } if (scrollToFirstDraftOrDiff) { var(key, _) = PullRequestReviewCommentThreadViewModel.GetDraftKeys( session.LocalRepository.CloneUrl.WithOwner(session.RepositoryOwner), session.PullRequest.Number, relativePath, 0); var drafts = (await draftStore.GetDrafts <PullRequestReviewCommentDraft>(key) .ConfigureAwait(true)) .OrderByDescending(x => x.data.UpdatedAt) .ToList(); if (drafts.Count > 0 && int.TryParse(drafts[0].secondaryKey, out var line)) { openThread = (line, drafts[0].data.Side);