Browse Source

update ChangeMarkerMargin when files are committed into the git repository

4.1
Siegfried Pammer 15 years ago
parent
commit
86f51556ff
  1. 8
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs
  2. 53
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs
  3. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs
  4. 52
      src/AddIns/VersionControl/GitAddIn/Src/GitVersionProvider.cs
  5. 5
      src/AddIns/VersionControl/SubversionAddIn/Src/SvnVersionProvider.cs
  6. 76
      src/Main/Base/Project/Src/Editor/IDocumentBaseVersionProvider.cs

8
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChangeMarkerMargin.cs

@ -2,24 +2,18 @@ @@ -2,24 +2,18 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit.AddIn.Options;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.AvalonEdit;
using ICSharpCode.SharpDevelop.Widgets;
namespace ICSharpCode.AvalonEdit.AddIn
{

53
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs

@ -6,14 +6,12 @@ using System.Collections.Generic; @@ -6,14 +6,12 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using ICSharpCode.AvalonEdit.AddIn.MyersDiff;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.AvalonEdit;
namespace ICSharpCode.AvalonEdit.AddIn
{
@ -23,6 +21,8 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -23,6 +21,8 @@ namespace ICSharpCode.AvalonEdit.AddIn
IDocument document;
TextDocument textDocument;
IDocument baseDocument;
IDocumentVersionProvider usedProvider;
IDisposable watcher;
public event EventHandler ChangeOccurred;
@ -47,23 +47,38 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -47,23 +47,38 @@ namespace ICSharpCode.AvalonEdit.AddIn
this.textDocument = (TextDocument)document.GetService(typeof(TextDocument));
this.changeList = new CompressingTreeList<LineChangeInfo>((x, y) => x.Equals(y));
Stream baseFileStream = GetBaseVersion();
InitializeBaseDocument();
if (usedProvider != null) {
string fileName = ((ITextEditor)document.GetService(typeof(ITextEditor))).FileName;
watcher = usedProvider.WatchBaseVersionChanges(fileName, HandleBaseVersionChanges);
}
SetupInitialFileState(false);
// TODO : update baseDocument on VCS actions
this.textDocument.LineTrackers.Add(this);
this.textDocument.UndoStack.PropertyChanged += UndoStackPropertyChanged;
}
void HandleBaseVersionChanges(object sender, EventArgs e)
{
ICSharpCode.Core.LoggingService.Info("HandleBaseVersionChanges");
InitializeBaseDocument();
SetupInitialFileState(true);
}
void InitializeBaseDocument()
{
Stream baseFileStream = GetBaseVersion();
if (baseFileStream != null) {
// ReadAll() is taking care of closing the stream
baseDocument = DocumentUtilitites.LoadReadOnlyDocumentFromBuffer(new StringTextBuffer(ReadAll(baseFileStream)));
} else {
// if the file is not under subversion, the document is the opened document
if (baseDocument == null) {
// if the file is not under subversion, the document is the opened document
baseDocument = DocumentUtilitites.LoadReadOnlyDocumentFromBuffer(document.CreateSnapshot());
}
}
SetupInitialFileState(false);
this.textDocument.LineTrackers.Add(this);
this.textDocument.UndoStack.PropertyChanged += UndoStackPropertyChanged;
}
LineChangeInfo TransformLineChangeInfo(LineChangeInfo info)
@ -115,9 +130,11 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -115,9 +130,11 @@ namespace ICSharpCode.AvalonEdit.AddIn
string ReadAll(Stream stream)
{
using (StreamReader reader = new StreamReader(stream)) {
return reader.ReadToEnd();
}
var memory = new MemoryStream();
stream.CopyTo(memory);
stream.Close();
memory.Position = 0;
return FileReader.ReadFileContent(memory, ParserService.DefaultFileEncoding);
}
Stream GetBaseVersion()
@ -126,10 +143,12 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -126,10 +143,12 @@ namespace ICSharpCode.AvalonEdit.AddIn
foreach (IDocumentVersionProvider provider in VersioningServices.Instance.DocumentVersionProviders) {
var result = provider.OpenBaseVersion(fileName);
if (result != null)
if (result != null) {
usedProvider = provider;
return result;
}
}
return null;
}
@ -172,6 +191,8 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -172,6 +191,8 @@ namespace ICSharpCode.AvalonEdit.AddIn
public void Dispose()
{
if (!disposed) {
if (watcher != null)
watcher.Dispose();
this.textDocument.LineTrackers.Remove(this);
this.textDocument.UndoStack.PropertyChanged -= UndoStackPropertyChanged;
disposed = true;

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs

@ -2,8 +2,6 @@ @@ -2,8 +2,6 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.AvalonEdit.AddIn

52
src/AddIns/VersionControl/GitAddIn/Src/GitVersionProvider.cs

@ -7,6 +7,7 @@ using System.IO; @@ -7,6 +7,7 @@ using System.IO;
using System.IO.Pipes;
using System.Runtime.InteropServices;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Util;
using Microsoft.Win32.SafeHandles;
@ -85,7 +86,7 @@ namespace ICSharpCode.GitAddIn @@ -85,7 +86,7 @@ namespace ICSharpCode.GitAddIn
return OpenOutput(git, fileName, GetBlobHash(git, fileName));
}
string GetBlobHash(string gitExe, string fileName)
internal static string GetBlobHash(string gitExe, string fileName)
{
ProcessRunner runner = new ProcessRunner();
runner.WorkingDirectory = Path.GetDirectoryName(fileName);
@ -136,5 +137,54 @@ namespace ICSharpCode.GitAddIn @@ -136,5 +137,54 @@ namespace ICSharpCode.GitAddIn
return pipe;
}
public IDisposable WatchBaseVersionChanges(string fileName, EventHandler callback)
{
if (!Git.IsInWorkingCopy(fileName))
return null;
string git = Git.FindGit();
if (git == null)
return null;
return new BaseVersionChangeWatcher(fileName, GetBlobHash(git, fileName), callback);
}
}
class BaseVersionChangeWatcher : IDisposable
{
EventHandler callback;
string fileName, hash;
RepoChangeWatcher watcher;
public BaseVersionChangeWatcher(string fileName, string hash, EventHandler callback)
{
string root = Git.FindWorkingCopyRoot(fileName);
if (root == null)
throw new InvalidOperationException(fileName + " must be under version control!");
this.callback = callback;
this.fileName = fileName;
this.hash = hash;
watcher = RepoChangeWatcher.AddWatch(Path.Combine(root, ".git"), HandleChanges);
}
void HandleChanges()
{
string newHash = GitVersionProvider.GetBlobHash(Git.FindGit(), fileName);
if (newHash != hash) {
LoggingService.Info(fileName + " was changed!");
callback(this, EventArgs.Empty);
}
this.hash = newHash;
}
public void Dispose()
{
watcher.ReleaseWatch(HandleChanges);
}
}
}

5
src/AddIns/VersionControl/SubversionAddIn/Src/SvnVersionProvider.cs

@ -19,5 +19,10 @@ namespace ICSharpCode.Svn @@ -19,5 +19,10 @@ namespace ICSharpCode.Svn
using (SvnClientWrapper client = new SvnClientWrapper())
return client.OpenBaseVersion(fileName);
}
public IDisposable WatchBaseVersionChanges(string fileName, EventHandler callback)
{
return null;
}
}
}

76
src/Main/Base/Project/Src/Editor/IDocumentBaseVersionProvider.cs

@ -6,6 +6,7 @@ using System.Collections.Generic; @@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Editor
{
@ -16,6 +17,8 @@ namespace ICSharpCode.SharpDevelop.Editor @@ -16,6 +17,8 @@ namespace ICSharpCode.SharpDevelop.Editor
/// to disk or a base version provided by any VCS.
/// </summary>
Stream OpenBaseVersion(string fileName);
IDisposable WatchBaseVersionChanges(string fileName, EventHandler callback);
}
public class VersioningServices
@ -34,4 +37,77 @@ namespace ICSharpCode.SharpDevelop.Editor @@ -34,4 +37,77 @@ namespace ICSharpCode.SharpDevelop.Editor
}
}
public class RepoChangeWatcher
{
static readonly Dictionary<string, RepoChangeWatcher> watchers
= new Dictionary<string, RepoChangeWatcher>(StringComparer.OrdinalIgnoreCase);
Action actions;
FileSystemWatcher watcher;
RepoChangeWatcher(string repositoryRoot)
{
this.watcher = new FileSystemWatcher(repositoryRoot);
if (WorkbenchSingleton.Workbench != null)
watcher.SynchronizingObject = WorkbenchSingleton.Workbench.SynchronizingObject;
WorkbenchSingleton.MainWindow.Activated += MainWindowActivated;
watcher.Created += FileChanged;
watcher.Deleted += FileChanged;
watcher.Changed += FileChanged;
watcher.Renamed += FileChanged;
// watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
}
void MainWindowActivated(object sender, EventArgs e)
{
alreadyCalled = false;
actions();
}
bool alreadyCalled;
void FileChanged(object sender, FileSystemEventArgs e)
{
if (!alreadyCalled) {
alreadyCalled = true;
LoggingService.Info(e.Name + " changed!" + e.ChangeType);
if (WorkbenchSingleton.Workbench.IsActiveWindow) {
WorkbenchSingleton.CallLater(
TimeSpan.FromSeconds(2),
() => { MainWindowActivated(this, EventArgs.Empty); }
);
}
}
}
public static RepoChangeWatcher AddWatch(string repositoryRoot, Action action)
{
RepoChangeWatcher watcher;
if (!watchers.TryGetValue(repositoryRoot, out watcher)) {
watcher = new RepoChangeWatcher(repositoryRoot);
watchers.Add(repositoryRoot, watcher);
}
watcher.actions += action;
return watcher;
}
bool disposed;
public void ReleaseWatch(Action action)
{
actions -= action;
if (actions == null && !disposed) {
WorkbenchSingleton.MainWindow.Activated -= MainWindowActivated;
watchers.Remove(watcher.Path);
this.watcher.Dispose();
disposed = true;
}
}
}
}

Loading…
Cancel
Save