# タップホールド設定オプション

<!---
  original document: 0.12.41:docs/tap_hold.md
  git diff 0.12.41 HEAD -- docs/tap_hold.md | cat
-->

タップホールドオプションは素晴らしいものですが、問題が無いわけではありません。デフォルト設定を適切なものにしようとしましたが、一部の人にとってまだ問題を引き起こすかもしれません。

次のオプションによりタップホールドキーの挙動を変更することができます。

## タッピング時間

以下の機能の全ての核心は、タッピング時間の設定です。これにより、何をタップとし、何をホールドとするかが決まります。これが自然に感じられるぴったりのタイミングは、キーボードごと、スイッチごと、あるいはキーごとに異ることもありえます。

`config.h` に以下の設定を追加することで、この時間を全体的に設定することができます:

```c
#define TAPPING_TERM 200
```

この設定はミリ秒で定義され、デフォルトは 200ms です。これは大多数の人にとっての適切な平均値です。

この機能をより細かく制御するために、以下を `config.h` に追加することができます:
```c
#define TAPPING_TERM_PER_KEY
```

そして、以下の関数をキーマップに追加します:

```c
uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case SFT_T(KC_SPC):
            return TAPPING_TERM + 1250;
        case LT(1, KC_GRV):
            return 130;
        default:
            return TAPPING_TERM;
    }
}
```


## 許容ホールド

[PR#1359](https://github.com/qmk/qmk_firmware/pull/1359/) 以降、新しい `config.h` オプションがあります:

```c
#define PERMISSIVE_HOLD
```

これは高速なタイピストや高い `TAPPING_TERM` 設定に対して、タップとホールドキー(モッドタップのような)の動作を向上させます。

モッドタップキーを押し、他のキーをタップ(押して放す)して、モッドタップキーを放すという動作の全てをタッピング時間内に行うと、両方のキーのタッピング機能が出力されます。

例えば:

- `SFT_T(KC_A)` を押す
- `KC_X` を押す
- `KC_X` を放す
- `SFT_T(KC_A)` を放す

通常、これら全てを `TAPPING_TERM` (デフォルト: 200ms) 内で行うと、ファームウェアとホストシステムによって `ax` として登録されます。許容ホールドを有効にすると、別のキーがタップされた場合にモッドタップキーを修飾キーと見なすように処理を変更し、 `X` (`SHIFT`+`x`)  と登録されます。

:::tip

`モッドタップ割り込みの無視`を有効にしている場合、これにより両方の動きが変更されます。通常のキーには、最初のキーが最初に放された場合、あるいは両方のキーが  `TAPPING_TERM` より長くホールドされた場合に、修飾キーが追加されます。

:::

この機能をより細かく制御するために、以下を `config.h` に追加することができます:

```c
#define PERMISSIVE_HOLD_PER_KEY
```

そして、以下の関数をキーマップに追加します:

```c
bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case LT(1, KC_BSPC):
            return true;
        default:
            return false;
    }
}
```

## モッドタップ割り込みの無視

この設定を有効にするには、これを `config.h` に追加してください:

```c
#define IGNORE_MOD_TAP_INTERRUPT
```

許容ホールドと同様に、これは高速なタイピストのためのファームウェアの処理方法を変更します。モッドタップキーを押し、他のキーを押し、モッドタップキーを放し、通常のキーを放すと、`TAPPING_TERM` 内で押された場合でも、通常はモッドと通常のキーが出力されます。これは、ローリングコンボキーや、頻繁に使用するキー(例えば、`RCTL_T(KC_QUOT)`)にモッドタップを使う高速なタイピストには望ましくない場合があります。

`モッドタップ割り込みの無視`を設定するには、両方のキーを `TAPPING_TERM` の間ホールドすると、(その修飾キーの)ホールド機能を実行する必要があります。

例えば:

- `SFT_T(KC_A)` を押す
- `KC_X` を押す
- `SFT_T(KC_A)` を放す
- `KC_X` を放す

通常、これは大文字の `X` (`SHIFT`+`x`)、またはモッド + キーを送信します。`モッドタップ割り込みの無視` を有効にすると、ホールドアクションを登録するには、両方のキーを `TAPPING_TERM` の間ホールドする必要があります。この場合、素早いタップは `ax` を送信しますが、両方をホールドすると、大文字の `X`  (`SHIFT`+`x`) を出力します。


:::tip

__注意__: これはモディファイアにのみ関係し、レイヤー切り替えキーには関係しません。

:::

:::tip

`許容ホールド`を有効にすると、これは両方がどのように動作するかを変更します。通常のキーには、最初のキーが最初に放された場合、あるいは両方のキーが  `TAPPING_TERM` より長くホールドされた場合に、修飾キーが追加されます。

:::

## タッピング強制ホールド

`タッピング強制ホールド` を有効にするには、以下を `config.h` に追加します:

```c
#define TAPPING_FORCE_HOLD
```

タップの後でユーザがキーをホールドすると、ホールド機能がアクティブになるのではなく、デフォルトでタッピング機能が繰り返されます。これにより、デュアルロールキーのタッピング機能を自動繰り返しする機能を維持することができます。`TAPPING_FORCE_HOLD` は、デュアルロールキーをタップした後ホールドした場合、ユーザがホールド機能をアクティブにする機能を削除します。

例:

- `SFT_T(KC_A)` を押す
- `SFT_T(KC_A)` を放す
- `SFT_T(KC_A)` を押す
- タッピング時間が終了するまで待ちます...
- `SFT_T(KC_A)` を放す

デフォルトの設定では、最初に放したときに `a` が送信され、2回目の押下で `a` が送信され、コンピュータに自動リピート機能を作動させることができます。

`TAPPING_FORCE_HOLD` を使うと、2回目の押下は Shift として解釈され、それをタップして使った後ですぐに修飾キーとして使うことができます。

:::caution

`TAPPING_FORCE_HOLD` はタッピングトグル(`TT` レイヤーキーコード、ワンショットタップトグルなど)を使うものをすべて破壊します。

:::

この機能をより細かく制御するために、以下を `config.h` に追加することができます:

```c
#define TAPPING_FORCE_HOLD_PER_KEY
```

そして、以下の関数をキーマップに追加します:

```c
bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case LT(1, KC_BSPC):
            return true;
        default:
            return false;
    }
}
```

## レトロタッピング

`レトロタッピング`を有効にするには、以下を `config.h` に追加してください:

```c
#define RETRO_TAPPING
```

他のキーを押さずにデュアルファンクションキーを押して放しても何も起こりません。レトロタッピングを有効にすると、他のキーを押さずにキーを放すと、元のキーコードがタッピング時間外であっても送信されます。

例えば、他のキーを押すことなく `LT(2, KC_SPACE)` を押したり放したりしても何も起こりません。これを有効にすると、代わりに `KC_SPACE` を送信します。

この機能をより細かく制御するために、以下を `config.h` に追加することができます:

```c
#define RETRO_TAPPING_PER_KEY
```

そして、以下の関数をキーマップに追加します:

```c
bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case LT(2, KC_SPACE):
            return true;
        default:
            return false;
    }
}
```

## キー別の関数にキーレコードを含めるのはなぜですか？

「キー別」の関数全てにキーレコードを含んでいることに気付いたかもしれません。そしてなぜそうしたのか不思議に思っているかもしれません。

まぁ、それは単純に本当にカスタマイズのためです。ただし、具体的には、それはキーボードの配線方法によって異なります。例えば、各行が実際にキーボードのマトリックスの1行を使っている場合、キーコード全体をチェックする代わりに、`if (record->event.row == 3)` を使うほうが簡単かもしれません。これは、ホームキー行でタップホールドタイプのキーを使っている人にとって特に便利です。そのため、通常のタイピングを妨げないように微調整することができるのではないでしょうか。

## `*_kb` や `*_user` 関数が無いのはなぜですか？

QMK にある他の多くの関数とは異なり、quantum あるいはキーボードレベルの関数を持つ必要はありません (または理由さえありません)。ここではユーザレベルの関数だけが有用なため、そのようにマークする必要はありません。
