- PVSM.RU - https://www.pvsm.ru -

Emacs как редактор кода для Python и Golang

image

Введение

Когда полгода назад я решил перейти с Vim на Emacs сначала я решил поискать статьи по настройке последнего на хабре. К моему удивлению нашлась всего одна [1] статья в которой рассказывали, как настроить данный редактор для работы с Python. У меня было 2 года опыта работы с vim и имелись определенные требования, которые не были затронуты в данной статье. Вообще рускоязычных статей про работу в Emacs над Python очень мало на просторах интернета. Я не буду рассказывать про тонкости настройки самого Emacs, для этого не хватит даже отдельной статьи.

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

Требования

Самое первое требование — легко переносимая конфигурация и установка плагинов между домом и работой.
Для этого использую github [2]. Так как часто случается, что я изменяю что-то в конфигах, я использую meld [3] для просмотра разницы между файлами.
В meld можно просматривать как директории, так и отдельные файлы. После синхронизации тем же мелдом все изменения добавляю в домашнюю директорию.

Не менее важное требование — удобный менеджер плагинов, с ленивой загрузкой и обновлением, как NeoBundle [4] из vim. В процессе поиска такого менеджера также выяснилось, что в емаксе плагины можно скомпилировать, для ускорения загрузки. На счастье, нашелся как раз такой менеджер, который удовлетворял всем требованиям и даже больше. Это el-get [5] — идеальный менеджер с автокомпиляцией, автоматической инициализацией, а также самое важное — рецептами установки. Приведу короткий пример рецепта, для наглядности.

(: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 [6] — плагина, для синтаксической проверки файлов при редактировании, на лету. В рецепте можно указывать источник кода — репозиторий git/github или просто ссылку на файл или название плагина в ELPA/MELPA, необходимые зависимости, в случае github — ветку или таг.
Команда :build позволяет запускать системные утилиты, если они необходимы для корректной установки плагина.
Также есть замечательная команда — :post-init, в ней можна указывать лисповый код, который будет запускатся каждый раз после инициализации плагина. Я решил прописывать в этой команде все настройки связанные с данным плагином. В общем — очень удобный инструмент.

Я сразу отказался от файла ~/.emacs.el по причине синхронизации между работой и домом.
Поэтому все настройки расположены в папке ~/.emacs.d. Максимально тонкий init.el [7] в котором подключаются логически разбитые файлы из папки 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 [8] описывает все стандартные настройки и включает необходимые режимы, которые уже присутствуют с нуля в любом свежем Emacs.

В package_my.el [9] список всех устанавливаемых плагинов и несколько функций для корректной установки.

Хуки разных режимов описаны в файле hooks_my.el [10].

Смена сочетаний клавиш вынесена в отдельный файл keybindings_my.el [11].

Также синхронизируются папка с сниппетами yasnippet [12] и с рецептами [13].
Очень часто я вношу изменения в рецепты, добавляя туда настройки плагинов, поэтому я храню их в отдельной папке.

Плагины, не зависимые от языка программирования

Я подробно не буду описывать все плагины, к каждому прилагается ссылка, где подробно все расписано.

Начнем пожалуй с avy [14], плагина позволяющего переходить на слово, содержащее введеный символ(аналог vim-easymotion [15]).

Для автодополнения используется company-mode [16] — универсальное автодополнение для Emacs.
Очень быстро работает, полностью настраивается, хотя документация у него неполная, в исходники заглядывал частенько. Удобство проявляется в структуре даного плагина. Есть бекенд — индивидуальный код для разных режимов и фронтенд — общий код, который отрисовывает результаты автодополнения в самом Emacs. Для разных режимов используются разные бекенды. Например для лиспа используется company-elisp бекенд, для Python — company-jedi [17](бекенд для jedi [18] — библиотеки статического анализа кода Python).
Для дополнения golang кода используется company-go [19] бекенд.

expand-region [20] используется для семантического выделения текста. Более подробно в этом видео [21].

Для работы с git использую три замечательных плагина — git-gutter [22], mo-git-blame [23] и magit [24]. Хочу особо выделить последний плагин — он просто потрясающий, пару касаний и код уже на сервере (видео [25]).

А как же файловый менеджер спросите вы? neotree [26]. Интеграция с git присутствует.

Очень полезный плагин — helm [27] — автодополнение к всему. Поиск по открытым буферам(helm-swoop [28]), по недавно открытым файлам, по файлам в текущей директории, поиск по командам, переименование переменных в нескольких буферах и много всего остального. Отличная статья [29] описывает все возможности данного плагина.

multiple-cursors [30] — после просмотра данного видео [31] вам обязательно захочется его попробовать:).

Плагин, с помощью которого можно назначить действие на двойное нажатие любых клавиш называется key-chord [32](видео [33])

Аналог vim-powerline [34]powerline [35]

projectile [36] — плагин для управления проектами в Emacs. Поиск по проекту, замена по файлам проекта, переход внутри проекта, переключение проекта и множество других полезных функций. Подробности в этой статье [37]

yasnippet [38] — позволяет создавать и использовать сниппеты для разных языков программирования.

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-default py-shell-name "ipython")
    (setq-default py-which-bufname "IPython")
    (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 [39].

Про автодополнение уже было выше(company-jedi), поиск по файлу и структуре файла(именам классов, переменным, методам и тд.) происходит через imenu(F10), открытие и закрытие файлового менеджера NeoTree происходит при нажатии F7.

Теперь немного о используемых плагинах

auto-virtualenv [40] — отлично работает, особенно в связке с projectile.

jedi-core [41] — отдает company-jedi варианты автодополнения, переходит по определениям, показывает доки к функциям и классам и тд.

pip-requirements [42] — как видно из названия — пакет для работы с requirements.

py-autopep8 [43] — позволяет автоматически форматировать код в cоответствии с стандартом pep8.

py-isort [44] — можно автоматически сортировать все импорты в файле

В качестве примера, хочу продемонстрировать несколько скриншотов
image

image

Emacs для golang

Несколько плагинов используется при работе с go проектами.

go-mode [45] — режим работы go-mode.
Позволяет смотреть документацию, переходить по определениям, использовать различные утилиты проверки и форматирования кода, типа gofmt, golint и тд. Очень удобный плагин.

flycheck-gometalinter [46] — интеграция gometalinter c flycheck.

company-go [19] — бекенд для company

image

Другие плагины

markdown-mode [47] — в данном режиме я как раз и пишу данную статью. А с помощью livedown [48] просматриваю результат сразу в браузере.

web-mode [49] — позволяет работать с html, css, Django/Jinja2 templates.

restclient [50] — плагин для работы с разнообразными апишками. Emacsrocks покажет больше в своем видео [51].

Заключение

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

Традиционно, все ошибки и замечания прошу отправлять мне в личные сообщения.

Полезные ссылки

Автор: Crandel

Источник [55]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/python/137733

Ссылки в тексте:

[1] одна: https://habrahabr.ru/post/188376/

[2] github: https://github.com/Crandel/home/tree/master/.emacs.d

[3] meld: http://meldmerge.org/

[4] NeoBundle: https://github.com/Shougo/neobundle.vim

[5] el-get: https://github.com/dimitri/el-get

[6] flycheck: https://github.com/flycheck/flycheck

[7] init.el: https://github.com/Crandel/home/blob/master/.emacs.d/init.el

[8] scratch_my.el: https://github.com/Crandel/home/blob/master/.emacs.d/settings/scratch_my.el

[9] package_my.el: https://github.com/Crandel/home/blob/master/.emacs.d/settings/package_my.el

[10] hooks_my.el: https://github.com/Crandel/home/blob/master/.emacs.d/settings/hooks_my.el

[11] keybindings_my.el: https://github.com/Crandel/home/blob/master/.emacs.d/settings/keybindings_my.el

[12] сниппетами yasnippet: https://github.com/Crandel/home/tree/master/.emacs.d/snippets

[13] рецептами: https://github.com/Crandel/home/tree/master/.emacs.d/settings/recipes

[14] avy: https://github.com/abo-abo/avy

[15] vim-easymotion: https://github.com/easymotion/vim-easymotion

[16] company-mode: http://company-mode.github.io/

[17] company-jedi: https://github.com/syohex/emacs-company-jedi

[18] jedi: https://github.com/davidhalter/jedi

[19] company-go: https://github.com/nsf/gocode/tree/master/emacs-company

[20] expand-region: https://github.com/magnars/expand-region.el

[21] видео: https://www.youtube.com/watch?v=_RvHz3vJ3kA

[22] git-gutter: https://github.com/syohex/emacs-git-gutter

[23] mo-git-blame: https://github.com/voins/mo-git-blame

[24] magit: https://magit.vc/

[25] видео: https://www.youtube.com/watch?v=7gGtzUwDUJw&list=PLECBtie1W1tGlrbDDBvcxnttRR4IA5qZn

[26] neotree: https://www.emacswiki.org/emacs/NeoTree

[27] helm: https://github.com/emacs-helm/helm

[28] helm-swoop: https://github.com/ShingoFukuyama/helm-swoop

[29] статья: http://tuhdo.github.io/helm-intro.html

[30] multiple-cursors: https://github.com/magnars/multiple-cursors.el

[31] видео: https://www.youtube.com/watch?v=jNa3axo40qM

[32] key-chord: https://www.emacswiki.org/emacs/KeyChord

[33] видео: http://emacsrocks.com/e07.html

[34] vim-powerline: https://github.com/powerline/powerline

[35] powerline: https://github.com/milkypostman/powerline

[36] projectile: https://github.com/bbatsov/projectile

[37] статье: http://tuhdo.github.io/helm-projectile.html

[38] yasnippet: https://www.emacswiki.org/emacs/Yasnippet

[39] imenu: https://www.emacswiki.org/emacs/ImenuMode

[40] auto-virtualenv: https://github.com/marcwebbie/auto-virtualenv

[41] jedi-core: https://github.com/tkf/emacs-jedi/blob/master/jedi-core.el

[42] pip-requirements: https://github.com/Wilfred/pip-requirements.el

[43] py-autopep8: https://github.com/paetzke/py-autopep8.el

[44] py-isort: https://github.com/paetzke/py-isort.el

[45] go-mode: https://github.com/dominikh/go-mode.el

[46] flycheck-gometalinter: https://github.com/favadi/flycheck-gometalinter

[47] markdown-mode: https://github.com/defunkt/markdown-mode

[48] livedown: https://github.com/shime/emacs-livedown

[49] web-mode: http://web-mode.org/

[50] restclient: https://github.com/pashky/restclient.el

[51] видео: http://emacsrocks.com/e15.html

[52] Common Lisp IDE: https://habrahabr.ru/post/259737/

[53] Emacsrocks: http://emacsrocks.com/

[54] Изучаем Emacs(плейлист): https://www.youtube.com/playlist?list=PLECBtie1W1tGlrbDDBvcxnttRR4IA5qZn

[55] Источник: https://habrahabr.ru/post/303600/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best