Введение
Недавно я редактировал сообщение в блоге, в котором брал интервью у жителей Метосинии относительно их любимых редакторов Clojure. Было довольно интересно увидеть, что используется разнообразная группа редакторов. В этом сообщении в блоге я сказал себе, что я настроил свою установку Emacs/Cider так, чтобы она была максимально близка к IDEA/Cursive в отношении внешнего вида. Кто-то в Reddit спросил об этом, и мне пришла в голову мысль, что я могу посмотреть на свои последние конфигурации, связанные с Cursive и Dygma, и проверить, есть ли необходимость в тонкой настройке моей настройки Emacs, чтобы Cursive и Emacs были похожи друг на друга в отношении их внешнего вида. -почувствуйте, насколько это возможно — и напишите новый пост в блоге об этом опыте. Есть несколько предыдущих сообщений в блоге, в которых я немного коснулся этой темы:
Версии и репозиторий
Я экспериментировал с редакторами Cursive и Emacs, используя свое последнее упражнение по мировой статистике — вы можете найти, например. deps.edn (например, профиль emacs
) и Justfile (например, команды backend-debug-reveal-kari-port
для запуска реплики для Cursive и backend-debug-kari-emacs
для запуска реплики для Emacs). Если вам интересно прочитать о самом упражнении по мировой статистике, у меня есть еще одна запись в блоге об этом: Упражнение по мировой статистике — я только что обновил вышеупомянутые файлы deps.edn и Justfile для этой новой записи в блоге.
Версии, использованные в этом сообщении блога:
- IntelliJ IDEA & Cursive: IntelliJ IDEA 2020.3 Ultimate, Cursive 1.10.0–2020.3 и nrepl 0.8.2.
- Emacs и Cider: Emacs 26.3, emacs-cider 1.0.0 и cider-nrepl 0.25.5.
Моя рабочая станция — Ubuntu 20.
Emacs и сидр
Emacs — старый редактор — первые версии были созданы в 1970-х, разработка GNU Emacs началась в 1980-х. Я начал использовать Emacs еще во время учебы в Хельсинкском технологическом университете в 1990-х — и с тех пор использую Emacs. Мне очень нравится Emacs, хотя я никоим образом не являюсь гуру Emacs или eLisp. Emacs реализован на Лиспе (Emacs Lisp), что делает его удобным редактором для написания кода на Лиспе, например. Кложур. Сказав это, я должен подчеркнуть, что Emacs — это редактор общего назначения, не предназначенный специально для программирования на Лиспе — вы можете найти так называемый основной режим Emacs практически для любого языка программирования. Emacs лучше всего можно описать так: это расширяемый, настраиваемый редактор — вы можете настроить его по своему усмотрению, используя язык eLisp. А поскольку eLisp — это Lisp, вы можете добавлять новые команды редактирования во время редактирования. Существует также множество пакетов Emacs, которые кто-то написал для вас с использованием языка eLisp — лучший способ расширить Emacs — это сначала поискать пакет melpa, и если вы не можете найти тот, который соответствует вашим потребностям, только тогда напишите один для себя.
Cider — это пакет Emacs, который расширяет возможности Emacs до полноценной среды разработки Clojure/сценариев. Используя Cider, вы можете делать те же волшебные действия REPL, что и с любым REPL Clojure. На самом деле хитрость заключается в том, что вы запускаете сервер nREPL, а затем подключаете Emacs через Cider к этому серверу — Cider — это клиент nREPL, который взаимодействует с сервером nREPL. Таким образом, вы можете отправить любую форму внутри вашего кода Clojure для оценки в nREPL, и он отправит результаты обратно в Emacs.
IntelliJ и курсив
IntelliJ IDEA только что исполнилось 20 лет, но я не так долго пользуюсь IDEA. Я программирую на Java и Python около 20 лет, но начал программировать на Java/Python с Emacs (с основными режимами Java и Python), а через несколько лет после этого начал использовать Eclipse для Java (и продолжил использовать Emacs для Питон). Я использовал Eclipse довольно много лет, но в какой-то момент я начал использовать IntelliJ IDEA для программирования как на Java, так и на Python — довольно приятно использовать один и тот же редактор с одинаковым внешним видом для обоих языков программирования, и я остановился на С тех пор IntelliJ IDEA, хотя я все еще использую Emacs для различных других задач программирования/редактирования. (В последнее время я также начал использовать Visual Studio Code, но это уже другая история.)
IntelliJ IDEA — действительно хорошая IDE, мне она очень нравится. Он не такой раздутый, как Eclipse, и расположение инструментов IDE мне больше нравится в IDEA, чем в Eclipse (которым мне всегда было сложно пользоваться). Cursive — это плагин для IDEA, предоставляющий действительно приятную среду программирования на Clojure. Итак, теперь я могу использовать IDEA для всех моих любимых языков программирования.
На данный момент я должен признать, что Clojure — мой любимый язык программирования, без вопросов. Раньше я использовал Python в качестве языка быстрого написания сценариев, но с Бабашкой вы можете писать сценарии оболочки также с помощью Clojure без длительного времени запуска JVM. Java — это немного вчерашний день — я настоятельно рекомендую использовать Clojure в JVM, а если Clojure не вариант, то Kotlin, который является своего рода Java, сделанным правильно. Кстати, вы можете больше узнать о моем опыте работы с различными языками программирования в моем блоге Пять языков — пять историй и Kotlin — гораздо больше, чем просто лучшая Java — мне действительно нужно обновить пост в блоге Пять историй на Сообщение в блоге «Шесть историй.
Что такое Clojure REPL?
REPL — секретное оружие мира Лиспа — способ взаимодействия с разрабатываемой программой Лиспа. Другие программисты могут сказать, что в их любимом языке тоже есть repl — это ничто по сравнению с настоящим REPL на Lisp — вам действительно нужен гомоиконный язык, чтобы реализовать действительно мощный REPL, а Lisp (и Clojure) — это гомоиконичный язык.
REPL — это аббревиатура от цикл чтения-оценки-печати. При программировании на Lisp (и Clojure) опытный программист всегда держит REPL открытым и оценивает различные формы (полное пространство имен, форму верхнего уровня или некоторое S-выражение внутри формы верхнего уровня) в исходном коде. Есть хорошие введения для Clojure REPL — я настоятельно рекомендую прочитать их и узнать, как использовать REPL.
Хорошо! Думаю, для вступления достаточно. Приступим к делу.
Запуск REPL для редакторов
Для новичков в Clojure поясню, что есть несколько способов использования REPL — либо запустить repl как часть вашей IDE, либо запустить внешний REPL и подключиться к нему из вашего редактора — я использую второй способ.
У меня есть в моем deps.edn версии Clojure, nrepl и cider-nrepl, определенные в выделенных псевдонимах:
{:paths ["resources"]
:deps {org.clojure/clojure {:mvn/version "1.10.1"}}
:aliases {
...
:backend {:extra-paths ["src/clj"]
:extra-deps {metosin/ring-http-response {:mvn/version "0.9.1"}
...
nrepl/nrepl {:mvn/version "0.8.2"}
...
;; Emacs Cider specific.
:emacs {:extra-deps {cider/cider-nrepl {:mvn/version "0.25.5"}}}}
Псевдоним backend
был фактическим псевдонимом для серверной разработки — я создал псевдоним emacs
для этого поста в блоге.
Justfile предоставляет команды для запуска реплик с псевдонимами: backend-debug-reveal-kari-port
для запуска реплики для Cursive и backend-debug-kari-emacs
для запуска реплики для Emacs:
# For Cursive @backend-debug-reveal-kari-port: # clj -J-Dvlaaad.reveal.prefs="{:theme :light}" -M:dev:test:common:backend:reveal:kari -m nrepl.cmdline --middleware '[com.gfredericks.debug-repl/wrap-debug-repl vlaaad.reveal.nrepl/middleware]' -p 44444 -i -C clj -M:dev:test:common:backend:reveal:kari -m nrepl.cmdline --middleware '[com.gfredericks.debug-repl/wrap-debug-repl vlaaad.reveal.nrepl/middleware]' -p 44444 -i -C
# Start backend repl with my toolbox for Emacs. @backend-debug-kari-emacs: PROFILE=emacs clj -M:dev:test:common:backend:reveal:kari:emacs -m nrepl.cmdline --middleware '[com.gfredericks.debug-repl/wrap-debug-repl vlaaad.reveal.nrepl/middleware cider.nrepl/cider-middleware]' -p 55555 -i -C
Я создал оба рецепта Просто для этого сообщения в блоге — идея состоит в том, что я добавил явный порт для обоих ответов, чтобы быть уверенным, что Cursive и Emacs подключаются к соответствующим ответам (порт Cursive 44444 и порт Emacs 55555). . У первой команды есть другая версия со светлой темой, которую я пробовал, но она мне не очень понравилась. В обоих REPL я запускаю nrepl (-m nrepl.cmdline
), а затем добавляю промежуточное ПО ('[com.gfredericks.debug-repl/wrap-debug-repl vlaaad.reveal.nrepl/middleware]'
и cider.nrepl/cider-middleware
для Emacs). Первый — помощник отладки, а второй — инструмент вывода REPL, подробнее об этом позже.
Подключение к REPL из редакторов
В IDEA / Cursive создайте конфигурацию запуска/отладки, как показано на рисунке ниже:
В Emacs/Cider введите команду: cider-connect
и укажите локальный хост и порт, которые вы использовали при запуске реплики ранее (55555
).
Вывод REPL в редакторах
На рисунке ниже показано окно вывода Cursive REPL. Здесь важно отметить, что кложурцы не пишут на REPL. Вы пишете в редакторе и отправляете формы для оценки в REPL, обычно используя горячую клавишу (подробнее об этом позже). Итак, на картинке ниже я сначала сбросил свое состояние Integrant (используя горячую клавишу, конечно). Затем я оценил формы (например, (set! *print-length* 100)
) одну за другой с помощью специальной горячей клавиши.
На самом деле у меня за столом три монитора, и я держу окно вывода Cursive REPL на другом мониторе, а не в самом редакторе. Недавно я экспериментировал с REPL-инструментом Reveal и держу оба выходных окна рядом, когда экспериментирую с Reveal:
Давайте теперь посмотрим на то же самое с помощью Emacs:
В Emacs вы видите 4 буфера. Верхний буфер показывает файл Clojure (один из моих черновых файлов, в котором я провожу некоторые эксперименты). Ниже расположен буфер cider-repl, который подключен к REPL, описанному в предыдущей главе, и буфер сообщений рядом с ним (выходные данные REPL повторяются). Внизу находится буфер команд, который также повторяет вывод REPL. Emacs также прекрасно повторяет вывод REPL в буфере редактора:
=> {:country_name "Finland", :country_code :FIN, :series-name "Hospital beds (per 1,000 people)", :series-code :SH.MED.BEDS.ZS, :year 2002, :value 7.4, :country-id 246}
Вы можете запустить инструмент вывода Reveal REPL так же, как и раньше (это промежуточное ПО REPL и не связано с редакторами) — у меня окно Reveal находится рядом с Emacs.
Теперь я объяснил, как запускать REPL и как подключаться к REPL с помощью редакторов. Давайте теперь погрузимся во внешний вид.
Look-And-Feel — внешний вид
Внешний вид — это в основном тема редактора — как используются цвета, лигатура шрифта и т. д.
Идея/курсив.
Когда я начал программировать на Clojure с помощью IDEA/Cursive, я хотел найти светлую тему, которая была бы приятной для моих глаз. Мне никогда не нравились темные темы. На самом деле я думал, что в IntelliJ есть тема Leuven, но теперь, когда я проверил ее, я заметил, что создал пользовательскую тему «KariLeuven» — возможно, использовал какую-то существующую тему, подобную Leuven, в качестве основы, уже не помню. В любом случае, цветовая тема довольно проста: светлая тема с небольшим количеством цветов (def
, defn
и языковые макросы, такие как comment
, используют синий цвет, ключевые слова используют фиолетовый, а строки - зеленый). На рисунке ниже показаны настройки моей темы.
Emacs.
Я взял начальную настройку для своей конфигурации Clojure Emacs из Flyingmachine’s Emacs Cursive setup. Затем я немного доработал его, например. используя тему Лёвена, которую я изначально получил от fniessen, и немного усовершенствовал ее.
Look-And-Feel — ощущение
Часть Feel — это то, как человек перемещается в редакторе и манипулирует S-выражениями. Поскольку Clojure — это Lisp и, следовательно, гомоиконный язык, все выражения являются так называемыми S-выражениями — S-выражения могут быть построены из других S-выражений. Вот почему в Лиспе много круглых скобок — но это также делает язык действительно мощным (макросы и т. д.) и удобным для редактирования. Есть две основные школы, связанные с редактированием кода на Лиспе: старый стиль paredit и новый стиль parinfer. Используя paredit, у вас есть определенные команды, которые вы используете для управления S-выражениями, например. переместить это S-выражение внутрь следующего S-выражения и т. д. При использовании parinfer вам не нужно запоминать какие-либо специальные команды, но вы достигаете тех же результатов, делая отступы в коде на Лиспе.
Вот пара веб-страниц, которые хорошо иллюстрируют разницу:
Сам пользуюсь паредитом. Я попробовал паринфер, но это было немного странно. У меня есть одни и те же горячие клавиши для глотания и рвоты как для IDEA/Cursive, так и для Emacs, и поэтому мне довольно легко редактировать код Lisp с помощью paredit. При собеседовании с моими коллегами в Metosin большинство программистов использовали paredit. Но если вы новичок в мире Lisp/Clojure, я предлагаю использовать parinfer — проще начать редактировать код, когда не нужно учить какие-то специальные команды.
Горячие клавиши для прихлебывания и рвоты
Чтобы понять, как я хлюпаю и блюю, горячие клавиши, читатель должен сначала прочитать мою предыдущую запись в блоге Dygma Raise Keyboard Reflections Part 1. В этом сообщении в блоге я объясняю, как я настроил клавишу CapsLock для работы в качестве клавиши AltGr, чтобы использовать ее для получения различных скобок, не поворачивая большой палец правой руки. Затем читатель должен понять два слоя, которые я настроил в своем Dygma Raise. Я очень рекомендую Dygma Raise — лучшую клавиатуру, которую я когда-либо использовал — идеальную клавиатуру для программиста.
На следующих двух рисунках показаны мои любимые горячие клавиши в IDEA/Cursive:
Наиболее часто используемые горячие клавиши REPL — это Integrant reset
= Alt-J
и Send Form Before Caret to REPL
= Alt-L
.
Затем горячие клавиши управления паролем:
Затем те же настройки в Emacs:
;; override the default keybindings in paredit
(eval-after-load 'paredit
'(progn
(define-key paredit-mode-map (kbd "C-M-j") nil)
(define-key paredit-mode-map (kbd "C-M-l") nil)
(define-key paredit-mode-map (kbd "C-M-j") 'paredit-backward-slurp-sexp)
(define-key paredit-mode-map (kbd "M-<right>") 'paredit-forward-slurp-sexp)
(define-key paredit-mode-map (kbd "C-M-l") 'paredit-backward-barf-sexp)
(define-key paredit-mode-map (kbd "M-<left>") 'paredit-forward-barf-sexp)
(define-key paredit-mode-map (kbd "C-<right>") 'right-word)
(define-key paredit-mode-map (kbd "C-<left>") 'left-word)
))
...
(eval-after-load 'cider
'(progn
...
(define-key cider-mode-map (kbd "M-l") 'cider-eval-last-sexp)
(define-key cider-mode-map (kbd "M-ö") 'cider-eval-defun-at-point)
(define-key cider-mode-map (kbd "M-n") 'cider-repl-set-ns)
(define-key cider-mode-map (kbd "M-m") 'cider-load-buffer)
(define-key cider-mode-map (kbd "M-{") 'cider-format-buffer)
(define-key cider-mode-map (kbd "M-å") 'cider-test-run-ns-tests)
(define-key cider-mode-map (kbd "M-ä") 'cider-test-run-test)
Как видите, довольно просто настроить одни и те же горячие клавиши REPL и одни и те же горячие клавиши paredit для IDEA/Cursive и Emacs/Cider. При чтении этого вы должны помнить, что я не использую клавиши со стрелками, но мои клавиши со стрелками определены как CapsLock + i/j/k/l, поэтому, когда я рву вперед, мой левый мизинец фактически находится в CapsLock, а мой левый большой палец на одной из клавиш большого пальца Dygma (это Alt) и ударил J
указательным пальцем правой руки. Это может показаться очень сложным, но на самом деле это не так — я рассматривал различные раскладки, и текущая раскладка — это своего рода эволюционный результат моих экспериментов с раскладкой клавиатуры. Мне очень нравится система, так как она немного напоминает игру на классической гитаре: я нажимаю комбинации клавиш «управление» (ctrl, shift, alt, CapsLock) левой рукой, а навигацию (стрелку), манипулирование (блевать/хлюпать) , и клавиши оценки (REPL) правой рукой. Все эти комбинации клавиш у меня в мышечной памяти и я не думаю о них сознательно — я просто редактирую код. Несмотря на то, что мне эта система очень подходит, я бы не стал ее рекомендовать кому-то еще — вам придется экспериментировать и найти свою клавиатуру, раскладку клавиатуры и, наконец, горячие клавиши для вашего любимого языка программирования в этой раскладке.
Выводы
И IDEA/Cursive, и Emacs/Cider являются отличными редакторами и интегрированными средами разработки Clojure. Если вы хотите переключиться с одного на другой, вы можете довольно легко настроить оба редактора так, чтобы они выглядели одинаково.
Автор работает в Metosin, используя Clojure в облачных проектах. Если вы заинтересованы в запуске проекта Clojure в Финляндии или хотите пройти обучение по Clojure в Финляндии, вы можете связаться со мной, отправив электронное письмо на мой адрес электронной почты Metosin или связавшись со мной через LinkedIn.
Кари Марттила
- Домашняя страница Кари Марттилы в LinkedIn: https://www.linkedin.com/in/karimarttila/