Управление пакетами в EMACS с помощью use-package
Что такое use-package и как с ним бороться.
Автор данного пакета преследовал цель удобного управления своими пакетами, поддержание чистоты конфигурационных файлов EMACS и по возможности оптимизацию запуска. Ему удалось их успешно решить, а я решил воспользоваться результатами чуждого труда и заодно поделиться информацией. Почитать на англиском про use-package можно здесь, а в статье я лишь оставлю заметку о том, что реально пригодилось.
~/.emacs
Мой файл .emacs
содержит довольно мало строк: установщик некоторых базовых пакетов, загрузчик файлов конфигурации, немного комментариев. Выглядит это всё так:
;;; package --- Summary
;;; Commentary:
;;; Main EMACS settings file, load settings from parts.
;;; Code:
(require 'package)
;;; Источники для установки пакетов. Дело в том, что MELPA Stable
;;; содержит не очень свежие версии, поэтому иногда лучше ставить
;;; пакеты из основного репозитория.
(add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/"))
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(setq package-enable-at-startup nil)
(package-initialize nil)
;;; Если пакет use-package не установлен, его нужно скачать и
;;; установить
(unless (package-installed-p 'use-package)
(message "EMACS install use-package.el")
(package-refresh-contents)
(package-install 'use-package))
;;; Установили, загрузили, указали, что недостающие пакеты нужно
;;; автоматически загружать и устанавливать.
(require 'use-package)
(setq use-package-always-ensure t)
;;; Указываем откуда брать части настроек.
(defconst user-init-dir
(cond ((boundp 'user-emacs-directory) user-emacs-directory)
((boundp 'user-init-directory) user-init-directory)
(t "~/.emacs.d/")))
;;; Функция для загрузки настроек из указанного файла.
(defun load-user-file (file)
(interactive "f")
"Load a file in current user's configuration directory"
(load-file (expand-file-name file user-init-dir)))
;;; Части конфигурации. Порядок не имеет принципиального значения,
;;; однако я рекомендую некоторые базовые вещи помещать в начало,
;;; чтобы не было необходимости вспоминать базовые команды EMACS
;;; если в результате улучшения сломается один из базовых конфигов.
(load-user-file "neotree.el")
(load-user-file "personal.el")
(load-user-file "themes.el")
(load-user-file "flycheck.el")
(load-user-file "company.el")
(load-user-file "ibuffer.el")
(load-user-file "python.el")
(load-user-file "web.el")
(load-user-file "javascript.el")
(load-user-file "markdown.el")
(load-user-file "json.el")
(load-user-file "yasnippet.el")
(load-user-file "helm.el")
(load-user-file "keyboard.el")
(load-user-file "fonts.el")
(load-user-file "powerline.el")
(load-user-file "elisp.el")
;;; А здесь EMACS хранит настройки, задаваемые через customize
(setq custom-file "~/.emacs.d/customize.el")
(load-user-file "customize.el")
;;; .emacs ends here
Половина дела сделана. Настройки размещены в разных файлах, каждый из которых не зависит от других. Вот теперь заживём!
neotree.el
;;; Package --- Summary
;;; Commentary:
;;; NeoTree - sidebar for file browsing
;;; Code:
;;; Как я и говорил, пакет будет скачан и установлен автоматически.
(use-package
neotree
:bind ([f8] . neotree-toggle) ;;; Так делается привязка клавиш.
:init (setq neo-window-width 35) ;;; Настройки ДО загрузки пакета.
:config (setq neo-smart-open nil)) ;;; Настройки ПОСЛЕ загрузки пакета.
;;; neotree.el ends here
Полагаю, данный пример наглядно показывает, как пользоваться use-package
. Продолжим.
personal.el
;;; Package --- Summary
;;; Commentary:
;;; User settings for .emacs
;;; Code:
;;; Закрывать *scratch* при запуске.
(kill-buffer "*scratch*")
;;; Цветные скобочки
(use-package
rainbow-delimiters
:init (add-hook 'prog-mode-hook #'rainbow-delimiters-mode)
(setq rainbow-delimiters-max-face-count 9))
;;; Scrolling
(setq scroll-step 1) ;; one line
(setq scroll-margin 10) ;; scroll buffer to 10 lines at going to last line
(setq scroll-conservatively 10000)
(setq directory-free-space-args "-Pm")
;; Подсветка результатов поиска и всё такое
(setq search-highlight t)
(setq query-replace-highlight t)
(setq column-number-mode 1) ;; Номера строк слева
(setq use-dialog-box nil) ;; Не нужны нам диалоги, будем всё руками делать
(auto-fill-mode -1) ;; Не знаю, что за параметр, так и не разобрался
(setq-default tab-width 4) ;; Заменить TAB на 4 пробела
(setq-default standart-indent 4) ;; Стандартный отступ - 4 пробела
(setq backup-inhibited t) ;; Backup'ы тоже делать не будем
(setq auto-save-default nil) ;; Автосохранение не нужно
(setq scroll-preserve-screen-position 10) ;; Показывать не менее 10 строк на экране
(setq-default c-basic-offset 4 c-indent-level 4 indent-tabs-mode nil) ;; TAB'ы не нужны
(setq-default save-place t) ;; Помнить, где был курсор в прошлый раз
;;; Нажатие Insert больше не включает режим замены
(define-key global-map [(insert)] nil)
;;; Автоформатирование перед сохранением
(defun format-current-buffer()
(indent-region (point-min)
(point-max)))
(defun untabify-current-buffer()
(if (not indent-tabs-mode)
(untabify (point-min)
(point-max)))
nil)
(add-to-list 'write-file-functions 'untabify-current-buffer)
(add-to-list 'write-file-functions 'delete-trailing-whitespace)
(cua-mode 1) ;;; Ctrl+C, Ctrl+V! Прямо как в Windows!
(desktop-save-mode 1) ;;; Помнить, какие файлы были открыты в прошлый раз
(fset 'yes-or-no-p 'y-or-n-p) ;;; Вместо yes и no понимать y и n
(global-hl-line-mode 1) ;;; Подсветка текущей строки
(global-linum-mode 1) ;;; Показывать номера строк всегда
(menu-bar-mode -1) ;;; А меню - никогда
(scroll-bar-mode -1) ;;; Скроллбар не нужен
(tool-bar-mode -1) ;;; Тулбар не нужен
;;; Умные скобочки
(use-package
smartparens
:config (smartparens-global-mode 1))
;; Electric pair mode
(electric-pair-mode 1)
;; Иконки в статус-баре
(use-package
mode-icons
:config (mode-icons-mode 1))
;; Показывать отступы во всех режимах
(use-package
indent-guide
:config (indent-guide-global-mode 1))
;;; Дерево отмены
(use-package
undo-tree
:config (global-undo-tree-mode 1))
;;; personal.el ends here
python.el
Очень интересный конфиг получается для Python.
;;; Package --- Summary
;;; Commentary:
;;; Settings for Python
;;; Code:
(defun annotate-pdb()
(interactive)
(highlight-lines-matching-regexp "import ipdb")
(highlight-lines-matching-regexp "import pdb")
(highlight-lines-matching-regexp "set_trace()")
(highlight-regexp "^TODO ")
(highlight-phrase "FIXME"))
(use-package
python
:mode ("\\.py'" . python-mode)
:init (progn
(defalias 'python2-mode 'python-mode)
(defalias 'python3-mode 'python-mod))
:config (setq-default py-separator-char 47) ;; Use spaces instead tab
(setq-default python-indent-offset 4) ;; 4 spaces instead 2 for python-mode
)
(use-package
company-anaconda
:ensure t
:init (add-to-list 'company-backends 'company-anaconda))
(use-package
py-autopep8
:init (progn (add-hook 'python-mode-hook 'py-autopep8-enable-on-save)))
(use-package
anaconda-mode
:commands anaconda-mode
:diminish anaconda-mode
:init (progn (add-hook 'python-mode-hook 'anaconda-mode)
(add-hook 'python-mode-hook 'eldoc-mode)
(add-hook 'python-mode-hook 'annotate-pdb)))
(use-package
pyvenv
:config (defalias 'workon 'pyvenv-workon))
(use-package
py-isort
:config (setq py-isort-options '("-sl"))
:init (progn (add-hook 'python-mode-hook 'py-isort-before-save)))
(use-package
company-anaconda
:config (add-to-list 'company-backends 'company-anaconda))
;;; python.el ends here
Не уверен, что нужно что-то тут объяснять, но на всякий случай свой company.el
тоже выставляю напоказ.
company.el
Этот модуль отвечает за подсказки и автозавершение. Он новее, чем autocomplete
, и активно развивается. Большая часть плагинов дополнения сейчас пишется именно под него.
;;; Package --- Summary
;;; Commentary:
;;; Settings for company
;;; Code:
(use-package
company
:diminish company-mode
:config (setq company-backends (remove 'company-ropemacs company-backends) company-tooltip-limit
20 company-tooltip-align-annotations t)
(global-company-mode 1))
;;; company.el ends here
Комментариев нет :
Отправить комментарий