Compartilhar via


Crie uma extensão simples

Em Criar sua primeira extensão, você aprendeu a usar o modelo de projeto VisualStudio.Extensibility para criar um projeto de extensão e aprendeu como criá-lo e depurá-lo na instância experimental do Visual Studio.

Neste tutorial, você aprenderá a criar uma extensão com um comando simples que faz algo no editor do Visual Studio. Nesse caso, ele insere um GUID recém-gerado. Você também verá como informar ao Visual Studio para quais tipos de arquivo a extensão GUID está habilitada e como fazer com que o novo comando apareça como uma barra de ferramentas ou item de menu.

O exemplo completo para este tutorial pode ser encontrado aqui.

O tutorial contém as seguintes etapas:

Configurar o comando

Nesta etapa, você aprenderá sobre as opções para configurar e colocar o comando. O objetivo de hospedar o comando é expô-lo ao usuário de alguma forma, como adicionar um item de menu ou um botão da barra de comandos.

O modelo de projeto ou o exemplo criado no tutorial Criar sua primeira extensão consiste em um único arquivo C# que já inclui uma Command classe. Você pode atualizar isso no lugar.

  1. Renomeie o arquivo para , renomeie Command1.cs a classe InsertGuidCommand, atualize a CommandConfiguration propriedade.InsertGuidCommand.cs

    public override CommandConfiguration CommandConfiguration => new("%InsertGuidCommand.DisplayName%")
    {
        Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu },
    };
    

    Placements especifica onde o comando deve aparecer no IDE. Nesse caso, o comando é colocado no menu Extensões, um dos menus de nível superior no Visual Studio.

    O argumento para o construtor é o nome de exibição do comando, que é o CommandConfiguration texto do menu. O nome de exibição é delimitado por % caracteres porque faz referência a um recurso de cadeia de caracteres para .vsextension/string-resources.json oferecer suporte à localização.

  2. Atualizar .vsextension/string-resources.json com o nome de exibição do InsertGuidCommand.

    {
      "InsertGuidCommand.DisplayName": "Insert new guid"
    }
    
  3. Adicione a propriedade Icon.

    public override CommandConfiguration CommandConfiguration => new("%InsertGuidCommand.DisplayName%")
    {
        Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu },
        Icon = new(ImageMoniker.KnownValues.OfficeWebExtension, IconSettings.IconAndText),
    };
    

    Você pode especificar um ícone interno conhecido, neste caso OfficeWebExtension, ou carregar imagens para o ícone, conforme descrito em Adicionar comandos do Visual Studio. O segundo argumento é uma enumeração que determina como o comando deve aparecer nas barras de ferramentas (além de seu lugar em um menu). A opção IconSettings.IconAndText significa mostrar o ícone e o nome de exibição um ao lado do outro.

  4. Adicione a VisibleWhen propriedade, que especifica as condições que devem ser aplicadas para que o item apareça para o usuário.

    public override CommandConfiguration CommandConfiguration => new("%InsertGuidCommand.DisplayName%")
    {
        Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu },
        Icon = new(ImageMoniker.KnownValues.OfficeWebExtension, IconSettings.IconAndText),
        VisibleWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveEditorContentType, ".+"),
    };
    

Consulte Usando restrições de ativação baseadas em regras para obter mais informações.

Criar o método de execução

Nesta etapa, você implementa o método do ExecuteCommandAsync comando, que define o que acontece quando o usuário escolhe o item de menu ou pressiona o item na barra de ferramentas do comando.

Copie o código a seguir para implementar o método.

public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
    {
        Requires.NotNull(context, nameof(context));
        var newGuidString = Guid.NewGuid().ToString("N", CultureInfo.CurrentCulture);

        using var textView = await context.GetActiveTextViewAsync(cancellationToken);
        if (textView is null)
        {
            this.logger.TraceInformation("There was no active text view when command is executed.");
            return;
        }

        await this.Extensibility.Editor().EditAsync(
            batch =>
            {
                textView.Document.AsEditable(batch).Replace(textView.Selection.Extent, newGuidString);
            },
            cancellationToken);
    }

A primeira linha valida os argumentos e, em seguida, criamos um novo Guid para usar mais tarde.

Em seguida, criamos um ITextViewSnapshot (o objeto aqui) chamando o textView método GetActiveTextViewAsyncassíncrono . Um token de cancelamento é passado para preservar a capacidade de cancelar a solicitação assíncrona, mas essa parte não é demonstrada neste exemplo. Se não obtivermos uma visualização de texto com sucesso, gravamos no log e encerramos sem fazer mais nada.

Agora estamos prontos para chamar o método assíncrono que envia uma solicitação de edição ao editor do Visual Studio. O método que queremos é EditAsync. Esse é um membro da classe, que permite a EditorExtensibility interação com o Editor do Visual Studio em execução no IDE. O Command tipo, do qual sua própria InsertGuidCommand classe herda, tem um membro Extensibility que fornece acesso ao EditorExtensibility objeto, para que possamos chegar à EditorExtensibility classe com uma chamada para this.Extensibility.Editor().

O EditAsync método usa um Action<IEditBatch> como parâmetro. Esse parâmetro é chamado editorSourcede ,

A chamada para EditAsync usa uma expressão lambda. Para detalhar um pouco isso, você também pode escrever essa chamada da seguinte maneira:

await this.Extensibility.Editor().EditAsync(
    batch =>
    {
        var editor = textView.Document.AsEditable(batch);
        // specify the desired changes here:
        editor.Replace(textView.Selection.Extent, newGuidString);
    },
    cancellationToken);

Você pode pensar nessa chamada como especificando o código que você deseja que seja executado no processo do editor do Visual Studio. A expressão lambda especifica o que você deseja alterar no editor. O batch é do tipo IEditBatch, o que implica que a expressão lambda definida aqui faz um pequeno conjunto de alterações que devem ser realizadas como uma unidade, em vez de serem interrompidas por outras edições pelo usuário ou serviço de idioma. Se o código for executado por muito tempo, isso pode levar à falta de resposta, por isso é importante manter as alterações dentro dessa expressão lambda limitadas e entender qualquer coisa que possa levar a atrasos.

Usando o AsEditable método no documento, você obtém um objeto de editor temporário que pode ser usado para especificar as alterações desejadas. Pense em tudo na expressão lambda como uma solicitação para o Visual Studio executar em vez de como realmente em execução, porque, conforme descrito em Usar extensibilidade do editor do Visual Studio, há um protocolo específico para lidar com essas solicitações de edição assíncronas de extensões, e há uma possibilidade de as alterações não serem aceitas, como se o usuário estiver fazendo alterações ao mesmo tempo que criem um conflito.

O EditAsync padrão pode ser usado para modificar o texto em geral, especificando suas modificações após o comentário "especifique suas alterações desejadas aqui".