diff --git a/CONFIGURATION.md b/CONFIGURATION.md index f308acc..2c6e7e3 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -114,11 +114,19 @@ alias hh=hstr Don't forget to source `~/.bashrc` to be able to to use `hh` command. -## HSTR Config Options +## HSTR Config Options HSTR reads the environment variable `HSTR_CONFIG` for a **comma-separated list** of options. -### Colors + +## Environment variables +- `HISTFILE` (defaults to `~/.bash_history` or `~/.zsh_history`) +- `HSTR_PROMPT` (defaults to `@$ `) +- `HSTR_IS_SUBSHELL` (when HSTR is used in a subshell, set to `1` to fix output when pressing `TAB` or `RIGHT` arrow key) +- `HSTR_CONFIG` (see below) + + +## Colors Let HSTR to use colors: ```bash diff --git a/INSTALLATION.md b/INSTALLATION.md index e3613ff..9378adf 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -78,7 +78,7 @@ Alternatively you can download and install `.deb` archive from [GitHub releases] section of the project: ```bash -sudo dpkg -i hstr_-.._1-amd64.deb +sudo dpkg -i hstr_-..-1-amd64.deb ``` diff --git a/build/test-memleaks.sh b/build/test-memleaks.sh index 336f3d5..6435de4 100755 --- a/build/test-memleaks.sh +++ b/build/test-memleaks.sh @@ -28,7 +28,8 @@ fi export HISTFILE=`pwd`/test/resources/.bash_history_valgrind_1_entry # Valgrind -valgrind --track-origins=yes --tool=memcheck --leak-check=full --show-leak-kinds=all ./hstr -n hist +#valgrind --track-origins=yes --tool=memcheck --leak-check=full --show-leak-kinds=all ./hstr -n hist +valgrind --track-origins=yes --tool=memcheck --leak-check=full --show-leak-kinds=all ./hstr a # Valgrind's GDB #valgrind --vgdb=yes --vgdb-error=0 --track-origins=yes --tool=memcheck --leak-check=full --show-leak-kinds=all ./hstr -n hist diff --git a/src/hstr.c b/src/hstr.c index 14d3371..1c13618 100644 --- a/src/hstr.c +++ b/src/hstr.c @@ -67,6 +67,7 @@ #define HSTR_ENV_VAR_CONFIG "HSTR_CONFIG" #define HSTR_ENV_VAR_PROMPT "HSTR_PROMPT" +#define HSTR_ENV_VAR_IS_SUBSHELL "HSTR_IS_SUBSHELL" #define HSTR_CONFIG_THEME_MONOCHROMATIC "monochromatic" #define HSTR_CONFIG_THEME_HICOLOR "hicolor" @@ -673,7 +674,11 @@ void print_help_label(void) void print_confirm_delete(const char* cmd) { char screenLine[CMDLINE_LNG]; - snprintf(screenLine, getmaxx(stdscr), "Do you want to delete all occurrences of '%s'? y/n", cmd); + if(hstr->view==HSTR_VIEW_FAVORITES) { + snprintf(screenLine, getmaxx(stdscr), "Do you want to delete favorites item '%s'? y/n", cmd); + } else { + snprintf(screenLine, getmaxx(stdscr), "Do you want to delete all occurrences of '%s'? y/n", cmd); + } // TODO make this function if(hstr->theme & HSTR_THEME_COLOR) { color_attr_on(COLOR_PAIR(HSTR_COLOR_DELETE)); @@ -691,7 +696,11 @@ void print_confirm_delete(const char* cmd) void print_cmd_deleted_label(const char* cmd, int occurences) { char screenLine[CMDLINE_LNG]; - snprintf(screenLine, getmaxx(stdscr), "History item '%s' deleted (%d occurrence%s)", cmd, occurences, (occurences==1?"":"s")); + if(hstr->view==HSTR_VIEW_FAVORITES) { + snprintf(screenLine, getmaxx(stdscr), "Favorites item '%s' deleted", cmd); + } else { + snprintf(screenLine, getmaxx(stdscr), "History item '%s' deleted (%d occurrence%s)", cmd, occurences, (occurences==1?"":"s")); + } // TODO make this function if(hstr->theme & HSTR_THEME_COLOR) { color_attr_on(COLOR_PAIR(HSTR_COLOR_DELETE)); @@ -1159,7 +1168,7 @@ void highlight_selection(int selectionCursorPosition, int previousSelectionCurso int remove_from_history_model(char* almostDead) { if(hstr->view==HSTR_VIEW_FAVORITES) { - return favorites_remove(hstr->favorites, almostDead); + return (int)favorites_remove(hstr->favorites, almostDead); } else { // raw & ranked history is pruned first as its items point to system history lines int systemOccurences=0, rawOccurences=history_mgmt_remove_from_raw(almostDead, hstr->history); @@ -1219,6 +1228,12 @@ void loop_to_select(void) { signal(SIGINT, signal_callback_handler_ctrl_c); + bool isSubshellHint=FALSE; + char* isSubshellHintText = getenv(HSTR_ENV_VAR_IS_SUBSHELL); + if(isSubshellHintText && strlen(isSubshellHintText)>0) { + isSubshellHint=TRUE; + } + hstr_curses_start(); // TODO move the code below to hstr_curses color_init_pair(HSTR_COLOR_NORMAL, -1, -1); @@ -1543,7 +1558,12 @@ void loop_to_select(void) break; case K_TAB: case KEY_RIGHT: - editCommand=TRUE; + if(!isSubshellHint) { + editCommand=TRUE; + } else { + // Not setting editCommand to TRUE here, + // because else an unnecessary blank line gets emitted before returning to prompt. + } if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) { result=getResultFromSelection(selectionCursorPosition, hstr, result); if(hstr->view==HSTR_VIEW_FAVORITES) { diff --git a/src/hstr_history.c b/src/hstr_history.c index 8a809e6..3b20d60 100644 --- a/src/hstr_history.c +++ b/src/hstr_history.c @@ -49,15 +49,16 @@ char* get_history_file_name(void) { char* historyFile = getenv(ENV_VAR_HISTFILE); if(!historyFile || strlen(historyFile)==0) { - char* home = getenv(ENV_VAR_HOME); - char* fileHistory; if(isZshParentShell()) { - fileHistory=FILE_ZSH_HISTORY; + historyFile = get_home_file_path(FILE_ZSH_HISTORY); + if(access(historyFile, F_OK) == -1) { + free(historyFile); + historyFile = get_home_file_path(FILE_ZSH_ZHISTORY); + // ... fallback if this file doesn't exist? + } } else { - fileHistory=FILE_DEFAULT_HISTORY; + historyFile = get_home_file_path(FILE_DEFAULT_HISTORY); } - historyFile = malloc(strlen(home) + 1 + strlen(fileHistory) + 1); - strcat(strcat(strcpy(historyFile, home), "/"), fileHistory); } else { // allocate so that this function always returns string to be freed // (getenv() returns pointer (no need to free), home is allocated (must be freed) diff --git a/src/hstr_utils.c b/src/hstr_utils.c index 2bfb7df..1431b6c 100644 --- a/src/hstr_utils.c +++ b/src/hstr_utils.c @@ -164,6 +164,14 @@ void get_hostname(int bufferSize, char *buffer) strcpy(buffer, "localhost"); } +char* get_home_file_path(char* filename) +{ + char* home = getenv(ENV_VAR_HOME); + char* path = malloc(strlen(home) + 1 + strlen(filename) + 1); + strcat(strcat(strcpy(path, home), "/"), filename); + return path; +} + void toggle_case(char *str, bool lowercase) { if(str && strlen(str)>0) { int i; diff --git a/src/include/hstr_favorites.h b/src/include/hstr_favorites.h index 80a57d1..d7e60ec 100644 --- a/src/include/hstr_favorites.h +++ b/src/include/hstr_favorites.h @@ -22,7 +22,6 @@ #include "hashset.h" #define ENV_VAR_USER "USER" -#define ENV_VAR_HOME "HOME" #define FILE_HSTR_FAVORITES ".hstr_favorites" diff --git a/src/include/hstr_history.h b/src/include/hstr_history.h index 80ca7d1..9639d9f 100644 --- a/src/include/hstr_history.h +++ b/src/include/hstr_history.h @@ -25,6 +25,7 @@ #include #include +#include "hstr_utils.h" #include "hstr_regexp.h" #include "radixsort.h" #include "hstr_favorites.h" @@ -33,6 +34,7 @@ #define FILE_DEFAULT_HISTORY ".bash_history" #define FILE_ZSH_HISTORY ".zsh_history" +#define FILE_ZSH_ZHISTORY ".zhistory" #define ZSH_HISTORY_ITEM_OFFSET 15 #define BASH_HISTORY_ITEM_OFFSET 0 diff --git a/src/include/hstr_utils.h b/src/include/hstr_utils.h index 660b041..f02dcf0 100644 --- a/src/include/hstr_utils.h +++ b/src/include/hstr_utils.h @@ -28,6 +28,8 @@ #include #include +#define ENV_VAR_HOME "HOME" + #define UNUSED_ARG(expr) do { (void)(expr); } while (0) #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -43,6 +45,7 @@ void tiocsti(); void fill_terminal_input(char* cmd, bool padding); void reverse_char_pointer_array(char** array, unsigned length); void get_hostname(int bufferSize, char* buffer); +char* get_home_file_path(char* filename); void toggle_case(char* str, bool lowercase); bool isZshParentShell(void);