├── .gitattributes ├── .gitignore ├── JSON Intellisense.sln ├── README.md ├── appveyor.yml ├── art ├── completion-name.png ├── completion-version.png ├── logo.pdn ├── smart-tags.png ├── tooltip-animated.gif ├── tooltip-dark.png ├── tooltip-light.png └── watermark.png ├── assemblies ├── Microsoft.JSON.Core.dll ├── Microsoft.JSON.Editor.dll └── Microsoft.Web.Editor.dll └── src ├── Bower ├── BowerPackage.cs ├── Completion │ ├── BowerNameCompletionEntry.cs │ ├── BowerNameCompletionProvider.cs │ ├── BowerVersionCompletionEntry.cs │ └── BowerVersionCompletionProvider.cs ├── Constants.cs ├── QuickInfo │ ├── BowerInfoBox.xaml │ ├── BowerInfoBox.xaml.cs │ └── BowerQuickInfo.cs ├── Resources │ ├── bower.png │ ├── text.Designer.cs │ └── text.resx └── SmartTags │ ├── BowerInstallPackage.cs │ ├── BowerNavigateToHomepage.cs │ ├── BowerUninstallPackage.cs │ └── BowerUpdatePackage.cs ├── Guids.cs ├── JSON Intellisense.csproj ├── JSON_Intellisense.vsct ├── JSON_IntellisensePackage.cs ├── NPM ├── Completion │ ├── NpmNameCompletionEntry.cs │ ├── NpmNameCompletionProvider.cs │ ├── NpmVersionCompletionEntry.cs │ └── NpmVersionCompletionProvider.cs ├── Constants.cs ├── NpmPackage.cs ├── QuickInfo │ ├── NpmInfoBox.xaml │ ├── NpmInfoBox.xaml.cs │ └── NpmQuickInfo.cs ├── Resources │ ├── npm.png │ ├── text.Designer.cs │ └── text.resx └── SmartTags │ ├── NpmInstallPackage.cs │ ├── NpmNavigateToHomepage.cs │ ├── NpmUninstallPackage.cs │ └── NpmUpdatePackage.cs ├── PkgCmdID.cs ├── Properties └── AssemblyInfo.cs ├── VSPackage.resx ├── _Shared ├── Adornments │ ├── LogoAdornment.cs │ ├── LogoLayer.cs │ └── LogoProvider.cs ├── Completion │ └── CompletionProviderBase.cs ├── Events │ ├── FileSaved.cs │ └── ProjectOpen.cs ├── Globals.cs ├── Helper.cs ├── JSONExtensions.cs ├── Logger.cs ├── Options.cs ├── QuickInfo │ ├── QuickInfoController.cs │ ├── QuickInfoControllerProvider.cs │ ├── QuickInfoSourceBase.cs │ └── QuickInfoSourceProvider.cs ├── Resources │ ├── License.txt │ ├── Package.ico │ ├── Resource.Designer.cs │ ├── Resource.resx │ ├── Watermarks │ │ ├── bower.png │ │ ├── grunt.png │ │ ├── gulp.png │ │ └── npm.png │ ├── browse.png │ ├── icon.png │ ├── install.png │ ├── preview.png │ ├── uninstall.png │ └── update.png └── SmartTags │ ├── IJSONSmartTagProvider.cs │ ├── JSONSmartTag.cs │ ├── JSONSmartTagActionBase.cs │ ├── JSONSmartTagProviderBase.cs │ ├── JSONSmartTagger.cs │ └── JSONViewTaggerProvider.cs ├── app.config ├── packages.config └── source.extension.vsixmanifest /.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 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | .vs 9 | 10 | # Build results 11 | [Dd]ebug/ 12 | [Dd]ebugPublic/ 13 | [Rr]elease/ 14 | x64/ 15 | build/ 16 | bld/ 17 | [Bb]in/ 18 | [Oo]bj/ 19 | 20 | # MSTest test Results 21 | [Tt]est[Rr]esult*/ 22 | [Bb]uild[Ll]og.* 23 | 24 | #NUNIT 25 | *.VisualState.xml 26 | TestResult.xml 27 | 28 | # Build Results of an ATL Project 29 | [Dd]ebugPS/ 30 | [Rr]eleasePS/ 31 | dlldata.c 32 | 33 | *_i.c 34 | *_p.c 35 | *_i.h 36 | *.ilk 37 | *.meta 38 | *.obj 39 | *.pch 40 | *.pdb 41 | *.pgc 42 | *.pgd 43 | *.rsp 44 | *.sbr 45 | *.tlb 46 | *.tli 47 | *.tlh 48 | *.tmp 49 | *.tmp_proj 50 | *.log 51 | *.vspscc 52 | *.vssscc 53 | .builds 54 | *.pidb 55 | *.svclog 56 | *.scc 57 | 58 | # Chutzpah Test files 59 | _Chutzpah* 60 | 61 | # Visual C++ cache files 62 | ipch/ 63 | *.aps 64 | *.ncb 65 | *.opensdf 66 | *.sdf 67 | *.cachefile 68 | 69 | # Visual Studio profiler 70 | *.psess 71 | *.vsp 72 | *.vspx 73 | 74 | # TFS 2012 Local Workspace 75 | $tf/ 76 | 77 | # Guidance Automation Toolkit 78 | *.gpState 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper*/ 82 | *.[Rr]e[Ss]harper 83 | *.DotSettings.user 84 | 85 | # JustCode is a .NET coding addin-in 86 | .JustCode 87 | 88 | # TeamCity is a build add-in 89 | _TeamCity* 90 | 91 | # DotCover is a Code Coverage Tool 92 | *.dotCover 93 | 94 | # NCrunch 95 | *.ncrunch* 96 | _NCrunch_* 97 | .*crunch*.local.xml 98 | 99 | # MightyMoose 100 | *.mm.* 101 | AutoTest.Net/ 102 | 103 | # Web workbench (sass) 104 | .sass-cache/ 105 | 106 | # Installshield output folder 107 | [Ee]xpress/ 108 | 109 | # DocProject is a documentation generator add-in 110 | DocProject/buildhelp/ 111 | DocProject/Help/*.HxT 112 | DocProject/Help/*.HxC 113 | DocProject/Help/*.hhc 114 | DocProject/Help/*.hhk 115 | DocProject/Help/*.hhp 116 | DocProject/Help/Html2 117 | DocProject/Help/html 118 | 119 | # Click-Once directory 120 | publish/ 121 | 122 | # Publish Web Output 123 | *.[Pp]ublish.xml 124 | *.azurePubxml 125 | 126 | # NuGet Packages Directory 127 | packages/ 128 | ## TODO: If the tool you use requires repositories.config uncomment the next line 129 | #!packages/repositories.config 130 | 131 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 132 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 133 | !packages/build/ 134 | 135 | # Windows Azure Build Output 136 | csx/ 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.dbproj.schemaview 151 | *.pfx 152 | *.publishsettings 153 | node_modules/ 154 | 155 | # RIA/Silverlight projects 156 | Generated_Code/ 157 | 158 | # Backup & report files from converting an old project file to a newer 159 | # Visual Studio version. Backup files are not needed, because we have git ;-) 160 | _UpgradeReport_Files/ 161 | Backup*/ 162 | UpgradeLog*.XML 163 | UpgradeLog*.htm 164 | 165 | # SQL Server files 166 | *.mdf 167 | *.ldf 168 | 169 | # Business Intelligence projects 170 | *.rdl.data 171 | *.bim.layout 172 | *.bim_*.settings 173 | 174 | # Microsoft Fakes 175 | FakesAssemblies/ 176 | 177 | # ========================= 178 | # Operating System Files 179 | # ========================= 180 | 181 | # OSX 182 | # ========================= 183 | 184 | .DS_Store 185 | .AppleDouble 186 | .LSOverride 187 | 188 | # Icon must ends with two \r. 189 | Icon 190 | 191 | # Thumbnails 192 | ._* 193 | 194 | # Files that might appear on external disk 195 | .Spotlight-V100 196 | .Trashes 197 | 198 | # Windows 199 | # ========================= 200 | 201 | # Windows image file caches 202 | Thumbs.db 203 | ehthumbs.db 204 | 205 | # Folder config file 206 | Desktop.ini 207 | 208 | # Recycle Bin used on file shares 209 | $RECYCLE.BIN/ 210 | 211 | # Windows Installer files 212 | *.cab 213 | *.msi 214 | *.msm 215 | *.msp 216 | -------------------------------------------------------------------------------- /JSON Intellisense.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JSON Intellisense", "src\JSON Intellisense.csproj", "{F84E6465-6D2A-4732-9707-5EFBAB8E82C9}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F81A2A0A-E487-4DEF-A9AC-2CFA173DA9E0}" 9 | ProjectSection(SolutionItems) = preProject 10 | .gitignore = .gitignore 11 | appveyor.yml = appveyor.yml 12 | README.md = README.md 13 | EndProjectSection 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | CI|Any CPU = CI|Any CPU 18 | Debug|Any CPU = Debug|Any CPU 19 | Release|Any CPU = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {F84E6465-6D2A-4732-9707-5EFBAB8E82C9}.CI|Any CPU.ActiveCfg = CI|Any CPU 23 | {F84E6465-6D2A-4732-9707-5EFBAB8E82C9}.CI|Any CPU.Build.0 = CI|Any CPU 24 | {F84E6465-6D2A-4732-9707-5EFBAB8E82C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {F84E6465-6D2A-4732-9707-5EFBAB8E82C9}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {F84E6465-6D2A-4732-9707-5EFBAB8E82C9}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {F84E6465-6D2A-4732-9707-5EFBAB8E82C9}.Release|Any CPU.Build.0 = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Package Intellisense for Visual Studio 2 | ================= 3 | 4 | [![Build status](https://ci.appveyor.com/api/projects/status/p4c2fevy6oyd2eoa)](https://ci.appveyor.com/project/madskristensen/json-intellisense) 5 | 6 | NPM and Bower package Intellisense directly in the Visual Studio JSON editor. 7 | 8 | __Note__ This extension requires VS2013 Update 3 RC or newer. 9 | 10 | Download this extension from the [VS Gallery](http://visualstudiogallery.msdn.microsoft.com/65748cdb-4087-497e-a394-2e3449c8e61e) 11 | or get the [nightly build](http://vsixgallery.com/extension/aaa8d5c5-24d8-4c45-9620-9f77b2aa6363/). 12 | 13 | ## Features 14 | 15 | ### Intellisense 16 | Live search results from both NPM and Bower show up in Intellisense: 17 | 18 | ![Screenshot](https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/master/art/completion-name.png) 19 | 20 | It can even show the package version as well: 21 | 22 | ![Screenshot](https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/master/art/completion-version.png) 23 | 24 | Please notice that npm version Intellisense is much faster than Bower's. 25 | This is due to Bower's slower API. 26 | 27 | 28 | ### Hover tooltips 29 | Get the information about the packages on mouse hover 30 | 31 | Light theme: 32 | ![Screenshot](https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/master/art/tooltip-light.png) 33 | 34 | Dark theme: 35 | ![Screenshot](https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/master/art/tooltip-dark.png) 36 | 37 | Animated: 38 | ![Screenshot](https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/master/art/tooltip-animated.gif) 39 | 40 | 41 | ### Smart Tags 42 | Smart Tags are small helpers that offers contextual features 43 | 44 | ![Screenshot](https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/master/art/smart-tags.png) 45 | 46 | ### Editor watermarks 47 | Sometimes JSON files tend to look the same, so watermarks are 48 | added to the bottom right corner to identify what file you are working in. 49 | 50 | ![Screenshot](https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/master/art/watermark.png) 51 | 52 | The watermark logos are added to: 53 | 54 | * bower.json 55 | * package.json 56 | * gruntfile.js 57 | * gulpfile.js 58 | 59 | ### Package restore on solution open 60 | Make sure you always have both npm and Bower packages restored when you 61 | open a project in Visual Studio. 62 | 63 | **Tools -> Options -> Package Intellisense** let's you modify the behavior 64 | of this feature. 65 | 66 | ### Package restore on save 67 | Any time you save either package.json or bower.json the packages will be 68 | restored/installed automatically in the background. -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 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 | 9 | build_script: 10 | - nuget restore 11 | - msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m 12 | 13 | after_build: 14 | - ps: Vsix-PushArtifacts | Vsix-PublishToGallery 15 | 16 | before_deploy: 17 | - ps: Vsix-CreateChocolatyPackage -packageId packageintellisense 18 | 19 | deploy: 20 | - provider: Environment 21 | name: Chocolatey 22 | on: 23 | branch: master 24 | appveyor_repo_commit_message_extended: /\[release\]/ -------------------------------------------------------------------------------- /art/completion-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/art/completion-name.png -------------------------------------------------------------------------------- /art/completion-version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/art/completion-version.png -------------------------------------------------------------------------------- /art/logo.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/art/logo.pdn -------------------------------------------------------------------------------- /art/smart-tags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/art/smart-tags.png -------------------------------------------------------------------------------- /art/tooltip-animated.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/art/tooltip-animated.gif -------------------------------------------------------------------------------- /art/tooltip-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/art/tooltip-dark.png -------------------------------------------------------------------------------- /art/tooltip-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/art/tooltip-light.png -------------------------------------------------------------------------------- /art/watermark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/art/watermark.png -------------------------------------------------------------------------------- /assemblies/Microsoft.JSON.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/assemblies/Microsoft.JSON.Core.dll -------------------------------------------------------------------------------- /assemblies/Microsoft.JSON.Editor.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/assemblies/Microsoft.JSON.Editor.dll -------------------------------------------------------------------------------- /assemblies/Microsoft.Web.Editor.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/assemblies/Microsoft.Web.Editor.dll -------------------------------------------------------------------------------- /src/Bower/BowerPackage.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | 3 | namespace JSON_Intellisense.Bower 4 | { 5 | public class BowerPackage 6 | { 7 | public string Name { get; set; } 8 | public string Url { get; set; } 9 | public int Hits { get; set; } 10 | 11 | public static BowerPackage FromPackageName(string name) 12 | { 13 | try 14 | { 15 | Options options = JSON_IntellisensePackage.Options; 16 | string packageUrl = Constants.PackageUrl; 17 | 18 | if (!string.IsNullOrEmpty(options.BowerCustomFeedUrl)) { 19 | packageUrl = options.BowerCustomFeedUrl; 20 | } 21 | 22 | string url = string.Format(packageUrl, HttpUtility.UrlEncode(name)); 23 | string result = Helper.DownloadText(url); 24 | 25 | if (string.IsNullOrEmpty(result)) 26 | return null; 27 | 28 | var root = Helper.ParseJSON(result); 29 | 30 | return new BowerPackage() 31 | { 32 | Name = name, 33 | Url = root.SelectItemText("url"), 34 | Hits = int.Parse(root.SelectItemText("hits")), 35 | }; 36 | } 37 | catch { /* JSON result is invalid. Ignore */ } 38 | 39 | return null; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Bower/Completion/BowerNameCompletionEntry.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading; 4 | using System.Web; 5 | using Microsoft.JSON.Core.Parser; 6 | using Microsoft.JSON.Editor.Completion; 7 | using Microsoft.VisualStudio.Language.Intellisense; 8 | 9 | namespace JSON_Intellisense.Bower 10 | { 11 | class BowerNameCompletionEntry : JSONCompletionEntry 12 | { 13 | private JSONDocument _doc; 14 | internal static IEnumerable _searchResults; 15 | 16 | public BowerNameCompletionEntry(string text, IIntellisenseSession session, JSONDocument doc) 17 | : base(text, "\"" + text + "\"", null, Constants.Icon, null, false, session as ICompletionSession) 18 | { 19 | _doc = doc; 20 | } 21 | 22 | public override void Commit() 23 | { 24 | if (_doc == null) 25 | { 26 | base.Commit(); 27 | } 28 | else 29 | { 30 | string searchTerm = _doc.GetMemberName(base.Session); 31 | 32 | if (string.IsNullOrEmpty(searchTerm)) 33 | return; 34 | 35 | ExecuteSearch(searchTerm); 36 | } 37 | } 38 | 39 | private void ExecuteSearch(string searchTerm) 40 | { 41 | ThreadPool.QueueUserWorkItem(o => 42 | { 43 | string url = string.Format(Constants.SearchUrl, HttpUtility.UrlEncode(searchTerm)); 44 | string result = Helper.DownloadText(url); 45 | var children = GetChildren(result); 46 | 47 | if (!children.Any()) 48 | { 49 | Helper.DTE.StatusBar.Text = string.Format(Resources.text.CompletionNoPackageFound, searchTerm); 50 | base.Session.Dismiss(); 51 | return; 52 | } 53 | 54 | Helper.DTE.StatusBar.Text = string.Empty; 55 | _searchResults = children; 56 | 57 | Helper.ExecuteCommand("Edit.CompleteWord"); 58 | }); 59 | } 60 | 61 | private static IEnumerable GetChildren(string result) 62 | { 63 | var arr = Helper.ParseJSON(result) as JSONArray; 64 | 65 | if (arr == null) 66 | yield break; 67 | 68 | foreach (JSONBlockItemChild child in arr.BlockItemChildren.Take(25)) 69 | { 70 | var foo = child.Children.First() as JSONObject; 71 | yield return foo.SelectItemText("name"); 72 | } 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /src/Bower/Completion/BowerNameCompletionProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using Microsoft.JSON.Core.Parser; 4 | using Microsoft.JSON.Editor.Completion; 5 | using Microsoft.JSON.Editor.Completion.Def; 6 | using Microsoft.VisualStudio.Utilities; 7 | 8 | namespace JSON_Intellisense.Bower 9 | { 10 | [Export(typeof(IJSONCompletionListProvider))] 11 | [Name("BowerNameCompletionProvider")] 12 | class BowerNameCompletionProvider : CompletionProviderBase 13 | { 14 | public override JSONCompletionContextType ContextType 15 | { 16 | get { return JSONCompletionContextType.PropertyName; } 17 | } 18 | 19 | public override string SupportedFileName 20 | { 21 | get { return Constants.FileName; } 22 | } 23 | 24 | protected override IEnumerable GetEntries(JSONCompletionContext context) 25 | { 26 | if (BowerNameCompletionEntry._searchResults != null) 27 | { 28 | foreach (string value in BowerNameCompletionEntry._searchResults) 29 | { 30 | yield return new BowerNameCompletionEntry(value, context.Session, null); 31 | } 32 | 33 | BowerNameCompletionEntry._searchResults = null; 34 | } 35 | else 36 | { 37 | JSONMember dependency = GetDependency(context); 38 | 39 | if (dependency != null) 40 | yield return new BowerNameCompletionEntry(Resources.text.CompletionSearch, context.Session, dependency.JSONDocument); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Bower/Completion/BowerVersionCompletionEntry.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.JSON.Editor.Completion; 2 | using Microsoft.VisualStudio.Language.Intellisense; 3 | 4 | namespace JSON_Intellisense.Bower 5 | { 6 | class BowerVersionCompletionEntry : JSONCompletionEntry 7 | { 8 | public BowerVersionCompletionEntry(string text, string description, IIntellisenseSession session) 9 | : base(text, "\"" + text + "\"", description, Constants.Icon, null, false, session as ICompletionSession) 10 | { } 11 | 12 | public override void Commit() 13 | { 14 | base.Commit(); 15 | Helper.DTE.StatusBar.Text = string.Empty; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Bower/Completion/BowerVersionCompletionProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using System.Diagnostics; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading; 7 | using Microsoft.JSON.Core.Parser; 8 | using Microsoft.JSON.Editor.Completion; 9 | using Microsoft.JSON.Editor.Completion.Def; 10 | using Microsoft.VisualStudio.Utilities; 11 | 12 | namespace JSON_Intellisense.Bower 13 | { 14 | [Export(typeof(IJSONCompletionListProvider))] 15 | [Name("BowerVersionCompletionProvider")] 16 | class BowerVersionCompletionProvider : CompletionProviderBase 17 | { 18 | internal static string _version; 19 | private static readonly Regex _regex = new Regex("\"?version\"?: (\"|')(.+)(\"|')", RegexOptions.Compiled); 20 | private static readonly EnvDTE.vsStatusAnimation _animation = EnvDTE.vsStatusAnimation.vsStatusAnimationFind; 21 | private static bool _isProcessing = false; 22 | 23 | public override JSONCompletionContextType ContextType 24 | { 25 | get { return JSONCompletionContextType.PropertyValue; } 26 | } 27 | 28 | public override string SupportedFileName 29 | { 30 | get { return Constants.FileName; } 31 | } 32 | 33 | protected override IEnumerable GetEntries(JSONCompletionContext context) 34 | { 35 | if (_version != null) 36 | { 37 | yield return new BowerVersionCompletionEntry(_version, Resources.text.CompletionVersionLatest, context.Session); 38 | yield return new BowerVersionCompletionEntry("~" + _version, Resources.text.CompletionVersionMinor, context.Session); 39 | yield return new BowerVersionCompletionEntry("^" + _version, Resources.text.CompletionVersionMajor, context.Session); 40 | 41 | _version = null; 42 | } 43 | else 44 | { 45 | JSONMember dependency = GetDependency(context); 46 | 47 | if (dependency != null) 48 | ExecuteRemoteSearch(dependency); 49 | } 50 | } 51 | 52 | private void ExecuteRemoteSearch(JSONMember dependency) 53 | { 54 | if (_isProcessing) 55 | return; 56 | 57 | ThreadPool.QueueUserWorkItem(o => 58 | { 59 | _isProcessing = true; 60 | 61 | try 62 | { 63 | Helper.DTE.StatusBar.Text = Resources.text.CompletionRetrievingVersion; 64 | Helper.DTE.StatusBar.Animate(true, _animation); 65 | 66 | Execute(dependency); 67 | } 68 | catch 69 | { 70 | Helper.DTE.StatusBar.Clear(); 71 | } 72 | 73 | Helper.DTE.StatusBar.Animate(false, _animation); 74 | _isProcessing = false; 75 | }); 76 | } 77 | 78 | private void Execute(JSONMember dependency) 79 | { 80 | string package = dependency.Name.Text.Trim('"'); 81 | 82 | ProcessStartInfo start = new ProcessStartInfo("cmd", "/c bower info " + package) 83 | { 84 | UseShellExecute = false, 85 | CreateNoWindow = true, 86 | ErrorDialog = false, 87 | RedirectStandardOutput = true, 88 | RedirectStandardError = true, 89 | StandardOutputEncoding = Encoding.UTF8, 90 | StandardErrorEncoding = Encoding.UTF8, 91 | }; 92 | 93 | using (Process p = new Process()) 94 | { 95 | p.StartInfo = start; 96 | p.EnableRaisingEvents = true; 97 | p.OutputDataReceived += OutputDataReceived; 98 | p.ErrorDataReceived += ErrorDataReceived; 99 | p.Exited += Exited; 100 | 101 | p.Start(); 102 | p.BeginOutputReadLine(); 103 | p.BeginErrorReadLine(); 104 | p.WaitForExit(); 105 | } 106 | } 107 | 108 | private void Exited(object sender, System.EventArgs e) 109 | { 110 | Process p = (Process)sender; 111 | 112 | try 113 | { 114 | if (p.ExitCode == 0) 115 | Helper.DTE.StatusBar.Clear(); 116 | else 117 | Helper.DTE.StatusBar.Text = Resources.text.CompletionRetrievingVersionError; 118 | } 119 | catch 120 | { 121 | Helper.DTE.StatusBar.Text = Resources.text.CompletionRetrievingVersionError; 122 | } 123 | } 124 | 125 | private void OutputDataReceived(object sender, DataReceivedEventArgs e) 126 | { 127 | if (e == null || string.IsNullOrEmpty(e.Data)) 128 | return; 129 | 130 | var match = _regex.Match(e.Data); 131 | 132 | if (match.Success) 133 | { 134 | _version = match.Groups[2].Value; 135 | Helper.ExecuteCommand("Edit.ListMembers"); 136 | } 137 | } 138 | 139 | private void ErrorDataReceived(object sender, DataReceivedEventArgs e) 140 | { 141 | if (e == null || string.IsNullOrEmpty(e.Data)) 142 | return; 143 | 144 | Logger.Log(e.Data); 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/Bower/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Media; 3 | using System.Windows.Media.Imaging; 4 | 5 | namespace JSON_Intellisense.Bower 6 | { 7 | public static class Constants 8 | { 9 | public const string FileName = "bower.json"; 10 | public const string SearchUrl = "https://bower.herokuapp.com/packages/search/{0}"; 11 | public const string PackageUrl = "https://bower.herokuapp.com/packages/{0}"; 12 | public static ImageSource Icon = BitmapFrame.Create(new Uri("pack://application:,,,/JSON Intellisense;component/Bower/Resources/bower.png", UriKind.RelativeOrAbsolute)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Bower/QuickInfo/BowerInfoBox.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 15 | 16 | -------------------------------------------------------------------------------- /src/Bower/QuickInfo/BowerInfoBox.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace JSON_Intellisense.Bower 4 | { 5 | public partial class BowerInfoBox : UserControl 6 | { 7 | private static BowerInfoBox _box = new BowerInfoBox(); 8 | 9 | public BowerInfoBox() 10 | { 11 | InitializeComponent(); 12 | imgLogo.Source = Constants.Icon; 13 | } 14 | 15 | public static BowerInfoBox Create(BowerPackage package) 16 | { 17 | _box.lblName.Content = package.Name; 18 | _box.lblUrl.Content = package.Url.Replace("git://", string.Empty).Replace(".git", string.Empty); 19 | _box.lblHits.Content = package.Hits.ToString("N0"); 20 | 21 | _box.descHits.Content = Bower.Resources.text.QuickInfoHits + ":"; 22 | 23 | _box.AnimateWindowSize(40, 53); 24 | 25 | return _box; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Bower/QuickInfo/BowerQuickInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using Microsoft.JSON.Core.Parser; 3 | using Microsoft.VisualStudio.Text; 4 | 5 | namespace JSON_Intellisense.Bower 6 | { 7 | internal class BowerQuickInfo : QuickInfoSourceBase 8 | { 9 | public BowerQuickInfo(ITextBuffer subjectBuffer) 10 | : base(subjectBuffer) 11 | { } 12 | 13 | public override UIElement CreateTooltip(string name, JSONParseItem item) 14 | { 15 | BowerPackage package = BowerPackage.FromPackageName(name); 16 | 17 | if (package == null) 18 | return null; 19 | 20 | return BowerInfoBox.Create(package); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Bower/Resources/bower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/Bower/Resources/bower.png -------------------------------------------------------------------------------- /src/Bower/Resources/text.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.0 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace JSON_Intellisense.Bower.Resources { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class text { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal text() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("JSON_Intellisense.Bower.Resources.text", typeof(text).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to No packages found matching '{0}'. 65 | /// 66 | internal static string CompletionNoPackageFound { 67 | get { 68 | return ResourceManager.GetString("CompletionNoPackageFound", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to Retrieving version number from Bower.... 74 | /// 75 | internal static string CompletionRetrievingVersion { 76 | get { 77 | return ResourceManager.GetString("CompletionRetrievingVersion", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// Looks up a localized string similar to Could not retrive the version number. 83 | /// 84 | internal static string CompletionRetrievingVersionError { 85 | get { 86 | return ResourceManager.GetString("CompletionRetrievingVersionError", resourceCulture); 87 | } 88 | } 89 | 90 | /// 91 | /// Looks up a localized string similar to Search Bower.... 92 | /// 93 | internal static string CompletionSearch { 94 | get { 95 | return ResourceManager.GetString("CompletionSearch", resourceCulture); 96 | } 97 | } 98 | 99 | /// 100 | /// Looks up a localized string similar to The currently latest version of the package. 101 | /// 102 | internal static string CompletionVersionLatest { 103 | get { 104 | return ResourceManager.GetString("CompletionVersionLatest", resourceCulture); 105 | } 106 | } 107 | 108 | /// 109 | /// Looks up a localized string similar to Matches the most recent major version (1.x.x). 110 | /// 111 | internal static string CompletionVersionMajor { 112 | get { 113 | return ResourceManager.GetString("CompletionVersionMajor", resourceCulture); 114 | } 115 | } 116 | 117 | /// 118 | /// Looks up a localized string similar to Matches the most recent minor version (1.2.x). 119 | /// 120 | internal static string CompletionVersionMinor { 121 | get { 122 | return ResourceManager.GetString("CompletionVersionMinor", resourceCulture); 123 | } 124 | } 125 | 126 | /// 127 | /// Looks up a localized string similar to Hits. 128 | /// 129 | internal static string QuickInfoHits { 130 | get { 131 | return ResourceManager.GetString("QuickInfoHits", resourceCulture); 132 | } 133 | } 134 | 135 | /// 136 | /// Looks up a localized string similar to Install package. 137 | /// 138 | internal static string SmartTagInstallPackage { 139 | get { 140 | return ResourceManager.GetString("SmartTagInstallPackage", resourceCulture); 141 | } 142 | } 143 | 144 | /// 145 | /// Looks up a localized string similar to Open homepage in browser. 146 | /// 147 | internal static string SmartTagNavigateToHomepage { 148 | get { 149 | return ResourceManager.GetString("SmartTagNavigateToHomepage", resourceCulture); 150 | } 151 | } 152 | 153 | /// 154 | /// Looks up a localized string similar to The package's doesn't specify a valid homepage. 155 | /// 156 | internal static string SmartTagNavigateToHomepageError { 157 | get { 158 | return ResourceManager.GetString("SmartTagNavigateToHomepageError", resourceCulture); 159 | } 160 | } 161 | 162 | /// 163 | /// Looks up a localized string similar to Uninstall package. 164 | /// 165 | internal static string SmartTagUninstallPackage { 166 | get { 167 | return ResourceManager.GetString("SmartTagUninstallPackage", resourceCulture); 168 | } 169 | } 170 | 171 | /// 172 | /// Looks up a localized string similar to Update package. 173 | /// 174 | internal static string SmartTagUpdatePackage { 175 | get { 176 | return ResourceManager.GetString("SmartTagUpdatePackage", resourceCulture); 177 | } 178 | } 179 | 180 | /// 181 | /// Looks up a localized string similar to Installing package.... 182 | /// 183 | internal static string statusbarInstalling { 184 | get { 185 | return ResourceManager.GetString("statusbarInstalling", resourceCulture); 186 | } 187 | } 188 | 189 | /// 190 | /// Looks up a localized string similar to Uninstalling package.... 191 | /// 192 | internal static string statusbarUninstalling { 193 | get { 194 | return ResourceManager.GetString("statusbarUninstalling", resourceCulture); 195 | } 196 | } 197 | 198 | /// 199 | /// Looks up a localized string similar to Updating package.... 200 | /// 201 | internal static string statusbarUpdating { 202 | get { 203 | return ResourceManager.GetString("statusbarUpdating", resourceCulture); 204 | } 205 | } 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/Bower/Resources/text.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 | No packages found matching '{0}' 122 | 123 | 124 | Retrieving version number from Bower... 125 | 126 | 127 | Could not retrive the version number 128 | 129 | 130 | Search Bower... 131 | 132 | 133 | The currently latest version of the package 134 | 135 | 136 | Matches the most recent major version (1.x.x) 137 | 138 | 139 | Matches the most recent minor version (1.2.x) 140 | 141 | 142 | Hits 143 | 144 | 145 | Install package 146 | 147 | 148 | Open homepage in browser 149 | 150 | 151 | The package's doesn't specify a valid homepage 152 | 153 | 154 | Uninstall package 155 | 156 | 157 | Update package 158 | 159 | 160 | Installing package... 161 | 162 | 163 | Uninstalling package... 164 | 165 | 166 | Updating package... 167 | 168 | -------------------------------------------------------------------------------- /src/Bower/SmartTags/BowerInstallPackage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.Composition; 4 | using System.IO; 5 | using Microsoft.JSON.Core.Parser; 6 | using Microsoft.VisualStudio.Language.Intellisense; 7 | using Microsoft.VisualStudio.Text; 8 | using Microsoft.VisualStudio.Utilities; 9 | 10 | namespace JSON_Intellisense.Bower 11 | { 12 | [Export(typeof(IJSONSmartTagProvider))] 13 | [Name("Bower Install Package")] 14 | class InstallPackageProvider : JSONSmartTagProviderBase 15 | { 16 | public override string SupportedFileName 17 | { 18 | get { return Constants.FileName; } 19 | } 20 | 21 | public override IEnumerable GetSmartTagActions(JSONMember item, ITextBuffer buffer) 22 | { 23 | // TODO: Check if the bower package is already installed and if so, don't show this SmartTag 24 | 25 | string directory = Path.GetDirectoryName(buffer.GetFileName()); 26 | 27 | if (item.Value != null && item.Value.Text.Trim('"').Length > 0) 28 | yield return new InstallPackageAction(item, directory); 29 | } 30 | } 31 | 32 | internal class InstallPackageAction : JSONSmartTagActionBase 33 | { 34 | private JSONMember _item; 35 | private string _directory; 36 | 37 | public InstallPackageAction(JSONMember item, string directory) 38 | { 39 | _item = item; 40 | _directory = directory; 41 | Icon = Globals.InstallIcon; 42 | } 43 | 44 | public override string DisplayText 45 | { 46 | get { return "Install package"; } 47 | } 48 | 49 | public override void Invoke() 50 | { 51 | Helper.SaveDocument(); 52 | string param = GenerateSaveParam(_item); 53 | string command = "bower install " + _item.UnquotedNameText + " " + param; 54 | Helper.RunProcess(command, _directory, Resources.text.statusbarInstalling); 55 | } 56 | 57 | private static string GenerateSaveParam(JSONMember item) 58 | { 59 | JSONMember parent = item.Parent.FindType(); 60 | 61 | string param = "--save"; 62 | 63 | if (parent.UnquotedNameText.Equals("devDependencies", StringComparison.OrdinalIgnoreCase)) 64 | param += "-dev"; 65 | 66 | return param; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Bower/SmartTags/BowerNavigateToHomepage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.Composition; 4 | using System.Windows.Forms; 5 | using Microsoft.JSON.Core.Parser; 6 | using Microsoft.VisualStudio.Language.Intellisense; 7 | using Microsoft.VisualStudio.Text; 8 | using Microsoft.VisualStudio.Utilities; 9 | 10 | namespace JSON_Intellisense.Bower 11 | { 12 | [Export(typeof(IJSONSmartTagProvider))] 13 | [Name("Bower Navigate To Homepage")] 14 | [Order(Before = "NPM Update Package")] 15 | class NavigateToHomepageProvider : JSONSmartTagProviderBase 16 | { 17 | public override string SupportedFileName 18 | { 19 | get { return Constants.FileName; } 20 | } 21 | 22 | public override IEnumerable GetSmartTagActions(JSONMember item, ITextBuffer buffer) 23 | { 24 | yield return new NavigateToHomePageAction(item.UnquotedNameText); 25 | } 26 | } 27 | 28 | internal class NavigateToHomePageAction : JSONSmartTagActionBase 29 | { 30 | private string _name; 31 | 32 | public NavigateToHomePageAction(string name) 33 | { 34 | _name = name; 35 | Icon = Globals.BrowseIcon; 36 | } 37 | 38 | public override string DisplayText 39 | { 40 | get { return Resources.text.SmartTagNavigateToHomepage; } 41 | } 42 | 43 | public override void Invoke() 44 | { 45 | BowerPackage package = BowerPackage.FromPackageName(_name); 46 | string cleanUrl = "http://" + package.Url.Replace("git://", string.Empty); 47 | Uri url; 48 | 49 | if (package != null && Uri.TryCreate(cleanUrl, UriKind.Absolute, out url)) 50 | { 51 | System.Diagnostics.Process.Start(url.ToString()); 52 | } 53 | else 54 | { 55 | MessageBox.Show(Resources.text.SmartTagNavigateToHomepageError, Globals.VsixName, MessageBoxButtons.OK, MessageBoxIcon.Hand); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Bower/SmartTags/BowerUninstallPackage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using System.IO; 4 | using Microsoft.JSON.Core.Parser; 5 | using Microsoft.VisualStudio.Language.Intellisense; 6 | using Microsoft.VisualStudio.Text; 7 | using Microsoft.VisualStudio.Utilities; 8 | 9 | namespace JSON_Intellisense.Bower 10 | { 11 | [Export(typeof(IJSONSmartTagProvider))] 12 | [Name("Bower Uninstall Package")] 13 | [Order(After = "Bower Update Package")] 14 | class UninstallPackageProvider : JSONSmartTagProviderBase 15 | { 16 | public override string SupportedFileName 17 | { 18 | get { return Constants.FileName; } 19 | } 20 | 21 | public override IEnumerable GetSmartTagActions(JSONMember item, ITextBuffer buffer) 22 | { 23 | string directory = Path.GetDirectoryName(buffer.GetFileName()); 24 | 25 | if (item.Value != null && item.Value.Text.Trim('"').Length > 0) 26 | yield return new UninstallPackageAction(item, directory, buffer); 27 | } 28 | } 29 | 30 | internal class UninstallPackageAction : JSONSmartTagActionBase 31 | { 32 | private JSONMember _item; 33 | private string _directory; 34 | private ITextBuffer _buffer; 35 | 36 | public UninstallPackageAction(JSONMember item, string directory, ITextBuffer buffer) 37 | { 38 | _item = item; 39 | _directory = directory; 40 | _buffer = buffer; 41 | Icon = Globals.UninstallIcon; 42 | } 43 | 44 | public override string DisplayText 45 | { 46 | get { return Resources.text.SmartTagUninstallPackage; } 47 | } 48 | 49 | public override void Invoke() 50 | { 51 | string command = "bower uninstall " + _item.UnquotedNameText; 52 | Helper.RunProcess(command, _directory, Resources.text.statusbarUninstalling, Helper.SaveDocument); 53 | 54 | Helper.DTE.UndoContext.Open(Resources.text.SmartTagUninstallPackage); 55 | _item.DeletePackageMember(_buffer); 56 | Helper.DTE.UndoContext.Close(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Bower/SmartTags/BowerUpdatePackage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using Microsoft.JSON.Core.Parser; 6 | using Microsoft.VisualStudio.Language.Intellisense; 7 | using Microsoft.VisualStudio.Text; 8 | using Microsoft.VisualStudio.Utilities; 9 | 10 | namespace JSON_Intellisense.Bower 11 | { 12 | [Export(typeof(IJSONSmartTagProvider))] 13 | [Name("Bower Update Package")] 14 | class UpdatePackageProvider : JSONSmartTagProviderBase 15 | { 16 | public override string SupportedFileName 17 | { 18 | get { return Constants.FileName; } 19 | } 20 | 21 | public override IEnumerable GetSmartTagActions(JSONMember item, ITextBuffer buffer) 22 | { 23 | string directory = Path.GetDirectoryName(buffer.GetFileName()); 24 | 25 | if (item.Value != null && item.Value.Text.Trim('"').Length > 0) 26 | yield return new UpdatePackageAction(item.UnquotedNameText, directory); 27 | } 28 | } 29 | 30 | internal class UpdatePackageAction : JSONSmartTagActionBase 31 | { 32 | private string _name; 33 | private string _directory; 34 | 35 | public UpdatePackageAction(string name, string directory) 36 | { 37 | _name = name; 38 | _directory = directory; 39 | Icon = Globals.UpdateIcon; 40 | } 41 | 42 | public override string DisplayText 43 | { 44 | get { return Resources.text.SmartTagUpdatePackage; } 45 | } 46 | 47 | public override void Invoke() 48 | { 49 | Helper.SaveDocument(); 50 | string command = "bower update " + _name; 51 | Helper.RunProcess(command, _directory, Resources.text.statusbarUpdating); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Guids.cs: -------------------------------------------------------------------------------- 1 | // Guids.cs 2 | // MUST match guids.h 3 | using System; 4 | 5 | namespace JSON_Intellisense 6 | { 7 | static class GuidList 8 | { 9 | public const string guidJSON_IntellisensePkgString = "aaa8d5c5-24d8-4c45-9620-9f77b2aa6363"; 10 | public const string guidJSON_IntellisenseCmdSetString = "302cecba-3f94-48f0-ab00-3549d04b6a51"; 11 | 12 | public static readonly Guid guidJSON_IntellisenseCmdSet = new Guid(guidJSON_IntellisenseCmdSetString); 13 | }; 14 | } -------------------------------------------------------------------------------- /src/JSON Intellisense.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(VisualStudioVersion) 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | Program 7 | $(DevEnvDir)\devenv.exe 8 | /rootsuffix Exp 9 | true 10 | Normal 11 | 12 | 13 | 14 | bin\CI\ 15 | TRACE 16 | true 17 | pdbonly 18 | AnyCPU 19 | prompt 20 | MinimumRecommendedRules.ruleset 21 | False 22 | 23 | 24 | 25 | Debug 26 | AnyCPU 27 | 2.0 28 | {F84E6465-6D2A-4732-9707-5EFBAB8E82C9} 29 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 30 | Library 31 | Properties 32 | JSON_Intellisense 33 | JSON Intellisense 34 | v4.5 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 | 58 | BowerInfoBox.xaml 59 | 60 | 61 | 62 | 63 | True 64 | True 65 | text.resx 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | NpmInfoBox.xaml 78 | 79 | 80 | True 81 | True 82 | text.resx 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | Component 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | True 115 | True 116 | Resource.resx 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | Designer 130 | 131 | 132 | 133 | 134 | true 135 | VSPackage 136 | Designer 137 | 138 | 139 | 140 | 141 | True 142 | 143 | 144 | True 145 | 146 | 147 | True 148 | 149 | 150 | True 151 | 152 | 153 | False 154 | $(DevEnvDir)\CommonExtensions\Microsoft\Web\Editor\Microsoft.CSS.Core.dll 155 | 156 | 157 | False 158 | ..\assemblies\Microsoft.JSON.Core.dll 159 | 160 | 161 | False 162 | ..\assemblies\Microsoft.JSON.Editor.dll 163 | 164 | 165 | 166 | 167 | True 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | False 182 | ..\assemblies\Microsoft.Web.Editor.dll 183 | 184 | 185 | ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll 186 | True 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | Menus.ctmenu 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | true 213 | 214 | 215 | 216 | 217 | true 218 | 219 | 220 | 221 | 222 | true 223 | 224 | 225 | 226 | 227 | 228 | 229 | Designer 230 | MSBuild:Compile 231 | 232 | 233 | MSBuild:Compile 234 | Designer 235 | 236 | 237 | 238 | 239 | ResXFileCodeGenerator 240 | text.Designer.cs 241 | 242 | 243 | ResXFileCodeGenerator 244 | text.Designer.cs 245 | 246 | 247 | ResXFileCodeGenerator 248 | Resource.Designer.cs 249 | 250 | 251 | 252 | 253 | true 254 | 255 | 256 | 257 | 264 | -------------------------------------------------------------------------------- /src/JSON_Intellisense.vsct: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/JSON_IntellisensePackage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using EnvDTE; 4 | using EnvDTE80; 5 | using Microsoft.VisualStudio.Shell; 6 | using Microsoft.VisualStudio.Shell.Interop; 7 | 8 | namespace JSON_Intellisense 9 | { 10 | [PackageRegistration(UseManagedResourcesOnly = true)] 11 | [ProvideAutoLoad(UIContextGuids80.SolutionExists)] 12 | [InstalledProductRegistration("#110", "#112", Version, IconResourceID = 400)] 13 | [ProvideMenuResource("Menus.ctmenu", 1)] 14 | [ProvideOptionPage(typeof(Options), "Package Intellisense", "General", 101, 101, true, new[] { "bower, npm, install, restore" })] 15 | [Guid(GuidList.guidJSON_IntellisensePkgString)] 16 | public sealed class JSON_IntellisensePackage : Package 17 | { 18 | public const string Version = "1.6"; 19 | public static Options Options; 20 | 21 | protected override void Initialize() 22 | { 23 | base.Initialize(); 24 | 25 | Events2 events = (Events2)Helper.DTE.Events; 26 | events.SolutionEvents.Opened += SolutionEvents_Opened; 27 | 28 | Options = (Options)GetDialogPage(typeof(Options)); 29 | 30 | // Add our command handlers for menu (commands must exist in the .vsct file) 31 | //OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; 32 | //if (null != mcs) 33 | //{ 34 | // // Create the command for the menu item. 35 | // CommandID menuCommandID = new CommandID(GuidList.guidJSON_IntellisenseCmdSet, (int)PkgCmdIDList.cmdidMyCommand); 36 | // MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID); 37 | // mcs.AddCommand(menuItem); 38 | //} 39 | } 40 | 41 | void SolutionEvents_Opened() 42 | { 43 | try 44 | { 45 | ProjectOpen po = new ProjectOpen(); 46 | po.InstallPackages(Options); 47 | } 48 | catch (Exception ex) 49 | { 50 | Logger.Log(ex.Message); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/NPM/Completion/NpmNameCompletionEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Web; 6 | using Microsoft.JSON.Core.Parser; 7 | using Microsoft.JSON.Editor.Completion; 8 | using Microsoft.VisualStudio.Language.Intellisense; 9 | using Newtonsoft.Json.Linq; 10 | 11 | namespace JSON_Intellisense.NPM 12 | { 13 | class NpmNameCompletionEntry : JSONCompletionEntry 14 | { 15 | private JSONDocument _doc; 16 | internal static IEnumerable _searchResults; 17 | 18 | public NpmNameCompletionEntry(string text, IIntellisenseSession session, JSONDocument doc) 19 | : base(text, "\"" + text + "\"", null, Constants.Icon, null, false, session as ICompletionSession) 20 | { 21 | _doc = doc; 22 | } 23 | 24 | public override void Commit() 25 | { 26 | if (_doc == null) 27 | { 28 | base.Commit(); 29 | } 30 | else 31 | { 32 | string searchTerm = _doc.GetMemberName(base.Session); 33 | 34 | if (string.IsNullOrEmpty(searchTerm)) 35 | return; 36 | 37 | ExecuteSearch(searchTerm); 38 | } 39 | } 40 | 41 | private void ExecuteSearch(string searchTerm) 42 | { 43 | ThreadPool.QueueUserWorkItem(o => 44 | { 45 | string url = string.Format(Constants.SearchUrl, HttpUtility.UrlEncode(searchTerm)); 46 | string result = Helper.DownloadText(url); 47 | var children = GetChildren(result); 48 | 49 | if (!children.Any()) 50 | { 51 | Helper.DTE.StatusBar.Text = string.Format(Resources.text.CompletionNoPackageFound, searchTerm); 52 | base.Session.Dismiss(); 53 | return; 54 | } 55 | 56 | Helper.DTE.StatusBar.Text = string.Empty; 57 | _searchResults = children; 58 | 59 | Helper.ExecuteCommand("Edit.CompleteWord"); 60 | }); 61 | } 62 | 63 | private static IEnumerable GetChildren(string result) 64 | { 65 | try 66 | { 67 | var root = JObject.Parse(result); 68 | var array = (JArray)root["sections"]["packages"]; 69 | 70 | return array.Select(a => a["value"].ToString()); 71 | } 72 | catch (Exception ex) 73 | { 74 | Logger.Log(ex.Message); 75 | return Enumerable.Empty(); 76 | } 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /src/NPM/Completion/NpmNameCompletionProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using Microsoft.JSON.Core.Parser; 4 | using Microsoft.JSON.Editor.Completion; 5 | using Microsoft.JSON.Editor.Completion.Def; 6 | using Microsoft.VisualStudio.Utilities; 7 | 8 | namespace JSON_Intellisense.NPM 9 | { 10 | [Export(typeof(IJSONCompletionListProvider))] 11 | [Name("NpmNameCompletionProvider")] 12 | class NpmNameCompletionProvider : CompletionProviderBase 13 | { 14 | public override JSONCompletionContextType ContextType 15 | { 16 | get { return JSONCompletionContextType.PropertyName; } 17 | } 18 | 19 | public override string SupportedFileName 20 | { 21 | get { return Constants.FileName; } 22 | } 23 | 24 | protected override IEnumerable GetEntries(JSONCompletionContext context) 25 | { 26 | if (NpmNameCompletionEntry._searchResults != null) 27 | { 28 | foreach (string value in NpmNameCompletionEntry._searchResults) 29 | { 30 | yield return new NpmNameCompletionEntry(value, context.Session, null); 31 | } 32 | 33 | NpmNameCompletionEntry._searchResults = null; 34 | } 35 | else 36 | { 37 | JSONMember dependency = GetDependency(context); 38 | 39 | if (dependency != null) 40 | yield return new NpmNameCompletionEntry(Resources.text.CompletionSearch, context.Session, dependency.JSONDocument); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/NPM/Completion/NpmVersionCompletionEntry.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.JSON.Editor.Completion; 2 | using Microsoft.VisualStudio.Language.Intellisense; 3 | 4 | namespace JSON_Intellisense.NPM 5 | { 6 | class NpmVersionCompletionEntry : JSONCompletionEntry 7 | { 8 | public NpmVersionCompletionEntry(string text, string description, IIntellisenseSession session) 9 | : base(text, "\"" + text + "\"", description, Constants.Icon, null, false, session as ICompletionSession) 10 | { } 11 | 12 | public override void Commit() 13 | { 14 | base.Commit(); 15 | Helper.DTE.StatusBar.Text = string.Empty; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/NPM/Completion/NpmVersionCompletionProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using System.Threading; 4 | using Microsoft.JSON.Core.Parser; 5 | using Microsoft.JSON.Editor.Completion; 6 | using Microsoft.JSON.Editor.Completion.Def; 7 | using Microsoft.VisualStudio.Utilities; 8 | 9 | namespace JSON_Intellisense.NPM 10 | { 11 | [Export(typeof(IJSONCompletionListProvider))] 12 | [Name("NpmVersionCompletionProvider")] 13 | class NpmVersionCompletionProvider : CompletionProviderBase 14 | { 15 | internal static string _version; 16 | 17 | public override JSONCompletionContextType ContextType 18 | { 19 | get { return JSONCompletionContextType.PropertyValue; } 20 | } 21 | 22 | public override string SupportedFileName 23 | { 24 | get { return Constants.FileName; } 25 | } 26 | 27 | protected override IEnumerable GetEntries(JSONCompletionContext context) 28 | { 29 | if (_version != null) 30 | { 31 | yield return new NpmVersionCompletionEntry(_version, Resources.text.CompletionVersionLatest, context.Session); 32 | yield return new NpmVersionCompletionEntry("~" + _version, Resources.text.CompletionVersionMinor, context.Session); 33 | yield return new NpmVersionCompletionEntry("^" + _version, Resources.text.CompletionVersionMajor, context.Session); 34 | 35 | _version = null; 36 | } 37 | else 38 | { 39 | JSONMember dependency = GetDependency(context); 40 | 41 | if (dependency != null) 42 | ExecuteRemoteSearch(dependency); 43 | } 44 | } 45 | 46 | private void ExecuteRemoteSearch(JSONMember dependency) 47 | { 48 | ThreadPool.QueueUserWorkItem(o => 49 | { 50 | string package = dependency.Name.Text.Trim('"'); 51 | string url = string.Format(Constants.PackageUrl, package); 52 | string result = Helper.DownloadText(url); 53 | _version = ParseVersion(result); 54 | 55 | if (_version != null) 56 | Helper.ExecuteCommand("Edit.ListMembers"); 57 | }); 58 | } 59 | 60 | private string ParseVersion(string result) 61 | { 62 | var root = Helper.ParseJSON(result); 63 | 64 | if (root != null) 65 | return root.SelectItemText("version"); 66 | 67 | return null; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/NPM/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Media; 3 | using System.Windows.Media.Imaging; 4 | 5 | namespace JSON_Intellisense.NPM 6 | { 7 | static class Constants 8 | { 9 | public const string FileName = "package.json"; 10 | public const string SearchUrl = "https://ac.cnstrc.com/autocomplete/{0}?autocomplete_key=CD06z4gVeqSXRiDL2ZNK";//"https://typeahead.npmjs.com/search?q={0}"; 11 | public const string PackageUrl = "http://registry.npmjs.org/{0}/latest"; 12 | public static ImageSource Icon = BitmapFrame.Create(new Uri("pack://application:,,,/JSON Intellisense;component/NPM/Resources/npm.png", UriKind.RelativeOrAbsolute)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/NPM/NpmPackage.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web; 3 | using Microsoft.JSON.Core.Parser; 4 | 5 | namespace JSON_Intellisense.NPM 6 | { 7 | public class NpmPackage 8 | { 9 | public string Name { get; set; } 10 | public string Description { get; set; } 11 | public string Version { get; set; } 12 | public string Author { get; set; } 13 | public string License { get; set; } 14 | public string Homepage { get; set; } 15 | 16 | public static NpmPackage FromPackageName(string name) 17 | { 18 | try 19 | { 20 | Options options = JSON_IntellisensePackage.Options; 21 | string packageUrl = Constants.PackageUrl; 22 | 23 | if (!string.IsNullOrEmpty(options.NpmCustomFeedUrl)) { 24 | packageUrl = options.NpmCustomFeedUrl; 25 | } 26 | 27 | string url = string.Format(packageUrl, HttpUtility.UrlEncode(name)); 28 | string result = Helper.DownloadText(url); 29 | var root = Helper.ParseJSON(result); 30 | 31 | NpmPackage package = new NpmPackage 32 | { 33 | Name = name, 34 | Description = root.SelectItemText("description"), 35 | Version = root.SelectItemText("version"), 36 | Author = root.SelectItemText("author/name"), 37 | Homepage = root.SelectItemText("homepage"), 38 | }; 39 | 40 | var licenses = root.SelectItem("licenses") as JSONArray; 41 | 42 | if (licenses != null) 43 | { 44 | var obj = licenses.BlockItemChildren.First().Value as JSONObject; 45 | if (obj != null) 46 | package.License = obj.SelectItemText("type"); 47 | } 48 | else 49 | { 50 | package.License = root.SelectItemText("license"); 51 | } 52 | 53 | return package; 54 | } 55 | catch 56 | { /* JSON result is invalid. Ignore */ } 57 | 58 | return null; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/NPM/QuickInfo/NpmInfoBox.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 22 | 23 | -------------------------------------------------------------------------------- /src/NPM/QuickInfo/NpmInfoBox.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace JSON_Intellisense.NPM 4 | { 5 | public partial class NpmInfoBox : UserControl 6 | { 7 | private static NpmInfoBox _box = new NpmInfoBox(); 8 | 9 | public NpmInfoBox() 10 | { 11 | InitializeComponent(); 12 | imgLogo.Source = Constants.Icon; 13 | } 14 | 15 | public static NpmInfoBox Create(NpmPackage package) 16 | { 17 | _box.lblName.Content = package.Name; 18 | _box.lblDesc.Content = package.Description; 19 | _box.lblLatest.Content = package.Version; 20 | _box.lblAuthor.Content = package.Author ?? "n/a"; 21 | _box.lblLicense.Content = package.License ?? "n/a"; 22 | _box.lblHomepage.Content = package.Homepage ?? "n/a"; 23 | 24 | _box.descAuthor.Content = NPM.Resources.text.QuickInfoAuthor + ":"; 25 | _box.descHomepage.Content = NPM.Resources.text.QuickInfoHomepage + ":"; 26 | _box.descLatest.Content = NPM.Resources.text.QuickInfoLatest + ":"; 27 | _box.descLicense.Content = NPM.Resources.text.QuickInfoLicense + ":"; 28 | 29 | _box.AnimateWindowSize(40, 108); 30 | 31 | return _box; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/NPM/QuickInfo/NpmQuickInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web; 3 | using System.Windows; 4 | using Microsoft.JSON.Core.Parser; 5 | using Microsoft.VisualStudio.Text; 6 | 7 | namespace JSON_Intellisense.NPM 8 | { 9 | internal class NpmQuickInfo : QuickInfoSourceBase 10 | { 11 | public NpmQuickInfo(ITextBuffer subjectBuffer) 12 | : base(subjectBuffer) 13 | { } 14 | 15 | public override UIElement CreateTooltip(string name, JSONParseItem item) 16 | { 17 | NpmPackage package = NpmPackage.FromPackageName(name); 18 | 19 | if (package == null) 20 | return null; 21 | 22 | return NpmInfoBox.Create(package); 23 | } 24 | 25 | private NpmPackage GetText(string packageName) 26 | { 27 | string url = string.Format(Constants.PackageUrl, HttpUtility.UrlEncode(packageName)); 28 | string result = Helper.DownloadText(url); 29 | 30 | if (string.IsNullOrEmpty(result)) 31 | return null; 32 | 33 | try 34 | { 35 | var root = Helper.ParseJSON(result); 36 | 37 | NpmPackage package = new NpmPackage 38 | { 39 | Name = packageName, 40 | Description = root.SelectItemText("description"), 41 | Version = root.SelectItemText("version"), 42 | Author = root.SelectItemText("author/name"), 43 | Homepage = root.SelectItemText("homepage"), 44 | }; 45 | 46 | var licenses = root.SelectItem("licenses") as JSONArray; 47 | 48 | if (licenses != null) 49 | { 50 | var obj = licenses.BlockItemChildren.First().Value as JSONObject; 51 | if (obj != null) 52 | package.License = obj.SelectItemText("type"); 53 | } 54 | else 55 | { 56 | package.License = root.SelectItemText("license"); 57 | } 58 | 59 | return package; 60 | } 61 | catch 62 | { /* JSON result is invalid. Ignore */ } 63 | finally 64 | { 65 | Helper.DTE.StatusBar.Text = string.Empty; 66 | } 67 | 68 | return null; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/NPM/Resources/npm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/NPM/Resources/npm.png -------------------------------------------------------------------------------- /src/NPM/Resources/text.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.0 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace JSON_Intellisense.NPM.Resources { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class text { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal text() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("JSON_Intellisense.NPM.Resources.text", typeof(text).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to No packages found matching '{0}'. 65 | /// 66 | internal static string CompletionNoPackageFound { 67 | get { 68 | return ResourceManager.GetString("CompletionNoPackageFound", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to Search npm.... 74 | /// 75 | internal static string CompletionSearch { 76 | get { 77 | return ResourceManager.GetString("CompletionSearch", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// Looks up a localized string similar to The currently latest version of the package. 83 | /// 84 | internal static string CompletionVersionLatest { 85 | get { 86 | return ResourceManager.GetString("CompletionVersionLatest", resourceCulture); 87 | } 88 | } 89 | 90 | /// 91 | /// Looks up a localized string similar to Matches the most recent major version (1.x.x). 92 | /// 93 | internal static string CompletionVersionMajor { 94 | get { 95 | return ResourceManager.GetString("CompletionVersionMajor", resourceCulture); 96 | } 97 | } 98 | 99 | /// 100 | /// Looks up a localized string similar to Matches the most recent minor version (1.2.x). 101 | /// 102 | internal static string CompletionVersionMinor { 103 | get { 104 | return ResourceManager.GetString("CompletionVersionMinor", resourceCulture); 105 | } 106 | } 107 | 108 | /// 109 | /// Looks up a localized string similar to Author. 110 | /// 111 | internal static string QuickInfoAuthor { 112 | get { 113 | return ResourceManager.GetString("QuickInfoAuthor", resourceCulture); 114 | } 115 | } 116 | 117 | /// 118 | /// Looks up a localized string similar to Homepage. 119 | /// 120 | internal static string QuickInfoHomepage { 121 | get { 122 | return ResourceManager.GetString("QuickInfoHomepage", resourceCulture); 123 | } 124 | } 125 | 126 | /// 127 | /// Looks up a localized string similar to Latest. 128 | /// 129 | internal static string QuickInfoLatest { 130 | get { 131 | return ResourceManager.GetString("QuickInfoLatest", resourceCulture); 132 | } 133 | } 134 | 135 | /// 136 | /// Looks up a localized string similar to License. 137 | /// 138 | internal static string QuickInfoLicense { 139 | get { 140 | return ResourceManager.GetString("QuickInfoLicense", resourceCulture); 141 | } 142 | } 143 | 144 | /// 145 | /// Looks up a localized string similar to Install package. 146 | /// 147 | internal static string SmartTagInstallPackage { 148 | get { 149 | return ResourceManager.GetString("SmartTagInstallPackage", resourceCulture); 150 | } 151 | } 152 | 153 | /// 154 | /// Looks up a localized string similar to Open homepage in browser. 155 | /// 156 | internal static string SmartTagNavigateToHomepage { 157 | get { 158 | return ResourceManager.GetString("SmartTagNavigateToHomepage", resourceCulture); 159 | } 160 | } 161 | 162 | /// 163 | /// Looks up a localized string similar to The package's doesn't specify a valid homepage. 164 | /// 165 | internal static string SmartTagNavigateToHomepageError { 166 | get { 167 | return ResourceManager.GetString("SmartTagNavigateToHomepageError", resourceCulture); 168 | } 169 | } 170 | 171 | /// 172 | /// Looks up a localized string similar to Uninstall package. 173 | /// 174 | internal static string SmartTagUninstallPackage { 175 | get { 176 | return ResourceManager.GetString("SmartTagUninstallPackage", resourceCulture); 177 | } 178 | } 179 | 180 | /// 181 | /// Looks up a localized string similar to Update package. 182 | /// 183 | internal static string SmartTagUpdatePackage { 184 | get { 185 | return ResourceManager.GetString("SmartTagUpdatePackage", resourceCulture); 186 | } 187 | } 188 | 189 | /// 190 | /// Looks up a localized string similar to Installing package.... 191 | /// 192 | internal static string statusbarInstalling { 193 | get { 194 | return ResourceManager.GetString("statusbarInstalling", resourceCulture); 195 | } 196 | } 197 | 198 | /// 199 | /// Looks up a localized string similar to Uninstalling package.... 200 | /// 201 | internal static string statusbarUninstalling { 202 | get { 203 | return ResourceManager.GetString("statusbarUninstalling", resourceCulture); 204 | } 205 | } 206 | 207 | /// 208 | /// Looks up a localized string similar to Updating package.... 209 | /// 210 | internal static string statusbarUpdating { 211 | get { 212 | return ResourceManager.GetString("statusbarUpdating", resourceCulture); 213 | } 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/NPM/Resources/text.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 | No packages found matching '{0}' 122 | 123 | 124 | Search npm... 125 | 126 | 127 | The currently latest version of the package 128 | 129 | 130 | Matches the most recent major version (1.x.x) 131 | 132 | 133 | Matches the most recent minor version (1.2.x) 134 | 135 | 136 | Author 137 | 138 | 139 | Homepage 140 | 141 | 142 | Latest 143 | 144 | 145 | License 146 | 147 | 148 | Install package 149 | 150 | 151 | Open homepage in browser 152 | 153 | 154 | The package's doesn't specify a valid homepage 155 | 156 | 157 | Uninstall package 158 | 159 | 160 | Update package 161 | 162 | 163 | Installing package... 164 | 165 | 166 | Uninstalling package... 167 | 168 | 169 | Updating package... 170 | 171 | -------------------------------------------------------------------------------- /src/NPM/SmartTags/NpmInstallPackage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using System.IO; 4 | using Microsoft.JSON.Core.Parser; 5 | using Microsoft.VisualStudio.Language.Intellisense; 6 | using Microsoft.VisualStudio.Text; 7 | using Microsoft.VisualStudio.Utilities; 8 | 9 | namespace JSON_Intellisense.NPM 10 | { 11 | [Export(typeof(IJSONSmartTagProvider))] 12 | [Name("Npm Install Package")] 13 | [Order(After = "NPM Update Package")] 14 | class InstallPackageProvider : JSONSmartTagProviderBase 15 | { 16 | public override string SupportedFileName 17 | { 18 | get { return Constants.FileName; } 19 | } 20 | 21 | public override IEnumerable GetSmartTagActions(JSONMember item, ITextBuffer buffer) 22 | { 23 | string directory = Path.GetDirectoryName(buffer.GetFileName()); 24 | string node_module = Path.Combine(directory, "node_modules", item.UnquotedNameText); 25 | 26 | if (item.Value != null && item.Value.Text.Trim('"').Length > 0 && !Directory.Exists(node_module)) 27 | yield return new InstallPackageAction(item, directory); 28 | } 29 | } 30 | 31 | internal class InstallPackageAction : JSONSmartTagActionBase 32 | { 33 | private JSONMember _item; 34 | private string _directory; 35 | 36 | public InstallPackageAction(JSONMember item, string directory) 37 | { 38 | _item = item; 39 | _directory = directory; 40 | Icon = Globals.InstallIcon; 41 | } 42 | 43 | public override string DisplayText 44 | { 45 | get { return Resources.text.SmartTagInstallPackage; } 46 | } 47 | 48 | public override void Invoke() 49 | { 50 | Helper.SaveDocument(); 51 | string command = "npm install " + _item.UnquotedNameText; 52 | Helper.RunProcess(command, _directory, Resources.text.statusbarInstalling); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/NPM/SmartTags/NpmNavigateToHomepage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.Composition; 4 | using System.Windows.Forms; 5 | using Microsoft.JSON.Core.Parser; 6 | using Microsoft.VisualStudio.Language.Intellisense; 7 | using Microsoft.VisualStudio.Text; 8 | using Microsoft.VisualStudio.Utilities; 9 | 10 | namespace JSON_Intellisense.NPM 11 | { 12 | [Export(typeof(IJSONSmartTagProvider))] 13 | [Name("NPM Navigate To Homepage")] 14 | [Order(Before = "NPM Update Package")] 15 | class NavigateToHomepageProvider : JSONSmartTagProviderBase 16 | { 17 | public override string SupportedFileName 18 | { 19 | get { return Constants.FileName; } 20 | } 21 | 22 | public override IEnumerable GetSmartTagActions(JSONMember item, ITextBuffer buffer) 23 | { 24 | yield return new NavigateToHomePageAction(item.UnquotedNameText); 25 | } 26 | } 27 | 28 | internal class NavigateToHomePageAction : JSONSmartTagActionBase 29 | { 30 | private string _name; 31 | 32 | public NavigateToHomePageAction(string name) 33 | { 34 | _name = name; 35 | Icon = Globals.BrowseIcon; 36 | } 37 | 38 | public override string DisplayText 39 | { 40 | get { return Resources.text.SmartTagNavigateToHomepage; } 41 | } 42 | 43 | public override void Invoke() 44 | { 45 | NpmPackage package = NpmPackage.FromPackageName(_name); 46 | 47 | Uri url; 48 | 49 | if (package != null && Uri.TryCreate(package.Homepage, UriKind.Absolute, out url)) 50 | { 51 | System.Diagnostics.Process.Start(url.ToString()); 52 | } 53 | else 54 | { 55 | MessageBox.Show(Resources.text.SmartTagNavigateToHomepageError, Globals.VsixName, MessageBoxButtons.OK, MessageBoxIcon.Hand); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/NPM/SmartTags/NpmUninstallPackage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using System.IO; 4 | using Microsoft.JSON.Core.Parser; 5 | using Microsoft.VisualStudio.Language.Intellisense; 6 | using Microsoft.VisualStudio.Text; 7 | using Microsoft.VisualStudio.Utilities; 8 | 9 | namespace JSON_Intellisense.NPM 10 | { 11 | [Export(typeof(IJSONSmartTagProvider))] 12 | [Name("Npm Uninstall Package")] 13 | [Order(After = "NPM Update Package")] 14 | class UninstallPackageProvider : JSONSmartTagProviderBase 15 | { 16 | public override string SupportedFileName 17 | { 18 | get { return Constants.FileName; } 19 | } 20 | 21 | public override IEnumerable GetSmartTagActions(JSONMember item, ITextBuffer buffer) 22 | { 23 | string directory = Path.GetDirectoryName(buffer.GetFileName()); 24 | 25 | if (item.Value != null && item.Value.Text.Trim('"').Length > 0) 26 | yield return new UninstallPackageAction(item, directory, buffer); 27 | } 28 | } 29 | 30 | internal class UninstallPackageAction : JSONSmartTagActionBase 31 | { 32 | private JSONMember _item; 33 | private string _directory; 34 | private ITextBuffer _buffer; 35 | 36 | public UninstallPackageAction(JSONMember item, string directory, ITextBuffer buffer) 37 | { 38 | _item = item; 39 | _directory = directory; 40 | _buffer = buffer; 41 | Icon = Globals.UninstallIcon; 42 | } 43 | 44 | public override string DisplayText 45 | { 46 | get { return Resources.text.SmartTagUninstallPackage; } 47 | } 48 | 49 | public override void Invoke() 50 | { 51 | string command = "npm uninstall " + _item.UnquotedNameText; 52 | Helper.RunProcess(command, _directory, Resources.text.statusbarUninstalling, Helper.SaveDocument); 53 | 54 | Helper.DTE.UndoContext.Open(Resources.text.SmartTagUninstallPackage); 55 | _item.DeletePackageMember(_buffer); 56 | Helper.DTE.UndoContext.Close(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/NPM/SmartTags/NpmUpdatePackage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using System.IO; 4 | using Microsoft.JSON.Core.Parser; 5 | using Microsoft.VisualStudio.Language.Intellisense; 6 | using Microsoft.VisualStudio.Text; 7 | using Microsoft.VisualStudio.Utilities; 8 | 9 | namespace JSON_Intellisense.NPM 10 | { 11 | [Export(typeof(IJSONSmartTagProvider))] 12 | [Name("NPM Update Package")] 13 | class UpdatePackageProvider : JSONSmartTagProviderBase 14 | { 15 | public override string SupportedFileName 16 | { 17 | get { return Constants.FileName; } 18 | } 19 | 20 | public override IEnumerable GetSmartTagActions(JSONMember item, ITextBuffer buffer) 21 | { 22 | string directory = Path.GetDirectoryName(buffer.GetFileName()); 23 | string node_module = Path.Combine(directory, "node_modules", item.UnquotedNameText); 24 | 25 | if (item.Value != null && item.Value.Text.Trim('"').Length > 0 && Directory.Exists(node_module)) 26 | yield return new UpdatePackageAction(item.UnquotedNameText, directory); 27 | } 28 | } 29 | 30 | internal class UpdatePackageAction : JSONSmartTagActionBase 31 | { 32 | private string _name; 33 | private string _directory; 34 | 35 | public UpdatePackageAction(string name, string directory) 36 | { 37 | _name = name; 38 | _directory = directory; 39 | Icon = Globals.UpdateIcon; 40 | } 41 | 42 | public override string DisplayText 43 | { 44 | get { return Resources.text.SmartTagUpdatePackage; } 45 | } 46 | 47 | public override void Invoke() 48 | { 49 | string command = "npm update " + _name; 50 | Helper.RunProcess(command, _directory, Resources.text.statusbarUpdating); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/PkgCmdID.cs: -------------------------------------------------------------------------------- 1 | // PkgCmdID.cs 2 | // MUST match PkgCmdID.h 3 | using System; 4 | 5 | namespace JSON_Intellisense 6 | { 7 | static class PkgCmdIDList 8 | { 9 | public const uint cmdidMyCommand = 0x100; 10 | }; 11 | } -------------------------------------------------------------------------------- /src/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Resources; 4 | using System.Runtime.InteropServices; 5 | using JSON_Intellisense; 6 | 7 | [assembly: AssemblyTitle("Package Intellisense")] 8 | [assembly: AssemblyDescription("Search for online NPM and Bower packages directly within Intellisense")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Mads Kristensen")] 11 | [assembly: AssemblyProduct("Package Intellisense")] 12 | [assembly: AssemblyCopyright("")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | [assembly: ComVisible(false)] 16 | [assembly: CLSCompliant(false)] 17 | [assembly: NeutralResourcesLanguage("en-US")] 18 | 19 | [assembly: AssemblyVersion(JSON_IntellisensePackage.Version)] 20 | [assembly: AssemblyFileVersion(JSON_IntellisensePackage.Version)] -------------------------------------------------------------------------------- /src/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 | Extension Updater 133 | 134 | 135 | Configure Visual Studio to automatically install updates to the extensions you are using 136 | 137 | 138 | _Shared\Resources\Package.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 139 | 140 | -------------------------------------------------------------------------------- /src/_Shared/Adornments/LogoAdornment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Controls; 3 | using System.Windows.Media; 4 | using System.Windows.Media.Imaging; 5 | using JSON_Intellisense._Shared.Resources; 6 | using Microsoft.VisualStudio.Text.Editor; 7 | 8 | namespace JSON_Intellisense 9 | { 10 | class LogoAdornment 11 | { 12 | private IAdornmentLayer _adornmentLayer; 13 | private Image _adornment; 14 | private readonly double _initOpacity; 15 | private double _currentOpacity; 16 | 17 | public LogoAdornment(IWpfTextView view, string imageName, bool isVisible, double initOpacity) 18 | { 19 | _adornmentLayer = view.GetAdornmentLayer(LogoLayer.LayerName); 20 | _currentOpacity = isVisible ? _initOpacity : 0; 21 | _initOpacity = initOpacity; 22 | 23 | CreateImage(imageName); 24 | 25 | view.ViewportHeightChanged += SetAdornmentLocation; 26 | view.ViewportWidthChanged += SetAdornmentLocation; 27 | VisibilityChanged += ToggleVisibility; 28 | 29 | if (_adornmentLayer.IsEmpty) 30 | _adornmentLayer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative, null, null, _adornment, null); 31 | } 32 | 33 | private void ToggleVisibility(object sender, bool isVisible) 34 | { 35 | _adornment.Opacity = isVisible ? _initOpacity : 0; 36 | _currentOpacity = _adornment.Opacity; 37 | } 38 | 39 | private void CreateImage(string imageName) 40 | { 41 | _adornment = new Image(); 42 | _adornment.Source = BitmapFrame.Create(new Uri("pack://application:,,,/JSON Intellisense;component/_Shared/Resources/Watermarks/" + imageName, UriKind.RelativeOrAbsolute)); 43 | _adornment.ToolTip = Resource.ClickToToggleVisibility; 44 | _adornment.Opacity = _currentOpacity; 45 | _adornment.SetValue(RenderOptions.BitmapScalingModeProperty, BitmapScalingMode.HighQuality); 46 | 47 | _adornment.MouseEnter += (s, e) => { _adornment.Opacity = 1D; }; 48 | _adornment.MouseLeave += (s, e) => { _adornment.Opacity = _currentOpacity; }; 49 | _adornment.MouseLeftButtonUp += (s, e) => { OnVisibilityChanged(_currentOpacity == 0); }; 50 | } 51 | 52 | private void SetAdornmentLocation(object sender, EventArgs e) 53 | { 54 | IWpfTextView view = (IWpfTextView)sender; 55 | Canvas.SetLeft(_adornment, view.ViewportRight - _adornment.Source.Width - 20); 56 | Canvas.SetTop(_adornment, view.ViewportBottom - _adornment.Source.Height - 20); 57 | } 58 | 59 | public static event EventHandler VisibilityChanged; 60 | 61 | private static void OnVisibilityChanged(bool isVisible) 62 | { 63 | if (VisibilityChanged != null) 64 | VisibilityChanged(null, isVisible); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/_Shared/Adornments/LogoLayer.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.Composition; 2 | using Microsoft.VisualStudio.Text.Editor; 3 | using Microsoft.VisualStudio.Utilities; 4 | 5 | namespace JSON_Intellisense 6 | { 7 | class LogoLayer 8 | { 9 | public const string LayerName = "JSON Logo"; 10 | 11 | [Export(typeof(AdornmentLayerDefinition))] 12 | [Name(LayerName)] 13 | [Order(After = PredefinedAdornmentLayers.Caret)] 14 | public AdornmentLayerDefinition editorAdornmentLayer = null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/_Shared/Adornments/LogoProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using System.IO; 4 | using Microsoft.VisualStudio.Settings; 5 | using Microsoft.VisualStudio.Shell; 6 | using Microsoft.VisualStudio.Shell.Settings; 7 | using Microsoft.VisualStudio.Text; 8 | using Microsoft.VisualStudio.Text.Editor; 9 | using Microsoft.VisualStudio.Utilities; 10 | 11 | namespace JSON_Intellisense 12 | { 13 | [Export(typeof(IWpfTextViewCreationListener))] 14 | [ContentType("json")] 15 | [ContentType("javascript")] 16 | [TextViewRole(PredefinedTextViewRoles.Document)] 17 | class LogoProvider : IWpfTextViewCreationListener 18 | { 19 | private const string _propertyName = "ShowWatermark"; 20 | private const double _initOpacity = 0.4D; 21 | 22 | private static bool _isVisible, _hasLoaded; 23 | private static readonly Dictionary _map = new Dictionary() 24 | { 25 | { "bower.json", "bower.png"}, 26 | { "package.json", "npm.png"}, 27 | { "gruntfile.js", "grunt.png"}, 28 | { "gulpfile.js", "gulp.png"}, 29 | }; 30 | 31 | [Import] 32 | public ITextDocumentFactoryService TextDocumentFactoryService { get; set; } 33 | 34 | [Import] 35 | public SVsServiceProvider serviceProvider { get; set; } 36 | 37 | private void LoadSettings() 38 | { 39 | _hasLoaded = true; 40 | 41 | SettingsManager settingsManager = new ShellSettingsManager(serviceProvider); 42 | SettingsStore store = settingsManager.GetReadOnlySettingsStore(SettingsScope.UserSettings); 43 | 44 | LogoAdornment.VisibilityChanged += (sender, isVisible) => 45 | { 46 | WritableSettingsStore wstore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings); 47 | _isVisible = isVisible; 48 | 49 | if (!wstore.CollectionExists(Globals.VsixName)) 50 | wstore.CreateCollection(Globals.VsixName); 51 | 52 | wstore.SetBoolean(Globals.VsixName, _propertyName, isVisible); 53 | }; 54 | 55 | _isVisible = store.GetBoolean(Globals.VsixName, _propertyName, true); 56 | } 57 | 58 | public void TextViewCreated(IWpfTextView textView) 59 | { 60 | if (!_hasLoaded) 61 | LoadSettings(); 62 | 63 | ITextDocument document; 64 | if (TextDocumentFactoryService.TryGetTextDocument(textView.TextDataModel.DocumentBuffer, out document)) 65 | { 66 | string fileName = Path.GetFileName(document.FilePath).ToLowerInvariant(); 67 | 68 | if (string.IsNullOrEmpty(fileName) || !_map.ContainsKey(fileName)) 69 | return; 70 | 71 | LogoAdornment highlighter = new LogoAdornment(textView, _map[fileName], _isVisible, _initOpacity); 72 | } 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /src/_Shared/Completion/CompletionProviderBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.JSON.Core.Parser; 4 | using Microsoft.JSON.Editor.Completion; 5 | using Microsoft.JSON.Editor.Completion.Def; 6 | 7 | namespace JSON_Intellisense 8 | { 9 | public abstract class CompletionProviderBase : IJSONCompletionListProvider 10 | { 11 | public abstract JSONCompletionContextType ContextType { get; } 12 | 13 | public abstract string SupportedFileName { get; } 14 | 15 | public IEnumerable GetListEntries(JSONCompletionContext context) 16 | { 17 | if (!Helper.IsSupportedFile(SupportedFileName)) 18 | return new List(); 19 | 20 | return GetEntries(context); 21 | } 22 | 23 | protected abstract IEnumerable GetEntries(JSONCompletionContext context); 24 | 25 | protected JSONMember GetDependency(JSONCompletionContext context) 26 | { 27 | JSONMember dependency = context.ContextItem.FindType(); 28 | JSONMember parent = dependency.Parent.FindType(); 29 | 30 | if (parent == null || !parent.UnquotedNameText.EndsWith("dependencies", StringComparison.OrdinalIgnoreCase)) 31 | return null; 32 | 33 | if (dependency.UnquotedNameText.Length == 0) 34 | return null; 35 | 36 | return dependency; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/_Shared/Events/FileSaved.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.Composition; 3 | using System.IO; 4 | using System.Threading; 5 | using JSON_Intellisense._Shared.Resources; 6 | using Microsoft.VisualStudio.Text; 7 | using Microsoft.VisualStudio.Text.Editor; 8 | using Microsoft.VisualStudio.Utilities; 9 | 10 | namespace JSON_Intellisense 11 | { 12 | [Export(typeof(IWpfTextViewCreationListener))] 13 | [ContentType("JSON")] 14 | [TextViewRole(PredefinedTextViewRoles.Document)] 15 | class FileSaved : IWpfTextViewCreationListener 16 | { 17 | ITextDocument _document; 18 | 19 | [Import] 20 | public ITextDocumentFactoryService TextDocumentFactoryService { get; set; } 21 | 22 | public void TextViewCreated(IWpfTextView textView) 23 | { 24 | if (TextDocumentFactoryService.TryGetTextDocument(textView.TextDataModel.DocumentBuffer, out _document)) 25 | { 26 | _document.FileActionOccurred += OnSave; 27 | } 28 | 29 | textView.Closed += OnViewClosed; 30 | } 31 | 32 | private void OnSave(object sender, TextDocumentFileActionEventArgs e) 33 | { 34 | if (e.FileActionType != FileActionTypes.ContentSavedToDisk || Helper.IsSaving) 35 | return; 36 | 37 | string fileName = Path.GetFileName(e.FilePath); 38 | 39 | if (!fileName.Equals(NPM.Constants.FileName) && !fileName.Equals(Bower.Constants.FileName)) 40 | return; 41 | 42 | Options options = JSON_IntellisensePackage.Options; 43 | 44 | if (!options.NpmInstallOnSave && !options.BowerInstallOnSave) 45 | return; 46 | 47 | string rootFolder = Path.GetDirectoryName(e.FilePath); 48 | 49 | RestorePackages(fileName, options, rootFolder); 50 | } 51 | 52 | private static void RestorePackages(string fileName, Options options, string rootFolder) 53 | { 54 | ThreadPool.QueueUserWorkItem((o) => 55 | { 56 | try 57 | { 58 | Helper.DTE.StatusBar.Animate(true, EnvDTE.vsStatusAnimation.vsStatusAnimationSync); 59 | 60 | if (fileName.Equals(NPM.Constants.FileName) && options.NpmInstallOnSave) 61 | Helper.RunProcessSync("npm install", rootFolder, Resource.RunningNpmRestore, false); 62 | else if (fileName.Equals(Bower.Constants.FileName) && options.BowerInstallOnSave) 63 | Helper.RunProcessSync("bower install", rootFolder, Resource.RunningNpmRestore, false); 64 | 65 | Helper.DTE.StatusBar.Text = Resource.PackageRestoreComplete; 66 | } 67 | catch (Exception ex) 68 | { 69 | Logger.Log(ex.Message); 70 | Helper.DTE.StatusBar.Text = Resource.ErrorRestoringPackages; 71 | } 72 | finally 73 | { 74 | Helper.DTE.StatusBar.Animate(false, EnvDTE.vsStatusAnimation.vsStatusAnimationSync); 75 | } 76 | }); 77 | } 78 | 79 | private void OnViewClosed(object sender, EventArgs e) 80 | { 81 | IWpfTextView view = (IWpfTextView)sender; 82 | 83 | if (_document != null) 84 | { 85 | _document.FileActionOccurred -= OnSave; 86 | _document = null; 87 | } 88 | 89 | if (view != null) 90 | { 91 | view.Closed -= OnViewClosed; 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/_Shared/Events/ProjectOpen.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Threading; 7 | using EnvDTE; 8 | using JSON_Intellisense._Shared.Resources; 9 | 10 | namespace JSON_Intellisense 11 | { 12 | class ProjectOpen 13 | { 14 | public void InstallPackages(Options options) 15 | { 16 | if (!options.BowerInstallOnOpen && !options.NpmInstallOnOpen) 17 | return; 18 | 19 | var projects = GetProjects(); 20 | List _dupeCache = new List(); 21 | 22 | foreach (Project project in projects) 23 | { 24 | string projectFolder = GetRootFolder(project); 25 | 26 | if (string.IsNullOrEmpty(projectFolder) || !Directory.Exists(projectFolder)) 27 | continue; 28 | 29 | string package = GetFileName(Path.Combine(projectFolder, NPM.Constants.FileName)); 30 | string bower = GetFileName(Path.Combine(projectFolder, Bower.Constants.FileName)); 31 | bool npmExist = File.Exists(package); 32 | bool bowerExist = File.Exists(bower); 33 | 34 | if (!npmExist && !bowerExist) 35 | continue; 36 | 37 | ThreadPool.QueueUserWorkItem(o => 38 | { 39 | try 40 | { 41 | Helper.DTE.StatusBar.Animate(true, EnvDTE.vsStatusAnimation.vsStatusAnimationSync); 42 | 43 | if (options.BowerInstallOnOpen && bowerExist && !_dupeCache.Contains(bower)) 44 | { 45 | _dupeCache.Add(bower); 46 | Helper.RunProcessSync("bower install", Path.GetDirectoryName(bower), Resource.RunningBowerRestore, false); 47 | } 48 | 49 | if (options.NpmInstallOnOpen && npmExist && !_dupeCache.Contains(package)) 50 | { 51 | _dupeCache.Add(package); 52 | Helper.RunProcessSync("npm install", Path.GetDirectoryName(package), Resource.RunningNpmRestore, false); 53 | } 54 | 55 | Helper.DTE.StatusBar.Text = Resource.PackageRestoreComplete; 56 | } 57 | catch (Exception) 58 | { 59 | Helper.DTE.StatusBar.Text = Resource.ErrorRestoringPackages; 60 | } 61 | finally 62 | { 63 | Helper.DTE.StatusBar.Animate(false, EnvDTE.vsStatusAnimation.vsStatusAnimationSync); 64 | } 65 | }); 66 | } 67 | } 68 | 69 | private static string GetFileName(string fileName) 70 | { 71 | try 72 | { 73 | if (File.Exists(fileName)) 74 | return fileName; 75 | 76 | DirectoryInfo directory = new DirectoryInfo(Path.GetDirectoryName(fileName)); 77 | if (directory.Parent == null) 78 | return fileName; 79 | 80 | string parent = Path.Combine(directory.Parent.FullName, Path.GetFileName(fileName)); 81 | return GetFileName(parent); 82 | } 83 | catch (Exception ex) 84 | { 85 | Logger.Log(ex.Message); 86 | return fileName; 87 | } 88 | } 89 | 90 | private IEnumerable GetProjects() 91 | { 92 | return Helper.DTE.Solution.Projects 93 | .Cast() 94 | .SelectMany(GetChildProjects) 95 | .Union(Helper.DTE.Solution.Projects.Cast()) 96 | .Where(p => { try { return !string.IsNullOrEmpty(p.FullName); } catch { return false; } }); 97 | } 98 | 99 | private static IEnumerable GetChildProjects(Project parent) 100 | { 101 | try 102 | { 103 | if (parent.Kind != "{66A26720-8FB5-11D2-AA7E-00C04F688DDE}" && parent.Collection == null) // Unloaded 104 | return Enumerable.Empty(); 105 | 106 | if (!string.IsNullOrEmpty(parent.FullName)) 107 | return new[] { parent }; 108 | } 109 | catch (COMException) 110 | { 111 | return Enumerable.Empty(); 112 | } 113 | 114 | return parent.ProjectItems 115 | .Cast() 116 | .Where(p => p.SubProject != null) 117 | .SelectMany(p => GetChildProjects(p.SubProject)); 118 | } 119 | 120 | public static string GetRootFolder(Project project) 121 | { 122 | try 123 | { 124 | if (string.IsNullOrEmpty(project.FullName)) 125 | return null; 126 | 127 | string fullPath; 128 | 129 | try 130 | { 131 | fullPath = project.Properties.Item("FullPath").Value as string; 132 | } 133 | catch (ArgumentException) 134 | { 135 | try 136 | { 137 | // MFC projects don't have FullPath, and there seems to be no way to query existence 138 | fullPath = project.Properties.Item("ProjectDirectory").Value as string; 139 | } 140 | catch (ArgumentException) 141 | { 142 | // Installer projects have a ProjectPath. 143 | fullPath = project.Properties.Item("ProjectPath").Value as string; 144 | } 145 | } 146 | 147 | if (String.IsNullOrEmpty(fullPath)) 148 | return File.Exists(project.FullName) ? Path.GetDirectoryName(project.FullName) : ""; 149 | 150 | if (Directory.Exists(fullPath)) 151 | return fullPath; 152 | 153 | if (File.Exists(fullPath)) 154 | return Path.GetDirectoryName(fullPath); 155 | 156 | return null; 157 | } 158 | catch (Exception) 159 | { 160 | return null; 161 | } 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /src/_Shared/Globals.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Media; 3 | using System.Windows.Media.Imaging; 4 | 5 | namespace JSON_Intellisense 6 | { 7 | static class Globals 8 | { 9 | public static ImageSource InstallIcon = BitmapFrame.Create(new Uri("pack://application:,,,/JSON Intellisense;component/_Shared/Resources/install.png", UriKind.RelativeOrAbsolute)); 10 | public static ImageSource UpdateIcon = BitmapFrame.Create(new Uri("pack://application:,,,/JSON Intellisense;component/_Shared/Resources/update.png", UriKind.RelativeOrAbsolute)); 11 | public static ImageSource UninstallIcon = BitmapFrame.Create(new Uri("pack://application:,,,/JSON Intellisense;component/_Shared/Resources/uninstall.png", UriKind.RelativeOrAbsolute)); 12 | public static ImageSource BrowseIcon = BitmapFrame.Create(new Uri("pack://application:,,,/JSON Intellisense;component/_Shared/Resources/browse.png", UriKind.RelativeOrAbsolute)); 13 | public const string VsixName = "Package Intellisense"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/_Shared/Helper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | using System.Windows.Media.Animation; 11 | using EnvDTE80; 12 | using Microsoft.CSS.Core; 13 | using Microsoft.JSON.Core.Parser; 14 | using Microsoft.VisualStudio.Shell; 15 | using Microsoft.VisualStudio.Shell.Interop; 16 | using Microsoft.VisualStudio.TextManager.Interop; 17 | using Microsoft.VisualStudio.Utilities; 18 | using Microsoft.Web.Editor; 19 | 20 | namespace JSON_Intellisense 21 | { 22 | static class Helper 23 | { 24 | public static DTE2 DTE = Package.GetGlobalService(typeof(EnvDTE.DTE)) as DTE2; 25 | public static bool IsSaving; 26 | 27 | public static JSONBlockItem ParseJSON(string document) 28 | { 29 | if (string.IsNullOrEmpty(document)) 30 | return null; 31 | 32 | JSONTree tree = new JSONTree(); 33 | 34 | try 35 | { 36 | tree.TextProvider = new StringTextProvider(document); 37 | var child = tree.JSONDocument.Children.First(); 38 | 39 | var obj = child as JSONBlockItem; 40 | if (obj != null) 41 | return obj; 42 | 43 | var arr = child as JSONArray; 44 | if (arr != null) 45 | return arr; 46 | } 47 | catch (Exception) 48 | { } 49 | 50 | return null; 51 | } 52 | 53 | public static void ExecuteCommand(string commandName) 54 | { 55 | var command = DTE.Commands.Item(commandName); 56 | if (command.IsAvailable) 57 | { 58 | DTE.ExecuteCommand(command.Name); 59 | } 60 | } 61 | 62 | public static bool IsSupportedFile(string allowedName) 63 | { 64 | var doc = DTE.ActiveDocument; 65 | 66 | if (doc == null || string.IsNullOrEmpty(doc.FullName) || Path.GetFileName(doc.FullName) != allowedName) 67 | return false; 68 | 69 | return true; 70 | } 71 | 72 | public static string DownloadText(string url) 73 | { 74 | try 75 | { 76 | using (WebClient client = new WebClient()) 77 | { 78 | return client.DownloadString(url); 79 | } 80 | } 81 | catch (Exception) 82 | { /* Can't download. Just ignore */ } 83 | 84 | return null; 85 | } 86 | 87 | public static void AnimateWindowSize(this UserControl target, double oldHeight, double newHeight) 88 | { 89 | target.Height = oldHeight; 90 | target.BeginAnimation(UserControl.HeightProperty, null); 91 | 92 | Storyboard sb = new Storyboard(); 93 | 94 | var aniHeight = new DoubleAnimationUsingKeyFrames(); 95 | aniHeight.Duration = new Duration(new TimeSpan(0, 0, 0, 2)); 96 | aniHeight.KeyFrames.Add(new EasingDoubleKeyFrame(target.Height, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 1)))); 97 | aniHeight.KeyFrames.Add(new EasingDoubleKeyFrame(newHeight, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 1, 200)))); 98 | 99 | Storyboard.SetTarget(aniHeight, target); 100 | Storyboard.SetTargetProperty(aniHeight, new PropertyPath(UserControl.HeightProperty)); 101 | 102 | sb.Children.Add(aniHeight); 103 | 104 | sb.Begin(); 105 | } 106 | 107 | public static string GetFileName(this IPropertyOwner owner) 108 | { 109 | IVsTextBuffer bufferAdapter; 110 | 111 | if (!owner.Properties.TryGetProperty(typeof(IVsTextBuffer), out bufferAdapter)) 112 | return null; 113 | 114 | var persistFileFormat = bufferAdapter as IPersistFileFormat; 115 | string ppzsFilename = null; 116 | uint pnFormatIndex; 117 | int returnCode = -1; 118 | 119 | if (persistFileFormat != null) 120 | { 121 | try 122 | { 123 | returnCode = persistFileFormat.GetCurFile(out ppzsFilename, out pnFormatIndex); 124 | } 125 | catch (NotImplementedException) 126 | { 127 | return null; 128 | } 129 | } 130 | 131 | if (returnCode != VSConstants.S_OK) 132 | return null; 133 | 134 | return ppzsFilename; 135 | } 136 | 137 | public static void RunProcess(string arguments, string directory, string statusbar, Action callback = null) 138 | { 139 | ThreadPool.QueueUserWorkItem(o => 140 | { 141 | try 142 | { 143 | RunProcessSync(arguments, directory, statusbar, true); 144 | 145 | if (callback != null) 146 | callback(); 147 | } 148 | catch { /* Ignore any failure */ } 149 | }); 150 | } 151 | 152 | public static void SaveDocument() 153 | { 154 | IsSaving = true; 155 | var doc = DTE.ActiveDocument; 156 | 157 | if (doc != null) 158 | doc.Save(); 159 | 160 | IsSaving = false; 161 | } 162 | 163 | public static void RunProcessSync(string arguments, string directory, string statusbar, bool clearStatus) 164 | { 165 | DTE.StatusBar.Text = statusbar; 166 | 167 | ProcessStartInfo start = new ProcessStartInfo("cmd", "/c " + arguments) 168 | { 169 | UseShellExecute = false, 170 | CreateNoWindow = true, 171 | ErrorDialog = false, 172 | WorkingDirectory = directory, 173 | RedirectStandardOutput = true, 174 | RedirectStandardError = true, 175 | StandardOutputEncoding = Encoding.UTF8, 176 | StandardErrorEncoding = Encoding.UTF8, 177 | }; 178 | 179 | using (Process p = new Process()) 180 | { 181 | p.StartInfo = start; 182 | p.EnableRaisingEvents = true; 183 | p.OutputDataReceived += DataReceived; 184 | p.ErrorDataReceived += DataReceived; 185 | 186 | p.Start(); 187 | p.BeginOutputReadLine(); 188 | p.BeginErrorReadLine(); 189 | p.WaitForExit(); 190 | } 191 | 192 | if (clearStatus) 193 | DTE.StatusBar.Clear(); 194 | } 195 | 196 | static void DataReceived(object sender, DataReceivedEventArgs e) 197 | { 198 | if (e == null || string.IsNullOrEmpty(e.Data)) 199 | return; 200 | 201 | Logger.Log(e.Data); 202 | } 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/_Shared/JSONExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.JSON.Core.Parser; 3 | using Microsoft.VisualStudio.Language.Intellisense; 4 | using Microsoft.VisualStudio.Text; 5 | 6 | namespace JSON_Intellisense 7 | { 8 | static class JSONExtensions 9 | { 10 | public static string GetMemberName(this JSONDocument doc, ICompletionSession session) 11 | { 12 | if (session == null || doc == null) 13 | return null; 14 | 15 | JSONParseItem member = doc.ItemBeforePosition(session.TextView.Caret.Position.BufferPosition.Position); 16 | 17 | if (member != null) 18 | return member.Text.Trim('"'); 19 | 20 | return null; 21 | } 22 | 23 | public static string SelectItemText(this JSONBlockItem block, string selector) 24 | { 25 | JSONParseItem item = SelectItem(block, selector); 26 | 27 | if (item != null) 28 | { 29 | string text = item.Text.Replace("\\\"", "\""); 30 | return text.Substring(1, text.Length - 2); 31 | } 32 | return string.Empty; 33 | } 34 | 35 | public static JSONParseItem SelectItem(this JSONBlockItem block, string selector) 36 | { 37 | string[] paths = selector.Split('/'); 38 | string path = paths[0]; 39 | 40 | var items = from b in block.BlockItemChildren 41 | let m = b as JSONMember 42 | where m != null && m.UnquotedNameText == path 43 | select m.Value; 44 | 45 | JSONParseItem item = items.ElementAtOrDefault(0); 46 | 47 | JSONObject obj = item as JSONObject; 48 | 49 | if (obj != null) 50 | return SelectItem(obj, string.Join("/", paths.Skip(1))); 51 | 52 | return item; 53 | } 54 | 55 | public static void DeletePackageMember(this JSONMember item, ITextBuffer buffer) 56 | { 57 | if (item.NextSibling != null && item.NextSibling.Text == "}" && item.PreviousSibling != null) 58 | { 59 | JSONMember prev = item.PreviousSibling as JSONMember; 60 | 61 | if (prev != null && prev.Comma != null) 62 | { 63 | Span comma = new Span(prev.Comma.Start, prev.Comma.Length); 64 | buffer.Delete(comma); 65 | } 66 | } 67 | 68 | var line = buffer.CurrentSnapshot.GetLineFromPosition(item.Start); 69 | 70 | Span lineSpan = new Span(line.Start.Position - 1, line.Length + 1); 71 | buffer.Delete(lineSpan); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/_Shared/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EnvDTE; 3 | 4 | namespace JSON_Intellisense 5 | { 6 | class Logger 7 | { 8 | private static OutputWindowPane pane; 9 | private static object _syncRoot = new object(); 10 | 11 | public static void Log(string message) 12 | { 13 | if (EnsurePane()) 14 | { 15 | pane.OutputString("[" + DateTime.Now.ToLongTimeString() + "] " + message + Environment.NewLine); 16 | } 17 | } 18 | 19 | private static bool EnsurePane() 20 | { 21 | if (pane == null) 22 | { 23 | lock (_syncRoot) 24 | { 25 | if (pane == null) 26 | { 27 | pane = Helper.DTE.ToolWindows.OutputWindow.OutputWindowPanes.Add(Globals.VsixName); 28 | } 29 | } 30 | } 31 | 32 | return pane != null; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/_Shared/Options.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Microsoft.VisualStudio.Shell; 3 | 4 | namespace JSON_Intellisense 5 | { 6 | public class Options : DialogPage 7 | { 8 | public Options() 9 | { 10 | BowerInstallOnOpen = true; 11 | NpmInstallOnOpen = true; 12 | BowerInstallOnSave = true; 13 | NpmInstallOnSave = true; 14 | NpmCustomFeedUrl = string.Empty; 15 | BowerCustomFeedUrl = string.Empty; 16 | } 17 | 18 | [Category("Project open")] 19 | [DisplayName("Automatic Bower install")] 20 | [Description("Calls 'bower install' on project open.")] 21 | [DefaultValue(true)] 22 | public bool BowerInstallOnOpen { get; set; } 23 | 24 | [Category("Project open")] 25 | [DisplayName("Automatic npm install")] 26 | [Description("Calls 'npm install' on project open.")] 27 | [DefaultValue(true)] 28 | public bool NpmInstallOnOpen { get; set; } 29 | 30 | [Category("Restore on save")] 31 | [DisplayName("bower.json")] 32 | [Description("Automatically calls 'bower install' when bower.json is saved.")] 33 | [DefaultValue(true)] 34 | public bool BowerInstallOnSave { get; set; } 35 | 36 | [Category("Restore on save")] 37 | [DisplayName("package.json")] 38 | [Description("Automatically calls 'npm install' when package.json is saved.")] 39 | [DefaultValue(true)] 40 | public bool NpmInstallOnSave { get; set; } 41 | 42 | [Category("Custom Feeds")] 43 | [DisplayName("Custom NPM Feed Url")] 44 | [Description("Enter the URL to your private or custom NPM feed.")] 45 | [DefaultValue(true)] 46 | public string NpmCustomFeedUrl { get; set; } 47 | 48 | [Category("Custom Feeds")] 49 | [DisplayName("Custom Bower Feed Url")] 50 | [Description("Enter the URL to your private or custom Bower feed.")] 51 | [DefaultValue(true)] 52 | public string BowerCustomFeedUrl { get; set; } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/_Shared/QuickInfo/QuickInfoController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.VisualStudio.Language.Intellisense; 3 | using Microsoft.VisualStudio.Text; 4 | using Microsoft.VisualStudio.Text.Editor; 5 | 6 | namespace JSON_Intellisense 7 | { 8 | internal class QuickInfoController : IIntellisenseController 9 | { 10 | private ITextView m_textView; 11 | private IList m_subjectBuffers; 12 | private QuickInfoControllerProvider m_provider; 13 | 14 | internal QuickInfoController(ITextView textView, IList subjectBuffers, QuickInfoControllerProvider provider) 15 | { 16 | m_textView = textView; 17 | m_subjectBuffers = subjectBuffers; 18 | m_provider = provider; 19 | 20 | m_textView.MouseHover += this.OnTextViewMouseHover; 21 | } 22 | 23 | private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e) 24 | { 25 | //find the mouse position by mapping down to the subject buffer 26 | SnapshotPoint? point = m_textView.BufferGraph.MapDownToFirstMatch 27 | (new SnapshotPoint(m_textView.TextSnapshot, e.Position), 28 | PointTrackingMode.Positive, 29 | snapshot => m_subjectBuffers.Contains(snapshot.TextBuffer), 30 | PositionAffinity.Predecessor); 31 | 32 | if (point != null) 33 | { 34 | ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position, 35 | PointTrackingMode.Positive); 36 | 37 | if (!m_provider.QuickInfoBroker.IsQuickInfoActive(m_textView)) 38 | { 39 | m_provider.QuickInfoBroker.TriggerQuickInfo(m_textView, triggerPoint, true); 40 | } 41 | } 42 | } 43 | 44 | public void Detach(ITextView textView) 45 | { 46 | if (m_textView == textView) 47 | { 48 | m_textView.MouseHover -= this.OnTextViewMouseHover; 49 | m_textView = null; 50 | } 51 | } 52 | 53 | public void ConnectSubjectBuffer(ITextBuffer subjectBuffer) 54 | { 55 | } 56 | 57 | public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer) 58 | { 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/_Shared/QuickInfo/QuickInfoControllerProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.Composition; 3 | using Microsoft.VisualStudio.Language.Intellisense; 4 | using Microsoft.VisualStudio.Text; 5 | using Microsoft.VisualStudio.Text.Editor; 6 | using Microsoft.VisualStudio.Utilities; 7 | 8 | namespace JSON_Intellisense 9 | { 10 | [Export(typeof(IIntellisenseControllerProvider))] 11 | [Name("JSON QuickInfo Controller")] 12 | [ContentType("JSON")] 13 | public class QuickInfoControllerProvider : IIntellisenseControllerProvider 14 | { 15 | [Import] 16 | public IQuickInfoBroker QuickInfoBroker { get; set; } 17 | 18 | public IIntellisenseController TryCreateIntellisenseController(ITextView textView, IList subjectBuffers) 19 | { 20 | return new QuickInfoController(textView, subjectBuffers, this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/_Shared/QuickInfo/QuickInfoSourceBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows; 4 | using Microsoft.JSON.Core.Parser; 5 | using Microsoft.JSON.Editor; 6 | using Microsoft.VisualStudio.Language.Intellisense; 7 | using Microsoft.VisualStudio.Text; 8 | using JSON_Intellisense._Shared.Resources; 9 | 10 | namespace JSON_Intellisense 11 | { 12 | public abstract class QuickInfoSourceBase : IQuickInfoSource 13 | { 14 | public ITextBuffer _buffer; 15 | 16 | public QuickInfoSourceBase(ITextBuffer subjectBuffer) 17 | { 18 | _buffer = subjectBuffer; 19 | } 20 | 21 | public void AugmentQuickInfoSession(IQuickInfoSession session, IList qiContent, out ITrackingSpan applicableToSpan) 22 | { 23 | applicableToSpan = null; 24 | 25 | if (session == null || qiContent == null) 26 | return; 27 | 28 | // Map the trigger point down to our buffer. 29 | SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); 30 | if (!point.HasValue) 31 | return; 32 | 33 | JSONEditorDocument doc = JSONEditorDocument.FromTextBuffer(_buffer); 34 | JSONParseItem item = doc.JSONDocument.ItemBeforePosition(point.Value.Position); 35 | 36 | if (item == null || !item.IsValid) 37 | return; 38 | 39 | JSONMember dependency = item.FindType(); 40 | if (dependency == null) 41 | return; 42 | 43 | var parent = dependency.Parent.FindType(); 44 | if (parent == null || !parent.UnquotedNameText.EndsWith("dependencies", StringComparison.OrdinalIgnoreCase)) 45 | return; 46 | 47 | applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); 48 | 49 | if (dependency.Value == item) 50 | { 51 | string version = item.Text.Trim('"', '~', '^'); 52 | qiContent.Add(" " + version + " " + Resource.CompletionVersionLatest + Environment.NewLine + 53 | "~" + version + " " + Resource.CompletionVersionMinor + Environment.NewLine + 54 | "^" + version + " " + Resource.CompletionVersionMajor); 55 | } 56 | else 57 | { 58 | UIElement element = CreateTooltip(dependency.UnquotedNameText, item); 59 | 60 | if (element != null) 61 | qiContent.Add(element); 62 | } 63 | } 64 | 65 | public abstract UIElement CreateTooltip(string name, JSONParseItem item); 66 | 67 | public void Dispose() 68 | { 69 | // Nothing to dispose 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/_Shared/QuickInfo/QuickInfoSourceProvider.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.Composition; 2 | using Microsoft.VisualStudio.Language.Intellisense; 3 | using Microsoft.VisualStudio.Text; 4 | using Microsoft.VisualStudio.Utilities; 5 | 6 | namespace JSON_Intellisense 7 | { 8 | [Export(typeof(IQuickInfoSourceProvider))] 9 | [Name("JSON QuickInfo Source")] 10 | [Order(Before = "Default Quick Info Presenter")] 11 | [ContentType("JSON")] 12 | internal class QuickInfoSourceProvider : IQuickInfoSourceProvider 13 | { 14 | public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer) 15 | { 16 | if (Helper.IsSupportedFile(Bower.Constants.FileName)) 17 | return new Bower.BowerQuickInfo(textBuffer); 18 | else if (Helper.IsSupportedFile(NPM.Constants.FileName)) 19 | return new NPM.NpmQuickInfo(textBuffer); 20 | 21 | return null; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/_Shared/Resources/License.txt: -------------------------------------------------------------------------------- 1 | Copyright 2014 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/_Shared/Resources/Package.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/Package.ico -------------------------------------------------------------------------------- /src/_Shared/Resources/Resource.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.0 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace JSON_Intellisense._Shared.Resources { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resource { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resource() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("JSON_Intellisense._Shared.Resources.Resource", typeof(Resource).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Click to toggle visibility. 65 | /// 66 | internal static string ClickToToggleVisibility { 67 | get { 68 | return ResourceManager.GetString("ClickToToggleVisibility", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to The exact version of the package. 74 | /// 75 | internal static string CompletionVersionLatest { 76 | get { 77 | return ResourceManager.GetString("CompletionVersionLatest", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// Looks up a localized string similar to The most recent major version. 83 | /// 84 | internal static string CompletionVersionMajor { 85 | get { 86 | return ResourceManager.GetString("CompletionVersionMajor", resourceCulture); 87 | } 88 | } 89 | 90 | /// 91 | /// Looks up a localized string similar to The most recent minor version. 92 | /// 93 | internal static string CompletionVersionMinor { 94 | get { 95 | return ResourceManager.GetString("CompletionVersionMinor", resourceCulture); 96 | } 97 | } 98 | 99 | /// 100 | /// Looks up a localized string similar to Error restoring Bower/npm packages. See output window for details.. 101 | /// 102 | internal static string ErrorRestoringPackages { 103 | get { 104 | return ResourceManager.GetString("ErrorRestoringPackages", resourceCulture); 105 | } 106 | } 107 | 108 | /// 109 | /// Looks up a localized string similar to Package restore complete. 110 | /// 111 | internal static string PackageRestoreComplete { 112 | get { 113 | return ResourceManager.GetString("PackageRestoreComplete", resourceCulture); 114 | } 115 | } 116 | 117 | /// 118 | /// Looks up a localized string similar to Running Bower package restore.... 119 | /// 120 | internal static string RunningBowerRestore { 121 | get { 122 | return ResourceManager.GetString("RunningBowerRestore", resourceCulture); 123 | } 124 | } 125 | 126 | /// 127 | /// Looks up a localized string similar to Running npm package restore.... 128 | /// 129 | internal static string RunningNpmRestore { 130 | get { 131 | return ResourceManager.GetString("RunningNpmRestore", resourceCulture); 132 | } 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/_Shared/Resources/Resource.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 | Click to toggle visibility 122 | 123 | 124 | The exact version of the package 125 | 126 | 127 | The most recent major version 128 | 129 | 130 | The most recent minor version 131 | 132 | 133 | Error restoring Bower/npm packages. See output window for details. 134 | 135 | 136 | Package restore complete 137 | 138 | 139 | Running Bower package restore... 140 | 141 | 142 | Running npm package restore... 143 | 144 | -------------------------------------------------------------------------------- /src/_Shared/Resources/Watermarks/bower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/Watermarks/bower.png -------------------------------------------------------------------------------- /src/_Shared/Resources/Watermarks/grunt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/Watermarks/grunt.png -------------------------------------------------------------------------------- /src/_Shared/Resources/Watermarks/gulp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/Watermarks/gulp.png -------------------------------------------------------------------------------- /src/_Shared/Resources/Watermarks/npm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/Watermarks/npm.png -------------------------------------------------------------------------------- /src/_Shared/Resources/browse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/browse.png -------------------------------------------------------------------------------- /src/_Shared/Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/icon.png -------------------------------------------------------------------------------- /src/_Shared/Resources/install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/install.png -------------------------------------------------------------------------------- /src/_Shared/Resources/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/preview.png -------------------------------------------------------------------------------- /src/_Shared/Resources/uninstall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/uninstall.png -------------------------------------------------------------------------------- /src/_Shared/Resources/update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/JSON-Intellisense/8d78bc7b7467d9edae4abf80b440a0c1834a781d/src/_Shared/Resources/update.png -------------------------------------------------------------------------------- /src/_Shared/SmartTags/IJSONSmartTagProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.JSON.Core.Parser; 4 | using Microsoft.VisualStudio.Language.Intellisense; 5 | using Microsoft.VisualStudio.Text; 6 | using Microsoft.VisualStudio.Text.Editor; 7 | 8 | namespace JSON_Intellisense 9 | { 10 | interface IJSONSmartTagProvider 11 | { 12 | Type ItemType { get; } 13 | IEnumerable GetSmartTagActions(JSONParseItem item, int caretPosition, ITrackingSpan itemTrackingSpan, ITextView view); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/_Shared/SmartTags/JSONSmartTag.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | using Microsoft.VisualStudio.Language.Intellisense; 3 | 4 | namespace JSON_Intellisense 5 | { 6 | class JSONSmartTag : SmartTag 7 | { 8 | public JSONSmartTag(ReadOnlyCollection actionSets) 9 | : base(SmartTagType.Factoid, actionSets) 10 | { 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/_Shared/SmartTags/JSONSmartTagActionBase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | using System.Windows.Media; 3 | using Microsoft.VisualStudio.Language.Intellisense; 4 | 5 | namespace JSON_Intellisense 6 | { 7 | internal abstract class JSONSmartTagActionBase : ISmartTagAction 8 | { 9 | public virtual ReadOnlyCollection ActionSets 10 | { 11 | get { return null; } 12 | } 13 | 14 | public virtual string DisplayText 15 | { 16 | get { return "NO DISPLAY TEXT SPECIFIED"; } 17 | } 18 | 19 | public ImageSource Icon { get; protected set; } 20 | 21 | public bool IsEnabled 22 | { 23 | get { return true; } 24 | } 25 | 26 | public abstract void Invoke(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/_Shared/SmartTags/JSONSmartTagProviderBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using Microsoft.JSON.Core.Parser; 6 | using Microsoft.VisualStudio.Language.Intellisense; 7 | using Microsoft.VisualStudio.Text; 8 | using Microsoft.VisualStudio.Text.Editor; 9 | 10 | namespace JSON_Intellisense 11 | { 12 | abstract class JSONSmartTagProviderBase : IJSONSmartTagProvider 13 | { 14 | public Type ItemType 15 | { 16 | get { return typeof(JSONMember); } 17 | } 18 | 19 | public abstract string SupportedFileName { get; } 20 | 21 | public virtual IEnumerable GetSmartTagActions(JSONParseItem item, int caretPosition, ITrackingSpan itemTrackingSpan, ITextView view) 22 | { 23 | string fileName = itemTrackingSpan.TextBuffer.GetFileName(); 24 | 25 | if (string.IsNullOrEmpty(fileName) || Path.GetFileName(fileName) != SupportedFileName) 26 | return Enumerable.Empty(); 27 | 28 | JSONMember member = (JSONMember)item; 29 | 30 | if (!member.Name.ContainsRange(caretPosition, 1)) 31 | return Enumerable.Empty(); 32 | 33 | JSONMember parent = member.Parent.FindType(); 34 | 35 | if (parent == null || !parent.UnquotedNameText.EndsWith("dependencies", StringComparison.OrdinalIgnoreCase)) 36 | return Enumerable.Empty(); 37 | 38 | return GetSmartTagActions(member, itemTrackingSpan.TextBuffer); 39 | } 40 | 41 | public abstract IEnumerable GetSmartTagActions(JSONMember item, ITextBuffer buffer); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/_Shared/SmartTags/JSONSmartTagger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.CSS.Core; 4 | using Microsoft.JSON.Core.Parser; 5 | using Microsoft.JSON.Editor; 6 | using Microsoft.VisualStudio.Language.Intellisense; 7 | using Microsoft.VisualStudio.Text; 8 | using Microsoft.VisualStudio.Text.Editor; 9 | using Microsoft.VisualStudio.Text.Tagging; 10 | using Microsoft.Web.Editor; 11 | using Microsoft.Web.Editor.EditorHelpers; 12 | 13 | namespace JSON_Intellisense 14 | { 15 | internal class JSONSmartTagger : ITagger, IDisposable 16 | { 17 | private ITextView _textView; 18 | private ITextBuffer _textBuffer; 19 | private JSONDocument _tree; 20 | private bool _pendingUpdate; 21 | private ItemHandlerRegistry _smartTagProviders; 22 | 23 | public event EventHandler TagsChanged; 24 | 25 | public JSONSmartTagger(ITextView textView, ITextBuffer textBuffer) 26 | { 27 | _textView = textView; 28 | _textBuffer = textBuffer; 29 | _pendingUpdate = true; 30 | 31 | _textView.Caret.PositionChanged += OnCaretPositionChanged; 32 | // [Mads] I've added this so the smart tags refreshes when buffer is manipulated 33 | //_textBuffer.ChangedLowPriority += BufferChanged; 34 | 35 | _smartTagProviders = new ItemHandlerRegistry(); 36 | } 37 | 38 | private void BufferChanged(object sender, TextContentChangedEventArgs e) 39 | { 40 | EnsureInitialized(); 41 | 42 | _pendingUpdate = true; 43 | } 44 | 45 | private void OnCaretPositionChanged(object sender, CaretPositionChangedEventArgs eventArgs) 46 | { 47 | EnsureInitialized(); 48 | 49 | _pendingUpdate = true; 50 | } 51 | 52 | /// 53 | /// This must be delayed so that the TextViewConnectionListener 54 | /// has a chance to initialize the WebEditor host. 55 | /// 56 | public bool EnsureInitialized() 57 | { 58 | if (_tree == null && WebEditor.Host != null) 59 | { 60 | try 61 | { 62 | JSONEditorDocument document = JSONEditorDocument.FromTextBuffer(_textBuffer); 63 | _tree = document.JSONDocument; 64 | 65 | RegisterSmartTagProviders(); 66 | 67 | WebEditor.OnIdle += OnIdle; 68 | } 69 | catch (Exception) 70 | { 71 | } 72 | } 73 | 74 | return _tree != null; 75 | } 76 | 77 | private void RegisterSmartTagProviders() 78 | { 79 | IEnumerable> providers = ComponentLocatorWithOrdering.ImportMany(); 80 | 81 | foreach (Lazy provider in providers) 82 | { 83 | _smartTagProviders.RegisterHandler(provider.Value.ItemType, provider.Value); 84 | } 85 | } 86 | 87 | private void OnIdle(object sender, EventArgs eventArgs) 88 | { 89 | Update(); 90 | } 91 | 92 | private void Update() 93 | { 94 | if (_pendingUpdate) 95 | { 96 | if (TagsChanged != null) 97 | { 98 | // Tell the editor that the tags in the whole buffer changed. It will call back into GetTags(). 99 | 100 | SnapshotSpan span = new SnapshotSpan(_textBuffer.CurrentSnapshot, new Span(0, _textBuffer.CurrentSnapshot.Length)); 101 | TagsChanged(this, new SnapshotSpanEventArgs(span)); 102 | } 103 | 104 | _pendingUpdate = false; 105 | } 106 | } 107 | 108 | public IEnumerable> GetTags(NormalizedSnapshotSpanCollection spans) 109 | { 110 | List> tags = new List>(); 111 | 112 | if (!EnsureInitialized()) 113 | return tags; 114 | 115 | // Map view caret to the CSS buffer 116 | ProjectionSelectionHelper selectionHelpers = new ProjectionSelectionHelper(_textView, new[] { _textBuffer }); 117 | SnapshotPoint? bufferPoint = selectionHelpers.MapFromViewToBuffer(_textView.Caret.Position.BufferPosition); 118 | 119 | if (!bufferPoint.HasValue) 120 | return tags; 121 | 122 | JSONParseItem currentItem = GetContextItem(_tree, bufferPoint.Value.Position); 123 | if (currentItem == null || currentItem.Parent == null) 124 | return tags; 125 | 126 | JSONParseItem parent = currentItem.Parent; 127 | 128 | IEnumerable providers = _smartTagProviders.GetHandlers(parent.GetType()); 129 | List actions = new List(); 130 | 131 | if (providers != null && _textBuffer.CurrentSnapshot.Length >= currentItem.AfterEnd) 132 | { 133 | ITrackingSpan trackingSpan = _textBuffer.CurrentSnapshot.CreateTrackingSpan(currentItem.Start, currentItem.Length, SpanTrackingMode.EdgeInclusive); 134 | 135 | foreach (IJSONSmartTagProvider provider in providers) 136 | { 137 | IEnumerable newActions = provider.GetSmartTagActions(parent, bufferPoint.Value.Position, trackingSpan, _textView); 138 | 139 | if (newActions != null) 140 | { 141 | actions.AddRange(newActions); 142 | } 143 | } 144 | } 145 | 146 | if (actions.Count > 0) 147 | { 148 | SmartTagActionSet actionSet = new SmartTagActionSet(actions.AsReadOnly()); 149 | List actionSets = new List(); 150 | actionSets.Add(actionSet); 151 | 152 | SnapshotSpan itemSpan = new SnapshotSpan(_textBuffer.CurrentSnapshot, currentItem.Start, currentItem.Length); 153 | JSONSmartTag smartTag = new JSONSmartTag(actionSets.AsReadOnly()); 154 | 155 | tags.Add(new TagSpan(itemSpan, smartTag)); 156 | } 157 | 158 | return tags; 159 | } 160 | 161 | /// 162 | /// This code was copied from CompletionEngine.cs in the CSS code. If this class gets 163 | /// copied into the CSS code, reuse that other function (CompletionEngine.GetCompletionContextLeafItem) 164 | /// 165 | private static JSONParseItem GetContextItem(JSONDocument styleSheet, int position) 166 | { 167 | // Look on both sides of the cursor for a context item. 168 | 169 | JSONParseItem prevItem = styleSheet.ItemBeforePosition(position) ?? styleSheet; 170 | JSONParseItem nextItem = styleSheet.ItemAfterPosition(position); 171 | 172 | if (position > prevItem.AfterEnd) 173 | { 174 | // Not touching the previous item, check its parents 175 | 176 | for (; prevItem != null; prevItem = prevItem.Parent) 177 | { 178 | if (prevItem.IsUnclosed || prevItem.AfterEnd >= position) 179 | { 180 | break; 181 | } 182 | } 183 | } 184 | 185 | // Only use the next item if the cursor is touching it, and it's not a comment 186 | if (nextItem != null && (position < nextItem.Start))// || nextItem.FindType() != null)) 187 | { 188 | nextItem = null; 189 | } 190 | 191 | // When two things touch the cursor inside of a selector, always prefer the previous item. 192 | // If this logic gets larger, consider a better design to choose between two items. 193 | if (nextItem != null && 194 | prevItem != null && 195 | prevItem.AfterEnd == position) 196 | { 197 | nextItem = null; 198 | } 199 | 200 | return nextItem ?? prevItem; 201 | } 202 | 203 | public void Dispose() 204 | { 205 | _tree = null; 206 | if (_textBuffer != null) 207 | { 208 | _textBuffer.ChangedLowPriority -= BufferChanged; 209 | _textBuffer = null; 210 | } 211 | 212 | if (_textView != null) 213 | { 214 | _textView.Caret.PositionChanged -= OnCaretPositionChanged; 215 | _textView = null; 216 | } 217 | } 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /src/_Shared/SmartTags/JSONViewTaggerProvider.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.Composition; 2 | using Microsoft.VisualStudio.Language.Intellisense; 3 | using Microsoft.VisualStudio.Text; 4 | using Microsoft.VisualStudio.Text.Editor; 5 | using Microsoft.VisualStudio.Text.Tagging; 6 | using Microsoft.VisualStudio.Utilities; 7 | 8 | namespace JSON_Intellisense 9 | { 10 | [Export(typeof(IViewTaggerProvider))] 11 | [ContentType("JSON")] 12 | [TagType(typeof(SmartTag))] 13 | internal class SmartTagViewTaggerProvider : IViewTaggerProvider 14 | { 15 | public ITagger CreateTagger(ITextView textView, ITextBuffer textBuffer) where T : ITag 16 | { 17 | JSONSmartTagger tagger = new JSONSmartTagger(textView, textBuffer); 18 | return tagger as ITagger; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Package Intellisense 6 | Search for online NPM and Bower packages directly within Intellisense and do automatic package restore 7 | https://github.com/madskristensen/JSON-Intellisense 8 | _Shared\Resources\License.txt 9 | http://visualstudiogallery.msdn.microsoft.com/65748cdb-4087-497e-a394-2e3449c8e61e 10 | _Shared\Resources\icon.png 11 | _Shared\Resources\preview.png 12 | npm, bower 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | --------------------------------------------------------------------------------