aboutsummaryrefslogtreecommitdiff
path: root/docs/ja/feature_macros.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/ja/feature_macros.md')
-rw-r--r--docs/ja/feature_macros.md303
1 files changed, 303 insertions, 0 deletions
diff --git a/docs/ja/feature_macros.md b/docs/ja/feature_macros.md
new file mode 100644
index 000000000..6371f0c20
--- /dev/null
+++ b/docs/ja/feature_macros.md
@@ -0,0 +1,303 @@
1# マクロ
2
3<!---
4 original document: 0.9.43:docs/feature_macros.md
5 git diff 0.9.43 HEAD -- docs/feature_macros.md | cat
6-->
7
8マクロにより、1つのキーを押すだけで複数のキーストロークを送信することができます。QMK にはマクロを定義し使う方法が幾つかあります。これらはなんでもすることができます: よく使うフレーズの入力、コピーペースト、反復的なゲームの動き、あるいはコードを書くことさえ手助けします。
9
10!> **セキュリティの注意**: マクロを使って、パスワード、クレジットカード番号、その他の機密情報のいずれも送信することが可能ですが、それは非常に悪い考えです。あなたのキーボードを手に入れた人は誰でもテキストエディタを開いてその情報にアクセスすることができます。
11
12## `SEND_STRING()` と `process_record_user`
13
14単語またはフレーズを入力するキーが欲しい時があります。最も一般的な状況のために `SEND_STRING()` を提供しています。これは文字列(つまり、文字のシーケンス)を入力します。簡単にキーコードに変換することができる全ての ASCII 文字がサポートされています (例えば、`qmk 123\n\t`)。
15
16以下は2キーのキーボードのための `keymap.c` の例です:
17
18```c
19enum custom_keycodes {
20 QMKBEST = SAFE_RANGE,
21};
22
23bool process_record_user(uint16_t keycode, keyrecord_t *record) {
24 switch (keycode) {
25 case QMKBEST:
26 if (record->event.pressed) {
27 // キーコード QMKBEST が押された時
28 SEND_STRING("QMK is the best thing ever!");
29 } else {
30 // キーコード QMKBEST が放された時
31 }
32 break;
33 }
34 return true;
35};
36
37const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
38 [0] = {
39 {QMKBEST, KC_ESC},
40 // ...
41 },
42};
43```
44
45ここで起きることは以下の通りです:
46最初に他のキーコードで使用されていない範囲で新しいカスタムキーコードを定義します。
47次に、`process_record_user` 関数を使います。これはキーが押されるか放されるたびに呼び出され、カスタムキーコードがアクティブかどうかを確認します。
48アクティブな場合、`SEND_STRING` マクロ (これは C プロセッサのマクロで、QMK のマクロと混同しないでください)を介して文字列 `"QMK is the best thing ever!"` をコンピュータに送信します。
49呼び出し元に、処理したばかりのキー押下を通常通り(機能を置き換えたり変更したりしなかったので)処理し続けるよう指示するため、`true` を返します。
50最後に、最初のボタンがマクロをアクティブにし、2番目のボタンが単なるエスケープボタンになるようにキーマップを定義します。
51
52複数のマクロを追加することもできます。
53以下のように、別のキーコードを追加し、switch 文に別の case ラベルを追加することで、それを行うことができます:
54
55```c
56enum custom_keycodes {
57 QMKBEST = SAFE_RANGE,
58 QMKURL,
59 MY_OTHER_MACRO,
60};
61
62bool process_record_user(uint16_t keycode, keyrecord_t *record) {
63 switch (keycode) {
64 case QMKBEST:
65 if (record->event.pressed) {
66 // キーコード QMKBEST が押された時
67 SEND_STRING("QMK is the best thing ever!");
68 } else {
69 // キーコード QMKBEST が放された時
70 }
71 break;
72
73 case QMKURL:
74 if (record->event.pressed) {
75 // キーコード QMKURL が押された場合
76 SEND_STRING("https://qmk.fm/\n");
77 } else {
78 // キーコード QMKURL が放された場合
79 }
80 break;
81
82 case MY_OTHER_MACRO:
83 if (record->event.pressed) {
84 SEND_STRING(SS_LCTL("ac")); // 全てを選択しコピーします
85 }
86 break;
87 }
88 return true;
89};
90
91const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
92 [0] = {
93 {MY_CUSTOM_MACRO, MY_OTHER_MACRO},
94 // ...
95 },
96};
97```
98
99### 高度なマクロ
100
101`process_record_user()` 関数のほかに、`post_process_record_user()` 関数があります。これは `process_record` の後に実行され、キーストロークが送信された後の処理に使用できます。これは例えば、通常のキーの前に押され、通常のキーの後で放されるキーがほしい場合に便利です。
102
103この例では、通常のキー入力を変更して、キーストロークが通常送信される前に `F22` が押されるようにし、キーが放された__後にのみ__ `F22` キーを放します。
104
105```c
106static uint8_t f22_tracker;
107
108bool process_record_user(uint16_t keycode, keyrecord_t *record) {
109 switch (keycode) {
110 case KC_A ... KC_F21: // F22 をスキップする方法に注意してください
111 case KC_F23 ... KC_EXSEL: //exsel は修飾キーの直前のキーです
112 if (record->event.pressed) {
113 register_code(KC_F22); //これは F22 を押したことを送信することを意味します
114 f22_tracker++;
115 register_code(keycode);
116 return false;
117 }
118 break;
119 }
120 return true;
121}
122
123void post_process_record_user(uint16_t keycode, keyrecord_t *record) {
124 switch (keycode) {
125 case KC_A ... KC_F21: // F22 をスキップする方法に注意してください
126 case KC_F23 ... KC_EXSEL: //exsel は修飾キーの直前のキーです
127 if (!record->event.pressed) {
128 f22_tracker--;
129 if (!f22_tracker) {
130 unregister_code(KC_F22); //これは F22 を放したことを送信することを意味します
131 }
132 }
133 break;
134 }
135}
136```
137
138
139### タップ、ダウン、アップ
140
141`Ctrl` あるいは `Home` など、ソースコードに文字列として表記できないキーをマクロで使うこともできます。
142以下のようにラップすることで任意のコードを送信することができます:
143
144* `SS_TAP()` キーを押して放します。
145* `SS_DOWN()` キーを押します (ただし、放しません)。
146* `SS_UP()` キーを放します。
147
148例えば:
149
150 SEND_STRING(SS_TAP(X_HOME));
151
152`KC_HOME` をタップします - プリフィックスが `X_` で `KC_` ではないことに注意してください。以下のように、他の文字列と組み合わせることもできます:
153
154 SEND_STRING("VE"SS_TAP(X_HOME)"LO");
155
156これは "VE" に続けて `KC_HOME` をタップ、そして "LO" (新しい行の場合は "LOVE" と綴る)を送信します。
157
158文字列に遅延を追加することもできます:
159
160* `SS_DELAY(msecs)` は指定されたミリ秒だけ遅らせます。
161
162例えば:
163
164 SEND_STRING("VE" SS_DELAY(1000) SS_TAP(X_HOME) "LO");
165
166これは "VE" 、1秒の遅延、`KC_HOME` をタップ、"LO" (新しい行の場合は "LOVE" と綴るが、中間に遅延がある) を送信します。
167
168使用できるモッドショートカットもいくつかあります:
169
170* `SS_LCTL(文字列)`
171* `SS_LSFT(文字列)`
172* `SS_LALT(文字列)`、`SS_LOPT(文字列)`
173* `SS_LGUI(文字列)`、`SS_LCMD(文字列)`、`SS_LWIN(文字列)`
174* `SS_RCTL(文字列)`
175* `SS_RSFT(文字列)`
176* `SS_RALT(文字列)`、`SS_ROPT(文字列)`、`SS_ALGR(文字列)`
177* `SS_RGUI(文字列)`、`SS_RCMD(文字列)`、`SS_RWIN(文字列)`
178
179これらはそれぞれの修飾キーを押し、指定された文字列を送信してから、修飾キーを解放します。
180それらは以下のように使うことができます:
181
182 SEND_STRING(SS_LCTL("a"));
183
184これは、左 Control +`a` (左 Control をダウンし、`a`、左 Control をアップ)を送信します - それらは文字列(例えば `"k"`)であり、`X_K` キーコードでは無いことに注意してください。
185
186### 代替キーマップ
187
188デフォルトでは、QWERTY レイアウトの US キーマップを想定しています; それを変更したい場合(例えば OS がソフトウェア Colemak を使う場合)、キーマップのどこかに以下を含めます:
189
190```c
191#include "sendstring_colemak.h"
192```
193
194### メモリ内の文字列
195
196何らかの理由で文字列を操作していて、(リテラル、文字列定数の代わりに)生成したばかりのものを出力する必要がある場合は、以下のように `send_string()` を使うことができます:
197
198```c
199char my_str[4] = "ok.";
200send_string(my_str);
201```
202
203上で定義したショートカットは `send_string()` では動作しないですが、必要に応じて別の行に分けることができます:
204
205```c
206char my_str[4] = "ok.";
207SEND_STRING("I said: ");
208send_string(my_str);
209SEND_STRING(".."SS_TAP(X_END));
210```
211
212
213## 高度なマクロ関数 :id=advanced-macro-functions
214
215マクロの生成に役立つ関数が幾つかあります。マクロの中にかなり高度なコードを書くことができますが、機能が複雑になりすぎる場合は、代わりにカスタムキーコードを定義することをお勧めします。マクロはシンプルにしなければなりません。
216
217?> 追加の機能として、[便利な関数](ja/ref_functions.md) の中で説明される関数を使うこともできます。例えば `reset_keyboard()` によりマクロの一部としてキーボードをリセットすることができます。
218
219### `record->event.pressed`
220
221これでスイッチが押されているか放されているかどうかをテストすることができます。以下が例です。
222
223```c
224 if (record->event.pressed) {
225 // キーダウン時
226 } else {
227 // キーアップ時
228 }
229```
230
231### `register_code(<kc>);`
232
233これはコンピュータに `<kc>` キーダウンイベントを送信します。例として `KC_ESC`、`KC_C`、`KC_4` や、`KC_LSFT` と `KC_LGUI` のような修飾キーなどもあります。
234
235### `unregister_code(<kc>);`
236
237`register_code` 関数と対応して、これは `<kc>` キーアップイベントをコンピュータに送信します。これを使わない場合、キーは送信されるまで押し続けられます。
238
239### `tap_code(<kc>);`
240
241これは `register_code(<kc>)` を送信し、その後 `unregister_code(<kc>)` を送信します。押下とリリースイベントの両方を送信する場合に便利です (押し続けるのではなく、キーを"タップ"する)。
242
243タップの登録(解除)に問題がある場合、`config.h` ファイルで `#define TAP_CODE_DELAY 100` を設定することで、登録イベントと解除イベントの間に遅延を追加することができます。値はミリ秒です。
244
245### `register_code16(<kc>);`、`unregister_code16(<kc>);`、`tap_code16(<kc>);`
246
247これらの関数は対応する通常の関数と同様に機能しますが、修飾キーで修飾されたキーコードを使うことができます (Shift、Alt、Control、GUI を適用)。
248
249例えば、修飾キーを押して(`register_code()`して)、キーコードを押す(`register_code()`する)代わりに、`register_code16(S(KC_5));` を使うことができます。
250
251### `clear_keyboard();`
252
253これは現在押されている全ての修飾キーとキーをクリアします。
254
255### `clear_mods();`
256
257これは現在押されている全ての修飾キーをクリアします。
258
259### `clear_keyboard_but_mods();`
260
261これは現在押されている修飾キー以外の全てのキーをクリアします。
262
263## 高度な例:
264
265### スーパー ALT↯TAB
266
267このマクロは `KC_LALT` を登録し、`KC_TAB` をタップして、1000ms 待ちます。キーが再度タップされると、別の `KC_TAB` が送信されます; タップが無い場合、`KC_LALT` が登録解除され、ウィンドウを切り替えることができます。
268
269```c
270bool is_alt_tab_active = false; // keymap.c の先頭付近にこれを追加します
271uint16_t alt_tab_timer = 0; // すぐにそれらを使います
272
273enum custom_keycodes { // 素晴らしいキーコードを用意してください
274 ALT_TAB = SAFE_RANGE,
275};
276
277bool process_record_user(uint16_t keycode, keyrecord_t *record) {
278 switch (keycode) { // これはキーコードを利用したつまらない作業のほとんどを行います。
279 case ALT_TAB:
280 if (record->event.pressed) {
281 if (!is_alt_tab_active) {
282 is_alt_tab_active = true;
283 register_code(KC_LALT);
284 }
285 alt_tab_timer = timer_read();
286 register_code(KC_TAB);
287 } else {
288 unregister_code(KC_TAB);
289 }
290 break;
291 }
292 return true;
293}
294
295void matrix_scan_user(void) { // とても重要なタイマー
296 if (is_alt_tab_active) {
297 if (timer_elapsed(alt_tab_timer) > 1000) {
298 unregister_code(KC_LALT);
299 is_alt_tab_active = false;
300 }
301 }
302}
303```