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 /quantum/process_keycode/process_terminal.c | |
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'
Diffstat (limited to 'quantum/process_keycode/process_terminal.c')
-rw-r--r-- | quantum/process_keycode/process_terminal.c | 125 |
1 files changed, 111 insertions, 14 deletions
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 | } |