33

Estoy tratando de comenzar en las extensiones de Visual Studio (2010) y estoy teniendo dificultades para encontrar los materiales correctos. Tengo el SDK, pero las muestras incluidas parecen ser cosas como adornos, ventanas e íconos.Extensión de Visual Studio Text Editor

Estoy tratando de hacer una extensión que funcione directamente con el editor de texto (para alfabetizar todos mis nombres de método en una clase, o hacer mayúsculas todos los nombres constantes, por ejemplo) pero no puedo encontrar una demo para este tipo de funcionalidad, o incluso un tutorial.

¿Alguien sabe dónde puedo encontrar este tipo de cosas?

+0

@ Pac-Man: Tristemente tuve que dejarlo en un segundo plano (debido a la falta de recursos para encontrarlo), así que nunca lo logré. Si alguna vez lo resuelvo, te lo haré saber. Para operaciones pequeñas, he encontrado que escribir macros funciona bastante bien. –

+0

@ Pac-Man: Eso sería excelente de hecho. Siento tu dolor por las cosas de MSDN (a veces). Lamentablemente, creo que esta extensión es solo una de esas 'artes negras' –

+0

Espero que mi enlace en la respuesta que publique pueda ayudarlo. Esos tutoriales me explican bastante todo lo que necesito saber acerca de los complementos de VS a pesar de que faltan las capturas de pantalla. –

Respuesta

54

que tenía exactamente la misma pregunta y ahora han navegado por la web varias horas hasta que fue el poder para comprender y explicar cómo necesitarías comenzar con esa extensión.

En mi ejemplo siguiente crearemos una extensión pequeña y tonta que siempre agregará "Hola" al comienzo de un archivo de código cuando se haya realizado una edición. Es muy básico, pero debería darle una idea de cómo continuar desarrollando esta cosa.

Tenga cuidado: usted tiene que analizar los archivos de código completamente por su cuenta - Visual Studio no le da ninguna información acerca de dónde están las clases, métodos o lo que sea y qué contienen. Ese es el mayor obstáculo que se debe tomar al hacer una herramienta de formato de código y no se tratará en esta respuesta. [*]

Para aquellos que omitieron esta respuesta, asegúrese de haber descargado e instalado primero el SDK de Visual Studio o no encontrará el tipo de proyecto mencionado en el paso uno.

Creación del proyecto

  1. de inicio mediante la creación de un nuevo proyecto del tipo "Visual C#> extensibilidad> Proyecto VSIX" (sólo visible si se ha seleccionado .NET Framework 4 como el marco de destino). Tenga en cuenta que es posible que tenga que seleccionar el tipo de proyecto "Editor clasificador" en lugar del tipo "Proyecto VSIX" para que funcione, s. Comenta abajo.

  2. Una vez creado el proyecto, se abrirá el archivo "source.extension.vsixmanifest", que le da la posibilidad de configurar el nombre del producto, autor, versión, descripción, icono y así sucesivamente. Creo que este paso es bastante autoexplicativo, puede cerrar la pestaña ahora y restaurarla más tarde abriendo el archivo vsixmanifest.

Creación de una clase de escucha para ser notificado acerca de instancia creaciones de edición de texto

A continuación, tenemos que escuchar cada vez que un editor de texto ha sido creado en Visual Studio y unir nuestra formato de código herramienta para ello. Un editor de texto en VS2010 es una instancia de IWpfTextView.

  1. Agregue una nueva clase a nuestro proyecto y llámelo TextViewCreationListener. Esta clase tiene que implementar la interfaz Microsoft.VisualStudio.Text.Editor.IWpfTextViewCreationListener. Debe agregar una referencia al Microsoft.VisualStudio.Text.UI.Wpf a su proyecto. La DLL de ensamblado se encuentra en su directorio de Visual Studio SDK en VisualStudioIntegration \ Common \ Assemblies \ v4.0.

  2. Tiene que implementar el método TextViewCreated de la interfaz. Este método tiene un parámetro que especifica la instancia del editor de texto que se ha creado. Crearemos una nueva clase de formato de código a la que esta instancia pasará más adelante.

  3. Necesitamos hacer que la clase TextViewCreationListener sea visible para Visual Studio especificando el atributo [Export(typeof(IWpfTextViewCreationListener))]. Agregue una referencia a System.ComponentModel.Composition a su proyecto para el atributo Export.

  4. Además, tenemos que especificar con qué tipos de archivos el formateador de código debe vincularse al editor de texto. Solo nos gusta formatear archivos de código y no archivos de texto sin formato, por lo que agregamos el atributo [ContentType("code")] a la clase de escucha. Tiene que agregar una referencia a Microsoft.VisualStudio.CoreUtility a su proyecto para esto.

  5. Además, solo queremos cambiar el código editable y no los colores o adornos que lo rodean (como se ve en los proyectos de ejemplo), así que agregamos el atributo [TextViewRole(PredefinedTextViewRoles.Editable)] a la clase. Nuevamente necesita una nueva referencia, esta vez a Microsoft.VisualStudio.Text.UI.

  6. Marque la clase como sellado interno. Al menos esa es mi recomendación. Ahora su clase debe ser similar a esto:

    [ContentType("code")] 
    [Export(typeof(IWpfTextViewCreationListener))] 
    [TextViewRole(PredefinedTextViewRoles.Editable)] 
    internal sealed class TextViewCreationListener : IWpfTextViewCreationListener 
    { 
        public void TextViewCreated(IWpfTextView textView) 
        { 
        } 
    } 
    

Creación de una clase de formato de código

A continuación, es necesario un manejo de la lógica de formato de código de clase, métodos de ordenación y así sucesivamente. Nuevamente, en este ejemplo, simplemente agregará "Hola" al inicio del archivo cada vez que se realice una edición.

  1. Agregue una nueva clase llamada Formatter a su proyecto.

  2. Agregue un constructor que tome un argumento IWpfTextView. Recuerde que queríamos pasar la instancia del editor creado a esta clase de formato en el método TextViewCreated de nuestra clase de escucha (simplemente agregue new Formatter(textView); al método allí).

  3. Guarde la instancia pasada en una variable miembro. Será útil al formatear el código más tarde (por ejemplo, para recuperar la posición de intercalación). También atar los Changed y PostChanged acontecimientos de la propiedad TextBuffer de la instancia del editor:

    public Formatter(IWpfTextView view) 
    { 
        _view = view; 
        _view.TextBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(TextBuffer_Changed); 
        _view.TextBuffer.PostChanged += new EventHandler(TextBuffer_PostChanged); 
    } 
    
  4. El Changed evento se llama cada vez que una edición ha sido hecha (tecleando por ejemplo, un char, pegar código o cambios programáticos). Como también reacciona a los cambios programáticos, utilizo un bool que determina si nuestra extensión o el usuario/cualquier otra cosa está cambiando el código en este momento y llamo a mi método personalizado FormatCode() solo si nuestra extensión no se está editando.De lo contrario se le llama a este método de forma recursiva, que se estrellaría Visual Studio:

    private void TextBuffer_Changed(object sender, TextContentChangedEventArgs e) 
    { 
        if (!_isChangingText) 
        { 
         _isChangingText = true; 
         FormatCode(e); 
        } 
    } 
    
  5. Tenemos que restablecer esta variable miembro bool en el controlador PostChanged caso de nuevo para false.

  6. Pasemos los eventos args del evento Changed a nuestro método personalizado FormatCode porque contienen lo que ha cambiado entre la última edición y ahora. Esas ediciones se almacenan en la matriz e.Changes del tipo INormalizedTextChangeCollection (s, el enlace al final de mi publicación para obtener más información acerca de este tipo). Pasamos por todas esas ediciones y llamamos a nuestro método personalizado HandleChange con el nuevo texto que ha producido esta edición.

    private void FormatCode(TextContentChangedEventArgs e) 
    { 
        if (e.Changes != null) 
        { 
         for (int i = 0; i < e.Changes.Count; i++) 
         { 
          HandleChange(e.Changes[0].NewText); 
         } 
        } 
    } 
    
  7. En el método HandleChange que podríamos explorar en busca de palabras clave para manejar los de una manera específica (recuerde, usted tiene que analizar cualquier código en sí mismo!) - pero aquí simplemente en silencio añadimos "Hola" a la inicio del archivo para fines de prueba. P.ej. tenemos que cambiar el TextBuffer de nuestra instancia de editor. Para hacerlo, necesitamos crear un objeto ITextEdit con el que podamos manipular el texto y aplicar sus cambios posteriormente. El código es bastante autoexplicativo:

    private void HandleChange(string newText) 
    { 
        ITextEdit edit = _view.TextBuffer.CreateEdit(); 
        edit.Insert(0, "Hello"); 
        edit.Apply(); 
    } 
    

Al compilar este complemento, una colmena experimental de Visual Studio se inicia con sólo nuestra extensión cargado. Crea un nuevo archivo C# y comienza a escribir para ver los resultados.

Espero que esto le dé algunas ideas de cómo continuar en este tema. Tengo que explorarlo yo mismo ahora.

Recomiendo mucho la documentación del modelo de texto del editor en MSDN para obtener pistas sobre cómo puede hacer esto y aquello. http://msdn.microsoft.com/en-us/library/dd885240.aspx#textmodel


Notas al pie

[*] Tenga en cuenta que Visual Studio 2015 o más nuevos vienen con el compilador de Plataforma Rosyln, que de hecho ya se analiza archivos C# y VB.NET para usted (y probablemente otros pre -installed languages ​​also) y expone su estructura sintáctica jerárquica, pero aún no soy un experto en este tema para dar una respuesta sobre cómo usar estos nuevos servicios. El progreso básico de iniciar una extensión de editor sigue siendo el mismo que se describe en esta respuesta de todos modos. Tenga en cuenta que, si usa estos servicios, se volverá dependiente de Visual Studio 2015+ y la extensión no funcionará en versiones anteriores.

+0

Creé el programa según sus especificaciones. No está funcionando. Inserté algunos registros y no se están llamando a ningún método. ¿Algunas ideas? –

+3

Lo conseguí trabajando utilizando el tipo de proyecto "Editor Clasificador", en lugar del tipo de proyecto VISX. Tu demo y mi extensión funcionan a la perfección. –

+0

@Mike Christian: OK, no puedo verificar por qué el tipo de proyecto VISX no funcionó correctamente, pero agregué una nota al tipo de proyecto en mi respuesta. –

Cuestiones relacionadas