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 d078fb02d99caf378e00020559ebb432c96870f5

Added history file management and fixed #9.
Author: Martin Dvorak
Author date (UTC): 2013-12-15 15:20
Committer name: Martin Dvorak
Committer date (UTC): 2013-12-15 15:20
Parent(s): a994222f43aafc309002326958432664419715fc
Signing key:
Tree: 6ebcba07060fbea5407de0ccdc415d425dfe35fb
File Lines added Lines deleted
src/hstr.c 21 4
src/hstr_history.c 9 9
src/hstr_utils.c 2 2
src/include/hstr_history.h 5 0
src/include/hstr_utils.h 2 1
File src/hstr.c changed (mode: 100644) (index 51b6058..0a16e41)
21 21 #include "include/hstr_history.h" #include "include/hstr_history.h"
22 22
23 23 #define LABEL_HISTORY " HISTORY " #define LABEL_HISTORY " HISTORY "
24 #define LABEL_HELP "Type to filter history, use UP and DOWN arrows to navigate, ENTER to select"
24 #define LABEL_HELP "Type to filter history, use UP and DOWN arrows to navigate, Ctrl-r to delete item, ENTER to select"
25 25 #define SELECTION_CURSOR_IN_PROMPT -1 #define SELECTION_CURSOR_IN_PROMPT -1
26 26
27 27 #define Y_OFFSET_PROMPT 0 #define Y_OFFSET_PROMPT 0
 
32 32 #define KEY_TERMINAL_RESIZE 410 #define KEY_TERMINAL_RESIZE 410
33 33 #define KEY_CTRL_A 1 #define KEY_CTRL_A 1
34 34 #define KEY_CTRL_E 5 #define KEY_CTRL_E 5
35 #define KEY_CTRL_R 18
35 36
36 37 #define MIN(a,b) (((a)<(b))?(a):(b)) #define MIN(a,b) (((a)<(b))?(a):(b))
37 38 #define MAX(a,b) (((a)>(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b))
 
... ... void print_help_label(WINDOW *win) {
70 71 refresh(); refresh();
71 72 } }
72 73
74 void print_cmd_deleted_label(WINDOW *win, char *cmd, int occurences) {
75 mvwprintw(win, Y_OFFSET_HELP, 0, "History item '%s' deleted (%d occurrences)", cmd, occurences);
76 clrtoeol();
77 refresh();
78 }
79
73 80 void print_history_label(WINDOW *win) { void print_history_label(WINDOW *win) {
74 81 char message[512]; char message[512];
75 82
 
... ... char *selection_loop(HistoryItems *history) {
216 223 int selectionCursorPosition=SELECTION_CURSOR_IN_PROMPT; int selectionCursorPosition=SELECTION_CURSOR_IN_PROMPT;
217 224 int previousSelectionCursorPosition=SELECTION_CURSOR_IN_PROMPT; int previousSelectionCursorPosition=SELECTION_CURSOR_IN_PROMPT;
218 225
219 int y = 1, c, maxHistoryItems, cursorX, cursorY;
226 int y = 1, c, maxHistoryItems, cursorX, cursorY, deleteOccurences;
220 227 bool done = FALSE; bool done = FALSE;
221 228 char prefix[500]=""; char prefix[500]="";
222 char *result="";
229 char *result="", *delete;
223 230 while (!done) { while (!done) {
224 231 maxHistoryItems=get_max_history_items(stdscr); maxHistoryItems=get_max_history_items(stdscr);
225 232
 
... ... char *selection_loop(HistoryItems *history) {
232 239 case KEY_CTRL_A: case KEY_CTRL_A:
233 240 case KEY_CTRL_E: case KEY_CTRL_E:
234 241 break; break;
242 case KEY_CTRL_R:
243 if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
244 delete=selection[selectionCursorPosition];
245 deleteOccurences=history_mgmt_remove(delete);
246 print_cmd_deleted_label(stdscr, delete, deleteOccurences);
247 move(y, basex+strlen(prefix));
248 }
249 break;
235 250 case 91: case 91:
236 251 // TODO 91 killed > debug to determine how to distinguish \e and [ // TODO 91 killed > debug to determine how to distinguish \e and [
237 252 break; break;
 
... ... char *selection_loop(HistoryItems *history) {
315 330
316 331 void hstr() { void hstr() {
317 332 HistoryItems *history=get_prioritized_history(); HistoryItems *history=get_prioritized_history();
333 history_mgmt_open();
318 334 char *command = selection_loop(history); char *command = selection_loop(history);
319 fill_terminal_input(command);
335 history_mgmt_close();
336 fill_terminal_input(command, true);
320 337 free_prioritized_history(); free_prioritized_history();
321 338 free_history_items(); free_history_items();
322 339 } }
File src/hstr_history.c changed (mode: 100644) (index c5b9d02..5ff24e3)
11 11 #include "include/hashset.h" #include "include/hashset.h"
12 12 #include "include/hashmap.h" #include "include/hashmap.h"
13 13 #include "include/radixsort.h" #include "include/radixsort.h"
14 #include <stdbool.h>
15 14
16 15 #include "include/hstr_utils.h" #include "include/hstr_utils.h"
17 16
 
... ... void history_mgmt_open() {
173 172 dirty=false; dirty=false;
174 173 } }
175 174
176 void history_mgmt_remove(char *cmd) {
177 get_history_items();
178
179 int offset=history_search_pos(cmd, 0, 0);
175 int history_mgmt_remove(char *cmd) {
176 int offset=history_search_pos(cmd, 0, 0), occurences=0;
180 177 while(offset>=0) { while(offset>=0) {
178 occurences++;
181 179 free_history_entry(remove_history(offset)); free_history_entry(remove_history(offset));
182 180 offset=history_search_pos(cmd, 0, ++offset); offset=history_search_pos(cmd, 0, ++offset);
183 181 } }
184
185 write_history(get_history_file_name());
186 dirty=true;
182 if(occurences) {
183 write_history(get_history_file_name());
184 dirty=true;
185 }
186 return occurences;
187 187 } }
188 188
189 189 void history_mgmt_close() { void history_mgmt_close() {
190 190 if(dirty) { if(dirty) {
191 fill_terminal_input("history -r\n");
191 fill_terminal_input("history -r\n", false);
192 192 } }
193 193 } }
File src/hstr_utils.c changed (mode: 100644) (index fb1bcb2..97d5032)
... ... void tiocsti() {
19 19 } }
20 20 } }
21 21
22 void fill_terminal_input(char *cmd){
22 void fill_terminal_input(char *cmd, bool padding){
23 23 size_t size = strlen(cmd); size_t size = strlen(cmd);
24 24 unsigned i; unsigned i;
25 25 char *c; char *c;
 
... ... void fill_terminal_input(char *cmd){
28 28 c=(cmd+i); c=(cmd+i);
29 29 ioctl(0, TIOCSTI, c); ioctl(0, TIOCSTI, c);
30 30 } }
31 printf("\n");
31 if(padding) printf("\n");
32 32 } }
33 33
34 34 void reverse_char_pointer_array(char **array, unsigned length) { void reverse_char_pointer_array(char **array, unsigned length) {
File src/include/hstr_history.h changed (mode: 100644) (index 198c2c9..00b8a1b)
16 16 #include <stdlib.h> #include <stdlib.h>
17 17 #include <readline/history.h> #include <readline/history.h>
18 18 #include <unistd.h> #include <unistd.h>
19 #include <stdbool.h>
19 20 #include "hstr_utils.h" #include "hstr_utils.h"
20 21
21 22 #define ENV_VAR_USER "USER" #define ENV_VAR_USER "USER"
 
... ... void free_history_items();
37 38 HistoryItems *prioritize_history(HistoryItems *historyFileItems); HistoryItems *prioritize_history(HistoryItems *historyFileItems);
38 39 void free_prioritized_history(); void free_prioritized_history();
39 40
41 void history_mgmt_open();
42 int history_mgmt_remove(char *cmd);
43 void history_mgmt_close();
44
40 45 #endif #endif
File src/include/hstr_utils.h changed (mode: 100644) (index 451f747..f887125)
14 14 #include <stdlib.h> #include <stdlib.h>
15 15 #include <string.h> #include <string.h>
16 16 #include <stdio.h> #include <stdio.h>
17 #include <stdbool.h>
17 18
18 19 void tiocsti(); void tiocsti();
19 void fill_terminal_input(char* cmd);
20 void fill_terminal_input(char* cmd, bool padding);
20 21 void reverse_char_pointer_array(char **array, unsigned length); void reverse_char_pointer_array(char **array, unsigned length);
21 22
22 23 #endif #endif
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