Restructure for and add option to delete entry from history.

This commit is contained in:
Qball Cow 2014-02-01 14:03:23 +01:00
parent 8310a97219
commit 6177c90a87
8 changed files with 175 additions and 75 deletions

View file

@ -30,11 +30,21 @@ typedef enum {
NEXT_DIALOG
} SwitcherMode;
typedef enum {
MENU_OK = 0,
MENU_CANCEL = -1,
MENU_NEXT = -2,
MENU_CUSTOM_INPUT = -3,
MENU_ENTRY_DELETE = -4
} MenuReturn;
typedef int ( *menu_match_cb )( char **tokens, const char *input, int index, void *data );
int menu( char **lines, char **input, char *prompt,
Time *time, int *shift, menu_match_cb mmc, void *mmc_data );
MenuReturn menu( char **lines, char **input, char *prompt,
Time *time, int *shift,
menu_match_cb mmc, void *mmc_data,
int *selected_line );
/**

View file

@ -66,8 +66,10 @@ static char **get_dmenu ( )
while ( fgets( buffer, 1024, stdin ) != NULL ) {
retv = realloc( retv, ( index+2 )*sizeof( char* ) );
retv[index] = strdup( buffer );
if( retv[index][strlen(buffer)-1] == '\n')
if ( retv[index][strlen( buffer )-1] == '\n' )
retv[index][strlen( buffer )-1] = '\0';
retv[index+1] = NULL;
index++;
}
@ -112,13 +114,14 @@ SwitcherMode dmenu_switcher_dialog ( char **input )
}
int shift=0;
int n = menu( list, input, dmenu_prompt,NULL, &shift,token_match, NULL );
int selected_line = 0;
int mretv = menu( list, input, dmenu_prompt,NULL, &shift,token_match, NULL, &selected_line );
if ( n == -2 ) {
if ( mretv == MENU_NEXT ) {
retv = DMENU_DIALOG;
} else if ( n >=0 && list[n] != NULL ) {
fputs( list[n],stdout );
} else if ( n == -3 && *input != NULL && *input[0] != '\0' ) {
} else if ( mretv == MENU_OK && list[selected_line] != NULL ) {
fputs( list[selected_line],stdout );
} else if ( mretv == MENU_CUSTOM_INPUT && *input != NULL && *input[0] != '\0' ) {
fputs( *input, stdout );
}

View file

@ -271,13 +271,14 @@ SwitcherMode mark_switcher_dialog ( char **input )
}
int shift=0;
int n = menu( cmd_list, input, "mark:", NULL, &shift,token_match, NULL );
int selected_line = 0;
int mretv = menu( cmd_list, input, "mark:", NULL, &shift,token_match,NULL, &selected_line );
if ( n == -2 ) {
if ( mretv == MENU_NEXT ) {
retv = NEXT_DIALOG;
} else if ( n >=0 && cmd_list[n] != NULL ) {
exec_mark( cmd_list[n] );
} else if ( n == -3 && *input != NULL && *input[0] != '\0' ) {
} else if ( mretv == MENU_OK && cmd_list[selected_line] != NULL ) {
exec_mark( cmd_list[selected_line] );
} else if ( mretv == MENU_CUSTOM_INPUT && *input != NULL && *input[0] != '\0' ) {
exec_mark( *input );
}

View file

@ -178,14 +178,13 @@ SwitcherMode profile_switcher_dialog ( char **input )
}
int shift=0;
int n = menu( cmd_list, input, "profile:", NULL, &shift,token_match, NULL );
int selected_line = 0;
int retvm = menu( cmd_list, input, "profile:", NULL, &shift,token_match, NULL, &selected_line );
if ( n == -2 ) {
if ( retvm == MENU_NEXT ) {
retv = NEXT_DIALOG;
} else if ( n >=0 && cmd_list[n] != NULL ) {
exec_profile( cmd_list[n] );
} else if ( n == -3 && *input != NULL && *input[0] != '\0' ) {
exec_profile( *input );
} else if ( retvm == MENU_OK && cmd_list[selected_line] != NULL ) {
exec_profile( cmd_list[selected_line] );
}
for ( int i=0; cmd_list[i] != NULL; i++ ) {

View file

@ -128,6 +128,66 @@ static pid_t exec_cmd( const char *cmd, int run_in_term )
return pid;
}
// execute sub-process
static void delete_entry( const char *cmd )
{
int curr = -1;
unsigned int index = 0;
char **retv = NULL;
printf( "Delete entry: %s\n", cmd );
/**
* This happens in non-critical time (After launching app)
* It is allowed to be a bit slower.
*/
char *path = allocate( strlen( cache_dir ) + strlen( RUN_CACHE_FILE )+3 );
sprintf( path, "%s/%s", cache_dir, RUN_CACHE_FILE );
FILE *fd = fopen ( path, "r" );
char buffer[1024];
if ( fd != NULL ) {
while ( fgets( buffer,1024,fd ) != NULL ) {
retv = realloc( retv, ( index+2 )*sizeof( char* ) );
buffer[strlen( buffer )-1] = '\0';
retv[index] = strdup( buffer );
retv[index+1] = NULL;
if ( strcasecmp( retv[index], cmd ) == 0 ) {
curr = index;
}
index++;
}
fclose( fd );
}
/**
* Write out the last 25 results again.
*/
fd = fopen ( path, "w" );
if ( fd ) {
for ( int i = 0; i < ( int )index && i < 20; i++ ) {
if ( i != curr ) {
fputs( retv[i], fd );
fputc( '\n', fd );
}
}
fclose( fd );
}
for ( int i=0; retv[i] != NULL; i++ ) {
free( retv[i] );
}
free( retv );
free( path );
}
static int sort_func ( const void *a, const void *b )
{
const char *astr = *( const char * const * )a;
@ -247,14 +307,17 @@ SwitcherMode run_switcher_dialog ( char **input )
}
int shift=0;
int n = menu( cmd_list, input, "$", NULL, &shift,token_match, NULL );
int selected_line = 0;
int mretv = menu( cmd_list, input, "$", NULL, &shift,token_match, NULL, &selected_line );
if ( n == -2 ) {
if ( mretv == MENU_NEXT ) {
retv = NEXT_DIALOG;
} else if ( n >=0 && cmd_list[n] != NULL ) {
exec_cmd( cmd_list[n], shift );
} else if ( n == -3 && *input != NULL && *input[0] != '\0' ) {
} else if ( mretv == MENU_OK && cmd_list[selected_line] != NULL ) {
exec_cmd( cmd_list[selected_line], shift );
} else if ( mretv == MENU_CUSTOM_INPUT && *input != NULL && *input[0] != '\0' ) {
exec_cmd( *input, shift );
} else if ( mretv == MENU_ENTRY_DELETE && cmd_list[selected_line] ) {
delete_entry ( cmd_list[selected_line] );
}
for ( int i=0; cmd_list[i] != NULL; i++ ) {

View file

@ -669,17 +669,19 @@ void menu_draw( textbox *text, textbox **boxes, int max_lines,int num_lines, int
// selected row is always visible.
// If selected is visible do not scroll.
if((selected - (*last_offset)) < (max_lines) &&(selected-(*last_offset)) >= 0) offset = *last_offset;
if ( ( selected - ( *last_offset ) ) < ( max_lines ) &&( selected-( *last_offset ) ) >= 0 ) offset = *last_offset;
else {
// If selected is above visible, scroll up.
if((selected-(*last_offset)) >= (max_lines)) {
if ( ( selected-( *last_offset ) ) >= ( max_lines ) ) {
offset = selected-max_lines+1;
// Scroll down otherwise
}else if ((selected-(*last_offset)) < 0){
// Scroll down otherwise
} else if ( ( selected-( *last_offset ) ) < 0 ) {
offset = selected;
}
// Sanitize
if(offset >= (num_lines)) offset = num_lines-max_lines-1;
if ( offset >= ( num_lines ) ) offset = num_lines-max_lines-1;
*last_offset = offset;
}
@ -691,8 +693,8 @@ void menu_draw( textbox *text, textbox **boxes, int max_lines,int num_lines, int
textbox_text( boxes[i], "" );
} else {
textbox_font( boxes[i], config.menu_font,
(i+offset) == selected ? config.menu_hlfg: config.menu_fg,
(i+offset) == selected ? config.menu_hlbg: config.menu_bg );
( i+offset ) == selected ? config.menu_hlfg: config.menu_fg,
( i+offset ) == selected ? config.menu_hlbg: config.menu_bg );
textbox_text( boxes[i], filtered[i+offset] );
}
@ -761,10 +763,10 @@ int window_match ( char **tokens, __attribute__( ( unused ) )const char *input,
return match;
}
int menu( char **lines, char **input, char *prompt, Time *time, int *shift,
menu_match_cb mmc, void *mmc_data )
MenuReturn menu( char **lines, char **input, char *prompt, Time *time, int *shift,
menu_match_cb mmc, void *mmc_data, int *selected_line )
{
int line = -1, chosen = 0;
int retv = MENU_CANCEL;
unsigned int i,j;
workarea mon;
monitor_active( &mon );
@ -963,8 +965,16 @@ int menu( char **lines, char **input, char *prompt, Time *time, int *shift,
if ( ( ( ev.xkey.state&ShiftMask ) == ShiftMask ) &&
key == XK_slash ) {
line = -2;
retv = MENU_NEXT;
*selected_line = 0;
break;
} else if ( ( ( ev.xkey.state&ShiftMask ) == ShiftMask ) &&
key == XK_Delete ) {
if ( filtered[selected] != NULL ) {
*selected_line = line_map[selected];
retv = MENU_ENTRY_DELETE;
break;
}
}
int rc = textbox_keypress( text, &ev );
@ -973,7 +983,13 @@ int menu( char **lines, char **input, char *prompt, Time *time, int *shift,
if ( shift != NULL )
( *shift ) = ( ( ev.xkey.state&ShiftMask ) == ShiftMask );
chosen = 1;
if ( filtered[selected] ) {
retv = MENU_OK;
*selected_line = line_map[selected];
} else {
retv = MENU_CUSTOM_INPUT;
}
break;
} else if ( rc ) {
char **tokens = tokenize( text->text );
@ -997,7 +1013,14 @@ int menu( char **lines, char **input, char *prompt, Time *time, int *shift,
filtered[j] = NULL;
if ( config.zeltak_mode && filtered_lines == 1 ) {
chosen = 1;
if ( filtered[selected] ) {
retv = MENU_OK;
*selected_line = line_map[selected];
} else {
fprintf( stderr, "We should never hit this." );
abort();
}
break;
}
@ -1012,11 +1035,9 @@ int menu( char **lines, char **input, char *prompt, Time *time, int *shift,
|| ( ( rundialog_modmask == AnyModifier || ev.xkey.state & rundialog_modmask ) && key == rundialog_keysym )
|| ( ( sshdialog_modmask == AnyModifier || ev.xkey.state & sshdialog_modmask ) && key == sshdialog_keysym )
) {
retv = MENU_CANCEL;
break;
}
else
} else {
// Up or Shift-Tab
if ( key == XK_Up || ( key == XK_Tab && ev.xkey.state & ShiftMask ) ||
( key == XK_j && ev.xkey.state& ControlMask ) ) {
@ -1026,20 +1047,28 @@ int menu( char **lines, char **input, char *prompt, Time *time, int *shift,
} else if ( key == XK_Down ||
( key == XK_k && ev.xkey.state& ControlMask ) ) {
selected = selected < filtered_lines-1 ? MIN( filtered_lines-1, selected+1 ): 0;
} else if ( key == XK_Page_Up) {
if(selected < max_lines) selected = 0;
} else if ( key == XK_Page_Up ) {
if ( selected < max_lines ) selected = 0;
else
selected -= (max_lines-1);
} else if ( key == XK_Page_Down) {
selected += (max_lines-1);
if(selected >= num_lines) selected = num_lines-1;
} else if ( key == XK_Home || key == XK_KP_Home) {
selected -= ( max_lines-1 );
} else if ( key == XK_Page_Down ) {
selected += ( max_lines-1 );
if ( selected >= num_lines ) selected = num_lines-1;
} else if ( key == XK_Home || key == XK_KP_Home ) {
selected = 0;
} else if ( key == XK_End || key == XK_KP_End) {
} else if ( key == XK_End || key == XK_KP_End ) {
selected = num_lines-1;
} else if ( key == XK_Tab ) {
if ( filtered_lines == 1 ) {
chosen = 1;
if ( filtered[selected] ) {
retv = MENU_OK;
*selected_line = line_map[selected];
} else {
fprintf( stderr, "We should never hit this." );
abort();
}
break;
}
@ -1052,10 +1081,11 @@ int menu( char **lines, char **input, char *prompt, Time *time, int *shift,
textbox_text( text, str );
textbox_cursor_end( text );
free( str );
} else{
} else {
selected = selected < filtered_lines-1 ? MIN( filtered_lines-1, selected+1 ): 0;
}
}
}
}
}
}
menu_draw( text, boxes, max_lines,num_lines, &last_offset, selected, filtered );
@ -1064,19 +1094,10 @@ int menu( char **lines, char **input, char *prompt, Time *time, int *shift,
release_keyboard();
if ( chosen && filtered[selected] ) {
line = line_map[selected];
}
if ( *input != NULL ) free( *input );
if ( line < 0 && input ) {
if ( *input != NULL ) free( *input );
*input = strdup( text->text );
*input = strdup( text->text );
// If chosen and the like.
if ( chosen )
line = -3;
}
textbox_free( text );
@ -1089,7 +1110,7 @@ int menu( char **lines, char **input, char *prompt, Time *time, int *shift,
free( filtered );
free( line_map );
return line;
return retv;
}
#define FORK 1
@ -1158,20 +1179,21 @@ SwitcherMode run_switcher_window ( char **input )
}
}
Time time;
int n = menu( list, input, ">", &time, NULL,window_match, ids );
int selected_line = 0;
MenuReturn mretv = menu( list, input, ">", &time, NULL,window_match, ids ,&selected_line );
if ( n == -2 ) {
if ( mretv == MENU_NEXT ) {
retv = NEXT_DIALOG;
} else if ( n >= 0 && list[n] ) {
} else if ( mretv == MENU_OK && list[selected_line] ) {
#ifdef I3
if ( config.i3_mode ) {
// Hack for i3.
focus_window_i3( i3_socket_path,ids->array[n] );
focus_window_i3( i3_socket_path,ids->array[selected_line] );
} else
#endif
{
window_send_message( root, ids->array[n], netatoms[_NET_ACTIVE_WINDOW], 2, // 2 = pager
window_send_message( root, ids->array[selected_line], netatoms[_NET_ACTIVE_WINDOW], 2, // 2 = pager
SubstructureNotifyMask | SubstructureRedirectMask, time );
}
}

View file

@ -245,13 +245,14 @@ SwitcherMode ssh_switcher_dialog ( char **input )
}
int shift=0;
int n = menu( cmd_list, input, "ssh", NULL, &shift,token_match, NULL );
int selected_line = 0;
int mretv = menu( cmd_list, input, "ssh", NULL, &shift,token_match, NULL , &selected_line );
if ( n == -2 ) {
if ( mretv == MENU_NEXT ) {
retv = NEXT_DIALOG;
} else if ( n >=0 && cmd_list[n] != NULL ) {
exec_ssh( cmd_list[n] );
} else if ( n == -3 && *input != NULL && *input[0] != '\0' ) {
} else if ( mretv == MENU_OK && cmd_list[selected_line] != NULL ) {
exec_ssh( cmd_list[selected_line] );
} else if ( mretv == MENU_CUSTOM_INPUT && *input != NULL && *input[0] != '\0' ) {
exec_ssh( *input );
}

View file

@ -374,6 +374,7 @@ int textbox_keypress( textbox *tb, XEvent *ev )
textbox_cursor_inc( tb );
return 1;
} /*else if ( key == XK_Home ) {
textbox_cursor_home( tb );
return 1;
} else if ( key == XK_End ) {