From e3ce01d6855c9330b1cd2dec19eff1139676c7db Mon Sep 17 00:00:00 2001 From: axel Date: Wed, 21 Sep 2005 09:42:00 +1000 Subject: [PATCH] Key binding functions darcs-hash:20050920234200-ac50b-3895a97cb024368258cd1562bdcc9fda2c84f521.gz --- ChangeLog | 7 +++++- Makefile.in | 3 ++- builtin.c | 40 +++++++++++++++++++++++++++++------ common.c | 2 +- doc_src/function.txt | 11 ++++++---- env_universal_common.c | 19 +++++++++++------ function.c | 10 ++++++--- function.h | 3 ++- init/fish_function.fish | 47 ++++++++++++++++++++++++++++------------- init/fish_inputrc | 11 +--------- input.c | 20 +++++++++++------- parser.h | 8 +++++++ 12 files changed, 123 insertions(+), 58 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52948c081..73010c957 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,12 @@ 2005-09-20 Axel Liljencrantz * 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 diff --git a/Makefile.in b/Makefile.in index 65b4b7e5f..1d81aa1bf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/builtin.c b/builtin.c index 92e4671bc..6dd429ea6 100644 --- a/builtin.c +++ b/builtin.c @@ -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); } diff --git a/common.c b/common.c index e26dc690b..1c3ccd036 100644 --- a/common.c +++ b/common.c @@ -18,6 +18,7 @@ parts of fish. #include #include #include +#include #if HAVE_NCURSES_H #include @@ -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*), diff --git a/doc_src/function.txt b/doc_src/function.txt index aa818493f..a8dba06f0 100644 --- a/doc_src/function.txt +++ b/doc_src/function.txt @@ -1,10 +1,13 @@ \section function function - create a function \subsection function-synopsis Synopsis - function NAME; BODY; end + function [OPTIONS] NAME; BODY; end \subsection function-description Description +- -d DESCRIPTION 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 - +BB will write hello whenever the user enters \c hi. @@ -27,7 +30,7 @@ are inserted into the environment variable will run the \c ls command, using the \c -l option, while passing on any additional files and switches to \c ls. - +A
 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.
- 
+
diff --git a/env_universal_common.c b/env_universal_common.c
index 3f28ade36..de81f197c 100644
--- a/env_universal_common.c
+++ b/env_universal_common.c
@@ -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) );
diff --git a/function.c b/function.c
index 385c8c898..b71eab883 100644
--- a/function.c
+++ b/function.c
@@ -8,7 +8,6 @@
 #include 
 #include 
 
-
 #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 );
 }
 
diff --git a/function.h b/function.h
index b0e8f1c3c..e70386de2 100644
--- a/function.h
+++ b/function.h
@@ -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.
diff --git a/init/fish_function.fish b/init/fish_function.fish
index 8c218a303..d73af23cb 100644
--- a/init/fish_function.fish
+++ b/init/fish_function.fish
@@ -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
+
diff --git a/init/fish_inputrc b/init/fish_inputrc
index 709969194..f252ca31a 100644
--- a/init/fish_inputrc
+++ b/init/fish_inputrc
@@ -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
 
diff --git a/input.c b/input.c
index 9abbb5d77..59894ea37 100644
--- a/input.c
+++ b/input.c
@@ -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" );
 	}
 
 	/*
diff --git a/parser.h b/parser.h
index 4c0f343df..215323816 100644
--- a/parser.h
+++ b/parser.h
@@ -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 
 	*/