Visual Studio Code vs Rider для Unity.

Комплексное сравнение реализации возможностей Rider и VSCode.

Nikita Goncharuk
Game Dev

--

Несколько лет назад я перешел с Atom на VSCode просто потому, что мне нравится его блочный и плоский интерфейс, но вскоре я обнаружил, что VSCode также обладает обширным количеством функций, но они хорошо спрятаны. Ладно, что побуждает меня рассматривать Rider именно сейчас?

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

Rider, в свою очередь, не может похвастаться отсутствием раздражающих фич, однако он известен своим IDE «интеллектом» и глубокой интеграцией с Unity. На самом деле мне все равно. Я просто хочу улучшенный и более укомплектованный текстовый редактор, такой как VSCode, но с отсутствием некоторых недостатков. В этой статье я расскажу о том, как настроить Rider и как сделать так, чтобы он был похож на VSCode, дабы я мог наслаждаться как отсутствием раздражающих моментов, так и простым и понятным интерфейсом.

Структура Rider vs VSCode

❶ Преимущества и недостатки Rider по сравнению с VSCode.

❷ Как сделать Rider более похожим на VSCode (для любителей VSCode, которые хотят избавиться от некоторых неприятных моментов VSCode).

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

P.S. В статье рассматривается версия Rider 2019.3

Бесконечная лицензия
Первое, что вы подумаете, когда посетите их вебсайт: «Я не хочу платить за подписку на обычный текстовый редактор!» Ну, текстовый редактор — это один из главных инструментов программиста, и к тому же его трудно совершенствовать, поэтому вам, возможно, придется пересмотреть его ценность.

В моем случае я бы согласился на разовый платеж. Мне понравилась модель подписки, которую предлагают разработчики Rider по причине отсутствия необходимости платить до тех пор, пока я не увижу, что они предлагают. По сути, когда вы прекращаете подписку, вы просто прекращаете получать обновления и можете продолжать использовать имеющуюся версию Rider. В Adobe, например, все иначе — по завершении подписки, вам блокируется доступ ко всем инструментам. Модель подписки Rider заставила меня задуматься о покупке. Да, эта модель больше похожа на покупку, а не на ежемесячные платежи. Больше информации здесь.

VSCodeVim vs IdeaVim

Я использую сочетания клавиш в Vim ежедневно, а у VSCodeVim есть с этим проблемы, которые не устранялись в течение нескольких лет:
gd для перехода к определению обычно работает нормально, но обратное Control + O часто возвращает неправильное место или выдает ошибку диалогового окна.
• Плагин не рассматривает рефакторинг кода как шаг отмены, и, когда вы делаете что-то, связанное с рефакторингом, а потом делаете отмену, вы отменяете этот шаг плюс весь рефакторинг.
Сниппеты кода с преобразованием переменных не работают, когда этот плагин включен.
• Макросъемка qq «слишком буквальна», а также она иногда не захватывает некоторые команды, что создает мне ряд неприятностей. Кроме того, она довольно медленно работает, если команда длинная.
Я не так хорошо знаю об IdeaVim, но, кажется, у него нет ни одной из вышеупомянутых проблем. Однако:
== или = i ( для форматирования кода в IdeaVim не работает, в то время как оно работает в VSCodeVim.
gc для комментирования в визуальном режиме не реализовано, но оно присутствует в VSCodeVim. В IdeaVim надо прибегать к Cmd + / .
Короче, в любой из эмуляций Vim всегда чего-то не хватает.

Я понимаю, что я не вправе осуждать VSCodeVim за наличие багов как минимум потому, что это проект с открытым исходным кодом, доступным на GitHub. Если я не вношу свой вклад в разработку, то я не имею права требовать от него чего-либо. Однако верно и то, что у меня может не быть времени на разработку VSCodeVim, и, в таком случае, IdeaVim — это неплохое решение, поддерживаемое коммерческой компанией, на которое я мог бы потратить деньги вместо времени. Я также полагаю, что деньги могут замотивировать вас и заставить делать продукт более изысканным.

IdeaVim быстрый!

Только за скорость уже можно платить деньги. Например, в VSCode, при выключении VSCodeVim, даже простая команда перемещения по линии работает медленнее, чем когда вы нажимаете на стрелку вниз с выключенным плагином. Это очевидно в команде, которая перескакивает через дистанцию, как Shift +].
Есть такое ощущение, что VSCodeVim проходит через «что-то», прежде чем начинать двигаться. Может быть, вы этого не почувствуете, но я любитель музыкальных игр, а также разработчик игр. Я могу заметить разницу в реагировании. При использовании реального Vim, такого как в Terminal или MacVim, ощущение отзывчивости очень схоже на реагирование в Rider, но не в VSCodeVim.

Omnisharp vs ReSharp

В целом Omnisharp работает нормально, в том числе когда дело касается переименования переменных во всем проекте, что, лично для меня, важно. Благодаря Omnisharp я могу не тратить много времени на название переменной, а просто придумывать его на ходу, а потом, если нужно будет, я могу его(название) легко изменить. Однако в некоторых ситуациях это не работает. Например, если эта переменная в лямбда-методе не завершается автоматически, в отличие от простой лямбды. Этот шаблон важен в библиотеке ECS Unity.

ReSharper еще круче…

Размер диалогового окна.

Есть одна вещь, которой VSCode поразил меня — это суперкомпактное диалоговое окно. Размер диалогового окна Rider слишком широк, а высота линии слишком велика. И, к сожалению, это нельзя изменить. Вы можете перетащить правый край, чтобы сузить его, но когда вы откроете его снова, оно расширится. Обширность Unity ECS заставляет диалоговое окно становиться громоздким почти всегда.

И я действительно ненавижу, когда приходится искать нужное поле, убирая при этом весь контекст, о котором я думаю. Это связано с тем, что высота слишком большая. Если бы я мог установить высоту окна примерно в 4–5 записей, тогда я чувствовал бы себя гораздо лучше.

Вот скрин из VSCode. Маленькое и удобное. Нет необходимости показывать все … хорошо ну в 95% случаев так точно. Окно с документацией выглядит также компактно.

А теперь сравните это с диалоговым окном Rider. Оно огромное! И, при этом, оно появляется, когда вы задержитесь на поле на 1 секунду. Я очень бесился по этому поводу и в итоге все закончилось тем, что я отключил этот функционал, потому что он был уж слишком навязчивым.

Также это превращается в настоящий ад с ForEach, который содержит миллион перестановок лямбд… Все начинает лагать и приходиться отключать данный функционал. Затем, при использовании обычного метода, когда мне нужно перейти к определению, чтобы увидеть сигнатуру, я опять его включаю…

Автозаполнение кода(code completion)

Rider медленный! VSCode работает также «просто», как и простая замена строки. Тем не менее, в Rider вы можете получить результат раньше, а нажатие клавиши может наверстать упущенное. Это, должно быть, из-за переформатирования вещей и другого интеллекта IDE. Я думаю, что могу с этим смириться, но VSCode более быстр в автозаполнении кода(code completion). (также с шаблонами / сниппетами)
Однако это компенсируется более быстрой производительностью Vim в Rider. Также перемещение курсора в Rider быстрее !

Внешний вид

Мне по душе минимальный и блочный интерфейс VSCode. Некоторым не нравится полноценные IDE, как Rider, не потому, что требуется много времени на их запуск, но из-за того, что они выглядят сложными. Вам должно быть знакомо это чувство, если вы работаете с Android Studio. У вас появляется усталость еще до начала работы.
Еще в Rider можно изменять внешний вид аж до тех пор, пока он не станет таким же пустым, как в VSCode. Самый важный момент для меня — один уровень верхней панели. Затем один уровень нижней панели. А затем отсутствие окружающих боковых панелей объектов (с такими надписями как «Проект» и так далее…это очень отвлекает»), которые вызывают ощущение, будто вы программируете в коробке. Чтобы это изменить перейдите в «Вид» -> «Внешний вид». В Rider также возможно отключение шрифтов!

До

После

Без боковой панели. Только верхняя и нижняя граница.

Тема редактора

Тема Rainglow также доступна в Rider. Мне нравится менять темы в зависимости от настроения, а не пытаться «освоить» имеющуюся тему. Но есть одна вещь, которая мне нравится в VSCode — тема также распространяется на боковую панель, а не только на область редактора. Например, тема Rider dark, которая хорошо смотрелась на скриншоте ранее, теперь выглядит странно, потому что теперь есть 2 вида разных оттенков темноты. Но, в любом случае, я прячу боковую панель, когда не использую ее.

Правила

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

Когда я использую ToComponentDataArray <T>, на мой взгляд «очевидно», что тип будет NativeArray <T>, но, конечно, предписанное правило может этого и не видеть. Шаблон out var часто конфликтует с некоторыми правилами. И, наконец, иногда я произвольно использую или не использую var в зависимости от того, насколько загружено окружение. (комбинированный JobHandle нуждается в этом для акцентирования, но дескриптор возвращается из var, поэтому я не хочу набирать JobHandle и т.д.) В итоге я отключил многие из правил. По правде говоря, в первые несколько дней программирования на VSCode мне всегда приходилось что-то выключать, например code lens. Чтобы полностью настроить Rider, мне понадобилось 1–2 часа.

Сниппеты против live шаблонов (с англ. Live template)

Live шаблон Rider выигрывает потому, что он работает с IdeaVim, в то время, как сниппеты VSCode не могут выполнять преобразование параметров в VSCodeVim. Вот пример файла конфигурации фрагмента из VSCode. Каждый $ представляет, куда будет перемещаться курсор на каждой вкладке. Вы можете выполнить некоторые преобразования с помощью регулярных выражений.

Детали: https://code.visualstudio.com/docs/editor/userdefinedsnippets

В Rider мне также нравится, что я могу назвать свою переменную как угодно, например $ type $(таким образом, имя типа внутри <>также может стать именем переменной). Пока я еще не читал, как выполнить преобразование переменной.

Использование пакетов

VSCode не понимает Unity, и когда вы пытаетесь использовать какой-то пакет, он запрашивает файл проекта C# и обнаруживает, что это dll, и поэтому он копается в dll (сгенерированный из asmdef) вместо фактического исходного кода пакета, который также доступен где-то еще.

Rider тут побеждает, потому что знает о пакетах Unity UPM. Например, если вы желаете использовать EntityCommandBuffer.RemoveComponent:

В Rider вы можете попасть в пакет. Это очень важно в Unity, так как в таком случае все исходные коды доступны. Вам больше не нужно задумываться о том, что происходит внутри, когда вы можете просто войти в пакет и быстро выйти с помощью Ctrl + O. (команда Vim) Можно также отключить все всплывающие окна документации . Я думаю, что это полезно, поскольку всплывающие окна отвлекают.(Хотя первая версия VSCode dll полезна для быстрого просмотра соседних перегрузок, например, с перегрузкой EntityQuery. Хотя в Rider вы также можете использовать outliner .)

Peeking

Вы можете использовать Red hot в Rider 2019.3 для просмотра определений:

В VSCode этот функционал уже давно доступен. Лично мне больше нравится VSCode, потому что он хорошо работает со своим «безграничным дизайном», заполняя его горизонтально.

Поиск

UX очень хорош при поиске. Теперь справа есть блок для просмотра.

Мне не нравится древовидная форма, которую предоставляет Rider. Это неуклюже, и я не могу сразу увидеть контекст кода, как в VSCode.

Со временем VSCode даже улучшится, добавив более полную версию использования поиска, которая все же лучше, чем древоподобная структура от Rider — просто файл и строки, где это используется.

К счастью, Rider можно настроить. Сначала нажмите на винтик и выберите опцию Left Top.

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

Если вам нравится стиль VSCode, перейдите в нижний левый угол и кликните по «Предварительный просмотр» (с англ. Preview Usages).

Поведение файлового браузера

Нажмите эту не очень описательную кнопку «Всегда выбирать открытый файл» (с англ. “Always Select Opened File”) со стрелкой вниз, чтобы файловый браузер работал как в VSCode. Когда вы используете Search Anything, браузер фокусируется на этом файле. Я предпочитаю это больше, чем навигационную панель вверху (которую к тому же я отключил), потому что так я могу видеть контекст, и также могу оставить верхнюю панель только для вкладок, как в VSCode.

Та кнопка слева с противоположной стрелкой, сделает так, чтобы одним щелчком мыши можно было открыть файл, как в VSCode.

Рефакторинг: переименования

В VSCode это обманчиво просто, но и многофункционально. При нажатии клавиши F2 появляется небольшая ячейка, в которой, если вы вводите что-то еще, обновляется весь проект и не возникает ошибок. (Если имя не создает конфликтов.)

Rider, в свою очередь, медленнее, так как более тщательно обновляет весь проект, а также комментарии. А еще он иногда выкидывает диалоговые окна без надобности. (скрин ниже)

Иногда тот же shortcut (сочетание клавиш) выдает совершенно другое окно. Не знаю почему оно так работает, но мне кажется, что это связано с локальной переменной?

Unity-осведомленный браузер проекта (с англ. Unity aware project browser)

Rider выглядит так, как панель проектов Unity и мне это нравится. Синее поле указывает на папку с asmdef внутри. Он также работает и с вложенным asmdef.

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

Раздражающие сохранения

Похоже, что Rider любит сохранять ваши файлы автоматически или делать странные вещи для того, чтобы вы чувствовали себя неуверенно по поводу того, был ли файл сохранен или нет. Это очень ужасно с Unity, где время итерации является очень весомой проблемой. Например, когда вы вернетесь в Unity, все файлы будут автоматически сохранены. Вы не можете оставить файл в “dirty state”, перейти Unity и вернуться. Вам придется сталкиваться с задержкой на 5–10 секунд каждый раз. К счастью, вы можете отключить такое поведение:

Вот странные фичи, которые вы не можете отключить:
– при закрытии “dirty state” файла Rider ничего не спросит, а просто закроет и автоматически сохранит его. Возможно, это не так уж и плохо, но иногда я делаю глупые вещи и я хотел бы удалять их путем закрытия, но теперь мне приходится многократно нажимать кнопку «Отмена». Да, если вы очень уверенно пользуетесь системой контроля версий, то вы можете с легкостью откатывать коммиты. Но, лично для меня, это тяжело и мне точно не нравится отсутствие всплывающего окна сохранения.

– вы не можете сохранять файлы по отдельности. Есть только кнопка «сохранить все». Это тоже странно, но в VSCode я всегда нажимаю сохранить все. Меня это не особо напрягает.

Авторекомпиляция после сохранения

Вы можете нажать «Сохранить все» в Rider, затем вы увидите, что Unity реагирует и перекомпилируется, как если бы вы выполнили Alt + Tab x2, который вы использовали в VSCode, чтобы заставить Unity сделать рекомпиляцию.
Я привыкаю к ​​этому. Обычно это выглядит так: я закончил работу над каким-то фрагментом кода и сохраняю все вручную. Потом я опять пересматриваю код и думаю: «Хорошо, дважды проверил. Все работает!». Но к тому времени, как я закончил проверку, Unity уже скомпилировал мой новый код, так как компиляция запускается, как только я нажимаю сохранить.
Если в будущем Unity удастся установить время итерации, которое будет меньше 500 мс, это станет еще более удобным.

Вы можете ограничить количество вкладок

Открывая много файлов, вы получите множество вкладок. Мне нравится опция, которая автоматически закрывает вкладки за меня. Тем не менее, это немного раздражает, когда закрывается несохраненная вкладка и, в то врем, как она сохраняется, запускается перекомпиляция Unity, из-за чего мой компьютер зависает.

Операции с файлами

VSCode имеет функционал массового переименования или отдельного класса для нового файла, где он правильно работает с Omnisharp. Однако есть ограничения. Вы не можете просто создать новый файл C# или переименовать его на панели проекта в VSCode. Чтобы он работал правильно, вам нужно нажать Alt + Tab х2 в Unity (сделать перекомпиляцию), и таким образом Omnisharp сделает своего рода перезагрузку и будет знать, что делать.

Как и ожидалось от похожего на Rider IDE, вы можете создавать новые файлы и перемещать их сколько угодно, не переключаясь при этом на Unity. Это довольно мощно, поскольку в Unity эта операция вызывает вращающееся колесо компиляции(c англ. spinning compile wheel of doom), за которым следует одно долгое зависание. Это длится примерно по полминуты каждый раз.

Рекурсивный индикатор ошибок

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

Обычно мне не хочется читать сообщения об ошибках, однако это единственный способ узнать об их происхождении.
Приходится постоянно нажимать Alt + Tab x2, чтобы сделать перекомпиляцию и узнать о появлении ошибок. Но в Rider, как показано на рисунке, появляется красное подчёркивание, которое рекурсивно показывает папки, в которых присутствует ошибка. При этом нет надобности обращаться к журналу ошибок. Чтение требует времени, а вы просто хотите узнать, где возникла, и когда вы видите код, вы, скорее всего, уже знаете, что нужно исправить, даже без прочтения сообщения об ошибке.

Это также относится к таким вещам, как Search Anything.

Find Usage: Права записи

Одна чрезвычайно ценная фича Rider, которой нет в VSCode, — это категория Find Usages, основанная на чтении или записи. Обычно главная трудность с тестами состоит в том, чтобы найти места, где они были написаны.Мне обычно приходится искать знак = в VSCode вручную или включать его в поиск по всему проекту.

Unit-тесты

Вы можете запустить Unit-тесты из Rider. В VSCode вы можете запустить только чистый тест NUnit.
Однако, это происходит так медленно, что у меня хватает времени на то, чтобы случайно сделать скриншот состояния «Ожидание» некоторых Unit-тестов, которые должны выполняться молниеносно.

Слева от метода теста есть удобная кнопка, чтобы вы могли запустить этот тест, так как в VSCode, но, при этом, он будет работать с Unity. Тем не менее, это МЕДЛЕННО, поэтому я предпочту Alt + Tab, чтобы запустить его в Unity.

Точка трассировки (с англ. Tracepoint — точка, которая регистрирует ошибки вместо остановки программы) не связана с консолью Unity. Также здесь есть сомнительное автозаполнение,налпись eight, которую вы можете увидеть на скриншоте, является действительным логом, потому что я переопределил ToString. Однако автозаполнение предлагает вещи, никак не связанные с текущей областью.

Вывод появляется на панели «Отладочный вывод». Но панель часто захламлена другими сообщениями. В идеале я хочу видеть лог в Unity, а не здесь.

Генерация равноправных членов

Реализация IEquatable очень нужна в Unity DOTS. Это очень полезная функция в ReSharper, которая недоступна в Omnisharp.

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

Генерация шаблона утилизации

Это полезно в Unity DOTS, где вы управляете памятью. Он сканирует все ваши IDisposable и DOTS следует за ними.

Генерация метки переключателей

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

Локальный / внутренний UPM

Я уже подчеркивал, насколько важно делать UPM своего собственного проекта, даже если вы не намереваетесь сделать его open source. В VSCode ваш проект представляет собой папку. Когда вы добавляете код в свой собственный пакет UPM, Omnisharp может это сделать только потому, что запрашивает .csproj . И вы также можете редактировать файл, если UPM находится на локальном компьютере.

В Rider вы можете сделать то же самое, за исключением просмотра дерева проекта этого пакета. Это потому что Rider знает Unity! Папка со стрелкой и коробкой является локальным UPM.

Я думаю, что это круто, потому что в VSCode я был ограничен в использовании Go To Definition. Для того, чтобы перейти к файлу пакета и изменить его, мне нельзя было свободно просматривать любые другие близлежащие файлы в пакете и я должен был найти путь к другим файлам с помощью Go To Definition. Он также не был выделен на панели проекта. Rider сделал так, чтобы все пакеты (не только для чтения) воспринимались как часть вашего проекта, как на панели проектов Unity.

UPM для вашей игры

Также вы можете перетаскивать любой файл в папку UPM во время редактирования кода. Наверное, вы знаете, как трудно перемещать файлы в Unity. Каждое, даже маленькое, перемещение вызывает кучу сложностей.

Редактирование asmdef даже отображает диалоговое окно, не позволяющее вам что-либо делать в это время. (хотя если бы вы могли, редактор завис бы). Авторефакторинг работает. Переименование объектов в пакете UPM из вашего основного проекта работает и обновляет также весь ваш основной проект. В целом, это ключевая особенность модульного и тестируемого кода игры. (у вас может быть другая версия Rider, которая открывает UPM в качестве основного пакета. Хотя, скорее всего, вы можете так же легко редактировать свой пакет из основной версии пакета)

Breakpoints

Мне очень нравится эта фича в Rider. Когда случается брейкпоинт(с англ. Breakpoint) , в каждой строке выдаются комментарии, даже если вы не наводите мышку и не проверяете список стека. Оно хорошо будет работать в коде, который вы «разбиваете» на несколько строк. Это очень помогает понять окружение.

Автозаполнение документации

Несмотря на то, что в VSCode можно установить плагин для ///, чтобы получить заключение, а также там есть функция автозаполнения внутри “” части see cref и можно переименовывать всю документацию, в VSCode невозможно автоматически заполнять see cref , в то время, как это возможно в Rider.

Комментарий к новой строке

Если вы нажмете enter в середине любого комментария, к новой строке будут добавлены //, которые сделают ее также комментарием. Понятно, что когда я так делаю, я не собираюсь писать код в следующей строке. Я даже и не знал, что мне будет полезен подобный функционал ранее. Это не влияет на нажатие enter в конце строки или использование клавиши o в эмуляции Vim. И если следующая строка имеет пробелы после //, она будет отформатирована подобным образом.

Почти идеальный импорт отсутствующих ссылок

Эта функция очень важна в VSCode. Лично у меня частенько возникают проблемы с импортом в область видимости. К счастью, это можно решить.

В VSCode, если у вас нет ссылки в вашем asmdef, Omnisharp не может разрешить ее для вас. VSCode не может точно знать, что этот конкретный класс находится в сборке Entities.Hybrid, потому что вы еще не подвязали asmdef. В итоге вы подвязываете это, потому что знаете, что это поможет.

В Rider все немного проще. Rider понимает Unity на таком уровне, который знает расположение классов в пакетах, связанных с манифестом проекта(с англ. project manifest), но, все же, не с данным конкретным asmdef. Но даже несмотря на то, что завершение работает и using было добавлено в заголовок, его все равно нельзя использовать, потому что он не может перейти в ваш файл asmdef и добавить недостающую перекрестную ссылку на asmdef.

ReSharper более стабилен, чем Omnisharp

Наверное, вам знакомо то чувство, когда вы делаете что-то слишком «возмутительное» в VSCode и вам начинает казаться, что Omnisharp терпит поражение. Когда вы проверяете журнал Omnisharp во всплывающей консоли, вы конечно увидите там некоторые ошибки, но Omnisharp самостоятельно не восстановится.

Это можно решить с помощью «Restart Omnisharp», но вам придется подождать некоторое время. VSCode, в отличие от Omnisharp, запускается быстро. Также я иногда замечаю, что Rider имеет подобные проблемы. Разница лишь в том, что у Rider просто падает производительность, но его не надо перезапускать.

Я подозреваю, что это происходит, когда Unity пытается перекомпилировать слишком много ссылок (непостепенно) и Rider / ReSharper обрабатывает это более изящно.

Один пробел до предыдущей строки

Когда я хочу отформатировать код так, чтобы он возвращался к концу предыдущей строки, я думаю, что нет подходящей команды Vim, чтобы сделать это достаточно быстро, кроме cut & paste. В Rider это можно сделать с помощью простого нажатия backspace в начале строки.

Спасибо за ваше внимание!

--

--