xaizek / hstr (License: Apachev2) (since 2018-12-07)
Bash and Zsh shell history suggest box - easily view, navigate, search and manage your command history.
Commit 995ad9481fac2e0366b2d40df5b45464b2712177

Refactoring tests.
Author: Martin Dvorak
Author date (UTC): 2014-01-17 21:28
Committer name: Martin Dvorak
Committer date (UTC): 2014-01-17 21:28
Parent(s): c7ff3d6783ded2367ae6cf45390ef11a80b1a982
Signing key:
Tree: 0690fa5ef0478763884b29c369b553193a18161a
File Lines added Lines deleted
src/hstr.c 129 111
tests/src/test_args.c 0 0
tests/src/test_hashset.c 0 0
tests/src/test_keyb.c 26 0
tests/test_args.sh 1 1
tests/test_hashset.sh 1 1
tests/test_keyb.c 0 36
tests/test_keyb.sh 1 0
File src/hstr.c changed (mode: 100644) (index 7b6156e..b6fcb75)
18 18 #include <string.h> #include <string.h>
19 19 #include <termios.h> #include <termios.h>
20 20 #include <unistd.h> #include <unistd.h>
21 #include <readline/chardefs.h>
21 22
22 23 #include "include/hashset.h" #include "include/hashset.h"
23 24 #include "include/hstr_utils.h" #include "include/hstr_utils.h"
 
33 34 #define Y_OFFSET_HISTORY 3 #define Y_OFFSET_HISTORY 3
34 35 #define Y_OFFSET_ITEMS 4 #define Y_OFFSET_ITEMS 4
35 36
37 #define K_ESC 91
38 #define K_ALT 27
39
36 40 #define K_CTRL_A 1 #define K_CTRL_A 1
37 41 #define K_CTRL_E 5 #define K_CTRL_E 5
42 #define K_CTRL_H 8
43 #define K_CTRL_I 9
38 44 #define K_CTRL_R 18 #define K_CTRL_R 18
39 45 #define K_CTRL_X 24 #define K_CTRL_X 24
40 #define K_CTRL_I 9
41 #define K_CTRL_H 8
42 #define K_ENTER 10
46
43 47 #define K_ARROW_LEFT 68 #define K_ARROW_LEFT 68
44 48 #define K_ARROW_RIGHT 67 #define K_ARROW_RIGHT 67
49 #define K_ARROW_UP 65
50 #define K_ARROW_DOWN 66
51
52 #define K_ENTER 10
45 53 #define K_BACKSPACE 127 #define K_BACKSPACE 127
46 #define K_UP 65
47 #define K_DOWN 66
48 54
55 #define DEBUG_KEYS
49 56 #ifdef DEBUG_KEYS #ifdef DEBUG_KEYS
50 #define LOGKEYS(Y,KEY) mvprintw(Y, 0, "Key number: '%3d' / Char: '%c'", KEY, KEY)
57 #define LOGKEYS(Y,KEY, BRANCH) mvprintw(Y, 0, "%s Key number: '%3d' / Char: '%c'", BRANCH, KEY, KEY)
51 58 #else #else
52 #define LOGKEYS(Y,KEY)
59 #define LOGKEYS(Y,KEY, BRANCH)
53 60 #endif #endif
54 61
55 62 #ifdef DEBUG_CURPOS #ifdef DEBUG_CURPOS
 
... ... char *selection_loop(HistoryItems *history)
330 337
331 338 initscr(); initscr();
332 339 color_start(); color_start();
333
334 340 color_init_pair(1, COLOR_WHITE, COLOR_BLACK); color_init_pair(1, COLOR_WHITE, COLOR_BLACK);
335 341 color_attr_on(COLOR_PAIR(1)); color_attr_on(COLOR_PAIR(1));
342
336 343 print_history_label(history); print_history_label(history);
337 344 print_help_label(); print_help_label();
338 345 print_selection(get_max_history_items(stdscr), NULL, history); print_selection(get_max_history_items(stdscr), NULL, history);
 
... ... char *selection_loop(HistoryItems *history)
361 368 } }
362 369 //echo(); //echo();
363 370
364 switch (c) {
365 case KEY_RESIZE:
366 print_history_label(history);
367 move(y, basex+strlen(prefix));
368 break;
369 case K_CTRL_A:
370 case K_CTRL_E:
371 case K_ARROW_LEFT:
372 case K_ARROW_RIGHT:
373 case 91: // TODO 91 killed > debug to determine how to distinguish \e and [
374 break;
375 case K_CTRL_R:
376 if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
377 delete=selection[selectionCursorPosition];
378 msg=malloc(strlen(delete)+1);
379 strcpy(msg,delete);
380 selection_remove(delete, history);
381 deleteOccurences=history_mgmt_remove(delete);
382 result = print_selection(maxHistoryItems, prefix, history);
383 print_cmd_deleted_label(msg, deleteOccurences);
384 move(y, basex+strlen(prefix));
385 }
386 print_history_label(history);
387 break;
388 case KEY_BACKSPACE:
389 case K_BACKSPACE:
390 if(strlen(prefix)>0) {
391 prefix[strlen(prefix)-1]=0;
392 x--;
393 wattron(stdscr,A_BOLD);
394 mvprintw(y, basex, "%s", prefix);
395 wattroff(stdscr,A_BOLD);
396 clrtoeol();
397 }
371 if(c==K_ALT) {
372 continue;
373 }
398 374
399 if(strlen(prefix)>0) {
400 make_selection(prefix, history, maxHistoryItems);
401 } else {
402 make_selection(NULL, history, maxHistoryItems);
403 }
404 result = print_selection(maxHistoryItems, prefix, history);
405
406 move(y, basex+strlen(prefix));
407 break;
408 case KEY_UP:
409 case K_UP:
410 previousSelectionCursorPosition=selectionCursorPosition;
411 if(selectionCursorPosition>0) {
412 selectionCursorPosition--;
413 } else {
414 selectionCursorPosition=selectionSize-1;
415 }
416 highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix);
417 move(y, basex+strlen(prefix));
418 break;
419 case KEY_DOWN:
420 case K_DOWN:
421 if(selectionCursorPosition==SELECTION_CURSOR_IN_PROMPT) {
422 selectionCursorPosition=previousSelectionCursorPosition=0;
423 } else {
424 previousSelectionCursorPosition=selectionCursorPosition;
425 if((selectionCursorPosition+1)<selectionSize) {
426 selectionCursorPosition++;
427 } else {
428 selectionCursorPosition=0;
375 if(CTRL_CHAR(c)) {
376 switch (c) {
377 case K_CTRL_R:
378 if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
379 delete=selection[selectionCursorPosition];
380 msg=malloc(strlen(delete)+1);
381 strcpy(msg,delete);
382 selection_remove(delete, history);
383 deleteOccurences=history_mgmt_remove(delete);
384 result = print_selection(maxHistoryItems, prefix, history);
385 print_cmd_deleted_label(msg, deleteOccurences);
386 move(y, basex+strlen(prefix));
429 387 } }
388 print_history_label(history);
389 break;
390 case K_CTRL_I:
391 caseSensitive=!caseSensitive;
392 result = print_selection(maxHistoryItems, prefix, history);
393 print_history_label(history);
394 break;
395 case K_CTRL_H:
396 defaultOrder=!defaultOrder;
397 result = print_selection(maxHistoryItems, prefix, history);
398 print_history_label(history);
399 break;
400 case K_CTRL_X:
401 result = NULL;
402 done = TRUE;
403 break;
404 case KEY_ENTER:
405 case K_ENTER:
406 if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
407 result=selection[selectionCursorPosition];
408 alloc_selection(0);
409 }
410 done = TRUE;
411 break;
412 default:
413 LOGKEYS(Y_OFFSET_HELP, c, "CTRL");
414 // skip
415 break;
430 416 } }
431 highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix);
432 move(y, basex+strlen(prefix));
433 break;
434 case KEY_ENTER:
435 case K_ENTER:
436 if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
437 result=selection[selectionCursorPosition];
438 alloc_selection(0);
439 }
440 done = TRUE;
441 break;
442 case K_CTRL_I:
443 caseSensitive=!caseSensitive;
444 result = print_selection(maxHistoryItems, prefix, history);
445 print_history_label(history);
446 break;
447 case K_CTRL_H:
448 defaultOrder=!defaultOrder;
449 result = print_selection(maxHistoryItems, prefix, history);
450 print_history_label(history);
451 break;
452 case K_CTRL_X:
453 result = NULL;
454 done = TRUE;
455 break;
456 default:
457 LOGKEYS(Y_OFFSET_HELP,c);
458 LOGCURSOR(Y_OFFSET_HELP);
459
460 if(c!=27) {
461 selectionCursorPosition=SELECTION_CURSOR_IN_PROMPT;
462
463 if(strlen(prefix)<(width-basex-1)) {
464 strcat(prefix, (char*)(&c));
417 } else {
418 switch (c) {
419 case KEY_RESIZE:
420 print_history_label(history);
421 move(y, basex+strlen(prefix));
422 break;
423 case KEY_BACKSPACE:
424 case K_BACKSPACE:
425 if(strlen(prefix)>0) {
426 prefix[strlen(prefix)-1]=0;
427 x--;
465 428 wattron(stdscr,A_BOLD); wattron(stdscr,A_BOLD);
466 429 mvprintw(y, basex, "%s", prefix); mvprintw(y, basex, "%s", prefix);
467 cursorX=getcurx(stdscr);
468 cursorY=getcury(stdscr);
469 430 wattroff(stdscr,A_BOLD); wattroff(stdscr,A_BOLD);
470 431 clrtoeol(); clrtoeol();
471 432 } }
472 433
434 if(strlen(prefix)>0) {
435 make_selection(prefix, history, maxHistoryItems);
436 } else {
437 make_selection(NULL, history, maxHistoryItems);
438 }
473 439 result = print_selection(maxHistoryItems, prefix, history); result = print_selection(maxHistoryItems, prefix, history);
474 move(cursorY, cursorX);
475 refresh();
440
441 move(y, basex+strlen(prefix));
442 break;
443 case KEY_UP:
444 case K_ARROW_UP:
445 previousSelectionCursorPosition=selectionCursorPosition;
446 if(selectionCursorPosition>0) {
447 selectionCursorPosition--;
448 } else {
449 selectionCursorPosition=selectionSize-1;
450 }
451 highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix);
452 move(y, basex+strlen(prefix));
453 break;
454 case KEY_DOWN:
455 case K_ARROW_DOWN:
456 if(selectionCursorPosition==SELECTION_CURSOR_IN_PROMPT) {
457 selectionCursorPosition=previousSelectionCursorPosition=0;
458 } else {
459 previousSelectionCursorPosition=selectionCursorPosition;
460 if((selectionCursorPosition+1)<selectionSize) {
461 selectionCursorPosition++;
462 } else {
463 selectionCursorPosition=0;
464 }
465 }
466 highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix);
467 move(y, basex+strlen(prefix));
468 break;
469 case K_ESC:
470 case K_ARROW_LEFT:
471 case K_ARROW_RIGHT:
472 break;
473 default:
474 LOGKEYS(Y_OFFSET_HELP, c, "ASCII");
475 LOGCURSOR(Y_OFFSET_HELP);
476
477 if(c!=27) { // TODO remove
478 selectionCursorPosition=SELECTION_CURSOR_IN_PROMPT;
479
480 if(strlen(prefix)<(width-basex-1)) {
481 strcat(prefix, (char*)(&c));
482 wattron(stdscr,A_BOLD);
483 mvprintw(y, basex, "%s", prefix);
484 cursorX=getcurx(stdscr);
485 cursorY=getcury(stdscr);
486 wattroff(stdscr,A_BOLD);
487 clrtoeol();
488 }
489
490 result = print_selection(maxHistoryItems, prefix, history);
491 move(cursorY, cursorX);
492 refresh();
493 }
494 break;
476 495 } }
477 break;
478 496 } }
479 497 } }
480 498 endwin(); endwin();
File tests/src/test_args.c renamed from tests/test_args.c (similarity 100%)
File tests/src/test_hashset.c renamed from tests/test_hashset.c (similarity 100%)
File tests/src/test_keyb.c added (mode: 100644) (index 0000000..6594896)
1 /*
2 ============================================================================
3 Name : test_keyb.c
4 Author : martin.dvorak@midforger.com
5 Copyright : Apache 2.0
6 Description : A test
7 ============================================================================
8 */
9
10 #include <stdio.h>
11 #include <readline/readline.h>
12 #include <readline/chardefs.h>
13
14 int main(int argc, char *argv[])
15 {
16 int c;
17
18 // for(c=0; c<255; c++) {
19 // printf("Key number: '%3d' / Char: '%c' Meta: \n", c, c, c&meta_character_bit);
20 // }
21
22 while(1) {
23 c = getc(stdin);
24 printf("Key number: '%3d' / Char: '%c' Meta: %d Ctrl: %d Ctrl mask: %d\n", c, c, META_CHAR(c), CTRL_CHAR(c), c&control_character_mask);
25 }
26 }
File tests/test_args.sh changed (mode: 100755) (index 07059dd..2a800a4)
1 gcc test_args.c -o test_args
1 gcc ./src/test_args.c -o _args
File tests/test_hashset.sh changed (mode: 100755) (index 9059fe9..a7b363e)
1 gcc test_hashset.c ../src/hashset.c -o test_hashset
1 gcc ./src/test_hashset.c ../src/hashset.c -o _hashset
File tests/test_keyb.c deleted (index 9e7e00f..0000000)
1 /*
2 ============================================================================
3 Name : test_args.c
4 Author : martin.dvorak@midforger.com
5 Copyright : Apache 2.0
6 Description : A test
7 ============================================================================
8 */
9
10 #include <string.h>
11 #include <stdio.h>
12
13 #define LINELNG 500
14
15 int main(int argc, char *argv[])
16 {
17 if(argc>0) {
18 int i;
19 char line[LINELNG];
20 line[0]=0;
21 for(i=0; i<argc; i++) {
22 if((strlen(line)+strlen(argv[i])*2)>LINELNG) break;
23 printf("%d %s\n", i, argv[i]);
24 if(strstr(argv[i], " ")) {
25 strcat(line, "\"");
26 }
27 strcat(line, argv[i]);
28 if(strstr(argv[i], " ")) {
29 strcat(line, "\"");
30 }
31 strcat(line, " ");
32 }
33
34 printf("#%s#", line);
35 }
36 }
File tests/test_keyb.sh added (mode: 100755) (index 0000000..c6683c9)
1 gcc ./src/test_keyb.c -o _keyb
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/hstr

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/hstr

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master