aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2005-10-02 23:40:46 +1000
committerGravatar axel <axel@liljencrantz.se>2005-10-02 23:40:46 +1000
commit4f197e226788c74f91a0e7b6a85b0793069a2f37 (patch)
treefb2d269c4dfcd2617ccb7ea94cb7796603122329
parent64c601c52fff2daff05350198f3b65cad52baf1c (diff)
Support symbolic keybindings
darcs-hash:20051002134046-ac50b-1e3dc058105d30ad0541c99a250e2d33c31dc7e3.gz
-rw-r--r--doc_src/doc.hdr9
-rw-r--r--input.c240
2 files changed, 235 insertions, 14 deletions
diff --git a/doc_src/doc.hdr b/doc_src/doc.hdr
index eb2dd473..4dd73d25 100644
--- a/doc_src/doc.hdr
+++ b/doc_src/doc.hdr
@@ -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
diff --git a/input.c b/input.c
index aaa7a494..2da86c83 100644
--- a/input.c
+++ b/input.c
@@ -67,6 +67,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
*/
const wchar_t *name_arr[] =
@@ -355,6 +364,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.
\\C-a is expanded to 1, etc.
@@ -720,16 +898,12 @@ 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 );
+ if( sequence )
+ {
+ add_mapping( L"global", sequence, key, val );
+ free( sequence );
+ }
- //fwprintf( stderr, L"%ls -> %ls\n", key, val );
-
return;
}
else if( wcsncmp( L"$include ", cmd, wcslen(L"$include ") ) == 0 )
@@ -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 );
}