5

I'm trying to get into developing an extension for Visual Studio for Mac. I'm using this tutorial. Everything had been going well until I tried to run my extension. In my case "Insert date" in Edit submenu is disabled. While debugging I've noticed that IdeApp.Workbench.ActiveDocument.Editor is null despite I have an open document. Here's my code

using System;
using MonoDevelop.Components.Commands;
using MonoDevelop.Ide;

namespace ExampleIDEExtension
{
    public class InsertDateHandler : CommandHandler
    {
        protected override void Run()
        {
            var editor = IdeApp.Workbench.ActiveDocument.Editor;
            var currentTime = DateTime.Now.ToString();
            editor.InsertAtCaret(currentTime);
        }

        protected override void Update(CommandInfo info)
        {
            info.Enabled = IdeApp.Workbench.ActiveDocument.Editor != null;
        }
    }
}

I have no idea why Editor is null despite having an open document.

Wolen
  • 874
  • 6
  • 15
  • 1
    That code may work only with the old editor. For the new editor did you try the [new API](https://github.com/mono/monodevelop/wiki/New-Editor-API-Guide)? – Matt Ward Sep 22 '19 at 17:52

2 Answers2

5

The editor is null, as Monodevelop is using Microsoft.VisualStudio.Text.Editor and it mentions that the API has been obsolete in the below link.

https://github.com/mono/monodevelop/blob/50fbe0a7e65c5439e3313c6b50e7ef927f5f1fe9/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs

Anyways, to answer your question, this is what I had to do to achieve the insert date handler demo addin

    protected override void Run()
    {
        var textBuffer = IdeApp.Workbench.ActiveDocument.GetContent<ITextBuffer>();
        var date = DateTime.Now.ToString();
        var textView = IdeApp.Workbench.ActiveDocument.GetContent<ITextView>();
        var caretPosition = textView.Caret.Position;
        textBuffer.Insert(caretPosition.BufferPosition.Position,date);
    }

    protected override void Update(CommandInfo info)
    {
        var textBuffer = IdeApp.Workbench.ActiveDocument.GetContent<ITextBuffer>();
        if (textBuffer != null && textBuffer.AsTextContainer() is SourceTextContainer container)
        {
            var document = container.GetTextBuffer();
            if (document != null)
            {
                info.Enabled = true;
            }
        }
    }
vin
  • 1,258
  • 5
  • 20
  • 33
  • Thanks so much, I was struggling too, The docs are terrible, there is hardly any help on the internet. Your answer solved it BUT, for others you need to mention what the usings need to be: using System; using MonoDevelop.Components.Commands; using MonoDevelop.Ide; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.CodeAnalysis.Text; – Arkon3 Nov 13 '20 at 11:03
0

Just to embellish vin's answer for others still struggling with creating extensions on Visual Studio for Mac it needs to look like this in InsertDateHandler.cs:

using System;
using MonoDevelop.Components.Commands;
using MonoDevelop.Ide;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.CodeAnalysis.Text;

namespace DateInserter
{
    class InsertDateHandler : CommandHandler
    {
        protected override void Run()
        {
            var textBuffer =      IdeApp.Workbench.ActiveDocument.GetContent<ITextBuffer>();
        var date = DateTime.Now.ToString();
        var textView = IdeApp.Workbench.ActiveDocument.GetContent<ITextView>();
        var caretPosition = textView.Caret.Position;
        textBuffer.Insert(caretPosition.BufferPosition.Position, date);

    }

        protected override void Update(CommandInfo info)
        {
            var textBuffer =     IdeApp.Workbench.ActiveDocument.GetContent<ITextBuffer>();
            if (textBuffer != null && textBuffer.AsTextContainer() is     SourceTextContainer container)
            {
                var document = container.GetTextBuffer();
                if (document != null)
                {
                    info.Enabled = true;
                }
           }
       }
    }
}

The next piece of the puzzle that seems to be missing everywhere is just exactly how to package up the extension so you can both install it yourself in your version if Visual studio for mac and how to share the extension for others.

Here is how I do it:

Open Terminal on the Mac, navigate to the .dll you just created when you build the extension for example:

/volumes/ssd1/Myapps/VSCodeextensions/dateinserter/dateinserter/bin/debug/net472

Then create a .mpack file by doing this:-

% mono /Applications/"Visual Studio.app"/Contents/Resources/lib/monodevelop/bin/vstool.exe setup pack DateInserter.dll
Dharman
  • 30,962
  • 25
  • 85
  • 135
Arkon3
  • 63
  • 6