Support symbolic keybindings

darcs-hash:20051002134046-ac50b-1e3dc058105d30ad0541c99a250e2d33c31dc7e3.gz
This commit is contained in:
axel 2005-10-02 23:40:46 +10:00
parent 64c601c52f
commit 4f197e2267
2 changed files with 235 additions and 14 deletions

@ -638,7 +638,7 @@ Here are some of the commands available in the editor:
- Home or Ctrl-a moves to the beginning of the line - Home or Ctrl-a moves to the beginning of the line
- End or Ctrl-e moves to the end of line - End or Ctrl-e moves to the end of line
- Left and right moves one character left or right - Left and right moves one character left or right
- Alt-left and Alt-right moves one word left or right - Alt-left and Alt-right moves one word left or right, or moves forward/backward in the directory history if the commandline is empty
- Delete and backspace removes one character forwards or backwards - Delete and backspace removes one character forwards or backwards
- Ctrl-c delete entire line - Ctrl-c delete entire line
- Ctrl-d delete one character to the right of the cursor, unless the buffer is empty, in which case the shell will exit - Ctrl-d delete one character to the right of the cursor, unless the buffer is empty, in which case the shell will exit
@ -656,10 +656,9 @@ this, copy the file /etc/fish_inputrc to your home directory and
rename it to '.fish_inputrc'. Now you can edit the file .fish_inputrc, rename it to '.fish_inputrc'. Now you can edit the file .fish_inputrc,
to change your key bindings. The fileformat of this file is described to change your key bindings. The fileformat of this file is described
in the manual page for readline. Use the command <tt>man readline</tt> in the manual page for readline. Use the command <tt>man readline</tt>
to read up on this syntax. Please note thet the key binding support in to read up on this syntax. Please note thet the list of key binding
\c fish is still limited. You can not use the set command or the functions in fish is different to that offered by readline. Currently,
keyname-syntax, and the list functions is incomplete. Currently, the the following functions are available:
following functions are available:
- \c backward-char, moves one character to the left - \c backward-char, moves one character to the left

240
input.c

@ -66,6 +66,15 @@ typedef struct
} }
mapping; mapping;
/**
Symbolic names for some acces-modifiers used when parsing symbolic sequences
*/
#define CTRL L"Control-"
/**
Symbolic names for some acces-modifiers used when parsing symbolic sequences
*/
#define META L"Meta-"
/** /**
Names of all the readline functions supported Names of all the readline functions supported
*/ */
@ -354,6 +363,175 @@ repaint();*/
} }
/**
Parse special character from the specified inputrc-style key binding.
Control-a is expanded to 1, etc.
*/
static wchar_t *input_symbolic_sequence( const wchar_t *in )
{
wchar_t *res=0;
if( !*in || *in == L'\n' )
return 0;
debug( 4, L"Try to parse symbolic sequence %ls", in );
if( wcsncmp( in, CTRL, wcslen(CTRL) ) == 0 )
{
int has_meta=0;
in += wcslen(CTRL);
/*
Control-Meta- Should be rearranged to Meta-Control, this
special-case must be handled manually.
*/
if( wcsncmp( in, META, wcslen(META) ) == 0 )
{
in += wcslen(META);
has_meta=1;
}
wchar_t c = towlower( *in );
in++;
if( c < L'a' || c > L'z' )
{
debug( 1, L"Invalid Control sequence" );
return 0;
}
if( has_meta )
{
res = wcsdup( L"\ea" );
res[1]=1+c-L'a';
}
else
{
res = wcsdup( L"a" );
res[0]=1+c-L'a';
}
debug( 4, L"Got control sequence %d", res[0] );
}
else if( wcsncmp( in, META, wcslen(META) ) == 0 )
{
in += wcslen(META);
res = wcsdup( L"\e" );
debug( 4, L"Got meta" );
}
else
{
int i;
struct
{
wchar_t *in;
char *out;
}
map[]=
{
{
L"rubout",
key_backspace
}
,
{
L"del",
key_dc
}
,
{
L"esc",
"\e"
}
,
{
L"lfd",
"\r"
}
,
{
L"newline",
"\n"
}
,
{
L"ret",
"\n"
}
,
{
L"return",
"\n"
}
,
{
L"spc",
" "
}
,
{
L"space",
" "
}
,
{
L"tab",
"\t"
}
,
{
0,
0
}
}
;
for( i=0; map[i].in; i++ )
{
if( wcsncmp( in, map[i].in, wcslen(map[i].in) )==0 )
{
in+= wcslen( map[i].in );
res = str2wcs( map[i].out );
break;
}
}
if( !res )
{
if( iswalnum( *in ) || iswpunct( *in ) )
{
res = wcsdup( L"a" );
*res = *in++;
debug( 4, L"Got character %lc", *res );
}
}
}
if( !res )
{
debug( 1, L"Could not parse sequence %ls", in );
return 0;
}
if( !*in || *in == L'\n')
{
debug( 4, L"Finished parsing sequence" );
return res;
}
wchar_t *res2 = input_symbolic_sequence( in );
if( !res2 )
{
free( res );
return 0;
}
wchar_t *res3 = wcsdupcat( res, res2 );
free( res);
free(res2);
return res3;
}
/** /**
Unescape special character from the specified inputrc-style key sequence. Unescape special character from the specified inputrc-style key sequence.
@ -720,16 +898,12 @@ void input_parse_inputrc_line( wchar_t *cmd )
val = cmd; val = cmd;
sequence = input_expand_sequence( key ); sequence = input_expand_sequence( key );
add_mapping( L"global", sequence, key, val ); if( sequence )
{
// fwprintf( stderr, L"Map %ls to %ls\n", key, val ); add_mapping( L"global", sequence, key, val );
free( sequence );
free( sequence ); }
//fwprintf( stderr, L"Remainder \'%ls\', endchar %d\n", cmd, *cmd );
//fwprintf( stderr, L"%ls -> %ls\n", key, val );
return; return;
} }
else if( wcsncmp( L"$include ", cmd, wcslen(L"$include ") ) == 0 ) else if( wcsncmp( L"$include ", cmd, wcslen(L"$include ") ) == 0 )
@ -812,6 +986,54 @@ void input_parse_inputrc_line( wchar_t *cmd )
return; return;
} }
else
{
/*
This is a redular key binding, like
Control-o: kill-word
Or at least we hope it is, since if it isn't, we have no idea what it is.
*/
wchar_t *key;
wchar_t *val;
wchar_t *sequence;
wchar_t prev=0;
key=cmd;
cmd = wcschr( cmd, ':' );
if( !cmd )
{
debug( 1,
L"Unable to parse binding" );
inputrc_error = 1;
return;
}
*cmd = 0;
cmd++;
while( *cmd == L' ' )
cmd++;
val = cmd;
debug( 1, L"Map %ls to %ls\n", key, val );
sequence = input_symbolic_sequence( key );
if( sequence )
{
add_mapping( L"global", sequence, key, val );
free( sequence );
}
return;
}
debug( 1, L"I don\'t know what %ls means", cmd ); debug( 1, L"I don\'t know what %ls means", cmd );
} }