はじめてのかんたんEmacsコマンド


これは「Emacs実践入門 出版記念イベント」で発表する内容です ヾ(〃><)ノ゙☆


お前誰よ

  • うさみけんた, @tadsan, Zonu.EXE
  • 会社ではPHPとかPHPとかPHPを書いてる
  • 前はRubyとかPythonとか書いてました
  • Emacs-JP, Slackとかに居ます
  • WEB+DB PRESSでPHPの記事とか書いてました
    • ほかでは読めない内容を結構書いたので
      バックナンバーおすすめ


Emacsでは

  • 20個ほどパッケージを公開してる
  • Qiitaにたまに何か書いてる
  • MELPAで新着のパッケージをウォッチしてる
  • 最近PHP Modeのメンテナを引き継ぎました

パッケージって何

  • Emacsの関数・コマンド・マクロなどをひとまとめにしたもの
  • 以前はLispファイルをダウンロードして手作業で配置してた

コマンドって難しいんじゃないの

  • 巨大なパッケージはすごい(かなり)
  • @tadsanはあまり複雑なことはやってなくて、基本機能をシンプルに組み合せたものが多い
  • シンプルなコマンドは意外に簡単に作れる

最初におぼえること


ちょっとだけおぼえるLisp

; は行コメント

;; たしざん
(+ 1 2 3) ;=> 6

;; かけざん
(* 1 2 3) ;=> 6


比較

ほかの言語でのtruetfalsenilです。
(馴れるしかない用語)

(> 1 2)     ;=> nil
(equal 1 2) ;=> nil
(< 1 2)     ;=> t
(equal 1 1) ;=> t

比較関数いろいろあるけど、equalでok。


一時変数は let*

(let* ((name "ミク"))
  (message "こんにちは、%s" name))

let でも良いけど、基本は let* を使っておいた方が混乱しないです。


一時変数は let*

(let* ((name "ミク")
       (hour (string-to-int (format-time-string "%H"))))
  (message "こんにちは、%s。今は%d時です。" name hour))

もちろん複数の変数も作れるし、式も書けます。


setq で変数を上書きする

(let* ((name "ミク")
       (hour (string-to-int (format-time-string "%H"))))
  (if (>= hour 12)
      (setq name "リン"))
  (message "こんにちは、%s。今は%d時です。" name hour))

この場合はこう書いた方がいい

(let* ((hour (string-to-int (format-time-string "%H")))
       (name (if (>= hour 12)
                 "リン"
               "ミク")))
  (message "こんにちは、%s。今は%d時です。" name hour)

インデントはEmacsに頼る

キーボードのTABボタンを押すと、いい感じに整列してくれます。 No 自己流インデント🙅🏻


覚えておくと良い関数


format

C言語とかのsprintfみたいな感じで、文字列をフォーマットします。

(format "%s, %s" "こんにちは" name)

message

同じような感じだけど、メッセージを表示したいときに使います。

(message "%s, %s" "こんにちは" name)

kill-new

キルリングに入れる(要はクリップボードにコピペ)

(kill-new "こんにちは!")

insert

現在編集中のバッファに文字列を入力する

(insert "こんにちは!")

関数にしてみよう


最初に設定

init.el
(show-paren-mode 1)
(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)

↑ こんな設定をしておくと良い


雑に init.el に書いちゃえ

コマンドはただの関数

(defun my/insert-datetime ()
  "現在のdatetimeを挿入する"
  (interactive)
  (insert
   (format-time-string "%Y-%m-%d %T")))

知っておくと良い関数・変数


buffer-file-name

ファイル名が入ってる変数

(defun my/copy-file-name ()
  "いまのファイル名をコピペする"
  (if buffer-file-name
      (kill-new buffer-file-name)
    (user-error "ファイルが開かれてないよ")))

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))

(locate-dominating-file)

ディレクトリファイルを

(locate-dominating-file (f-dirname buffer-file-name) ".idea")

(read-file-name)

ファイル名を読み込む関数

(defun my/find-file-temporary-file-directory (filename)
  "`temporary-file-directory'."
  (interactive
   (list (read-file-name "Find files: " temporary-file-directory)))
  (find-file filename))