-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add inline comments #1004
Add inline comments #1004
Conversation
Conflicts: .ncrunch/GitHub.UI.UnitTests.v3.ncrunchproject src/GitHub.Exports/Settings/Guids.cs
Use a heuristic to recalculate comment positions when opening a file in response to any changes that may be present locally.
When editing occurs, recalculate comment positions on a background thread.
One of the files might not exist of the file is added or deleted.
`IVsDifferenceService.OpenComparisonWindow2` doesn't allow us to pass extra information to the tagger, such as the path to the file being tagged (the left file path is always passed, which may be a temp file). Hack around this by storing global state in the pull request review session object (ugh).
Previously it was exposing an `AccountCacheItem` instead of an `IAccount` which wasn't that useful.
Doesn't actually do anything yet mind.
Make margin visible on Left, Right and Inline views.
The glyphs may be in the wrong place, and they're displayed erroneously on the RHS too, but they're there.
This required a rewrite of our diff handling - now using VS' inbuilt differ rather than DiffPlex.
There's a distinction - reviews are made of comments.
GitHub.VisualStudio was previously referencing it directly meaning that it wasn't found on a machine without VS2015 installed.
It was causing a crash on VS2017 for some reason.
| } | ||
| else | ||
| { | ||
| j = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we could do second, more forgiving pass that still matches if lines have been added? That would address the inconsistency where you can add lines above the chunk, but if you happen to add a line within the chunk the comment dissapears (for me this is the most disconcerting bit).
I'm sure there are fancier things we could do later, but this would be simple, consistent and predictable. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, one really simple thing we could do is treat / as white space when matching lines. That way a developer could // out lines and not immediately loose their inline comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…sualStudio into feature/inline-reviews
| return Task.Factory.StartNew(() => | ||
| { | ||
| var commit = repository.Lookup<Commit>(commitSha); | ||
| if(commit == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space missing!
| var tempFile = Path.Combine(tempDir, tempFileName); | ||
|
|
||
| Directory.CreateDirectory(tempDir); | ||
| File.WriteAllText(tempFile, contents, encoding); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which thread is this happening in? If it's on the main thread, IO is slow for some reason and the file is large, this may block the UI. All IO should be off on a side thread to avoid this.
| if (mergeBase == null) | ||
| { | ||
| throw new FileNotFoundException($"Could not retrieve {fileName}@{pullRequest.Base.Sha}"); | ||
| throw new FileNotFoundException($"Couldn't find merge base between {baseSha} and {headSha}."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exception type doesn't match the actual exception, this isn't an IO operation. Perhaps a custom exception type could be useful here for conveying meaning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was reluctant to create a new exception type for something that really shouldn't happen. I've changed it to InvalidOperationException which we're using elsewhere in this class. Still not ideal, but at least it isn't an IO exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the heads up. I'll revert my other commit. Did you fix a test for that as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I changed the test to expect NotFoundException too.
| static string CreateTempFile(string fileName, string commitSha, string contents, Encoding encoding) | ||
| { | ||
| var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); | ||
| var tempFileName = $"{Path.GetFileNameWithoutExtension(fileName)}@{commitSha}{Path.GetExtension(fileName)}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't be trusting that the filename coming from the PR is valid under the current locale and encoding or even valid to Windows. There are certain filenames that can be created in other OSs that the Windows fs can't deal with, and there are certain characters and encodings that might not match the local. In this case, ignoring the string formatting warning is not a good option, and using the original filename to create a temp file is probably not a good option either.
We're already creating a GUID in the directory name, if we use the GUID instead for the filename we avoid both issues entirely. Alternatively, if you want to reuse the cached temp file, you could encode the filename with Convert.ToBase64String(Encoding.UTF8.GetBytes(filename)) and put it in a known temp directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment I don't think the file path is surfaced anywhere, but it is visible in the #1036 PR (which isn't ideal).
Maybe we should find a way to sanitize the file name and not include the commitSha? Would URL-encoding the filename work? I think we definitely need to need to keep the file extension for automatic syntax highlighting.
| var tempFileName = $"{Path.GetFileNameWithoutExtension(fileName)}@{commitSha}{Path.GetExtension(fileName)}"; | ||
| var tempFile = Path.Combine(tempDir, tempFileName); | ||
|
|
||
| Directory.CreateDirectory(tempDir); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have an OS facade to abstract the filesystem out for these things. We should use it everywhere, for consistency.
| return sb.ToString(); | ||
| } | ||
|
|
||
| public static bool EqualsIgnoringLineEndings(this string a, string b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't being used anywhere, is it still needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope!
| } | ||
| } | ||
|
|
||
| private void ViewCommentsClick(object sender, RoutedEventArgs e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👀 private 👀
| null); | ||
| } | ||
|
|
||
| private async void ViewFileCommentsClick(object sender, RoutedEventArgs e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👀 private 👀
| { | ||
| foreach (var b in encoding.GetPreamble()) | ||
| { | ||
| if(b != stream.ReadByte()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if space!
| glyphs = dictionary; | ||
| } | ||
| } | ||
| static ITextViewLine GetStartingLine(IList<ITextViewLine> lines, Span span) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing newline
| } | ||
| } | ||
|
|
||
| public FrameworkElement MarginVisual => glyphMarginGrid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properties should be defined after methods
|
|
||
| public event EventHandler Disposed; | ||
|
|
||
| public void Dispose() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs implementing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's actually anything we need to dispose here. The reason this method appears is that IPeekResult implements IDisposable so we need to implement it too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've marked it as sealed because it isn't intended to be extended.
| public ReactiveCommand<object> CancelEdit { get; } | ||
|
|
||
| /// <inheritdoc/> | ||
| public ReactiveCommand<Unit> CommitEdit { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these properties should be after methods
| /// <summary> | ||
| /// Gets the thread of comments to display. | ||
| /// </summary> | ||
| public ICommentThreadViewModel Thread |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably called something other than Thread, since there's a Thread type that can easily be confused with it, and makes the code harder to read. We call a series of related comments a Discussion on .com.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd not considered this; I've used Thread in the names of quite a few types as well.
| nextCommentCommand, | ||
| previousCommentCommand); | ||
| viewModel.Initialize().Forget(); | ||
| peekableItems.Add(new InlineCommentPeekableItem(viewModel)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The viewmodel may not be finished initializing by the time it's added to this list. What is the impact of that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be fine - the view model will update itself in-place. The reason I did it like this was to make clear that there's async work to be done - the other options were to do the async work in the ctor or make Initialize an async void method.
| IEnumerable<string> FilePaths | ||
| { | ||
| get { return PullRequest.ChangedFiles.Select(x => x.FileName); } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properties after methods
| catch (FileNotFoundException) | ||
| { | ||
| var pullHeadRef = $"refs/pull/{pullRequestNumber}/head"; | ||
| await gitClient.Fetch(repo, "origin", sha, pullHeadRef); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to use an https remote, so it needs to do var remote = await gitClient.GetHttpRemote(repo); and call fetch with the returned remote.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Already fixed this in the work associated with the PR details right-click menu.
shana
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a bunch of comments and there are things to address in subsequent PRs. Been using this branch to review, it works nicely! 😄


This PR adds inline comments for Pull Requests to editor and compare views in Visual Studio.
This PR implements the MVP for this feature, namely:
Toolbar buttons for text editordon't think this is necessary, toolbar buttons aren't very discoverableToolbar buttons already exist in the diff view - can we hook into them?can't find a way to do thisExisting comments displayed as marks on scrollbarspunting to a later date