emacs-lisp

どのようなプログラムであっても、一つのファイルにすべてを書き込むのは好ましくない。小さなモジュールに分割するべきだ。最も簡単な方法は load 関数を使って下のように読み込む。拡張子は省略しても良い。ちょっと作ってみた関数とかは適当な名前をつけて隔離しておき下のようにして読み込めばいい。

(load "~/my-lisp/hogehoge.el")

より高機能な方法として require を使う方法がある。

(require hoge-feature)

require の引数には feature と呼ばれるものを与える。 feature とは読み込もうとしているパッケージの名前で、パスではない。自分で feature を作るには次のようなファイルを作る。

(provide 'hoge-feature)
(message "hoge-feature is loaded")

この feature はメッセージを出力するだけのモジュールである。このファイルを ~/my-lisp/hoge-feature.el として保存してみよう。最後に下記のプログラムを実行すれば ~/my-lisp/hoge-feature.el が読み込まれる。

(add-to-list 'load-path "~/my-lisp/")
(require hoge-feature)

変数 load-path は feature の探索範囲を示すリストで、このリストに ~/my-lisp/ を加えることでそこにあるファイルを見つけることができる。 require を使えば2重に読み込んでしまうことを避けられるので、依存関係は require を使って読み込むべきである。

emacs

文字コードについて

C-x RET f で sjis で外部エンコーディングと内部エンコーディングを指定できる。

フォントについて

この記事を読んでみる。そこで紹介されていたこの記事がとても情報が充実していて良い記事だった。 冷静になってみるとこんな背景の知識というのは必要なくて、どうすればフォントが変えれるのかという設定だけわかっていれば良いのかもしれない。 最終的なコードは下のようになったのでそれだけメモしておく。

(set-fontset-font "fontset-default" 'unicode "Ricty" nil 'prepend)
(set-face-attribute 'default nil :family "Ricty" :height 200)
  • フォントファミリ: フォントの集合。 Meiryo など。

  • フォント: フォントファミリ、サイズ、厚みなどが指示されたフォントファミリのインスタンス。 Meiryo bold 14px など。

  • キャラクタセット(charset): 文字のグループ。各文字には番号が割り振られている。ASCII, japanese-jisx0208, unicode など。文字集合と訳される。

  • フォントセット: キャラクタセットとフォントの対応関係を示したもの。

;; Emacs で使用可能な charset の一覧を表示する
;; 適当な文字集合にカーソルを当てて RET を押すとそこに含まれる文字の一覧を表示する
M-x list-character-sets

;; Emacs で使用可能な(定義済みの) fontset の一覧を表示する
;; ここで表示される内容は XLFD の末尾にフォントセットの名前を与えたもの。
;; フォントセットの詳細を見るには describe-fontset を使う
M-x list-fontsets

;; 使用可能なフォントファミリの一覧を表示する
(font-family-list)
;; 使用可能なフォントのXLFDを表示する(XLFD というのはフォントの太字、斜体などのバリエーションを表現した文字列)
(x-list-fonts "Inconsolata")
;; XLFD を使わない場合は font-spec 関数によってフォントを指示する。こちらのほうがわかりやすい。
(font-spec :family "MeiryoKe_Console" :size 14)
;; XLFD の他には font config 形式という形式でフォントを指示することも可能なようだが省略する。

;; デフォルトのフレーム(ウィンドウ)の設定する
;; 座標とかも指定できるけど今回はフォントを XLFD によって設定する
(setq default-frame-alist '((font . "-*-Inconsolata-normal-normal-normal-*-*-*-*-*-m-0-iso10646-1")))

;; 現在のフレーム(ウィンドウ)のフォントを XLFD によって設定する
(set-frame-font "-*-Inconsolata-bold-italic-normal-*-*-*-*-*-m-0-iso10646-1")

;: カーソル位置のフォントのXLFD を表示する
;; たとえば 🙇 (絵文字)のところでカーソル当てて期待したフォントが使われてるか確かめたりできる。
(font-xlfd-name (font-at (point)))

M-x describe-char

emacs-packages

flymake

Emacs には flymake というビルトインパッケージが含まれています。 このパッケージは lint ツールやコンパイラなど外部プログラムを呼び出し、シンタックスエラーなどを見やすく表示します。 flymake は LSP のクライアントとして動作するので language server を持っている言語ではさらに強力になります。 しかしながら flymake は低レイヤの機能しか提供していないため、ツールの呼び出しやツールの出力結果の解析を自前で書く必要があります。 flymake で ruby -c による lint を動かす例 からも設定の難しさが伝わると思います。 基本的には LSP のクライアントから利用するパッケージだと考えるのが良いと思います。

flycheck

flymake よりも少し使いやすいパッケージとして flycheck があります。 flycheck は flymake と同様に他の lint ツールと Emacs を接続するアダプタとして働きます。 flycheck はほとんどの実装を隠蔽しているので flymake よりもかなり少ない設定で動作します。 しかしながら外部プログラムを呼び出して lint を行う都合上、複雑化している部分があります。

Javascript なら eslint、Ruby なら rubocop といったようにそれぞれ言語に応じた lint ツールが必要です。 それらのインストールした上で Emacs からツールを呼び出せるように準備しておく必要があります。 しかし一部の lint ツールはグローバルインストールせずに、プロジェクトごとの隔離されたパッケージ空間にインストールすることがあります。 そのような背景の下でも正しく flycheck を働かせることが、この文書の目的です。

まず、ドキュメントに書いてある通り、パッケージマネージャを使って flycheck をインストールします。 ドキュメントでは global-flycheck-mode が紹介されていますが、私はおすすめしません。 なぜなら、標準で emacs-lisp の lint が動作し init.el に lint の警告が出てしまうからです。 emacs-lisp の lint は emacs にビルトインされているためすぐに動作します。 しかしこの lint は初心者にとってはかなり厳しいルールを持ちます。 そのつもりがなくとも init.el に対してはかなりエラーや警告を出してしまうでしょう。 これらのメッセージはライブラリを開発するような lisp プログラマにとっては有益かもしれませんが、 lisp を普段使いしていない Emacs ユーザにとっては関心が低い問題でしょう。 また、他の言語ではインストールされていないツールを実行しようとして 内部エラーを出してしまったりすることがあります。

上記の理由から flycheck-mode を初めて利用するときは lint したい言語だけを設定するのが良いと思います。

flycheck ruby-rubocop

次に flycheck で Rubocop を有効にする方法を紹介します。

flycheck は checker chains と呼ばれる仕組みを持ちます。 これはプログラミング言語ごとに lint ツールの優先度が決まっており インストールされているものが見つかり次第をそれを採用するという仕組みです。 flycheck の対応言語リスト Ruby によると、ruby-mode では

  1. ruby-rubocop

  2. ruby-reek

  3. ruby-rubylint

  4. ruby

  5. ruby-jruby

の順にツールが利用できるかチェックした上で存在するものを利用すると書かれています。 たとえば rubocop コマンドがグローバルインストールされている場合には、 特に細かい設定なしで rubocop が利用されることが期待できます。

しかし、多くの場合 rubocop は特定のプロジェクトで bundler によりインストールされ、 プロジェクトルート配下に設定ファイル rubocop.yml や rubocoptodo.yml が配置されます。 このようにプロジェクトに依存する状況下では、flycheck のデフォルト設定はうまく機能しません。 その場合 flycheck-verify-setup により設定がどのように解釈され有効になっているかを確認できます。

ruby-rubocop
  - may enable:         yes
  - executable:         Found at /Users/eggc/.rbenv/shims/rubocop
  - configuration file: Found at "/Users/eggc/work/my_project/.rubocop.yml"
  - next checkers:      ruby-reek, ruby-rubylint

magit

最近 instant fixup という機能が増えたらしくて使ってみる。

diminish

モードラインのマイナーモードを非表示にする。

EasyPG

emacs でテキストの暗号化はできたなーというのはなんとなく覚えていたけどやり方は忘れていたので改めて調べる。 「拡張子 .gpg にするだけで暗号化出来るよ」というのをどこかのサイトで読んだけど試してみたらエラーになった。

> epg-context--make: GPG error: "no usable configuration", OpenPGP

gpg コマンドをインストールしてないとこれが出てくるらしい。なので brew install gnupg を実行する。 さてもう一度 .gpg なファイルを作って保存してみた。すると下のようなプロンプトが出てきた。

Select recipients for encryption.
If no one is selected, symmetric encryption will be performed.
- ‘m’ to mark a key on the line
- ‘u’ to unmark a key on the line
[Cancel][OK]

これは何か暗号化の方法を選ばせているようなのだが選択肢が一個もないのでどうしようもない。 gpg で事前に鍵を作っておかないといけないらしい。 しかし github にアクセスする時に使っている秘密鍵・公開鍵を使えばいいんじゃないかと思ったので調べた。 それなりにめんどくさそうなので諦めよう。暇なときにでもいつかまたやってみる。