aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorM1K <michael@m1k.me>2018-05-01 18:39:46 +0100
committerJack Humbert <jack.humb@gmail.com>2018-05-01 13:39:46 -0400
commit5112af887ae59c9c54eabaec5c1ae2f5a53de180 (patch)
treeb5ec0dfbc99af7eb3890e9e661aca7d57836fa89
parentf756b72167a573640d2427920603fa369c7949ae (diff)
downloadqmk_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.md31
-rw-r--r--quantum/audio/song_list.h6
-rw-r--r--quantum/process_keycode/process_terminal.c125
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
17Pressing "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
51Outputs the last 5 commands entered
52
53```
54> print-buffer
550. print-buffer
561. help
572. about
583. keymap 0
594. help
605. flush-buffer
61```
62
63### `flush-buffer`
64
65Clears command buffer
66```
67> flush-buffer
68Buffer cleared!
69```
70
71
46### `help` 72### `help`
47 73
74
48Prints out the available commands: 75Prints out the available commands:
49 76
50``` 77```
51> help 78> help
52commands available: 79commands 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
23bool terminal_enabled = false; 28bool terminal_enabled = false;
24char buffer[80] = ""; 29char buffer[80] = "";
30char cmd_buffer[CMD_BUFF_SIZE][80];
31bool cmd_buffer_enabled = true; //replace with ifdef?
25char newline[2] = "\n"; 32char newline[2] = "\n";
26char arguments[6][20]; 33char arguments[6][20];
34bool firstTime = true;
35
36short 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))
29const char terminal_prompt[8] = "> "; 39const 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))
42const char keycode_to_ascii_lut[58] = { 52const 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))
51const char shifted_keycode_to_ascii_lut[58] = { 61const 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
59struct stringcase { 69struct stringcase {
60 char* string; 70 char* string;
61 void (*func)(void); 71 void (*func)(void);
62} typedef stringcase; 72} typedef stringcase;
63 73
64void enable_terminal(void) { 74void 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
74void disable_terminal(void) { 85void disable_terminal(void) {
75 terminal_enabled = false; 86 terminal_enabled = false;
87 SEND_STRING("\n");
88}
89
90void push_to_cmd_buffer(void) {
91if (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
78void terminal_about(void) { 112void terminal_about(void) {
@@ -136,11 +170,34 @@ void terminal_keymap(void) {
136 } 170 }
137} 171}
138 172
139stringcase terminal_cases[] = { 173void 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
189void flush_cmd_buffer(void) {
190 memset(cmd_buffer,0,CMD_BUFF_SIZE * 80);
191 SEND_STRING("Buffer Cleared!\n");
192}
193
194stringcase 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
156void command_not_found(void) { 213void 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}
253void 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
196bool process_terminal(uint16_t keycode, keyrecord_t *record) { 264bool 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}