├── art
├── adornment.png
└── edit-mode.png
├── src
├── Resources
│ └── Icon.png
├── source.extension.ico
├── Adornment
│ ├── AdornmentLayer.cs
│ ├── Adornment.cs
│ └── ItemControl.cs
├── ErrorList
│ ├── ErrorResult.cs
│ └── ErrorProcessor.cs
├── Properties
│ └── AssemblyInfo.cs
├── source.extension.cs
├── Options.cs
├── ErrorCatcherPackage.cs
├── source.extension.vsixmanifest
├── TextViewCreationListener.cs
├── packages.config
├── source.extension.resx
└── ErrorCatcher.csproj
├── .gitignore
├── .github
├── ISSUE_TEMPLATE.md
└── CONTRIBUTING.md
├── .gitattributes
├── LICENSE
├── CHANGELOG.md
├── appveyor.yml
├── ErrorCatcher.sln
└── README.md
/art/adornment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/ErrorCatcher/master/art/adornment.png
--------------------------------------------------------------------------------
/art/edit-mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/ErrorCatcher/master/art/edit-mode.png
--------------------------------------------------------------------------------
/src/Resources/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/ErrorCatcher/master/src/Resources/Icon.png
--------------------------------------------------------------------------------
/src/source.extension.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/ErrorCatcher/master/src/source.extension.ico
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | packages
2 |
3 | # User files
4 | *.suo
5 | *.user
6 | *.sln.docstates
7 | .vs/
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Rr]elease/
12 | x64/
13 | [Bb]in/
14 | [Oo]bj/
15 |
16 | # MSTest test Results
17 | [Tt]est[Rr]esult*/
18 | [Bb]uild[Ll]og.*
19 |
20 | # NCrunch
21 | *.ncrunchsolution
22 | *.ncrunchproject
23 | _NCrunch_WebCompiler
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Installed product versions
2 | - Visual Studio: [example 2015 Professional]
3 | - This extension: [example 1.1.21]
4 |
5 | ### Description
6 | Replace this text with a short description
7 |
8 | ### Steps to recreate
9 | 1. Replace this
10 | 2. text with
11 | 3. the steps
12 | 4. to recreate
13 |
14 | ### Current behavior
15 | Explain what it's doing and why it's wrong
16 |
17 | ### Expected behavior
18 | Explain what it should be doing after it's fixed.
--------------------------------------------------------------------------------
/src/Adornment/AdornmentLayer.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.Composition;
2 | using Microsoft.VisualStudio.Text.Editor;
3 | using Microsoft.VisualStudio.Utilities;
4 |
5 | namespace ErrorCatcher
6 | {
7 | public class AdornmentLayer
8 | {
9 | public const string LayerName = Vsix.Name;
10 |
11 | [Export(typeof(AdornmentLayerDefinition))]
12 | [Name(LayerName)]
13 | [Order(Before = PredefinedAdornmentLayers.Caret)]
14 | public AdornmentLayerDefinition editorAdornmentLayer = null;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/ErrorList/ErrorResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ErrorCatcher
8 | {
9 | public class ErrorResult
10 | {
11 | public ErrorResult(string fileName)
12 | {
13 | FileName = fileName;
14 | }
15 |
16 | public string FileName { get; set; }
17 | public int Errors { get; set; }
18 | public int Warnings { get; set; }
19 | public int Info { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2016 Mads Kristensen
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/src/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using ErrorCatcher;
2 | using System.Reflection;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle(Vsix.Name)]
6 | [assembly: AssemblyDescription(Vsix.Description)]
7 | [assembly: AssemblyConfiguration("")]
8 | [assembly: AssemblyCompany(Vsix.Author)]
9 | [assembly: AssemblyProduct(Vsix.Name)]
10 | [assembly: AssemblyCopyright(Vsix.Author)]
11 | [assembly: AssemblyTrademark("")]
12 | [assembly: AssemblyCulture("")]
13 |
14 | [assembly: ComVisible(false)]
15 |
16 | [assembly: AssemblyVersion(Vsix.Version)]
17 | [assembly: AssemblyFileVersion(Vsix.Version)]
18 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Road map
2 |
3 | - [ ] Flash on save
4 |
5 | Features that have a checkmark are complete and available for
6 | download in the
7 | [CI build](http://vsixgallery.com/extension/376e6cdc-893d-4ae7-ad93-325575c35301/).
8 |
9 | # Change log
10 |
11 | These are the changes to each version that has been released
12 | on the official Visual Studio extension gallery.
13 |
14 | ## 1.2
15 |
16 | - [x] Only show in PrimaryDocument (not diff view etc.)
17 | - [x] Fixed null reference exception
18 |
19 | ## 1.1
20 |
21 | - [x] Option to hide errors, warnings and/or messages
22 |
23 | ## 1.0
24 |
25 | - [x] Initial release
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | image: Visual Studio 2017
2 |
3 | install:
4 | - ps: (new-object Net.WebClient).DownloadString("https://raw.github.com/madskristensen/ExtensionScripts/master/AppVeyor/vsix.ps1") | iex
5 |
6 | before_build:
7 | - ps: Vsix-IncrementVsixVersion | Vsix-UpdateBuildVersion
8 | - ps: Vsix-TokenReplacement src\source.extension.cs 'Version = "([0-9\\.]+)"' 'Version = "{version}"'
9 |
10 | build_script:
11 | - nuget restore -Verbosity quiet
12 | - msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m
13 |
14 | after_test:
15 | - ps: Vsix-PushArtifacts | Vsix-PublishToGallery
16 |
--------------------------------------------------------------------------------
/src/source.extension.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | //
3 | // This file was generated by Extensibility Tools v1.10.211
4 | //
5 | // ------------------------------------------------------------------------------
6 | namespace ErrorCatcher
7 | {
8 | static class Vsix
9 | {
10 | public const string Id = "376e6cdc-893d-4ae7-ad93-325575c35301";
11 | public const string Name = "Error Catcher II";
12 | public const string Description = @"The easiest way to make sure not to miss any errors or warnings in any code file.";
13 | public const string Language = "en-US";
14 | public const string Version = "1.2";
15 | public const string Author = "Mads Kristensen";
16 | public const string Tags = "error, exception";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Options.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Shell;
2 | using System;
3 | using System.ComponentModel;
4 |
5 | namespace ErrorCatcher
6 | {
7 | public class Options : DialogPage
8 | {
9 | [Category("General")]
10 | [DisplayName("Show Errors")]
11 | [DefaultValue(true)]
12 | public bool ShowErrors { get; set; } = true;
13 |
14 | [Category("General")]
15 | [DisplayName("Show Warnings")]
16 | [DefaultValue(true)]
17 | public bool ShowWarnings { get; set; } = true;
18 |
19 | [Category("General")]
20 | [DisplayName("Show Messages")]
21 | [DefaultValue(true)]
22 | public bool ShowMessages { get; set; } = true;
23 |
24 | public override void SaveSettingsToStorage()
25 | {
26 | base.SaveSettingsToStorage();
27 | Saved?.Invoke(this, EventArgs.Empty);
28 | }
29 |
30 | public static event EventHandler Saved;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ErrorCatcher.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26228.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ErrorCatcher", "src\ErrorCatcher.csproj", "{E94CFCD4-8B0F-4F6D-A3B1-20BD05ACDE30}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C584E629-8641-4576-9B49-760878C945EE}"
9 | ProjectSection(SolutionItems) = preProject
10 | appveyor.yml = appveyor.yml
11 | CHANGELOG.md = CHANGELOG.md
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {E94CFCD4-8B0F-4F6D-A3B1-20BD05ACDE30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {E94CFCD4-8B0F-4F6D-A3B1-20BD05ACDE30}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {E94CFCD4-8B0F-4F6D-A3B1-20BD05ACDE30}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {E94CFCD4-8B0F-4F6D-A3B1-20BD05ACDE30}.Release|Any CPU.Build.0 = Release|Any CPU
25 | EndGlobalSection
26 | GlobalSection(SolutionProperties) = preSolution
27 | HideSolutionNode = FALSE
28 | EndGlobalSection
29 | EndGlobal
30 |
--------------------------------------------------------------------------------
/src/ErrorCatcherPackage.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio;
2 | using Microsoft.VisualStudio.Shell;
3 | using Microsoft.VisualStudio.Shell.Interop;
4 | using System;
5 | using System.Runtime.InteropServices;
6 | using System.Threading;
7 | using Tasks = System.Threading.Tasks;
8 |
9 | namespace ErrorCatcher
10 | {
11 | [Guid("a6ea2ef8-a48a-4ebd-89d5-16b1ba16f5e3")]
12 | [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
13 | [InstalledProductRegistration("#110", "#112", Vsix.Version, IconResourceID = 400)]
14 | [ProvideAutoLoad(VSConstants.VsEditorFactoryGuid.TextEditor_string, PackageAutoLoadFlags.BackgroundLoad)] // Load when any document opens
15 | [ProvideOptionPage(typeof(Options), Vsix.Name, "General", 0, 0, true, new string[0])]
16 | public sealed class ErrorCatcherPackage : AsyncPackage
17 | {
18 | public static Options Options
19 | {
20 | get;
21 | private set;
22 | }
23 |
24 | protected override async Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress progress)
25 | {
26 | var errorList = await GetServiceAsync(typeof(SVsErrorList)) as IErrorList;
27 |
28 | await JoinableTaskFactory.SwitchToMainThreadAsync();
29 | Options = (Options)GetDialogPage(typeof(Options));
30 |
31 | ErrorProcessor.Initialize(errorList);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/source.extension.vsixmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Error Catcher II
6 | The easiest way to make sure not to miss any errors or warnings in any code file.
7 | https://github.com/madskristensen/ErrorCatcher
8 | Resources\LICENSE
9 | https://github.com/madskristensen/ErrorCatcher/blob/master/CHANGELOG.md
10 | Resources\Icon.png
11 | Resources\Icon.png
12 | error, exception
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/TextViewCreationListener.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Text;
2 | using Microsoft.VisualStudio.Text.Editor;
3 | using Microsoft.VisualStudio.Utilities;
4 | using System;
5 | using System.ComponentModel.Composition;
6 |
7 | namespace ErrorCatcher
8 | {
9 | [Export(typeof(IWpfTextViewCreationListener))]
10 | [ContentType("code")]
11 | [TextViewRole(PredefinedTextViewRoles.PrimaryDocument)]
12 | public class TextViewCreationListener : IWpfTextViewCreationListener
13 | {
14 | [Import]
15 | public ITextDocumentFactoryService DocumentService { get; set; }
16 |
17 | public void TextViewCreated(IWpfTextView textView)
18 | {
19 | if (!DocumentService.TryGetTextDocument(textView.TextBuffer, out var doc) || ErrorProcessor.Instance == null)
20 | return;
21 |
22 | textView.Properties.AddProperty("filePath", doc.FilePath);
23 | textView.Closed += TextView_Closed;
24 |
25 | var adornment = textView.Properties.GetOrCreateSingletonProperty(() => new Adornment(textView));
26 | ErrorProcessor.Instance.Register(doc.FilePath, (result) => adornment.Update(result));
27 | }
28 |
29 | private void TextView_Closed(object sender, EventArgs e)
30 | {
31 | var view = (IWpfTextView)sender;
32 |
33 | if (view == null)
34 | return;
35 |
36 | if (view.Properties.TryGetProperty(typeof(Adornment), out Adornment adornment))
37 | {
38 | adornment.Dispose();
39 | }
40 |
41 | if (view.Properties.TryGetProperty("filePath", out string filePath))
42 | {
43 | ErrorProcessor.Instance.Unregister(filePath);
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Error Catcher II
2 |
3 | [](https://ci.appveyor.com/project/madskristensen/errorcatcher)
4 |
5 | Download this extension from the [VS Marketplace](https://marketplace.visualstudio.com/items?itemName=MadsKristensen.ErrorCatcherII)
6 | or get the [CI build](http://vsixgallery.com/extension/376e6cdc-893d-4ae7-ad93-325575c35301/).
7 |
8 | ---------------------------------------
9 |
10 | The easiest way to make sure not to miss any errors or warnings in any code file.
11 |
12 | See the [change log](CHANGELOG.md) for changes and road map.
13 |
14 | ### Show errors
15 |
16 | Sometimes it can be hard to tell if the file you're editing
17 | contains errors. Perhaps the error is all the way to the bottom
18 | of the file and you don't notice it. You might save the file
19 | containing the error and something bad happens when you then
20 | try to run your application.
21 |
22 | 
23 |
24 | ### Customize
25 | You can decide if you wish to show errors, warnings and/or messages. Just right-click on the icons to enter edit mode. Then check the checkboxes for each of the error types you wish to see.
26 |
27 | 
28 |
29 | ### How it works
30 |
31 | 1. Displays errors at the top right corner of the editor
32 | 2. Displays both the number of errors, warnings and messages
33 | 3. Only shows errors that are currently visible in the Error List
34 | 4. Right-click icons to enter edit mode
35 | 5. Left-click icons to open Error List
36 |
37 | ## Contribute
38 | Check out the [contribution guidelines](.github/CONTRIBUTING.md)
39 | if you want to contribute to this project.
40 |
41 | For cloning and building this project yourself, make sure
42 | to install the
43 | [Extensibility Tools 2015](https://visualstudiogallery.msdn.microsoft.com/ab39a092-1343-46e2-b0f1-6a3f91155aa6)
44 | extension for Visual Studio which enables some features
45 | used by this project.
46 |
47 | ## License
48 | [Apache 2.0](LICENSE)
--------------------------------------------------------------------------------
/src/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/Adornment/Adornment.cs:
--------------------------------------------------------------------------------
1 | using EnvDTE;
2 | using EnvDTE80;
3 | using Microsoft.VisualStudio.Imaging;
4 | using Microsoft.VisualStudio.Shell;
5 | using Microsoft.VisualStudio.Shell.Interop;
6 | using Microsoft.VisualStudio.Text.Editor;
7 | using System;
8 | using System.Windows;
9 | using System.Windows.Controls;
10 | using System.Windows.Input;
11 | using System.Windows.Threading;
12 |
13 | namespace ErrorCatcher
14 | {
15 |
16 | class Adornment : StackPanel, IDisposable
17 | {
18 | private ITextView _view;
19 | private ItemControl _error, _warning, _info;
20 | private static DTE2 _dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE2;
21 |
22 | public Adornment(IWpfTextView view)
23 | {
24 | _view = view;
25 |
26 | Visibility = Visibility.Hidden;
27 | Orientation = Orientation.Vertical;
28 | Opacity = 0.6;
29 | Cursor = Cursors.Hand;
30 |
31 | IAdornmentLayer adornmentLayer = view.GetAdornmentLayer(AdornmentLayer.LayerName);
32 |
33 | if (adornmentLayer.IsEmpty)
34 | adornmentLayer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative, null, null, this, null);
35 | }
36 |
37 | protected override void OnInitialized(EventArgs e)
38 | {
39 | _error = new ItemControl(KnownMonikers.StatusError, __VSERRORCATEGORY.EC_ERROR);
40 | _warning = new ItemControl(KnownMonikers.StatusWarning, __VSERRORCATEGORY.EC_WARNING);
41 | _info = new ItemControl(KnownMonikers.StatusInformation, __VSERRORCATEGORY.EC_MESSAGE);
42 |
43 | Children.Add(_error);
44 | Children.Add(_warning);
45 | Children.Add(_info);
46 |
47 | MouseLeftButtonUp += (snd, evt) => { _dte.ExecuteCommand("View.ErrorList"); evt.Handled = true; };
48 | MouseRightButtonUp += (snd, evt) => { EnterEditMode(true); evt.Handled = true; };
49 | MouseLeave += (snd, evt) => { EnterEditMode(false); };
50 |
51 | Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() =>
52 | {
53 | SetAdornmentLocation(_view, EventArgs.Empty);
54 |
55 | _view.ViewportHeightChanged += SetAdornmentLocation;
56 | _view.ViewportWidthChanged += SetAdornmentLocation;
57 | }));
58 | }
59 |
60 | private void EnterEditMode(bool editable)
61 | {
62 | _error.EditMode(editable);
63 | _warning.EditMode(editable);
64 | _info.EditMode(editable);
65 | }
66 |
67 | public void Update(ErrorResult result)
68 | {
69 | if (_error == null)
70 | return;
71 |
72 | ThreadHelper.Generic.BeginInvoke(() =>
73 | {
74 | _error.Update(result.Errors);
75 | _warning.Update(result.Warnings);
76 | _info.Update(result.Info);
77 | });
78 | }
79 |
80 | private void SetAdornmentLocation(object sender, EventArgs e)
81 | {
82 | var view = (IWpfTextView)sender;
83 | Canvas.SetLeft(this, view.ViewportRight - 65);
84 | Canvas.SetTop(this, _view.ViewportTop + 10);
85 | Visibility = Visibility.Visible;
86 | }
87 |
88 | public void Dispose()
89 | {
90 | if (_view != null)
91 | {
92 | _view.ViewportHeightChanged -= SetAdornmentLocation;
93 | _view.ViewportWidthChanged -= SetAdornmentLocation;
94 | }
95 |
96 | _error.Dispose();
97 | _warning.Dispose();
98 | _info.Dispose();
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/ErrorList/ErrorProcessor.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Shell;
2 | using Microsoft.VisualStudio.Shell.Interop;
3 | using Microsoft.VisualStudio.Shell.TableControl;
4 | using Microsoft.VisualStudio.Shell.TableManager;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using Tasks = System.Threading.Tasks;
9 |
10 | namespace ErrorCatcher
11 | {
12 | public class ErrorProcessor
13 | {
14 | private static Dictionary> _dic = new Dictionary>();
15 | private IWpfTableControl _table;
16 |
17 | private ErrorProcessor(IErrorList errorList)
18 | {
19 | _table = errorList.TableControl;
20 | errorList.TableControl.EntriesChanged += EntriesChanged;
21 | }
22 |
23 | public static ErrorProcessor Instance
24 | {
25 | get;
26 | private set;
27 | }
28 |
29 | public static void Initialize(IErrorList errorList)
30 | {
31 | Instance = new ErrorProcessor(errorList);
32 | }
33 |
34 | public void Register(string fileName, Action action)
35 | {
36 | _dic[fileName] = action;
37 | var entries = _table.Entries.ToArray();
38 |
39 | Tasks.Task.Run(() =>
40 | {
41 | Update(entries);
42 | });
43 | }
44 |
45 | public void Unregister(string fileName)
46 | {
47 | if (_dic.ContainsKey(fileName))
48 | _dic.Remove(fileName);
49 | }
50 |
51 | private void EntriesChanged(object sender, EventArgs e)
52 | {
53 | var entries = _table.Entries.ToArray();
54 |
55 | Tasks.Task.Run(() =>
56 | {
57 | Update(entries);
58 | });
59 | }
60 |
61 | private void Update(ITableEntryHandle[] entries)
62 | {
63 | var errors = GetErrors(entries);
64 |
65 | foreach (string file in _dic.Keys)
66 | {
67 | var error = errors.FirstOrDefault(e => e.FileName == file) ?? new ErrorResult(file);
68 | _dic[file].Invoke(error);
69 | }
70 | }
71 |
72 | private IEnumerable GetErrors(ITableEntryHandle[] entries)
73 | {
74 | var list = new Dictionary();
75 |
76 | try
77 | {
78 | foreach (var entry in entries)
79 | {
80 | if (!entry.TryGetValue(StandardTableKeyNames.DocumentName, out string fileName) || !_dic.ContainsKey(fileName))
81 | break;
82 |
83 | if (!entry.TryGetValue(StandardTableKeyNames.ErrorSeverity, out __VSERRORCATEGORY severity))
84 | severity = __VSERRORCATEGORY.EC_MESSAGE;
85 |
86 | if (!list.ContainsKey(fileName))
87 | list.Add(fileName, new ErrorResult(fileName));
88 |
89 | switch (severity)
90 | {
91 | case __VSERRORCATEGORY.EC_ERROR:
92 | list[fileName].Errors += 1;
93 | break;
94 | case __VSERRORCATEGORY.EC_WARNING:
95 | list[fileName].Warnings += 1;
96 | break;
97 | default:
98 | list[fileName].Info += 1;
99 | break;
100 | }
101 | }
102 |
103 | return list.Values;
104 | }
105 | catch (Exception ex)
106 | {
107 | System.Diagnostics.Debug.Write(ex);
108 | return null;
109 | }
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/Adornment/ItemControl.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Imaging.Interop;
2 | using Microsoft.VisualStudio.PlatformUI;
3 | using Microsoft.VisualStudio.Shell;
4 | using Microsoft.VisualStudio.Shell.Interop;
5 | using System;
6 | using System.Runtime.InteropServices;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Imaging;
11 |
12 | namespace ErrorCatcher
13 | {
14 | public class ItemControl : StackPanel, IDisposable
15 | {
16 | private TextBlock _text;
17 | private CheckBox _checkbox;
18 | public ImageMoniker _icon;
19 | private __VSERRORCATEGORY _category;
20 | private bool _isInEditMode;
21 |
22 | public ItemControl(ImageMoniker icon, __VSERRORCATEGORY category)
23 | {
24 | _icon = icon;
25 | _category = category;
26 |
27 | Orientation = Orientation.Horizontal;
28 | VerticalAlignment = VerticalAlignment.Center;
29 | Visibility = Visibility.Collapsed;
30 |
31 | Options.Saved += OptionsSaved;
32 | }
33 |
34 | private void OptionsSaved(object sender, EventArgs e)
35 | {
36 | if (!_isInEditMode)
37 | {
38 | bool isChecked = IsChecked();
39 | _checkbox.IsChecked = isChecked;
40 | Visibility = isChecked && _text.Text != "0" ? Visibility.Visible : Visibility.Collapsed;
41 | }
42 | }
43 |
44 | protected override void OnInitialized(EventArgs e)
45 | {
46 | _checkbox = new CheckBox();
47 | _checkbox.IsChecked = IsChecked();
48 | _checkbox.Visibility = Visibility.Hidden;
49 | _checkbox.Padding = new Thickness(0, 0, 4, 0);
50 | _checkbox.Checked += CheckedChanged;
51 | _checkbox.Unchecked += CheckedChanged;
52 | Children.Add(_checkbox);
53 |
54 | var img = new Image();
55 | img.Source = ToBitmap(_icon, 14);
56 | img.SetValue(RenderOptions.BitmapScalingModeProperty, BitmapScalingMode.HighQuality);
57 |
58 | var border = new Border();
59 | border.BorderBrush = Brushes.Transparent;
60 | border.BorderThickness = new Thickness(1);
61 | border.Child = img;
62 | Children.Add(border);
63 |
64 | _text = new TextBlock();
65 | _text.Width = 30;
66 | _text.Padding = new Thickness(4, 0, 0, 0);
67 | _text.SetResourceReference(Control.ForegroundProperty, VsBrushes.CaptionTextKey);
68 | _text.SetValue(TextOptions.TextRenderingModeProperty, TextRenderingMode.Aliased);
69 | _text.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Ideal);
70 | Children.Add(_text);
71 | }
72 |
73 | public void Update(int count)
74 | {
75 | if (_text != null)
76 | {
77 | _text.Text = count.ToString();
78 | Visibility = count == 0 ? Visibility.Collapsed : Visibility.Visible;
79 | }
80 | }
81 |
82 | public void EditMode(bool editable)
83 | {
84 | _isInEditMode = editable;
85 | _checkbox.Visibility = editable ? Visibility.Visible : Visibility.Hidden;
86 |
87 | if (editable)
88 | {
89 | Visibility = Visibility.Visible;
90 |
91 | }
92 | else if (!IsChecked() || _text.Text == "0")
93 | {
94 | Visibility = Visibility.Collapsed;
95 | }
96 | }
97 |
98 | private void CheckedChanged(object sender, RoutedEventArgs e)
99 | {
100 | var isChecked = _checkbox.IsChecked.HasValue && _checkbox.IsChecked.Value;
101 |
102 | switch (_category)
103 | {
104 | case __VSERRORCATEGORY.EC_ERROR:
105 | ErrorCatcherPackage.Options.ShowErrors = isChecked;
106 | break;
107 | case __VSERRORCATEGORY.EC_WARNING:
108 | ErrorCatcherPackage.Options.ShowWarnings = isChecked;
109 | break;
110 | case __VSERRORCATEGORY.EC_MESSAGE:
111 | ErrorCatcherPackage.Options.ShowMessages = isChecked;
112 | break;
113 | }
114 |
115 | ErrorCatcherPackage.Options.SaveSettingsToStorage();
116 | }
117 |
118 | private bool IsChecked()
119 | {
120 | switch (_category)
121 | {
122 | case __VSERRORCATEGORY.EC_ERROR:
123 | return ErrorCatcherPackage.Options.ShowErrors;
124 | case __VSERRORCATEGORY.EC_WARNING:
125 | return ErrorCatcherPackage.Options.ShowWarnings;
126 | case __VSERRORCATEGORY.EC_MESSAGE:
127 | return ErrorCatcherPackage.Options.ShowMessages;
128 | }
129 |
130 | return false;
131 | }
132 |
133 | private static BitmapSource ToBitmap(ImageMoniker moniker, int size)
134 | {
135 | var shell = ServiceProvider.GlobalProvider.GetService(typeof(SVsUIShell)) as IVsUIShell5;
136 | uint backgroundColor = VsColors.GetThemedColorRgba(shell, EnvironmentColors.BrandedUIBackgroundBrushKey);
137 |
138 | var imageAttributes = new ImageAttributes
139 | {
140 | Flags = (uint)_ImageAttributesFlags.IAF_RequiredFlags | unchecked((uint)_ImageAttributesFlags.IAF_Background),
141 | ImageType = (uint)_UIImageType.IT_Bitmap,
142 | Format = (uint)_UIDataFormat.DF_WPF,
143 | Dpi = 96,
144 | LogicalHeight = size,
145 | LogicalWidth = size,
146 | Background = backgroundColor,
147 | StructSize = Marshal.SizeOf(typeof(ImageAttributes))
148 | };
149 |
150 | var service = (IVsImageService2)Package.GetGlobalService(typeof(SVsImageService));
151 | IVsUIObject result = service.GetImage(moniker, imageAttributes);
152 | result.get_Data(out object data);
153 |
154 | return data as BitmapSource;
155 | }
156 |
157 | public void Dispose()
158 | {
159 | Options.Saved -= OptionsSaved;
160 | if (_checkbox != null)
161 | {
162 | _checkbox.Checked -= CheckedChanged;
163 | _checkbox.Unchecked -= CheckedChanged;
164 | }
165 |
166 | _checkbox = null;
167 | _text = null;
168 |
169 | }
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Looking to contribute something? **Here's how you can help.**
4 |
5 | Please take a moment to review this document in order to make the contribution
6 | process easy and effective for everyone involved.
7 |
8 | Following these guidelines helps to communicate that you respect the time of
9 | the developers managing and developing this open source project. In return,
10 | they should reciprocate that respect in addressing your issue or assessing
11 | patches and features.
12 |
13 |
14 | ## Using the issue tracker
15 |
16 | The issue tracker is the preferred channel for [bug reports](#bug-reports),
17 | [features requests](#feature-requests) and
18 | [submitting pull requests](#pull-requests), but please respect the
19 | following restrictions:
20 |
21 | * Please **do not** use the issue tracker for personal support requests. Stack
22 | Overflow is a better place to get help.
23 |
24 | * Please **do not** derail or troll issues. Keep the discussion on topic and
25 | respect the opinions of others.
26 |
27 | * Please **do not** open issues or pull requests which *belongs to* third party
28 | components.
29 |
30 |
31 | ## Bug reports
32 |
33 | A bug is a _demonstrable problem_ that is caused by the code in the repository.
34 | Good bug reports are extremely helpful, so thanks!
35 |
36 | Guidelines for bug reports:
37 |
38 | 1. **Use the GitHub issue search** — check if the issue has already been
39 | reported.
40 |
41 | 2. **Check if the issue has been fixed** — try to reproduce it using the
42 | latest `master` or development branch in the repository.
43 |
44 | 3. **Isolate the problem** — ideally create an
45 | [SSCCE](http://www.sscce.org/) and a live example.
46 | Uploading the project on cloud storage (OneDrive, DropBox, et el.)
47 | or creating a sample GitHub repository is also helpful.
48 |
49 |
50 | A good bug report shouldn't leave others needing to chase you up for more
51 | information. Please try to be as detailed as possible in your report. What is
52 | your environment? What steps will reproduce the issue? What browser(s) and OS
53 | experience the problem? Do other browsers show the bug differently? What
54 | would you expect to be the outcome? All these details will help people to fix
55 | any potential bugs.
56 |
57 | Example:
58 |
59 | > Short and descriptive example bug report title
60 | >
61 | > A summary of the issue and the Visual Studio, browser, OS environments
62 | > in which it occurs. If suitable, include the steps required to reproduce the bug.
63 | >
64 | > 1. This is the first step
65 | > 2. This is the second step
66 | > 3. Further steps, etc.
67 | >
68 | > `` - a link to the project/file uploaded on cloud storage or other publicly accessible medium.
69 | >
70 | > Any other information you want to share that is relevant to the issue being
71 | > reported. This might include the lines of code that you have identified as
72 | > causing the bug, and potential solutions (and your opinions on their
73 | > merits).
74 |
75 |
76 | ## Feature requests
77 |
78 | Feature requests are welcome. But take a moment to find out whether your idea
79 | fits with the scope and aims of the project. It's up to *you* to make a strong
80 | case to convince the project's developers of the merits of this feature. Please
81 | provide as much detail and context as possible.
82 |
83 |
84 | ## Pull requests
85 |
86 | Good pull requests, patches, improvements and new features are a fantastic
87 | help. They should remain focused in scope and avoid containing unrelated
88 | commits.
89 |
90 | **Please ask first** before embarking on any significant pull request (e.g.
91 | implementing features, refactoring code, porting to a different language),
92 | otherwise you risk spending a lot of time working on something that the
93 | project's developers might not want to merge into the project.
94 |
95 | Please adhere to the [coding guidelines](#code-guidelines) used throughout the
96 | project (indentation, accurate comments, etc.) and any other requirements
97 | (such as test coverage).
98 |
99 | Adhering to the following process is the best way to get your work
100 | included in the project:
101 |
102 | 1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork,
103 | and configure the remotes:
104 |
105 | ```bash
106 | # Clone your fork of the repo into the current directory
107 | git clone https://github.com//.git
108 | # Navigate to the newly cloned directory
109 | cd
110 | # Assign the original repo to a remote called "upstream"
111 | git remote add upstream https://github.com/madskristensen/.git
112 | ```
113 |
114 | 2. If you cloned a while ago, get the latest changes from upstream:
115 |
116 | ```bash
117 | git checkout master
118 | git pull upstream master
119 | ```
120 |
121 | 3. Create a new topic branch (off the main project development branch) to
122 | contain your feature, change, or fix:
123 |
124 | ```bash
125 | git checkout -b
126 | ```
127 |
128 | 4. Commit your changes in logical chunks. Please adhere to these [git commit
129 | message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
130 | or your code is unlikely be merged into the main project. Use Git's
131 | [interactive rebase](https://help.github.com/articles/interactive-rebase)
132 | feature to tidy up your commits before making them public. Also, prepend name of the feature
133 | to the commit message. For instance: "SCSS: Fixes compiler results for IFileListener.\nFixes `#123`"
134 |
135 | 5. Locally merge (or rebase) the upstream development branch into your topic branch:
136 |
137 | ```bash
138 | git pull [--rebase] upstream master
139 | ```
140 |
141 | 6. Push your topic branch up to your fork:
142 |
143 | ```bash
144 | git push origin
145 | ```
146 |
147 | 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)
148 | with a clear title and description against the `master` branch.
149 |
150 |
151 | ## Code guidelines
152 |
153 | - Always use proper indentation.
154 | - In Visual Studio under `Tools > Options > Text Editor > C# > Advanced`, make sure
155 | `Place 'System' directives first when sorting usings` option is enabled (checked).
156 | - Before committing, organize usings for each updated C# source file. Either you can
157 | right-click editor and select `Organize Usings > Remove and sort` OR use extension
158 | like [BatchFormat](http://visualstudiogallery.msdn.microsoft.com/a7f75c34-82b4-4357-9c66-c18e32b9393e).
159 | - Before committing, run Code Analysis in `Debug` configuration and follow the guidelines
160 | to fix CA issues. Code Analysis commits can be made separately.
161 |
--------------------------------------------------------------------------------
/src/source.extension.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Error Catcher II
122 |
123 |
124 | The easiest way to make sure not to miss any errors or warnings in any code file.
125 |
126 |
127 |
128 | source.extension.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
--------------------------------------------------------------------------------
/src/ErrorCatcher.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(VisualStudioVersion)
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 | true
9 | Program
10 | $(DevEnvDir)\devenv.exe
11 | /rootsuffix Exp
12 |
13 |
14 |
15 | Debug
16 | AnyCPU
17 | 2.0
18 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 | {E94CFCD4-8B0F-4F6D-A3B1-20BD05ACDE30}
20 | Library
21 | Properties
22 | ErrorCatcher
23 | ErrorCatcher
24 | v4.5.2
25 | true
26 | true
27 | true
28 | true
29 | true
30 | false
31 |
32 |
33 | true
34 | full
35 | false
36 | bin\Debug\
37 | DEBUG;TRACE
38 | prompt
39 | 4
40 |
41 |
42 | pdbonly
43 | true
44 | bin\Release\
45 | TRACE
46 | prompt
47 | 4
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Component
58 |
59 |
60 |
61 | source.extension.vsixmanifest
62 |
63 |
64 |
65 |
66 |
67 | Resources\LICENSE
68 | true
69 |
70 |
71 |
72 | Designer
73 | VsixManifestGenerator
74 | source.extension.resx
75 |
76 |
77 |
78 |
79 | False
80 | False
81 |
82 |
83 | False
84 | False
85 |
86 |
87 | False
88 | False
89 |
90 |
91 | False
92 | False
93 |
94 |
95 |
96 |
97 | False
98 | False
99 |
100 |
101 | ..\packages\Microsoft.VisualStudio.CoreUtility.14.3.25407\lib\net45\Microsoft.VisualStudio.CoreUtility.dll
102 | False
103 |
104 |
105 | ..\packages\Microsoft.VisualStudio.Editor.14.3.25407\lib\net45\Microsoft.VisualStudio.Editor.dll
106 | False
107 |
108 |
109 | ..\packages\Microsoft.VisualStudio.ImageCatalog.14.3.25407\lib\net45\Microsoft.VisualStudio.ImageCatalog.dll
110 | False
111 |
112 |
113 | ..\packages\Microsoft.VisualStudio.Imaging.14.3.25407\lib\net45\Microsoft.VisualStudio.Imaging.dll
114 | False
115 |
116 |
117 | True
118 | ..\packages\Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.14.3.25407\lib\Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll
119 | True
120 |
121 |
122 | ..\packages\Microsoft.VisualStudio.OLE.Interop.7.10.6070\lib\Microsoft.VisualStudio.OLE.Interop.dll
123 | False
124 |
125 |
126 | ..\packages\Microsoft.VisualStudio.Shell.14.0.14.3.25407\lib\Microsoft.VisualStudio.Shell.14.0.dll
127 | False
128 |
129 |
130 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.10.0.10.0.30319\lib\net40\Microsoft.VisualStudio.Shell.Immutable.10.0.dll
131 | False
132 |
133 |
134 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.11.0.11.0.50727\lib\net45\Microsoft.VisualStudio.Shell.Immutable.11.0.dll
135 | False
136 |
137 |
138 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.12.0.12.0.21003\lib\net45\Microsoft.VisualStudio.Shell.Immutable.12.0.dll
139 | False
140 |
141 |
142 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.14.0.14.3.25407\lib\net45\Microsoft.VisualStudio.Shell.Immutable.14.0.dll
143 | False
144 |
145 |
146 | ..\packages\Microsoft.VisualStudio.Shell.Interop.7.10.6071\lib\Microsoft.VisualStudio.Shell.Interop.dll
147 | False
148 |
149 |
150 | True
151 | ..\packages\Microsoft.VisualStudio.Shell.Interop.10.0.10.0.30319\lib\Microsoft.VisualStudio.Shell.Interop.10.0.dll
152 | True
153 |
154 |
155 | True
156 | ..\packages\Microsoft.VisualStudio.Shell.Interop.11.0.11.0.61030\lib\Microsoft.VisualStudio.Shell.Interop.11.0.dll
157 | True
158 |
159 |
160 | True
161 | ..\packages\Microsoft.VisualStudio.Shell.Interop.12.0.12.0.30110\lib\Microsoft.VisualStudio.Shell.Interop.12.0.dll
162 | True
163 |
164 |
165 | True
166 | ..\packages\Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime.14.3.25407\lib\Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime.dll
167 | True
168 |
169 |
170 | ..\packages\Microsoft.VisualStudio.Shell.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.Shell.Interop.8.0.dll
171 | False
172 |
173 |
174 | ..\packages\Microsoft.VisualStudio.Shell.Interop.9.0.9.0.30729\lib\Microsoft.VisualStudio.Shell.Interop.9.0.dll
175 | False
176 |
177 |
178 | ..\packages\Microsoft.VisualStudio.Text.Data.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.Data.dll
179 | False
180 |
181 |
182 | ..\packages\Microsoft.VisualStudio.Text.Logic.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.Logic.dll
183 | False
184 |
185 |
186 | ..\packages\Microsoft.VisualStudio.Text.UI.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.UI.dll
187 | False
188 |
189 |
190 | ..\packages\Microsoft.VisualStudio.Text.UI.Wpf.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.UI.Wpf.dll
191 | False
192 |
193 |
194 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.7.10.6070\lib\Microsoft.VisualStudio.TextManager.Interop.dll
195 | False
196 |
197 |
198 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.TextManager.Interop.8.0.dll
199 | False
200 |
201 |
202 | ..\packages\Microsoft.VisualStudio.Threading.14.1.111\lib\net45\Microsoft.VisualStudio.Threading.dll
203 | False
204 |
205 |
206 | ..\packages\Microsoft.VisualStudio.Utilities.14.3.25407\lib\net45\Microsoft.VisualStudio.Utilities.dll
207 | False
208 |
209 |
210 | ..\packages\Microsoft.VisualStudio.Validation.14.1.111\lib\net45\Microsoft.VisualStudio.Validation.dll
211 | False
212 |
213 |
214 |
215 |
216 | False
217 | False
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 | true
227 |
228 |
229 | source.extension.vsixmanifest
230 |
231 |
232 |
233 |
234 | True
235 | True
236 | source.extension.vsixmanifest
237 | true
238 | VSPackage
239 |
240 |
241 |
242 |
243 |
244 |
251 |
--------------------------------------------------------------------------------