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 069ad24822f9674b55d1d41f8d77c373fa9c4b62

Added CLI parameter to delete the last command from the history and thus fixed #251.
Author: Martin Dvorak
Author date (UTC): 2018-02-18 10:15
Committer name: Martin Dvorak
Committer date (UTC): 2018-02-18 10:15
Parent(s): 71e20a17b858cb388c80acde1469c680673052fd
Signing key:
Tree: e9e108ff20374dc730bc51b677588ca172365090
File Lines added Lines deleted
man/hh.1 3 0
src/hstr.c 9 1
src/hstr_history.c 27 6
src/include/hstr_history.h 7 6
File man/hh.1 changed (mode: 100644) (index ff0f0a5..9a80817)
... ... Show help
23 23 \fB-n --non-interactive\fR \fB-n --non-interactive\fR
24 24 Print filtered history on standard output and exit Print filtered history on standard output and exit
25 25 .TP .TP
26 \fB-k --kill-last-command\fR
27 Delete the last command from history and exit
28 .TP
26 29 \fB-f --favorites\fR \fB-f --favorites\fR
27 30 Show favorites view immediately Show favorites view immediately
28 31 .TP .TP
File src/hstr.c changed (mode: 100644) (index 1263ddd..c8bdd25)
... ... static const char *HELP_STRING=
234 234 "\nShell history suggest box:" "\nShell history suggest box:"
235 235 "\n" "\n"
236 236 "\n --favorites -f ... show favorites view" "\n --favorites -f ... show favorites view"
237 "\n --kill-last-command -k ... delete last command in history"
237 238 "\n --non-interactive -n ... print filtered history and exit" "\n --non-interactive -n ... print filtered history and exit"
238 239 "\n --show-configuration -s ... show configuration to be added to ~/.bashrc" "\n --show-configuration -s ... show configuration to be added to ~/.bashrc"
239 240 "\n --show-zsh-configuration -z ... show Zsh configuration to be added to ~/.zshrc" "\n --show-zsh-configuration -z ... show Zsh configuration to be added to ~/.zshrc"
 
... ... static const char *LABEL_HELP=
259 260
260 261 static const struct option long_options[] = { static const struct option long_options[] = {
261 262 {"favorites", GETOPT_NO_ARGUMENT, NULL, 'f'}, {"favorites", GETOPT_NO_ARGUMENT, NULL, 'f'},
263 {"kill-last-command", GETOPT_NO_ARGUMENT, NULL, 'k'},
262 264 {"version", GETOPT_NO_ARGUMENT, NULL, 'V'}, {"version", GETOPT_NO_ARGUMENT, NULL, 'V'},
263 265 {"help", GETOPT_NO_ARGUMENT, NULL, 'h'}, {"help", GETOPT_NO_ARGUMENT, NULL, 'h'},
264 266 {"non-interactive", GETOPT_NO_ARGUMENT, NULL, 'n'}, {"non-interactive", GETOPT_NO_ARGUMENT, NULL, 'n'},
 
... ... void hstr_main(Hstr *hstr)
1417 1419 void hstr_getopt(int argc, char **argv, Hstr *hstr) void hstr_getopt(int argc, char **argv, Hstr *hstr)
1418 1420 { {
1419 1421 int option_index = 0; int option_index = 0;
1420 int option = getopt_long(argc, argv, "fVhnszb", long_options, &option_index);
1422 int option = getopt_long(argc, argv, "fkVhnszb", long_options, &option_index);
1421 1423 if(option != -1) { if(option != -1) {
1422 1424 switch(option) { switch(option) {
1423 1425 case 'f': case 'f':
 
... ... void hstr_getopt(int argc, char **argv, Hstr *hstr)
1426 1428 case 'n': case 'n':
1427 1429 hstr->interactive=false; hstr->interactive=false;
1428 1430 break; break;
1431 case 'k':
1432 if(history_mgmt_remove_last_history_entry()) {
1433 exit(EXIT_SUCCESS);
1434 } else {
1435 exit(EXIT_FAILURE);
1436 }
1429 1437 case 'b': case 'b':
1430 1438 blacklist_load(&hstr->blacklist); blacklist_load(&hstr->blacklist);
1431 1439 blacklist_dump(&hstr->blacklist); blacklist_dump(&hstr->blacklist);
File src/hstr_history.c changed (mode: 100644) (index 1e01f35..3c1280f)
... ... unsigned history_ranking_function(unsigned rank, int newOccurenceOrder, size_t l
49 49 return metrics; return metrics;
50 50 } }
51 51
52 char *get_history_file_name()
52 char *get_history_file_name(void)
53 53 { {
54 54 char *historyFile=getenv(ENV_VAR_HISTFILE); char *historyFile=getenv(ENV_VAR_HISTFILE);
55 55 if(!historyFile || strlen(historyFile)==0) { if(!historyFile || strlen(historyFile)==0) {
 
... ... void dump_prioritized_history(HistoryItems *historyItems)
74 74 printf("\n"); fflush(stdout); printf("\n"); fflush(stdout);
75 75 } }
76 76
77 int get_item_offset()
77 int get_item_offset(void)
78 78 { {
79 79 if(isZshParentShell()) { if(isZshParentShell()) {
80 80 // In zsh history file, the format of item is // In zsh history file, the format of item is
 
... ... HistoryItems *get_prioritized_history(int optionBigKeys, HashSet *blacklist)
202 202 } }
203 203 } }
204 204
205 void free_prioritized_history()
205 void free_prioritized_history(void)
206 206 { {
207 207 free(prioritizedHistory->items); free(prioritizedHistory->items);
208 208 free(prioritizedHistory); free(prioritizedHistory);
209 209 } }
210 210
211 void history_mgmt_open()
211 void history_mgmt_open(void)
212 212 { {
213 213 dirty=false; dirty=false;
214 214 } }
215 215
216 void history_clear_dirty()
216 void history_clear_dirty(void)
217 217 { {
218 218 dirty=false; dirty=false;
219 219 } }
 
... ... int history_mgmt_remove_from_system_history(char *cmd)
263 263 return occurences; return occurences;
264 264 } }
265 265
266 bool history_mgmt_remove_last_history_entry()
267 {
268 using_history();
269
270 char *historyFile = get_history_file_name();
271 if(read_history(historyFile)!=0) {
272 fprintf(stderr, "\nUnable to read history file from '%s'!\n",historyFile);
273 exit(EXIT_FAILURE);
274 }
275 HISTORY_STATE *historyState=history_get_history_state();
276 // delete the last command + the command that was used to run HSTR
277 if(historyState->length > 1) {
278 // length is NOT updated on history entry removal
279 free_history_entry(remove_history(historyState->length-1));
280 free_history_entry(remove_history(historyState->length-2));
281 write_history(get_history_file_name());
282 return true;
283 }
284 return false;
285 }
286
266 287 int history_mgmt_remove_from_raw(char *cmd, HistoryItems *history) { int history_mgmt_remove_from_raw(char *cmd, HistoryItems *history) {
267 288 int occurences=history->rawCount; int occurences=history->rawCount;
268 289 if(history->rawCount) { if(history->rawCount) {
 
... ... int history_mgmt_remove_from_ranked(char *cmd, HistoryItems *history) {
291 312 return occurences-history->count; return occurences-history->count;
292 313 } }
293 314
294 void history_mgmt_flush()
315 void history_mgmt_flush(void)
295 316 { {
296 317 if(dirty) { if(dirty) {
297 318 fill_terminal_input("history -r\n", false); fill_terminal_input("history -r\n", false);
File src/include/hstr_history.h changed (mode: 100644) (index baac5f3..34c82e4)
... ... typedef struct {
51 51
52 52 HistoryItems *get_prioritized_history(int optionBigKeys, HashSet *blacklist); HistoryItems *get_prioritized_history(int optionBigKeys, HashSet *blacklist);
53 53
54 HistoryItems *get_history_items();
55 void free_history_items();
54 HistoryItems *get_history_items(void);
55 void free_history_items(void);
56 56
57 57 HistoryItems *prioritize_history(HistoryItems *historyFileItems); HistoryItems *prioritize_history(HistoryItems *historyFileItems);
58 void free_prioritized_history();
58 void free_prioritized_history(void);
59 59
60 void history_mgmt_open();
61 void history_clear_dirty();
60 void history_mgmt_open(void);
61 void history_clear_dirty(void);
62 62 int history_mgmt_remove_from_system_history(char *cmd); int history_mgmt_remove_from_system_history(char *cmd);
63 bool history_mgmt_remove_last_history_entry();
63 64 int history_mgmt_remove_from_raw(char *cmd, HistoryItems *history); int history_mgmt_remove_from_raw(char *cmd, HistoryItems *history);
64 65 int history_mgmt_remove_from_ranked(char *cmd, HistoryItems *history); int history_mgmt_remove_from_ranked(char *cmd, HistoryItems *history);
65 void history_mgmt_flush();
66 void history_mgmt_flush(void);
66 67
67 68 #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