mirror of
https://github.com/dvorka/hstr.git
synced 2024-12-28 18:50:54 +08:00
Merging favorites branch - command favorites are comming ;)
This commit is contained in:
commit
f995ecdc1d
9 changed files with 395 additions and 48 deletions
|
@ -172,6 +172,14 @@ make search case sensitive (insensitive by default):
|
|||
```bash
|
||||
export HH_CONFIG=casesensitive
|
||||
```
|
||||
show warnings:
|
||||
```bash
|
||||
export HH_CONFIG=warning
|
||||
```
|
||||
show debug messages:
|
||||
```bash
|
||||
export HH_CONFIG=warning
|
||||
```
|
||||
more colors and case sensitive search:
|
||||
```bash
|
||||
export HH_CONFIG=hicolor,casesensitive
|
||||
|
|
35
man/hh.1
35
man/hh.1
|
@ -9,19 +9,24 @@ uses shell history to provide suggest box like functionality
|
|||
for commands used in the past. By default it parses .bash-history
|
||||
file that is filtered as you type a command substring. Commands
|
||||
are not just filtered, but also ordered by a ranking algorithm
|
||||
that considers number of occurences, length and timestamp. In addition
|
||||
hh allows removal of commands from history - for instance with a typo or with a sensitive content.
|
||||
that considers number of occurences, length and timestamp.
|
||||
Favorite and frequently used commands can be bookmarked. In addition
|
||||
hh allows removal of commands from history - for instance with a typo
|
||||
or with a sensitive content.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB--show-configuration\fR
|
||||
Show configuration that can be added to .bashrc
|
||||
.TP
|
||||
\fB--help\fR
|
||||
Show help
|
||||
.TP
|
||||
\fB--favorites\fR
|
||||
Show favorites view immediately
|
||||
.TP
|
||||
\fB--show-configuration\fR
|
||||
Show configuration that can be added to ~/.bashrc
|
||||
.TP
|
||||
\fB--version\fR
|
||||
Show version information
|
||||
.SH COMMANDS
|
||||
.SH KEYS
|
||||
.TP
|
||||
\fBpattern\fR
|
||||
Type to filter shell history.
|
||||
|
@ -30,7 +35,7 @@ Type to filter shell history.
|
|||
Toggle case sensitive search.
|
||||
.TP
|
||||
\fBCtrl\-/\fR
|
||||
Toggle history as provided by shell vs. ranked history ordered by the number of occurences, length and timestamp.
|
||||
Rotate view of history as provided by BASH, ranked history ordered by the number of occurences/length/timestamp and favorites.
|
||||
.TP
|
||||
\fBCtrl\-l\fR
|
||||
Make search pattern lowercase or uppercase.
|
||||
|
@ -68,14 +73,26 @@ Configuration options:
|
|||
Get more colors with this option (default is monochromatic).
|
||||
|
||||
\fIcasesensitive\fR
|
||||
Make the pattern-based filtering case sensitive by default.
|
||||
Make the pattern-based filtering case sensitive (it's case insensitive by default).
|
||||
|
||||
\fIrawhistory\fR
|
||||
Show normal history by default (default is metric-based).
|
||||
Show normal history as a default view (metric-based view is shown otherwise).
|
||||
|
||||
\fIfavorites\fR
|
||||
Show favorites as a default view (metric-based view is shown otherwise).
|
||||
|
||||
\fIwarning\fR
|
||||
Show warning.
|
||||
|
||||
\fIdebug\fR
|
||||
Show debug information.
|
||||
|
||||
Example:
|
||||
\fBexport HH_CONFIG=casesensitive,hicolor\fR
|
||||
|
||||
.SH FILES
|
||||
\fB~/.hh_favorites\fR bookmarked favorite commands
|
||||
|
||||
.SH CONFIGURATION
|
||||
Optionally add the following lines to ~/.bashrc:
|
||||
.nf
|
||||
|
|
140
src/hstr.c
140
src/hstr.c
|
@ -38,6 +38,7 @@
|
|||
|
||||
#define K_CTRL_A 1
|
||||
#define K_CTRL_E 5
|
||||
#define K_CTRL_F 6
|
||||
#define K_CTRL_G 7
|
||||
#define K_CTRL_H 8
|
||||
#define K_CTRL_L 12
|
||||
|
@ -60,10 +61,21 @@
|
|||
#define HH_COLOR_PROMPT 3
|
||||
#define HH_COLOR_DELETE 4
|
||||
|
||||
#define ENV_VAR_HH_CONFIG "HH_CONFIG"
|
||||
#define HH_ENV_VAR_CONFIG "HH_CONFIG"
|
||||
#define HH_CONFIG_HICOLOR "hicolor"
|
||||
#define HH_CONFIG_CASE "casesensitive"
|
||||
#define HH_CONFIG_SORTING "rawhistory"
|
||||
#define HH_CONFIG_FAVORITES "favorites"
|
||||
#define HH_CONFIG_DEBUG "debug"
|
||||
#define HH_CONFIG_WARN "warning"
|
||||
|
||||
#define HH_DEBUG_LEVEL_NONE 0
|
||||
#define HH_DEBUG_LEVEL_WARN 1
|
||||
#define HH_DEBUG_LEVEL_DEBUG 2
|
||||
|
||||
#define HH_VIEW_RANKING 0
|
||||
#define HH_VIEW_HISTORY 1
|
||||
#define HH_VIEW_FAVORITES 2
|
||||
|
||||
#define SPACE_PADDING " "
|
||||
|
||||
|
@ -79,6 +91,11 @@
|
|||
#define LOGCURSOR(Y)
|
||||
#endif
|
||||
|
||||
static const char *HH_VIEW_LABELS[]={
|
||||
"ranking",
|
||||
"history",
|
||||
"favorites"};
|
||||
|
||||
static const char *INSTALL_STRING=
|
||||
"\n# add this configuration to ~/.bashrc"
|
||||
"\nexport HH_CONFIG=hicolor # get more colors"
|
||||
|
@ -95,7 +112,8 @@ static const char *HELP_STRING=
|
|||
"Usage: hh [option] [arg1] [arg2]..."
|
||||
"\nShell history suggest box:"
|
||||
"\n"
|
||||
"\n --show-configuration ... show configuration to be added to .bashrc"
|
||||
"\n --favorites -f ... show command favorites"
|
||||
"\n --show-configuration ... show configuration to be added to ~/.bashrc"
|
||||
"\n --help ... display this help and exit"
|
||||
"\n"
|
||||
"\nReport bugs to martin.dvorak@mindforger.com"
|
||||
|
@ -108,19 +126,20 @@ static const char *VERSION_STRING=
|
|||
"\n";
|
||||
|
||||
static const char *LABEL_HELP=
|
||||
"Type to filter, UP/DOWN to move, DEL to remove, TAB to select, C-g to cancel";
|
||||
"Type to filter, UP/DOWN move, DEL remove, TAB select, C-f add favorite, C-g cancel";
|
||||
|
||||
static char **selection=NULL;
|
||||
static unsigned selectionSize=0;
|
||||
static bool caseSensitive=FALSE;
|
||||
static bool defaultOrder=FALSE;
|
||||
static int historyView=HH_VIEW_RANKING;
|
||||
static bool hicolor=FALSE;
|
||||
static int debugLevel=0;
|
||||
static char screenLine[CMDLINE_LNG];
|
||||
static char cmdline[CMDLINE_LNG];
|
||||
|
||||
void get_env_configuration()
|
||||
{
|
||||
char *hhconfig=getenv(ENV_VAR_HH_CONFIG);
|
||||
char *hhconfig=getenv(HH_ENV_VAR_CONFIG);
|
||||
if(hhconfig && strlen(hhconfig)>0) {
|
||||
if(strstr(hhconfig,HH_CONFIG_HICOLOR)) {
|
||||
hicolor=TRUE;
|
||||
|
@ -129,7 +148,18 @@ void get_env_configuration()
|
|||
caseSensitive=TRUE;
|
||||
}
|
||||
if(strstr(hhconfig,HH_CONFIG_SORTING)) {
|
||||
defaultOrder=TRUE;
|
||||
historyView=HH_VIEW_HISTORY;
|
||||
} else {
|
||||
if(strstr(hhconfig,HH_CONFIG_FAVORITES)) {
|
||||
historyView=HH_VIEW_FAVORITES;
|
||||
}
|
||||
}
|
||||
if(strstr(hhconfig,HH_CONFIG_DEBUG)) {
|
||||
debugLevel=HH_DEBUG_LEVEL_DEBUG;
|
||||
} else {
|
||||
if(strstr(hhconfig,HH_CONFIG_WARN)) {
|
||||
debugLevel=HH_DEBUG_LEVEL_WARN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,12 +211,28 @@ void print_cmd_deleted_label(char *cmd, int occurences)
|
|||
refresh();
|
||||
}
|
||||
|
||||
void print_cmd_added_favorite_label(char *cmd)
|
||||
{
|
||||
snprintf(screenLine, getmaxx(stdscr), "Command '%s' added to favorites (C-/ to show favorites)", cmd);
|
||||
if(hicolor) {
|
||||
color_attr_on(COLOR_PAIR(4));
|
||||
color_attr_on(A_BOLD);
|
||||
}
|
||||
mvprintw(Y_OFFSET_HELP, 0, screenLine);
|
||||
if(hicolor) {
|
||||
color_attr_off(A_BOLD);
|
||||
color_attr_on(COLOR_PAIR(1));
|
||||
}
|
||||
clrtoeol();
|
||||
refresh();
|
||||
}
|
||||
|
||||
void print_history_label(HistoryItems *history)
|
||||
{
|
||||
int width=getmaxx(stdscr);
|
||||
snprintf(screenLine, width, "- HISTORY - case:%s (C-t) - order:%s (C-/) - %d/%d ",
|
||||
snprintf(screenLine, width, "- HISTORY - match:%s (C-t) - view:%s (C-/) - %d/%d ",
|
||||
(caseSensitive?"sensitive":"insensitive"),
|
||||
(defaultOrder?"history":"ranking"),
|
||||
HH_VIEW_LABELS[historyView],
|
||||
history->count,
|
||||
history->rawCount);
|
||||
width -= strlen(screenLine);
|
||||
|
@ -241,8 +287,23 @@ unsigned make_selection(char *prefix, HistoryItems *history, int maxSelectionCou
|
|||
realloc_selection(sizeof(char*) * maxSelectionCount);
|
||||
|
||||
unsigned i, selectionCount=0;
|
||||
char **source=(defaultOrder?history->raw:history->items);
|
||||
unsigned count=(defaultOrder?history->rawCount:history->count);
|
||||
char **source;
|
||||
unsigned count;
|
||||
|
||||
switch(historyView) {
|
||||
case HH_VIEW_RANKING:
|
||||
source=history->items;
|
||||
count=history->count;
|
||||
break;
|
||||
case HH_VIEW_HISTORY:
|
||||
source=history->raw;
|
||||
count=history->rawCount;
|
||||
break;
|
||||
case HH_VIEW_FAVORITES:
|
||||
source=history->favorites->items;
|
||||
count=history->favorites->count;
|
||||
break;
|
||||
}
|
||||
|
||||
for(i=0; i<count && selectionCount<maxSelectionCount; i++) {
|
||||
if(source[i]) {
|
||||
|
@ -369,15 +430,19 @@ void highlight_selection(int selectionCursorPosition, int previousSelectionCurso
|
|||
|
||||
void selection_remove(char *cmd, HistoryItems *history)
|
||||
{
|
||||
if(history->count) {
|
||||
int i, w;
|
||||
for(i=0, w=0; i<history->count; i++) {
|
||||
if(strcmp(history->items[i], cmd)) {
|
||||
history->items[w]=history->items[i];
|
||||
w++;
|
||||
if(historyView==HH_VIEW_FAVORITES) {
|
||||
favorites_remove(history->favorites, cmd);
|
||||
} else {
|
||||
if(history->count) {
|
||||
int i, w;
|
||||
for(i=0, w=0; i<history->count; i++) {
|
||||
if(strcmp(history->items[i], cmd)) {
|
||||
history->items[w]=history->items[i];
|
||||
w++;
|
||||
}
|
||||
}
|
||||
history->count=w;
|
||||
}
|
||||
history->count=w;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -396,6 +461,15 @@ void signal_callback_handler_ctrl_c(int signum)
|
|||
}
|
||||
}
|
||||
|
||||
int seletion_source_remove(char* delete, HistoryItems *history)
|
||||
{
|
||||
if(historyView!=HH_VIEW_FAVORITES) {
|
||||
return history_mgmt_remove(delete);
|
||||
} else {
|
||||
return favorites_remove(history->favorites, delete);
|
||||
}
|
||||
}
|
||||
|
||||
void loop_to_select(HistoryItems *history)
|
||||
{
|
||||
signal(SIGINT, signal_callback_handler_ctrl_c);
|
||||
|
@ -417,7 +491,7 @@ void loop_to_select(HistoryItems *history)
|
|||
print_selection(get_max_history_items(stdscr), NULL, history);
|
||||
color_attr_off(COLOR_PAIR(HH_COLOR_NORMAL));
|
||||
|
||||
bool done=FALSE, skip=TRUE, executeResult=FALSE, lowercase=TRUE, justDeleted=FALSE;
|
||||
bool done=FALSE, skip=TRUE, executeResult=FALSE, lowercase=TRUE, printDefaultLabel=FALSE;
|
||||
int basex=print_prompt(stdscr);
|
||||
int x=basex, y=0, c, cursorX=0, cursorY=0, maxHistoryItems, deleteOccurences;
|
||||
int width=getmaxx(stdscr);
|
||||
|
@ -446,9 +520,9 @@ void loop_to_select(HistoryItems *history)
|
|||
continue;
|
||||
}
|
||||
|
||||
if(justDeleted) {
|
||||
if(printDefaultLabel) {
|
||||
print_help_label();
|
||||
justDeleted=FALSE;
|
||||
printDefaultLabel=FALSE;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
|
@ -458,11 +532,11 @@ void loop_to_select(HistoryItems *history)
|
|||
msg=malloc(strlen(delete)+1);
|
||||
strcpy(msg,delete);
|
||||
selection_remove(delete, history);
|
||||
deleteOccurences=history_mgmt_remove(delete);
|
||||
deleteOccurences=seletion_source_remove(delete, history);
|
||||
result=print_selection(maxHistoryItems, pattern, history);
|
||||
print_cmd_deleted_label(msg, deleteOccurences);
|
||||
move(y, basex+strlen(pattern));
|
||||
justDeleted=TRUE;
|
||||
printDefaultLabel=TRUE;
|
||||
}
|
||||
print_history_label(history);
|
||||
break;
|
||||
|
@ -473,11 +547,26 @@ void loop_to_select(HistoryItems *history)
|
|||
selectionCursorPosition=0;
|
||||
break;
|
||||
case K_CTRL_SLASH:
|
||||
defaultOrder=!defaultOrder;
|
||||
historyView=(++historyView)%3;
|
||||
result=print_selection(maxHistoryItems, pattern, history);
|
||||
print_history_label(history);
|
||||
selectionCursorPosition=0;
|
||||
break;
|
||||
case K_CTRL_F:
|
||||
if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) {
|
||||
result=selection[selectionCursorPosition];
|
||||
|
||||
if(historyView==HH_VIEW_FAVORITES) {
|
||||
favorites_choose(history->favorites, result);
|
||||
} else {
|
||||
favorites_add(history->favorites, result);
|
||||
print_cmd_added_favorite_label(result);
|
||||
printDefaultLabel=TRUE;
|
||||
}
|
||||
result=print_selection(maxHistoryItems, pattern, history);
|
||||
selectionCursorPosition=0;
|
||||
}
|
||||
break;
|
||||
case KEY_RESIZE:
|
||||
print_history_label(history);
|
||||
result=print_selection(maxHistoryItems, pattern, history);
|
||||
|
@ -618,7 +707,6 @@ void hstr()
|
|||
HistoryItems *history=get_prioritized_history();
|
||||
if(history) {
|
||||
history_mgmt_open();
|
||||
get_env_configuration();
|
||||
loop_to_select(history);
|
||||
hstr_on_exit();
|
||||
} else {
|
||||
|
@ -628,8 +716,12 @@ void hstr()
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
get_env_configuration();
|
||||
if(argc>0) {
|
||||
if(argc==2) {
|
||||
if(strstr(argv[1], "--favorites") || strstr(argv[1], "-f")) {
|
||||
historyView=HH_VIEW_FAVORITES;
|
||||
}
|
||||
if(strstr(argv[1], "--show-configuration")) {
|
||||
printf("%s", INSTALL_STRING);
|
||||
return EXIT_SUCCESS;
|
||||
|
|
178
src/hstr_favorites.c
Normal file
178
src/hstr_favorites.c
Normal file
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
============================================================================
|
||||
Name : hstr_favorites.c
|
||||
Author : martin.dvorak@midforger.com
|
||||
Copyright : Apache 2.0
|
||||
Description : Favorite commands.
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "include/hstr_favorites.h"
|
||||
|
||||
#define FAVORITE_SEGMENT_SIZE 10
|
||||
|
||||
void favorites_init(FavoriteItems *favorites)
|
||||
{
|
||||
favorites->items=NULL;
|
||||
favorites->count=0;
|
||||
favorites->loaded=false;
|
||||
}
|
||||
|
||||
char* favorites_get_filename()
|
||||
{
|
||||
char *home = getenv(ENV_VAR_HOME);
|
||||
char *fileName = (char*) malloc(strlen(home) + 1 + strlen(FILE_HH_RC) + 1);
|
||||
strcpy(fileName, home);
|
||||
strcat(fileName, "/");
|
||||
strcat(fileName, FILE_HH_RC);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
void favorites_get(FavoriteItems *favorites)
|
||||
{
|
||||
if(!favorites->loaded) {
|
||||
char* fileName = favorites_get_filename();
|
||||
char *file_contents=NULL;
|
||||
if(access(fileName, F_OK) != -1) {
|
||||
long input_file_size;
|
||||
|
||||
FILE *input_file = fopen(fileName, "rb");
|
||||
fseek(input_file, 0, SEEK_END);
|
||||
input_file_size = ftell(input_file);
|
||||
rewind(input_file);
|
||||
file_contents = malloc((input_file_size + 1) * (sizeof(char)));
|
||||
if(fread(file_contents, sizeof(char), input_file_size, input_file)==-1) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(input_file);
|
||||
file_contents[input_file_size] = 0;
|
||||
|
||||
if(file_contents && strlen(file_contents)) {
|
||||
favorites->count = 0;
|
||||
char *p=strchr(file_contents,'\n');
|
||||
while (p!=NULL) {
|
||||
favorites->count++;
|
||||
p=strchr(p+1,'\n');
|
||||
}
|
||||
|
||||
favorites->items = malloc(sizeof(char*) * favorites->count);
|
||||
int i = 0;
|
||||
char *pb=file_contents, *pe;
|
||||
pe=strchr(file_contents, '\n');
|
||||
while(pe!=NULL) {
|
||||
favorites->items[i]=pb;
|
||||
*pe=0;
|
||||
favorites->items[i]=strdup(pb);
|
||||
pb=pe+1;
|
||||
pe=strchr(pb, '\n');
|
||||
i++;
|
||||
}
|
||||
free(file_contents);
|
||||
}
|
||||
} else {
|
||||
// favorites file not found > favorites don't exist yet
|
||||
favorites->loaded=true;
|
||||
return;
|
||||
}
|
||||
free(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void favorites_save(FavoriteItems *favorites)
|
||||
{
|
||||
char *fileName=favorites_get_filename();
|
||||
|
||||
if(favorites->count) {
|
||||
FILE *output_file = fopen(fileName, "wb");
|
||||
rewind(output_file);
|
||||
int i;
|
||||
for(i=0; i<favorites->count; i++) {
|
||||
if(fwrite(favorites->items[i], sizeof(char), strlen(favorites->items[i]), output_file)==-1) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(fwrite("\n", sizeof(char), strlen("\n"), output_file)==-1) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
fclose(output_file);
|
||||
} else {
|
||||
if(access(fileName, F_OK) != -1) {
|
||||
FILE *output_file = fopen(fileName, "wb");
|
||||
fclose(output_file);
|
||||
}
|
||||
}
|
||||
|
||||
free(fileName);
|
||||
}
|
||||
|
||||
void favorites_add(FavoriteItems *favorites, char *newFavorite)
|
||||
{
|
||||
if(favorites->count) {
|
||||
favorites->items=realloc(favorites->items, sizeof(char *) * ++favorites->count);
|
||||
favorites->items[favorites->count-1]=strdup(newFavorite);
|
||||
favorites_choose(favorites, newFavorite);
|
||||
} else {
|
||||
favorites->items=malloc(sizeof(char*));
|
||||
favorites->items[0]=strdup(newFavorite);
|
||||
favorites->count=1;
|
||||
}
|
||||
|
||||
favorites_save(favorites);
|
||||
}
|
||||
|
||||
void favorites_choose(FavoriteItems *favorites, char *choice)
|
||||
{
|
||||
if(favorites->count && choice) {
|
||||
int i;
|
||||
char *b=0, *next;
|
||||
for(i=0; i<favorites->count; i++) {
|
||||
if(!strcmp(favorites->items[i],choice)) {
|
||||
favorites->items[0]=favorites->items[i];
|
||||
if(b) {
|
||||
favorites->items[i]=b;
|
||||
}
|
||||
return;
|
||||
}
|
||||
next=favorites->items[i];
|
||||
favorites->items[i]=b;
|
||||
b=next;
|
||||
}
|
||||
}
|
||||
favorites_save(favorites);
|
||||
}
|
||||
|
||||
bool favorites_remove(FavoriteItems *favorites, char *almostDead)
|
||||
{
|
||||
if(favorites->count) {
|
||||
int i, j;
|
||||
for(i=0, j=0; i<favorites->count && j<favorites->count; i++, j++) {
|
||||
if(!strcmp(favorites->items[i], almostDead)) {
|
||||
j=i+1;
|
||||
favorites->count--;
|
||||
} else {
|
||||
if(j>i) {
|
||||
favorites->items[i]=favorites->items[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
favorites_save(favorites);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void favorites_destroy(FavoriteItems *favorites)
|
||||
{
|
||||
if(favorites) {
|
||||
int i;
|
||||
for(i=0; i<favorites->count; i++) {
|
||||
free(favorites->items[i]);
|
||||
}
|
||||
free(favorites);
|
||||
}
|
||||
}
|
|
@ -47,8 +47,8 @@ char *get_history_file_name()
|
|||
char *historyFile=getenv(ENV_VAR_HISTFILE);
|
||||
if(!historyFile || strlen(historyFile)==0) {
|
||||
char *home = getenv(ENV_VAR_HOME);
|
||||
historyFile = malloc(strlen(home) + 1 + strlen(DEFAULT_HISTORY_FILE) + 1);
|
||||
strcat(strcat(strcpy(historyFile, home), "/"), DEFAULT_HISTORY_FILE);
|
||||
historyFile = malloc(strlen(home) + 1 + strlen(FILE_DEFAULT_HISTORY) + 1);
|
||||
strcat(strcat(strcpy(historyFile, home), "/"), FILE_DEFAULT_HISTORY);
|
||||
}
|
||||
return historyFile;
|
||||
}
|
||||
|
@ -150,6 +150,13 @@ HistoryItems *get_prioritized_history()
|
|||
|
||||
radixsort_destroy(&rs);
|
||||
|
||||
|
||||
FavoriteItems *favoriteItems=malloc(sizeof(FavoriteItems));
|
||||
favorites_init(favoriteItems);
|
||||
// TODO make favorites loading lazy > github issue
|
||||
favorites_get(favoriteItems);
|
||||
prioritizedHistory->favorites=favoriteItems;
|
||||
|
||||
return prioritizedHistory;
|
||||
} else {
|
||||
return NULL;
|
||||
|
@ -159,6 +166,7 @@ HistoryItems *get_prioritized_history()
|
|||
void free_prioritized_history()
|
||||
{
|
||||
free(prioritizedHistory->items);
|
||||
favorites_destroy(prioritizedHistory->favorites);
|
||||
free(prioritizedHistory);
|
||||
}
|
||||
|
||||
|
|
33
src/include/hstr_favorites.h
Normal file
33
src/include/hstr_favorites.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
============================================================================
|
||||
Name : hstr_favorites.h
|
||||
Author : martin.dvorak@midforger.com
|
||||
Copyright : Apache 2.0
|
||||
Description : Favorite commands.
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#ifndef _HSTR_FAVORITES_H_
|
||||
#define _HSTR_FAVORITES_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ENV_VAR_USER "USER"
|
||||
#define ENV_VAR_HOME "HOME"
|
||||
|
||||
#define FILE_HH_RC ".hh_favorites"
|
||||
|
||||
typedef struct {
|
||||
char **items;
|
||||
unsigned count;
|
||||
bool loaded;
|
||||
} FavoriteItems;
|
||||
|
||||
void favorites_init(FavoriteItems *favorites);
|
||||
void favorites_get(FavoriteItems *favorites);
|
||||
void favorites_add(FavoriteItems *favorites, char *favorite);
|
||||
void favorites_choose(FavoriteItems *favorites, char *choice);
|
||||
bool favorites_remove(FavoriteItems *favorites, char *almostDead);
|
||||
void favorites_destroy(FavoriteItems *favorites);
|
||||
|
||||
#endif
|
|
@ -17,21 +17,21 @@
|
|||
#include <readline/history.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include "hstr_favorites.h"
|
||||
#include "hstr_utils.h"
|
||||
#include "hashset.h"
|
||||
#include "radixsort.h"
|
||||
|
||||
#define ENV_VAR_USER "USER"
|
||||
#define ENV_VAR_HOME "HOME"
|
||||
#define ENV_VAR_HISTFILE "HISTFILE"
|
||||
|
||||
#define DEFAULT_HISTORY_FILE ".bash_history"
|
||||
#define FILE_DEFAULT_HISTORY ".bash_history"
|
||||
|
||||
typedef struct {
|
||||
char **items;
|
||||
char **raw;
|
||||
unsigned count;
|
||||
char **raw;
|
||||
unsigned rawCount;
|
||||
FavoriteItems *favorites;
|
||||
} HistoryItems;
|
||||
|
||||
HistoryItems *get_prioritized_history();
|
||||
|
|
|
@ -17,7 +17,11 @@
|
|||
#include <stddef.h>
|
||||
#include "hstr_utils.h"
|
||||
|
||||
#define SLOT_SIZE 1000
|
||||
#define RADIX_SLOT_SIZE 1000
|
||||
|
||||
#define RADIX_DEBUG_LEVEL_NONE 0
|
||||
#define RADIX_DEBUG_LEVEL_WARN 1
|
||||
#define RADIX_DEBUG_LEVEL_DEBUG 2
|
||||
|
||||
typedef struct radixitem {
|
||||
unsigned key;
|
||||
|
@ -43,9 +47,11 @@ typedef struct {
|
|||
RadixSlot **_slotDescriptors;
|
||||
unsigned _slotsCount;
|
||||
unsigned _topIndexLimit;
|
||||
unsigned _debug;
|
||||
} RadixSorter;
|
||||
|
||||
void radixsort_init(RadixSorter *rs, unsigned keyLimit);
|
||||
void radixsort_set_debug_level(RadixSorter *rs, unsigned debugLevel);
|
||||
void radixsort_add(RadixSorter *rs, RadixItem *item);
|
||||
RadixItem *radix_cut(RadixSorter *rs, unsigned key, void *data);
|
||||
RadixItem **radixsort_dump(RadixSorter *rs);
|
||||
|
|
|
@ -9,10 +9,8 @@
|
|||
|
||||
#include "include/radixsort.h"
|
||||
|
||||
#define GET_TOP_INDEX(KEY) KEY/SLOT_SIZE
|
||||
#define GET_LOW_INDEX(KEY) KEY%SLOT_SIZE
|
||||
|
||||
#define RADIX_DEBUG 1
|
||||
#define GET_TOP_INDEX(KEY) KEY/RADIX_SLOT_SIZE
|
||||
#define GET_LOW_INDEX(KEY) KEY%RADIX_SLOT_SIZE
|
||||
|
||||
void radixsort_init(RadixSorter *rs, unsigned keyLimit)
|
||||
{
|
||||
|
@ -30,10 +28,15 @@ void radixsort_init(RadixSorter *rs, unsigned keyLimit)
|
|||
rs->_slotsCount=0;
|
||||
}
|
||||
|
||||
void radixsort_set_debug_level(RadixSorter *rs, unsigned debugLevel)
|
||||
{
|
||||
rs->_debug=debugLevel;
|
||||
}
|
||||
|
||||
RadixItem **radixsort_get_slot(RadixSorter *rs, unsigned topIndex)
|
||||
{
|
||||
RadixItem **slot=malloc(SLOT_SIZE * sizeof(RadixItem *));
|
||||
memset(slot, 0, SLOT_SIZE * sizeof(RadixItem *));
|
||||
RadixItem **slot=malloc(RADIX_SLOT_SIZE * sizeof(RadixItem *));
|
||||
memset(slot, 0, RADIX_SLOT_SIZE * sizeof(RadixItem *));
|
||||
|
||||
RadixSlot *descriptor=malloc(sizeof(RadixSlot));
|
||||
descriptor->min=rs->keyLimit;
|
||||
|
@ -48,7 +51,9 @@ RadixItem **radixsort_get_slot(RadixSorter *rs, unsigned topIndex)
|
|||
void radixsort_add(RadixSorter *rs, RadixItem *item)
|
||||
{
|
||||
if(item->key > rs->keyLimit) {
|
||||
if(RADIX_DEBUG) fprintf(stderr, "ERROR: Radix sort overflow - inserted key is bigger than limit (%u): %u\n", rs->keyLimit, item->key);
|
||||
if(rs->_debug > RADIX_DEBUG_LEVEL_NONE) {
|
||||
fprintf(stderr, "WARNING: Radix sort overflow - inserted key is bigger than limit (%u): %u\n", rs->keyLimit, item->key);
|
||||
}
|
||||
if(rs->optFloorAndInsertBigKeys) {
|
||||
item->key = rs->keyLimit-1;
|
||||
} else {
|
||||
|
@ -174,7 +179,7 @@ void radixsort_stat(RadixSorter *rs, bool listing)
|
|||
printf("\n Radixsort (size/max/limit/slot count): %u %u %u %u", rs->size, rs->maxKey, rs->keyLimit, rs->_slotsCount);
|
||||
unsigned memory=rs->_topIndexLimit * sizeof(RadixItem ***);
|
||||
memory+=memory;
|
||||
memory+=rs->_slotsCount*(SLOT_SIZE * sizeof(RadixItem *));
|
||||
memory+=rs->_slotsCount*(RADIX_SLOT_SIZE * sizeof(RadixItem *));
|
||||
printf("\n Memory: %u\n", memory);
|
||||
if(listing && rs->size>0) {
|
||||
int t = GET_TOP_INDEX(rs->maxKey);
|
||||
|
|
Loading…
Reference in a new issue