Sunday, July 7, 2013

Emacs как Сlojure IDE

Во время изучения нового языка программирования вопрос об IDE стоит не на последнем месте. Я предпочитаю, когда рабочее окружение строится вокруг привычного инструментария, доставил плагин - получаешь необходимый функционал. Обычно это работает. Но только не с clojure. dev.clojure.org предлагает множество вариантов, но действительно рабочими являются немногие. До недавнего времени использовал Counterclockwise, но как показала практика, решение не самое удобное и стабильное. Плагин для IntelliJ IDEA на удивление еще хуже. И того получается, что список вроде бы большой, но выбрать особо не из чего(что было бы более ли менее привычным). В итоге я решил попробовать emacs в связке с clojure-mode. Должен признаться, что в некоторой степени на меня повлиял просмотр вот этого видео:

В статье я хочу рассказать о необходимых настройках, которые следует выполнить для того чтобы использовать emacs как Clojure-IDE. Все описанные шаги былы проделаны на Debian Wheezy в связке с emacs-snapshot.

Начальная конфигураця

Emacs из коробки не так хорошо, как мог бы быть, поэтому нам придется его немного допилить. В далекие времена, каждый уважающий себя девелопер почитал за честь создать свою уникальную конфигурацию(что-то вроде хобби, когда нечем заняться на досуге). Сейчас ситуация изменилась в лучшую сторону. Существует проект emacs-starter-kit(статья на хабре) - конфигурация, которую не стыдно взять за начальную. В добавок ко всему, starter-kit поддерживается и развивается. Все что нам нужно - это сделать клон:

# perform this command from home directory
git clone https://github.com/technomancy/emacs-starter-kit.git .emacs.d

После добавить ~/home/.emacs.d/init.el, который у меня выглядит так:

(require 'package)
(add-to-list 'package-archives
             '("marmalade" . "http://marmalade-repo.org/packages/") t)
(package-initialize)

(setq inhibit-startup-message t)  ;; dont show splash
(global-linum-mode t)
(column-number-mode 1)
(global-hl-line-mode 1)
(setq scroll-step 1)              ;; line-by-line scrolling
(setq make-backup-files nil)      ;; prevent backup files
(setq-default fill-column 120)
(fset 'yes-or-no-p 'y-or-n-p)     ;; use 'y' and 'n' instead 'yes' and 'no'
(show-paren-mode 1)
(electric-pair-mode 1)

(if window-system (set-frame-size (selected-frame) 140 40))
(if window-system (tool-bar-mode -1))    ;; M-x tool-bar-mode
(if window-system (scroll-bar-mode -1))   
(if window-system (menu-bar-mode -1))    ;; M-x menu-bar-mode

;;(set-default-font "Inconsolata-11")
;;(set-default-font "Consolas-10")

;;
;; C-x C-g binding for go to line number
;;
(global-set-key [?\C-x ?\C-g] 'goto-line)


(require 'auto-complete)
(global-auto-complete-mode t)
(setq ac-auto-start nil)
(setq ac-auto-start 3) ;; when entring 3 characters
(define-key ac-complete-mode-map "\t" 'ac-complete)
(define-key ac-complete-mode-map "\r" nil)

Установка пакетов

В самом начале следует обновить содержимое репозитария. Для этого в запущенном редакторе выполяем команду:

M-x package-refresh-contents [RET]

Инсталляции пакета - это последовательность двух команд:

M-x package-install [RET] package-name [RET]

Для работы с clojure нам понадобятся: starter-kit, starter-kit-lisp, starter-kit-bindings, starter-kit-eshell, clojure-mode, clojure-test-mode, nrepl.

Проверим рабочее окружение... Запускаем REPL:

M-x nrepl-jack-in

И пробуем выполнить произвольную операцию:

Clojure Test Mode

Я предпочитаю ТDD и, как мне кажется, все современные IDE должны предоставлять средства для данного стиля разработки. Помимо прочего clojure-mode содержит clojure-test-mode.el - модуль умеющий запускать тесты и представлять результаты.

Для запуска тестов текущего буфера используется сочетание клавиш C-c C-,, для очистки результатов- C-c k. Ошибки и непройденные тесты будут помечены маркерами:

Переключение между тестом и реализацией, осуществляется сочетанием клавиш C-c C-t. В корне проекта должна находиться директория src/, содержащая исходный код и директория test/ - юнит тесты. Пространство имен тестов должно быть таким же как и у исоходников с добавлением суффикса -test. Например, пространство имен my.project.frob имеет следующую организацию файлов src/my/project/frob.clj и тестов my.project.frob-test и test/my/project/frob_test.clj.

nrepl

nrepl - это клиент для Clojure networked REPL server, пришел на смену проекту SLIME + swank-clojure. Как упоминалось ранее, для запуска REPL служит команда M-x nrepl-jack-in(во время работы может быть запущено несколько сессий). Для закрытия текущей и для закрытия всех сессий - M-x nrepl-close, M-x nrepl-quit соответственно. Команды редактируемого буфера(полный список можно посмотреть на оф. странице):

  • C-x C-e - показать результат в эхо-буфере
  • C-c C-r - отобразить результат выделенной области в эхо буфере
  • C-c C-b - прервать выполнение команды
  • C-c M-n - переключить пространство имен текущего буфера
  • C-c M-o - очистить REPL, оставить лишь приглашение
  • C-c C-k - загрузить буфер
  • C-c C-l - загрузить файл
  • C-c C-d - показать документацию по текущему символу
  • C-c C-s - показать сорцы
  • C-c C-j - показать Javadoc(в броузере)
  • M-. - перейти к декларации/определению символа
  • M-, - вернуться на прежнее место(смь. предыдущий пункт)
  • M-TAB - автодополнение/автозавершение символа
Команды REPL буфера:
  • C-RET - дополнить все скобки выражение и вычислить результат
  • C-j - перейти на новую строку
  • C-c M-o - очистить REPL, оставить лишь приглашение
  • C-c C-o - очистить результат предыдущего вычисления
  • C-c C-b/C-c C-с - прервать выполнение команды
  • C-up/C-down - переход по истории команд
  • C-c C-d - показать документацию по текущему символу

Плюшки

Для работы с clojure-mode(и не только) рекомендуется использовать Paredit. Данный пакет в разы облегчает редактирование кода. Установить можно из репозитария. Для перманентной активации необходимо добавить следующую строчку в файл конфигурации:

;; (require 'paredit) if you didn't install it via package.el
(add-hook 'clojure-mode-hook 'paredit-mode)

Краткий справочник по Paredit можно найти здесь.

Линки

No comments:

Post a Comment