Emacs как редактор кода для Python и Golang
Введение
Когда полгода назад я решил перейти с Vim на Emacs сначала я решил поискать статьи по настройке последнего на хабре. К моему удивлению нашлась всего одна статья в которой рассказывали, как настроить данный редактор для работы с Python. У меня было 2 года опыта работы с vim и имелись определенные требования, которые не были затронуты в данной статье. Вообще рускоязычных статей про работу в Emacs над Python очень мало на просторах интернета. Я не буду рассказывать про тонкости настройки самого Emacs, для этого не хватит даже отдельной статьи.
Сразу хочу предупредить любителей холивара Emacs vs Vim, а также Emacs/Vim vs IDE — я не хочу разводить бесполезные споры на эти темы. После долгих поисков я нашел редактор, который устраивает меня всем и который можно настроить как душе угодно. Я просто хочу поделится своими конфигами, а также надеюсь увидеть альтернативные решения в комментариях, чтобы продолжать настраивать данный инструмент под себя.
Требования
Самое первое требование — легко переносимая конфигурация и установка плагинов между домом и работой.
Для этого использую github. Так как часто случается, что я изменяю что-то в конфигах, я использую meld для просмотра разницы между файлами.
В meld можно просматривать как директории, так и отдельные файлы. После синхронизации тем же мелдом все изменения добавляю в домашнюю директорию.
Не менее важное требование — удобный менеджер плагинов, с ленивой загрузкой и обновлением, как NeoBundle из vim. В процессе поиска такого менеджера также выяснилось, что в емаксе плагины можно скомпилировать, для ускорения загрузки. На счастье, нашелся как раз такой менеджер, который удовлетворял всем требованиям и даже больше. Это el-get — идеальный менеджер с автокомпиляцией, автоматической инициализацией, а также самое важное — рецептами установки. Приведу короткий пример рецепта, для наглядности.
(:name flycheck
:type github
:pkgname "flycheck/flycheck"
:checkout "0.25.1"
:minimum-emacs-version "24.3"
:description "On-the-fly syntax checking extension"
:build '(("makeinfo" "-o" "doc/flycheck.info" "doc/flycheck.texi"))
:info "./doc"
:depends (dash pkg-info let-alist seq)
:post-init (progn
(add-hook 'python-mode-hook #'flycheck-mode)
(add-hook 'js-mode-hook #'flycheck-mode)
(add-hook 'web-mode-hook #'flycheck-mode)
(add-hook 'lisp-interaction-mode-hook #'flycheck-mode)
(add-hook 'fish-mode-hook #'flycheck-mode)
(add-hook 'markdown-mode-hook #'flycheck-mode)
(add-hook 'go-mode-hook #'flycheck-mode)
(setq flycheck-check-syntax-automatically '(mode-enabled save idle-change))
(setq flycheck-highlighting-mode 'lines)
(setq flycheck-indication-mode 'left-fringe)
(setq flycheck-checker-error-threshold 2000)
))
Это рецепт установки flycheck — плагина, для синтаксической проверки файлов при редактировании, на лету. В рецепте можно указывать источник кода — репозиторий git/github или просто ссылку на файл или название плагина в ELPA/MELPA, необходимые зависимости, в случае github — ветку или таг.
Команда : build позволяет запускать системные утилиты, если они необходимы для корректной установки плагина.
Также есть замечательная команда — : post-init, в ней можна указывать лисповый код, который будет запускатся каждый раз после инициализации плагина. Я решил прописывать в этой команде все настройки связанные с данным плагином. В общем — очень удобный инструмент.
Я сразу отказался от файла ~/.emacs.el
по причине синхронизации между работой и домом.
Поэтому все настройки расположены в папке ~/.emacs.d
. Максимально тонкий init.el в котором подключаются логически разбитые файлы из папки settings.
(add-to-list 'load-path (expand-file-name "settings" user-emacs-directory))
(require 'dark-mint-theme)
(require 'scratch_my)
(require 'package_my)
(require 'hooks_my)
(require 'keybindings_my)
...
автоматически генерируемый при customize код
Первый файл — тема оформления. Больше тем тут
scratch_my.el описывает все стандартные настройки и включает необходимые режимы, которые уже присутствуют с нуля в любом свежем Emacs.
В package_my.el список всех устанавливаемых плагинов и несколько функций для корректной установки.
Хуки разных режимов описаны в файле hooks_my.el.
Смена сочетаний клавиш вынесена в отдельный файл keybindings_my.el.
Также синхронизируются папка с сниппетами yasnippet и с рецептами.
Очень часто я вношу изменения в рецепты, добавляя туда настройки плагинов, поэтому я храню их в отдельной папке.
Плагины, не зависимые от языка программирования
Я подробно не буду описывать все плагины, к каждому прилагается ссылка, где подробно все расписано.
Начнем пожалуй с avy, плагина позволяющего переходить на слово, содержащее введеный символ (аналог vim-easymotion).
Для автодополнения используется company-mode — универсальное автодополнение для Emacs.
Очень быстро работает, полностью настраивается, хотя документация у него неполная, в исходники заглядывал частенько. Удобство проявляется в структуре даного плагина. Есть бекенд — индивидуальный код для разных режимов и фронтенд — общий код, который отрисовывает результаты автодополнения в самом Emacs. Для разных режимов используются разные бекенды. Например для лиспа используется company-elisp бекенд, для Python — company-jedi (бекенд для jedi — библиотеки статического анализа кода Python).
Для дополнения golang кода используется company-go бекенд.
expand-region используется для семантического выделения текста. Более подробно в этом видео.
Для работы с git использую три замечательных плагина — git-gutter, mo-git-blame и magit. Хочу особо выделить последний плагин — он просто потрясающий, пару касаний и код уже на сервере (видео).
А как же файловый менеджер спросите вы? neotree. Интеграция с git присутствует.
Очень полезный плагин — helm — автодополнение к всему. Поиск по открытым буферам (helm-swoop), по недавно открытым файлам, по файлам в текущей директории, поиск по командам, переименование переменных в нескольких буферах и много всего остального. Отличная статья описывает все возможности данного плагина.
multiple-cursors — после просмотра данного видео вам обязательно захочется его попробовать:).
Плагин, с помощью которого можно назначить действие на двойное нажатие любых клавиш называется key-chord (видео)
Аналог vim-powerline — powerline
projectile — плагин для управления проектами в Emacs. Поиск по проекту, замена по файлам проекта, переход внутри проекта, переключение проекта и множество других полезных функций. Подробности в этой статье
yasnippet — позволяет создавать и использовать сниппеты для разных языков программирования.
Python mode
Наконец-то мы переходим к настройке Emacs непосредственно для работы с Python.
Начнем пожалуй с хуков
;; Python mode
(defun my-merge-imenu ()
(interactive)
(let ((mode-imenu (imenu-default-create-index-function))
(custom-imenu (imenu--generic-function imenu-generic-expression)))
(append mode-imenu custom-imenu)))
(defun my-python-hooks()
(interactive)
(setq tab-width 4)
(setq python-indent 4)
(setq python-shell-interpreter "ipython"
python-shell-interpreter-args "-i")
(if (string-match-p "rita" (or (buffer-file-name) ""))
(setq indent-tabs-mode t)
(setq indent-tabs-mode nil)
)
(add-to-list
'imenu-generic-expression
'("Sections" "^#### \\[ \\(.*\\) \\]$" 1))
(setq imenu-create-index-function 'my-merge-imenu)
;; pythom mode keybindings
(define-key python-mode-map (kbd "M-.") 'jedi:goto-definition)
(define-key python-mode-map (kbd "M-,") 'jedi:goto-definition-pop-marker)
(define-key python-mode-map (kbd "M-/") 'jedi:show-doc)
(define-key python-mode-map (kbd "M-?") 'helm-jedi-related-names)
;; end python mode keybindings
(eval-after-load "company"
'(progn
(unless (member 'company-jedi (car company-backends))
(setq comp-back (car company-backends))
(push 'company-jedi comp-back)
(setq company-backends (list comp-back)))
)))
(add-hook 'python-mode-hook 'my-python-hooks)
;; End Python mode
Для работы плагинов нужно установить пару пакетов через pip
pip install -U jedi virtualenv flake8
Устанавливаем настройки отступов и путь к интерпретатору, выставляем специфические сочетания клавиш, добавляем бекенд company-jedi и настраиваем imenu.
Про автодополнение уже было выше (company-jedi), поиск по файлу и структуре файла (именам классов, переменным, методам и тд.) происходит через imenu (F10), открытие и закрытие файлового менеджера NeoTree происходит при нажатии F7.
Теперь немного о используемых плагинах
auto-virtualenv — отлично работает, особенно в связке с projectile.
jedi-core — отдает company-jedi варианты автодополнения, переходит по определениям, показывает доки к функциям и классам и тд.
pip-requirements — как видно из названия — пакет для работы с requirements.
py-autopep8 — позволяет автоматически форматировать код в cоответствии с стандартом pep8.
py-isort — можно автоматически сортировать все импорты в файле
Python REPL
В хуках мы указали какую версию shell мы будем использовать
(setq python-shell-interpreter "ipython"
python-shell-interpreter-args "-i")
При нажатии C-c C-c
— все содержимое текущего буфера передается в ipython, где его можно тут же протестировать.
Если нужно лиш часть кода просмотреть, выделяете ее и нажимаете C-c C-r
Также можно использовать встроенный в python-mode деббагер, выполнив команду M-x pdb RET
(RET — в емаксе обозначает ентер/return, поначалу меня это сбивало с толку). Также есть более функциональная версия — realgud
В качестве примера, хочу продемонстрировать несколько скриншотов
Emacs для golang
Несколько плагинов используется при работе с go проектами.
go-mode — режим работы go-mode.
Позволяет смотреть документацию, переходить по определениям, использовать различные утилиты проверки и форматирования кода, типа gofmt, golint и тд. Очень удобный плагин.
flycheck-gometalinter — интеграция gometalinter c flycheck.
company-go — бекенд для company
Другие плагины
markdown-mode — в данном режиме я как раз и пишу данную статью. А с помощью livedown просматриваю результат сразу в браузере.
web-mode — позволяет работать с html, css, Django/Jinja2 templates.
restclient — плагин для работы с разнообразными апишками. Emacsrocks покажет больше в своем видео.
Заключение
Жаль что в одной статье невозможно расписать все особенности и тонкости настройки каждого плагина, но я надеюсь список с коротким описанием позволит читателям узнать что-то новое из моего опыта. Также хабрахабр славен тем, что действительно полезную информацию часто можно узнать из комментариев, поэтому прошу вас делится своими настройками и опытом, это будет полезно и мне и вам.
Традиционно, все ошибки и замечания прошу отправлять мне в личные сообщения.
Полезные ссылки