diff options
author | M1K <michael@m1k.me> | 2018-05-01 18:39:46 +0100 |
---|---|---|
committer | Jack Humbert <jack.humb@gmail.com> | 2018-05-01 13:39:46 -0400 |
commit | 5112af887ae59c9c54eabaec5c1ae2f5a53de180 (patch) | |
tree | b5ec0dfbc99af7eb3890e9e661aca7d57836fa89 | |
parent | f756b72167a573640d2427920603fa369c7949ae (diff) | |
download | qmk_firmware-5112af887ae59c9c54eabaec5c1ae2f5a53de180.tar.gz qmk_firmware-5112af887ae59c9c54eabaec5c1ae2f5a53de180.zip |
Added command history to terminal with other bug fixes, added new song to song_list.h (#2855)
* Implemented Terminal + added song to song_list.h
* Added wait() in order to prevent misbehaviour of 'command not found'
-rw-r--r-- | docs/feature_terminal.md | 31 | ||||
-rw-r--r-- | quantum/audio/song_list.h | 6 | ||||
-rw-r--r-- | quantum/process_keycode/process_terminal.c | 125 |
3 files changed, 146 insertions, 16 deletions
diff --git a/docs/feature_terminal.md b/docs/feature_terminal.md index 334a46c2d..1863599f8 100644 --- a/docs/feature_terminal.md +++ b/docs/feature_terminal.md | |||
@@ -14,12 +14,14 @@ When enabled, a `> ` prompt will appear, where you'll be able to type, backspace | |||
14 | 14 | ||
15 | `#define TERMINAL_HELP` enables some other output helpers that aren't really needed with this page. | 15 | `#define TERMINAL_HELP` enables some other output helpers that aren't really needed with this page. |
16 | 16 | ||
17 | Pressing "up" and "down" will allow you to cycle through the past 5 commands entered. | ||
18 | |||
17 | ## Future Ideas | 19 | ## Future Ideas |
18 | 20 | ||
19 | * Keyboard/user-extensible commands | 21 | * Keyboard/user-extensible commands |
20 | * Smaller footprint | 22 | * Smaller footprint |
21 | * Arrow key support | 23 | * Arrow key support |
22 | * Command history | 24 | * Command history - Done |
23 | * SD card support | 25 | * SD card support |
24 | * LCD support for buffer display | 26 | * LCD support for buffer display |
25 | * Keycode -> name string LUT | 27 | * Keycode -> name string LUT |
@@ -43,14 +45,39 @@ QMK Firmware | |||
43 | Built: 2017-08-29-20:24:44 | 45 | Built: 2017-08-29-20:24:44 |
44 | ``` | 46 | ``` |
45 | 47 | ||
48 | |||
49 | ### `print-buffer` | ||
50 | |||
51 | Outputs the last 5 commands entered | ||
52 | |||
53 | ``` | ||
54 | > print-buffer | ||
55 | 0. print-buffer | ||
56 | 1. help | ||
57 | 2. about | ||
58 | 3. keymap 0 | ||
59 | 4. help | ||
60 | 5. flush-buffer | ||
61 | ``` | ||
62 | |||
63 | ### `flush-buffer` | ||
64 | |||
65 | Clears command buffer | ||
66 | ``` | ||
67 | > flush-buffer | ||
68 | Buffer cleared! | ||
69 | ``` | ||
70 | |||
71 | |||
46 | ### `help` | 72 | ### `help` |
47 | 73 | ||
74 | |||
48 | Prints out the available commands: | 75 | Prints out the available commands: |
49 | 76 | ||
50 | ``` | 77 | ``` |
51 | > help | 78 | > help |
52 | commands available: | 79 | commands available: |
53 | about help keycode keymap exit | 80 | about help keycode keymap exit print-buffer flush-buffer |
54 | ``` | 81 | ``` |
55 | 82 | ||
56 | ### `keycode <layer> <row> <col>` | 83 | ### `keycode <layer> <row> <col>` |
diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h index a66c4d864..1ddcfb345 100644 --- a/quantum/audio/song_list.h +++ b/quantum/audio/song_list.h | |||
@@ -20,6 +20,12 @@ | |||
20 | 20 | ||
21 | #define NO_SOUND | 21 | #define NO_SOUND |
22 | 22 | ||
23 | #define LP_NUMB \ | ||
24 | H__NOTE(_CS5), H__NOTE(_E5), H__NOTE(_CS5), WD_NOTE(_FS5), \ | ||
25 | WD_NOTE(_A5), WD_NOTE(_GS5), WD_NOTE(_REST), H__NOTE(_CS5), H__NOTE(_E5), \ | ||
26 | H__NOTE(_CS5), WD_NOTE(_A5), WD_NOTE(_GS5), WD_NOTE(_E5), | ||
27 | |||
28 | |||
23 | #define ODE_TO_JOY \ | 29 | #define ODE_TO_JOY \ |
24 | Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ | 30 | Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ |
25 | Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ | 31 | Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ |
diff --git a/quantum/process_keycode/process_terminal.c b/quantum/process_keycode/process_terminal.c index deb1543e3..bc365dddf 100644 --- a/quantum/process_keycode/process_terminal.c +++ b/quantum/process_keycode/process_terminal.c | |||
@@ -20,10 +20,20 @@ | |||
20 | #include <stdio.h> | 20 | #include <stdio.h> |
21 | #include <math.h> | 21 | #include <math.h> |
22 | 22 | ||
23 | #ifndef CMD_BUFF_SIZE | ||
24 | #define CMD_BUFF_SIZE 5 | ||
25 | #endif | ||
26 | |||
27 | |||
23 | bool terminal_enabled = false; | 28 | bool terminal_enabled = false; |
24 | char buffer[80] = ""; | 29 | char buffer[80] = ""; |
30 | char cmd_buffer[CMD_BUFF_SIZE][80]; | ||
31 | bool cmd_buffer_enabled = true; //replace with ifdef? | ||
25 | char newline[2] = "\n"; | 32 | char newline[2] = "\n"; |
26 | char arguments[6][20]; | 33 | char arguments[6][20]; |
34 | bool firstTime = true; | ||
35 | |||
36 | short int current_cmd_buffer_pos = 0; //used for up/down arrows - keeps track of where you are in the command buffer | ||
27 | 37 | ||
28 | __attribute__ ((weak)) | 38 | __attribute__ ((weak)) |
29 | const char terminal_prompt[8] = "> "; | 39 | const char terminal_prompt[8] = "> "; |
@@ -34,36 +44,37 @@ const char terminal_prompt[8] = "> "; | |||
34 | #endif | 44 | #endif |
35 | float terminal_song[][2] = TERMINAL_SONG; | 45 | float terminal_song[][2] = TERMINAL_SONG; |
36 | #define TERMINAL_BELL() PLAY_SONG(terminal_song) | 46 | #define TERMINAL_BELL() PLAY_SONG(terminal_song) |
37 | #else | 47 | #else |
38 | #define TERMINAL_BELL() | 48 | #define TERMINAL_BELL() |
39 | #endif | 49 | #endif |
40 | 50 | ||
41 | __attribute__ ((weak)) | 51 | __attribute__ ((weak)) |
42 | const char keycode_to_ascii_lut[58] = { | 52 | const char keycode_to_ascii_lut[58] = { |
43 | 0, 0, 0, 0, | 53 | 0, 0, 0, 0, |
44 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', | 54 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
45 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', | 55 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', |
46 | '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0, '\t', | 56 | '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0, '\t', |
47 | ' ', '-', '=', '[', ']', '\\', 0, ';', '\'', '`', ',', '.', '/' | 57 | ' ', '-', '=', '[', ']', '\\', 0, ';', '\'', '`', ',', '.', '/' |
48 | }; | 58 | }; |
49 | 59 | ||
50 | __attribute__ ((weak)) | 60 | __attribute__ ((weak)) |
51 | const char shifted_keycode_to_ascii_lut[58] = { | 61 | const char shifted_keycode_to_ascii_lut[58] = { |
52 | 0, 0, 0, 0, | 62 | 0, 0, 0, 0, |
53 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', | 63 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', |
54 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', | 64 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', |
55 | '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', 0, 0, 0, '\t', | 65 | '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', 0, 0, 0, '\t', |
56 | ' ', '_', '+', '{', '}', '|', 0, ':', '\'', '~', '<', '>', '?' | 66 | ' ', '_', '+', '{', '}', '|', 0, ':', '\'', '~', '<', '>', '?' |
57 | }; | 67 | }; |
58 | 68 | ||
59 | struct stringcase { | 69 | struct stringcase { |
60 | char* string; | 70 | char* string; |
61 | void (*func)(void); | 71 | void (*func)(void); |
62 | } typedef stringcase; | 72 | } typedef stringcase; |
63 | 73 | ||
64 | void enable_terminal(void) { | 74 | void enable_terminal(void) { |
65 | terminal_enabled = true; | 75 | terminal_enabled = true; |
66 | strcpy(buffer, ""); | 76 | strcpy(buffer, ""); |
77 | memset(cmd_buffer,0,CMD_BUFF_SIZE * 80); | ||
67 | for (int i = 0; i < 6; i++) | 78 | for (int i = 0; i < 6; i++) |
68 | strcpy(arguments[i], ""); | 79 | strcpy(arguments[i], ""); |
69 | // select all text to start over | 80 | // select all text to start over |
@@ -73,6 +84,29 @@ void enable_terminal(void) { | |||
73 | 84 | ||
74 | void disable_terminal(void) { | 85 | void disable_terminal(void) { |
75 | terminal_enabled = false; | 86 | terminal_enabled = false; |
87 | SEND_STRING("\n"); | ||
88 | } | ||
89 | |||
90 | void push_to_cmd_buffer(void) { | ||
91 | if (cmd_buffer_enabled) { | ||
92 | if (cmd_buffer == NULL) { | ||
93 | return; | ||
94 | } else { | ||
95 | if (firstTime) { | ||
96 | firstTime = false; | ||
97 | strcpy(cmd_buffer[0],buffer); | ||
98 | return; | ||
99 | } | ||
100 | |||
101 | for (int i= CMD_BUFF_SIZE - 1;i > 0 ;--i) { | ||
102 | strncpy(cmd_buffer[i],cmd_buffer[i-1],80); | ||
103 | } | ||
104 | |||
105 | strcpy(cmd_buffer[0],buffer); | ||
106 | |||
107 | return; | ||
108 | } | ||
109 | } | ||
76 | } | 110 | } |
77 | 111 | ||
78 | void terminal_about(void) { | 112 | void terminal_about(void) { |
@@ -136,11 +170,34 @@ void terminal_keymap(void) { | |||
136 | } | 170 | } |
137 | } | 171 | } |
138 | 172 | ||
139 | stringcase terminal_cases[] = { | 173 | void print_cmd_buff(void) { |
174 | /* without the below wait, a race condition can occur wherein the | ||
175 | buffer can be printed before it has been fully moved */ | ||
176 | wait_ms(250); | ||
177 | for(int i=0;i<CMD_BUFF_SIZE;i++){ | ||
178 | char tmpChar = ' '; | ||
179 | itoa(i ,&tmpChar,10); | ||
180 | const char * tmpCnstCharStr = &tmpChar; //because sned_string wont take a normal char * | ||
181 | send_string(tmpCnstCharStr); | ||
182 | SEND_STRING(". "); | ||
183 | send_string(cmd_buffer[i]); | ||
184 | SEND_STRING("\n"); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | |||
189 | void flush_cmd_buffer(void) { | ||
190 | memset(cmd_buffer,0,CMD_BUFF_SIZE * 80); | ||
191 | SEND_STRING("Buffer Cleared!\n"); | ||
192 | } | ||
193 | |||
194 | stringcase terminal_cases[] = { | ||
140 | { "about", terminal_about }, | 195 | { "about", terminal_about }, |
141 | { "help", terminal_help }, | 196 | { "help", terminal_help }, |
142 | { "keycode", terminal_keycode }, | 197 | { "keycode", terminal_keycode }, |
143 | { "keymap", terminal_keymap }, | 198 | { "keymap", terminal_keymap }, |
199 | { "flush-buffer" , flush_cmd_buffer}, | ||
200 | { "print-buffer" , print_cmd_buff}, | ||
144 | { "exit", disable_terminal } | 201 | { "exit", disable_terminal } |
145 | }; | 202 | }; |
146 | 203 | ||
@@ -154,6 +211,7 @@ void terminal_help(void) { | |||
154 | } | 211 | } |
155 | 212 | ||
156 | void command_not_found(void) { | 213 | void command_not_found(void) { |
214 | wait_ms(50); //sometimes buffer isnt grabbed quick enough | ||
157 | SEND_STRING("command \""); | 215 | SEND_STRING("command \""); |
158 | send_string(buffer); | 216 | send_string(buffer); |
159 | SEND_STRING("\" not found\n"); | 217 | SEND_STRING("\" not found\n"); |
@@ -171,7 +229,7 @@ void process_terminal_command(void) { | |||
171 | pch = strtok(NULL, " "); | 229 | pch = strtok(NULL, " "); |
172 | i++; | 230 | i++; |
173 | } | 231 | } |
174 | 232 | ||
175 | bool command_found = false; | 233 | bool command_found = false; |
176 | for( stringcase* case_p = terminal_cases; case_p != terminal_cases + sizeof( terminal_cases ) / sizeof( terminal_cases[0] ); case_p++ ) { | 234 | for( stringcase* case_p = terminal_cases; case_p != terminal_cases + sizeof( terminal_cases ) / sizeof( terminal_cases[0] ); case_p++ ) { |
177 | if( 0 == strcmp( case_p->string, buffer ) ) { | 235 | if( 0 == strcmp( case_p->string, buffer ) ) { |
@@ -192,6 +250,16 @@ void process_terminal_command(void) { | |||
192 | send_string(terminal_prompt); | 250 | send_string(terminal_prompt); |
193 | } | 251 | } |
194 | } | 252 | } |
253 | void check_pos(void) { | ||
254 | if (current_cmd_buffer_pos >= CMD_BUFF_SIZE) { //if over the top, move it back down to the top of the buffer so you can climb back down... | ||
255 | current_cmd_buffer_pos = CMD_BUFF_SIZE - 1; | ||
256 | } else if (current_cmd_buffer_pos < 0) { //...and if you fall under the bottom of the buffer, reset back to 0 so you can climb back up | ||
257 | current_cmd_buffer_pos = 0; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | |||
262 | |||
195 | 263 | ||
196 | bool process_terminal(uint16_t keycode, keyrecord_t *record) { | 264 | bool process_terminal(uint16_t keycode, keyrecord_t *record) { |
197 | 265 | ||
@@ -210,6 +278,8 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) { | |||
210 | char char_to_add; | 278 | char char_to_add; |
211 | switch (keycode) { | 279 | switch (keycode) { |
212 | case KC_ENTER: | 280 | case KC_ENTER: |
281 | push_to_cmd_buffer(); | ||
282 | current_cmd_buffer_pos = 0; | ||
213 | process_terminal_command(); | 283 | process_terminal_command(); |
214 | return false; break; | 284 | return false; break; |
215 | case KC_ESC: | 285 | case KC_ESC: |
@@ -226,9 +296,36 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) { | |||
226 | return false; | 296 | return false; |
227 | } break; | 297 | } break; |
228 | case KC_LEFT: | 298 | case KC_LEFT: |
299 | return false; break; | ||
229 | case KC_RIGHT: | 300 | case KC_RIGHT: |
230 | case KC_UP: | 301 | return false; break; |
302 | case KC_UP: // 0 = recent | ||
303 | check_pos(); //check our current buffer position is valid | ||
304 | if (current_cmd_buffer_pos <= CMD_BUFF_SIZE - 1) { //once we get to the top, dont do anything | ||
305 | str_len = strlen(buffer); | ||
306 | for(int i= 0;i < str_len ;++i) { | ||
307 | send_string(SS_TAP(X_BSPACE)); //clear w/e is on the line already | ||
308 | //process_terminal(KC_BSPC,record); | ||
309 | } | ||
310 | strncpy(buffer,cmd_buffer[current_cmd_buffer_pos],80); | ||
311 | |||
312 | send_string(buffer); | ||
313 | ++current_cmd_buffer_pos; //get ready to access the above cmd if up/down is pressed again | ||
314 | } | ||
315 | return false; break; | ||
231 | case KC_DOWN: | 316 | case KC_DOWN: |
317 | check_pos(); | ||
318 | if (current_cmd_buffer_pos >= 0) { //once we get to the bottom, dont do anything | ||
319 | str_len = strlen(buffer); | ||
320 | for(int i= 0;i < str_len ;++i) { | ||
321 | send_string(SS_TAP(X_BSPACE)); //clear w/e is on the line already | ||
322 | //process_terminal(KC_BSPC,record); | ||
323 | } | ||
324 | strncpy(buffer,cmd_buffer[current_cmd_buffer_pos],79); | ||
325 | |||
326 | send_string(buffer); | ||
327 | --current_cmd_buffer_pos; //get ready to access the above cmd if down/up is pressed again | ||
328 | } | ||
232 | return false; break; | 329 | return false; break; |
233 | default: | 330 | default: |
234 | if (keycode <= 58) { | 331 | if (keycode <= 58) { |
@@ -240,7 +337,7 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) { | |||
240 | } | 337 | } |
241 | if (char_to_add != 0) { | 338 | if (char_to_add != 0) { |
242 | strncat(buffer, &char_to_add, 1); | 339 | strncat(buffer, &char_to_add, 1); |
243 | } | 340 | } |
244 | } break; | 341 | } break; |
245 | } | 342 | } |
246 | 343 | ||
@@ -249,4 +346,4 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) { | |||
249 | } | 346 | } |
250 | } | 347 | } |
251 | return true; | 348 | return true; |
252 | } \ No newline at end of file | 349 | } |