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 8ec2ca503a1907510cffe2195f1a20f52bdc4aaf

WIP: Add keywords search mode
Author: Tomas Babej
Author date (UTC): 2014-10-04 08:10
Committer name: Tomas Babej
Committer date (UTC): 2014-10-04 08:12
Parent(s): 796556dae00fc397686cb573cd5d0488536ba4a0
Signing key:
Tree: 6e8666cbee3741cf33755049ad8b628e90ebb92d
File Lines added Lines deleted
src/hstr.c 59 4
File src/hstr.c changed (mode: 100644) (index 337fc13..821b1f0)
74 74 #define HH_CONFIG_CASE "casesensitive" #define HH_CONFIG_CASE "casesensitive"
75 75 #define HH_CONFIG_REGEXP "regexp" #define HH_CONFIG_REGEXP "regexp"
76 76 #define HH_CONFIG_SUBSTRING "substring" #define HH_CONFIG_SUBSTRING "substring"
77 #define HH_CONFIG_KEYWORDS "keywords"
77 78 #define HH_CONFIG_SORTING "rawhistory" #define HH_CONFIG_SORTING "rawhistory"
78 79 #define HH_CONFIG_FAVORITES "favorites" #define HH_CONFIG_FAVORITES "favorites"
79 80 #define HH_CONFIG_DEBUG "debug" #define HH_CONFIG_DEBUG "debug"
 
88 89 #define HH_VIEW_FAVORITES 2 #define HH_VIEW_FAVORITES 2
89 90
90 91 #define HH_MATCH_SUBSTRING 0 #define HH_MATCH_SUBSTRING 0
91 #define HH_MATCH_REGEXP 1
92 #define HH_MATCH_REGEXP 1
93 #define HH_MATCH_KEYWORDS 2
94
95 #define HH_NUM_HISTORY_MATCH 3
92 96
93 97 #define HH_CASE_INSENSITIVE 0 #define HH_CASE_INSENSITIVE 0
94 98 #define HH_CASE_SENSITIVE 1 #define HH_CASE_SENSITIVE 1
 
113 117 #define LOGUTF8(Y,P) #define LOGUTF8(Y,P)
114 118 #endif #endif
115 119
120 void logstring(char* str){
121 FILE *f = fopen("/home/tbabej/hh.log", "a");
122 if (f == NULL)
123 {
124 perror("fopen");
125 printf("Error opening file!\n");
126 exit(1);
127 }
128 fprintf(f, "Debug: %s \n", str);
129 fclose(f);
130 }
131
116 132 static const char *HH_VIEW_LABELS[]={ static const char *HH_VIEW_LABELS[]={
117 133 "ranking", "ranking",
118 134 "history", "history",
 
... ... static const char *HH_VIEW_LABELS[]={
121 137
122 138 static const char *HH_MATCH_LABELS[]={ static const char *HH_MATCH_LABELS[]={
123 139 "exact", "exact",
124 "regexp"
140 "regexp",
141 "keywords"
125 142 }; };
126 143
127 144 static const char *HH_CASE_LABELS[]={ static const char *HH_CASE_LABELS[]={
 
... ... void hstr_get_env_configuration(Hstr *hstr)
235 252 } else { } else {
236 253 if(strstr(hstr_config,HH_CONFIG_SUBSTRING)) { if(strstr(hstr_config,HH_CONFIG_SUBSTRING)) {
237 254 hstr->historyMatch=HH_MATCH_SUBSTRING; hstr->historyMatch=HH_MATCH_SUBSTRING;
238 }
255 } else {
256 if(strstr(hstr_config, HH_CONFIG_KEYWORDS)) {
257 hstr->historyMatch=HH_MATCH_KEYWORDS;
258 }
259 }
239 260 } }
240 261 if(strstr(hstr_config,HH_CONFIG_SORTING)) { if(strstr(hstr_config,HH_CONFIG_SORTING)) {
241 262 hstr->historyView=HH_VIEW_HISTORY; hstr->historyView=HH_VIEW_HISTORY;
 
... ... unsigned hstr_make_selection(char *prefix, HistoryItems *history, int maxSelecti
431 452 regmatch_t regexpMatch; regmatch_t regexpMatch;
432 453 char regexpErrorMessage[CMDLINE_LNG]; char regexpErrorMessage[CMDLINE_LNG];
433 454 bool regexpCompilationError=false; bool regexpCompilationError=false;
455 bool keywordsAllMatch;
456 char *keywordsSavePtr;
457 char *keywordsToken;
458 char *keywordsParsedLine;
459 char *keywordsPointerToDelete;
434 460 for(i=0; i<count && selectionCount<maxSelectionCount; i++) { for(i=0; i<count && selectionCount<maxSelectionCount; i++) {
435 461 if(source[i]) { if(source[i]) {
436 462 if(!prefix || !strlen(prefix)) { if(!prefix || !strlen(prefix)) {
 
... ... unsigned hstr_make_selection(char *prefix, HistoryItems *history, int maxSelecti
465 491 } }
466 492 } }
467 493 break; break;
494 case HH_MATCH_KEYWORDS:
495 // TODO: differentiate between case-sensitive and insensitive
496 keywordsParsedLine = strdup(prefix);
497 keywordsAllMatch = true;
498 keywordsPointerToDelete = keywordsParsedLine;
499 while (true) {
500 keywordsToken = strtok_r(keywordsParsedLine, " ", &keywordsSavePtr);
501 keywordsParsedLine = NULL;
502 if (keywordsToken == NULL) {
503 break;
504 }
505
506 if (strcasestr(source[i], keywordsToken) == NULL) {
507 keywordsAllMatch = false;
508 }
509 }
510 if (keywordsAllMatch) {
511 hstr->selection[selectionCount++]=source[i];
512 }
513 free(keywordsPointerToDelete);
514 break;
468 515 } }
469 516 } }
470 517 } }
 
... ... unsigned hstr_make_selection(char *prefix, HistoryItems *history, int maxSelecti
493 540 case HH_MATCH_REGEXP: case HH_MATCH_REGEXP:
494 541 // all regexps matched previously - user decides whether match ^ or infix // all regexps matched previously - user decides whether match ^ or infix
495 542 break; break;
543 // case HH_MATCH_KEYWORDS:
544 // keywordsParsedLine =
545 //
546 // break;
496 547 } }
497 548 } }
498 549 } }
 
... ... void print_selection_row(char *text, int y, int width, char *pattern)
529 580 p=strstr(text, pattern); p=strstr(text, pattern);
530 581 mvprintw(y, 1+(p-text), "%s", pattern); mvprintw(y, 1+(p-text), "%s", pattern);
531 582 break; break;
583 case HH_MATCH_KEYWORDS:
584 p=strstr(text, pattern);
585 mvprintw(y, 1+(p-text), "%s", pattern);
586 break;
532 587 } }
533 588 color_attr_off(A_BOLD); color_attr_off(A_BOLD);
534 589 } }
 
... ... void loop_to_select(Hstr *hstr)
762 817 break; break;
763 818 case K_CTRL_E: case K_CTRL_E:
764 819 hstr->historyMatch++; hstr->historyMatch++;
765 hstr->historyMatch=hstr->historyMatch%2;
820 hstr->historyMatch=hstr->historyMatch%HH_NUM_HISTORY_MATCH;
766 821 // TODO make this a function // TODO make this a function
767 822 result=hstr_print_selection(maxHistoryItems, pattern, hstr); result=hstr_print_selection(maxHistoryItems, pattern, hstr);
768 823 print_history_label(hstr); print_history_label(hstr);
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