GithubHelp home page GithubHelp logo

madskristensen / community.visualstudio.toolkit Goto Github PK

View Code? Open in Web Editor NEW
24.0 10.0 3.0 680 KB

A community toolkit for writing Visual Studio extensions

License: Other

C# 100.00%
visual-studio-extensions nuget

community.visualstudio.toolkit's Introduction

community.visualstudio.toolkit's People

Contributors

bluetarpmedia avatar japj avatar madskristensen avatar reduckted avatar sql-mistermagoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

community.visualstudio.toolkit's Issues

Make VSCT menu IDs more discoverable

I don't know about anyone else, but names like IDG_VS_WNDO_OTRWNDWS1 aren't exactly clear about what they refer to. ๐Ÿคฃ

It would be great if this package could some how define aliases for these IDs so that they were more discoverable.

For example, IDG_VS_WNDO_OTRWNDWS1 could be Group_View_OtherWindows.

[Proposal] Make VSGlobals.vsct available via nuget as part of Community.VisualStudio.Toolkit

I loved the new stuff for VSGlobals.vsct as part of #21 but thought rather than having the file as part of the template, make it part of the nuget package and therefore updatable when new names get added.

I did some quick experimentation and came up with some stuff that I think works at CZEMacLeod/Community.VisualStudio.Toolkit.VSGlobals.VSCT

Very basically, it adds a new Item type VSCTInclude to go with the existing VSCTCompile. It then ensures that any items of this type have their paths added to the include directories for the VSCTCompile task.

Then, if you have any VSCTCompile items in your project, it adds the VSGlobals.vsct file from the package as an VSCTInclude item.

I also added a quick check to give you a warning if you have VSCTInclude items that are not actually included in your VSCTCompile files.

e.g. if you missed out the

<Include href="VSGlobals.vsct"/>

I did a quick check with a modified version of the community template, and to make it easier to test, I also created a 'short form' or SDK style VSIX project. (It does work there too, and builds and debugs, although some of the editors such as the manifest editor refuse to work as it is the wrong project type.)

If you like the idea of this - feel free to take as much or as little as you like.

I think the project as it stands works without CVST or any extensions, and provides the VSCTInclude functionality, so it could either get contributed to Microsoft.VSSDK.BuildTools or be made a dependency of CVST and just the VSGlobals.vcst file moved here.

VS.MessageBox.ShowXXX to hide the ugliness of VsShellUtilities.ShowMessageBox

In Luminous Code & in Start Page+'s DialogService, I have various message helpers, but I was using WPF's MessageBox.Show which I learned recently in one of Mads's shows that it shouldn't be done that way. A perfect example of the raison d'etre for VSSDK.Helpers! Or Microsoft.Toolbox.VSSDK as I've suggested in issue #2.

I then built on that to have:

public Result ShowMessage(string message, string title = null, Button button = Button.OK, Icon icon = Icon.None)
    => MessageBox.Show(message, title ?? Vsix.Name, button, icon);

public void ShowExclamation(string message, string title = null)
    => ShowMessage(message, title, button: Button.OK, icon: Icon.Exclamation);

public void ShowWarning(string message, string title = null)
    => ShowMessage(message, title, button: Button.OK, icon: Icon.Warning);

public void ShowError(string message, string title = null)
    => ShowMessage(message, title, button: Button.OK, icon: Icon.Error);

public void ShowError(Exception ex, bool extendedMessage = true)
    => ShowError(extendedMessage ? ex.ExtendedMessage() : ex.Message);

public Result ShowConfirm(string question, string title = null, Button button = Button.YesNo)
    => ShowMessage(question, title: title ?? "Please Confirm", button, icon: Icon.Question);

Building on that idea, we could have:

VS.MessageBox.ShowExclamation
VS.MessageBox.ShowWarning
VS.MessageBox.ShowError
VS.MessageBox.ShowConfirm (or better maybe VS.MessageBox.GetConfirmation)

etc

Writing code like:


VSSDK Community Toolkit (Microsoft.Toolkit.VSSDK)

As James suggested, using a name like VSSDK Community Toolkit would fit in well with:

  • Windows Community Toolkit
  • UDP Community Toolkit
  • Xamarin Community Toolkit
  • Microsoft MVVM Toolkit
  • etc

And a perfect namespace could be Microsoft.Toolkit.VSSDK, again in line with the namespaces in the toolkits mentioned above.

A natural extension (no pun intended) would be namespaces like:

  • Microsoft.Toolkit.VSSDK.UI
  • Microsoft.Toolkit.VSSDK.UI.Controls
  • Microsoft.Toolkit.VSSDK.ProjectTemplates
  • Microsoft.Toolkit.VSSDK.ItemTemplates
  • etc

If this idea is accepted, I'd also suggest that the repo should be renamed Microsoft.Toolkit.VSSDK. It's early enough that only a few people would have to adjust. Or maybe just create a new repo, and archive this one.

Develop API to read .editorconfig settings for a file that is part of a solution

For a project that I am working on we want to add support for .editorconfig.
We want to read some settings (like C# does) for editor options, such as formatting and code style.
I know there is some support for this in VS, but is very well hidden..
It would be nice if we could add something like Vs.Editor.GetConfigOption( strFileName, strOption, strDefault) that would automatically

  • extract the extension from the filename
  • find the "nearest" .editorconfig file in the solution/project hierarchy
  • read the value and return it or return the default when it does not exist

I am sure other developers for 3rd party languages will need (or already have) this as well. If we have a standardized API with possibly standardized caching of values that would life much easier for everybody and would reduce the amount of duplicate code.

Solution methods design (GetSelectedItemAsync, and more)

GetSelectedItemAsync

        /// <summary>
        /// Returns either a Project or ProjectItem. Returns null if Solution is Selected.
        /// </summary>
        public async Task<object?> GetSelectedItemAsync()

what if I select solution AND file(s)? will I get the selected file(s) only? Looks strange from my point of view.

I would suggest to include a solution into allowed results.

GetAllSelectedProjectItems

If 1 will be accepted, do we want a new method like GetAllSelectedProjectItems that returns not only selected ProjectItems directly, but also recursively?

GetSelectedItemFilePathsAsync

I can't play with this nuget now, but I'm not sure if this method returns xaml.cs file in case I select .xaml file. If so, we need to expand its description to enlight these details.

WPF Theming

First of all, thanks for this library @madskristensen! I think it's going to be a great asset for extension authors. Now, onto the issue.

It would be great to have your VSTheme helper class that applies the current Visual Studio theme to dialogs and other controls as part of this library.

I'm not sure if these are a new addition to the Visual Studio SDK, but I've recently used ThemedDialogStyleLoader.UseDefaultThemedDialogStyles and ImageThemingUtilities.ThemeScrollBars to style a dialog. Perhaps they supersede part or all of the VSTheme helpers, or maybe they are complimentary?

GitHub Action NuGet Publish Alternative?

Is it worth also having an example of how to publish using GitHub Actions too?

name: Publish to NuGet

on:
  push:
    branches:
      - main # Your default release branch
    paths:
      - 'src/**'

jobs:
  publish:
    name: Publish to NuGet
    runs-on: windows-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      
      - name: Setup dotnet
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: 3.1.100
      
      - name: Publish
        uses: rohith/publish-nuget@v2
        #uses: brandedoutcast/[email protected]
        with:
          PROJECT_FILE_PATH: src/VSSDK.Helpers.15.0/VSSDK.Helpers.15.0.csproj
          NUGET_KEY: ${{secrets.NUGET_API_KEY}} # nuget.org API key

Async Tool Window Helpers

Creating async tool windows is a pain. There are three methods in the AsyncPackage that you need to override, and it's not obvious that you should override all three of those methods. Plus there are some overridable methods for non-async tool windows, which adds to the confusion.

There's also some boilerplate code for creating/showing the tool window (which differs between VS 15 and 16) that could be put in a helper method.

Proposed API

Registering a Tool Window

We will need a new base class for packages to inherit from. This will provide helper methods for registering the tool window.

This base class would override the GetAsyncToolWindowFactory, GetToolWindowTitle and InitializeToolWindowAsync methods (and the equivalents for VS15) to take care of the work required to create a tool window.

abstract class ToolkitPackage : AsyncPackage {
    void AddToolWindow<T>(string title);
    void AddToolWindow<T>(string title, Func<object> initializer);
    void AddToolWindow<T>(string title, Func<Taks<object>> initializer);
}

The AddToolWindow method would be called by the derived class in the InitializeAsync method (similar to how you would use the existing AsyncPackage.AddOptionKey and AsyncPackage.AddService methods).

The generic parameter T is the type of the tool window. This would be used by GetAsyncToolWindowFactory. The title would be used by GetToolWindowTitle, and the initializer function would be used by InitializeToolWindowAsync.

Opening a Tool Window

The boilerplate code for opening a tool window can also be put in the new ToolkitPackage.

abstract class ToolkitPackage : AsyncPackage {
    public Task<T> ShowToolWindowAsync<T>(CancellationToken cancellationToken = default);
}

Examples

Adding a Tool Window

public sealed class TestExtensionPackage : ToolkitPackage
{
    protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
    {
        AddToolWindow<RunnerWindow>(RunnerWindow.Title, async () =>
        {
            await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
            return await VS.GetDTEAsync();
        });

        AddToolWindow<ThemeWindow>(ThemeWindow.Title, () => new ThemeWindowControlViewModel());
    }
}

Opening a Tool Window

protected override async Task ExecuteAsync(OleMenuCmdEventArgs e)
{
    await Package.ShowToolWindowAsync<RunnerWindow>();
}

Notes

The ToolkitPackage would need to be passed around everywhere instead of an AsyncPackage so that the helper method to open a tool window is accessible. For example, CommandBase.InitializeAsync would need to take a ToolkitPackage rather than an AsyncPackage so that the derived classes can use ShowToolWindowAsync.

Prototype

I've thrown together a prototype here: master...reduckted:prototype/async-tool-window

If you like this idea, I'll clean it up and create a pull request.

[Docs] Example Publish to Marketplace

Is it worth adding a WIKI with steps to do things?

If you upload a release then publish it:

name: Publish

on:
  release:
    types:
      - released

jobs:
  main:
    runs-on: windows-latest

    steps:
      - uses: actions/checkout@v2
      
      - name: Download Assets
        uses: i3h/[email protected]
        with:
          owner: ${{ github.event.repository.owner.login }}
          repo: ${{ github.event.repository.name }}
          tag: ${{ github.event.release.tag_name }}
          file: EXTNAME.vsix
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Script
        run: |
          # Find VsixPublisher
          $Installation = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -format json | ConvertFrom-Json
          $Path = $Installation.installationPath
          Write-Host $Path
          $VsixPublisher = Join-Path -Path $Path -ChildPath "VSSDK\VisualStudioIntegration\Tools\Bin\VsixPublisher.exe" -Resolve
          & $VsixPublisher publish -payload ".\ EXTNAME.vsix" -publishManifest ".\build\extension-manifest.json" -personalAccessToken $env:PersonalAccessToken -ignoreWarnings "VSIXValidatorWarning01,VSIXValidatorWarning02,VSIXValidatorWarning08"
        env:
          PersonalAccessToken: ${{ secrets.PERSONAL_ACCESS_TOKEN }}

Prefer AsyncPackage.JoinableTaskFactory when running async tasks instead of ThreadHelper

My understanding is that best practice is to use the AsyncPackage JTF when running async tasks instead of ThreadHelper so that VS can ensure they finish/cancel correctly before shutdown.

"But you generally should prefer your own AsyncPackage.JoinableTaskFactory instance over ThreadHelper.JoinableTaskFactory so that any async work you execute will be tracked and will block IDE shutdown till its done." -- Andrew Arnott (NuGet/Home#8317 (comment))

See also:
https://github.com/microsoft/vs-threading/blob/main/doc/cookbook_vs.md#how-do-i-effectively-verify-that-my-code-is-fully-free-threaded

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.