mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Support symbolic keybindings
darcs-hash:20051002134046-ac50b-1e3dc058105d30ad0541c99a250e2d33c31dc7e3.gz
This commit is contained in:
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
|
||||
- End or Ctrl-e moves to the end of line
|
||||
- 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
|
||||
- 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
|
||||
|
@ -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,
|
||||
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>
|
||||
to read up on this syntax. Please note thet the key binding support in
|
||||
\c fish is still limited. You can not use the set command or the
|
||||
keyname-syntax, and the list functions is incomplete. Currently, the
|
||||
following functions are available:
|
||||
to read up on this syntax. Please note thet the list of key binding
|
||||
functions in fish is different to that offered by readline. Currently,
|
||||
the following functions are available:
|
||||
|
||||
|
||||
- \c backward-char, moves one character to the left
|
||||
|
|
240
input.c
240
input.c
|
@ -66,6 +66,15 @@ typedef struct
|
|||
}
|
||||
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
|
||||
*/
|
||||
|
@ -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.
|
||||
|
||||
|
@ -720,15 +898,11 @@ void input_parse_inputrc_line( wchar_t *cmd )
|
|||
val = cmd;
|
||||
|
||||
sequence = input_expand_sequence( key );
|
||||
add_mapping( L"global", sequence, key, val );
|
||||
|
||||
// fwprintf( stderr, L"Map %ls to %ls\n", key, val );
|
||||
|
||||
free( sequence );
|
||||
|
||||
//fwprintf( stderr, L"Remainder \'%ls\', endchar %d\n", cmd, *cmd );
|
||||
|
||||
//fwprintf( stderr, L"%ls -> %ls\n", key, val );
|
||||
if( sequence )
|
||||
{
|
||||
add_mapping( L"global", sequence, key, val );
|
||||
free( sequence );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -812,6 +986,54 @@ void input_parse_inputrc_line( wchar_t *cmd )
|
|||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue