├── README.md
├── art
└── context-menu.png
├── src
├── Resources
│ └── Icon.png
├── Commands
│ ├── BaseCommand.cs
│ ├── CommandRegistration.cs
│ └── AutoPrefixCommand.cs
├── CssAutoPrefixPackage.cs
├── Properties
│ └── AssemblyInfo.cs
├── source.extension.cs
├── Helpers
│ └── Logger.cs
├── source.extension.vsixmanifest
├── VSCommandTable.cs
├── packages.config
├── VSCommandTable.vsct
├── NodeProcess.cs
└── CssAutoPrefixer.csproj
├── .gitignore
├── .github
├── ISSUE_TEMPLATE.md
└── CONTRIBUTING.md
├── .gitattributes
├── LICENSE
├── CHANGELOG.md
├── appveyor.yml
├── CssAutoPrefixer.sln
└── .editorconfig
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssAutoPrefixer/master/README.md
--------------------------------------------------------------------------------
/art/context-menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssAutoPrefixer/master/art/context-menu.png
--------------------------------------------------------------------------------
/src/Resources/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssAutoPrefixer/master/src/Resources/Icon.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | packages
2 |
3 | # User files
4 | *.suo
5 | *.user
6 | *.sln.docstates
7 | .vs/
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Rr]elease/
12 | x64/
13 | [Bb]in/
14 | [Oo]bj/
15 |
16 | # MSTest test Results
17 | [Tt]est[Rr]esult*/
18 | [Bb]uild[Ll]og.*
19 |
20 | # NCrunch
21 | *.ncrunchsolution
22 | *.ncrunchproject
23 | _NCrunch_WebCompiler
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Installed product versions
2 | - Visual Studio: [example 2015 Professional]
3 | - This extension: [example 1.1.21]
4 |
5 | ### Description
6 | Replace this text with a short description
7 |
8 | ### Steps to recreate
9 | 1. Replace this
10 | 2. text with
11 | 3. the steps
12 | 4. to recreate
13 |
14 | ### Current behavior
15 | Explain what it's doing and why it's wrong
16 |
17 | ### Expected behavior
18 | Explain what it should be doing after it's fixed.
--------------------------------------------------------------------------------
/src/Commands/BaseCommand.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.OLE.Interop;
2 | using System;
3 |
4 | namespace CssAutoPrefixer
5 | {
6 | abstract class BaseCommand : IOleCommandTarget
7 | {
8 | public IOleCommandTarget Next { get; set; }
9 |
10 | public abstract int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut);
11 |
12 | public abstract int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/CssAutoPrefixPackage.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Shell;
2 | using System;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace CssAutoPrefixer
6 | {
7 | [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
8 | [InstalledProductRegistration(Vsix.Name, Vsix.Description, Vsix.Version)]
9 | [Guid(PackageGuids.guidPackageString)]
10 | [ProvideMenuResource("Menus.ctmenu", 1)]
11 | public sealed class CssAutoPrefixPackage : AsyncPackage
12 | {
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2016 Mads Kristensen
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/src/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using CssAutoPrefixer;
2 | using System.Reflection;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle(Vsix.Name)]
6 | [assembly: AssemblyDescription(Vsix.Description)]
7 | [assembly: AssemblyConfiguration("")]
8 | [assembly: AssemblyCompany(Vsix.Author)]
9 | [assembly: AssemblyProduct(Vsix.Name)]
10 | [assembly: AssemblyCopyright(Vsix.Author)]
11 | [assembly: AssemblyTrademark("")]
12 | [assembly: AssemblyCulture("")]
13 |
14 | [assembly: ComVisible(false)]
15 |
16 | [assembly: AssemblyVersion(Vsix.Version)]
17 | [assembly: AssemblyFileVersion(Vsix.Version)]
18 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Road map
2 |
3 | - [x] Added UTF-8 encoding support
4 |
5 | Features that have a checkmark are complete and available for
6 | download in the
7 | [CI build](http://vsixgallery.com/extension/7df8a985-0e26-4aab-95fc-f48ee61b086a/).
8 |
9 | # Change log
10 |
11 | These are the changes to each version that has been released
12 | on the official Visual Studio extension gallery.
13 |
14 | ## 0.6
15 |
16 | - [x] Support for LESS and Scss
17 | - [x] Scoped keyboard shortcut to JS editor
18 |
19 | ## 0.5
20 |
21 | - [x] Initial release
22 | - [x] Install npm modules
23 | - [x] Command on CSS context menu
24 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | image: Visual Studio 2017
2 |
3 | install:
4 | - ps: (new-object Net.WebClient).DownloadString("https://raw.github.com/madskristensen/ExtensionScripts/master/AppVeyor/vsix.ps1") | iex
5 |
6 | before_build:
7 | - ps: Vsix-IncrementVsixVersion | Vsix-UpdateBuildVersion
8 | - ps: Vsix-TokenReplacement src\source.extension.cs 'Version = "([0-9\\.]+)"' 'Version = "{version}"'
9 |
10 | build_script:
11 | - nuget restore -Verbosity quiet
12 | - msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m
13 |
14 | after_test:
15 | - ps: Vsix-PushArtifacts | Vsix-PublishToGallery
16 |
--------------------------------------------------------------------------------
/src/source.extension.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | //
3 | // This file was generated by VSIX Synchronizer
4 | //
5 | // ------------------------------------------------------------------------------
6 | namespace CssAutoPrefixer
7 | {
8 | internal sealed partial class Vsix
9 | {
10 | public const string Id = "7df8a985-0e26-4aab-95fc-f48ee61b086a";
11 | public const string Name = "CSS AutoPrefixer";
12 | public const string Description = @"Write your CSS rules without vendor prefixes (in fact, forget about them entirely). Autoprefixer will use the data based on current browser popularity and property support to apply prefixes for you.";
13 | public const string Language = "en-US";
14 | public const string Version = "0.7";
15 | public const string Author = "Mads Kristensen";
16 | public const string Tags = "CSS, LESS, Sass, Scss, autoprefixer";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Helpers/Logger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.Shell;
3 | using Microsoft.VisualStudio.Shell.Interop;
4 |
5 | internal static class Logger
6 | {
7 | private static IVsOutputWindowPane _pane;
8 | private static IVsOutputWindow _output = (IVsOutputWindow)ServiceProvider.GlobalProvider.GetService(typeof(SVsOutputWindow));
9 |
10 | public static void Log(object message)
11 | {
12 | try
13 | {
14 | if (EnsurePane())
15 | {
16 | _pane.OutputString(DateTime.Now.ToString() + ": " + message + Environment.NewLine);
17 | }
18 | }
19 | catch (Exception ex)
20 | {
21 | System.Diagnostics.Debug.Write(ex);
22 | }
23 | }
24 |
25 | private static bool EnsurePane()
26 | {
27 | if (_pane == null)
28 | {
29 | var guid = Guid.NewGuid();
30 | _output.CreatePane(ref guid, CssAutoPrefixer.Vsix.Name, 1, 1);
31 | _output.GetPane(ref guid, out _pane);
32 | }
33 |
34 | return _pane != null;
35 | }
36 | }
--------------------------------------------------------------------------------
/CssAutoPrefixer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26212.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaScriptPrettier", "src\CssAutoPrefixer.csproj", "{D1F752E5-6CAB-4513-980A-51B44E104CDF}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{50552A90-8343-4135-A563-AE454C22F3D6}"
9 | ProjectSection(SolutionItems) = preProject
10 | .editorconfig = .editorconfig
11 | appveyor.yml = appveyor.yml
12 | CHANGELOG.md = CHANGELOG.md
13 | README.md = README.md
14 | EndProjectSection
15 | EndProject
16 | Global
17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
18 | Debug|Any CPU = Debug|Any CPU
19 | Release|Any CPU = Release|Any CPU
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {D1F752E5-6CAB-4513-980A-51B44E104CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {D1F752E5-6CAB-4513-980A-51B44E104CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {D1F752E5-6CAB-4513-980A-51B44E104CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {D1F752E5-6CAB-4513-980A-51B44E104CDF}.Release|Any CPU.Build.0 = Release|Any CPU
26 | EndGlobalSection
27 | GlobalSection(SolutionProperties) = preSolution
28 | HideSolutionNode = FALSE
29 | EndGlobalSection
30 | EndGlobal
31 |
--------------------------------------------------------------------------------
/src/source.extension.vsixmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CSS AutoPrefixer
6 | Write your CSS rules without vendor prefixes (in fact, forget about them entirely). Autoprefixer will use the data based on current browser popularity and property support to apply prefixes for you.
7 | https://github.com/madskristensen/CssAutoPrefixer
8 | Resources\LICENSE
9 | https://github.com/madskristensen/CssAutoPrefixer/blob/master/CHANGELOG.md
10 | Resources\Icon.png
11 | Resources\Icon.png
12 | CSS, LESS, Sass, Scss, autoprefixer
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/VSCommandTable.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | //
3 | // This file was generated by Extensibility Tools v1.10.188
4 | //
5 | // ------------------------------------------------------------------------------
6 | namespace CssAutoPrefixer
7 | {
8 | using System;
9 |
10 | ///
11 | /// Helper class that exposes all GUIDs used across VS Package.
12 | ///
13 | internal sealed partial class PackageGuids
14 | {
15 | public const string guidPackageString = "1fb559a7-7c51-4b78-b941-697bd7764ade";
16 | public const string guidPackageCmdSetString = "df207aa8-51d1-44f8-b6c1-31af17cce355";
17 | public const string CssEditorString = "a5401142-f49d-43db-90b1-f57ba349e55c";
18 | public const string CssEditorWithEncodingString = "226f7e34-0ae8-4157-9cd8-b66b4eaf2c7b";
19 | public const string LessEditorString = "28c69eda-edf9-4ca8-9ebe-443348b6d916";
20 | public const string LessEditorWithEncodingString = "eb284e36-4c91-422b-8df6-4dfc2ec3d350";
21 | public const string ScssEditorString = "181fe41b-5a5d-479f-9f8f-bf665f4ebc2a";
22 | public const string ScssEditorWithEncodingString = "52334ead-0711-4a03-804e-7169f077a621";
23 | public const string CssCmdSetString = "64da400e-b4ad-4d67-aa92-4b7acb01ecd5";
24 | public static Guid guidPackage = new Guid(guidPackageString);
25 | public static Guid guidPackageCmdSet = new Guid(guidPackageCmdSetString);
26 | public static Guid CssEditor = new Guid(CssEditorString);
27 | public static Guid CssEditorWithEncoding = new Guid(CssEditorWithEncodingString);
28 | public static Guid LessEditor = new Guid(LessEditorString);
29 | public static Guid LessEditorWithEncoding = new Guid(LessEditorWithEncodingString);
30 | public static Guid ScssEditor = new Guid(ScssEditorString);
31 | public static Guid ScssEditorWithEncoding = new Guid(ScssEditorWithEncodingString);
32 | public static Guid CssCmdSet = new Guid(CssCmdSetString);
33 | }
34 | ///
35 | /// Helper class that encapsulates all CommandIDs uses across VS Package.
36 | ///
37 | internal sealed partial class PackageIds
38 | {
39 | public const int MyMenuGroup = 0x1020;
40 | public const int AutoPrefixCommandId = 0x0100;
41 | public const int cssContextMenu = 0x0002;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome:http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Don't use tabs for indentation.
7 | [*]
8 | indent_style = space
9 | end_of_line = crlf
10 | # (Please don't specify an indent_size here; that has too many unintended consequences.)
11 |
12 | # Code files
13 | [*.{cs,csx,vb,vbx}]
14 | indent_size = 4
15 |
16 | # Xml project files
17 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
18 | indent_size = 2
19 |
20 | # Xml config files
21 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
22 | indent_size = 2
23 |
24 | # JSON files
25 | [*.json]
26 | indent_size = 2
27 |
28 | # Dotnet code style settings:
29 | [*.{cs,vb}]
30 | # Sort using and Import directives with System.* appearing first
31 | dotnet_sort_system_directives_first = true
32 | # Avoid "this." and "Me." if not necessary
33 | dotnet_style_qualification_for_field = false:suggestion
34 | dotnet_style_qualification_for_property = false:suggestion
35 | dotnet_style_qualification_for_method = false:suggestion
36 | dotnet_style_qualification_for_event = false:suggestion
37 |
38 | # Use language keywords instead of framework type names for type references
39 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
40 | dotnet_style_predefined_type_for_member_access = true:suggestion
41 |
42 | # Suggest more modern language features when available
43 | dotnet_style_object_initializer = true:suggestion
44 | dotnet_style_collection_initializer = true:suggestion
45 | dotnet_style_coalesce_expression = true:suggestion
46 | dotnet_style_null_propagation = true:suggestion
47 | dotnet_style_explicit_tuple_names = true:suggestion
48 |
49 | # CSharp code style settings:
50 | [*.cs]
51 | # Prefer "var" everywhere
52 | csharp_style_var_for_built_in_types = false:suggestion
53 | csharp_style_var_when_type_is_apparent = true:suggestion
54 | csharp_style_var_elsewhere = false:suggestion
55 |
56 | # Prefer method-like constructs to have a block body
57 | csharp_style_expression_bodied_methods = false:none
58 | csharp_style_expression_bodied_constructors = false:none
59 | csharp_style_expression_bodied_operators = false:none
60 |
61 | # Prefer property-like constructs to have an expression-body
62 | csharp_style_expression_bodied_properties = true:none
63 | csharp_style_expression_bodied_indexers = true:none
64 | csharp_style_expression_bodied_accessors = true:none
65 |
66 | # Suggest more modern language features when available
67 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
68 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
69 | csharp_style_inlined_variable_declaration = true:suggestion
70 | csharp_style_throw_expression = true:suggestion
71 | csharp_style_conditional_delegate_call = true:suggestion
72 |
73 | # Newline settings
74 | csharp_new_line_before_open_brace = all
75 | csharp_new_line_before_else = true
76 | csharp_new_line_before_catch = true
77 | csharp_new_line_before_finally = true
78 | csharp_new_line_before_members_in_object_initializers = true
79 | csharp_new_line_before_members_in_anonymous_types = true
--------------------------------------------------------------------------------
/src/Commands/CommandRegistration.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Editor;
2 | using Microsoft.VisualStudio.Shell;
3 | using Microsoft.VisualStudio.Shell.Interop;
4 | using Microsoft.VisualStudio.Text;
5 | using Microsoft.VisualStudio.Text.Editor;
6 | using Microsoft.VisualStudio.Text.Operations;
7 | using Microsoft.VisualStudio.TextManager.Interop;
8 | using Microsoft.VisualStudio.Utilities;
9 | using System;
10 | using System.ComponentModel.Composition;
11 | using System.IO;
12 | using System.Linq;
13 |
14 | namespace CssAutoPrefixer
15 | {
16 | [Export(typeof(IVsTextViewCreationListener))]
17 | [ContentType("CSS")]
18 | [ContentType("LESS")]
19 | [ContentType("SCSS")]
20 | [TextViewRole(PredefinedTextViewRoles.PrimaryDocument)]
21 | internal sealed class CommandRegistration : IVsTextViewCreationListener
22 | {
23 | public static string[] FileExtensions { get; } = { ".css", ".less", ".sass", ".scss" };
24 |
25 | [Import]
26 | private IVsEditorAdaptersFactoryService AdaptersFactory { get; set; }
27 |
28 | [Import]
29 | private ITextDocumentFactoryService DocumentService { get; set; }
30 |
31 | [Import]
32 | private ITextBufferUndoManagerProvider UndoProvider { get; set; }
33 |
34 | public async void VsTextViewCreated(IVsTextView textViewAdapter)
35 | {
36 | IWpfTextView view = AdaptersFactory.GetWpfTextView(textViewAdapter);
37 |
38 | if (!DocumentService.TryGetTextDocument(view.TextBuffer, out ITextDocument doc))
39 | return;
40 |
41 | string ext = Path.GetExtension(doc.FilePath);
42 |
43 | if (!FileExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase))
44 | return;
45 |
46 | ITextBufferUndoManager undoManager = UndoProvider.GetTextBufferUndoManager(view.TextBuffer);
47 | NodeProcess node = view.Properties.GetOrCreateSingletonProperty(() => new NodeProcess());
48 |
49 | AddCommandFilter(textViewAdapter, new AutoPrefixCommand(view, undoManager, node));
50 |
51 | if (!node.IsReadyToExecute())
52 | {
53 | await Install(node);
54 | }
55 | }
56 |
57 | private static async System.Threading.Tasks.Task Install(NodeProcess node)
58 | {
59 | var statusbar = (IVsStatusbar)ServiceProvider.GlobalProvider.GetService(typeof(SVsStatusbar));
60 |
61 | statusbar.FreezeOutput(0);
62 | statusbar.SetText($"Installing {NodeProcess.Packages} npm modules...");
63 | statusbar.FreezeOutput(1);
64 |
65 | bool success = await node.EnsurePackageInstalled();
66 | string status = success ? "Done" : "Failed";
67 |
68 | statusbar.FreezeOutput(0);
69 | statusbar.SetText($"Installing {NodeProcess.Packages} npm modules... {status}");
70 | statusbar.FreezeOutput(1);
71 | }
72 |
73 | private void AddCommandFilter(IVsTextView textViewAdapter, BaseCommand command)
74 | {
75 | textViewAdapter.AddCommandFilter(command, out var next);
76 | command.Next = next;
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/VSCommandTable.vsct:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/Commands/AutoPrefixCommand.cs:
--------------------------------------------------------------------------------
1 | using EnvDTE;
2 | using Microsoft.VisualStudio;
3 | using Microsoft.VisualStudio.OLE.Interop;
4 | using Microsoft.VisualStudio.Shell;
5 | using Microsoft.VisualStudio.Text;
6 | using Microsoft.VisualStudio.Text.Editor;
7 | using Microsoft.VisualStudio.Text.Operations;
8 | using System;
9 | using System.Threading.Tasks;
10 |
11 | namespace CssAutoPrefixer
12 | {
13 | internal sealed class AutoPrefixCommand : BaseCommand
14 | {
15 | private Guid _commandGroup = PackageGuids.guidPackageCmdSet;
16 | private const uint _commandId = PackageIds.AutoPrefixCommandId;
17 |
18 | private IWpfTextView _view;
19 | private ITextBufferUndoManager _undoManager;
20 | private NodeProcess _node;
21 |
22 | public AutoPrefixCommand(IWpfTextView view, ITextBufferUndoManager undoManager, NodeProcess node)
23 | {
24 | _view = view;
25 | _undoManager = undoManager;
26 | _node = node;
27 | }
28 |
29 | public override int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
30 | {
31 | if (pguidCmdGroup == _commandGroup && nCmdID == _commandId)
32 | {
33 | if (_node != null && _node.IsReadyToExecute())
34 | {
35 | ThreadHelper.JoinableTaskFactory.RunAsync(ExecuteAsync);
36 | }
37 |
38 | return VSConstants.S_OK;
39 | }
40 |
41 | return Next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
42 | }
43 |
44 | private async Task ExecuteAsync()
45 | {
46 | string input = _view.TextBuffer.CurrentSnapshot.GetText();
47 | string output = await _node.ExecuteProcess(input);
48 |
49 | if (string.IsNullOrEmpty(output) || input == output)
50 | return false;
51 |
52 | using (ITextEdit edit = _view.TextBuffer.CreateEdit())
53 | using (ITextUndoTransaction undo = _undoManager.TextBufferUndoHistory.CreateTransaction(Vsix.Name))
54 | {
55 | edit.Replace(0, _view.TextBuffer.CurrentSnapshot.Length, output);
56 | edit.Apply();
57 |
58 | var dte = (DTE)ServiceProvider.GlobalProvider.GetService(typeof(DTE));
59 | dte.ExecuteCommand("Edit.FormatDocument");
60 |
61 | undo.Complete();
62 | }
63 |
64 | return true;
65 | }
66 |
67 | public override int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
68 | {
69 | if (pguidCmdGroup == _commandGroup && prgCmds[0].cmdID == _commandId)
70 | {
71 | if (_node != null)
72 | {
73 | if (_node.IsReadyToExecute())
74 | {
75 | prgCmds[0].cmdf = (uint)OLECMDF.OLECMDF_ENABLED | (uint)OLECMDF.OLECMDF_SUPPORTED;
76 | }
77 | else
78 | {
79 | prgCmds[0].cmdf = (uint)OLECMDF.OLECMDF_SUPPORTED;
80 | }
81 | }
82 |
83 | return VSConstants.S_OK;
84 | }
85 |
86 | return Next.QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/src/NodeProcess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CssAutoPrefixer
8 | {
9 | internal class NodeProcess
10 | {
11 | public const string Packages = "postcss-cli autoprefixer";
12 |
13 | private static string _installDir = Path.Combine(Path.GetTempPath(), Vsix.Name, Packages.GetHashCode().ToString());
14 | private static readonly string _executable = Path.Combine(_installDir, "node_modules\\.bin\\postcss.cmd");
15 |
16 | public bool IsInstalling
17 | {
18 | get;
19 | private set;
20 | }
21 |
22 | public bool IsReadyToExecute()
23 | {
24 | return File.Exists(_executable);
25 | }
26 |
27 | public async Task EnsurePackageInstalled()
28 | {
29 | if (IsInstalling)
30 | return false;
31 |
32 | if (IsReadyToExecute())
33 | return true;
34 |
35 | IsInstalling = true;
36 |
37 | try
38 | {
39 | if (!Directory.Exists(_installDir))
40 | Directory.CreateDirectory(_installDir);
41 |
42 | var start = new ProcessStartInfo("cmd", $"/c npm install {Packages}")
43 | {
44 | WorkingDirectory = _installDir,
45 | UseShellExecute = false,
46 | CreateNoWindow = true,
47 | RedirectStandardOutput = true,
48 | RedirectStandardError = true,
49 | StandardOutputEncoding = Encoding.UTF8,
50 | StandardErrorEncoding = Encoding.UTF8,
51 | };
52 |
53 | ModifyPathVariable(start);
54 |
55 | using (var proc = Process.Start(start))
56 | {
57 | string output = await proc.StandardOutput.ReadToEndAsync();
58 | string error = await proc.StandardError.ReadToEndAsync();
59 |
60 | if (!string.IsNullOrEmpty(output))
61 | Logger.Log(output);
62 |
63 | if (!string.IsNullOrEmpty(error))
64 | Logger.Log(error);
65 |
66 | proc.WaitForExit();
67 | return proc.ExitCode == 0;
68 | }
69 | }
70 | catch (Exception ex)
71 | {
72 | Logger.Log(ex);
73 | return false;
74 | }
75 | finally
76 | {
77 | IsInstalling = false;
78 | }
79 | }
80 |
81 | public async Task ExecuteProcess(string input)
82 | {
83 | if (!await EnsurePackageInstalled())
84 | return null;
85 |
86 | var start = new ProcessStartInfo("cmd", $"/c \"{_executable}\" --use autoprefixer --no-map")
87 | {
88 | UseShellExecute = false,
89 | CreateNoWindow = true,
90 | RedirectStandardOutput = true,
91 | RedirectStandardError = true,
92 | RedirectStandardInput = true,
93 | StandardOutputEncoding = Encoding.UTF8,
94 | StandardErrorEncoding = Encoding.UTF8,
95 | };
96 |
97 | ModifyPathVariable(start);
98 |
99 | try
100 | {
101 | using (var proc = Process.Start(start))
102 | {
103 | using (var stream = new StreamWriter(proc.StandardInput.BaseStream, Encoding.UTF8))
104 | {
105 | await stream.WriteAsync(input);
106 | }
107 |
108 | string output = await proc.StandardOutput.ReadToEndAsync();
109 | string error = await proc.StandardError.ReadToEndAsync();
110 |
111 | if (!string.IsNullOrEmpty(error))
112 | {
113 | Logger.Log(error);
114 | }
115 |
116 | proc.WaitForExit();
117 | return output;
118 | }
119 | }
120 | catch (Exception ex)
121 | {
122 | Logger.Log(ex);
123 | return null;
124 | }
125 | }
126 |
127 | private static void ModifyPathVariable(ProcessStartInfo start)
128 | {
129 | string path = start.EnvironmentVariables["PATH"];
130 |
131 | var process = Process.GetCurrentProcess();
132 | string ideDir = Path.GetDirectoryName(process.MainModule.FileName);
133 |
134 | if (Directory.Exists(ideDir))
135 | {
136 | string parent = Directory.GetParent(ideDir).Parent.FullName;
137 |
138 | string rc2Preview1Path = new DirectoryInfo(Path.Combine(parent, @"Web\External")).FullName;
139 |
140 | if (Directory.Exists(rc2Preview1Path))
141 | {
142 | path += ";" + rc2Preview1Path;
143 | path += ";" + rc2Preview1Path + "\\git";
144 | }
145 | else
146 | {
147 | path += ";" + Path.Combine(ideDir, @"Extensions\Microsoft\Web Tools\External");
148 | path += ";" + Path.Combine(ideDir, @"Extensions\Microsoft\Web Tools\External\git");
149 | }
150 | }
151 |
152 | start.EnvironmentVariables["PATH"] = path;
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Looking to contribute something? **Here's how you can help.**
4 |
5 | Please take a moment to review this document in order to make the contribution
6 | process easy and effective for everyone involved.
7 |
8 | Following these guidelines helps to communicate that you respect the time of
9 | the developers managing and developing this open source project. In return,
10 | they should reciprocate that respect in addressing your issue or assessing
11 | patches and features.
12 |
13 |
14 | ## Using the issue tracker
15 |
16 | The issue tracker is the preferred channel for [bug reports](#bug-reports),
17 | [features requests](#feature-requests) and
18 | [submitting pull requests](#pull-requests), but please respect the
19 | following restrictions:
20 |
21 | * Please **do not** use the issue tracker for personal support requests. Stack
22 | Overflow is a better place to get help.
23 |
24 | * Please **do not** derail or troll issues. Keep the discussion on topic and
25 | respect the opinions of others.
26 |
27 | * Please **do not** open issues or pull requests which *belongs to* third party
28 | components.
29 |
30 |
31 | ## Bug reports
32 |
33 | A bug is a _demonstrable problem_ that is caused by the code in the repository.
34 | Good bug reports are extremely helpful, so thanks!
35 |
36 | Guidelines for bug reports:
37 |
38 | 1. **Use the GitHub issue search** — check if the issue has already been
39 | reported.
40 |
41 | 2. **Check if the issue has been fixed** — try to reproduce it using the
42 | latest `master` or development branch in the repository.
43 |
44 | 3. **Isolate the problem** — ideally create an
45 | [SSCCE](http://www.sscce.org/) and a live example.
46 | Uploading the project on cloud storage (OneDrive, DropBox, et el.)
47 | or creating a sample GitHub repository is also helpful.
48 |
49 |
50 | A good bug report shouldn't leave others needing to chase you up for more
51 | information. Please try to be as detailed as possible in your report. What is
52 | your environment? What steps will reproduce the issue? What browser(s) and OS
53 | experience the problem? Do other browsers show the bug differently? What
54 | would you expect to be the outcome? All these details will help people to fix
55 | any potential bugs.
56 |
57 | Example:
58 |
59 | > Short and descriptive example bug report title
60 | >
61 | > A summary of the issue and the Visual Studio, browser, OS environments
62 | > in which it occurs. If suitable, include the steps required to reproduce the bug.
63 | >
64 | > 1. This is the first step
65 | > 2. This is the second step
66 | > 3. Further steps, etc.
67 | >
68 | > `` - a link to the project/file uploaded on cloud storage or other publicly accessible medium.
69 | >
70 | > Any other information you want to share that is relevant to the issue being
71 | > reported. This might include the lines of code that you have identified as
72 | > causing the bug, and potential solutions (and your opinions on their
73 | > merits).
74 |
75 |
76 | ## Feature requests
77 |
78 | Feature requests are welcome. But take a moment to find out whether your idea
79 | fits with the scope and aims of the project. It's up to *you* to make a strong
80 | case to convince the project's developers of the merits of this feature. Please
81 | provide as much detail and context as possible.
82 |
83 |
84 | ## Pull requests
85 |
86 | Good pull requests, patches, improvements and new features are a fantastic
87 | help. They should remain focused in scope and avoid containing unrelated
88 | commits.
89 |
90 | **Please ask first** before embarking on any significant pull request (e.g.
91 | implementing features, refactoring code, porting to a different language),
92 | otherwise you risk spending a lot of time working on something that the
93 | project's developers might not want to merge into the project.
94 |
95 | Please adhere to the [coding guidelines](#code-guidelines) used throughout the
96 | project (indentation, accurate comments, etc.) and any other requirements
97 | (such as test coverage).
98 |
99 | Adhering to the following process is the best way to get your work
100 | included in the project:
101 |
102 | 1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork,
103 | and configure the remotes:
104 |
105 | ```bash
106 | # Clone your fork of the repo into the current directory
107 | git clone https://github.com//.git
108 | # Navigate to the newly cloned directory
109 | cd
110 | # Assign the original repo to a remote called "upstream"
111 | git remote add upstream https://github.com/madskristensen/.git
112 | ```
113 |
114 | 2. If you cloned a while ago, get the latest changes from upstream:
115 |
116 | ```bash
117 | git checkout master
118 | git pull upstream master
119 | ```
120 |
121 | 3. Create a new topic branch (off the main project development branch) to
122 | contain your feature, change, or fix:
123 |
124 | ```bash
125 | git checkout -b
126 | ```
127 |
128 | 4. Commit your changes in logical chunks. Please adhere to these [git commit
129 | message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
130 | or your code is unlikely be merged into the main project. Use Git's
131 | [interactive rebase](https://help.github.com/articles/interactive-rebase)
132 | feature to tidy up your commits before making them public. Also, prepend name of the feature
133 | to the commit message. For instance: "SCSS: Fixes compiler results for IFileListener.\nFixes `#123`"
134 |
135 | 5. Locally merge (or rebase) the upstream development branch into your topic branch:
136 |
137 | ```bash
138 | git pull [--rebase] upstream master
139 | ```
140 |
141 | 6. Push your topic branch up to your fork:
142 |
143 | ```bash
144 | git push origin
145 | ```
146 |
147 | 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)
148 | with a clear title and description against the `master` branch.
149 |
150 |
151 | ## Code guidelines
152 |
153 | - Always use proper indentation.
154 | - In Visual Studio under `Tools > Options > Text Editor > C# > Advanced`, make sure
155 | `Place 'System' directives first when sorting usings` option is enabled (checked).
156 | - Before committing, organize usings for each updated C# source file. Either you can
157 | right-click editor and select `Organize Usings > Remove and sort` OR use extension
158 | like [BatchFormat](http://visualstudiogallery.msdn.microsoft.com/a7f75c34-82b4-4357-9c66-c18e32b9393e).
159 | - Before committing, run Code Analysis in `Debug` configuration and follow the guidelines
160 | to fix CA issues. Code Analysis commits can be made separately.
161 |
--------------------------------------------------------------------------------
/src/CssAutoPrefixer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(VisualStudioVersion)
6 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
7 | true
8 | v3
9 | Program
10 | $(DevEnvDir)\devenv.exe
11 | /rootsuffix Exp
12 |
13 |
14 |
15 |
16 |
17 | Debug
18 | AnyCPU
19 | 2.0
20 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
21 | {D1F752E5-6CAB-4513-980A-51B44E104CDF}
22 | Library
23 | Properties
24 | CssAutoPrefixer
25 | CssAutoPrefixer
26 | v4.5.2
27 | true
28 | true
29 | true
30 | true
31 | true
32 | false
33 |
34 |
35 | true
36 | full
37 | false
38 | bin\Debug\
39 | DEBUG;TRACE
40 | prompt
41 | 4
42 |
43 |
44 | pdbonly
45 | true
46 | bin\Release\
47 | TRACE
48 | prompt
49 | 4
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | True
61 | True
62 | source.extension.vsixmanifest
63 |
64 |
65 | True
66 | True
67 | VSCommandTable.vsct
68 |
69 |
70 |
71 |
72 | Resources\LICENSE
73 | true
74 |
75 |
76 |
77 | Designer
78 | VsixManifestGenerator
79 | source.extension.cs
80 |
81 |
82 |
83 |
84 | False
85 | False
86 |
87 |
88 | False
89 | False
90 |
91 |
92 | False
93 | False
94 |
95 |
96 | False
97 | False
98 |
99 |
100 |
101 |
102 | False
103 | False
104 |
105 |
106 | ..\packages\Microsoft.VisualStudio.CoreUtility.14.3.25407\lib\net45\Microsoft.VisualStudio.CoreUtility.dll
107 | False
108 |
109 |
110 | ..\packages\Microsoft.VisualStudio.Editor.14.3.25407\lib\net45\Microsoft.VisualStudio.Editor.dll
111 | False
112 |
113 |
114 | ..\packages\Microsoft.VisualStudio.Imaging.14.3.25407\lib\net45\Microsoft.VisualStudio.Imaging.dll
115 | False
116 |
117 |
118 | ..\packages\Microsoft.VisualStudio.OLE.Interop.7.10.6070\lib\Microsoft.VisualStudio.OLE.Interop.dll
119 | False
120 |
121 |
122 | ..\packages\Microsoft.VisualStudio.Shell.14.0.14.3.25407\lib\Microsoft.VisualStudio.Shell.14.0.dll
123 | False
124 |
125 |
126 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.10.0.10.0.30319\lib\net40\Microsoft.VisualStudio.Shell.Immutable.10.0.dll
127 | False
128 |
129 |
130 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.11.0.11.0.50727\lib\net45\Microsoft.VisualStudio.Shell.Immutable.11.0.dll
131 | False
132 |
133 |
134 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.12.0.12.0.21003\lib\net45\Microsoft.VisualStudio.Shell.Immutable.12.0.dll
135 | False
136 |
137 |
138 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.14.0.14.3.25407\lib\net45\Microsoft.VisualStudio.Shell.Immutable.14.0.dll
139 | False
140 |
141 |
142 | ..\packages\Microsoft.VisualStudio.Shell.Interop.7.10.6071\lib\Microsoft.VisualStudio.Shell.Interop.dll
143 | False
144 |
145 |
146 | True
147 | ..\packages\Microsoft.VisualStudio.Shell.Interop.10.0.10.0.30319\lib\Microsoft.VisualStudio.Shell.Interop.10.0.dll
148 | True
149 |
150 |
151 | True
152 | ..\packages\Microsoft.VisualStudio.Shell.Interop.11.0.11.0.61030\lib\Microsoft.VisualStudio.Shell.Interop.11.0.dll
153 | True
154 |
155 |
156 | True
157 | ..\packages\Microsoft.VisualStudio.Shell.Interop.12.0.12.0.30110\lib\Microsoft.VisualStudio.Shell.Interop.12.0.dll
158 | True
159 |
160 |
161 | ..\packages\Microsoft.VisualStudio.Shell.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.Shell.Interop.8.0.dll
162 | False
163 |
164 |
165 | ..\packages\Microsoft.VisualStudio.Shell.Interop.9.0.9.0.30729\lib\Microsoft.VisualStudio.Shell.Interop.9.0.dll
166 | False
167 |
168 |
169 | ..\packages\Microsoft.VisualStudio.Text.Data.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.Data.dll
170 | False
171 |
172 |
173 | ..\packages\Microsoft.VisualStudio.Text.Logic.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.Logic.dll
174 | False
175 |
176 |
177 | ..\packages\Microsoft.VisualStudio.Text.UI.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.UI.dll
178 | False
179 |
180 |
181 | ..\packages\Microsoft.VisualStudio.Text.UI.Wpf.14.3.25407\lib\net45\Microsoft.VisualStudio.Text.UI.Wpf.dll
182 | False
183 |
184 |
185 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.7.10.6070\lib\Microsoft.VisualStudio.TextManager.Interop.dll
186 | False
187 |
188 |
189 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.TextManager.Interop.8.0.dll
190 | False
191 |
192 |
193 | ..\packages\Microsoft.VisualStudio.Threading.14.1.111\lib\net45\Microsoft.VisualStudio.Threading.dll
194 | False
195 |
196 |
197 | ..\packages\Microsoft.VisualStudio.Utilities.14.3.25407\lib\net45\Microsoft.VisualStudio.Utilities.dll
198 | False
199 |
200 |
201 | ..\packages\Microsoft.VisualStudio.Validation.14.1.111\lib\net45\Microsoft.VisualStudio.Validation.dll
202 | False
203 |
204 |
205 | False
206 | False
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 | Menus.ctmenu
218 | VsctGenerator
219 | VSCommandTable.cs
220 |
221 |
222 |
223 |
224 | true
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
233 |
234 |
235 |
236 |
237 |
238 |
239 |
246 |
--------------------------------------------------------------------------------