Emacsの上にも3年

はじめに

研究室に配属されて以来Emacsを使い続けて,そろそろ3年になる.研究室のPCもそろそろ返却しないといけないので,自宅のPCにEmacsをインストールしつつ,今やってる設定をまとめてみようと思う.3年使っているけれど,lispはさっぱりなので,色々な方のブログ等を頼りに.だいたいはコピペしているだけなので,参考元のページを参照してほしい.使っている言語はpythonC++TeXが主なので,そのあたりの設定だけしかしていない.

環境

Emacs24.4は普通にやると入らなかった覚えがある.特にMacは,こちらをみてパッチを当てるなどした.

[追記]

1年たって、helmを導入したり色々変わった。 特にpythonの設定について、こっちに書きなおした。 ksknw.hatenablog.com

init-loader

最近まで,init.elに全部書いて,適当に管理していたので,設定がぐっちゃぐちゃになっていた.init-loaderは特定のディレクトリ以下のすべてのファイルを自動的に読み込んでくれる.設定ファイルを簡単に分割できるので便利.

こちらのサイトから設定,その他をありがたくコピペさせていただいた.

;;init-loaderで残りの設定を読み込む
(require 'init-loader)

;;initファイルを読み込むときのエラーを表示
(defun init-loader-re-load (re dir &optional sort)
  (let ((load-path (cons dir load-path)))
    (dolist (el (init-loader--re-load-files re dir sort))
      (condition-case e
      (let ((time (car (benchmark-run (load (file-name-sans-extension el))))))
        (init-loader-log (format "loaded %s. %s" (locate-library el) time)))
    (error
     (init-loader-error-log (format "%s. %s" (locate-library el) (error-message-string e))) ;追加
     )))))

;;~/.emacs.d/inits/ 以下を読み込み
(init-loader-load "~/.emacs.d/inits")

分割は今のところこんな感じ.

anything

研究室にあったinit.elを捨てて,自分で最初に入れた拡張がこれだった.すべてのファイル,コマンド,クリップボードなんかを統合的に扱ってくれるインターフェイスといえばいいのか.とにかく便利だった.今では依存しきっていて,anythingがないと,ちょっと前に作ったファイルは開けないだろうし,コマンドもほぼ打てないだろうと思う.

こちらはるびきちさんのサイトを参考に.

(require 'anything-startup)

(setq anything-c-filelist-file-name "~/.emacs.d/all.filelist")
(setq anything-grep-candidates-fast-directory-regexp "^~/.emacs.d/")

;;anythingでファイルリストを検索
(define-key global-map (kbd "C-:") 'anything-filelist+)
;;クリップボードの履歴をanythingで検索
(global-set-key "\M-y" 'anything-show-kill-ring)
(global-set-key (kbd "C-.") 'anything-do-grep)

ファイルとコマンドだけでなく,クリップボードに溜め込んだものを扱える,anything-kill-ringも便利.anything-grepは未だに使い方がよくわかってなくて,たまにうまく検索できない.

undo histを使ってるので,filelistを作るスクリプトにそのディレクトリを見ないように設定した以外は,ほぼデフォルト.最近はhelmのほうがいい(?)らしいけど,初めに入れたのがanythingだったので,なんとなく使っている.

migemo

migemoは日本語をローマ字のまま検索してくれる機能.コード書いてて,コメントを検索したいときに,いちいち変換する必要がなくなる.

このあたりを参考にさせていただいて,インストールして

sudo apt-get install cmigemo

適当に設定を書く.

(setq migemo-dictionary "~/cmigemo/dict/utf-8.d/migemo-dict")
(setq migemo-command "cmigemo")
(setq migemo-options '("-q" "--emacs"))
(setq migemo-user-dictionary nil)
(setq migemo-coding-system 'utf-8)
(setq migemo-regex-dictionary nil)
(load-library "migemo")
(migemo-init)

そんなに賢くはないので,大量の日本語から英単語を見つけるときにはむしろ邪魔かもしれない.特にTeX書いてるときとか.

white space

white spaceはスペースやタブなどを可視化してくれる機能.ついでに行末のスペースとか文末の改行とか消すこともできる.

僕は諸悪の根源たる全角スペースを可視化している.ついでに,行末のスペースとかも不要なので消すようにした.

こちらこちらを参考にした.

;;保存時に行末のスペースを削除.文末の改行は削除しない
(require 'whitespace)
(set-face-foreground 'whitespace-space "DarkGoldenrod1")
(set-face-background 'whitespace-space nil)
(set-face-bold-p 'whitespace-space t)
(setq whitespace-style '(tabs           ; タブ
             trailing       ; 行末
             spaces         ; スペース
             space-mark     ; 表示のマッピング
;;                         tab-mark
             ))
(setq whitespace-action '(auto-cleanup))
(global-whitespace-mode 1)

;;全角のスペースを目立たせる   <-こんな感じ
(setq whitespace-space-regexp "\\(\x3000+\\)")
(setq whitespace-display-mappings
      '((space-mark ?\x3000 [?\□])
    (tab-mark   ?\t   [?\xBB ?\t])
    ))

undo tree and hist

undo histはファイルを閉じてもundoの履歴を保存してくれる機能.undo tree は今までのundoの履歴を樹形図みたいに表示してくれる機能.

こちらこちらを参考にした.

;; undoの履歴をウィンドウを閉じても保持する
(when (require 'undohist nil t)
  (undohist-initialize))

;; undoの樹形図を表示する C-x u
(when (require 'undo-tree nil t)
  (global-undo-tree-mode))

関係ないけど,EmacsのundoはWindowsとかの場合と挙動が違っていて,最初に躓いた記憶がある.

その他の細かい設定

基本は研究室にもとからあったものを参考.

自分で入れたのはpopwinとieditとflycheck.それぞれ,コンパイルとかanythingとかでウィンドウ構成を変えないようにする機能.複数箇所の同時編集.文法チェック.

を参考にした.

;;改行時に自動でインデントする
;;C-mとEnterは同等なので,これでOK
(global-set-key "\C-m" 'newline-and-indent)

;;ファイルを開くときに大文字小文字の違いを無視
(setq read-buffer-completion-ignore-case t)    ;; バッファ名
(setq read-file-name-completion-ignore-case t) ;; ファイル名

;; 問い合わせを簡略化 yes/no を y/n
(fset 'yes-or-no-p 'y-or-n-p)

;; C-k で行末の改行も消去
(setq kill-whole-line t)

;;バッファ自動読み込み
(global-auto-revert-mode 1)

;;同名のファイルのバッファ名を変更
(require 'uniquify)
(setq uniquify-buffer-name-style 'post-forward-angle-brackets)

;;compileとかでウィンドウ構成がこわれないようにする
(require 'popwin)
(setq display-buffer-function 'popwin:display-buffer)

;;コンパイル画面でスクロールする
(setq compilation-scroll-output t)

;; 行番号を表示する
(require 'linum)
(global-linum-mode t)      ; デフォルトで linum-mode を有効にする
(setq linum-format "%5d ") ; 5 桁分の領域を確保して行番号のあとにスペースを入れる

;; スタートアップページを表示しない
(setq inhibit-startup-message t)
(server-start)

;タイトルバーにファイル名を表示
(setq frame-title-format (format "%%f - Emacs@%s" (system-name)))

;; ツールバーを消す
(tool-bar-mode 0)

;; バックアップファイルを作らない
(setq backup-inhibited t)
(setq make-backup-files nil)
;; 終了時にオートセーブファイルを消す
(setq delete-auto-save-files t)

;;音を鳴らさない
(setq visible-bell t)
(setq ring-bell-function 'ignore)

;;対応する括弧を挿入
(defun electric-pair ()
  "Insert character pair without sournding spaces"
  (interactive)
  (let (parens-require-spaces)
    (insert-pair)))

;;複数箇所の同時編集 sublime text的なやつ
(require 'iedit)

;; syntaxチェック
(require 'flycheck)

python-mode

追記:結局jediが最強だったので、以下のpython設定はもう使っていない。

最近は以下。 PythonをEmacsで書く+α - やったことの説明

elpy

僕のPythonの設定はほぼこれで終わりといってもいいかもしれない.どこまでがelpyなのかよくわからないが,package-list-packagesで入れると,色々くっついてインストールされた.変数名の補完から,文法チェックまでいろいろしてくれる."."を打つだけで,メソッド名を補完してくれるのが嬉しい.

英語で説明してくれるビデオを参考にして入れた.この動画のシリーズが結構いいかもしれない.

設定は1行.

(elpy-enable)

elpyをインストールする前に入れていた,yasnippetとかauto-completeとかflycheckとかと干渉してよくわからないことになったことがあった.結局Python時にACを切って,snippetのフォルダからpython-modeを削除して,flycheckも言語ごとに設定するようにして,なんとかなった.

その他

色々書いているけど,なくてもelpyで動くとこもありそう.

(add-hook 'python-mode-hook
           '(lambda ()
              (setq indent-tabs-mode nil);;tabの幅を変える
              (setq indent-level 4)
              (setq python-indent 4)
              (setq tab-width 4)
              (define-key python-mode-map "\"" 'electric-pair) ;;括弧の補完
              (define-key python-mode-map "\'" 'electric-pair)
              (define-key python-mode-map "(" 'electric-pair)
              (define-key python-mode-map "[" 'electric-pair)
              (define-key python-mode-map "{" 'electric-pair)
              (define-key company-active-map (kbd "\C-n") 'company-select-next)
              (define-key company-active-map (kbd "\C-p") 'company-select-previous)
              (define-key company-active-map (kbd "\C-d") 'company-show-doc-buffer)
              (define-key company-active-map (kbd "<tab>") 'company-complete)
              (auto-complete-mode -1)
              ))

;;elpy 色の設定 デフォルトは黄色でださい
(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.
 '(company-minimum-prefix-length 1)
 '(company-selection-wrap-around 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.
 '(default ((t (:background "#131313" :foreground "white"))))
 '(company-scrollbar-bg ((t (:inherit company-tooltip :background "dim gray"))))
 '(company-scrollbar-fg ((t (:background "blue"))))
 '(company-tooltip ((t (:background "dim gray" :foreground "white"))))
 '(company-tooltip-annotation ((t (:inherit company-tooltip :foreground "white"))))
 '(company-tooltip-common ((t (:inherit company-tooltip :foreground "white"))))
 '(company-tooltip-common-selection ((t (:inherit company-tooltip-selection :foreground "white"))))
 '(company-tooltip-selection ((t (:inherit company-tooltip :background "blue"))))
 '(mode-line ((t (:foreground "#F8F8F2" :background "#303030" :box (:line-width 1 :color "#000000" :style released-button)))))
 '(mode-line-buffer-id ((t (:foreground nil :background nil))))
 '(mode-line-inactive ((t (:foreground "#BCBCBC" :background "#101010" :box (:line-width 1 :color "#333333"))))))

ネットで見ていると,どうもEmacspython書くには微妙という記述をちょくちょく見かける.どうなんでしょうか.

YaTex-mode

修士論文書くのにも大活躍中のYaTeX.数式のショートカット覚えてから,数式を打つのがそんなに苦ではなくなった.

auto-complete入ってるけど,使うコマンドはだいたいショートカットかsnippetがあるので,あまり必要ないかもしれない.RefTeXの使い方を全く知らないので,設定も研究室にあったものをそのまま.

;; YaTeX
(autoload 'yatex-mode "yatex" "Yet Another LaTeX mode" t)
(setq auto-mode-alist (append
  '(("\\.tex$" . yatex-mode)
    ("\\.ltx$" . yatex-mode)
    ("\\.cls$" . yatex-mode)
    ("\\.sty$" . yatex-mode)
    ("\\.clo$" . yatex-mode)
    ("\\.bbl$" . yatex-mode)) auto-mode-alist))

;;自動改行を抑制 これがないと長い文章のよくわからないところで改行される
(add-hook ' yatex-mode-hook
'(lambda () (auto-fill-mode -1)))

;; RefTexという参考文献とかを補完するモードをONにする 使い方がよくわかってないので調べる
(add-hook 'yatex-mode-hook
      #'(lambda ()
          (reftex-mode 1)
          (define-key reftex-mode-map
        (concat YaTeX-prefix ">") 'YaTeX-comment-region)
          (define-key reftex-mode-map
        (concat YaTeX-prefix "<") 'YaTeX-uncomment-region)
          ))

;;YaTeXのいろいろをAutoCompleteの補完リストに追加する
;;snippetsは"\"いらないけど,ACは"\" も打たないと補完されない 変えたほうがいい?
;; for YaTeX
(require 'auto-complete-latex)
(setq ac-l-dict-directory "~/.emacs.d/ac-l-dict/")
(add-to-list 'ac-modes 'yatex-mode)
(add-hook 'yatex-mode-hook 'ac-l-setup)
(add-to-list 'ac-modes 'foo-mode)
(add-hook 'foo-mode-hook 'ac-l-setup)

(add-hook 'yatex-mode-hook
      #'(lambda ()
          (define-key YaTeX-mode-map (kbd "C-c c") 'compile) ;;C-c c でmake できるようにする
          (auto-complete-mode t)
          ))

c++-mode

auto-complete,yasnippet,gtags,flycheckぐらいしか使っていない.昔はauto-complete-clangとか使っていたような気もする.

それぞれ以下のサイトを参考にした.

cc-mode いらないのではないかという気はしている.

(setq auto-mode-alist (append
  '(("\\.cpp$" . c++-mode)
    ("\\.hpp$" . c++-mode)
    ("\\.h$"   . c++-mode) )auto-mode-alist))


(setq gtags-prefix-key "\C-c")
(require 'gtags)
(require 'anything-gtags)
;; キーバインド
(setq gtags-mode-hook
      '(lambda ()
     (define-key gtags-mode-map "\C-cs" 'gtags-find-symbol)
     (define-key gtags-mode-map "\C-cr" 'gtags-find-rtag)
     (define-key gtags-mode-map "\C-ct" 'gtags-find-tag)
     (define-key gtags-mode-map "\C-cf" 'gtags-parse-file)))


(defvar c++-ac-sources
          '(ac-source-yasnippet
        ac-source-abbrev
        ac-source-dictionary
        ac-source-words-in-same-mode-buffers
        ;;ac-source-clang-async
        ))


;; cc-modeの自前スタイル設定
(add-hook 'c-mode-common-hook
      (lambda()
         (setq completion-mode t)
         (setq compilation-window-height 10)
         (setq c-basic-offset 2)
         ;; cc-mode内で定義されるキーバインド
         (define-key c-mode-base-map "\C-cc"      'compile)
         (define-key c-mode-base-map "\C-cg"      'gdb)
         (define-key c-mode-base-map "\C-ck" 'kill-compilation);やめる
         (define-key c-mode-base-map "\C-ce" 'next-error)   ;エラー検索
         (define-key c-mode-base-map "\"" 'electric-pair)
         (define-key c-mode-base-map "\'" 'electric-pair)
         (define-key c-mode-base-map "(" 'electric-pair)
         (define-key c-mode-base-map "[" 'electric-pair)
         (define-key c-mode-base-map "{" 'electric-pair)
         ;; 括弧や;を入力すると自動で改行
         ;(setq c-auto-newline t)
         ;; TAB はスペース 2 個ぶんで
         (setq-default tab-width 2)
         (setq indent-tabs-mode nil)
         ;; # をインデントしない
         ;;(setq c-electric-pound-behavior '(alignleft))
         (c-set-offset 'cpp-macro 0)
         (c-set-offset 'cpp-macro-cont '+)
         (setq-default ac-sources c++-ac-sources)
         (flycheck-mode t)
         (gtags-mode 1)
         ))


(add-hook 'c++-mode-common-hook
      (lambda()
        (setq completion-mode t)
        (setq compilation-window-height 10)
        (setq c-basic-offset 2)
        ;; cc-mode内で定義されるキーバインド
        (define-key c++-mode-base-map "\C-cc"      'compile)
        (define-key c++-mode-base-map "\C-cg"      'gdb)
        (define-key c++-mode-base-map "\C-ck" 'kill-compilation);やめる
        (define-key c++-mode-base-map "\C-ce" 'next-error)  ;エラー検索
        (define-key c++-mode-base-map "\"" 'electric-pair)
        (define-key c++-mode-base-map "\'" 'electric-pair)
        (define-key c++-mode-base-map "(" 'electric-pair)
        (define-key c++-mode-base-map "[" 'electric-pair)
        (define-key c++-mode-base-map "{" 'electric-pair)
        ;; TAB はスペース 2 個ぶんで
        (setq-default tab-width 2)
        (setq indent-tabs-mode nil)
        ;; # をインデントしない
        (setq c-electric-pound-behavior '(alignleft))
        (c-set-offset 'cpp-macro 0)
        (c-set-offset 'cpp-macro-cont '+)
        (setq-default ac-sources c++-ac-sources)
        (flycheck-mode t)
        (gtags-mode 1)
        ))

;; update GTAGS
(defun update-gtags (&optional prefix)
  (interactive "P")
  (let ((rootdir (gtags-get-rootpath))
    (args (if prefix "-v" "-iv")))
    (when rootdir
      (let* ((default-directory rootdir)
         (buffer (get-buffer-create "*update GTAGS*")))
    (save-excursion
      (set-buffer buffer)
      (erase-buffer)
      (let ((result (process-file "gtags" nil buffer nil args)))
        (if (= 0 result)
        (message "GTAGS successfully updated.")
          (message "update GTAGS error with exit status %d" result))))))))
(add-hook 'after-save-hook 'update-gtags)

org-mode

TODOリストとかメモとかを管理できるモード.最近入れたので,まだ使い方はよくわかっていない.この記事もこのモードで書いて,Markdownで出力している.このモードがなければ,この記事の長さは10分の1以下になっていたであろうと思う.

こちらを参考にした.

画面の切り替えをC-Tabに設定しているので,そこだけ動くようにした.

(require 'ox-qmd)

;; capture templates
(setq org-capture-templates
      '(("p" "Project Task" entry (file+headline (expand-file-name "~/project/project.org") "Inbox")
         "** TODO %?\n    %i\n    %a\n    %T")
    ("m" "memo" entry (file (expand-file-name "~/memo.org"))
         "* %?\n    %i\n    %a\n    %T")))

;; agenda
(setq org-agenda-files (list (expand-file-name "~/project")))

;; C-tab はウインドウの移動に使いたいのではずす
(add-hook 'org-mode-hook
      '(lambda ()
         (define-key org-mode-map [(control tab)] nil)))

見た目

基本的に研究室にあったinit.elからそのまま.mode-lineの色とかはいじった気がする.

;;文字サイズ
(set-face-attribute 'default nil
       :height 110)    ;; font siez
;; 日本語
(set-fontset-font
 nil 'japanese-jisx0208
;; (font-spec :family "Hiragino Mincho Pro")) ;; font
  (font-spec :family "Hiragino Kaku Gothic ProN")) ;; font

;; 半角と全角の比を1:2に
(setq face-font-rescale-alist
      '((".*Hiragino_Mincho_pro.*" . 1.2)))

;;折り返し記号の色
(set-face-foreground 'fringe "#7f7f7f")
;;折り返し記号のとこの背景色
(set-face-background 'fringe "gray12")

;; region の色
(custom-set-faces
 '(default ((t
         (:background "#131313" :foreground "white")
         )))
 '(mode-line ((t (:foreground "#F8F8F2" :background "#303030" :box (:line-width 1 :color "#000000" :style released-button)))))
 '(mode-line-inactive ((t (:foreground "#BCBCBC" :background "#101010" :box (:line-width 1 :color "#333333")))))
 '(mode-line-buffer-id ((t (:foreground nil :background nil))))
 )


;;カーソル行のハイライト
(defface hlline-face
  '((((class color)
      (background dark))
     (:background "gray13" :underline nil))
    (((class color)
      (background light))
     (:background "#00AA00":underline nil))
    (t ()))
  "*Face used by hl-line.")

(setq hl-line-face 'hlline-face)
(global-hl-line-mode)
;;; カーソルの点滅を止める
(blink-cursor-mode 0)


;;透過の設定
(when window-system
  (progn
    (setq default-frame-alist
      (append
       (list
        '(vertical-scroll-bars . nil) ;;スクロールバーはいらない
        '(alpha  . 93))
       default-frame-alist))))

;;起動時にウィンドウを最大化する
(set-frame-parameter nil 'fullscreen 'maximized)

;; リージョン指定,括弧対応に色をつける
(setq transient-mark-mode t)
(show-paren-mode)
(setq show-paren-style 'parenthesis)
(setq show-paren-delay 0.05) ;; default: 0.125

;;行,桁番号,バッファサイズの表示
(line-number-mode t)
(column-number-mode t)

;; 行末のスペースを表示
(setq-default show-trailing-whitespace t)

そのうち入れようと思っているもの

helm

anythingとなにが違うのか,ちゃんと調べてないので保留.

jedi

pythonのオムニ補完.最初入れてたけど,elpyを設定しなおしたときに消してしまった.elpyの設定,しばらくは触りたくない.

stan-mode

pythonとかRからも触れて,簡単にMCMCできるstanという言語のモード.stanについてほぼ知らないので保留.

git関連

バージョン管理の大事さは最近とても感じる.git-gutterとかその辺りをいれるつもり.

おわりに

入れたほうがいいものがあったら教えてください.

参考にさせていただいたサイト

Yosemite で Emacs-24.4 をビルドして動かす

年末emacs設定大掃除をして、これは捨てられないと思った設定書いてく - $shibayu36->blog;

anything導入のeverything ~3分で使えるanything.el~

migemoを使ってEmacsライフを快適に

whitespace-modeを使って、ファイルの保存時に行末のスペースや末尾の改行を削除する

emacsで全角スペースを見やすくする。 - プログラミングのメモ

Emacs24.3の導入とundo-tree.elの紹介

ヘルプバッファや補完バッファをポップアップで表示してくれるpopwin.elをリリースしました - Functional Emacser

Emacs as a C/C++ Editor/IDE (Part I): auto-complete, yasnippet, and auto-complete-c-headers

flymakeの設定する前に flycheckを確認しよう - Life is very short

Emacs as a Python editor and IDE (Part 1): Installing elpy mode

「Emacsのトラノマキ」連載第09回「auto-completeを使おう」(松山智大) | ありえるえりあ

Emacs - コードリーディングにとっても便利な GNU GLOBAL と gtags.el (と anything-gtags.el) をつかおう

Emacs - org-modeの使い方例