Как написать расширение для vs code

In this topic, we’ll teach you the fundamental concepts for building extensions. Make sure you have Node.js and Git installed, then install Yeoman and VS Code Extension Generator with:

npm install -g yo generator-code

The generator scaffolds a TypeScript or JavaScript project ready for development. Run the generator and fill out a few fields for a TypeScript project:

yo code

# ? What type of extension do you want to create? New Extension (TypeScript)
# ? What's the name of your extension? HelloWorld
### Press <Enter> to choose default for all options below ###

# ? What's the identifier of your extension? helloworld
# ? What's the description of your extension? LEAVE BLANK
# ? Initialize a git repository? Yes
# ? Bundle the source code with webpack? No
# ? Which package manager to use? npm

# ? Do you want to open the new folder with Visual Studio Code? Open with `code`

Then, inside the editor, press F5. This will compile and run the extension in a new Extension Development Host window.

Run the Hello World command from the Command Palette (⇧⌘P (Windows, Linux Ctrl+Shift+P)) in the new window:

You should see the Hello World from HelloWorld! notification showing up. Success!

Developing the extension

Let’s make a change to the message:

  1. Change the message from «Hello World from HelloWorld!» to «Hello VS Code» in extension.ts.
  2. Run Developer: Reload Window in the new window.
  3. Run the command Hello World again.

You should see the updated message showing up.

Here are some ideas for things for you to try:

  • Give the Hello World command a new name in the Command Palette.
  • Contribute another command that displays current time in an information message. Contribution points are static declarations you make in the package.json Extension Manifest to extend VS Code, such as adding commands, menus, or keybindings to your extension.
  • Replace the vscode.window.showInformationMessage with another VS Code API call to show a warning message.

Debugging the extension

VS Code’s built-in debugging functionality makes it easy to debug extensions. Set a breakpoint by clicking the gutter next to a line, and VS Code will hit the breakpoint. You can hover over variables in the editor or use the Run and Debug view in the left to check a variable’s value. The Debug Console allows you to evaluate expressions.

You can learn more about debugging Node.js apps in VS Code in the Node.js Debugging Topic.

Next steps

In the next topic, Extension Anatomy, we’ll take a closer look at the source code of the Hello World sample and explain key concepts.

You can find the source code of this tutorial at: https://github.com/microsoft/vscode-extension-samples/tree/main/helloworld-sample. The Extension Guides topic contains other samples, each illustrating a different VS Code API or Contribution Point, and following the recommendations in our UX Guidelines.

Using JavaScript

In this guide, we mainly describe how to develop VS Code extension with TypeScript because we believe TypeScript offers the best experience for developing VS Code extensions. However, if you prefer JavaScript, you can still follow along using helloworld-minimal-sample.

UX Guidelines

This is also a good time to review our UX Guidelines so you can start designing your extension user interface to follow the VS Code best practices.

3/1/2023

Эта статья продолжает небольшую серию «Создаём ваш первый плагин для…», в которую уже вошли статьи про написания плагина для Grunt и Gulp.

Дисклеймер

Я люблю JavaScript. Мне довольно приятно наблюдать за тем, что этот прекрасный язык программирования вышел за пределы браузера и собирает всё больше и больше областей применения. Так, например, благодаря Electron от GitHub у меня появилось сразу несколько приложений, которые я использую в повседневной жизни. К таким приложениям относится Hain, 1Clipboard, Wagon, Gitify и, конечно же, Visual Studio Code.

Теперь поговорим о приятном для некоторых людей и противном для других. У меня нет симпатий к TypeScript. На то есть свои причины, в основном, связанные с типизацией — не люблю я её, что тут поделать. При этом я не буду отрицать, что когда-нибудь начну использовать TypeScript или подобный язык, компилируемый в JavaScript — всё бывает, мнение может меняться со временем. Однако, в связи с этим, в статье все примеры будут написаны на JavaScript, хотя сам редактор и вся документация к нему написана с применением TypeScript в примерах.

Кстати, я недавно узнал, что создателем TypeScript был Андерс Хейлсберг, который, оказывается, приложил руку к Turbo Pascal, Delphi и C#.

Что-то вместо введения

Герой нашего дня (VS Code) построен на Electron, который подробно рассматривался в статье «Построение Electron приложения. Введение». На момент написания статьи (июнь 2016) в основе редактора лежит Electron версии 0.37.6, что подразумевает под собой Chromium 49-ой ветки и Node.js версии 5.10.0. В репозитории на GitHub уже думают над переходом на новую версию Electron, где версия Chromium поднимется минимум до 51-ой ветки, а Node.js до версии 6.1.0 или выше. Всё это означает, что вы можете писать плагины, используя синтаксис ES2015 без Babel и его альтернатив, а также применяя любой API Node.js.

Предупреждение

Не стоит читать эту статью дальше введения, если вы не понимаете фишки, введённые в ES2015. Если говорить конкретно, то от вас требуется понимание деструктуризации, обещаний, стрелочных функций, const и let, а также понимание основ Node.js.

Итак, пожалуй, начнём с того, что плагины в VS Code изолированы от самого редактора и запускаются в отдельном хост-процессе (extension host process), который представляет собой процесс Node.js с возможностью использования VS Code API. Такой подход не позволяет плагинам влиять на производительность редактора при его запуске или в процессе его работы. Для пользователя это означает, что редактор не зависнет на время выполнения задач каким-либо плагином или, если плагин выдаст фатальную ошибку.

Для экономии расхода памяти разработчики также добавили ленивую загрузку плагинов. Это означает, что плагины активируются лишь в тот момент, когда они нужны. Например, если пользователь открывает Markdown-файл, то плагины, работающие с Markdown, будут загружены только в момент открытия файла. Разумеется, мы должны сообщить редактору о том, когда именно он должен активировать какой-либо плагин. О настройке ленивой загрузки мы поговорим позднее в разделе про файл манифеста.

Помимо всего прочего, плагины делятся на три вида в зависимости от функционала:

К первому виду относятся стандартные плагины, которые запускаются в хост-процессе, активируются в нужный момент и не требуют серьёзных вычислений.

Ко второму виду относятся так называемые «языковые серверы». Клиентская часть плагина запускается в хост-процессе, а серверная часть создаёт дополнительный процесс, в котором производятся все сложные вычисления. К такому виду плагинов относятся линтеры.

К третьему виду относят «службы отладки», которые пишутся в виде отдельной программы и взаимодействуют с VS Code по специальному протоколу CDP (VS Code Debug Protocol).

В этой статье будет рассматриваться лишь первый вид плагинов на примере vscode-lebab. Во второй статье разбирается процесс построения второго вида плагинов на примере vscode-puglint.

Манифест плагина

Написание плагина начинается не с кода, а с файла манифеста, которым в мире Node.js является файл package.json. VS Code дополняет стандартный файл манифеста своими полями. Ниже будут рассмотрены самые основные из них.

publisher [string]

Имя пользователя, под которым вы зарегистрировались в vsce.

icon [string]

Путь до иконки, которая будет отображаться в магазине расширений. Размер иконки 128×128 пикселей. Также поддерживается SVG формат.

displayName [string]

Название плагина, которое будет отображаться в магазине расширений.

categories [array]

Массив, содержащий имена категорий, к которым относится плагин. Доступны следующие категории: [Languages, Snippets, Linters, Themes, Debuggers, Other]. Пожалуйста, указывайте категорию или категории обдуманно. Например, если ваше расширение включает в себя подсветку синтаксиса языка и сниппеты, то указывайте только эти две категории.

galleryBanner [object]

Настройки оформления страницы расширения в магазине. Используется для того, чтобы иконка расширения и фон подложки были контрастны. Свойство color отвечает за цвет фона, свойство theme за цвет шрифта: dark — белый, light — чёрный.

"galleryBanner": {
    "color": "#0000FF",
    "theme": "dark"
}

preview [boolean]

Флаг, позволяющий пометить плагин сообщением о том, что он доступен в режиме предварительного просмотра.

activationEvents [array]

Массив событий, в случае наступления которых плагин будет активирован редактором. Поддерживаются следующие события, активирующие плагин в том случае, если будет:

  • onLanguage — открыт файл указанного языка (не расширения).
  • onCommand — вызвана указанная команда.
  • onDebug — запущен сеанс отладки указанного типа.
  • workspaceContains — найден указанный файл в корневой папке проекта.

Отдельно стоит отметить событие *, которое активирует плагин при загрузке редактора. Однако, использовать это событие нужно крайне редко и в том случае, если комбинации других событий не могут решить сложившуюся проблему.

contributes [object]

С помощью этого поля в package.json разработчик описывает своё расширение. Доступно довольно большое количество всевозможных полей, описывающих:

  • configuration — поля, доступные пользователю в настройках редактора.
  • commands — команды, доступные пользователю в палитре команд F1.
  • keybindings — сочетания клавиш для вызова команд.
  • languages — языки.
  • debuggers — отладочный адаптер.
  • grammars — TextMate-грамматику, необходимую для подсветки синтаксиса.
  • themes — темы.
  • snippets — сниппеты.
  • jsonValidation — схемы проверки определённых JSON-файлов.

Несложно догадаться, что поля необходимо указывать в зависимости от типа вашего расширения. Если это плагин, сортирующий строки, то, вероятнее всего, вы будете использовать поля: configuration, commands и keybindings.

extensionDependencies [array]

Массив идентификаторов расширений, которые требуются для работы плагина. Например, если ваше расширение требует поддержки синтаксиса C#, то необходимо будет добавить в массив строку vscode.csharp, где vscode — ник опубликовавшего расширение, а csharp — имя расширения.

Немного про VS Code API

Как и полагается любому крупному проекту, VS Code имеет довольно обширный API, доступный разработчикам плагинов. Рассмотрим лишь так называемые пространства имён:

  • commands — это пространство имён для работы с командами. С помощью доступных методов разработчик может регистрировать, получать и выполнять команды.
  • env — пространство имён, содержащее описание переменных окружения редактора при запуске. С помощью соответствующих методов можно получить имя окна редактора, его язык, идентификатор редактора в системе и идентификатора сессии редактора, которые устанавливается при запуске.
  • extensions — пространство имён для работы с установленными расширениями. С помощью этого API можно получить все или конкретные расширения, известные редактору.
  • languages — пространство имён, позволяющее получить доступ к языковым возможностям редактора, например, к IntelliSense, подсказкам, а также функциям диагностики кода для линтеров.
  • window — пространство имён для работы с текущим окном редактора. Доступно API для работы с видимыми и активными окнами редактора, а также элементами пользовательского интерфейса. Последнее подразумевает под собой возможность отображения различных сообщений, ввода текста или выбора каких-либо вариантов.
  • workspace — пространство имён для работы с текущей рабочей областью, включая открытую директорию и файлы. С помощью этого API осуществляется вся работа с содержимым открытого файла.

Пишем стандартный плагин

Постановка задачи

В этой части статьи я буду описывать процесс написания плагина для VS Code на основе lebab, который автоматически конвертирует JavaScript-код, написанный по стандарту ES5 в ES2015. Это проект является альтернативой проекту Babel, но в обратную сторону.

Манифест

И снова скажу, что написание плагина начинается не с кода на JavaScript, а с манифеста. Первым делом создаём файл package.json и пишем туда пару десятков строк, описывающих плагин. Полный листинг манифеста вы сможете найти в репозитории плагина vscode-lebab. Остановимся именно на тех моментах, которые касаются работы с VS Code.

Во-первых, укажем информацию, которая будет отображаться в маркете:

{
  "displayName": "lebab",
  "publisher": "mrmlnc",
  "icon": "icon.png",
  "homepage": "https://github.com/mrmlnc/vscode-lebab/blob/master/README.md",
  "categories": [
    "Other"
  ]
}

Во-вторых, укажем массив событий, на которые наш плагин должен откликаться. Про команду lebab.convert я расскажу немного позднее.

{
  "activationEvents": [
    "onCommand:lebab.convert"
  ]
}

В-третьих, опишем плагин. Предполагается, что пользователю будет доступна лишь одна команда, по вызову которой он получит сконвертированный ES5-код в синтаксис ES2015. Также предполагается, что в настройках редактора пользователь сможет указать, что именно он хочет конвертировать с помощью lebab. Для этого я определил опцию lebab.transforms, содержащую объект ключей, с которыми будет работать конвертер.

{
  "contributes": {

    "commands": [{
      "command": "lebab.convert",
      "title": "Lebab: convert JavaScript code from ES5 to ES2015"
    }],

    "configuration": {
      "type": "object",
      "title": "Lebab configuration",
      "properties": {
        "lebab.transforms": {
          "type": "object",
          "default": {},
          "description": "Convert your old-fashioned code with a specific transformation."
        }
      }
    }

  }
}

Убираем из маркета лишнее

Сколько раз не говори, но я всё равно встречаю модули в npm, у которых вместе с кодом я получаю файлы тестов, изображений и прочей лабуды. К счастью, теперь я могу ссылаться на эту статью в отношении npm. В случае VS Code, необходимо создать файл .vscodeignore, который действует так же, как и файл .gitignore, но в отношении маркета расширений.

У меня файл .vscodeignore имеет следующее содержимое:

.vscode/**
typings/**
test/**
.editorconfig
.gitignore
.travis.yml
jsconfig.json

Я очень прошу, убирайте всё лишнее из плагина, иначе я вас вычислю по IP и накажу.

Базовый код

В мире Node.js принято писать код модуля в файле index.js, а приложения — app.js. Мир VS Code тоже имеет традиции, и код плагина пишется в файле extension.js.

Внимание

Если очень хочется писать код в файле с именем, отличным от extension.js, то, как и в мире Node.js, вам придётся указать имя файла в поле main в манифесте.

Для начала определим две функции. Первая функция будет иметь имя activate и вызываться в том случае, если плагин был активирован событием, указанным в манифесте. Вторая функция имеет имя deactivate и вызывается в том случае, если плагин был деактивирован. Под деактивацией следует понимать последействие команды, а не удаление плагина. Её предназначение в большинстве плагинов излишне, поэтому она не обязательна. Далее в статье я не буду упоминать функцию деактивации плагина.

const vscode = require('vscode');

function activate(context) {
  // Code...
}

exports.activate = activate;

function deactivate() {
  // Code...
}

exports.deactivate = deactivate;

Напомню, что в файле манифеста была указана команда lebab.convert — самое время её зарегистрировать. Для регистрации команд существует два метода:

  • registerTextEditorCommand — регистрирует команду в контексте текстового редактора или файла.
  • registerCommand — регистрирует команду в глобальном контексте, то есть вне зависимости от наличия открытого редатора с текстом.

Второй метод используется крайне редко, вследствие того, что, в основном, плагины нацелены на работу с содержимом текстового редактора.

В конце все объявленные команды должны быть добавлены в массив subscriptions.

'use strict';

const vscode = require('vscode');

function activate(context) {
  const convert = vscode.commands.registerTextEditorCommand('lebab.convert', (textEditor) => {
    // ...
  });

  context.subscriptions.push(convert);
}

exports.activate = activate;

При регистрации команды необходимо передать идентификатор команды, указанный в файле манифеста и функцию обратного вызова, в которую передаётся объект textEditor, содержащий всю информацию о текущем редакторе, такую как:

  • Файл на диске или новый файл (untitled)
  • Путь до файла и его имя
  • Идентификатор языка
  • Наличие EOL
  • Если было выделение текста, то параметры этого выделения
  • Статистика текста (количество символов в строке и прочее)
  • Версия файла (проще говоря, номер сохранения в истории файла)
  • Строки файла
  • и т.д.

Чисто практически, вы можете обращаться к свойствам объекта и работать с полученными из него данными. Но, разумеется, лучше всего обращаться к этому объекту с помощью определённых методов. На данном этапе нам нужно получить текст файла, чтобы в дальнейшем обработать его, и настройки, определённые в редакторе для нашего плагина.

Получить текст открытого документа можно, используя метод getText, а настройки, используя метод getConfiguration у workspace API:

const convert = vscode.commands.registerTextEditorCommand('lebab.convert', (textEditor) => {
  // Обычный объект, где имена свойств совпадают с теми, что были обозначены в манифесте.
  const options = vscode.workspace.getConfiguration('lebab');

  // Текст открытого файла.
  const text = textEditor.document.getText();
});

Внимание

Настройки редактора нужно получать в момент вызова команды, иначе, если получить их в момент активации плагина, то при обновлении настроек редактора, объект в переменной не обновится.

Далее я не буду рассматривать процесс вызова Lebab, потому что это элементарное действие, не относящееся к VS Code. Покажу лишь тот участок, что отвечает за вставку обработанного текста обратно в окно редактора. Для этого мы обратимся к объекту textEditor и вызовем метод edit с коллбэком, представленным ниже. Конечно же, код должен располагаться после получения текста документа и настроек редактора в функции обратного вызова регистрации команды.

textEditor.edit((editBuilder) => {
  // Получаем текущий документ.
  const document = textEditor.document;

  // Получаем последнюю строку документа.
  const lastLine = document.lineAt(document.lineCount - 1);

  // Создаём нулевую позицию, то есть начало документа, где первый ноль — номер
  // строки, а второй ноль — номер символа в строке.
  const start = new vscode.Position(0, 0);

  // Создаём завершающую позицию, где первое число — последняя строка документа,
  // а второе — номер последнего символа в строке.
  const end = new vscode.Position(document.lineCount - 1, lastLine.text.length);

  // Создаём диапазон, используя специальное API.
  const range = new vscode.Range(start, end);

  // Заменяем текст в обозначенном диапазоне на что-либо.
  editBuilder.replace(range, text);
});

Собственно, это всё, что требуется сделать в обычном плагине для VS Code: получить текст, обработать его и вернуть обратно. Полный листинг кода содержит 52 строки и размещён на GitHub в репозитории vscode-lebab.

Как можно заметить, ничего сложно — простейший JavaScript-код, который разбавлен вызовами необходимых API редактора. В этой статье был рассмотрен простейший случай, когда у вас есть готовое решение и его нужно подружить с редактором. В случае, если готового решения нет, то лучше оформить его в виде npm-пакета по всем канонам (тесты, документация), а уже потом подружить его с редактором. В качестве примеров, если решите писать плагин на JavaScript, вы можете посмотреть код следующих плагинов:

  • vscode-lebab
  • vscode-attrs-sorter
  • vscode-csscomb
  • vscode-postcss-sorting
  • vscode-stylefmt

Что-то вместо вывода

В этой статье я помог вам начать писать плагины для VS Code. Многое осталось за кулисами и не рассматривалось, однако вам в любом случае придётся обращаться к документации. Считайте, что эта статья преследует цель показать, что писать плагин для VS Code довольно просто, причём необязательно делать это на TypeScript. Хотя, при этом не стоит забывать, что TypeScript — это всё тот же JavaScript.

Также, советую посмотреть на код, представленный в репозитории VSCode-Sample. Здесь автор собрал примеры взаимодействия с UI редактора, которые, возможно, помогут вам освоиться.

Если вам интересна тема разработки плагинов для VS Code, то добро пожаловать во вторую часть этой статьи, в которой рассматривается процесс написания плагина, использующего языковой сервер.

Что почитать?

  • Конечно, документацию:
    • Обзор экосистемы расширений
    • Обзор API
    • Про публикацию расширений
    • Про утилиты, упрощающие создание расширений
    • Примеры
  • Visual Studio Code Extensions: Editing the Document
  • Getting Input and Displaying Output in a Visual Studio Code Extension

How to Make Your Own VS Code Extension

I just made my first VS Code extension. And it felt good! This article will cover basic steps to help you create your own VS Code extension. Along the way I’ll share what I learned from making one for the first time.

I am not an expert at this yet, but I can truly say that nothing is as hard as it seems. ?

Let’s talk about VS Code and its Extension Marketplace

If you opened this article, you have probably at least heard about VS Code (or Visual Studio Code). If not, it’s basically a light-weight code editor developed by Microsoft.

Since VS Code is a code editor, it can perform much faster and lighter than a typical IDE such as Eclipse. But with that performance comes one disadvantage: IDEs often provide better tools such as built-in linters, better code templates, code versioning tools, and some features such as auto complete.

But where VS Code actually shines is the power of the community. It allows you to install extensions that come directly from the VS Code marketplace itself. These extensions allow you to customize it however you wish. You can, for example, add a linter or any other features like colorful brackets. You can even put a nyan cat in your VS Code!

Screenshot-from-2020-05-31-23-42-52

Who doesn’t like a nyan cat?

Why should you create a VS Code extension?

0-EErfJXzBUg_qzUsI

Yes, ‘why’ is the keyword here. It’s the first and most important thing to talk about when you want to start doing something.

Ask yourself why do you want to make it? Most people usually answer because they want to learn something or gain fame, or maybe even both. But the more reasons there are, the more motivation you will have.

One thing I can say is that you don’t need to think big yet. Just make a tool that is very specific, that maybe only you will use. The first step is always the hardest. And at the end of day at least you’ve helped yourself with your extension.

As for myself, I built an extension because of one particular reason: I wanted to make a tool that I could use to increase my productivity. And that would maybe even help a small part of the community near me. (Spoiler: it’s golang unit test generator)

That’s why the extensions that I’ve made are very precise and have a very specific use case. I’m not going for a big mark, I am aiming to increase my productivity and learn something new. I think that is enough reason for me.

And of course everything seemed impossible at the start. Making VS Code extensions looks like some genius level piece art of work (but of course it’s not). Since I have a lot of free time on my hands at the moment, I figured I might as well try it out.

The Very first step of Building a VS Code Extension

To get started, you have to have VS Code installed. In case you don’t have it yet, I will just put the download link here.

VS Code extensions support two main languages: JavaScript and TypeScript. So having some knowledge of either of these is pretty mandatory.

Also, make sure you have Node.js installed, since we are going to use a lot of npm packages here.

How to Generate a VS Code Extension Template

Ah, templates. How very convenient. VS Code already has its own template generator, so let’s jump straight into it.

First, install your template generator with npm install -g yo generator-code

Afterwards, let’s run it with yo code. And it will prompt out this weird head thing (?) and language selection. Just pick your preferred language and proceed. (I picked JavaScript here).

yo-code

yo code

Afterwards, you will need to edit your extension name and description. You can just proceed with anything you prefer.

Screenshot-from-2020-05-26-23-07-28

or maybe just enter all the way

Now, a folder called hellovscode will be created in your home directory. Open it with VS Code by simply typing code hellovscode in the folder directory.

Use the F5 key to run your extension and another window will popup. Now press ctrl+shift+p and find the Hello World command, run it, and a popup should come out in the bottom right corner. Like this:

sample-hello

Magic? Nope. Just collection of code.

Voilà! You’ve just run your first extension. But what is actually happening with all that? Don’t worry, I will explain some bits below, mainly regarding two files: extension.js and package.json.

What is the Extension.js File in VS Code?

This is where you will spend most of your time coding. This file will contain all your code blocks and logic flow.

There isn’t much difference between this and normal Node code. But one of the main differences is registering your commands. You will come upon this block vscode.commands.registerCommand('hellovscode.helloWorld'.

In a nutshell, it will register your function call to be used.

Another difference is the frequent usage of the VS Code API – but we will come back to that later on.

If you looked through the code, you will see this too: vscode.window.showInformationMessage('Hello World from hellovscode!');

As an experiment, try changing the value of the message and try running it again.

Package.json

This file is the one that basically will link the commands you created from extension.js with the commands that you defined.

You will see the command that you have registered above hellovscode.helloWorld being put as a part of the command titled Hello World. And that’s how the command actually links to your code.

Apart from this, this file will also enable the command to be put on the right click bar. It will also filter where the command should appear (file type).

How to Publish Your VS Code Plugin

Just in case you might want to publish your extension, I will show you how to do that here:

Step 1: First and foremost, install vsce with npm install -g vsce. We will use this most of the time to publish.

Step 2: If you don’t have a Microsoft account yet, you should register here since we will be needing the access token you’ll get.

Step 3: Once you have the account sign in to the marketplace. Create your organization and click on it (you should see something like the below).

ss

Step 4: Now click on the upper right corner where the red circle is and select Personal Access Token. Create your personal access token and choose all accessible organizations with full access.

Screenshot-from-2020-05-29-23-56-42

Step 5: Remember your token since you’ll use it when uploading your extension.

Step 6: You will need to create your publisher identity now. So go to your command prompt and type run vsce create-publisher YOUR_PUBLISHER_NAME .
Insert your own name, email, and personal access token when prompted. Your publisher account should successfully be created.

Step 7: It’s publishing time! Prepare your extension environment in the command prompt and type vsce package. This will package your extension to marketplace format. Then type vsce publish.

And that’s it, your extension will be published.

On a side note, when publishing you should modify your readme (at least the first part where it says This is Readme for.. ) since vsce will detect it and ask you to modify it.

Some Additional Tips for Building VS Code Extensions

Now you should have some basic understanding of how VS Code extensions work. Here, I will share some things that I have learned.

Utilizing VS Code’s API

VS Code itself has provided a lot of APIs for you to use to make your extension. You might encounter several common obstacles when building your extension, like getting your cursor position, getting the line position, or maybe getting the highlighted word. Those all can be tackled with using the VS Code API.

You should read through their documentation and experiment with their API. You can even try reading through their API code! With the amount of documentation inside the code itself, you should be able to somewhat figure out which API will be most helpful.

Googling things (read the docs or code)

image-169

Most of the time in our programming life, when we are stuck there is always Google or Stack Overflow that can provide quick help.

But this time it will not always save you.

First of all, googling for help in this case is quite tricky. For example, say you want to highlight a word on cursor – you might search for vs code extension how to get total line... or something similar.

But let me tell you, most of the time it will direct you to the real extension itself or give you manual on how to use VS Code.

One way you can make it easier for yourself is by adding the «API» keyword in your search, like vs code extension api how to ....

Also, it is pretty hard to find the relevant answers in Google, because the developer community is not that huge, and VS Code extensions may look intimidating for many newcomers. But truthfully, it is not exactly that hard.

That’s why sometimes the best way to learn how to develop a VS Code extension is by reading the documentation or the code.

A VS Code Extension GitHub Example Repository

I have provided a text manipulation example in my GitHub repository which might help for code references (watch out for some messy code though!). The code will generate some template unit tests in the Go language.

Wrapping up

What I have covered here are just the basics of creating a VS Code extension. One message I want you to take to heart is that it is not as hard as it looks. Sometimes you just need to push yourself a bit and try it out.

You might come across some challenges along the way, but if you never even start you are missing out completely.

In the end, thanks for taking the time to read this. I hope you enjoyed it and started to understand all the things I just explained.

And hopefully you will also start making an extension too!

Happy coding to you all in this social distancing time.



Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

How to Make Your Own VS Code Extension

I just made my first VS Code extension. And it felt good! This article will cover basic steps to help you create your own VS Code extension. Along the way I’ll share what I learned from making one for the first time.

I am not an expert at this yet, but I can truly say that nothing is as hard as it seems. ?

Let’s talk about VS Code and its Extension Marketplace

If you opened this article, you have probably at least heard about VS Code (or Visual Studio Code). If not, it’s basically a light-weight code editor developed by Microsoft.

Since VS Code is a code editor, it can perform much faster and lighter than a typical IDE such as Eclipse. But with that performance comes one disadvantage: IDEs often provide better tools such as built-in linters, better code templates, code versioning tools, and some features such as auto complete.

But where VS Code actually shines is the power of the community. It allows you to install extensions that come directly from the VS Code marketplace itself. These extensions allow you to customize it however you wish. You can, for example, add a linter or any other features like colorful brackets. You can even put a nyan cat in your VS Code!

Screenshot-from-2020-05-31-23-42-52

Who doesn’t like a nyan cat?

Why should you create a VS Code extension?

0-EErfJXzBUg_qzUsI

Yes, ‘why’ is the keyword here. It’s the first and most important thing to talk about when you want to start doing something.

Ask yourself why do you want to make it? Most people usually answer because they want to learn something or gain fame, or maybe even both. But the more reasons there are, the more motivation you will have.

One thing I can say is that you don’t need to think big yet. Just make a tool that is very specific, that maybe only you will use. The first step is always the hardest. And at the end of day at least you’ve helped yourself with your extension.

As for myself, I built an extension because of one particular reason: I wanted to make a tool that I could use to increase my productivity. And that would maybe even help a small part of the community near me. (Spoiler: it’s golang unit test generator)

That’s why the extensions that I’ve made are very precise and have a very specific use case. I’m not going for a big mark, I am aiming to increase my productivity and learn something new. I think that is enough reason for me.

And of course everything seemed impossible at the start. Making VS Code extensions looks like some genius level piece art of work (but of course it’s not). Since I have a lot of free time on my hands at the moment, I figured I might as well try it out.

The Very first step of Building a VS Code Extension

To get started, you have to have VS Code installed. In case you don’t have it yet, I will just put the download link here.

VS Code extensions support two main languages: JavaScript and TypeScript. So having some knowledge of either of these is pretty mandatory.

Also, make sure you have Node.js installed, since we are going to use a lot of npm packages here.

How to Generate a VS Code Extension Template

Ah, templates. How very convenient. VS Code already has its own template generator, so let’s jump straight into it.

First, install your template generator with npm install -g yo generator-code

Afterwards, let’s run it with yo code. And it will prompt out this weird head thing (?) and language selection. Just pick your preferred language and proceed. (I picked JavaScript here).

yo-code

yo code

Afterwards, you will need to edit your extension name and description. You can just proceed with anything you prefer.

Screenshot-from-2020-05-26-23-07-28

or maybe just enter all the way

Now, a folder called hellovscode will be created in your home directory. Open it with VS Code by simply typing code hellovscode in the folder directory.

Use the F5 key to run your extension and another window will popup. Now press ctrl+shift+p and find the Hello World command, run it, and a popup should come out in the bottom right corner. Like this:

sample-hello

Magic? Nope. Just collection of code.

Voilà! You’ve just run your first extension. But what is actually happening with all that? Don’t worry, I will explain some bits below, mainly regarding two files: extension.js and package.json.

What is the Extension.js File in VS Code?

This is where you will spend most of your time coding. This file will contain all your code blocks and logic flow.

There isn’t much difference between this and normal Node code. But one of the main differences is registering your commands. You will come upon this block vscode.commands.registerCommand('hellovscode.helloWorld'.

In a nutshell, it will register your function call to be used.

Another difference is the frequent usage of the VS Code API – but we will come back to that later on.

If you looked through the code, you will see this too: vscode.window.showInformationMessage('Hello World from hellovscode!');

As an experiment, try changing the value of the message and try running it again.

Package.json

This file is the one that basically will link the commands you created from extension.js with the commands that you defined.

You will see the command that you have registered above hellovscode.helloWorld being put as a part of the command titled Hello World. And that’s how the command actually links to your code.

Apart from this, this file will also enable the command to be put on the right click bar. It will also filter where the command should appear (file type).

How to Publish Your VS Code Plugin

Just in case you might want to publish your extension, I will show you how to do that here:

Step 1: First and foremost, install vsce with npm install -g vsce. We will use this most of the time to publish.

Step 2: If you don’t have a Microsoft account yet, you should register here since we will be needing the access token you’ll get.

Step 3: Once you have the account sign in to the marketplace. Create your organization and click on it (you should see something like the below).

ss

Step 4: Now click on the upper right corner where the red circle is and select Personal Access Token. Create your personal access token and choose all accessible organizations with full access.

Screenshot-from-2020-05-29-23-56-42

Step 5: Remember your token since you’ll use it when uploading your extension.

Step 6: You will need to create your publisher identity now. So go to your command prompt and type run vsce create-publisher YOUR_PUBLISHER_NAME .
Insert your own name, email, and personal access token when prompted. Your publisher account should successfully be created.

Step 7: It’s publishing time! Prepare your extension environment in the command prompt and type vsce package. This will package your extension to marketplace format. Then type vsce publish.

And that’s it, your extension will be published.

On a side note, when publishing you should modify your readme (at least the first part where it says This is Readme for.. ) since vsce will detect it and ask you to modify it.

Some Additional Tips for Building VS Code Extensions

Now you should have some basic understanding of how VS Code extensions work. Here, I will share some things that I have learned.

Utilizing VS Code’s API

VS Code itself has provided a lot of APIs for you to use to make your extension. You might encounter several common obstacles when building your extension, like getting your cursor position, getting the line position, or maybe getting the highlighted word. Those all can be tackled with using the VS Code API.

You should read through their documentation and experiment with their API. You can even try reading through their API code! With the amount of documentation inside the code itself, you should be able to somewhat figure out which API will be most helpful.

Googling things (read the docs or code)

image-169

Most of the time in our programming life, when we are stuck there is always Google or Stack Overflow that can provide quick help.

But this time it will not always save you.

First of all, googling for help in this case is quite tricky. For example, say you want to highlight a word on cursor – you might search for vs code extension how to get total line... or something similar.

But let me tell you, most of the time it will direct you to the real extension itself or give you manual on how to use VS Code.

One way you can make it easier for yourself is by adding the «API» keyword in your search, like vs code extension api how to ....

Also, it is pretty hard to find the relevant answers in Google, because the developer community is not that huge, and VS Code extensions may look intimidating for many newcomers. But truthfully, it is not exactly that hard.

That’s why sometimes the best way to learn how to develop a VS Code extension is by reading the documentation or the code.

A VS Code Extension GitHub Example Repository

I have provided a text manipulation example in my GitHub repository which might help for code references (watch out for some messy code though!). The code will generate some template unit tests in the Go language.

Wrapping up

What I have covered here are just the basics of creating a VS Code extension. One message I want you to take to heart is that it is not as hard as it looks. Sometimes you just need to push yourself a bit and try it out.

You might come across some challenges along the way, but if you never even start you are missing out completely.

In the end, thanks for taking the time to read this. I hope you enjoyed it and started to understand all the things I just explained.

And hopefully you will also start making an extension too!

Happy coding to you all in this social distancing time.



Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

11 сентября, 2021 12:00 пп
2 073 views
| Комментариев нет

Development

Visual Studio Code – это редактор кода от Microsoft, доступный для систем Windows, Linux и macOS. Для внедрения дополнительных функций он предлагает готовые расширения, которые вы можете установить через Visual Studio Code Marketplace. Но если вы не можете найти расширение, которое делает именно то, что вам нужно, вы можете создать необходимое расширение самостоятельно.

В этом руководстве вы узнаете, как создать свое первое расширение Visual Studio Code.

Требования

Для выполнения этого урока нужно:

  • Загрузить и установить последнюю версию Visual Studio Code.
  • Установить Node.js. Инструкции по установке зависят от дистрибутива: Mac OS, Ubuntu, CentOS, Debian.

Это руководство было проверено на версиях Node v14.4.0, npm v6.14.5, yo v3.1.1 и generator-code v1.2.16.

1: Установка инструментов

Команда Visual Studio Code разработала специальный генератор для создания расширений. Он генерирует все необходимые стартовые файлы, чтобы вы легко могли начать создание вашего расширения.

Чтобы начать разработку расширений VS Code, вам понадобятся два пакета npm:

  • yo – интерфейс командной строки для Yeoman.
  • generator-code – генератор Yeoman для написания расширений Visual Studio Code.

Используйте встроенный терминал Visual Studio Code, чтобы при помощи npx запустить локальные копии yo и generator-code, а затем введите команду yo code для инициализации вашего нового проекта:

npx -p yo -p generator-code yo code

После этого Yeoman запустит генератор кода.

2: Создание расширения

Теперь вы готовы начать разработку вашего первого расширения. На вашем экране вы увидите сообщение:

Welcome to the Visual Studio Code Extension Generator!

Сейчас вам нужно будет ответить на несколько вопросов о проекте: указать, какое расширение вы создаете, а также выбрать между TypeScript и JavaScript. В этом уроке мы выберем JavaScript.

Затем вам будет предложено еще несколько вопросов. В этом мануале мы выбрали следующие ответы:

? What type of extension do you want to create? New Extension (JavaScript)
? What's the name of your extension? testytest
? What's the identifier of your extension? testytest
? What's the description of your extension? This is a test extension
? Enable JavaScript type checking in 'jsconfig.json'? Yes
? Initialize a git repository? Yes
? Which package manager to use? npm

После завершения этого процесса вы получите все файлы, необходимые для начала работы. Два самых важных файла:

  • package.json
  • extension.js

Откройте package.json и взгляните на его содержимое. Вы увидите название, описание проекта и т.п. В нем есть два очень важных раздела.

  • activationEvents – это список событий, которые активируют ваше расширение. Расширения загружаются по ленивой загрузке, поэтому они не активируются, пока не произойдет одно из перечисленных событий.
  • commands – список команд, которые пользователи смогут запускать через ваше расширение.

Мы вернемся к ним в ближайшее время.

{
  // ...
  "activationEvents": [
    "onCommand:testytest.helloWorld"
  ],
  "main": "./extension.js",
  "contributes": {
    "commands": [
      {
        "command": "testytest.helloWorld",
        "title": "Hello World"
      }
    ]
  },
  // ...
}

Вы также можете просмотреть файл extension.js. В нем мы напишем код для нашего расширения. Здесь уже есть шаблонный код, давайте разберемся с ним.

В выделенной ниже строке мы регистрируем в VS Code нашу команду. Обратите внимание, что имя helloWorld совпадает с именем команды в package.json. Это не случайно. Пакет package.json определяет, какие команды доступны пользователю, но файл extension.js регистрирует код для этой команды.

// ...

/**
 * @param {vscode.ExtensionContext} context
 */
function activate(context) {
  console.log('Congratulations, your extension "testytest" is now active!');

  let disposable = vscode.commands.registerCommand('testytest.helloWorld', function () {
    vscode.window.showInformationMessage('Hello World from testytest!');
  });

  context.subscriptions.push(disposable);
}

// ...

В этом примере наша команда будет только отображать на экране пользователя сообщение «Hello World».

3: Отладка расширения

Теперь, когда все необходимые файлы установлены, мы можем запустить наше расширение.

Папка .vscode – это место, где VS Code хранит конфигурационные файлы проекта. В нашем случае он включает файл launch.json, содержащий конфигурации отладки.

// ...
{
  // ...
  "configurations": [
    {
      "name": "Run Extension",
      "type": "extensionHost",
      "request": "launch",
      "runtimeExecutable": "${execPath}",
      "args": [
        "--extensionDevelopmentPath=${workspaceFolder}"
      ]
    },
    // ...
  ]
}

В этом файле проводится отладка расширения. Откройте вкладку debug в левой части экрана, а затем кликните на плей.

Это откроет новый (отладочный) экземпляр VS Code.

Открыв его, вы можете развернуть палитру команд (с помощью Command + Shift + P на Mac или Ctrl + Shift + P в Windows) и запустить Hello World.

Вы увидите всплывающее сообщение «Hello World» в правом нижнем углу.

4: Редактирование расширения

Прежде чем приступить к работе над кодом, давайте еще раз взглянем на раздел activateEvents в файле package.json. Как вы уже знаете, этот раздел содержит список событий, которые активируют наше расширение всякий раз, когда происходят. По умолчанию расширение активируется при запуске нашей команды.

Теоретически это событие может быть любым (что определяется символом *). Если установить для события активации значение *, то ваше расширение будет загружено при запуске VS Code.

{
  // ...
  "activationEvents": [
    "*"
  ],
  // ...
}

Примечание: Этого делать не нужно, это просто комментарий.

Итак, у нас есть необходимые файлы и мы знаем, как их отлаживать. Приступим же к созданию нашего расширения. Предположим, мы хотим, чтобы это расширение создавало HTML-файл, который содержит шаблонный код и добавляется в наш проект.

Сначала давайте обновим название нашей команды. Откройте extension.js и обновите имя команды с extension.helloworld на extension.createBoilerplate.

// ...

/**
 * @param {vscode.ExtensionContext} context
 */
function activate(context) {
  console.log('Congratulations, your extension "testytest" is now active!');

  let disposable = vscode.commands.registerCommand('testytest.createBoilerplate', function () {
    vscode.window.showInformationMessage('Hello World from testytest!');
  });

  context.subscriptions.push(disposable);
}

// ...

Соответствующим образом обновите package.json:

{
  // ...
  "activationEvents": [
    "onCommand:testytest.createBoilerplate"
  ],
  "main": "./extension.js",
  "contributes": {
    "commands": [
      {
        "command": "testytest.createBoilerplate",
        "title": "Create Boilerplate"
      }
    ]
  },
  // ...
}

Теперь напишем наш функционал. Первое, что нужно сделать, это потребовать пару пакетов. Мы будем использовать модули fs (file system) и path. В файл extension.js поместите:

const fs = require('fs');
const path = require('path');

Также нам нужно получить путь к текущей папке. Внутри раздела command поместите следующий фрагмент:

if (!vscode.workspace) {
  return vscode.window.showErrorMessage('Please open a project folder first');
}

const folderPath = vscode.workspace.workspaceFolders[0].uri
  .toString()
  .split(':')[1];

Нам также нужно присвоить шаблонный HTML-код переменной в файле extension.js, чтобы он автоматически записывался в файл. Вот этот шаблонный HTML:

const htmlContent = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>Document</title>
  <link rel="stylesheet" href="app.css" />
</head>
<body>
  <script src="app.js"></script>
</body>
</html>`;

Теперь нужно вызвать функцию writeFile модуля файловой системы и передать ее в пути к папке и HTML-коде.

Обратите внимание, мы используем модуль path, чтобы объединить путь к папке с именем файла, который мы хотим создать. Если внутри обратного вызова есть ошибка, мы отображаем ее пользователю. В противном случае расширение сообщает, что шаблонный файл успешно создан:

fs.writeFile(path.join(folderPath, 'index.html'), htmlContent, (err) => {
  if (err) {
    return vscode.window.showErrorMessage('Failed to create boilerplate file!');
  }
  vscode.window.showInformationMessage('Created boilerplate files');
});

Вот как выглядит полный код extension.js:

//...
  let disposable = vscode.commands.registerCommand(
    'testytest.createBoilerplate', async function () {
    // The code you place here will be executed every time your command is executed

    if (!vscode.workspace) {
      return vscode.window.showErrorMessage('Please open a project folder first');
    }

    const folderPath = vscode.workspace.workspaceFolders[0].uri
      .toString()
      .split(':')[1];

    const htmlContent = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>Document</title>
  <link rel="stylesheet" href="app.css" />
</head>
<body>
  <script src="app.js"></script>
</body>
</html>`;

    fs.writeFile(path.join(folderPath, 'index.html'), htmlContent, (err) => {
      if (err) {
        return vscode.window.showErrorMessage(
          'Failed to create boilerplate file!'
        );
      }
      vscode.window.showInformationMessage('Created boilerplate files');
    });

    // ...
  }
// ...

Попробуйте выполнить отладку вашего нового расширения. Откройте палитру команд и запустите Create Boilerplate (помните, мы изменили имя).

После выполнения команды вы увидите только что созданный файл index.html и сообщение, которое уведомляет вас об этом:

Created boilerplate files.

Заключение

Чтобы узнать больше о том, какие API можно использовать и как именно их использовать, прочтите документацию по API от Visual Studio.

Tags: Node.js, Visual Studio Code

Время на прочтение
10 мин

Количество просмотров 18K

Автор материала, перевод которого мы сегодня публикуем, создал 33 расширения для VS Code. Он решил поделиться с теми, кому нравится этот редактор, методикой разработки и поддержки расширений. Кроме того, он кратко рассказал о своих проектах. Возможно, вы найдёте среди них что-нибудь такое, что вам пригодится.

Как писать расширения

Я стремлюсь к продуктивной работе и люблю автоматизацию, поэтому я выработал чётко организованный процесс разработки расширений для VS Code. Расскажу об основных составных частях этого процесса.

▍Инструменты

Я написал очень простой инструмент, который помогает быстро начинать работу над новыми проектами, используя шаблон. Соответствующая утилита работает так:

  • На вход она принимает папку (это и есть то, что называется «шаблоном»).
  • Она обрабатывает все файлы средствами пакета handlebars, задавая в процессе обработки вопросы о том, что должно быть подставлено в качестве каждого найденного местозаполнителя (наподобие {{name}}).
  • В результате она формирует новую папку, файлы в которой содержат то, что было введено в ответ на её вопросы.

Я подумывал о том, чтобы использовать для работы с шаблонами утилиту yeoman, но, для моих нужд, она кажется неоправданно сложной. Я пользовался инструментом khaos, но он не поддерживается и не обновляет шаблоны автоматически, а обновлять их вручную всякий раз, когда мне надо их использовать, не особенно удобно.

▍Шаблон

Вот как я, пользуясь шаблоном template-vscode-extension, приступаю к разработке нового расширения для VS Code.

Создание нового проекта

После того, как ответы на вопросы программы введены, в моём распоряжении оказывается рабочее расширение, нечто вроде «Hello, world!» для VS Code. Шаблон включает в себя множество вспомогательных функций, которыми, как оказалось, я часто пользуюсь при разработке расширений. В частности, шаблон поддерживает загрузку пользовательского конфигурационного файла из папки .vscode, автоматическую регистрацию команд, он умеет находить текущую корневую директорию на основе активного файла и решать другие подобные задачи.

Если бы я мог повернуть время вспять, я бы, вероятно, поместил бы все эти вспомогательные функции в самостоятельный пакет, в нечто вроде vscode-utils, вместо того, чтобы делать копии этих функций в каждом проекте по разработке расширения. Но тогда я, к сожалению, не знал, что создам десятки расширений. Теперь мне приходится тратить определённое время на то, чтобы обновлять соответствующий код во всех проектах моих расширений.

Если вы планируете заняться разработкой расширений для VS Code, я посоветовал бы вам создать собственный шаблон, возможно, взяв за основу мой.

▍Полезная документация

В процессе разработки я всегда держу под рукой документацию по API VS Code. Поначалу работать с этим документом, представляющим собой огромную страницу, не особенно удобно, но если вы уделите некоторое время на то, чтобы бегло его просмотреть, если поймёте, какие API вам доступны, пользоваться им будет комфортно. В целом, могу отметить, что меня набор доступных API вполне устраивает.

И, кстати, если вы хотите разрабатывать расширения для VS Code, вам будет крайне полезно почитать этот раздел документации.

▍О разработанных мной расширениях

Я разрабатываю расширения для решения различных задач, о них мы поговорим ниже. Кроме того, некоторые из этих расширений помогают мне разрабатывать другие расширения.

Мои расширения

Как я уже говорил, я стремлюсь к продуктивности, поэтому многие мои расширения направлены на повышение производительности труда. Я стараюсь не заниматься постоянным изобретением велосипеда, пытаюсь добиваться чёткого разделения функций различных расширений для того, чтобы их совместное использование не вызывало бы проблем.

Не знаю, хорошо это или плохо, но мне нравится создавать расширения для VS Code. К тому же, поток задач, которые можно автоматизировать, не иссякает. Именно поэтому я, после того, как написал первое расширение, сделал второе, потом третье, дойдя, в итоге, до тридцать третьего.

Сейчас я в двух словах расскажу о моих расширениях. Подробности о них вы можете найти на их страницах.

▍Расширения для создания расширений

№1. Debug Manager

Расширение Debug Manager позволяет запускать отладку, даже из терминала, без необходимости создания задач или конфигурационных файлов. Я создал это расширение из-за того, что мне не хотелось засорять репозитории ненужными файлами (да и кто, например, пользуется задачами?). Я полагаю, что запуск отладчика из терминала — это возможность настолько полезная, что её стоило бы включить в сам VS Code.

Запуск отладчика из терминала

№2. StatusBar Debugger

Расширение StatusBar Debugger добавляет средства управления отладкой в строку состояния программы. Это гораздо удобнее, чем стандартная панель отладки. Кроме того, если бы VS Code давал бы больше данных по отладке, моё расширение было бы ещё лучше.

№3. Install .VSIX

Расширение Install .VSIX позволяет устанавливать .vsix-файлы прямо из панели Проводник (Explorer). Причиной появления этого расширения стал тот факт, что стандартная процедура установки таких файлов неудобна.

№4. Bump

Расширение Bump позволяет увеличивать номер версии проекта и вносить новые данные в журнал изменений. Этот инструмент действует, следуя собственной внутренней логике, но поддаётся настройке. Создал я его из-за того, что любому приличному расширению нужен журнал изменений, но это не означает, что разработчик такого расширения должен вносить записи в журнал вручную. Это — одно из моих любимых расширений. Возможно, я создам на его основе инструмент командной строки, так как мне хотелось бы, чтобы когда-нибудь оно позволило бы автоматизировать и GitHub-релизы.

Использование расширения Bump

№5. Optimize Images

Расширение Optimize Images позволяет оптимизировать изображения, имеющиеся в проекте, с использованием внешнего приложения, выбранного пользователем. Одна команда — и дело сделано.

▍Управление проектами

№6. Projects+

Расширение Projects+ служит для управления проектами. Оно обладает богатыми возможностями, поддаётся настройке, автоматически находит проекты. Одним из наиболее широко используемых расширений такого рода является Project Manager, но у меня около сотни репозиториев, и мне нужны подходящие инструменты для управления ими, одним из которых является поддержка групп неограниченного уровня вложенности.

Работа с расширением Project+

▍Управление todo-списками

№7. Todo+

Расширение Todo+ упрощает работу с todo-списками. Это мощный инструмент, лёгкий в использовании и поддающийся настройке. Если вам не нужна подсветка синтаксиса для TODO-файлов, или если вас, возможно, устроит стандартная встроенная подсветка, можете попробовать неплохое расширение Todo Tree.

Подсветка синтаксиса с использованием Todo+ и сведения уровня проекта

№8. Highlight

Расширение Highlight представляет собой продвинутое средство подсветки синтаксиса, основанное на регулярных выражениях. Оно пригодится для работы с todo-списками, аннотациями и прочим подобным. Весьма популярным в этой сфере является расширение TODO Highlight, но моё расширение является более универсальным и гораздо более мощным. Кроме того, вероятно, оно работает быстрее.

№9. Markdown Todo

Расширение Markdown Todo позволяет упростить работу с todo-списками внутри markdown-файлов. В нём нет ничего особенного, но оно позволяет пользоваться возможностями Todo+ внутри markdown-файлов.

№10. Projects+ Todo+

Расширение Projects+ Todo+ позволяет анализировать проекты, так сказать, с высоты птичьего полёта, видеть результат агрегации всех todo-файлов в одном файле. Если вы используете, для управления проектами, расширение Projects+, а для работы с todo-списками — Todo+, то, благодаря этому расширению, вы сможете собрать todo-списки из всех (или из некоторых) проектов в одном месте.

▍Расширения для открытия файлов

Мне важна возможность быстрого переключения между различными приложениями или веб-страницами. Именно поэтому я создал серию расширений для VS Code, упрощающих решение подобных задач.

№11. Open in Application

Расширение Open in Application позволяет открывать произвольные файлы в заданном по умолчанию приложении или в том приложении, которое решит использовать разработчик. Это — универсальное расширение.

№12. Open in Browsers

Расширение Open in Browsers добавляет в редактор команды, позволяющие открыть текущий файл или проект в любом браузере или даже сразу во всех доступных браузерах.

№13. Open in Code

Расширение Open in Code упрощает переключение между VS Code и VS Code Insiders.

№14. Open in Finder

Расширение Open in Finder предназначено для открытия текущего файла или проекта в файловом менеджере Finder.

№15. Open in GitHub

Расширение Open in GitHub позволяет открывать текущий проект или файл на github.com. Существует множество расширений для решения этой задачи, но, когда я их опробовал, оказалось, что в них слишком много функций, которые мне не нужны.

№16. Open in GitTower

Расширение Open in GitTower добавляет в редактор команду для открытия текущего проекта в GitTower.

№17. Open in Marketplace

Расширение Open in Marketplace оснащает редактор командой для открытия текущего проекта в каталоге расширений для VS Code.

№18. Open in node_modules

Расширение Open in node_modules позволяет находить в папке node_modules модули, соответствующие выделенному тексту или некоей произвольной строке, и открывать их папки. Оно полезно для тех случаев, когда разработчик хочет лучше разобраться с используемыми им модулями.

№19. Open in NPM

Расширение Open in NPM позволяет открывать страницы модулей в каталоге npm. Его удобно использовать для просмотра справочной информации модулей.

№20. Open in Ship

Расширение Open in Ship добавляет в редактор команду для открытия текущего проекта в Ship. К сожалению, Ship прекратил работу. Поэтому теперь мне, для того, чтобы не забыть о поступающих мне сведениях о проблемах в моих проектах, приходится пользоваться специальным листком с напоминаниями в Noty.

№21. Open in Terminal

Расширение Open in Terminal упрощает открытие текущего проекта в терминале.

№22. Open in Transmit

Расширение Open in Transmit позволяет открывать текущий файл или проект в Transmit.

▍Разное

№23. Browser Refresh

Расширение Browser Refresh позволяет обновлять страницу в браузере по нажатию ⌘R прямо из VS Code, без необходимости переключения на браузер. Это расширение пригодится в тех случаях, когда возможностью интерактивной перезагрузки пользоваться нельзя, и тогда, когда вам не нужно, чтобы browser-sync обновлял бы страницу без необходимости в этом.

№24. Commands

Расширение Commands позволяет вызывать произвольные команды из строки состояния. Поддерживается передача аргументов.

Пользовательские команды, созданные средствами Commands

№25. Diff

Расширение Diff позволяет сравнивать открытые файлы. Я создал это расширение из-за того, что конструкция code-diff path1 path2 работает слишком медленно.

№26. Git File History

Расширение Git File History упрощает анализ отличий текущего файла от его предыдущей версии. Существует множество расширений для решения этой задачи, но когда я их пробовал, они оказывались либо переполненными ненужными мне возможностями, либо нерабочими.

№27. GitHub Notifications

Расширение GitHub Notifications, безопасное и поддающееся настройке, предназначено для вывода в строку состояния сведений об уведомлениях на GitHub.

№28. Тема Monokai Night

Monokai Night Theme — это минималистичная тёмная тема, основанная на теме Monokai. Создал я её из-за того, что не смог подобрать то, что меня бы устраивало, из существующих тем.

Тема Monokai Night

№29. No [Unsupported]

Расширение No [Unsupported] предназначено для удаления строки «[Unsupported]» из заголовка редактора. Это расширение уже устарело, поэтому вместо него я рекомендую Fix VSCode Checksums. К несчастью, даже после этого и этого обсуждений надоедливая надпись «[Unsupported]» так никуда и не делась.

№30. Open Multiple Files

Расширение Open Multiple Files позволяет одновременно открывать все файлы в некоей папке. При необходимости файлы можно фильтровать по шаблону.

№31. Search — Open All Results

Расширение Search — Open All Results позволяет одновременно выводить все результаты поиска с использованием единственной команды.

№32. Terminals Manager

Расширение Terminals Manager автоматизирует работу сразу с несколькими терминалами, например, выполнение в них каких-то команд. Надо сказать, что Terminals Manager было моим первым расширением. Если вы пользуетесь терминалами — рекомендую его попробовать.

№33. Transmit

Расширение Transmit оснащает редактор несколькими командами для организации взаимодействия с Transmit.

Управление расширениями

Управление множеством репозиториев может оказаться непростой задачей. Расскажу о том, как это делаю я.

▍Повторяющиеся коммиты

Рано или поздно наступает момент, когда требуется внести некое изменение во все поддерживаемые репозитории. Это сводится к тому, что во множество репозиториев приходится делать одни и те же коммиты. Очень скоро это превращается в скучнейшее занятие.

Для того чтобы автоматизировать решение этой задачи я создал autogit — инструмент, который позволяет выполнять команды в применении ко множеству репозиториев.

Выполнение команды с помощью autogit

Я постоянно нахожу новые способы использования autogit. Например, недавно я выполнял с помощью этого инструмента следующие изменения во всех репозиториях, в которых хранится код моих расширений для VS Code:

  • Сборка с помощью webpack. Это дало улучшение скорости запуска примерно на 80%.
  • Игнорирование файла package-lock.json. Этот файл только засоряет мою историю коммитов. Вот хороший материал на эту тему.
  • Обновление tsconfig.json. Я интенсивно использую новые возможности языка, в частности, асинхронные функции. Они транспилируются, если цель транспиляции задана как <= es5, в весьма медленные конструкции. Так как VS Code понимает современный код, в этом нужды больше нет.
  • Удаление TSLint. Я обнаружил, что, в основном, не обращаю внимания на подсказки линтера, поэтому от этой возможности я избавился.
  • Использование логотипа высокого разрешение в справочных материалах. Раньше я пользовался логотипом размером 128×128, теперь, для того, чтобы улучшить внешний вид справочных материалов, использовал более качественное изображение. Не могу сказать, что сама картинка чудо как хороша, но это уже другая история.

Внести подобные изменения в один репозиторий недолго, а вот когда речь идёт о тридцати трёх, без средств автоматизации жить уже гораздо сложней.

▍Синхронизация описания и ключевых слов с GitHub

То, о чём тут пойдёт речь, делать необязательно, но мне не помешал бы инструмент, который автоматизирует синхронизацию описаний и ключевых слов. С этой задачей можно справиться средствами моих инструментов autogit и autogit-command-github-sync.

Синхронизация описаний и ключевых слов средствами autogit

А вот autogit-command-github-publish — моё средство для автоматизированного создания новых репозиториев.

▍Отчёты

Вскоре после того, как я создал несколько расширений, мне стало интересно узнать о том, насколько они популярны, как, со временем, меняется количество их загрузок. Найти сведения по всем расширениям некоего разработчика можно на специальной странице. Например, вот моя страница. Однако эта страница не даёт сведений, например, о том, сколько загрузок расширений было сделано с момента последней проверки. Именно поэтому я создал rssa. Это — инструмент, который позволяет отслеживать изменения всего чего угодно, доступного по URL.

Данные, получаемые средствами rssa

Текст — это хорошо, но куда лучше было бы представить данные в виде графика. Сейчас я занимаюсь разработкой инструмента для решения этой задачи, его я пока не опубликовал. Вот, например, как выглядит график загрузок расширения Todo+, построенный на основе данных, полученных с помощью rssa.

График загрузок Todo+

Здесь, в некоторых местах, можно заметить резкое увеличение числа загрузок. Происходит это при публикации обновлений, так как установка обновлений расширения учитывается системой как загрузка. Это ведёт к тому, что любой может оказаться автором расширения с миллионом загрузок, написав его и опубликовав множество обновлений. Это, кстати, одна из проблем каталога расширений для VS Code.

Итоги

Одно время я думал, что, по количеству опубликованных расширений для VS Code, я нахожусь на втором месте после Microsoft. Однако, как оказалось, кое у кого их на 2 больше, чем у меня. Поэтому я продолжаю писать расширения.

Уважаемые читатели! Пишете ли вы расширения для VS Code?

Your First Extension

This document will take you through creating your first VS Code extension («Hello World») and will explain the basic VS Code extensibility concepts.

In this walkthrough, you’ll add a new command to VS Code which will display a simple «Hello World» message. Later in the walkthrough, you’ll interact with the VS Code editor and query for the user’s currently selected text.

Prerequisites

You need node.js installed and available in your $PATH.

Generate a New Extension

The simplest way to add your own functionality to VS Code is through adding a command. A command is registers a callback function which can be invoked from the Command Palette or with a key binding.

We have written a Yeoman generator to help get you started. Install Yeoman and the Yeoman VS Code Extension generator and scaffold a new extension:

npm install -g yo generator-code
yo code

For the hello world extension, you can either create a TypeScript extension or a JavaScript one. For this example, we pick a TypeScript extension.

The command generator

Running your Extension

  • Launch VS Code, choose File > Open Folder and pick the folder that you generated.
  • Press kb(workbench.action.debug.start) or click on the Debug icon and click Start.
  • A new instance of VS Code will start in a special mode (Extension Development Host) and this new instance is now aware of your extension.
  • Press kb(workbench.action.showCommands) and run the command named Hello World.
  • Congratulations! You’ve just created and executed your first VS Code command!

Running VS Code with an extension

The Structure of an Extension

After running, the generated extension should have the following structure:

.
├── .gitignore
├── .vscode                     // VS Code integration
│   ├── launch.json
│   ├── settings.json
│   └── tasks.json
├── .vscodeignore
├── README.md
├── src                         // sources
│   └── extension.ts            // extension.js, in case of JavaScript extension
├── test                        // tests folder
│   ├── extension.test.ts      // extension.test.js, in case of JavaScript extension
│   └── index.ts                // index.js, in case of JavaScript extension
├── node_modules
│   ├── vscode                  // language services
│   └── typescript              // compiler for typescript (TypeScript only)
├── out                         // compilation output (TypeScript only)
│   ├── src
│   |   ├── extension.js
│   |   └── extension.js.map
│   └── test
│       ├── extension.test.js
│       ├── extension.test.js.map
│       ├── index.js
│       └── index.js.map
├── package.json                // extension's manifest
├── tsconfig.json               // jsconfig.json, in case of JavaScript extension
├── typings                     // type definition files
│   ├── node.d.ts               // link to Node.js APIs
│   └── vscode-typings.d.ts     // link to VS Code APIs
└── vsc-extension-quickstart.md // extension development quick start

Let’s go through the purpose of all these files and explain what they do:

The extension manifest: package.json

  • Please read the package.json extension manifest reference
  • More information on package.json contribution points
  • Each VS Code extension must have a package.json file that describes it and its capabilities.
  • VS Code reads this file during start-up and reacts to each contributes section immediately.

Example TypeScript extension manifest

{
    "name": "myFirstExtension",
    "description": "",
    "version": "0.0.1",
    "publisher": "",
    "engines": {
        "vscode": "^0.10.1"
    },
    "categories": [
        "Other"
    ],
    "activationEvents": [
        "onCommand:extension.sayHello"
    ],
    "main": "./out/src/extension",
    "contributes": {
        "commands": [{
            "command": "extension.sayHello",
            "title": "Hello World"
        }]
    },
    "scripts": {
        "vscode:prepublish": "node ./node_modules/vscode/bin/compile",
        "compile": "node ./node_modules/vscode/bin/compile -watch -p ./"
    },
    "devDependencies": {
        "typescript": "^1.6.2",
        "vscode": "0.10.x"
    }
}

Note: A JavaScript extension doesn’t require the scripts field as no compilation is needed.

  • This specific package.json describes an extension that:
  • contributes an entry to the Command Palette (kb(workbench.action.showCommands)) with the label "Hello world" that will invoke a command "extension.sayHello".
  • requests to get loaded (activationEvents) when the command "extension.sayHello" is invoked.
  • has its main JavaScript code in a file called "./out/src/extension.js".

Note: VS Code does not load the code of an extension eagerly at start-up. An extension must describe, through the activationEvents property under what conditions it should get activated (loaded).

Code

The generated extension’s code is in extension.ts (or extension.js in case of a JavaScript extension):

// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {

    // Use the console to output diagnostic information (console.log) and errors (console.error)
    // This line of code will only be executed once when your extension is activated
    console.log('Congratulations, your extension "my-first-extension" is now active!');

    // The command has been defined in the package.json file
    // Now provide the implementation of the command with  registerCommand
    // The commandId parameter must match the command field in package.json
    var disposable = vscode.commands.registerCommand('extension.sayHello', () => {
        // The code you place here will be executed every time your command is executed

        // Display a message box to the user
        vscode.window.showInformationMessage('Hello World!');
    });

    context.subscriptions.push(disposable);
}
  • Each extension should export from its main file a function named activate(), which VS Code will invoke only once when any of the activationEvents described in the package.json file occur.
  • This specific extension imports the vscode API and then registers a command, associating a function to be called when the command "extension.sayHello" gets invoked. The command’s implementation displays a «Hello world» message in VS Code.

Note: The contributes section of the package.json adds an entry to the Command Palette. The code in extension.ts/.js defines the implementation of "extension.sayHello".

Note: For TypeScript extensions, the generated file out/src/extension.js will be loaded at runtime and executed by VS Code.

Miscellaneous files

  • .vscode/launch.json defines launching VS Code in the Extension Development mode. It also points with preLaunchTask to a task defined in .vscode/tasks.json that runs the TypeScript compiler.
  • .vscode/settings.json by default excludes the out folder. You can modify which file types you want to hide.
  • .gitignore — Tells Git version control which patterns to ignore.
  • .vscodeignore — Tells the packaging tool which files to ignore when publishing the extension.
  • README.md — README file describing your extension for VS Code users.
  • vsc-extension-quickstart.md — A Quick Start guide for you.
  • test/extension.test.ts — you can put your extension unit tests in here and run your tests against the VS Code API (see Testing Your Extension)

Running your Extension

Now that the roles of the files included in the extension are clarified, here is how your extension gets activated:

  • The extension development instance discovers the extension and reads its package.json file.
  • Later when you press kb(workbench.action.showCommands):
  • The registered commands are displayed in the Command Palette.
  • In this list there is now an entry "Hello world" that is defined in the package.json.
  • When selecting the "Hello world" command:
  • The command "extension.sayHello" is invoked:
  • An activation event "onCommand:extension.sayHello" is created.
  • All extensions listing this activation event in their activationEvents are activated.
    • The file at ./out/src/extension.js gets loaded in the JavaScript VM.
    • VS Code looks for an exported function activate and calls it.
    • The command "extension.sayHello" is registered and its implementation is now defined.
  • The command "extension.sayHello" implementation function is invoked.
  • The command implementation displays the «Hello World» message.

Debugging your Extension

Simply set a breakpoint, for example inside the registered command and run the "Hello world" command in the Extension Development VS Code instance.

Debug Extension

Note: For TypeScript extensions, even though VS Code loads and executes out/src/extension.js, you are actually able to debug the original TypeScript code due to the generated source map out/src/extension.js.map and VS Code’s debugger support for source maps.

Tip: The Debug Console will show all the messages you log to the console.

To learn more about the extension development environment.

A Simple Change

In extension.ts (or extension.js, in a JavaScript extension), try replacing the extension.sayHello command implementation to show the number of characters selected in the editor:

var editor = vscode.window.activeTextEditor;
if (!editor) {
    return; // No open text editor
}

var selection = editor.selection;
var text = editor.document.getText(selection);

// Display a message box to the user
vscode.window.showInformationMessage('Selected characters: ' + text.length);

Tip: Once you make changes to the extension source code, you need to restart the Extension Development instance of VS Code. You can do that by using kbstyle(Ctrl+R) (Mac: kbstyle(Cmd+R)) in the second instance or by clicking the Restart button at the top of your primary VS Code instance.

Running the modified extension

Installing your Extension Locally

So far, the extension you have written only runs in a special instance of VS Code, the Extension Development instance. To get your extension running in all instances of VS Code, you need to copy it to a new folder under your local extensions folder:

  • Windows: %USERPROFILE%.vscodeextensions
  • Mac/Linux: $HOME/.vscode/extensions

Publishing your Extension

Read about how to Share an Extension.

Next Steps

In this walkthrough, we’ve seen a very simple extension. For a more detailed example, see the Word Count Example which shows how to target a specific language (Markdown) and listen to the editor’s document changed events.

If you’d like to read more generally about the extension APIs, try these topics:

  • Extension API Overview — Learn about the full VS Code extensibility model.
  • API Patterns and Principles — VS Code extensibility is based on several guiding patterns and principles.
  • Contribution Points — Details about the various VS Code contribution points.
  • Activation Events — VS Code activation events reference

Common Questions

Nothing yet

Понравилась статья? Поделить с друзьями:
  • Как написать расширение для visual studio
  • Как написать расширение для opera
  • Как написать расширение для chrome
  • Как написать расчет ущерба
  • Как написать расчертить