Pular para conteúdo

Plugins Python

O Modular Text Editor carrega plugins Python ao lado dos nativos em C++ pela mesma superfície de gerenciamento de plugins. Um plugin Python é uma pasta contendo um plugin.json e ao menos um arquivo .py com uma função register(ctx) de nível superior.

O editor gera um pequeno subprocesso trabalhador por plugin, executa register(ctx) dentro dele e transporta comandos / menus / eventos por um canal RPC. Seu plugin nunca toca no Qt nem no Scintilla — o objeto ctx é um localizador de serviços Python puro.

O que funciona hoje (fases 1–5: funcionalidade completa)

Fase 1: comandos, itens de menu, assinaturas de evento (abrir / fechar / salvar / documento ativo alterado / seleção alterada / saída do aplicativo), o log, a barra de status.

Fase 2: buffer do editor / seleção / cursor / busca / recuo / operações de arquivo via ctx.editor.*, configurações persistentes via ctx.settings.* e configurações do aplicativo somente leitura via ctx.app_settings.*, provedores de autocompletar (com um pequeno prazo por tecla) via @ctx.completions.provider(...), e ctx.data_dir() para o diretório gravável de cada plugin.

Fase 3: painéis acopláveis declarativos via ctx.docks.add_panel(...), páginas de Preferências via ctx.settings_page.register(...), ambos construídos com os construtores de formulários mte.ui, e acesso aos controles em tempo de execução via ctx.ui.get / ctx.ui.set.

Fase 4: instalador de pacotes .mteplugin — compacte a pasta do seu plugin e instale-a por Preferências → Plug-ins (veja Empacotamento).

Fase 5: ambientes virtuais por plugin — declare as dependências do pip em pyRequires e o editor provisiona um ambiente virtual para o seu plugin na primeira inicialização (veja Dependências); uma declaração de permissions exibida na página de Plugins; e um substrato RPC com fluxo e cancelamento (ainda sem API voltada aos plugins — ele sustenta os futuros serviços de IA).

Plugin mínimo

Crie <any-folder>/hello/ com estes dois arquivos.

hello/plugin.json
{
  "id":         "org.example.hello",
  "name":       "Hello (Python)",
  "version":    "1.0.0",
  "apiVersion": 1,
  "entry":      "python",
  "module":     "main",
  "menus": [
    { "title": "Plugins", "barPriority": 570, "itemPriority": 100 }
  ]
}
hello/main.py
import mte  # noqa: F401


def register(ctx):

    @ctx.commands.command(id="hello.sayHi",
                          title="Say Hi",
                          shortcut="Ctrl+Alt+H")
    def _say_hi():
        ctx.status.show("Hello from Python!", timeout_ms=3000)
        ctx.log.info("hello: Say Hi invoked")

    ctx.menus.add_item("Plugins/Hello/Say Hi", "hello.sayHi")

Compacte a pasta como hello.mteplugin e instale-a por Preferências → Plug-ins → Instalar um plug-in... — ou coloque a pasta manualmente no seu diretório de plugins por usuário (veja Empacotamento). Reinicie o editor e Plugins → Hello → Say Hi aparece na barra de menus.

O que você precisa ter na máquina

  • Um interpretador Python 3.9+ alcançável de uma de duas formas:
    • No PATH (py.exe, python.exe ou python3.exe no Windows; python3 no macOS/Linux), ou
    • Apontado pela variável de ambiente MTE_PYTHON (ou um caminho absoluto para um python.exe, ou um nome simples a ser procurado no PATH).
  • Nenhum pacote pip: a biblioteca cliente mte da fase 1 vem com o editor e é acrescentada ao sys.path por você.

O editor registra no log qual interpretador selecionou na inicialização:

PluginHost: MTE_PYTHON is not set; falling back to PATH.
PluginHost: located Python on PATH: py.exe -> C:/Windows/py.exe
PluginHost: Python plugin backend enabled; interpreter=..., worker=.../mte_python_host.py

Se você vir Python plugins disabled, vá para Solução de problemas.

O que o seu plugin pode fazer

Cada item abaixo leva à seção de API dele:

Capacidade Seção
Registrar comandos (com atalho de teclado opcional) ctx.commands
Contribuir itens de menu e separadores ctx.menus
Assinar todos os eventos do editor (documentos, texto, seleção, configurações, tema, espaço de trabalho, …) e publicar os do espaço de trabalho ctx.events e a referência de eventos
Escrever no fluxo de diagnóstico do editor ctx.log
Publicar mensagens passageiras na barra de status e ser dono de um segmento persistente ctx.status
Ler/modificar buffers, seleções (inclusive com vários cursores), cursor, arquivos, busca, marcadores, marcas, realce de URL, recuo, grupos de visualização dividida ctx.editor
Listar linguagens, ler / trocar a linguagem de um documento, contribuir uma definição de linguagem ctx.languages
Persistir configuração por plugin, ler as configurações do aplicativo (mte.keys), ler configurações por documento em camadas com .editorconfig ctx.settings / ctx.app_settings / ctx.document_settings
Publicar diagnósticos (traços ondulados e glifos de margem) ctx.diagnostics
Registrar cores adaptáveis ao tema para a sua própria interface ctx.theme
Abrir a visualização de comparação lado a lado ctx.compare
Registrar um provedor de autocompletar (com um prazo por tecla) ctx.completions
Localizar o seu diretório gravável por plugin ctx.data_dir()
Acrescentar um painel acoplável declarativo e exibi-lo/ocultá-lo por um comando ctx.docks e mte.ui
Acrescentar uma página nas Preferências ctx.settings_page
Ler / escrever controles de painel em tempo de execução ctx.ui
Alternar uma marca de verificação persistente em um item de menu ctx.menus.set_item_checked
Esmaecer um item de menu enquanto o comando dele não pode rodar ctx.menus.set_item_enabled

O que vem a seguir