Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Open from clipboard url #1771

Merged
merged 69 commits into from
Jul 13, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
1de94ef
Add GitHub.OpenFromUrl command
jcansdale Jun 22, 2018
516128a
Update UriString to handle extended GitHub URLs
jcansdale Jun 22, 2018
7071b43
Support opening target from GitHub URL
jcansdale Jun 22, 2018
199a79f
Allow navigating to URL from clipboard
jcansdale Jun 25, 2018
134f6a8
Checkout or open using default path
jcansdale Jun 25, 2018
d5b833d
Don't open folder if current solution is inside it
jcansdale Jun 25, 2018
c097098
Add support for navigating to a PR URL
jcansdale Jun 25, 2018
12eb8d5
Open at line number from GitHub URL
jcansdale Jun 25, 2018
9399711
Add Open from GitHub command to File > Open
jcansdale Jun 25, 2018
89484dc
Merge branch 'master' into fixes/1757-open-from-url
jcansdale Jun 26, 2018
0aade59
Update UriString to allow http URLs with owner
jcansdale Jun 26, 2018
70d9d90
Find GitHub context from Chrome window title
jcansdale Jun 27, 2018
a82390f
Add support for opening from topmost browser
jcansdale Jun 27, 2018
c4cac4d
Support syncing the file open in topmost browser
jcansdale Jun 27, 2018
d1b0231
Ask user before cloning or opening a repository
jcansdale Jun 28, 2018
0d264d5
Factor GitHub URL parsing into FindContextFromUrl
jcansdale Jun 28, 2018
19249b0
Convert from GitHub to Visual Studio line numbers
jcansdale Jun 28, 2018
9b0fe66
Add support for file links that use a commit SHA
jcansdale Jun 28, 2018
7320235
Fix a few typos
jcansdale Jun 28, 2018
e900d7d
Update title regex to work with Firefox
jcansdale Jun 29, 2018
5019370
Detect repository home with no description
jcansdale Jul 2, 2018
90c0aa9
Use regex for matching line
jcansdale Jul 3, 2018
0bed9b2
Find line end from GitHub URL
jcansdale Jul 3, 2018
0aae4ca
Add support for navigating to a range of lines
jcansdale Jul 3, 2018
0fc10b7
Highlight line when single line is selected
jcansdale Jul 3, 2018
cfdf410
Select just the target lines
jcansdale Jul 3, 2018
55b1570
Stop the tuple madness
jcansdale Jul 3, 2018
cb7816c
Explicitly match CommitSha in blob URLs
jcansdale Jul 3, 2018
2243891
Add ResolvePath to resolve Treeish + BlobName
jcansdale Jul 3, 2018
39f3a54
Rename Treeish to TreeishPath
jcansdale Jul 4, 2018
d06ba40
First try opening in active repository
jcansdale Jul 4, 2018
d9ce6f5
Add separate `GitHub.OpenFromClipboard` command
jcansdale Jul 4, 2018
dbcb792
Simplify OpenFromClipboardCommand
jcansdale Jul 4, 2018
8e968cc
Show alert when no GitHub URL in clipboard
jcansdale Jul 4, 2018
b31b14f
Add ResolveGitObject to find local object from URL
jcansdale Jul 5, 2018
5b16030
Merge branch 'master' into fixes/1757-open-from-url
jcansdale Jul 5, 2018
92ffa39
Show message when there is no repo to navigate
jcansdale Jul 5, 2018
1f0f5fb
Return commitish and path from ResolveGitObject
jcansdale Jul 5, 2018
1d468d9
Let ResolveGitObject resolve commit without path
jcansdale Jul 5, 2018
5058564
Warn user when changes in local version of file
jcansdale Jul 5, 2018
bc780c4
If target blob has changed then show AnnotateFile
jcansdale Jul 6, 2018
c175d97
Don't throw when navigating to non-blob
jcansdale Jul 6, 2018
7784364
Rename ResolveGitObject to ResolveBlob
jcansdale Jul 6, 2018
6a3d8e4
Remove legacy ResolvePath method
jcansdale Jul 6, 2018
11866fb
Remove Open from GitHub... from File > Open menu
jcansdale Jul 9, 2018
c5c493d
Warn when user isn't in target repository
jcansdale Jul 9, 2018
36d6b0b
Merge branch 'master' into feature/open-from-clipboard-url
jcansdale Jul 9, 2018
3029ccd
Merge branch 'feature/open-from-clipboard-url' of https://github.com/…
jcansdale Jul 9, 2018
de5726f
Make ResolveBlob return if commitish is a SHA
jcansdale Jul 9, 2018
ab3e7e9
Change ResolveBlob to resolve remote refs
jcansdale Jul 9, 2018
19be672
Return commit SHA from ResolveBlob
jcansdale Jul 10, 2018
381806b
Add support for resolving tags
jcansdale Jul 10, 2018
f81fb36
Warn if URL owner is different to current owner
jcansdale Jul 10, 2018
e1bfa23
Allow repository names to differ in case
jcansdale Jul 10, 2018
fd0f835
Merge branch 'master' into feature/open-from-clipboard-url
jcansdale Jul 12, 2018
c429d76
Show dialog when attempting to open non-blob URL
jcansdale Jul 12, 2018
9ad3ba7
We don't support vpath in a URL
jcansdale Jul 12, 2018
81b6d8a
Lose the App form GitHub.App.Services
jcansdale Jul 12, 2018
f651b19
Clean up and xmldoc the AnnotateFile method
jcansdale Jul 12, 2018
f12ab09
Remove FindContextFromBrowser from hidden command
jcansdale Jul 12, 2018
057a77f
Add xmldocs for GitHubContext
jcansdale Jul 12, 2018
513b562
Add xmldocs for GitHubContextService
jcansdale Jul 12, 2018
b26b2a9
Merge branch 'master' into feature/open-from-clipboard-url
jcansdale Jul 13, 2018
83610bf
Only show command when in context of git repo
jcansdale Jul 13, 2018
bec5eca
Add more xmldocs
jcansdale Jul 13, 2018
ce68103
Lazy initialize the UIContext
jcansdale Jul 13, 2018
e88a3e4
Merge branch 'master' into feature/open-from-clipboard-url
grokys Jul 13, 2018
22ec886
Use <inheritdoc/> on members not classes!
jcansdale Jul 13, 2018
edbec49
Make <summary> xmldoc elements a single sentence
jcansdale Jul 13, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add xmldocs for GitHubContextService
  • Loading branch information
jcansdale committed Jul 12, 2018
commit 513b562a9ce4939c011e9f6e34a1bf712f87698c
95 changes: 76 additions & 19 deletions src/GitHub.App/Services/GitHubContextService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,21 @@ public GitHubContextService(IGitHubServiceProvider serviceProvider, IGitService
textManager = new Lazy<IVsTextManager2>(() => serviceProvider.GetService<SVsTextManager, IVsTextManager2>());
}

/// <summary>
/// Find the context from a URL in the clipboard if any.
/// </summary>
/// <returns>The context or null if clipboard doesn't contain a GitHub URL</returns>
public GitHubContext FindContextFromClipboard()
{
var text = Clipboard.GetText(TextDataFormat.Text);
return FindContextFromUrl(text);
}

/// <summary>
/// Convert a GitHub URL to a context object.
/// </summary>
/// <param name="url">A GitHub URL</param>
/// <returns>The context from the URL or null</returns>
public GitHubContext FindContextFromUrl(string url)
{
var uri = new UriString(url);
Expand Down Expand Up @@ -117,6 +126,10 @@ public GitHubContext FindContextFromUrl(string url)
return context;
}

/// <summary>
/// Find the context from the title of the topmost browser.
/// </summary>
/// <returns>A context or null if a context can't be found.</returns>
public GitHubContext FindContextFromBrowser()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we'd decided not to put this feature in?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feature is on a back-burner, but the code and the hope is to eventually reactivate it.

The command that uses it GitHub.OpenFromUrl has been removed from the UI. It was previously surfaced via File > Open > Open from GitHub.... The command that is surfaced via GitHub > Open from clipboard is GitHub.OpenFromClipboard`.

It does make sense to remove it from GitHub.OpenFromUrl (which needs to be explicitly bound to a keyboard shortcut).

{
return
Expand All @@ -126,31 +139,23 @@ public GitHubContext FindContextFromBrowser()
.FirstOrDefault();
}

public IEnumerable<string> FindWindowTitlesForClass(string className = "MozillaWindowClass")
{
IntPtr handleWin = IntPtr.Zero;
while (IntPtr.Zero != (handleWin = User32.FindWindowEx(IntPtr.Zero, handleWin, className, IntPtr.Zero)))
{
// Allocate correct string length first
int length = User32.GetWindowTextLength(handleWin);
if (length == 0)
{
continue;
}

var titleBuilder = new StringBuilder(length + 1);
User32.GetWindowText(handleWin, titleBuilder, titleBuilder.Capacity);
yield return titleBuilder.ToString();
}
}

/// <summary>
/// Convert a context to a repository URL.
/// </summary>
/// <param name="context">The context to convert.</param>
/// <returns>A repository URL</returns>
public Uri ToRepositoryUrl(GitHubContext context)
{
var builder = new UriBuilder("https", context.Host ?? "github.com");
builder.Path = $"{context.Owner}/{context.RepositoryName}";
return builder.Uri;
}

/// <summary>
/// Find a context from a browser window title.
/// </summary>
/// <param name="windowTitle">A browser window title.</param>
/// <returns>The context or null if none can be found</returns>
public GitHubContext FindContextFromWindowTitle(string windowTitle)
{
var match = windowTitleBlobRegex.Match(windowTitle);
Expand Down Expand Up @@ -237,6 +242,12 @@ public GitHubContext FindContextFromWindowTitle(string windowTitle)
return null;
}

/// <summary>
/// Open a file in the working directory that corresponds to a context and navigate to a line/range.
/// </summary>
/// <param name="repositoryDir">The working directory.</param>
/// <param name="context">A context to navigate to.</param>
/// <returns>True if navigation was successful</returns>
public bool TryOpenFile(string repositoryDir, GitHubContext context)
{
var (commitish, path, isSha) = ResolveBlob(repositoryDir, context);
Expand All @@ -251,6 +262,13 @@ public bool TryOpenFile(string repositoryDir, GitHubContext context)
return true;
}

/// <summary>
/// Map from a context to a repository blob object.
/// </summary>
/// <param name="repositoryDir">The target repository.</param>
/// <param name="context">The context to map from.</param>
/// <param name="remoteName">The name of the remote to search for branches.</param>
/// <returns>The resolved commit-ish, blob path and commit SHA for the blob. Path will be null if the commit-ish can be resolved but not the blob.</returns>
public (string commitish, string path, string commitSha) ResolveBlob(string repositoryDir, GitHubContext context, string remoteName = "origin")
{
Guard.ArgumentNotNull(repositoryDir, nameof(repositoryDir));
Expand Down Expand Up @@ -316,6 +334,16 @@ public bool TryOpenFile(string repositoryDir, GitHubContext context)
}
}

/// <summary>
/// Check if a file in the working directory has changed since a specified commit-ish.
/// </summary>
/// <remarks>
/// The commit-ish might be a commit SHA, a tag or a remote branch.
/// </remarks>
/// <param name="repositoryDir">The target repository.</param>
/// <param name="commitish">A commit SHA, remote branch or tag.</param>
/// <param name="path">The path for a blob.</param>
/// <returns>True if the working file is different.</returns>
public bool HasChangesInWorkingDirectory(string repositoryDir, string commitish, string path)
{
using (var repo = gitService.GetRepository(repositoryDir))
Expand All @@ -327,6 +355,17 @@ public bool HasChangesInWorkingDirectory(string repositoryDir, string commitish,
}
}

/// <summary>
/// Attempt to open the Blame/Annotate view for a context.
/// </summary>
/// <remarks>
/// The access to the Blame/Annotate view was added in a version of Visual Studio 2017. This method will return
/// false is this functionality isn't available.
/// </remarks>
/// <param name="repositoryDir">The target repository</param>
/// <param name="currentBranch">A branch in the local repository. It isn't displayed on the UI but must exist. It can be a remote or local branch.</param>
/// <param name="context">The context to open.</param>
/// <returns>True if AnnotateFile functionality is available.</returns>
public async Task<bool> TryAnnotateFile(string repositoryDir, string currentBranch, GitHubContext context)
{
var (commitish, path, commitSha) = ResolveBlob(repositoryDir, context);
Expand Down Expand Up @@ -371,7 +410,7 @@ IVsTextView FindActiveView()
/// <param name="branchName">A branch of the target repository</param>
/// <param name="relativePath">A path the the target blob</param>
/// <param name="versionSha">The commit version of the blob</param>
/// <returns></returns>
/// <returns>True if AnnotateFile functionality is available.</returns>
bool AnnotateFile(string repositoryPath, string branchName, string relativePath, string versionSha)
{
var serviceType = Type.GetType("Microsoft.VisualStudio.TeamFoundation.Git.Extensibility.IGitExt2, Microsoft.TeamFoundation.Git.Provider", false);
Expand Down Expand Up @@ -485,6 +524,24 @@ static string FindSubPath(UriString gitHubUrl, string matchPath)
return path;
}

static IEnumerable<string> FindWindowTitlesForClass(string className)
{
IntPtr handleWin = IntPtr.Zero;
while (IntPtr.Zero != (handleWin = User32.FindWindowEx(IntPtr.Zero, handleWin, className, IntPtr.Zero)))
{
// Allocate correct string length first
int length = User32.GetWindowTextLength(handleWin);
if (length == 0)
{
continue;
}

var titleBuilder = new StringBuilder(length + 1);
User32.GetWindowText(handleWin, titleBuilder, titleBuilder.Capacity);
yield return titleBuilder.ToString();
}
}

static class User32
{
[DllImport("user32.dll", SetLastError = true)]
Expand Down
2 changes: 0 additions & 2 deletions src/GitHub.Exports/Services/IGitHubContextService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace GitHub.Services
{
Expand All @@ -10,7 +9,6 @@ public interface IGitHubContextService
GitHubContext FindContextFromBrowser();
GitHubContext FindContextFromUrl(string url);
GitHubContext FindContextFromWindowTitle(string windowTitle);
IEnumerable<string> FindWindowTitlesForClass(string className);
Uri ToRepositoryUrl(GitHubContext context);
bool TryOpenFile(string repositoryDir, GitHubContext context);
Task<bool> TryAnnotateFile(string repositoryDir, string currentBranch, GitHubContext context);
Expand Down