Skip to content
Browse files

Update the diff margin when changes are made to the repository

  • Loading branch information...
1 parent e1035c9 commit 40588d1c5f0eeeea286b9feddb5a342917419c12 @laurentkempe committed Apr 6, 2013
View
52 GitDiffMargin/DiffUpdateBackgroundParser.cs
@@ -1,28 +1,69 @@
-using GitDiffMargin.Git;
+using System.IO;
+using System.Threading;
+using EnvDTE;
+using GitDiffMargin.Git;
using System;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text;
using Stopwatch = System.Diagnostics.Stopwatch;
+using Task = System.Threading.Tasks.Task;
namespace GitDiffMargin
{
public class DiffUpdateBackgroundParser : BackgroundParser
{
+ private readonly FileSystemWatcher _watcher;
private readonly IGitCommands _commands;
- private ITextDocument _textDocument;
+ private readonly ITextDocument _textDocument;
- public DiffUpdateBackgroundParser(ITextBuffer textBuffer, TaskScheduler taskScheduler, ITextDocumentFactoryService textDocumentFactoryService, IGitCommands commands)
+ public DiffUpdateBackgroundParser(ITextBuffer textBuffer, TaskScheduler taskScheduler, ITextDocumentFactoryService textDocumentFactoryService, SVsServiceProvider serviceProvider, IGitCommands commands)
: base(textBuffer, taskScheduler, textDocumentFactoryService)
{
+ var dte = (DTE)serviceProvider.GetService(typeof(DTE));
+
_commands = commands;
ReparseDelay = TimeSpan.FromMilliseconds(500);
if (TextDocumentFactoryService.TryGetTextDocument(TextBuffer, out _textDocument))
{
_textDocument.FileActionOccurred += OnFileActionOccurred;
+
+ if (!string.IsNullOrWhiteSpace(dte.Solution.FullName))
+ {
+ if (_commands.IsGitRepository(dte.Solution.FullName))
+ {
+ var solutionDirectory = Path.GetDirectoryName(dte.Solution.FullName);
+
+ _watcher = new FileSystemWatcher(solutionDirectory);
+ _watcher.IncludeSubdirectories = true;
+ _watcher.Changed += HandleFileSystemChanged;
+ _watcher.Created += HandleFileSystemChanged;
+ _watcher.Deleted += HandleFileSystemChanged;
+ _watcher.Renamed += HandleFileSystemChanged;
+ _watcher.EnableRaisingEvents = true;
+ }
+ }
}
}
+
+ private void HandleFileSystemChanged(object sender, FileSystemEventArgs e)
+ {
+ Action action = () => ProcessFileSystemChange(e);
+ Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
+ }
+
+ private void ProcessFileSystemChange(FileSystemEventArgs e)
+ {
+ if (e.ChangeType == WatcherChangeTypes.Changed && Directory.Exists(e.FullPath))
+ return;
+
+ if (string.Equals(Path.GetExtension(e.Name), ".lock", StringComparison.OrdinalIgnoreCase))
+ return;
+
+ MarkDirty(true);
+ }
private void OnFileActionOccurred(object sender, TextDocumentFileActionEventArgs e)
{
@@ -71,6 +112,11 @@ protected override void Dispose(bool disposing)
if (disposing)
{
_textDocument.FileActionOccurred -= OnFileActionOccurred;
+
+ if (_watcher != null)
+ {
+ _watcher.Dispose();
+ }
}
}
}
View
15 GitDiffMargin/Git/GitCommands.cs
@@ -36,6 +36,21 @@ public void StartExternalDiff(string filename)
p.Start();
}
+ public bool IsGitRepository(string directory)
+ {
+ var p = GetProcess(directory);
+ p.StartInfo.Arguments = String.Format(@" rev-parse");
+
+ p.Start();
+ // Do not wait for the child process to exit before
+ // reading to the end of its redirected stream.
+ // p.WaitForExit();
+ // Read the output stream first and then wait.
+ p.WaitForExit();
+
+ return p.ExitCode == 0;
+ }
+
private static Process GetProcess(string filename)
{
var p = new Process();
View
1 GitDiffMargin/Git/IGitCommands.cs
@@ -11,5 +11,6 @@ public interface IGitCommands
{
IEnumerable<HunkRangeInfo> GetGitDiffFor(string filename, ITextSnapshot snapshot);
void StartExternalDiff(string filename);
+ bool IsGitRepository(string directory);
}
}
View
2 GitDiffMargin/GitDiffMargin.cs
@@ -47,7 +47,7 @@ internal GitDiffMargin(IWpfTextView textView, MarginFactory factory)
_textView.Options.OptionChanged += HandleOptionChanged;
_gitDiffBarControl = new DiffMarginControl();
- _viewModel = new DiffMarginViewModel(this, _textView, factory.TextDocumentFactoryService, new GitCommands());
+ _viewModel = new DiffMarginViewModel(this, _textView, factory.TextDocumentFactoryService, factory.ServiceProvider, new GitCommands());
_gitDiffBarControl.DataContext = _viewModel;
_gitDiffBarControl.Width = MarginWidth;
}
View
4 GitDiffMargin/GitDiffMargin.csproj
@@ -67,6 +67,9 @@
<ApplicationIcon>Resources\Git-Icon-1788C.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ </Reference>
<Reference Include="GalaSoft.MvvmLight.Extras.WPF4">
<HintPath>..\packages\MvvmLightPreview.4.1.21.1\lib\net40\GalaSoft.MvvmLight.Extras.WPF4.dll</HintPath>
</Reference>
@@ -80,6 +83,7 @@
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.VisualStudio.Text.Data">
<Private>False</Private>
</Reference>
View
4 GitDiffMargin/GitDiffMarginFactory.cs
@@ -1,6 +1,7 @@
#region using
using System.ComponentModel.Composition;
+using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
@@ -26,6 +27,9 @@ internal sealed class MarginFactory : IWpfTextViewMarginProvider
[Import]
internal IEditorFormatMapService EditorFormatMapService { get; private set; }
+
+ [Import]
+ internal SVsServiceProvider ServiceProvider { get; private set; }
public IWpfTextViewMargin CreateMargin(IWpfTextViewHost textViewHost, IWpfTextViewMargin containerMargin)
{
View
5 GitDiffMargin/ViewModel/DiffMarginViewModel.cs
@@ -7,6 +7,7 @@
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GitDiffMargin.Git;
+using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
@@ -22,7 +23,7 @@ public class DiffMarginViewModel : ViewModelBase
private RelayCommand<DiffViewModel> _previousChangeCommand;
private RelayCommand<DiffViewModel> _nextChangeCommand;
- internal DiffMarginViewModel(GitDiffMargin margin, IWpfTextView textView, ITextDocumentFactoryService textDocumentFactoryService, IGitCommands gitCommands)
+ internal DiffMarginViewModel(GitDiffMargin margin, IWpfTextView textView, ITextDocumentFactoryService textDocumentFactoryService, SVsServiceProvider serviceProvider, IGitCommands gitCommands)
{
if (margin == null)
throw new ArgumentNullException("margin");
@@ -40,7 +41,7 @@ internal DiffMarginViewModel(GitDiffMargin margin, IWpfTextView textView, ITextD
_textView.LayoutChanged += OnLayoutChanged;
_textView.ViewportHeightChanged += OnViewportHeightChanged;
- _parser = new DiffUpdateBackgroundParser(textView.TextBuffer, TaskScheduler.Default, textDocumentFactoryService, gitCommands);
+ _parser = new DiffUpdateBackgroundParser(textView.TextBuffer, TaskScheduler.Default, textDocumentFactoryService, serviceProvider, gitCommands);
_parser.ParseComplete += HandleParseComplete;
_parser.RequestParse(false);
}

0 comments on commit 40588d1

Please sign in to comment.
Something went wrong with that request. Please try again.