mirror of
https://github.com/dvorka/hstr.git
synced 2024-12-28 18:50:54 +08:00
Minor favorites refactoring and blacklist skeleton.
This commit is contained in:
parent
8dc27fac20
commit
f82800ae5d
6 changed files with 308 additions and 8 deletions
158
DOCUMENTATION.md
Normal file
158
DOCUMENTATION.md
Normal file
|
@ -0,0 +1,158 @@
|
|||
This document is an unfinished draft.
|
||||
|
||||
HSTR DOCUMENTATION
|
||||
==================
|
||||
Table of contents:
|
||||
* Installation
|
||||
* Distribution
|
||||
* Source code
|
||||
* Ubuntu
|
||||
* Debian
|
||||
* Mint
|
||||
* Arch
|
||||
* Mac OS
|
||||
* Configuration
|
||||
* Keyboard shortcut
|
||||
* Colors
|
||||
* View
|
||||
* Verbosity
|
||||
* Shell specific
|
||||
* Bash
|
||||
* Zsh
|
||||
* Features
|
||||
* History views
|
||||
* Ranking
|
||||
* Raw
|
||||
* Favorites
|
||||
* History filtering
|
||||
* Choosing a command
|
||||
* Favorite commands
|
||||
* Blacklist
|
||||
* Examples
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
`hh` is typically started by pressing `Ctrl-r` after
|
||||
you configure it for this shorcut for your shell. However,
|
||||
you can run it as a normal program just by typing:
|
||||
```bash
|
||||
hh
|
||||
```
|
||||
|
||||
It opens a page with a history view (ranking view is default).
|
||||
Alternatively you can run `hh` in non-interactive mode -
|
||||
commands are just listed on standard output based on history
|
||||
view:
|
||||
```bash
|
||||
hh --non-interactive
|
||||
```
|
||||
|
||||
Filtering pattern can be optionally specified as well:
|
||||
```bash
|
||||
hh -i git
|
||||
```
|
||||
|
||||
Prints history items containing `git` to standard output and
|
||||
exits.
|
||||
|
||||
|
||||
### History filtering
|
||||
When `hh` starts in interative mode, a view of commands
|
||||
is shown. This list of commands can be filtered just by typing
|
||||
a string pattern.
|
||||
|
||||
|
||||
### Choosing a command
|
||||
When you filtered the view of history items enough, you can
|
||||
move around it with `UP` and `DOWN` arrow keys. Selected history
|
||||
items is highlighted. Once you are done with your choice:
|
||||
|
||||
* press `ENTER` to choose the command and execute it
|
||||
* or press `TAB` or `RIGHT` arrow key to choose the command and edit it on command line after exiting `hh`
|
||||
* or press `LEFT` arrow key to choose the command and open it in editor (Bash `fc` i.e. fix command)
|
||||
|
||||
|
||||
|
||||
Favorite Commands
|
||||
-----------------
|
||||
`hh` allows you to store and manage your favorite
|
||||
commands.
|
||||
|
||||
A new favorite command can be added from
|
||||
ranking or raw history view by pressing `Ctrl-f`.
|
||||
|
||||
You can check your favorite commands by choosing
|
||||
favorite view - rotate views using `Ctrl-/` or start
|
||||
`hh` by adding `favorites` to `HH_CONFIG` environment
|
||||
property. A favorite command can be choosen just
|
||||
by pressing `ENTER` when on command in favorite view.
|
||||
Last chosen favorite commands appears as the first
|
||||
one (at the top of the page) in the favorite view.
|
||||
You can delete a favorite command with `DEL` key.
|
||||
|
||||
Tips:
|
||||
* Favorite commands are stored in `~/.hh_favorites`
|
||||
* Suffix your favorite commands with comments
|
||||
describing their purpose. For example
|
||||
`printf "\e[?2004l" # fix terminal copy/paste`
|
||||
Such comment can be used for normal commands
|
||||
as well and may serve as a way how to **tag**
|
||||
commands.
|
||||
|
||||
|
||||
Blacklist
|
||||
---------
|
||||
`hh` allows you to specify a set of commands to be
|
||||
skipped from all the views. Blacklist typically contains
|
||||
frequently used commands whose completion from history
|
||||
has a little or no value. The default blacklist looks
|
||||
like this:
|
||||
|
||||
```bash
|
||||
pwd
|
||||
cd
|
||||
cd ..
|
||||
ls
|
||||
hh
|
||||
mc
|
||||
```
|
||||
|
||||
Tips:
|
||||
* Blacklist of commands is stored in `~/.hh_blacklist`
|
||||
If the file doesn't exist, you may create it and complete
|
||||
it with your own blacklist.
|
||||
* You can skip any command from history just by
|
||||
prefixing it with `SPACE`. For example:
|
||||
` echo "Skip this from history"` It's a Bash
|
||||
option that is configured using
|
||||
`HISTCONTROL=ignorespace` environment variable.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
Get more colors when running `hh`:
|
||||
```bash
|
||||
export HH_CONFIG=hicolor
|
||||
```
|
||||
|
||||
Start `hh` in configured view and filter out history items
|
||||
containing 'git':
|
||||
```bash
|
||||
hh git
|
||||
```
|
||||
|
||||
Print history items containing 'git' to standard output and exit:
|
||||
```bash
|
||||
hh --non-interactive git
|
||||
```
|
||||
|
||||
Append default `hh` configuration to your Bash profile:
|
||||
```bash
|
||||
hh --show-configuration >> ~/.bashrc
|
||||
```
|
||||
|
||||
Check `hh` man page:
|
||||
```bash
|
||||
man hh
|
||||
```
|
|
@ -869,6 +869,7 @@ void loop_to_select(Hstr *hstr)
|
|||
deletedOccurences=remove_from_history_model(msg, hstr);
|
||||
result=hstr_print_selection(maxHistoryItems, pattern, hstr);
|
||||
print_cmd_deleted_label(msg, deletedOccurences, hstr);
|
||||
free(msg);
|
||||
move(y, basex+strlen(pattern));
|
||||
printDefaultLabel=TRUE;
|
||||
print_history_label(hstr);
|
||||
|
|
104
src/hstr_blacklist.c
Normal file
104
src/hstr_blacklist.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
============================================================================
|
||||
Name : hstr_blacklist.c
|
||||
Author : martin.dvorak@midforger.com
|
||||
Copyright : Apache 2.0
|
||||
Description : Commands to be skipped from history.
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "include/hstr_blacklist.h"
|
||||
|
||||
static const char *implicitCommandBlacklist[] = {
|
||||
"ls", "pwd", "cd", "cd ..", "hh", "mc",
|
||||
"ls ", "pwd ", "cd ", "cd .. ", "hh ", "mc "
|
||||
};
|
||||
|
||||
void blacklist_init(Blacklist *blacklist)
|
||||
{
|
||||
blacklist->loaded=false;
|
||||
blacklist->implicit=false;
|
||||
blacklist->set=malloc(sizeof(HashSet));
|
||||
hashset_init(blacklist->set);
|
||||
}
|
||||
|
||||
char* blacklist_get_filename()
|
||||
{
|
||||
char *home = getenv(ENV_VAR_HOME);
|
||||
char *fileName = (char*) malloc(strlen(home) + 1 + strlen(FILE_HH_BLACKLIST) + 1);
|
||||
strcpy(fileName, home);
|
||||
strcat(fileName, "/");
|
||||
strcat(fileName, FILE_HH_BLACKLIST);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
void blacklist_get(Blacklist *blacklist)
|
||||
{
|
||||
if(!blacklist->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)) {
|
||||
char *p=strchr(file_contents,'\n');
|
||||
while (p!=NULL) {
|
||||
p=strchr(p+1,'\n');
|
||||
}
|
||||
char *pb=file_contents, *pe, *s;
|
||||
pe=strchr(file_contents, '\n');
|
||||
while(pe!=NULL) {
|
||||
*pe=0;
|
||||
if(!hashset_contains(blacklist->set,pb)) {
|
||||
s=hstr_strdup(pb);
|
||||
hashset_add(blacklist->set,s);
|
||||
}
|
||||
pb=pe+1;
|
||||
pe=strchr(pb, '\n');
|
||||
}
|
||||
free(file_contents);
|
||||
}
|
||||
} else {
|
||||
// blacklist not found - use default one (flushed on exit)
|
||||
blacklist->loaded=true;
|
||||
blacklist->implicit=true;
|
||||
int i, length=sizeof(implicitCommandBlacklist)/sizeof(implicitCommandBlacklist[0]);
|
||||
for(i=0; i<length; i++) {
|
||||
hashset_add(blacklist->set, implicitCommandBlacklist[i]);
|
||||
}
|
||||
}
|
||||
free(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
bool blacklist_in(Blacklist *blacklist, char *cmd)
|
||||
{
|
||||
return hashset_contains(blacklist->set, cmd);
|
||||
}
|
||||
|
||||
void blacklist_destroy(Blacklist *blacklist)
|
||||
{
|
||||
if(blacklist) {
|
||||
if(blacklist->implicit) {
|
||||
// TODO save blacklist to file if implicit
|
||||
}
|
||||
hashset_destroy(blacklist->set, false);
|
||||
free(blacklist->set);
|
||||
free(blacklist);
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ void favorites_init(FavoriteItems *favorites)
|
|||
favorites->count=0;
|
||||
favorites->loaded=false;
|
||||
favorites->set=malloc(sizeof(HashSet));
|
||||
hashset_init(favorites->set);
|
||||
}
|
||||
|
||||
void favorites_show(FavoriteItems *favorites)
|
||||
|
@ -39,10 +40,10 @@ void favorites_show(FavoriteItems *favorites)
|
|||
char* favorites_get_filename()
|
||||
{
|
||||
char *home = getenv(ENV_VAR_HOME);
|
||||
char *fileName = (char*) malloc(strlen(home) + 1 + strlen(FILE_HH_RC) + 1);
|
||||
char *fileName = (char*) malloc(strlen(home) + 1 + strlen(FILE_HH_FAVORITES) + 1);
|
||||
strcpy(fileName, home);
|
||||
strcat(fileName, "/");
|
||||
strcat(fileName, FILE_HH_RC);
|
||||
strcat(fileName, FILE_HH_FAVORITES);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
@ -74,17 +75,15 @@ void favorites_get(FavoriteItems *favorites)
|
|||
}
|
||||
|
||||
favorites->items = malloc(sizeof(char*) * favorites->count);
|
||||
favorites->count=0;
|
||||
favorites->count = 0;
|
||||
char *pb=file_contents, *pe, *s;
|
||||
pe=strchr(file_contents, '\n');
|
||||
HashSet set;
|
||||
hashset_init(&set);
|
||||
while(pe!=NULL) {
|
||||
*pe=0;
|
||||
if(!hashset_contains(&set,pb)) {
|
||||
if(!hashset_contains(favorites->set,pb)) {
|
||||
s=hstr_strdup(pb);
|
||||
favorites->items[favorites->count++]=s;
|
||||
hashset_add(&set,s);
|
||||
hashset_add(favorites->set,s);
|
||||
}
|
||||
pb=pe+1;
|
||||
pe=strchr(pb, '\n');
|
||||
|
@ -139,6 +138,7 @@ void favorites_add(FavoriteItems *favorites, char *newFavorite)
|
|||
}
|
||||
|
||||
favorites_save(favorites);
|
||||
hashset_add(favorites->set, newFavorite);
|
||||
}
|
||||
|
||||
void favorites_choose(FavoriteItems *favorites, char *choice)
|
||||
|
@ -178,6 +178,7 @@ bool favorites_remove(FavoriteItems *favorites, char *almostDead)
|
|||
}
|
||||
}
|
||||
favorites_save(favorites);
|
||||
// kept in set and removed/freed on favs destroy
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -187,11 +188,14 @@ bool favorites_remove(FavoriteItems *favorites, char *almostDead)
|
|||
void favorites_destroy(FavoriteItems *favorites)
|
||||
{
|
||||
if(favorites) {
|
||||
// TODO hashset destroys keys - no need to destroy items!
|
||||
int i;
|
||||
for(i=0; i<favorites->count; i++) {
|
||||
free(favorites->items[i]);
|
||||
}
|
||||
// TODO hashset destroys keys - no need to destroy items!
|
||||
hashset_destroy(favorites->set, false);
|
||||
free(favorites->set);
|
||||
free(favorites);
|
||||
}
|
||||
}
|
||||
|
|
33
src/include/hstr_blacklist.h
Normal file
33
src/include/hstr_blacklist.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
============================================================================
|
||||
Name : hstr_blacklist.h
|
||||
Author : martin.dvorak@midforger.com
|
||||
Copyright : Apache 2.0
|
||||
Description : Commands to be skipped from history.
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
#ifndef HSTR_BLACKLIST_H_
|
||||
#define HSTR_BLACKLIST_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "hashset.h"
|
||||
|
||||
#define ENV_VAR_USER "USER"
|
||||
#define ENV_VAR_HOME "HOME"
|
||||
|
||||
#define FILE_HH_BLACKLIST ".hh_blacklist"
|
||||
|
||||
typedef struct {
|
||||
bool loaded;
|
||||
bool implicit;
|
||||
HashSet *set;
|
||||
} Blacklist;
|
||||
|
||||
void blacklist_init(Blacklist *blacklist);
|
||||
void blacklist_get(Blacklist *blacklist);
|
||||
bool blacklist_in(Blacklist *blacklist, char *cmd);
|
||||
void blacklist_destroy(Blacklist *blacklist);
|
||||
|
||||
#endif
|
|
@ -17,7 +17,7 @@
|
|||
#define ENV_VAR_USER "USER"
|
||||
#define ENV_VAR_HOME "HOME"
|
||||
|
||||
#define FILE_HH_RC ".hh_favorites"
|
||||
#define FILE_HH_FAVORITES ".hh_favorites"
|
||||
|
||||
typedef struct {
|
||||
char **items;
|
||||
|
|
Loading…
Reference in a new issue