Skip to content

Commit

Permalink
Merge branch 'hdevtools'
Browse files Browse the repository at this point in the history
  • Loading branch information
LukaHorvat committed Aug 3, 2014
2 parents dcc9fec + 9e2ce95 commit 20e55dd
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 39 deletions.
96 changes: 65 additions & 31 deletions HaskellPackage/ErrorTagger.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EnvDTE;
using HDevTools;
using LukaHorvat.GHCi;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.OLE.Interop;
Expand Down Expand Up @@ -39,6 +40,7 @@ internal class ErrorTaggerProvider : IViewTaggerProvider
private DTE dte;
private Events events;
private DocumentEvents docEvents;
private DTEEvents dteEvents;

private static SortedSet<string> filesStartedFor = new SortedSet<string>();

Expand All @@ -48,19 +50,45 @@ internal class ErrorTaggerProvider : IViewTaggerProvider
private static event Action<string> saveEvent;
private static Dictionary<Document, Action<string>> handlersByDocument = new Dictionary<Document, Action<string>>();

private static bool hDevServerStarted = false;

private void KillServers()
{
while (System.Diagnostics.Process.GetProcessesByName("hdevtools").Any())
{
HDevToolsRunner.StopServer();
System.Threading.Thread.Sleep(100);
}
}

public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
{
var document = (ITextDocument)buffer.Properties[typeof(ITextDocument)];

if (errorListProvider == null)
{
dte = (DTE)ServiceProvider.GetService(typeof(DTE));
events = dte.Events;
dteEvents = events.DTEEvents;
docEvents = events.DocumentEvents;
errorListProvider = new ErrorListProvider(ServiceProvider);
docEvents.DocumentSaved += doc => { if (saveEvent != null) saveEvent.Invoke(doc.FullName); };
dteEvents.OnBeginShutdown += delegate
{
if (hDevServerStarted)
{
KillServers();
hDevServerStarted = false;
}
};
if (!hDevServerStarted)
{
KillServers();
hDevServerStarted = true;
HDevToolsRunner.StartServer(document.FilePath);
}
}

var document = (ITextDocument)buffer.Properties[typeof(ITextDocument)];

if (!filesStartedFor.Contains(document.FilePath))
{
IVsUIHierarchy hierarchy;
Expand Down Expand Up @@ -90,36 +118,42 @@ public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where
MyControl.CurrentInstance.RestartInstance(doc);
}
}
var errors = Diagnostics.GetErrors(buffer, document);
foreach (var error in errors)
new System.Threading.Thread(() =>
{
bool skip = aggregator.Any(entry =>
entry.Line == error.Line &&
entry.Column == error.Column &&
entry.FileName == error.FileName &&
entry.Message == error.Message
);
if (skip) continue;
var errorTask = new ErrorTask
var errors = Diagnostics.GetErrors(buffer, document);
foreach (var error in errors)
{
ErrorCategory = error.Severity,
Category = TaskCategory.BuildCompile,
Text = error.Message,
Document = error.FileName,
Line = error.Line,
Column = error.Column,
};
errorTask.Navigate += (sender, args) =>
{
errorTask.Line++;
errorListProvider.Navigate(errorTask, new Guid("{7651A701-06E5-11D1-8EBD-00A0C90F26EA}") /* EnvDTE.Constants.vsViewKindCode */);
errorTask.Line--;
};
errorListProvider.Tasks.Add(errorTask);
aggregator.Add(error);
}
errorListProvider.Refresh();
errorListProvider.Show();
lock (aggregator)
{
bool skip = aggregator.Any(entry =>
entry.Line == error.Line &&
entry.Column == error.Column &&
entry.FileName == error.FileName &&
entry.Message == error.Message
);
if (skip) continue;
var errorTask = new ErrorTask
{
ErrorCategory = error.Severity,
Category = TaskCategory.BuildCompile,
Text = error.Message,
Document = error.FileName,
Line = error.Line,
Column = error.Column,
};
errorTask.Navigate += (sender, args) =>
{
errorTask.Line++;
errorListProvider.Navigate(errorTask, new Guid("{7651A701-06E5-11D1-8EBD-00A0C90F26EA}") /* EnvDTE.Constants.vsViewKindCode */);
errorTask.Line--;
};
errorListProvider.Tasks.Add(errorTask);
aggregator.Add(error);
}
}
errorListProvider.Refresh();
errorListProvider.Show();
}).Start();
};
saveEvent += handler;
textView.Closed += delegate
Expand Down Expand Up @@ -262,7 +296,7 @@ public static string FullPathRelativeTo(string root, string partialPath)

public static IEnumerable<ErrorReportEntry> GetErrors(ITextBuffer buffer, ITextDocument document)
{
var report = GhcMod.GhcMod.Check(document.FilePath).Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(err => err.Replace('\0', '\n')).ToList();
var report = HDevToolsRunner.Check(document.FilePath).Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(err => err.Replace('\0', '\n')).ToList();
foreach (var errorString in report)
{
var regex = new Regex(@"((\w:)?[^:]*):([0-9]*):([0-9]*):(.*)");
Expand Down
4 changes: 2 additions & 2 deletions HaskellPackage/HaskellPackage.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
<Reference Include="envdte100, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="GhcMod">
<HintPath>..\..\GhcMod\GhcMod\bin\Debug\GhcMod.dll</HintPath>
<Reference Include="HDevTools">
<HintPath>..\..\HDevTools\HDevTools\bin\Debug\HDevTools.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.CoreUtility" />
<Reference Include="Microsoft.VisualStudio.Editor, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
Expand Down
6 changes: 3 additions & 3 deletions HaskellPackage/QuickInfoSource.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.VisualStudio.Language.Intellisense;
using HDevTools;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.Utilities;
Expand All @@ -8,7 +9,6 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GhcMod;

namespace HaskellPackage
{
Expand Down Expand Up @@ -42,7 +42,7 @@ public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qui
else column += 1;

}
var typeInfo = GhcMod.GhcMod.GetType(doc.FilePath, line.LineNumber + 1, column);
var typeInfo = HDevToolsRunner.GetType(doc.FilePath, line.LineNumber + 1, column);
if (typeInfo == null)
{
applicableToSpan = null;
Expand Down
5 changes: 3 additions & 2 deletions HaskellPackage/source.extension.vsixmanifest
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="HaskellPackage..53ffb502-1e2e-4639-bf19-031b15d6cafe" Version="1.0" Language="en-US" Publisher="Luka Horvat" />
<Identity Id="HaskellPackage..53ffb502-1e2e-4639-bf19-031b15d6cafe" Version="2.0" Language="en-US" Publisher="Luka Horvat" />
<DisplayName>HaskellPackage</DisplayName>
<Description>This is a sample classifier extension to the Visual Studio Editor.</Description>
<Description xml:space="preserve">This is a Haskell integration package for Visual Studio</Description>
</Metadata>
<Installation>
<InstallationTarget Id="Microsoft.VisualStudio.Pro" Version="12.0" />
<InstallationTarget Version="[10.0,13.0)" Id="Microsoft.VisualStudio.Pro" />
</Installation>
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="4.5" />
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ Haskell integration for Visual Studio
I make absolutely no guarantees about it working properly but I would appreciate bug reports if anyone tries using it.

You need to have ghc/ghci installed. Preferably the Haskell Platform because that's what I tested it on.
You also need ghc-mod which you can get via cabal. All of those need to be in your PATH.
You also need hdevtools, the fork with Windows support.
Clone this project https://github.com/mvoidex/hdevtools, go into the folder and run 'cabal install'.
All of those need to be in your PATH. They should be there by default.

Aside from that, I've only tested it on VS2013 ultimate and have NO idea how well, if at all, it works on other versions.

When you run the extension for the first time you might be asked to add the hdevtools server to firewall exceptions. It doesn't matter if you do or don't.

To use the extension just open any .hs file in Visual Studio. If you see syntax coloring, then it works.
Everything works by invoking ghc-mod from the command line so to use features make sure you save your file.

Expand All @@ -21,6 +26,11 @@ The comment/uncomment block feature also works.
To get the GHCi window go to View -> Other Windows -> GHCi.
GHCi automatically refreshes and loads the currently open file whenever you hit save. If you get stuck with GHCi outputting too much data (for example, typing [1..]) just Ctrl-S on the currently open file and it will restart.

Notes
=====

Due to certain limitations, you can only use the extension for a single project at a time. If you want to switch to another project, close Visual Studio and open up a new file.

Installation
============

Expand Down

0 comments on commit 20e55dd

Please sign in to comment.