【zsh】zshのヒストリ関連の変数、オプションまとめ。おまけでfcコマンドについて

## はじめに

zshのHistory関連のオプションとかについてまとめてみた記事
ですが履歴展開については触れません
メモベースなのはご愛嬌

[man](http://zsh.sourceforge.net/Doc/Release/Options.html#History)

#### 本記事での用語

- **イベント**:memo:：履歴として積まれるコマンドライン群

- **履歴リスト**:closed_book:：メモリに記憶する履歴一覧

- **履歴ファイル**:file_cabinet: ：履歴一覧を保持するファイル

#### zshの仕様的な話

- デフォルトだと イベントは履歴ファイルに保存されない
- ファイルとして保持したい場合は `HISTFILE`および `SAVEHIST` を指定
- 履歴ファイルが存在する場合は、シェル起動時にファイルに保持している履歴が履歴リストに読み込まれる。また、セッション終了時に履歴リストの内容が履歴ファイルに書き込まれる



## ヒストリ関連の変数一覧 [:link:](http://zsh.sourceforge.net/Doc/Release/Parameters.html#Parameters-Used-By-The-Shell)

- `histchars`
  イベント呼び出し等に使用される3つの文字列。 `!` とかのこと。変えるな。

- `HISTFILE`
  履歴ファイルの保存先。
  設定なしの場合、ファイルとして保存されないよ。


- `HISTORY_IGNORE`
  履歴ファイルに保存したくない(除外したい)パターンを記述する。 履歴リストに登録したくない方は [こちら](https://qiita.com/sho-t/items/d44bfbc783db7ca278c0)


- `HISTSIZE`
  履歴リストに記憶しておくイベントの最大数。 デフォルトは30。
  シェル起動時に、履歴ファイルから読み込むイベントの最大数でもある。

- `SIZEHIST`
  履歴ファイルに保存するイベントの最大数。


## ヒストリ関連のオプション一覧 [:link:](http://zsh.sourceforge.net/Doc/Release/Options.html#History)

めっちゃある。  :bulb: がついているものは筆者がONにしてるオプション

- `APPEND_HISTORY` 
  zshのセッション終了時に、履歴ファイルを上書きするのではなく、追加する。
  デフォルトでONになってる。　

- `EXTENDED_HISTORY` :bulb:
  開始時刻(タイムスタンプ)、経過秒数がコマンドと一緒に履歴ファイルに保存される。

- `HIST_ALLOW_CLOBBER` :bulb: 
  リダイレクト`>` したとき、履歴上で `|>`置き換える。しんせつ！

- ` HIST_BEEP` 
  アクセスした履歴が存在しないときに、ビープ音を鳴らす。

- `HIST_EXPIRE_DUPS_FIRST`
  履歴リストのイベント数が上限(HISTSIZE)に達したときに、古いものではなく重複したイベントを削除する
  HIST_IGNORE_ALL_DUPS 設定してればいらない気。

- `HIST_FCNTL_LOCK` 
  よくわからんけど、ファイルロックに関する設定。man によるとパフォーマンスが向上するらしい。

- `HIST_FIND_NO_DUPS` :bulb: 
  ラインエディタでヒストリ検索するときに、一度見つかったものは後続で表示しない。

- `HIST_IGNORE_ALL_DUPS` :bulb: 
  履歴リスト登録時に、すでに同じものがあったら削除する。

- `HIST_IGNORE_DUPS` :bulb: 
  入力したコマンドが、直前のものと同じなら履歴リストに追加しない。
  HIST_IGNORE_ALL_DUPS を ONにしてたらいらない。

- `HIST_IGNORE_SPACE` :bulb: 
  行の先頭がスペースの場合は、履歴リストに追加しない。というか次のコマンド入力時に消去される。

- `HIST_LEX_WORDS`
  デフォルトで zshの履歴は空白で単語分割される。
  このオプションがONの場合は、通常のコマンドラインと同様の方法で分割される。
  らしい。 少し試しましたが違いがわからなかった。

- `HIST_NO_FUNCTIONS` :bulb: 
  関数定義のコマンドを履歴リストに追加しない。というか次の(ry

- `HIST_NO_STORE` :bulb: 
  ヒストリ参照コマンド`(fc -l, history) `を履歴リストに追加しない。 というか次の(ry

- `HIST_REDUCE_BLANKS` :bulb: 
  履歴リスト登録時に、コマンドライン中の余分なスペースを削除する

- `HIST_SAVE_NO_DUPS`
  履歴ファイルに書き込むとき、重複したイベントを削除する。

- `HIST_VERIFY` :bulb: 
  ヒストリ展開を利用するときに、直接実行しない。一旦コマンドライン上に展開される。
  ビビリなので ON安定

##### 以下の三つは それぞれ排他的な(同時にONにすべきじゃない)オプション

- `INC_APPEND_HISTORY`
  履歴リストにイベントを登録するのと同時に、履歴ファイルにも書き込みを行う(追加する)。

- `INC_APPEND_HISTORY_TIME`  :bulb: 
  コマンド終了時に、履歴ファイルに書き込む。
  つまりコマンドの経過時間が正しく記録される。
  逆に言うと `INC_APPEND_HISTORY` × `EXTENDED_HISTORY` の併用では**経過時間が全て0で記録される**

- `SHARE_HISTORY`
  各端末で履歴(ファイル)を共有する = 履歴ファイルに対して参照と書き込みを行う。
  書き込みは 時刻(タイムスタンプ) 付き。
  今までONにしてたが、よくよく考えるとあまりいいオプションじゃないかもしれない。

`HIST_SAVE_BY_COPY` もあるけど デフォルトONのオプションなので割愛

以下筆者の設定

```zsh:.zshrc
HISTFILE=~/.zsh_histfile
HISTORY_IGNORE="(cd|pwd|l[sal])"
HISTSIZE=10000
SAVEHIST=10000

setopt extended_history
setopt hist_allow_clobber
setopt hist_fcntl_lock
setopt hist_find_no_dups 
setopt hist_ignore_all_dups
setopt hist_ignore_dups
setopt hist_ignore_space
setopt hist_no_functions
setopt hist_no_store

setopt hist_reduce_blanks
setopt hist_save_no_dups
setopt hist_verify
setopt inc_append_history_time

```



## fc コマンド 

zsh の builtin command
履歴リストの参照、編集。履歴ファイルへの書き込み、読み込みが行える。
**色々 書いてますが、履歴リストの参照( `fc -l`) と 履歴ファイルの読み込み(`fc -R`) だけ知っておけばいい気がします。**


後続で紹介する `fc -RI` は、 `SHARE_HISTORY` オプションがOFFの場合に、別の端末の新しい履歴を参照したいときなんかに使用するといいです。

### 参照 :eye: 

**書式**

```zsh
fc -l [ -LI ] [ -nrdfEiD ] [ old=new ... ] [ first [ last ] ]
```

first , last には 文字列、またはイベント番号を指定できる。
イベント番号は数値が大きいほど新しい。負の値は相対指定になる。

```:例えば
1  → 一番古いコマンド
-3 → 3つ前のコマンドライン
```
lastのデフォルトは `最新のコマンドライン`
firstのデフォルトは -`16`

`fc -l` と打ってみると直近のコマンドが16件表示されるのはそゆこと。

よくある履歴全件は下記。~~**つーかこれしか用途ない**~~

```
fc -l 1
```



**オプション**

| Option        | 説明                                                         |
| ------------- | ------------------------------------------------------------ |
| -I (アイだよ) | ヒストリリストの内容のみを表示する                           |
| -L            | ローカルイベントのみを表示する。 `SHARE_HISTORY` ON時に使う  |
| -m            | first 部分にパターンの記述ができる。 endは指定できない       |
| -n            | イベント番号を表示しない                                     |
| -r            | 逆順に表示                                                   |
| -d            | コマンドラインが入力された時刻を表示する                     |
| -f            | コマンドラインが入力された時刻と日付を表示する。フォーマットは`MM/DD/YY hh:mm` |
| -E            | `-f`と同様。フォーマットが違う  `dd.mm.yyyy hh:mm`           |
| -i            | `-f`と同様。フォーマットが違う。 ISO8601 `yyyy-mm-dd hh:mm`  |
| -t *fmt*      | フォーマットを指定して日付、時刻を表示する                   |
| -D            | 経過時間=コマンドを入力してから終了するまでの時間を表示する  |


### 編集 :pencil: 


```zsh:書式
fc [ -e ename ] 
```
オプションは 参照と同じ

`-l` 無しの場合は、 履歴を編集して実行というアクションになる。
`-e` でエディタを指定できる。デフォルトは vi。

あんまり使わない。というかエディタ閉じると即時実行されちゃうのでビビる。


### 読み書き :writing_hand:

```zsh:書式
fc -ARWI [ filename ]
```

`-R` : 履歴リストの内容を履歴ファイルに読み込み。
`I`と併用した場合は、*履歴リストに無いもの* のみを読み込む。

`-W` : 履歴リストの内容を履歴ファイルに保存(上書き)する

`-A`：履歴リストの内容を履歴ファイルに保存(追加)する
`I` と併用した場合は最後に書き込み以降のコマンドラインを保存する。
 `HIST_SAVE_NO_DUPS` をONにしても `-I` がない場合は保存されちゃう(重複しちゃう)ので注意。

以上です。 マニアック！