Key binding functions

darcs-hash:20050920234200-ac50b-3895a97cb024368258cd1562bdcc9fda2c84f521.gz
This commit is contained in:
axel 2005-09-21 09:42:00 +10:00
parent 3a60fc5206
commit e3ce01d685
12 changed files with 123 additions and 58 deletions

View file

@ -1,7 +1,12 @@
2005-09-20 Axel Liljencrantz <axel@liljencrantz.se>
* exec.c, reader.c (exec_read_io_buffer, run_pager): Don't leak file descriptors when showing completion pager
* builtin_set.c (print_variables): Fix broken sort of variable names on print
* builtin.c, function.c, function.h: Add support for --key-binding flag on function definitions
* init/fish_input, init/fish_function, input.c: Switch over to using keybinding-functions for keybindings
2005-09-19 Axel Liljencrantz <axel@liljencrantz.se>

View file

@ -399,6 +399,7 @@ complete.o: history.h intern.h wutil.h
env.o: config.h util.h wutil.h proc.h common.h env.h sanity.h expand.h
env.o: history.h reader.h parser.h env_universal.h env_universal_common.h
env_universal.o: util.h common.h wutil.h env_universal_common.h
env_universal.o: env_universal.h
env_universal_common.o: util.h common.h wutil.h env_universal_common.h
exec.o: config.h util.h common.h wutil.h proc.h exec.h parser.h builtin.h
exec.o: function.h env.h wildcard.h sanity.h expand.h env_universal.h
@ -428,7 +429,7 @@ mimedb.o: config.h xdgmime.h util.h
output.o: config.h util.h wutil.h expand.h common.h output.h highlight.h
parser.o: config.h util.h common.h wutil.h proc.h parser.h tokenizer.h exec.h
parser.o: wildcard.h function.h builtin.h builtin_help.h env.h expand.h
parser.o: reader.h sanity.h
parser.o: reader.h sanity.h env_universal.h env_universal_common.h
proc.o: config.h util.h wutil.h proc.h common.h reader.h sanity.h env.h
reader.o: config.h util.h wutil.h highlight.h reader.h proc.h parser.h
reader.o: complete.h history.h common.h sanity.h env.h exec.h expand.h

View file

@ -697,6 +697,23 @@ static int builtin_functions( wchar_t **argv )
}
/**
Test whether the specified string is a valid name for a keybinding
*/
static int wcsbindingname( wchar_t *str )
{
while( *str )
{
if( (!iswalnum(*str)) && (*str != L'-' ) )
{
return 0;
}
str++;
}
return 1;
}
/**
The function builtin, used for providing subroutines.
@ -707,6 +724,7 @@ static int builtin_function( wchar_t **argv )
int argc = builtin_count_args( argv );
int res=0;
wchar_t *desc=0;
int is_binding=0;
woptind=0;
@ -717,6 +735,10 @@ static int builtin_function( wchar_t **argv )
L"description", required_argument, 0, 'd'
}
,
{
L"key-binding", no_argument, 0, 'b'
}
,
{
0, 0, 0, 0
}
@ -729,7 +751,7 @@ static int builtin_function( wchar_t **argv )
int opt = wgetopt_long( argc,
argv,
L"d:",
L"d:b",
long_options,
&opt_index );
if( opt == -1 )
@ -755,6 +777,11 @@ static int builtin_function( wchar_t **argv )
desc=woptarg;
break;
case 'b':
is_binding=1;
break;
case '?':
builtin_print_help( argv[0], sb_err );
@ -772,7 +799,7 @@ static int builtin_function( wchar_t **argv )
argc-woptind );
res=1;
}
else if( !wcsvarname( argv[woptind] ) )
else if( !(is_binding?wcsbindingname( argv[woptind] ) : wcsvarname( argv[woptind] ) ))
{
sb_append2( sb_err,
argv[0],
@ -780,6 +807,7 @@ static int builtin_function( wchar_t **argv )
argv[woptind],
L"\'\n",
0 );
res=1;
}
else if( parser_is_reserved(argv[woptind] ) )
@ -791,13 +819,9 @@ static int builtin_function( wchar_t **argv )
argv[woptind],
L"\' is reserved,\nand can not be used as a function name\n",
0 );
res=1;
}
if( res )
{
int i;
@ -840,6 +864,7 @@ static int builtin_function( wchar_t **argv )
parser_push_block( FUNCTION_DEF );
current_block->function_name=wcsdup(argv[woptind]);
current_block->function_description=desc?wcsdup(desc):0;
current_block->function_is_binding = is_binding;
}
current_block->tok_pos = parser_get_pos();
@ -2375,7 +2400,8 @@ static int builtin_end( wchar_t **argv )
{
function_add( current_block->function_name,
def,
current_block->function_description);
current_block->function_description,
current_block->function_is_binding );
}
free(def);
}

View file

@ -18,6 +18,7 @@ parts of fish.
#include <stdarg.h>
#include <signal.h>
#include <locale.h>
#include <time.h>
#if HAVE_NCURSES_H
#include <ncurses.h>
@ -204,7 +205,6 @@ static int completion_cmp( const void *a, const void *b )
void sort_list( array_list_t *comp )
{
qsort( comp->arr,
al_get_count( comp ),
sizeof( void*),

View file

@ -1,10 +1,13 @@
\section function function - create a function
\subsection function-synopsis Synopsis
<tt>function NAME; BODY; end </tt>
<tt>function [OPTIONS] NAME; BODY; end </tt>
\subsection function-description Description
- <tt>-d DESCRIPTION</tt> or \c --description=DESCRIPTION is a description of what the function does, suitable as a completion description
- \c -b or \c --key-binding specifies that the function is a key biding. Key binding functions work exactly like regular functions except that they can not be tab-completed, and may contain the '-' character.
This builtin command is used to create a new function. A Function is a
list of commands that will be executed when the name of the function
is entered. The function
@ -13,7 +16,7 @@ is entered. The function
function hi
echo hello
end
</pre>
BB</pre>
will write <tt>hello</tt> whenever the user enters \c hi.
@ -27,7 +30,7 @@ are inserted into the environment variable <a href="index.html#variables-arrays"
</pre>
will run the \c ls command, using the \c -l option, while passing on any additional files and switches to \c ls.
A
<pre>
function mkdir -d "Create a directory and set CWD"
mkdir $argv
@ -45,4 +48,4 @@ end
will run the mkdir command, and if it is succesfull, change the
current working directory to the one just created.

View file

@ -48,18 +48,21 @@
*/
#define PARSE_ERR L"Unable to parse universal variable message: '%ls'"
static void parse_message( wchar_t *msg, connection_t *src );
static void parse_message( wchar_t *msg,
connection_t *src );
/**
The table of all universal variables
*/
hash_table_t env_universal_var;
void (*callback)(int type, const wchar_t *key, const wchar_t *val );
void (*callback)( int type,
const wchar_t *key,
const wchar_t *val );
void env_universal_common_init(void (*cb)(int type, const wchar_t *key, const wchar_t *val ) )
void env_universal_common_init( void (*cb)(int type, const wchar_t *key, const wchar_t *val ) )
{
debug( 2, L"Init env_universal_common" );
callback = cb;
@ -107,8 +110,8 @@ void read_message( connection_t *src )
if( src->input.used > 0 )
{
debug( 1,
L"Universal variable connection closed while reading command. Partial command recieved: '%ls'",
(wchar_t *)src->input.buff );
L"Universal variable connection closed while reading command. Partial command recieved: '%ls'",
(wchar_t *)src->input.buff );
}
return;
}
@ -159,7 +162,8 @@ static int match( const wchar_t *msg, const wchar_t *cmd )
}
static void parse_message( wchar_t *msg, connection_t *src )
static void parse_message( wchar_t *msg,
connection_t *src )
{
debug( 2, L"parse_message( %ls );", msg );
@ -245,7 +249,8 @@ static void parse_message( wchar_t *msg, connection_t *src )
}
}
int try_send( message_t *msg, int fd )
int try_send( message_t *msg,
int fd )
{
int res = write( fd, msg->body, strlen(msg->body) );

View file

@ -8,7 +8,6 @@
#include <termios.h>
#include <signal.h>
#include "config.h"
#include "util.h"
#include "function.h"
@ -31,6 +30,7 @@ typedef struct
wchar_t *cmd;
/** Function description */
wchar_t *desc;
int is_binding;
}
function_data_t;
@ -61,7 +61,8 @@ void function_destroy()
void function_add( const wchar_t *name,
const wchar_t *val,
const wchar_t *desc )
const wchar_t *desc,
int is_binding)
{
if( function_exists( name ) )
function_remove( name );
@ -69,6 +70,7 @@ void function_add( const wchar_t *name,
function_data_t *d = malloc( sizeof( function_data_t ) );
d->cmd = wcsdup( val );
d->desc = desc?wcsdup( desc ):0;
d->is_binding = is_binding;
hash_put( &function, intern(name), d );
}
@ -130,7 +132,9 @@ static void get_names_internal( const void *key,
void *aux )
{
wchar_t *name = (wchar_t *)key;
if( name[0] != L'_' )
function_data_t *f = (function_data_t *)val;
if( name[0] != L'_' && !f->is_binding)
al_push( (array_list_t *)aux, name );
}

View file

@ -19,7 +19,8 @@ void function_destroy();
*/
void function_add( const wchar_t *name,
const wchar_t *val,
const wchar_t *desc );
const wchar_t *desc,
int is_binding );
/**
Remove the function with the specified name.

View file

@ -288,21 +288,6 @@ function vared -d "Edit variable value"
end
end
#
# This function deletes a character from the commandline if it is
# non-empty, and exits the shell otherwise. Implementing this
# functionality has been a longstanding request from various
# fish-users.
#
function __fish_delete_or_exit -d "Exit the shell if the commandline is empty, delete a character otherwise"
if test (commandline)
commandline -f delete-char
else
exit
end
end
#
# This function is bound to Alt-L, it is used to list the contents of
# the directory under the cursor
@ -672,3 +657,35 @@ function type -d "Print the type of a command"
return $status
end
function prevd-or-backward-word --key-binding
if test -z (commandline)
prevd
else
commandline -f backward-word
end
end
function nextd-or-forward-word --key-binding
if test -z (commandline)
nextd
else
commandline -f forward-word
end
end
#
# This function deletes a character from the commandline if it is
# non-empty, and exits the shell otherwise. Implementing this
# functionality has been a longstanding request from various
# fish-users.
#
function delete-or-exit --key-binding -d "Exit the shell if the commandline is empty, delete a character otherwise"
if test (commandline)
commandline -f delete-char
else
exit
end
end

View file

@ -16,17 +16,8 @@ $if fish
"\M-d": kill-word
"\C-w": backward-kill-word
"\M-k": dump-functions
"\C-d": __fish_delete_or_exit
"\M-d": if test -z (commandline); dirh; else; commandline -f kill-word; end
"\e\eOD": if test -z (commandline); prevd; else; commandline -f backward-word; end
"\e\eOC": if test -z (commandline); nextd; else; commandline -f forward-word; end
"\eO3D": if test -z (commandline); prevd; else; commandline -f backward-word; end
"\eO3C": if test -z (commandline); nextd; else; commandline -f forward-word; end
"\e[3D": if test -z (commandline); prevd; else; commandline -f backward-word; end
"\e[3C": if test -z (commandline); nextd; else; commandline -f forward-word; end
"\C-d": delete-or-exit
$endif

20
input.c
View file

@ -874,17 +874,19 @@ static void add_common_bindings()
add_mapping( name[i], L"\x7f", L"Backspace", L"backward-delete-char" );
add_terminfo_mapping( name[i], (key_home), L"Home", L"beginning-of-line" );
add_terminfo_mapping( name[i], (key_end), L"End", L"end-of-line" );
add_mapping( name[i], L"\e\eOC", L"Alt-Right", L"forward-word" );
add_mapping( name[i], L"\e\eOD", L"Alt-Left", L"backward-word" );
add_mapping( name[i], L"\e\eOC", L"Alt-Right", L"nextd-or-forward-word" );
add_mapping( name[i], L"\e\eOD", L"Alt-Left", L"prevd-or-backward-word" );
add_mapping( name[i], L"\eO3C", L"Alt-Right", L"forward-word" );
add_mapping( name[i], L"\eO3D", L"Alt-Left", L"backward-word" );
add_mapping( name[i], L"\eO3C", L"Alt-Right", L"nextd-or-forward-word" );
add_mapping( name[i], L"\eO3D", L"Alt-Left", L"prevd-or-backward-word" );
add_mapping( name[i], L"\e[3C", L"Alt-Right", L"forward-word" );
add_mapping( name[i], L"\e[3D", L"Alt-Left", L"backward-word" );
add_mapping( name[i], L"\e[3C", L"Alt-Right", L"nextd-or-forward-word" );
add_mapping( name[i], L"\e[3D", L"Alt-Left", L"prevd-or-backward-word" );
add_mapping( name[i], L"\e[1;3C", L"Alt-Right", L"nextd-or-forward-word" );
add_mapping( name[i], L"\e[1;3D", L"Alt-Left", L"prevd-or-backward-word" );
add_mapping( name[i], L"\e\eOA", L"Alt-Up", L"history-token-search-backward" );
add_mapping( name[i], L"\e\eOB", L"Alt-Down", L"history-token-search-forward" );
@ -894,7 +896,9 @@ static void add_common_bindings()
add_mapping( name[i], L"\e[3A", L"Alt-Up", L"history-token-search-backward" );
add_mapping( name[i], L"\e[3B", L"Alt-Down", L"history-token-search-forward" );
add_mapping( name[i], L"\e[1;3A", L"Alt-Up", L"history-token-search-backward" );
add_mapping( name[i], L"\e[1;3B", L"Alt-Down", L"history-token-search-forward" );
}
/*

View file

@ -38,6 +38,14 @@ typedef struct block
wchar_t *function_description; /**< The description of the function to define */
};
/**
Third block type specific variable
*/
union
{
int function_is_binding; /**< Whether a function is a keybinding */
};
/**
Next outer block
*/