Introduction

Cela plusieurs années déjà que j’utilise Visual Studio Code et l’idée m’a pris de faire ma propre extension.

Il existe une documentation très bien faite sur la création d’une extension ainsi qu’une page décrivant bien les composants qui peuvent être personnalisés/ajoutés par une extension. Egalement, un projet GitHub permet d’avoir des exemples d’utilisation de ces composants.

Je ne vais pas reprendre un "hello world" mais plutôt les quelques astuces que j’ai glané ci et là pour ma v0.0.1, en espérant que cela puisse vous être utile.

Rendre invisible des commandes

J’ai ajouté des commandes qui devaient être appelées à partir de ma tree view et qui ne pouvait être appelé à partir de la commande de palette. On peut alors dans le package.json "désactiver" cette commande en ne l’affichant jamais :

{

    "contributes": {
        ...
        "menus": {
            "commandPalette": [
                {
                    "command": "mycommand",
                    "when": "never"
                },
                ...
            ]
        }
    }
}

Texte de bienvenue

Il est possible d’afficher un texte dans une vue (ou un Tree View) si cette vue ne contient rien et ainsi guider l’utilisateur pour ajouter des chose: c’est ce qu’on appelle les Welcome views.

_Welcome Views_

Il est possible d’ajouter du texte, des liens, des boutons, sachant qu’un bouton est un lien tout seul sur sa ligne.

Elles peuvent se déclarer dans le package.json :

{

    "contributes": {
        ...
        "views": {
			"mycontainer": [
				{
					"id": "my-view-id",
					"name": "Ma vue",
					"icon": "resources/monicone.svg"
				}
			]
		},
        "viewsWelcome": [
			{
				"view":"my-view-id",
				"contents": "Blabbal.\n[Mon bouton](command:id-de-ma-commande)"
			}
		],
        ...
    }
}

Utilisation des icônes standard

Visual Studio utilise des icônes standards qui peuvent être réutilisés par les extensions.

Dans package.json, on peut utiliser la syntaxe $(codicon ID) pour les commandes. Par exemple :

{
    "contributes": {
        ...
        "commands": [
            {
                "command": "ma-commande-de-suppression",
                "title": "Delete",
                "icon": "$(trash)"
            },
            ...
        ]
    }
}

Il est également possible de l’utiliser programmatiquement sur des TreeItem :

item.iconPath = new ThemeIcon('folder-opened');

Ouvrir un document et le "typer"

Visual Studio Code fournit une méthode pour ouvrir un document et l’afficher à partir de son chemin  vscode.window.showTextDocument.

Par contre, on peut vouloir forcer le langage utilisé. Il faut alors passer par la commande vscode.workspace.openTextDocument :

let document = await vscode.workspace.openTextDocument(node.uri);
document = await vscode.languages.setTextDocumentLanguage(document, 'json');
await vscode.window.showTextDocument(document, { preview: true });

Afficher un progrès

Il est possible d’utiliser une barre de progression. Un exemple est fourni par Microsoft. En voici un extrait :

await vscode.window.withProgress({
    location: vscode.ProgressLocation.Notification,
    title: 'Opening File(s)...',
    cancellable: false
}, async (task, token) => {
    ...
});

Etes-vous sûrs ?

Il est possible d’afficher des fenêtres de confirmation facilement. En les rendant "modal", la popup apparait.

const response = await vscode.window.showWarningMessage(
    `Are you sure you want to delete XXX?`,
    { modal: true },
    ...["Yes", "No"]
);
if (response !== "Yes") {
    return;
}

Gestion des chemins aux ressources et bundle

Il est fortement recommandé de bundler son extension. Il faut faire attention à la récupération des ressources.

On peut alors définir l’accès à une ressource en utilisant la méthode asAbsolutePath de ExtensionContext, ou les propriétés extensionUri et extensionPath

Conclusion

J’espère que vous avez pu trouver ce que vous cherchiez. Je vais continuer mon chemin pour la création d’une extension (snippets, web view, etc.). J’aurai donc peut-être d’autres astuces à partager.