Emacsを使ってるけどLispは書いたことがないとはよく聞きますが、ちょっとした処理をするのにEmacsコマンドを定義するのは有用なので、割と簡単めなものを紹介していきます ヾ(〃><)ノ゙☆
コマンド
そもそもコマンドとは何か
Emacsにおけるコマンドとは、コマンド定義の最初(引数または説明文字列の次)の場所に(interactive)
と書かれた関数のことです。
このコマンドはキーバインドを割り当てるか、M-x
で検索して実行することができます。
個人で利用するコマンドはinit.el
とか.emacs
とかのファイルに雑に書いてやれば動きます。
Lispってどう書けばいいの
そもそもEmacsの設定もあまり馴れてない場合はEmacsを書く前のLisp - Qiitaを読んでください。
おてがるなコマンド
すごく簡単には、こんなEmacsコマンドを作るのはおてがるです。
- ファイル(ディレクトリ)を開く
- バッファに何かを入力する
- 何かをコピペする
- 外部コマンドを実行する
今日の記事では、一番下の「外部コマンドを実行する」以外の、いちばん簡単なパターンを紹介します。
ファイルを開く
Emacsでファイルをバッファとして開くのはfind-file
コマンドです。これは関数としても呼ぶことができます1。
これはふだんC-x C-fで利用するコマンドです。いつものC-x C-fは「1. ファイル名を検索(または新しく作成するファイル名を入力)して」「2. バッファを開く」の二段構成になってますが、実はfind-file
の本当の機能は「2. バッファを開く」の方です。
いつもお馴染みの「1. ファイル名を検索(または新しく作成するファイル名を入力)」を受け持つのは、実はread-file-name
関数です。これを利用すれば、いつもと同じ操作感でファイルを開くことができます。
特定のファイルを開く
init.el
を開くだけのコマンドです。
(defun my-find-file-init-el ()
"init.elを開く"
(interactive)
(find-file "~/.emacs.d/init.el"))
いちばん最初のサンプルにふさわしい簡単さですね。自分用のコマンドなんでものは、この程度の雑さで良いでしょう。
特定のディレクトリでファイルを開く
ふつうfind-file
は、編集中のバッファ(ファイル)のあるディレクトリ(具体的には変数default-directory
)のある場所から開かれますが、次のようなコマンドを定義することで、そのディレクトリからファイルを検索できます。
(defun my-find-file-temporary-file-directory (filename)
"ディレクトリ `temporary-file-directory' のファイルを開く"
(interactive
(list (read-file-name "Find files: " temporary-file-directory)))
(find-file filename))
コピペ
Emacsではコピペするには(kill-new)
関数が利用できます。なんか物騒な名前ですが、Emacs用語でざっくり切り取りしてクリップボードに入れるのこと2です。(kill-new)
の引数として文字列を渡してやれば、雑にコピペができます。
GUI版のEmacsであれば、基本的には特別な設定をしなくてもデフォルトでOSのクリップボードと同期されます。端末からEmacsを利用する場合も、うまく設定すればOSのクリップボードと同期できるようです。(Emacs と Mac のクリップボードを共有する | Engineering My Life)
バッファのファイルパスをコピペする
buffer-file-name
はバッファのディレクトリを含んだフルパス(など)が入った変数です。
(defun my-copy-buffer-name ()
"編集中のファイル名またはバッファ名をコピペする"
(kill-new (or buffer-file-name
(buffer-name))))
insert
(insert)
は現在のバッファに文字列を挿入する関数です。
現在時刻をインサートする
(format-time-string)
を組み合せます。
(defun my-insert-datetime-simple ()
"現在の日時を挿入する YYYY-mm-dd形式
http://ergoemacs.org/emacs/elisp_datetime.html"
(interactive)
(insert
(format-time-string "%Y-%m-%d %T")))
もうちょっと複雑にHTMLのdatetime形式の文字列を入力するには、こうします。
(defun my/insert-datetime-attr ()
"
http://ergoemacs.org/emacs/elisp_datetime.html"
(interactive)
(insert
" datetime=\""
(format-time-string "%Y-%m-%dT%T")
(let ((x (format-time-string "%z")))
(concat (substring x 0 3) ":" (substring x 3 5)))
"\""))
まとめ
複雑なコマンドを構築するには面倒なこともありますが、ちょっとしたことをするコマンドを組み立てるのは意外といけます。