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. 51
      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 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit.AddIn.Options;
using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering; using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.AvalonEdit;
using ICSharpCode.SharpDevelop.Widgets;
namespace ICSharpCode.AvalonEdit.AddIn namespace ICSharpCode.AvalonEdit.AddIn
{ {

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

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

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

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

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

@ -7,6 +7,7 @@ using System.IO;
using System.IO.Pipes; using System.IO.Pipes;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Util; using ICSharpCode.SharpDevelop.Util;
using Microsoft.Win32.SafeHandles; using Microsoft.Win32.SafeHandles;
@ -85,7 +86,7 @@ namespace ICSharpCode.GitAddIn
return OpenOutput(git, fileName, GetBlobHash(git, fileName)); 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(); ProcessRunner runner = new ProcessRunner();
runner.WorkingDirectory = Path.GetDirectoryName(fileName); runner.WorkingDirectory = Path.GetDirectoryName(fileName);
@ -136,5 +137,54 @@ namespace ICSharpCode.GitAddIn
return pipe; 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
using (SvnClientWrapper client = new SvnClientWrapper()) using (SvnClientWrapper client = new SvnClientWrapper())
return client.OpenBaseVersion(fileName); 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;
using System.IO; using System.IO;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Editor namespace ICSharpCode.SharpDevelop.Editor
{ {
@ -16,6 +17,8 @@ namespace ICSharpCode.SharpDevelop.Editor
/// to disk or a base version provided by any VCS. /// to disk or a base version provided by any VCS.
/// </summary> /// </summary>
Stream OpenBaseVersion(string fileName); Stream OpenBaseVersion(string fileName);
IDisposable WatchBaseVersionChanges(string fileName, EventHandler callback);
} }
public class VersioningServices public class VersioningServices
@ -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