Код
#статьи

Как писать код быстро и эффективно: Emacs, Vim и другие редакторы для хаскелиста

Haskell-разработчик Дмитрий Коваников рассказывает, зачем ставить плагины Emacs и Vim в свою IDE и как они помогают эффективно программировать.

Иллюстрация: Chanikarn Thongsupa / Rawpixel / Annie для Skillbox Media

Дмитрий Коваников

об эксперте

Haskell-разработчик в лондонском банке. Любит функциональное программирование и выступает на конференциях. Несколько лет преподавал Haskell в ИТМО, вместе с подругой основал организацию Kowainik, где поддерживает опенсорсные проекты, менторит новичков, ведёт блог и курс по Haskell.


Ссылки


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

До банка я работал в медицинской компании — разрабатывал приложение, которое помогает людям с диабетом второго типа вести более здоровый образ жизни. Занимался архитектурой, бэкендом, интеграциями с различными API, внедрением AI-моделей. До этого работал в блокчейне.

Чем хорош Vim и для каких задач он подходит

С Vim я познакомился в университете на курсе по операционным системам. У нас был интересный преподаватель, который говорил: «Код на C вы обязательно должны писать в Vim». В нём же он просил делать домашние задания, поэтому кроме языка программирования нам пришлось осваивать ещё и новый текстовый редактор.

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

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

Ещё преимущество Vim — всегда можно зайти на сервер по SSH и отредактировать любые файлы. Через ту же IntelliJ IDEA сделать это не получится, если среда не установлена на сервере.

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

В Vim есть свой скриптовый язык — VimL (или Vim script). На нём можно написать программу и прямо в блокноте проводить какие-то вычисления, настраивать IDE и создавать конфигурации. В других IDE разные функции включаются галочками в настройках, а Vim — редактор, который можно полностью запрограммировать под себя.

Вот пример того, как я использую Vim из терминала, если мне нужно отредактировать файл. Я могу открыть его сразу в терминале, перейти в нужное место и что-то исправить. Потом я файл сохраняю, закрываю и компилирую.

Так я использую Vim из терминала, чтобы отредактировать файл

Некоторые фичи Vim я покажу из VS Code, потому что там отображение мультикурсоров из коробки работает лучше. Я могу зайти в режим замены и что-то исправить, не меняя расположение других частей кода. Допустим, я хочу один импорт сделать с qualified, а другой — без. Это всё делается с помощью нескольких горячих клавиш.

В режиме замены я могу быстро править код

Если в типе данных ко всем полям нужно добавить префикс user, из-за особенностей Haskell я должен присвоить полям типов данных уникальные названия — это нужно, чтобы исключить конфликт имён.

Я жму Ctrl + V и вхожу в режим блочного выделения, выделяю начало, нажимаю ~ (тильду), меняю регистр первых букв и добавляю префикс user — просто вытягиваю его курсором. Чтобы после блочного выделения вернуться в режим редактирования, я нажал Shift + i.

Из коробки Vim позволяет редактировать несколько строк сразу

Можно делать и обычные вещи — например, быстро удалить функцию. Я жму на клавиатуре комбинацию dd, и это удаляет текущую строку. Другая стандартная возможность — объединить несколько строк в одну при помощи Shift + j (или просто J).

Если дважды нажать d на клавиатуре, Vim удаляет текущую строку

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

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

Если функцию нужно переименовать, в Vim есть полезная кнопка s, которая удаляет один символ и включает режим редактирования. Например, заменим strictSum на veryStrictSum.

Три простые функции Vim — удаление текста внутри скобок, быстрое редактирование и переименование функции

Бывает, что комментарий в коде получается слишком длинным, и его нужно разбить на абзацы. Для этого в Vim есть стандартная комбинация клавиш g + q + l, с которой текст автоматически разносится по строкам. Да, приходится нажимать целых три кнопки, но я запомнил сочетание и пользуюсь им довольно часто.

Разбиваем длинный комментарий на несколько строк нажатием одной горячей клавиши

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

Вот в каком порядке это происходит:

1) Ctrl + V — вхожу в режим блочного выделения;

2) j — двигаюсь вниз (вместо стрелочек стандартная навигация Vim работает через h, j, k и l);

3) y — копирую выделенное;

4) p — вставляю последнее скопированное значение;

5) Ctrl + V — выделяю начало всех строк;

6) Shift + i (или просто i) — вхожу в режим вставки;

7) набираю нужный текст;

8) r[ — перехожу к первой запятой и заменяю её на открывающую квадратную скобку (r заменяет символ под курсором);

9) перемещаю курсор в конец блока и ставлю закрывающую квадратную скобку;

10) Ctrl + V — снова вхожу в режим блочного выделения;

11) Shift + i — вхожу в режим вставки;

12) добавляю открывающую кавычку;

13) Ctrl + V — включаю режим блочного выделения, выделяю все слова;

14) $ — выделяю всё от курсора до конца строки;

15) Shift + i — вхожу в режим вставки;

16) добавляю закрывающую кавычку.

Звучит сложно, но я часто применяю эти сочетания, поэтому пользуюсь ими на автомате.

Быстро превращаем несколько слов в список

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

Почему Emacs — незаменимый редактор кода

На Emacs я перешёл ещё на первой работе, где мне пришлось писать на Haskell. Всё из-за плагина Org Mode — он помогал следить, сколько времени уходит на каждую задачу.

Мне больше не приходилось открывать задачу, засекать и считать потраченное время. Я делал это в плагине с помощью нескольких горячих клавиш, а в конце месяца автоматически генерировал отчёт. Это была главная причина, почему я попробовал Emacs.

Мне казалось странным открывать Emacs только ради трекинга времени, а программировать в другой среде. Поэтому я немного заморочился, настроил плагин для Haskell и с тех пор в основном пишу код в нём.

Правда, в Emacs мне не нравится то, что нельзя просто писать свои проекты — приходится ещё и постоянно дорабатывать IDE под себя. Этот подход отличается от подхода в обычных IDE — у него есть и плюсы, и минусы.

А вот VS Code и IntelliJ IDEA мне нравятся, потому что там всё работает из коробки. К ним быстро привыкаешь, особенно если это твоя первая среда разработки.

В Emacs нужно заморочиться, но зато ты полностью настроишь среду под себя, добавишь кастомные функции и даже наладишь процессы. Хотя я не люблю сильно дорабатывать инструмент — лучше, чтобы он сразу работал как мне надо.

После Emacs я долго пользовался Spacemacs. Это целая отдельная экосистема поверх Emacs — в ней отличаются настройки, проще устанавливать плагины, а ещё есть другие интересные вещи. Spacemacs хорошо работает из коробки: ты добавляешь одну строчку на новом языке, например YAML или Rust, и у тебя сразу появляется его поддержка. Это очень удобно. Визуально Spacemacs тоже выглядит симпатичнее.

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

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

Emacs (и Spacemacs) использует Emacs Lisp (или просто elisp) для описания конфигурации IDE. Это диалект Lisp. Язык VimL мне показался не таким дружелюбным.

А вот горячие клавиши в Emacs не такие удобные, как в Vim. Мизинец будет болеть — постоянно приходится жать Ctrl. Поэтому я пользуюсь в нём сочетаниями из Vim.

И да, в Emacs я всё равно использую Vim через плагин Evil — мне нравится его концепция редактирования, горячие клавиши, режим просмотра и вставки. Такому же правилу я следую в работе с любой IDE — всегда ставлю плагин Vim, чтобы добавить привычные хоткеи.

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

Правда, мне не нравится язык Lisp, на котором пишутся плагины. Особенно раздражает динамическая типизация — допустим, я открываю какой-то плагин и разбираюсь в нём. Вижу функцию или горячую клавишу, но не могу понять, как они работают: нельзя посмотреть на тип данных, чтобы узнать, могу я, например, передать в функцию булевый флажок или строку. Передать можно хоть число, хоть строку — поэтому иногда код не работает.

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

В Emacs мне нравится одна функция — она не очень новая, но я видел её не в каждой IDE. Когда я закрываю программу, а потом запускаю снова, у меня открываются те же файлы, с которыми я работал. Если я не занимался проектом неделю, мне достаточно просто открыть Emacs и продолжить с того места, на котором я остановился в последний раз.

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

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

Я привык, что в Vim у тебя есть режим просмотра и редактирования. Ты что-то пишешь в коде в режиме вставки, а потом нажимаешь Esc, чтобы перейти в нормальный режим. В Emacs я довольно быстро сделал так, чтобы текущий редактируемый файл автоматически сохранялся, когда я выхожу из режима редактирования, — то есть мне больше не нужно сохранять файлы по расписанию.

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

Каких-то других специальных настроек Emacs у меня нет — я не какой-нибудь евангелист этого редактора и заморачиваюсь меньше других. Например, один программист сделал для Emacs плагин для Telegram — теперь в мессенджере можно сидеть прямо из среды разработки. Поддерживаются даже видеосообщения: ты можешь в одном окне писать код, а в другом общаться в чатах.

Так выглядит плагин для Telegram под Emacs. Скриншот: GitHub

Допустим, я хочу работать с проектами в Emacs. Я захожу в поиск файлов, внизу появляется строка, я открываю то, что мне надо, — в данном случае файл с настройками. Если есть потребность что-то отредактировать, у меня по-прежнему работают все горячие клавиши из Vim.

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

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

Открываю нужные файлы в Emacs и редактирую их горячими клавишами из Vim

У меня есть и базовые настройки — например, подсветка изменений. Рядом с удалёнными строками появляются красные кубики, рядом с модифицированными — оранжевые. Внизу окна написано, в какой строке и колонке я работаю, какой файл открыт.

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

Так Emacs подсвечивает синтаксис и изменения в коде

Кому стоит изучить Vim и Emacs

Когда осваиваешь другую IDE, нельзя сразу понять, нравится она тебе или нет. Это не Notion, которым можно попользоваться день и сказать: «Окей, в нём удобно вести документацию». После первого дня в новой IDE все говорят: «Нет, мне не нравится». Это потому что сперва нужно выстроить процесс работы и ко всему привыкнуть.

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

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

Сначала будет больно и тяжело, но в самом Vim есть встроенный двадцатиминутный онбординг. Другие руководства можно найти в Сети. С Emacs всё сложнее, потому что это почти что полноценная IDE. Но его стоит освоить, если вы много программируете на разных языках, особенно не мейнстримных, для которых нет продвинутых IDE.

Если для вашего языка нет продвинутой IDE, у него точно найдётся плагин для Emacs. Всё потому, что плагин для этого редактора сделать гораздо проще, чем для той же IntelliJ IDEA. Хорошо, если вы можете сами сделать для неё качественный плагин. Но для Emacs на это уйдёт меньше сил.

Ещё одна причина изучить Emacs — если вы хотите освоить языки с зависимыми типами, например Idris или Agda. В них есть парадигма программирования, которая называется Type-driven Development. Она состоит из case splitting и Hole-driven Development — по сути, вы просто пишете тип функции, нажимаете горячую клавишу, и реализация функции генерируется автоматически.

Пример парадигмы Type-Driven Development в Emacs с седьмой минуты показывает создатель языка Idris Эдвин Брэйди

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

Sublime Text, IntelliJ IDEA, VS Code и Atom

Я перепробовал много IDE и редакторов кода. Начинал с Sublime Text — продвинутого блокнота, в котором очень плохо работал плагин Haskell. Там были базовые возможности, подсветка синтаксиса и автодополнение кода, но ничего больше. Плюс редактор часто вылетал. Чтобы добавить в Sublime новую функциональность, приходилось сильно заморачиваться. Может быть, сейчас у этого редактора дела идут получше, но тогда он мне не понравился.

Потом я перешёл на Atom. Сейчас о нём ничего не слышно, но в своё время это было популярное приложение. Хотя у него тоже были проблемы с поддержкой Haskell.

Ещё я пользовался IntelliJ IDEA. Это хорошая IDE, и если вас всё в ней устраивает, то нет смысла устанавливать что-то ещё. Минус в том, что в intelliJ IDEA есть несколько плагинов для программирования на Haskell, но даже самый живой из них поддерживается всего лишь одним разработчиком. Пару лет назад этот плагин был очень медленным, но сейчас стал получше. Правда, я давно им не пользуюсь.

На работе я программирую в VS Code. Последние полтора года для него очень активно разрабатывают плагин под Haskell — даже объединили волонтёров в полноценное комьюнити, а некоторые сотрудники Meta работают над ним фултайм. Благодаря этому плагину VS Code даёт хороший пользовательский опыт хаскелистам.

Поддержка многих языков в VS Code достигается за счёт Language Server Protocol (LSP): благодаря ему любой разработчик может реализовать Language Server для своего языка, сделать плагин и добавить его в IDE. На GitHub есть готовый сервер для Haskell.

Недавно у JetBrains вышел легковесный редактор Fleet. Там пока нет поддержки Haskell, но есть LSP — добавить язык будет просто. Нужно только сделать плагин, который подключит к IDE языковой сервер Haskell, где реализована вся логика работы с кодом.

Полезные ресурсы для тех, кто учит Emacs и Vim

Вот какие материалы я советую:

  1. Официальное введение в Emacs — там рассказывают про модель, буферы и основные сочетания клавиш. Чтобы разобраться, поначалу мне хватило только его.
  2. Короткое видео про настройку Emacs с нуля — Haskell-разработчик рассказывает, как вникнуть в эту экосистему и настроить среду.
  3. Пользовательская документация — полное руководство по Emacs.
  4. Мой репозиторий с конфигами — там лежат мои базовые настройки для Vim и конфигурация Emacs со всеми плагинами и цветовыми схемами.
Проверьте свой английский. Бесплатно ➞
Нескучные задания: small talk, поиск выдуманных слов — и не только. Подробный фидбэк от преподавателя + персональный план по повышению уровня.
Пройти тест
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована