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:
- Change the message from «Hello World from HelloWorld!» to «Hello VS Code» in
extension.ts
. - Run Developer: Reload Window in the new window.
- 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
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!
Why should you create a VS Code extension?
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).
Afterwards, you will need to edit your extension name and description. You can just proceed with anything you prefer.
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:
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).
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.
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)
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
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!
Why should you create a VS Code extension?
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).
Afterwards, you will need to edit your extension name and description. You can just proceed with anything you prefer.
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:
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).
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.
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)
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.
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 theDebug
icon and clickStart
. - 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 namedHello World
. - Congratulations! You’ve just created and executed your first VS Code command!
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 theactivationEvents
described in thepackage.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 thepackage.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 withpreLaunchTask
to a task defined in.vscode/tasks.json
that runs the TypeScript compiler..vscode/settings.json
by default excludes theout
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 thepackage.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 file at
- 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.
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 mapout/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.
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