Add a 'generic' type of event that can be emited from any piece of code or by the user. Use this event layer to perform interactive configuration startup at the correct time.

darcs-hash:20070819164230-75c98-f91b8a73de7bbbb500d80770ddf4d2d46ae592cc.gz
This commit is contained in:
liljencrantz 2007-08-20 02:42:30 +10:00
parent e464b4270c
commit ad02bb9b48
14 changed files with 446 additions and 264 deletions

View File

@ -215,7 +215,7 @@ ETC_DIR_FILES :=etc/config.fish.in etc/fish_inputrc
# Files in ./share/
#
SHARE_DIR_FILES :=share/config.fish.in share/config_interactive.fish.in
SHARE_DIR_FILES :=share/config.fish.in
#
@ -268,7 +268,7 @@ TRANSLATIONS := $(TRANSLATIONS_SRC:.po=.gmo)
# Make everything needed for installing fish
#
all: $(PROGRAMS) user_doc share/man etc/config.fish share/config.fish share/config_interactive.fish $(TRANSLATIONS)
all: $(PROGRAMS) user_doc share/man etc/config.fish share/config.fish $(TRANSLATIONS)
@echo fish has now been built.
@echo Use \'$(MAKE) install\' to install fish.
.PHONY: all
@ -576,7 +576,6 @@ install-force: all install-translations
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/man
$(INSTALL) -m 644 etc/config.fish $(DESTDIR)$(sysconfdir)/fish/
$(INSTALL) -m 644 share/config.fish $(DESTDIR)$(datadir)/fish/
$(INSTALL) -m 644 share/config_interactive.fish $(DESTDIR)$(datadir)/fish/
for i in $(COMPLETIONS_DIR_FILES); do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/completions/; \
done;
@ -857,7 +856,7 @@ rpm: fish-@PACKAGE_VERSION@.tar.bz2 fish.spec
distclean: clean
rm -f fish.spec Doxyfile.help
rm -f etc/config.fish share/config_interactive.fish seq share/config.fish
rm -f etc/config.fish seq share/config.fish
rm -f config.status config.log config.h Makefile
.PHONY: distclean

120
builtin.c
View File

@ -66,7 +66,6 @@
#include "path.h"
/**
The default prompt for the read command
*/
@ -731,6 +730,74 @@ static int builtin_builtin( wchar_t **argv )
return STATUS_BUILTIN_OK;
}
static int builtin_emit( wchar_t **argv )
{
int argc=builtin_count_args( argv );
woptind=0;
const static struct woption
long_options[] =
{
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
while( 1 )
{
int opt_index = 0;
int opt = wgetopt_long( argc,
argv,
L"h",
long_options,
&opt_index );
if( opt == -1 )
break;
switch( opt )
{
case 0:
if(long_options[opt_index].flag != 0)
break;
sb_printf( sb_err,
BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name );
builtin_print_help( argv[0], sb_err );
return STATUS_BUILTIN_ERROR;
case 'h':
builtin_print_help( argv[0], sb_out );
return STATUS_BUILTIN_OK;
case '?':
builtin_unknown_option( argv[0], argv[woptind-1] );
return STATUS_BUILTIN_ERROR;
}
}
for (; woptind < argc; woptind++ )
{
event_fire_generic( argv[woptind] );
}
return STATUS_BUILTIN_OK;
}
/**
A generic bultin that only supports showing a help message. This is
only a placeholder that prints the help message. Useful for
@ -859,12 +926,18 @@ static void functions_def( wchar_t *name, string_buffer_t *out )
break;
}
case EVENT_GENERIC:
{
sb_printf( out, L" --on-event %ls", next->param1.param );
break;
}
}
}
al_destroy( &ev );
named = function_get_named_arguments( name );
if( named )
{
@ -1143,6 +1216,10 @@ static int builtin_function( wchar_t **argv )
L"on-variable", required_argument, 0, 'v'
}
,
{
L"on-event", required_argument, 0, 'e'
}
,
{
L"help", no_argument, 0, 'h'
}
@ -1166,10 +1243,10 @@ static int builtin_function( wchar_t **argv )
int opt_index = 0;
int opt = wgetopt_long( argc,
argv,
L"d:s:j:p:v:haS",
long_options,
&opt_index );
argv,
L"d:s:j:p:v:e:haS",
long_options,
&opt_index );
if( opt == -1 )
break;
@ -1230,8 +1307,7 @@ static int builtin_function( wchar_t **argv )
}
e = halloc( current_block, sizeof(event_t));
if( !e )
DIE_MEM();
e->type = EVENT_VARIABLE;
e->param1.variable = halloc_wcsdup( current_block, woptarg );
e->function_name=0;
@ -1239,6 +1315,20 @@ static int builtin_function( wchar_t **argv )
break;
}
case 'e':
{
event_t *e;
e = halloc( current_block, sizeof(event_t));
e->type = EVENT_GENERIC;
e->param1.param = halloc_wcsdup( current_block, woptarg );
e->function_name=0;
al_push( events, e );
break;
}
case 'j':
case 'p':
{
@ -2281,9 +2371,7 @@ static int builtin_contains( wchar_t ** argv )
int argc;
argc = builtin_count_args( argv );
int i;
int res=STATUS_BUILTIN_OK;
wchar_t *needle;
wchar_t **haystack;
woptind=0;
@ -3177,10 +3265,6 @@ static int builtin_case( wchar_t **argv )
*/
const static builtin_data_t builtin_data[]=
{
{
L"exit", &builtin_exit, N_( L"Exit the shell" )
}
,
{
L"block", &builtin_block, N_( L"Temporarily block delivery of events" )
}
@ -3201,6 +3285,14 @@ const static builtin_data_t builtin_data[]=
L"contains", &builtin_contains, N_( L"Search for a specified string in a list" )
}
,
{
L"emit", &builtin_emit, N_( L"Emit an event" )
}
,
{
L"exit", &builtin_exit, N_( L"Exit the shell" )
}
,
{
L"function", &builtin_function, N_( L"Define a new function" )
}

23
doc_src/emit.txt Normal file
View File

@ -0,0 +1,23 @@
\section emit emit - Emit a generic event
\subsection block-synopsis Synopsis
<tt>emit EVENT_NAME</tt>
\subsection emit-description Description
The emit builtin fires a generic fish event. Such events can be caught by special functions called event handlers.
\subsection emit-example Example
The following code first defines an event handler for the generig
event named 'test_event', and then emits an event of that type.
<pre>
function event_test --on-event test_event
echo event test!!!
end
emit test_event
</pre>

View File

@ -1264,6 +1264,7 @@ specific event takes place. Events that can trigger a handler currently are:
- When a signal is delivered
- When a process or job exits
- When the value of a variable is updated
- When the prompt is about to be shown
Example:

47
event.c
View File

@ -91,6 +91,7 @@ static string_buffer_t *get_desc_buff=0;
*/
static int event_match( event_t *class, event_t *instance )
{
if( class->function_name && instance->function_name )
{
if( wcscmp( class->function_name, instance->function_name ) != 0 )
@ -103,15 +104,15 @@ static int event_match( event_t *class, event_t *instance )
if( class->type != instance->type )
return 0;
switch( class->type )
{
case EVENT_SIGNAL:
if( class->param1.signal == EVENT_ANY_SIGNAL )
return 1;
return class->param1.signal == instance->param1.signal;
case EVENT_VARIABLE:
return wcscmp( instance->param1.variable,
class->param1.variable )==0;
@ -123,6 +124,11 @@ static int event_match( event_t *class, event_t *instance )
case EVENT_JOB_ID:
return class->param1.job_id == instance->param1.job_id;
case EVENT_GENERIC:
return wcscmp( instance->param1.param,
class->param1.param )==0;
}
/**
@ -139,8 +145,10 @@ static int event_match( event_t *class, event_t *instance )
static event_t *event_copy( event_t *event, int copy_arguments )
{
event_t *e = malloc( sizeof( event_t ) );
if( !e )
DIE_MEM();
memcpy( e, event, sizeof(event_t));
if( e->function_name )
@ -148,6 +156,8 @@ static event_t *event_copy( event_t *event, int copy_arguments )
if( e->type == EVENT_VARIABLE )
e->param1.variable = wcsdup( e->param1.variable );
else if( e->type == EVENT_GENERIC )
e->param1.param = wcsdup( e->param1.param );
al_init( &e->arguments );
if( copy_arguments )
@ -246,6 +256,14 @@ const wchar_t *event_get_desc( event_t *e )
break;
}
case EVENT_GENERIC:
sb_printf( get_desc_buff, _(L"handler for generic event '%ls'"), e->param1.param );
break;
default:
sb_printf( get_desc_buff, _(L"Unknown event type") );
break;
}
return (const wchar_t *)get_desc_buff->buff;
@ -675,7 +693,30 @@ void event_free( event_t *e )
free( (void *)e->function_name );
if( e->type == EVENT_VARIABLE )
{
free( (void *)e->param1.variable );
}
else if( e->type == EVENT_GENERIC )
{
free( (void *)e->param1.param );
}
free( e );
}
void event_fire_generic(const wchar_t *name)
{
event_t ev;
CHECK( name, );
ev.type = EVENT_GENERIC;
ev.param1.param = name;
ev.function_name=0;
al_init( &ev.arguments );
event_fire( &ev );
}

13
event.h
View File

@ -27,6 +27,7 @@ enum
EVENT_VARIABLE, /**< An event triggered by a variable update */
EVENT_EXIT, /**< An event triggered by a job or process exit */
EVENT_JOB_ID, /**< An event triggered by a job exit */
EVENT_GENERIC, /**< A generic event */
}
;
@ -67,7 +68,11 @@ typedef struct
Job id for EVENT_JOB_ID type events
*/
int job_id;
/**
The parameter describing this generic event
*/
const wchar_t *param;
} param1;
/**
@ -142,4 +147,10 @@ void event_free( event_t *e );
*/
const wchar_t *event_get_desc( event_t *e );
/**
Fire a generic event with the specified name
*/
void event_fire_generic(const wchar_t *name);
#endif

View File

@ -140,7 +140,6 @@ fi
# Non-configuration initialization files
%dir %_datadir/fish
%_datadir/fish/config.fish
%_datadir/fish/config_interactive.fish
# Program specific tab-completions
%dir %_datadir/fish/completions

View File

@ -2149,12 +2149,13 @@ int exit_status()
*/
static int read_i()
{
event_fire_generic(L"fish_prompt");
reader_push(L"fish");
reader_set_complete_function( &complete );
reader_set_highlight_function( &highlight_shell );
reader_set_test_function( &reader_shell_test );
data->prev_end_loop=0;
while( (!data->end_loop) && (!sanity_check()) )

View File

@ -843,7 +843,7 @@ void s_write( screen_t *s,
}
s_desired_append_char( s, b[i], col, indent[i], prompt_width );
if( i== cursor && s->desired_cursor[1] != cursor_arr[1] && b[i] != L'\n' )
{
/**

View File

@ -5,6 +5,7 @@ complete -c function -s j -l on-job-exit --description "Make the function a job
complete -c function -s p -l on-process-exit --description "Make the function a process exit event handler" -x
complete -c function -s s -l on-signal --description "Make the function a signal event handler" -x
complete -c function -s v -l on-variable --description "Make the function a variable update event handler" -x
complete -c function -s v -l on-event --description "Make the function a generic event handler" -x
complete -c function -s b -l key-binding --description "Allow dash (-) in function name"
complete -c function -s a -l argument-names --description "Specify named arguments"
complete -c function -s S -l no-scope-shadowing --description "Do not shadow variable scope of calling function"

View File

@ -22,7 +22,11 @@ if set -q XDG_CONFIG_HOME
end
if not set -q __fish_datadir
set -U __fish_datadir @datadir@/fish
set -g __fish_datadir @datadir@/fish
end
if not set -q __fish_sysconfdir
set -g __fish_sysconfdir @sysconfdir@/fish
end
if not set -q fish_function_path
@ -44,24 +48,6 @@ if test -d /usr/xpg4/bin
end
end
#
# Make sure there are no invalid entries in the PATH
#
if status --is-interactive
set -l new_path
for i in $PATH
if not test -d $i
printf (_ '%s: Warning: The directory %s has been removed from your PATH because it does not exist\n') fish $i
else
set new_path $new_path $i
end
end
set PATH $new_path
end
#
# Add a few common directories to path, if they exists. Note that pure
# console programs like makedep sometimes live in /usr/X11R6/bin, so we
@ -71,7 +57,8 @@ end
set -l path_list /bin /usr/bin /usr/X11R6/bin @prefix@/bin @optbindirs@
# Root should also have the sbin directories in the path
if test "$USER" = root
switch $USER
case root
set path_list $path_list /sbin /usr/sbin /usr/local/sbin
end
@ -86,11 +73,18 @@ for i in (printf "%s\n" $path_list|sgrep -E -v $path_regexp)
end
end
#
# Launch debugger on SIGTRAP
#
function fish_sigtrap_handler --on-signal TRAP --no-scope-shadowing --description "Signal handler for the TRAP signal. Lanches a debug prompt."
breakpoint
end
if status --is-interactive
. config_interactive.fish
#
# Whenever a prompt is displayed, make sure that interactive
# mode-specific initializations have been performed.
#
function __fish_on_interactive --on-event fish_prompt
__fish_config_interactive
end

View File

@ -1,215 +0,0 @@
#
# Initializations that should only be performed when in interactive mode.
#
#
# @configure_input@
#
set -l configdir ~/.config
if set -q XDG_CONFIG_HOME
set configdir $XDG_CONFIG_HOME
end
if not set -q __fish_init_1_22_0
if test -f ~/.fish_history -o -f ~/.fish -o -d ~/.fish.d -a ! -d $configdir/fish
# Perform upgrade of configuration file hierarchy
if not test -d $configdir
command mkdir $configdir >/dev/null
end
if test -d $configdir
if command mkdir $configdir/fish
# These files are sometimes overwritten to by fish, so
# we want backups of them in case something goes wrong
cp ~/.fishd.(hostname) $configdir/fish/fishd.(hostname).backup
cp ~/.fish_history $configdir/fish/fish_history.backup
# Move the files
mv ~/.fish_history $configdir/fish/fish_history
mv ~/.fish $configdir/fish/config.fish
mv ~/.fish_inputrc $configdir/fish/fish_inputrc
mv ~/.fish.d/functions $configdir/fish/functions
mv ~/.fish.d/completions $configdir/fish/completions
#
# Move the fishd stuff from another shell to avoid concurrency problems
#
/bin/sh -c mv\ \~/.fishd.(hostname)\ $configdir/fish/fishd.(hostname)\;kill\ -9\ (echo %fishd)
# Update paths to point to new configuration locations
set fish_function_path (printf "%s\n" $fish_function_path|sed -e "s|@sysconfdir@/fish.d/|@sysconfdir@/fish/|")
set fish_complete_path (printf "%s\n" $fish_complete_path|sed -e "s|@sysconfdir@/fish.d/|@sysconfdir@/fish/|")
set fish_function_path (printf "%s\n" $fish_function_path|sed -e "s|$HOME/.fish.d/|$configdir/fish/|")
set fish_complete_path (printf "%s\n" $fish_complete_path|sed -e "s|$HOME/.fish.d/|$configdir/fish/|")
printf (_ "\nWARNING\n\nThe location for fish configuration files has changed to %s.\nYour old files have been moved to this location.\nYou can change to a different location by changing the value of the variable \$XDG_CONFIG_HOME.\n\n") $configdir
end ^/dev/null
end
end
# Make sure this is only done once
set -U __fish_init_1_22_0
end
#
# Print a greeting
#
if not set -q fish_greeting
set -l line1 (printf (_ 'Welcome to fish, the friendly interactive shell') )
set -l line2 (printf (_ 'Type %shelp%s for instructions on how to use fish') (set_color green) (set_color normal))
set -U fish_greeting $line1\n$line2
end
if test "$fish_greeting"
echo $fish_greeting
end
#
# Set exit message
#
function fish_on_exit --description "Commands to execute when fish exits" --on-process %self
printf (_ "Good bye\n")
end
#
# Set INPUTRC to something nice
#
# We override INPUTRC if already set, since it may be set by a shell
# other than fish, which may use a different file. The new value should
# be exported, since the fish inputrc file plays nice with other files
# by including them when found.
#
for i in $configdir/fish/fish_inputrc @sysconfdir@/fish/fish_inputrc ~/.inputrc /etc/inputrc
if test -f $i
set -xg INPUTRC $i
break
end
end
#
# Set various defaults using these throwaway functions
#
function set_default -d "Set an universal variable, unless it has already been set"
if not set -q $argv[1]
set -U -- $argv
end
end
# Regular syntax highlighting colors
set_default fish_color_normal normal
set_default fish_color_command green
set_default fish_color_redirection normal
set_default fish_color_comment red
set_default fish_color_error red --bold
set_default fish_color_escape cyan
set_default fish_color_operator cyan
set_default fish_color_quote brown
set_default fish_color_valid_path --underline
set_default fish_color_cwd green
# Background color for matching quotes and parenthesis
set_default fish_color_match cyan
# Background color for search matches
set_default fish_color_search_match purple
# Pager colors
set_default fish_pager_color_prefix cyan
set_default fish_pager_color_completion normal
set_default fish_pager_color_description normal
set_default fish_pager_color_progress cyan
#
# Directory history colors
#
set_default fish_color_history_current cyan
#
# Setup the CDPATH variable
#
set_default CDPATH . ~
#
# Remove temporary functions for setting default variable values
#
functions -e set_default
#
# This event handler makes sure the prompt is repainted when
# fish_color_cwd changes value. Like all event handlers, it can't be
# autoloaded.
#
function __fish_repaint --on-variable fish_color_cwd --description "Event handler, repaints the prompt when fish_color_cwd changes"
if status --is-interactive
set -e __fish_prompt_cwd
commandline -f repaint ^/dev/null
end
end
#
# A few minor convenience functions
#
# The naming heuristic is that __fish_complete_* prints completions
# and descriptions, while __fish_print_* only prints the completions
# and no descriptions
#
function __fish_complete_users --description "Print a list of local users, with the real user name as a description"
cat /etc/passwd | sed -e "s/^\([^:]*\):[^:]*:[^:]*:[^:]*:\([^:]*\):.*/\1\t\2/"
end
function __fish_complete_groups --description "Print a list of local groups, with group members as the description"
cat /etc/group | sed -e "s/^\([^:]*\):[^:]*:[^:]*:\(.*\)/\1\tMembers: \2/"
end
function __fish_complete_command --description "Complete using all available commands"
printf "%s\n" (commandline -ct)(complete -C (commandline -ct))
end
function __fish_print_interfaces --description "Print a list of known network interfaces"
netstat -i -n -a | awk 'NR>2'|awk '{print $1}'
end
function __fish_print_addresses --description "Print a list of known network addresses"
/sbin/ifconfig |sgrep 'inet addr'|cut -d : -f 2|cut -d ' ' -f 1
end
function __fish_print_users --description "Print a list of local users"
cat /etc/passwd | cut -d : -f 1
end
#
# Completions for SysV startup scripts
#
complete -x -p "/etc/init.d/*" -a start --description 'Start service'
complete -x -p "/etc/init.d/*" -a stop --description 'Stop service'
complete -x -p "/etc/init.d/*" -a status --description 'Print service status'
complete -x -p "/etc/init.d/*" -a restart --description 'Stop and then start service'
complete -x -p "/etc/init.d/*" -a reload --description 'Reload service configuration'

View File

@ -0,0 +1,235 @@
#
# Initializations that should only be performed when entering interactive mode.
#
#
# This function is called by the __fish_on_interactive function, which is defined in config.fish.
#
function __fish_config_interactive -d "Initializations that should be performed when entering interactive mode"
# Make sure this function is only run once
if set -q __fish_config_interactive_done
return
end
set -g __fish_config_interactive_done
# Set the correct configuration directory
set -l configdir ~/.config
if set -q XDG_CONFIG_HOME
set configdir $XDG_CONFIG_HOME
end
# Migrate old (pre 1.22.0) init scripts if they exist
if not set -q __fish_init_1_22_0
if test -f ~/.fish_history -o -f ~/.fish -o -d ~/.fish.d -a ! -d $configdir/fish
# Perform upgrade of configuration file hierarchy
if not test -d $configdir
command mkdir $configdir >/dev/null
end
if test -d $configdir
if command mkdir $configdir/fish
# These files are sometimes overwritten to by fish, so
# we want backups of them in case something goes wrong
cp ~/.fishd.(hostname) $configdir/fish/fishd.(hostname).backup
cp ~/.fish_history $configdir/fish/fish_history.backup
# Move the files
mv ~/.fish_history $configdir/fish/fish_history
mv ~/.fish $configdir/fish/config.fish
mv ~/.fish_inputrc $configdir/fish/fish_inputrc
mv ~/.fish.d/functions $configdir/fish/functions
mv ~/.fish.d/completions $configdir/fish/completions
#
# Move the fishd stuff from another shell to avoid concurrency problems
#
/bin/sh -c mv\ \~/.fishd.(hostname)\ $configdir/fish/fishd.(hostname)\;kill\ -9\ (echo %fishd)
# Update paths to point to new configuration locations
set fish_function_path (printf "%s\n" $fish_function_path|sed -e "s|/usr/local/etc/fish.d/|/usr/local/etc/fish/|")
set fish_complete_path (printf "%s\n" $fish_complete_path|sed -e "s|/usr/local/etc/fish.d/|/usr/local/etc/fish/|")
set fish_function_path (printf "%s\n" $fish_function_path|sed -e "s|$HOME/.fish.d/|$configdir/fish/|")
set fish_complete_path (printf "%s\n" $fish_complete_path|sed -e "s|$HOME/.fish.d/|$configdir/fish/|")
printf (_ "\nWARNING\n\nThe location for fish configuration files has changed to %s.\nYour old files have been moved to this location.\nYou can change to a different location by changing the value of the variable \$XDG_CONFIG_HOME.\n\n") $configdir
end ^/dev/null
end
end
# Make sure this is only done once
set -U __fish_init_1_22_0
end
#
# Print a greeting
#
if not set -q fish_greeting
set -l line1 (printf (_ 'Welcome to fish, the friendly interactive shell') )
set -l line2 (printf (_ 'Type %shelp%s for instructions on how to use fish') (set_color green) (set_color normal))
set -U fish_greeting $line1\n$line2
end
if test "$fish_greeting"
echo $fish_greeting
end
#
# Set exit message
#
function fish_on_exit --description "Commands to execute when fish exits" --on-process %self
printf (_ "Good bye\n")
end
#
# Set INPUTRC to something nice
#
# We override INPUTRC if already set, since it may be set by a shell
# other than fish, which may use a different file. The new value should
# be exported, since the fish inputrc file plays nice with other files
# by including them when found.
#
for i in $configdir/fish/fish_inputrc $__fish_sysconfdir/fish_inputrc ~/.inputrc /etc/inputrc
if test -f $i
set -xg INPUTRC $i
break
end
end
#
# Set various defaults using these throwaway functions
#
function set_default -d "Set an universal variable, unless it has already been set"
if not set -q $argv[1]
set -U -- $argv
end
end
# Regular syntax highlighting colors
set_default fish_color_normal normal
set_default fish_color_command green
set_default fish_color_redirection normal
set_default fish_color_comment red
set_default fish_color_error red --bold
set_default fish_color_escape cyan
set_default fish_color_operator cyan
set_default fish_color_quote brown
set_default fish_color_valid_path --underline
set_default fish_color_cwd green
set_default fish_color_cwd_root red
# Background color for matching quotes and parenthesis
set_default fish_color_match cyan
# Background color for search matches
set_default fish_color_search_match purple
# Pager colors
set_default fish_pager_color_prefix cyan
set_default fish_pager_color_completion normal
set_default fish_pager_color_description normal
set_default fish_pager_color_progress cyan
#
# Directory history colors
#
set_default fish_color_history_current cyan
#
# Setup the CDPATH variable
#
set_default CDPATH . ~
#
# Remove temporary functions for setting default variable values
#
functions -e set_default
#
# This event handler makes sure the prompt is repainted when
# fish_color_cwd changes value. Like all event handlers, it can't be
# autoloaded.
#
function __fish_repaint --on-variable fish_color_cwd --description "Event handler, repaints the prompt when fish_color_cwd changes"
if status --is-interactive
set -e __fish_prompt_cwd
commandline -f repaint ^/dev/null
end
end
function __fish_repaint_root --on-variable fish_color_cwd_root --description "Event handler, repaints the prompt when fish_color_cwd_root changes"
if status --is-interactive
set -e __fish_prompt_cwd
commandline -f repaint ^/dev/null
end
end
#
# A few minor convenience functions
#
# The naming heuristic is that __fish_complete_* prints completions
# and descriptions, while __fish_print_* only prints the completions
# and no descriptions
#
function __fish_complete_users --description "Print a list of local users, with the real user name as a description"
cat /etc/passwd | sed -e "s/^\([^:]*\):[^:]*:[^:]*:[^:]*:\([^:]*\):.*/\1\t\2/"
end
function __fish_complete_groups --description "Print a list of local groups, with group members as the description"
cat /etc/group | sed -e "s/^\([^:]*\):[^:]*:[^:]*:\(.*\)/\1\tMembers: \2/"
end
function __fish_complete_command --description "Complete using all available commands"
printf "%s\n" (commandline -ct)(complete -C (commandline -ct))
end
function __fish_print_interfaces --description "Print a list of known network interfaces"
netstat -i -n -a | awk 'NR>2'|awk '{print $1}'
end
function __fish_print_addresses --description "Print a list of known network addresses"
/sbin/ifconfig |sgrep 'inet addr'|cut -d : -f 2|cut -d ' ' -f 1
end
function __fish_print_users --description "Print a list of local users"
cat /etc/passwd | cut -d : -f 1
end
#
# Completions for SysV startup scripts
#
complete -x -p "/etc/init.d/*" -a start --description 'Start service'
complete -x -p "/etc/init.d/*" -a stop --description 'Stop service'
complete -x -p "/etc/init.d/*" -a status --description 'Print service status'
complete -x -p "/etc/init.d/*" -a restart --description 'Stop and then start service'
complete -x -p "/etc/init.d/*" -a reload --description 'Reload service configuration'
end

2
util.c
View File

@ -1317,7 +1317,7 @@ void sb_destroy( string_buffer_t * b )
void sb_clear( string_buffer_t * b )
{
sb_truncate( b, 0 );
assert( !wcslen( b->buff) );
assert( !wcslen( (wchar_t *)b->buff) );
}
void sb_truncate( string_buffer_t *b, int chars_left )