├── .gitattributes ├── .gitignore ├── ProjectionBufferTutorial.sln ├── ProjectionBufferTutorial ├── Key.snk ├── ProjBufferToolWindow.cs ├── ProjBufferToolWindowCommand.cs ├── ProjBufferToolWindowControl.xaml ├── ProjBufferToolWindowControl.xaml.cs ├── ProjBufferToolWindowPackage.cs ├── ProjBufferToolWindowPackage.vsct ├── ProjectionBufferTutorial.csproj ├── Properties │ └── AssemblyInfo.cs ├── Resources │ ├── ProjBufferToolWindowCommand.png │ └── ProjBufferToolWindowPackage.ico ├── VSPackage.resx ├── VisualStudioServices.cs ├── packages.config └── source.extension.vsixmanifest └── README.md /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | *.ide 19 | /packages 20 | 21 | # External tool builders 22 | .externalToolBuilders/ 23 | 24 | # Locally stored "Eclipse launch configurations" 25 | *.launch 26 | 27 | # CDT-specific 28 | .cproject 29 | 30 | # PDT-specific 31 | .buildpath 32 | 33 | 34 | ################# 35 | ## Visual Studio 36 | ################# 37 | 38 | ## Ignore Visual Studio temporary files, build results, and 39 | ## files generated by popular Visual Studio add-ons. 40 | 41 | # User-specific files 42 | *.suo 43 | *.user 44 | *.sln.docstates 45 | 46 | # Build results 47 | 48 | [Dd]ebug/ 49 | [Rr]elease/ 50 | x64/ 51 | build/ 52 | [Bb]in/ 53 | [Oo]bj/ 54 | 55 | # MSTest test Results 56 | [Tt]est[Rr]esult*/ 57 | [Bb]uild[Ll]og.* 58 | 59 | *_i.c 60 | *_p.c 61 | *.ilk 62 | *.meta 63 | *.obj 64 | *.pch 65 | *.pdb 66 | *.pgc 67 | *.pgd 68 | *.rsp 69 | *.sbr 70 | *.tlb 71 | *.tli 72 | *.tlh 73 | *.tmp 74 | *.tmp_proj 75 | *.log 76 | *.vspscc 77 | *.vssscc 78 | .builds 79 | *.pidb 80 | *.log 81 | *.scc 82 | 83 | # Visual C++ cache files 84 | ipch/ 85 | *.aps 86 | *.ncb 87 | *.opensdf 88 | *.sdf 89 | *.cachefile 90 | 91 | # Visual Studio profiler 92 | *.psess 93 | *.vsp 94 | *.vspx 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | 103 | # TeamCity is a build add-in 104 | _TeamCity* 105 | 106 | # DotCover is a Code Coverage Tool 107 | *.dotCover 108 | 109 | # NCrunch 110 | *.ncrunch* 111 | .*crunch*.local.xml 112 | 113 | # Installshield output folder 114 | [Ee]xpress/ 115 | 116 | # DocProject is a documentation generator add-in 117 | DocProject/buildhelp/ 118 | DocProject/Help/*.HxT 119 | DocProject/Help/*.HxC 120 | DocProject/Help/*.hhc 121 | DocProject/Help/*.hhk 122 | DocProject/Help/*.hhp 123 | DocProject/Help/Html2 124 | DocProject/Help/html 125 | 126 | # Click-Once directory 127 | publish/ 128 | 129 | # Publish Web Output 130 | *.Publish.xml 131 | *.pubxml 132 | 133 | # NuGet Packages Directory 134 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 135 | #packages/ 136 | 137 | # Windows Azure Build Output 138 | csx 139 | *.build.csdef 140 | 141 | # Windows Store app package directory 142 | AppPackages/ 143 | 144 | # Others 145 | sql/ 146 | *.Cache 147 | ClientBin/ 148 | [Ss]tyle[Cc]op.* 149 | ~$* 150 | *~ 151 | *.dbmdl 152 | *.[Pp]ublish.xml 153 | *.pfx 154 | *.publishsettings 155 | 156 | # RIA/Silverlight projects 157 | Generated_Code/ 158 | 159 | # Backup & report files from converting an old project file to a newer 160 | # Visual Studio version. Backup files are not needed, because we have git ;-) 161 | _UpgradeReport_Files/ 162 | Backup*/ 163 | UpgradeLog*.XML 164 | UpgradeLog*.htm 165 | 166 | # SQL Server files 167 | App_Data/*.mdf 168 | App_Data/*.ldf 169 | 170 | # Probably Roslyn related 171 | ProjectKiwi.sln.ide/ 172 | 173 | ############# 174 | ## Windows detritus 175 | ############# 176 | 177 | # Windows image file caches 178 | Thumbs.db 179 | ehthumbs.db 180 | 181 | # Folder config file 182 | Desktop.ini 183 | 184 | # Recycle Bin used on file shares 185 | $RECYCLE.BIN/ 186 | 187 | # Mac crap 188 | .DS_Store 189 | 190 | 191 | ############# 192 | ## Python 193 | ############# 194 | 195 | *.py[co] 196 | 197 | # Packages 198 | *.egg 199 | *.egg-info 200 | dist/ 201 | build/ 202 | eggs/ 203 | parts/ 204 | var/ 205 | sdist/ 206 | develop-eggs/ 207 | .installed.cfg 208 | 209 | # Installer logs 210 | pip-log.txt 211 | 212 | # Unit test / coverage reports 213 | .coverage 214 | .tox 215 | 216 | #Translations 217 | *.mo 218 | 219 | #Mr Developer 220 | .mr.developer.cfg 221 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26403.7 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectionBufferTutorial", "ProjectionBufferTutorial\ProjectionBufferTutorial.csproj", "{BC132864-3437-4379-B7EE-4F02FA68D3F7}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BC132864-3437-4379-B7EE-4F02FA68D3F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {BC132864-3437-4379-B7EE-4F02FA68D3F7}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {BC132864-3437-4379-B7EE-4F02FA68D3F7}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {BC132864-3437-4379-B7EE-4F02FA68D3F7}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/Key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/ProjectionBufferTutorial/39364fbf5177b330382eb4728cb5649c07a04632/ProjectionBufferTutorial/Key.snk -------------------------------------------------------------------------------- /ProjectionBufferTutorial/ProjBufferToolWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections; 4 | using System.ComponentModel; 5 | using System.Drawing; 6 | using System.Data; 7 | using System.Windows; 8 | using System.Runtime.InteropServices; 9 | using Microsoft.VisualStudio.Shell.Interop; 10 | using Microsoft.VisualStudio.Shell; 11 | using Microsoft.VisualStudio.OLE.Interop; 12 | using Microsoft.VisualStudio; 13 | using Microsoft.VisualStudio.TextManager.Interop; 14 | using Microsoft.VisualStudio.Editor; 15 | using Microsoft.VisualStudio.Text.Editor; 16 | using Microsoft.VisualStudio.ComponentModelHost; 17 | using System.Windows.Forms; 18 | 19 | namespace ProjectionBufferTutorial 20 | { 21 | [Guid("e12a35c8-4a60-400a-af8e-5a1e4ed6cf50")] 22 | public class ProjBufferToolWindow : ToolWindowPane, IOleCommandTarget 23 | { 24 | //CHANGE ME TO A FILE THAT YOU HAVE OPENED IN VISUAL STUDIO WHEN LAUNCHING THE TOOL WINDOW 25 | //CHANGE ME TO A FILE THAT YOU HAVE OPENED IN VISUAL STUDIO WHEN LAUNCHING THE TOOL WINDOW 26 | private string filePath = @"C:\Users\Josh\Documents\Visual Studio 2013\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs"; 27 | //CHANGE ME TO A FILE THAT YOU HAVE OPENED IN VISUAL STUDIO WHEN LAUNCHING THE TOOL WINDOW 28 | //CHANGE ME TO A FILE THAT YOU HAVE OPENED IN VISUAL STUDIO WHEN LAUNCHING THE TOOL WINDOW 29 | 30 | IComponentModel _componentModel; 31 | IVsInvisibleEditorManager _invisibleEditorManager; 32 | //This adapter allows us to convert between Visual Studio 2010 editor components and 33 | //the legacy components from Visual Studio 2008 and earlier. 34 | IVsEditorAdaptersFactoryService _editorAdapter; 35 | ITextEditorFactoryService _editorFactoryService; 36 | IVsTextView _currentlyFocusedTextView; 37 | 38 | public ProjBufferToolWindow() : base(null) 39 | { 40 | this.Caption = "ProjBufferToolWindow"; 41 | 42 | this.BitmapResourceID = 301; 43 | this.BitmapIndex = 1; 44 | 45 | _componentModel = (IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)); 46 | _invisibleEditorManager = (IVsInvisibleEditorManager)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsInvisibleEditorManager)); 47 | _editorAdapter = _componentModel.GetService(); 48 | _editorFactoryService = _componentModel.GetService(); 49 | } 50 | 51 | /// 52 | /// Creates an invisible editor for a given filePath. 53 | /// If you're frequently creating projection buffers, it may be worth caching 54 | /// these editors as they're somewhat expensive to create. 55 | /// 56 | private IVsInvisibleEditor GetInvisibleEditor(string filePath) 57 | { 58 | IVsInvisibleEditor invisibleEditor; 59 | ErrorHandler.ThrowOnFailure(this._invisibleEditorManager.RegisterInvisibleEditor( 60 | filePath 61 | , pProject: null 62 | , dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING 63 | , pFactory: null 64 | , ppEditor: out invisibleEditor)); 65 | RegisterDocument(filePath); 66 | return invisibleEditor; 67 | } 68 | 69 | uint RegisterDocument(string targetFile) 70 | { 71 | //Then when creating the IVsInvisibleEditor, find and lock the document 72 | uint itemID; 73 | IntPtr docData; 74 | uint docCookie; 75 | IVsHierarchy hierarchy; 76 | var runningDocTable = (IVsRunningDocumentTable)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsRunningDocumentTable)); 77 | 78 | ErrorHandler.ThrowOnFailure(runningDocTable.FindAndLockDocument( 79 | dwRDTLockType: (uint) _VSRDTFLAGS.RDT_EditLock, 80 | pszMkDocument: targetFile, 81 | ppHier: out hierarchy, 82 | pitemid: out itemID, 83 | ppunkDocData: out docData, 84 | pdwCookie: out docCookie)); 85 | 86 | return docCookie; 87 | } 88 | 89 | public IWpfTextViewHost CreateEditor(string filePath, int start = 0, int end = 0, bool createProjectedEditor = false) 90 | { 91 | //IVsInvisibleEditors are in-memory represenations of typical Visual Studio editors. 92 | //Language services, highlighting and error squiggles are hooked up to these editors 93 | //for us once we convert them to WpfTextViews. 94 | var invisibleEditor = GetInvisibleEditor(filePath); 95 | 96 | var docDataPointer = IntPtr.Zero; 97 | Guid guidIVsTextLines = typeof(IVsTextLines).GUID; 98 | 99 | ErrorHandler.ThrowOnFailure(invisibleEditor.GetDocData( 100 | fEnsureWritable: 1 101 | , riid: ref guidIVsTextLines 102 | , ppDocData: out docDataPointer)); 103 | 104 | IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer); 105 | 106 | // This will actually be defined as _codewindowbehaviorflags2.CWB_DISABLEDIFF once the latest version of 107 | // Microsoft.VisualStudio.TextManager.Interop.16.0.DesignTime is published. Setting the flag will have no effect 108 | // on releases prior to d16.0. 109 | const _codewindowbehaviorflags CWB_DISABLEDIFF = (_codewindowbehaviorflags)0x04; 110 | 111 | //Create a code window adapter 112 | var codeWindow = _editorAdapter.CreateVsCodeWindowAdapter(VisualStudioServices.OLEServiceProvider); 113 | 114 | // You need to disable the dropdown, splitter and -- for d16.0 -- diff since you are extracting the code window's TextViewHost and using it. 115 | ((IVsCodeWindowEx)codeWindow).Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER | (uint)_codewindowbehaviorflags.CWB_DISABLEDROPDOWNBAR | (uint)CWB_DISABLEDIFF, 116 | VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter, 117 | string.Empty, 118 | string.Empty, 119 | 0, 120 | new INITVIEW[1]); 121 | 122 | ErrorHandler.ThrowOnFailure(codeWindow.SetBuffer(docData)); 123 | 124 | //Get a text view for our editor which we will then use to get the WPF control for that editor. 125 | IVsTextView textView; 126 | ErrorHandler.ThrowOnFailure(codeWindow.GetPrimaryView(out textView)); 127 | 128 | if (createProjectedEditor) 129 | { 130 | //We add our own role to this text view. Later this will allow us to selectively modify 131 | //this editor without getting in the way of Visual Studio's normal editors. 132 | var roles = _editorFactoryService.DefaultRoles.Concat(new string[] { "CustomProjectionRole" }); 133 | 134 | var vsTextBuffer = docData as IVsTextBuffer; 135 | var textBuffer = _editorAdapter.GetDataBuffer(vsTextBuffer); 136 | 137 | textBuffer.Properties.AddProperty("StartPosition", start); 138 | textBuffer.Properties.AddProperty("EndPosition", end); 139 | var guid = VSConstants.VsTextBufferUserDataGuid.VsTextViewRoles_guid; 140 | ((IVsUserData)codeWindow).SetData(ref guid, _editorFactoryService.CreateTextViewRoleSet(roles).ToString()); 141 | } 142 | 143 | _currentlyFocusedTextView = textView; 144 | var textViewHost = _editorAdapter.GetWpfTextViewHost(textView); 145 | return textViewHost; 146 | } 147 | 148 | 149 | private IWpfTextViewHost _completeTextViewHost; 150 | public IWpfTextViewHost CompleteTextViewHost 151 | { 152 | get 153 | { 154 | if (_completeTextViewHost == null) 155 | { 156 | _completeTextViewHost = CreateEditor(filePath); 157 | } 158 | return _completeTextViewHost; 159 | } 160 | } 161 | 162 | private IWpfTextViewHost _projectedTextViewHost; 163 | public IWpfTextViewHost ProjectedTextViewHost 164 | { 165 | get 166 | { 167 | if (_projectedTextViewHost == null) 168 | { 169 | _projectedTextViewHost = CreateEditor(filePath, start: 0, end: 100, createProjectedEditor: true); 170 | } 171 | return _projectedTextViewHost; 172 | } 173 | } 174 | 175 | private ProjBufferToolWindowControl _myControl; 176 | public override object Content 177 | { 178 | get 179 | { 180 | if (_myControl == null) 181 | { 182 | _myControl = new ProjBufferToolWindowControl(); 183 | _myControl.fullFile.Content = CompleteTextViewHost.HostControl; // Don't rely on the IWpfTextViewHost implementation being a FrameworkElement 184 | _myControl.partialFile.Content = ProjectedTextViewHost.HostControl; 185 | } 186 | return _myControl; 187 | } 188 | } 189 | 190 | public override void OnToolWindowCreated() 191 | { 192 | //We need to set up the tool window to respond to key bindings 193 | //They're passed to the tool window and its buffers via Query() and Exec() 194 | var windowFrame = (IVsWindowFrame)Frame; 195 | var cmdUi = Microsoft.VisualStudio.VSConstants.GUID_TextEditorFactory; 196 | windowFrame.SetGuidProperty((int)__VSFPROPID.VSFPROPID_InheritKeyBindings, ref cmdUi); 197 | base.OnToolWindowCreated(); 198 | } 199 | 200 | protected override bool PreProcessMessage(ref Message m) 201 | { 202 | if (CompleteTextViewHost != null) 203 | { 204 | // copy the Message into a MSG[] array, so we can pass 205 | // it along to the active core editor's IVsWindowPane.TranslateAccelerator 206 | var pMsg = new MSG[1]; 207 | pMsg[0].hwnd = m.HWnd; 208 | pMsg[0].message = (uint)m.Msg; 209 | pMsg[0].wParam = m.WParam; 210 | pMsg[0].lParam = m.LParam; 211 | 212 | var vsWindowPane = (IVsWindowPane)_currentlyFocusedTextView; 213 | return vsWindowPane.TranslateAccelerator(pMsg) == 0; 214 | } 215 | return base.PreProcessMessage(ref m); 216 | } 217 | 218 | int IOleCommandTarget.Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) 219 | { 220 | var hr = 221 | (int)Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED; 222 | 223 | if (_currentlyFocusedTextView != null) 224 | { 225 | var cmdTarget = (IOleCommandTarget)_currentlyFocusedTextView; 226 | hr = cmdTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); 227 | } 228 | return hr; 229 | } 230 | 231 | int IOleCommandTarget.QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) 232 | { 233 | var hr = 234 | (int)Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED; 235 | 236 | if (_currentlyFocusedTextView != null) 237 | { 238 | var cmdTarget = (IOleCommandTarget)_currentlyFocusedTextView; 239 | hr = cmdTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText); 240 | } 241 | return hr; 242 | } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/ProjBufferToolWindowCommand.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Copyright (c) Company. All rights reserved. 4 | // 5 | //------------------------------------------------------------------------------ 6 | 7 | using System; 8 | using System.ComponentModel.Design; 9 | using System.Globalization; 10 | using Microsoft.VisualStudio.Shell; 11 | using Microsoft.VisualStudio.Shell.Interop; 12 | 13 | namespace ProjectionBufferTutorial 14 | { 15 | /// 16 | /// Command handler 17 | /// 18 | internal sealed class ProjBufferToolWindowCommand 19 | { 20 | /// 21 | /// Command ID. 22 | /// 23 | public const int CommandId = 0x0100; 24 | 25 | /// 26 | /// Command menu group (command set GUID). 27 | /// 28 | public static readonly Guid CommandSet = new Guid("6ae1c686-8dbf-4964-adec-0850aab5de43"); 29 | 30 | /// 31 | /// VS Package that provides this command, not null. 32 | /// 33 | private readonly Package package; 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// Adds our command handlers for menu (commands must exist in the command table file) 38 | /// 39 | /// Owner package, not null. 40 | private ProjBufferToolWindowCommand(Package package) 41 | { 42 | if (package == null) 43 | { 44 | throw new ArgumentNullException("package"); 45 | } 46 | 47 | this.package = package; 48 | 49 | OleMenuCommandService commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService; 50 | if (commandService != null) 51 | { 52 | var menuCommandID = new CommandID(CommandSet, CommandId); 53 | var menuItem = new MenuCommand(this.ShowToolWindow, menuCommandID); 54 | commandService.AddCommand(menuItem); 55 | } 56 | } 57 | 58 | /// 59 | /// Gets the instance of the command. 60 | /// 61 | public static ProjBufferToolWindowCommand Instance 62 | { 63 | get; 64 | private set; 65 | } 66 | 67 | /// 68 | /// Gets the service provider from the owner package. 69 | /// 70 | private IServiceProvider ServiceProvider 71 | { 72 | get 73 | { 74 | return this.package; 75 | } 76 | } 77 | 78 | /// 79 | /// Initializes the singleton instance of the command. 80 | /// 81 | /// Owner package, not null. 82 | public static void Initialize(Package package) 83 | { 84 | Instance = new ProjBufferToolWindowCommand(package); 85 | } 86 | 87 | /// 88 | /// Shows the tool window when the menu item is clicked. 89 | /// 90 | /// The event sender. 91 | /// The event args. 92 | private void ShowToolWindow(object sender, EventArgs e) 93 | { 94 | // Get the instance number 0 of this tool window. This window is single instance so this instance 95 | // is actually the only one. 96 | // The last flag is set to true so that if the tool window does not exists it will be created. 97 | ToolWindowPane window = this.package.FindToolWindow(typeof(ProjBufferToolWindow), 0, true); 98 | if ((null == window) || (null == window.Frame)) 99 | { 100 | throw new NotSupportedException("Cannot create tool window"); 101 | } 102 | 103 | IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame; 104 | Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show()); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/ProjBufferToolWindowControl.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/ProjBufferToolWindowControl.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ProjectionBufferTutorial 4 | { 5 | public partial class ProjBufferToolWindowControl : UserControl 6 | { 7 | public ProjBufferToolWindowControl() 8 | { 9 | this.InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ProjectionBufferTutorial/ProjBufferToolWindowPackage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.Design; 3 | using System.Diagnostics; 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Globalization; 6 | using System.Runtime.InteropServices; 7 | using Microsoft.VisualStudio; 8 | using Microsoft.VisualStudio.OLE.Interop; 9 | using Microsoft.VisualStudio.Shell; 10 | using Microsoft.VisualStudio.Shell.Interop; 11 | using Microsoft.Win32; 12 | 13 | namespace ProjectionBufferTutorial 14 | { 15 | [PackageRegistration(UseManagedResourcesOnly = true)] 16 | [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About 17 | [ProvideMenuResource("Menus.ctmenu", 1)] 18 | [ProvideToolWindow(typeof(ProjBufferToolWindow))] 19 | [Guid(ProjBufferToolWindowPackage.PackageGuidString)] 20 | public sealed class ProjBufferToolWindowPackage : Package 21 | { 22 | public const string PackageGuidString = "1c4c82af-4508-4dde-9c56-1437492bff5d"; 23 | 24 | public ProjBufferToolWindowPackage() 25 | { 26 | } 27 | 28 | protected override void Initialize() 29 | { 30 | ProjBufferToolWindowCommand.Initialize(this); 31 | base.Initialize(); 32 | 33 | VisualStudioServices.ServiceProvider = this; 34 | VisualStudioServices.OLEServiceProvider = (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)VisualStudioServices.ServiceProvider.GetService(typeof(Microsoft.VisualStudio.OLE.Interop.IServiceProvider)); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/ProjBufferToolWindowPackage.vsct: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 33 | 34 | 35 | 37 | 38 | 45 | 52 | 53 | 54 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/ProjectionBufferTutorial.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 15.0 6 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 7 | 8 | 9 | true 10 | 11 | 12 | true 13 | 14 | 15 | Key.snk 16 | 17 | 18 | 19 | Debug 20 | AnyCPU 21 | 2.0 22 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 23 | {BC132864-3437-4379-B7EE-4F02FA68D3F7} 24 | Library 25 | Properties 26 | ProjectionBufferTutorial 27 | ProjectionBufferTutorial 28 | v4.6 29 | true 30 | true 31 | true 32 | true 33 | true 34 | false 35 | 36 | 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | 45 | 46 | pdbonly 47 | true 48 | bin\Release\ 49 | TRACE 50 | prompt 51 | 4 52 | 53 | 54 | 55 | 56 | 57 | ProjBufferToolWindowControl.xaml 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Designer 68 | 69 | 70 | 71 | 72 | Designer 73 | MSBuild:Compile 74 | 75 | 76 | 77 | 78 | False 79 | 80 | 81 | False 82 | 83 | 84 | False 85 | 86 | 87 | False 88 | 89 | 90 | 91 | False 92 | 93 | 94 | ..\packages\Microsoft.VisualStudio.ComponentModelHost.15.0.26201\lib\net45\Microsoft.VisualStudio.ComponentModelHost.dll 95 | True 96 | 97 | 98 | ..\packages\Microsoft.VisualStudio.CoreUtility.15.0.26201\lib\net45\Microsoft.VisualStudio.CoreUtility.dll 99 | True 100 | 101 | 102 | ..\packages\Microsoft.VisualStudio.Editor.15.0.26201\lib\net45\Microsoft.VisualStudio.Editor.dll 103 | True 104 | 105 | 106 | ..\packages\Microsoft.VisualStudio.Imaging.15.0.26201\lib\net45\Microsoft.VisualStudio.Imaging.dll 107 | True 108 | 109 | 110 | ..\packages\Microsoft.VisualStudio.OLE.Interop.7.10.6070\lib\Microsoft.VisualStudio.OLE.Interop.dll 111 | True 112 | 113 | 114 | ..\packages\Microsoft.VisualStudio.Shell.15.0.15.0.26201\lib\Microsoft.VisualStudio.Shell.15.0.dll 115 | True 116 | 117 | 118 | ..\packages\Microsoft.VisualStudio.Shell.Framework.15.0.26201\lib\net45\Microsoft.VisualStudio.Shell.Framework.dll 119 | True 120 | 121 | 122 | ..\packages\Microsoft.VisualStudio.Shell.Interop.7.10.6071\lib\Microsoft.VisualStudio.Shell.Interop.dll 123 | True 124 | 125 | 126 | True 127 | ..\packages\Microsoft.VisualStudio.Shell.Interop.10.0.10.0.30319\lib\Microsoft.VisualStudio.Shell.Interop.10.0.dll 128 | True 129 | 130 | 131 | True 132 | ..\packages\Microsoft.VisualStudio.Shell.Interop.11.0.11.0.61030\lib\Microsoft.VisualStudio.Shell.Interop.11.0.dll 133 | True 134 | 135 | 136 | True 137 | ..\packages\Microsoft.VisualStudio.Shell.Interop.12.0.12.0.30110\lib\Microsoft.VisualStudio.Shell.Interop.12.0.dll 138 | True 139 | 140 | 141 | ..\packages\Microsoft.VisualStudio.Shell.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.Shell.Interop.8.0.dll 142 | True 143 | 144 | 145 | ..\packages\Microsoft.VisualStudio.Shell.Interop.9.0.9.0.30729\lib\Microsoft.VisualStudio.Shell.Interop.9.0.dll 146 | True 147 | 148 | 149 | ..\packages\Microsoft.VisualStudio.Text.Data.15.0.26201\lib\net45\Microsoft.VisualStudio.Text.Data.dll 150 | True 151 | 152 | 153 | ..\packages\Microsoft.VisualStudio.Text.Logic.15.0.26201\lib\net45\Microsoft.VisualStudio.Text.Logic.dll 154 | True 155 | 156 | 157 | ..\packages\Microsoft.VisualStudio.Text.UI.15.0.26201\lib\net45\Microsoft.VisualStudio.Text.UI.dll 158 | True 159 | 160 | 161 | ..\packages\Microsoft.VisualStudio.Text.UI.Wpf.15.0.26201\lib\net45\Microsoft.VisualStudio.Text.UI.Wpf.dll 162 | True 163 | 164 | 165 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.7.10.6070\lib\Microsoft.VisualStudio.TextManager.Interop.dll 166 | True 167 | 168 | 169 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.TextManager.Interop.8.0.dll 170 | True 171 | 172 | 173 | ..\packages\Microsoft.VisualStudio.Threading.15.0.240\lib\net45\Microsoft.VisualStudio.Threading.dll 174 | True 175 | 176 | 177 | ..\packages\Microsoft.VisualStudio.Utilities.15.0.26201\lib\net45\Microsoft.VisualStudio.Utilities.dll 178 | True 179 | 180 | 181 | ..\packages\Microsoft.VisualStudio.Validation.15.0.82\lib\net45\Microsoft.VisualStudio.Validation.dll 182 | True 183 | 184 | 185 | 186 | 187 | False 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | Menus.ctmenu 201 | 202 | 203 | 204 | 205 | 206 | 207 | true 208 | VSPackage 209 | 210 | 211 | 212 | 213 | 214 | 215 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 216 | 217 | 218 | 219 | 220 | 221 | 228 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ProjectionBufferTutorial")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ProjectionBufferTutorial")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyVersion("1.0.0.0")] 33 | [assembly: AssemblyFileVersion("1.0.0.0")] 34 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/Resources/ProjBufferToolWindowCommand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/ProjectionBufferTutorial/39364fbf5177b330382eb4728cb5649c07a04632/ProjectionBufferTutorial/Resources/ProjBufferToolWindowCommand.png -------------------------------------------------------------------------------- /ProjectionBufferTutorial/Resources/ProjBufferToolWindowPackage.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/ProjectionBufferTutorial/39364fbf5177b330382eb4728cb5649c07a04632/ProjectionBufferTutorial/Resources/ProjBufferToolWindowPackage.ico -------------------------------------------------------------------------------- /ProjectionBufferTutorial/VSPackage.resx: -------------------------------------------------------------------------------- 1 |  2 | 12 | 13 | 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 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | text/microsoft-resx 120 | 121 | 122 | 2.0 123 | 124 | 125 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 126 | 127 | 128 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 129 | 130 | 131 | 132 | ProjBufferToolWindow Extension 133 | 134 | 135 | ProjBufferToolWindow Visual Studio Extension Detailed Info 136 | 137 | 138 | Resources\ProjBufferToolWindowPackage.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 139 | 140 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/VisualStudioServices.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 ProjectionBufferTutorial 8 | { 9 | public static class VisualStudioServices 10 | { 11 | public static EnvDTE.DTE DTE 12 | { 13 | get; 14 | set; 15 | } 16 | 17 | public static Microsoft.VisualStudio.OLE.Interop.IServiceProvider OLEServiceProvider 18 | { 19 | get; 20 | set; 21 | } 22 | 23 | public static System.IServiceProvider ServiceProvider 24 | { 25 | get; 26 | set; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/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 | -------------------------------------------------------------------------------- /ProjectionBufferTutorial/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | ProjectionBufferTutorial 6 | Empty VSIX Project. 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ProjectionBufferTutorial 2 | ======================== 3 | 4 | Full explanation and tutorial at: [http://joshvarty.wordpress.com/2014/08/01/ripping-the-visual-studio-editor-apart-with-projection-buffers/](http://joshvarty.wordpress.com/2014/08/01/ripping-the-visual-studio-editor-apart-with-projection-buffers/) 5 | 6 | **Note**: This project must be deployed to an instance of Visual Studio using Roslyn. The Language Services were rewritten to properly handle projection buffers. 7 | 8 | This project demonstrates the use of projection buffers with C# Language Services. 9 | 10 | :exclamation: :exclamation: 11 | 12 | Before running, you must modify the [filePath](https://github.com/JoshVarty/ProjectionBufferTutorial/blob/master/ProjectionBufferTutorial/ProjBufferToolWindow.cs#L26) string in [ProjBufferToolWindow.cs](https://github.com/JoshVarty/ProjectionBufferTutorial/blob/master/ProjectionBufferTutorial/ProjBufferToolWindow.cs). It must point to a valid C# file on your machine. 13 | 14 | :exclamation: :exclamation: 15 | 16 | After downloading, you must modify the properties of the project as follows: 17 | 18 | 1. Right click the project and select Properties 19 | 20 | 2. Choose Debug 21 | 22 | 3. Choose Start External program and use the path to devenv.exe 23 | 24 | 4. Set the command line arguments to "/rootsuffix Exp" 25 | 26 | 5. Save and then run. 27 | 28 | 6. Open the C# solution that contain C# file you specificed in [filePath](https://github.com/JoshVarty/ProjectionBufferTutorial/blob/master/ProjectionBufferTutorial/MyToolWindow.cs#L24) 29 | 30 | 7. View > Other Windows > ProjectionBufferTutorial 31 | --------------------------------------------------------------------------------