Adding Snippets to Visual Studio Code
Code snippets are ready-made snippets of code you can quickly insert into your source code. For example, a for code snippet creates an empty for loop.
Each snippet defines a prefix under which it will appear in IntelliSense via ( kb(editor.action.triggerSuggest) ) as well as a body inserted when the snippet is selected. The snippet syntax follows the TextMate snippet syntax with the exception of ‘regular expression replacements’, ‘interpolated shell code’ and ‘transformations’, which are not supported.

Add Snippets from the Gallery
Many snippets have been uploaded to the VS Code Extension Gallery by the community. If you find one you want to use, simply install it and restart VS Code and the new snippet will be available.
You can also browse the VS Code Marketplace to find available snippets.
Creating your Own Snippets
You can define your own snippets for specific languages. Snippets are defined in a JSON format.
The example below is a For Loop snippet for JavaScript .
"For Loop": < "prefix": "for", "body": [ "for (var $= 0; $ < $.length; $++) = $[$];", "\t$0", ">" ], "description": "For Loop" >,
In the example above:
- For Loop is the snippet name
- prefix defines a prefix used in the IntelliSense drop down. In this case for .
- body is the snippet content.
Possible variables are:- $1, $2 for tab stops
- $ and $ and $ for variables
- Variables with the same id are connected.
To open up a snippet file for editing, open User Snippets under File , Preferences and select the language for which the snippets should appear.
Once you have added a new snippet, you can try it out right away, no restart needed.
Using TextMate Snippets
You can also add TextMate snippets (.tmSnippets) to your VS Code installation using the yo code extension generator. The generator has an option New Code Snippets which lets you point to a folder containing multiple .tmSnippets files and they will be packaged into a VS Code snippet extension. The generator also supports Sublime snippets (.sublime-snippets).
The final generator output has two files: an extension manifest package.json which has metadata to integrate the snippets into VS Code and a snippets.json file which includes the snippets converted to the VS Code snippet format.
. ├── snippets // VS Code integration │ └── snippets.json // The JSON file w/ the snippets └── package.json // extension's manifestCopy the generated snippets folder to a new folder under your .vscode/extensions folder and restart VS Code.
Sharing Your Snippets in the Gallery
Once you have created your snippets and tested them out, you can share them with the community.
To do this, you need to create a snippet extension. If you’ve used the yo code extension generator, your snippet extension is ready to be published.
If you want to share user snippets, you’ll need to package your snippet json file along with an extension manifest which has the necessary metadata to integrate the snippets into VS Code.
Depending on your plaform, your user snippets file is located here:
- Windows %APPDATA%\Code\User\snippets\(language).json
- Mac $HOME/Library/Application Support/Code/User/snippets/(language).json
- Linux $HOME/.config/Code/User/snippets/(language).json
where (language).json depends on the targeted language of the snippets (e.g. markdown.json for Markdown snippets). Create a new folder for your extension and copy your snippet file to a snippets subdirectory.
Now add a extension manifest package.json file to the extension folder. The snippet extension manifest follows the structure defined in the Extension Manifest reference and provides a snippets contribution.
Below is an example manifest for Markdown snippets:
< "name": "DM-Markdown", "publisher": "mscott", "description": "Dunder Mifflin Markdown snippets", "version": "0.1.0", "engines": < "vscode": "0.10.x" >, "categories": ["Snippets"], "contributes": < "snippets": [ < "language": "markdown", "path": "./snippets/markdown.json" >] > >Note that snippets need to be associated with a language identifier. This can be a language supported directly by VS Code or a language provided by an extension. Make sure the language identifier is correct.
You then use the vsce publishing tool to publish the snippet extension to the VS Code Extension Gallery.
Tip: To make it easy for users to find your snippet, include the word «snippet» in the extension description and set the Category to Snippets in your package.json .
We also have recommendations on how to make your extension look great on the VS Code Marketplace, see Marketplace Presentation Tips.
Next Steps
Snippets are just one way to extend VS Code. If you’d like to learn more about VS Code extensibility, try these topics:
- Colorizers and Bracket Matchers — Learn how to import TextMate colorizers
- Custom themes — Learn how to import existing TextMate themes.
- Extending Visual Studio Code — Learn about other ways to extend VS Code
- Editing Evolved — Learn more about the VS Code editor’s capabilities
Common Questions
Q: I created a snippets extension but they aren’t showing up in the VS Code editor?
A: Be sure you have correctly specified the language identifier for your snippet (e.g. markdown for Markdown .md files, plaintext for Plain Text .txt files). Also verify that the relative path to the snippets json file is correct.
How to Create Snippets for VS Code
This article is geared towards JavaScript and TypeScript so the code examples will be written in mentioned languages. However, the article describes snippet creation in a general way so even if JavaScript or TypeScript isn’t your choice of language, you will hopefully understand how snippet creation works.
Let’s talk about snippets generally. Snippets are pieces of code that we can use again and again in our code projects. They are usually created to speed up our development work so we can spend time-solving interesting problems instead of typing the _same old_ _boring code_.
We tend to use snippets someone else has created for us, or we create our own that fits our coding style.
So what is a good candidate to make a snippet out of:
- Class, oftentimes we create plenty of classes in our solution
- If, we tend to write quite a lot of if, if else, if else if, else statements
- Try-catch, this is also a very common construct. Wouldn’t it be nice if there was a snippet that supported try, catch and finally?
- Function, we create a ton of functions, so some kind of default function with a suitable number of parameters make sense
- Logging to the screen, we tend to do this quite often for the purpose of debugging
- Your choice, you might have things you do quite often that’s unique to you — such as reading to/from a file, accessing a database, etc. What snippets you exactly need, is up to you.
Snippets in VS Code
You can create two types of snippets in VS Code:
- global, selectable for all languages
- language specific, only possible to use for a specific language
Creating our first snippet
It’s almost dead easy to create a snippet so let’s do just that and explain concepts as we encounter them.
The first thing we need to do is to select the type of snippet we are about to create. Our choice here is global vs language specific. Let’s head to the menu and create a global snippet. Select the following from the menu Code /Preference / User Snippets
the above image shows you several things of interest:
- Existing snippets, if you have created snippets before, you can select those and have them loaded into VS code
- New Global Snippets file…, selecting this option creates a global file
- Language-specific files, selecting any of these options will create a specific snippet file for that language. Select HTML, for example, will create a html.json file
As we stated earlier, let’s create a global file so select New Global Snippets file, the second option from the top. Let’s name it global, the result show looks like this:
It is worth noting that global named itself global.code-snippets. This file has placed itself in /Users//Library/Application Support/Code/User/snippets, if you want to look at it afterward. We also see that everything is commented out. There is some code of interest though starting with Example: so let’s uncomment that and have a closer look, so it looks like this:
Now we are looking at a working example. It is worth noting how everything starts with curly braces, and the reason for that is that we are simply editing a JSON file. The next point of interest is Print to console. This one is simply the name of the snippet. Print to console defines an object within curly braces so let’s break down each property that it defines:
- scope, this is the supported languages for this snippet, supported languages here are javascript and typescript. Each supported language is separated by a comma. This means that if we are inside of .js or .ts file this snippet would be possible to use
- prefix, this is what you need to type in the code window for the snippet to appear. In our case we need to type log
- body, this is your snippet. The data type is an array and to support a snippet that has several rows we need to add a new entry to the array. We will go through that later
- description, this is a field that lets us describe a little more what is going on
- $1, $2, this is simply where the cursor ends up when you hit the tab button
Trying out our snippet
We stated the log is what we need to type to activate the snippet and we need to be inside of a file ending in .js or .ts . So let’s try it:
We can see above that we are being presented with a list as we type log. The first item in the list our snippet. You can see that “Print to console” is what we wrote as the snippet name and “Log output to console” is our description field. We hit the return key at this point and we end up with this:
We see our snippet is being placed in the code window, and we also see how our cursor ended up inside of the log() method. Why is that? That has a very simple explanation, that’s where we said the cursor should end up, we decided upon that here:
So you see where we place $1 or $2 matters and correctly placed it can really speed up the developer experience.
Second snippet — a class
Ok so know we understand what goes on and the inner anatomy of a snippet. Let’s create our own snippet from scratch now:
We have a second snippet and a multiline snippet at that. Let’s break it down.
We support javascript and typescript by defining that as values to scope.
We say to activate the snippet by typing cc .
Then we come to the actual snippet — our body property, which is multiline. We can see that it is multiline as we have added x number of items in our body array property. The value of the body is simply what we can expect from a class definition, with a constructor. We have added some interesting bits in here though $1 and $2 . Those are placed after the class property and inside the constructor. This is done on purpose so the user has to type as little as possible. The first thing you typically do as a developer is to name the class and secondly is to add some initialization code to your constructor. If that isn’t the order in which you do things, feel free to move $1 and $2 to where they make sense to you.
Trying out our snippet
Now we type cc to activate our snippet and we are faced with its name and description. Upon selecting the snippet by hitting the return key we end up with this:
As you can see above, we are shown where the cursor first ends up $1, which is right after class. Hitting the tab key again we should go to the point of the second tab step, $2. So let’s see what that looks like:
We see we have given the class a name Test and we have hit tab and we ended up with our cursor inside of the constructor function.
Language-specific snippet
This time we want to create a language-specific snippet. So we go to the menu and select Code / Preferences / User Snippets. Once there we select Typescript and we are presented with the following result:
We can see that the filename is a bit different this time around. Instead of being called .code-snippets it’s called typescript.json. So when the file ends with .json we are dealing with a language specific file. It is worth highlighting that a language-specific snippet will only work for that snippet, so if we are inside of a file ending in .js typing our prefix value won’t activate it. Instead, we need to be inside of .ts file for our snippet to be selectable.
Ok let’s think for a second, we have chosen Typescript as the specific language, so that’s all we are going to support. This means we are about to create snippets using language specific constructs like types and other things. Let’s recreate our class snippet but for Typescript:
Above we have created a snippet that utilizes some language-specific features from Typescript such as enum and private used within a constructor (that creates the backing fields for us ) and to top it off we have created a pretty cool theme, a fantasy environment. So if you had some game creation in mind, this snippet is ready for action 🙂
Trying out our snippet
Ok, so we set the prefix to tc so we need to type tc to activate our snippet. The end result looks like the following:
Above we can see our enum construct CharacterTypes is being created and also our class snippet. We can now easily create an object from this by for example typing:
const hero = new Hero(‘hero’, 18, CharacterTypes.Healer);That’s it. Creating a language-specific snippet wasn’t all that different. The filename ending looks different and it is targeted to a specific language.
Summary
We have looked at snippets in VS Code. We have shown how we can
- load existing snippets into our coding environment
- create a global / language specific snippet
- explain the different parts that make up a snippet and how to use it
It is my hope that you with this new found knowledge are able to both use existing snippets, create your own snippets, and boost your productivity.
Further reading
We’ve only scratched a bit on what is possible to do with a snippet but it should be enough to get you going. For more information on snippets please have a look at the official docs Snippet creation.
What’s next?
In the next article, we will cover how we can package our snippet into an extension and tell the world about it. Why not let the whole code community benefit from your creation. 🙂 Stay tuned.
Сниппеты в VS Code

Впереди нас ждут две увлекательные статьи, так что, пожалуй, начнем же прямо сейчас.
- «VS Code — Создание cниппета», вы здесь)
- «VS Code — публикуем свое расширение (сниппет)», в этой статье будет рассказано, как стать автором расширения и загрузить обернутый в пакет расширения сниппет в marketplace.
Сниппет (англ. snippet — фрагмент, отрывок) — программный термин, обозначающий небольшой фрагмент исходного кода или текста, пригодного для повторного использования. Данная технология избавляет от пустой траты времени на ввод текста с самого начала каждого проекта. Кроме того, у вас также могут быть особые требования к стандартной функции, которую вы хотите использовать. Все это может войти в сниппет. Будьте более продуктивны — используйте сниппеты
В статье мы расскажем:
- Что такое сниппеты и для чего используются. Может быть, вы никогда не слышали о сниппетах или, не совсем понимаете, что-же может стать хорошим сниппетом для наших задач.
- Мы расскажем, как написать сниппет и как, к примеру, взаимодействовать с положением курсора.
- Мы разберем, как создавать снипетты как и для всех языков сразу, так и для одного.
Эта статья посвященна JavaScript и TypeScripts. Примеры кода будут написаны на указанных языках. Тем не менее, т.к статья описывает базовые принципы создания сниппетов вы сможете все понять, несмотря на то. что возможно не пишете на этих языках.
Ресурсы
Главными ресурсами для этого приложения становятся: официальная документация для VS Code и специализированная страница по созданию сниппетов кода. На этих ресурсах многому можно научиться, так что посмотрите там:
- Официальная документация VS Code
- Создание собственных сниппетов
Что же такое эти причудливые сниппеты и для чего они нужны?
Давайте в целом детальнее рассмотрим что такое сниппеты. Сниппеты кода — это фрагменты кода, которые мы можем многократно использовать в наших проектах. Создаются они обычно для того, чтобы ускорить время разработки и тратить время на решение интересных задач вместо того, чтобы набирать тот же старый скучный код.
Мы можем использовать сниппеты, которые кто-то другой создал для нас, или же мы создаем свои собственные, соответствующие код стайлу нашей компании.
Так что же хорошо подходит в роле сниппета :
- Class, часто мы создаем много классов в нашем решении.
- If, мы склонны писать довольно много if , if else , if else if, else конструкций.
- Try-Catch, это также очень распространенная конструкция. Разве не было бы хорошо, если бы был сниппет, который поддерживал try, catch and finally ?
- Function, мы обычно создаем массу функций, поэтому имеет смысл использовать какую-то дефолтовую функцию в роле шаблона с подходящим количеством параметров.
- Вход на экран, мы склонны делать это довольно часто с целью отладки.
- Сниппет на ваш выбор, у вас могут быть такие вещи, которые вы делаете довольно часто и которые, возможно, уникальны для вас, к примеру, чтение из файла, доступ к базе данных. Какие сниппеты использовать зависит от вас.
Сниппеты в VS Code
Вы можете создать два типа сниппетов в VS Code:
- глобальный, подходящий для всех языков
- для конкретного языка, возможно использовать только для определенного языка
Создаем первый сниппет
Просто взять и создать сниппет практически невозможно, поэтому давайте детально разберем как мы приходим к его созданию.
Первое, что нам нужно сделать, это выбрать тип фрагмента, который мы собираемся создать. Сейчас оттадим предпочтение варианту global заместо language specific . Давайте создадим global snippet. Выберите в меню следующее: Code => Preference => User Snippets.

Рассмотрим этот скрин, т.к на нем есть много чего интересного:
- Существующие сниппеты: если вы создавали их заранее, то сможете выбрать и загрузить в VS
- Новый файл Global Snippets . выбор этой опции создает глобальный файл
- Файлы, зависящие от языка: при выборе любого из этих параметров будет создан специальный файл сниппета для этого языка. Выберите html и для примера создайте html.json файл.
Как мы уже говорили ранее, давайте создадим глобальный файл, поэтому выберите New Global Snippets file , второй вариант сверху. Давайте назовем его global и получим вот такой результат:

Стоит отметить, что глобальное имя само по себе называется global.code-snippets . Этот файл лежит в /Users//Library/Application Support/Code/User/snippets , если вы хотите потом на него посмотреть. Вы увидете, что все закомментировано, а все самое интересное, на самом деле, начинается с слова Example : поэтому давайте раскомментируем его и рассмотрим подробнее. Выглядит все так:

Теперь перед нами рабочий пример. Стоит отметить, что все начинается с фигурных скобок, причина в том, что мы просто редактируем файл JSON. Следующий интересный момент — за печать в консоль у нас полностью отвечает сниппет и мы лишь указываем его имя. Вывод в консоль определяет объект в фигурных скобках, поэтому давайте разберем каждое свойство :
- scope, это поддерживаемые языки для этого сниппета. В примере поддерживаются javascript and typescript. Каждый поддерживаемый язык отделяется запятой. Это означает, что если мы находимся внутри .js или .ts файла, то можно будет использовать этот сниппет.
- prefix, это то, что вам нужно ввести в окне кода, чтобы появился сниппет. В нашем случае нам нужно набрать log .
- body, это непосредственно ваш фрагмент кода. Тип данных — это массив, и для поддержки фрагмента, содержащего несколько строк, нам нужно добавить новую запись в массив, позже мы обьясним, как это сделать.
- description, это поле, в котором нужно дать краткое описание того, какой компонент за что ответственен.
- $1 , $2 , это просто отметки, где заканчивается курсор, когда вы нажимаете кнопку табуляции
Попробуем сниппет на деле
Мы указали в логике, что нам нужно ввести, чтобы активировать фрагмент, и мы помним, что, чтобы все сработало, нам нужно быть внутри файла, заканчивающегося на .js или .ts .Итак, давайте попробуем:

Как только мы начинаем набирать команду log , раскрывается список вариантов. Первый пункт в списке это наш сниппет. Вы можете видеть, что Print to console — это то, что мы написали как имя фрагмента, а Log output to console.. это наше поле описания. В этот момент мы нажимаем кнопку return и в итоге получаем следующее:

Мы видим, что наш фрагмент помещается в окно кода, но мы также видим, как наш курсор оказался внутри метода log() . Почему так получилось? Этому есть очень простое объяснение, вот здесь мы как раз указали, что курсору нужно остановиться:

Таким образом, вы видите, что от того, как мы размещаем $ 1 или $2 зависит многое, в том числе и скорость процесса разработки.
Второй сниппет- класс
Итак, теперь мы знаем и понимаем всю внутреннюю анатомию сниппета. Настало время создать собственный сниппет с нуля:

Хорошо, теперь у нас есть второй сниппет и, к тому же, многострочный сниппет. Давайте разберемся с этим. Мы поддерживаем javascript и typescript, определяя их как значения scope. Кроме того, мы можем активировать сниппет, набрав команду cc . Затем мы подошли к текущему сниппету нашего свойства body . Теперь он будет уже многострочным. Это следует из того, что мы добавили x количество элементов в нашем свойстве массива. Значение тела — это то, что мы можем ожидать от определения класса с помощью конструктора. Здесь мы добавили несколько интересных битов, при помощи $1 и $2 . Они размещаются после свойства class и внутри конструктора. Это сделано специально, поэтому пользователь должен печатать как можно меньше. Первое, что вы будете делать как разработчик, — это, вероятно, msot, для того, чтобы дать имя классу и добавить некоторый код инициализации в ваш конструктор. Если вы делаете это в другом порядке, не стесняйтесь перемещать $1 и $2 туда, где они будут кстати.
Применим наш сниппет

Итак, мы ввели cc , чтобы активировать наш сниппет и получили его название и описание. После выбора фрагмента, нажатием кнопки return мы получим следующее:

На скриншоте вы можете увидеть, где заканчивается курсор вначале $ 1. Нажав снова на клавишу, мы должны перейти к точке второго шага табуляции, $ 2. Итак, давайте посмотрим, как это выглядит:

Мы видим, что мы дали классу название Test и можем нажать tab , в результате которого мы получим курсор внутри функции конструктора.
Сниппет для конкретного языка
На этот раз мы хотим создать фрагмент кода для конкретного языка. Итак, мы идем в меню и выбираем Code => Preferences => User Snippets. Оказавшись там, мы выбираем Typescript .
Мы видим, что в этот раз имя файла немного отличается. Вместо того, как бывает обычно .code-snippets он называется typescript.json .Поэтому, когда файл заканчивается на .json , мы имеем дело с файлом, относящимся к конкретному языку. Стоит подчеркнуть, что сниппет кода для конкретного языка будет работать только для этого фрагмента, поэтому, если мы находимся внутри файла, оканчивающегося на .js , ввод нашего prefix значения не активирует его. Вместо этого мы должны быть внутри .ts файла, чтобы наш сниппет мог быть выбран.
Итак, давайте на секунду отвлечемся и подумаем, мы выбрали Typescript в качестве конкретного языка, так что это пока единственный язык, что мы собираемся поддерживать. Это означает, что мы собираемся создавать сниппеты, используя специфические для языка конструкции, такие как типы и всякие другие вещи. Давайте воссоздадим наш сниппет кода, но для Typescript:

Выше мы создали сниппет, который использует некоторые специфические для языка функции из Typescript, такие как enum и private , используемые в конструкторе (который создает для нас вспомогательные поля), и, в завершение, мы создали довольно классную тему, фантастическую среду, так что если вы думали, что мы здесь в игрушки играем, то, заметьте — сниппет готов к использованию:)
Применим наш сниппет
Итак, мы задали prefix значение tc и т.к нам нужно ввести tc значение, чтобы активировать наш сниппет. Конечный результат выглядит следующим образом:

Выше мы видим, как создается наш enum CharacterTypes , а также наш сниппет класса. Теперь из этого легко можно создать объект, например, набрав:
const hero = new Hero('hero', 18, CharacterTypes.Healer);Вот и все. Создание фрагмента для конкретного языка не так уж и отличается. Окончание имени файла выглядит по-другому, и оно ориентировано на определенный язык.
Резюмируя
Мы рассмотрели сниппеты в VS Code. Мы разобрали, каким образом можно:
- загрузить существующие сниппеты в нашу среду программирования
- создать глобальный/специфичный для языка сниппет
- а также дали обьяснение тому, какие части составляют сниппет и как его использовать
Я надеюсь, что благодаря этим новым знаниям вы сможете использовать существующие сниппеты, создавать свои собственные и реально повысить свою производительность.
Мысли на будущее
Мы лишь немного набросали примеров того, как можно использовать сниппеты кода, но этого должно быть достаточно, чтобы начать работу. Для получения дополнительной информации о сниппетах, пожалуйста, читайте официальную документацию «Создание собственных фрагментов»
Что будет дальше?
В следующей статье мы рассмотрим, как упаковать наш сниппет в расширение и расшарить его на весь мир. Почему бы не позволить всему сообществу разработчиков кода воспользоваться вашим творением. 🙂 Оставайтесь в курсе
Взаимодействие: alert, prompt, confirm
Так как мы будем использовать браузер как демо-среду, нам нужно познакомиться с несколькими функциями его интерфейса, а именно: alert , prompt и confirm .
alert
С этой функцией мы уже знакомы. Она показывает сообщение и ждёт, пока пользователь нажмёт кнопку «ОК».
alert("Hello");Это небольшое окно с сообщением называется модальным окном. Понятие модальное означает, что пользователь не может взаимодействовать с интерфейсом остальной части страницы, нажимать на другие кнопки и т.д. до тех пор, пока взаимодействует с окном. В данном случае – пока не будет нажата кнопка «OK».
prompt
Функция prompt принимает два аргумента:
result = prompt(title, [default]);Этот код отобразит модальное окно с текстом, полем для ввода текста и кнопками OK/Отмена.
title Текст для отображения в окне. default Необязательный второй параметр, который устанавливает начальное значение в поле для текста в окне.
Квадратные скобки в синтаксисе [. ]
Квадратные скобки вокруг default в описанном выше синтаксисе означают, что параметр факультативный, необязательный.
Пользователь может напечатать что-либо в поле ввода и нажать OK. Введённый текст будет присвоен переменной result . Пользователь также может отменить ввод нажатием на кнопку «Отмена» или нажав на клавишу Esc . В этом случае значением result станет null .
Вызов prompt возвращает текст, указанный в поле для ввода, или null , если ввод отменён пользователем.
let age = prompt('Сколько тебе лет?', 100); alert(`Тебе $ лет!`); // Тебе 100 лет!Для IE: всегда устанавливайте значение по умолчанию
Второй параметр является необязательным, но если не указать его, то Internet Explorer вставит строку «undefined» в поле для ввода.
Запустите код в Internet Explorer и посмотрите на результат:
let test = prompt("Test");Чтобы prompt хорошо выглядел в IE, рекомендуется всегда указывать второй параметр:
let test = prompt("Test", ''); //confirm
result = confirm(question);Функция confirm отображает модальное окно с текстом вопроса question и двумя кнопками: OK и Отмена.
Результат – true , если нажата кнопка OK. В других случаях – false .
let isBoss = confirm("Ты здесь главный?"); alert( isBoss ); // true, если нажата OKИтого
Мы рассмотрели 3 функции браузера для взаимодействия с пользователем:
alert показывает сообщение. prompt показывает сообщение и запрашивает ввод текста от пользователя. Возвращает напечатанный в поле ввода текст или null , если была нажата кнопка «Отмена» или Esc с клавиатуры. confirm показывает сообщение и ждёт, пока пользователь нажмёт OK или Отмена. Возвращает true , если нажата OK, и false , если нажата кнопка «Отмена» или Esc с клавиатуры.
Все эти методы являются модальными: останавливают выполнение скриптов и не позволяют пользователю взаимодействовать с остальной частью страницы до тех пор, пока окно не будет закрыто.
На все указанные методы распространяются два ограничения:
- Расположение окон определяется браузером. Обычно окна находятся в центре.
- Визуальное отображение окон зависит от браузера, и мы не можем изменить их вид.
Такова цена простоты. Есть другие способы показать более приятные глазу окна с богатой функциональностью для взаимодействия с пользователем, но если «навороты» не имеют значения, то данные методы работают отлично.