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

これは「[Emacs実践入門 出版記念イベント](https://shibuya-el.connpass.com/event/66842/)」で発表する内容です ヾ(〃＞＜)ﾉﾞ☆

![@tadsan](https://qiita-image-store.s3.amazonaws.com/0/4121/profile-images/1473683797)

-----

## お前誰よ

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

-----

<img src="https://qiita-image-store.s3.amazonaws.com/0/4121/72fb1ce4-7cde-5a8f-ae6e-627bfddf0cec.jpeg">

-----

## Emacsでは

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

-----

## パッケージって何

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

-----

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

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

-----

## 最初におぼえること

-----

### ちょっとだけおぼえるLisp

`;` は行コメント

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

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

-----

![elisp-1.gif](https://qiita-image-store.s3.amazonaws.com/0/4121/cddfd122-d994-44a5-807e-50761a8bb7fc.gif)

-----

### 比較

ほかの言語での`true`は**`t`**、`false`は**`nil`**です。
(馴れるしかない用語)

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

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

-----

### 一時変数は `let*` 

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

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

-----

### 一時変数は `let*` 

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

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

-----

### `setq` で変数を上書きする

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

-----

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

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

-----

### インデントはEmacsに頼る

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

![elisp-2.gif](https://qiita-image-store.s3.amazonaws.com/0/4121/511efb5a-fdea-ae14-7f7d-a79ff15f8f90.gif)

-----

## 覚えておくと良い関数

-----

### `format`

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

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

-----

### `message`

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

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

-----

### `kill-new`

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

```el
(kill-new "こんにちは！")
```

-----

### `insert`

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

```el
(insert "こんにちは！")
```

----

## 関数にしてみよう

----

### 最初に設定


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

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

-----

### 雑に `init.el` に書いちゃえ

コマンドはただの関数

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

------

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


------

### `buffer-file-name`

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

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

------

### `default-directory`

現在のディレクトリ

```el
(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)`

ディレクトリファイルを

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

------

### `(read-file-name)`

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

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