17 февраля 2011

Lisp. Операционная система Emacs

Начнем с настройки emacs. Сразу скажу, что эта настройка никогда больше не закончится. Я дам Вам всего лишь несколько советов, которые увидел у гуру.

1. Не редактируйте .emacs.

Почти все описания расширений содержат "добавте это [лисп-код] в .emacs". Если вы узнаете сколько расширений существует, вы ни за что не захотите держать их конфигурации в одном месте.

2. Создайте папки ~/.emacs.d и ~/.emacs.d/site-lisp

В первой папке будут находиться конфигурационные скрипты для расширений, во-второй сами расширения.

3. Создайте файлы ~/.emacs.d/init.el и ~/.emacs.d/custom.el

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

4. Располагайте emacs плагины в поддиректориях ~/.emacs.d/site-lisp.

Например ~/.emacs.d/site-lisp/muse-mode или ~/.emacs.d/site-lisp/git-blame

Для каждого расширения создайте ~/.emacs.d/init-[name].el

Теперь давайте заложим скелет Вашей будущей операционной системы Emacs.

~/.emacs

(add-to-list 'load-path "~/.emacs.d/")
(require 'init)

~/.emacs.d/init.el

;;----------------------------------------------------------------------------
;; Set load path
;;----------------------------------------------------------------------------
(let ((default-directory "~/.emacs.d/site-lisp/"))
  (normal-top-level-add-to-load-path '("."))
  (normal-top-level-add-subdirs-to-load-path))

;;----------------------------------------------------------------------------
;; Load configs for specific features and modes
;;----------------------------------------------------------------------------
;; TODO: load configuration scripts, for example (require 'init-javascript)

;;----------------------------------------------------------------------------
;; Allow access from emacsclient
;;----------------------------------------------------------------------------
(server-start)

;;----------------------------------------------------------------------------
;; Variables configured via the interactive 'customize' interface
;;----------------------------------------------------------------------------
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file)

(require 'init-locale)

(provide 'init)
Как видите все просто. Первая секция перечисляет все папки в ~/.emacs.d/site-lisp. Далее будут загружаться наши конфигурации. Затем запускаем emacs-server, будем потом все файлы открывать в одном экземпляре программы. Загружаем файл custom.el с общими настройками. Загружаем файл с настройками локали.

custom.el

(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(column-number-mode t)
 '(cua-mode t nil (cua-base))
 '(display-time-mode t)
 '(indent-tabs-mode nil)
 '(inhibit-startup-screen t)
 '(interprogram-paste-function (quote x-cut-buffer-or-selection-value) t)
 '(keyboard-coding-system (quote utf-8-unix))
 '(linum-format "%d ")
 '(lisp-indent-offset 2)
 '(mouse-drag-copy-region nil)
 '(muse-mode-auto-p t)
 '(qooxdoo-compile-on-save nil)
 '(scroll-preserve-screen-position nil)
 '(select-active-regions t)
 '(show-paren-mode t)
 '(standard-indent 2)
 '(tab-width 2)
 '(x-select-enable-clipboard t)
 '(x-select-enable-primary nil)
 '(x-select-request-type (quote (UTF8_STRING COMPOUND_TEXT TEXT STRING)) t))

(custom-set-faces
  ;; custom-set-faces was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
)

init-locale.el

(custom-set-variables
 '(current-language-environment "UTF-8")
 '(default-input-method "russian-computer")
 '(keyboard-coding-system 'utf-8-unix)
)


(set-terminal-coding-system 'utf-8)
(prefer-coding-system 'mule-utf-8)

(provide 'init-locale)

5 комментариев:

  1. Есть замечания по поводу хранить файл настроек для каждого модуля в отдельном файле.

    Ну во первых скорость загрузки Emacs страдает (вы ведь не используете ;;;autoload???).

    А во вторых идогда имеются зависимости между настройками, и вместо того что бы это рулить elisp кодом, легче расположить в ПРАВИЛЬНОМ порядке в ОДНОМ файле настроек.

    Во вторых зачем:

    (if (fboundp 'normal-top-level-add-subdirs-to-load-path)

    если normal-top-level-add-subdirs-to-load-path есть даже в версии GNU Emacs 21.3??

    ОтветитьУдалить
  2. Насчет (if (fboundp 'normal-top-level-add-subdirs-to-load-path) спасибо, поправил.

    За замечания тоже спасибо.
    Скорость загрузки не критична в моем случае, так как использую emacs server/client.
    Зависимости, да, есть, но немного.

    Емакс очень просто наращивается большим количество расширений, но просто физически неудобно по одному файлу лазить и запиливать. Например, когда что-то нужно отключить. К тому же можно емакс запускать как си, кложур, пайтон ide по-отдельности.

    ОтветитьУдалить
  3. > К тому же можно емакс запускать как си, кложур, пайтон ide по-отдельности.
    Да, этот вариант интересен.

    Можно использовать (eval-after-load 'lang (lambda nil (load "~/emacs.d/init-lang.el"))) патерн для загрузки необходимых конфигов как только появится фича lang. Т.е. открыли в первый раз .cxx файл и сразу загрузились настройки для С++.

    ОтветитьУдалить
  4. Ну, можно и отложенной загрузкой, да)
    Просто это слегка усложняет конструкцию. А вообще последнее время люблю очень-очень явную инициализацию в одном месте, один раз и навсегда.

    ОтветитьУдалить
  5. > в одном месте, один раз и навсегда
    Да, проще отлаживать и понимать!

    ОтветитьУдалить