mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 04:43:10 +00:00
Autoloaded functions
darcs-hash:20060208092005-ac50b-8e784f79a4e158c8c15b553fad85002dccc7bd03.gz
This commit is contained in:
parent
47b652c76e
commit
73a9c8bcb8
31 changed files with 1319 additions and 1229 deletions
12
Makefile.in
12
Makefile.in
|
@ -171,6 +171,8 @@ TESTS_DIR_FILES := $(TEST_IN) $(TEST_IN:.in=.out) $(TEST_IN:.in=.err) \
|
|||
|
||||
COMPLETIONS_DIR_FILES := $(wildcard init/completions/*.fish)
|
||||
|
||||
FUNCTIONS_DIR_FILES := $(wildcard init/functions/*.fish)
|
||||
|
||||
# Programs to build
|
||||
PROGRAMS:=fish set_color @XSEL@ @SEQ_FALLBACK@ mimedb count fish_pager fishd
|
||||
|
||||
|
@ -262,7 +264,7 @@ doc.h:$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC) doc_src/doc.hdr
|
|||
fi
|
||||
|
||||
# Create a template translation object
|
||||
messages.pot: *.c *.h init/*.in init/*.fish init/completions/*.fish seq
|
||||
messages.pot: *.c *.h init/*.in init/*.fish init/completions/*.fish init/functions/*.fish seq
|
||||
if test $(HAVE_GETTEXT) = 1;then \
|
||||
xgettext -k_ -kN_ -kcomplete_desc *.c *.h -o messages.pot; \
|
||||
if ! xgettext -j -k_ -LShell init/*.in init/*.fish init/completions/*.fish seq -o messages.pot; then \
|
||||
|
@ -346,6 +348,7 @@ install: all install-translations
|
|||
done;
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)$(fishdir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)$(fishdir)/completions
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)$(fishdir)/functions
|
||||
$(INSTALL) -m 644 init/fish $(DESTDIR)$(sysconfdir)$(fishfile)
|
||||
for i in $(INIT_DIR_INSTALL); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)$(fishdir); \
|
||||
|
@ -353,6 +356,9 @@ install: all install-translations
|
|||
for i in $(COMPLETIONS_DIR_FILES); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)$(fishdir)/completions/; \
|
||||
done;
|
||||
for i in $(FUNCTIONS_DIR_FILES); do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)$(fishdir)/functions/; \
|
||||
done;
|
||||
$(INSTALL) -m 644 init/fish_inputrc $(DESTDIR)$(sysconfdir)$(fishinputfile);
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
|
||||
for i in user_doc/html/* ChangeLog; do \
|
||||
|
@ -450,18 +456,20 @@ depend:
|
|||
#
|
||||
# Uses install instead of mkdir so build won't fail if the directory
|
||||
# exists
|
||||
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(INIT_DIR_FILES) $(TEST_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog
|
||||
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(INIT_DIR_FILES) $(TEST_DIR_FILES) $(FUNCTIONS_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog
|
||||
rm -rf fish-@PACKAGE_VERSION@
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/doc_src
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/init
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/init/completions
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/init/functions
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/tests
|
||||
$(INSTALL) -d fish-@PACKAGE_VERSION@/po
|
||||
cp -f $(DOC_SRC_DIR_FILES) fish-@PACKAGE_VERSION@/doc_src
|
||||
cp -f $(MAIN_DIR_FILES) fish-@PACKAGE_VERSION@/
|
||||
cp -f $(INIT_DIR_FILES) fish-@PACKAGE_VERSION@/init/
|
||||
cp -f $(COMPLETIONS_DIR_FILES) fish-@PACKAGE_VERSION@/init/completions/
|
||||
cp -f $(FUNCTIONS_DIR_FILES) fish-@PACKAGE_VERSION@/init/functions/
|
||||
cp -f $(TESTS_DIR_FILES) fish-@PACKAGE_VERSION@/tests/
|
||||
cp -f $(TRANSLATIONS_SRC) fish-@PACKAGE_VERSION@/po/
|
||||
tar -c fish-@PACKAGE_VERSION@ >fish-@PACKAGE_VERSION@.tar
|
||||
|
|
1
common.c
1
common.c
|
@ -287,6 +287,7 @@ wchar_t *str2wcs( const char *in )
|
|||
{
|
||||
return out;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
in_pos += res;
|
||||
|
|
135
complete.c
135
complete.c
|
@ -215,11 +215,6 @@ static hash_table_t *suffix_hash=0;
|
|||
*/
|
||||
static hash_table_t *condition_cache=0;
|
||||
|
||||
/**
|
||||
Set of commands for which completions have already been loaded
|
||||
*/
|
||||
static hash_table_t *loaded_completions=0;
|
||||
|
||||
/**
|
||||
String buffer used by complete_get_desc
|
||||
*/
|
||||
|
@ -326,15 +321,6 @@ static void clear_hash_entry( const void *key, const void *data )
|
|||
free( (void *)data );
|
||||
}
|
||||
|
||||
/**
|
||||
Free hash value, but not hash key
|
||||
*/
|
||||
static void clear_hash_value( const void *key, const void *data )
|
||||
{
|
||||
free( (void *)data );
|
||||
}
|
||||
|
||||
|
||||
void complete_destroy()
|
||||
{
|
||||
complete_entry *i=first_entry, *prev;
|
||||
|
@ -355,15 +341,6 @@ void complete_destroy()
|
|||
suffix_hash=0;
|
||||
}
|
||||
|
||||
if( loaded_completions )
|
||||
{
|
||||
hash_foreach( loaded_completions,
|
||||
&clear_hash_value );
|
||||
hash_destroy( loaded_completions );
|
||||
free( loaded_completions );
|
||||
loaded_completions = 0;
|
||||
}
|
||||
|
||||
if( get_desc_buff )
|
||||
{
|
||||
sb_destroy( get_desc_buff );
|
||||
|
@ -1464,117 +1441,15 @@ static int short_ok( wchar_t *arg,
|
|||
return 1;
|
||||
}
|
||||
|
||||
void complete_load( wchar_t *cmd,
|
||||
int reload )
|
||||
static void complete_load_handler( const wchar_t *cmd )
|
||||
{
|
||||
const wchar_t *path_var;
|
||||
array_list_t path_list;
|
||||
int i;
|
||||
string_buffer_t path;
|
||||
time_t *tm;
|
||||
|
||||
/*
|
||||
First check that the specified completion hasn't already been loaded
|
||||
*/
|
||||
if( !loaded_completions )
|
||||
{
|
||||
loaded_completions = malloc( sizeof( hash_table_t ) );
|
||||
if( !loaded_completions )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
hash_init( loaded_completions, &hash_wcs_func, &hash_wcs_cmp );
|
||||
}
|
||||
|
||||
/*
|
||||
Get modification time of file
|
||||
*/
|
||||
tm = (time_t *)hash_get( loaded_completions, cmd );
|
||||
|
||||
/*
|
||||
Return if already loaded and we are skipping reloading
|
||||
*/
|
||||
if( !reload && tm )
|
||||
return;
|
||||
|
||||
/*
|
||||
Do we know where to look for completions?
|
||||
*/
|
||||
path_var = env_get( L"fish_complete_path" );
|
||||
if( !path_var )
|
||||
return;
|
||||
|
||||
al_init( &path_list );
|
||||
|
||||
sb_init( &path );
|
||||
|
||||
expand_variable_array( path_var, &path_list );
|
||||
|
||||
/*
|
||||
Iterate over path searching for suitable completion files
|
||||
*/
|
||||
for( i=0; i<al_get_count( &path_list ); i++ )
|
||||
{
|
||||
struct stat buf;
|
||||
wchar_t *next = (wchar_t *)al_get( &path_list, i );
|
||||
sb_clear( &path );
|
||||
sb_append2( &path, next, L"/", cmd, L".fish", (void *)0 );
|
||||
if( (wstat( (wchar_t *)path.buff, &buf )== 0) &&
|
||||
(waccess( (wchar_t *)path.buff, R_OK ) == 0) )
|
||||
{
|
||||
if( !tm || (*tm != buf.st_mtime ) )
|
||||
{
|
||||
wchar_t *esc = escape( (wchar_t *)path.buff, 1 );
|
||||
wchar_t *src_cmd = wcsdupcat( L". ", esc );
|
||||
|
||||
if( !tm )
|
||||
{
|
||||
tm = malloc(sizeof(time_t));
|
||||
if( !tm )
|
||||
die_mem();
|
||||
}
|
||||
|
||||
*tm = buf.st_mtime;
|
||||
hash_put( loaded_completions,
|
||||
intern( cmd ),
|
||||
tm );
|
||||
|
||||
free( esc );
|
||||
|
||||
complete_remove( cmd, COMMAND, 0, 0 );
|
||||
|
||||
/*
|
||||
Source the completion file for the specified completion
|
||||
*/
|
||||
exec_subshell( src_cmd, 0 );
|
||||
free(src_cmd);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If no file was found we insert a last modified time of Jan 1, 1970.
|
||||
This way, the completions_path wont be searched over and over again
|
||||
when reload is set to 0.
|
||||
*/
|
||||
if( !tm )
|
||||
{
|
||||
tm = malloc(sizeof(time_t));
|
||||
if( !tm )
|
||||
die_mem();
|
||||
|
||||
*tm = 0;
|
||||
hash_put( loaded_completions, intern( cmd ), tm );
|
||||
}
|
||||
|
||||
sb_destroy( &path );
|
||||
al_foreach( &path_list, (void (*)(const void *))&free );
|
||||
|
||||
al_destroy( &path_list );
|
||||
}
|
||||
|
||||
void complete_load( const wchar_t *name, int reload )
|
||||
{
|
||||
parse_util_load( name, env_get( L"fish_complete_path" ), &complete_load_handler, reload );
|
||||
}
|
||||
|
||||
/**
|
||||
Find completion for the argument str of command cmd_orig with
|
||||
|
|
|
@ -162,6 +162,6 @@ int complete_is_valid_argument( const wchar_t *str,
|
|||
\param cmd the command for which to load command-specific completions
|
||||
\param reload should the commands completions be reloaded, even if they where previously loaded. (This is set to true on actual completions, so that changed completion are updated in running shells)
|
||||
*/
|
||||
void complete_load( wchar_t *cmd, int reload );
|
||||
void complete_load( const wchar_t *cmd, int reload );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,6 +67,8 @@ fi
|
|||
%config %_sysconfdir/fish.d/fish_*.fish
|
||||
%dir %_sysconfdir/fish.d/completions
|
||||
%config %_sysconfdir/fish.d/completions/*.fish
|
||||
%dir %_sysconfdir/fish.d/functions
|
||||
%config %_sysconfdir/fish.d/functions/*.fish
|
||||
%_datadir/locale/*/LC_MESSAGES/fish.mo
|
||||
|
||||
%changelog
|
||||
|
|
60
function.c
60
function.c
|
@ -19,6 +19,7 @@
|
|||
#include "event.h"
|
||||
#include "reader.h"
|
||||
#include "parse_util.h"
|
||||
#include "env.h"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -33,6 +34,7 @@ typedef struct
|
|||
const wchar_t *definition_file;
|
||||
int definition_offset;
|
||||
int is_binding;
|
||||
int is_autoload;
|
||||
}
|
||||
function_data_t;
|
||||
|
||||
|
@ -40,6 +42,31 @@ typedef struct
|
|||
Table containing all functions
|
||||
*/
|
||||
static hash_table_t function;
|
||||
static int is_autoload = 0;
|
||||
|
||||
|
||||
static int load( const wchar_t *name )
|
||||
{
|
||||
int was_autoload = is_autoload;
|
||||
int res;
|
||||
function_data_t *data;
|
||||
data = (function_data_t *)hash_get( &function, name );
|
||||
if( data && !data->is_autoload )
|
||||
return 0;
|
||||
|
||||
is_autoload = 1;
|
||||
res = parse_util_load( name,
|
||||
env_get( L"fish_function_path" ),
|
||||
&function_remove,
|
||||
1 );
|
||||
is_autoload = was_autoload;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void load_all()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Free all contents of an entry to the function hash table
|
||||
|
@ -92,6 +119,7 @@ void function_add( const wchar_t *name,
|
|||
d->desc = desc?wcsdup( desc ):0;
|
||||
d->is_binding = is_binding;
|
||||
d->definition_file = intern(reader_current_filename());
|
||||
d->is_autoload = is_autoload;
|
||||
|
||||
hash_put( &function, intern(name), d );
|
||||
|
||||
|
@ -104,6 +132,11 @@ void function_add( const wchar_t *name,
|
|||
|
||||
int function_exists( const wchar_t *cmd )
|
||||
{
|
||||
function_data_t *data;
|
||||
if( parser_is_reserved(cmd) )
|
||||
return 0;
|
||||
|
||||
load( cmd );
|
||||
return (hash_get(&function, cmd) != 0 );
|
||||
}
|
||||
|
||||
|
@ -130,8 +163,9 @@ void function_remove( const wchar_t *name )
|
|||
|
||||
const wchar_t *function_get_definition( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
function_data_t *data;
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
return data->cmd;
|
||||
|
@ -139,8 +173,9 @@ const wchar_t *function_get_definition( const wchar_t *argv )
|
|||
|
||||
const wchar_t *function_get_desc( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
function_data_t *data;
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
|
@ -149,8 +184,9 @@ const wchar_t *function_get_desc( const wchar_t *argv )
|
|||
|
||||
void function_set_desc( const wchar_t *name, const wchar_t *desc )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, name );
|
||||
function_data_t *data;
|
||||
load( name );
|
||||
data = (function_data_t *)hash_get( &function, name );
|
||||
if( data == 0 )
|
||||
return;
|
||||
|
||||
|
@ -173,6 +209,8 @@ static void get_names_internal( const void *key,
|
|||
|
||||
void function_get_names( array_list_t *list, int get_hidden )
|
||||
{
|
||||
load_all();
|
||||
|
||||
if( get_hidden )
|
||||
hash_get_keys( &function, list );
|
||||
else
|
||||
|
@ -182,8 +220,9 @@ void function_get_names( array_list_t *list, int get_hidden )
|
|||
|
||||
const wchar_t *function_get_definition_file( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
function_data_t *data;
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
||||
|
@ -193,8 +232,9 @@ const wchar_t *function_get_definition_file( const wchar_t *argv )
|
|||
|
||||
int function_get_definition_offset( const wchar_t *argv )
|
||||
{
|
||||
function_data_t *data =
|
||||
(function_data_t *)hash_get( &function, argv );
|
||||
function_data_t *data;
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -87,6 +87,8 @@ if test 1 = "@HAVE_GETTEXT@"
|
|||
end
|
||||
end
|
||||
|
||||
set -g fish_function_path $PWD/fish.d/functions
|
||||
|
||||
#
|
||||
# Load additional initialization files
|
||||
#
|
||||
|
|
|
@ -14,16 +14,6 @@ end
|
|||
|
||||
set -g fish_complete_path @SYSCONFDIR@/fish.d/completions ~/.fish.d/completions
|
||||
|
||||
# Knowing the location of the whatis database speeds up command
|
||||
# description lookup.
|
||||
|
||||
for i in /var/cache/man/{whatis,windex} /usr{,/local}{,/share}/man/{whatis,windex}
|
||||
if test -f $i
|
||||
set -g __fish_whatis_path $i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Convenience functions
|
||||
#
|
||||
|
@ -32,55 +22,6 @@ end
|
|||
# without the description
|
||||
#
|
||||
|
||||
#
|
||||
# Find files that complete $argv[1], has the suffix $argv[2], and
|
||||
# output them as completions with description $argv[3]
|
||||
#
|
||||
|
||||
function __fish_complete_suffix -d "Complete using files"
|
||||
|
||||
set -- comp $argv[1]
|
||||
set -- suff $argv[2]
|
||||
set -- desc $argv[3]
|
||||
|
||||
set -- base (echo $comp |sed -e 's/\.[a-zA-Z0-9]*$//')
|
||||
eval "set -- files $base*$suff"
|
||||
|
||||
if test $files[1]
|
||||
printf "%s\t$desc\n" $files
|
||||
end
|
||||
|
||||
#
|
||||
# Also do directory completion, since there might be files
|
||||
# with the correct suffix in a subdirectory
|
||||
#
|
||||
|
||||
__fish_complete_directory $comp
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Find directories that complete $argv[1], output them as completions
|
||||
# with description $argv[2] if defined, otherwise use 'Directory'
|
||||
#
|
||||
|
||||
function __fish_complete_directory -d "Complete using directories"
|
||||
|
||||
set -- comp $argv[1]
|
||||
set -- desc (_ Directory)
|
||||
|
||||
if test (count $argv) -gt 1
|
||||
set desc $argv[2]
|
||||
end
|
||||
|
||||
eval "set -- dirs "$comp"*/"
|
||||
|
||||
if test $dirs[1]
|
||||
printf "%s\t$desc\n" $dirs
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function __fish_complete_users -d "Print a list of local users, with the real user name as a description"
|
||||
cat /etc/passwd | sed -e "s/^\([^:]*\):[^:]*:[^:]*:[^:]*:\([^:]*\):.*/\1\t\2/"
|
||||
end
|
||||
|
@ -101,42 +42,6 @@ function __fish_complete_command -d "Complete using all available commands"
|
|||
printf "%s\n" (commandline -ct)(complete -C (commandline -ct))
|
||||
end
|
||||
|
||||
function __fish_complete_subcommand -d "Complete subcommand"
|
||||
set -l res ""
|
||||
set -l had_cmd 0
|
||||
set -l cmd (commandline -cop) (commandline -ct)
|
||||
set -l skip_next 1
|
||||
|
||||
for i in $cmd
|
||||
|
||||
if test "$skip_next" = 1
|
||||
set skip_next 0
|
||||
continue
|
||||
end
|
||||
|
||||
if test "$had_cmd" = 1
|
||||
set res "$res $i"
|
||||
else
|
||||
|
||||
if contains -- $i $argv
|
||||
set skip_next 1
|
||||
continue
|
||||
end
|
||||
|
||||
switch $i
|
||||
case '-*'
|
||||
|
||||
case '*'
|
||||
set had_cmd 1
|
||||
set res $i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
printf "%s\n" (commandline -ct)(complete -C $res)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
function __fish_print_hostnames -d "Print a list of known hostnames"
|
||||
|
@ -166,59 +71,6 @@ function __fish_print_users -d "Print a list of local users"
|
|||
cat /etc/passwd | cut -d : -f 1
|
||||
end
|
||||
|
||||
|
||||
function __fish_contains_opt -d "Checks if a specific option has been given in the current commandline"
|
||||
set -l next_short
|
||||
|
||||
set -l short_opt
|
||||
set -l long_opt
|
||||
|
||||
for i in $argv
|
||||
if test $next_short
|
||||
set next_short
|
||||
set -- short_opt $short_opt $i
|
||||
else
|
||||
switch $i
|
||||
case -s
|
||||
set next_short 1
|
||||
case '-*'
|
||||
echo __fish_contains_opt: Unknown option $i
|
||||
return 1
|
||||
|
||||
case '**'
|
||||
set -- long_opt $long_opt $i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i in $short_opt
|
||||
|
||||
if test -z $i
|
||||
continue
|
||||
end
|
||||
|
||||
if commandline -cpo | grep -- "^-"$i"\|^-[^-]*"$i >/dev/null
|
||||
return 0
|
||||
end
|
||||
|
||||
if commandline -ct | grep -- "^-"$i"\|^-[^-]*"$i >/dev/null
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
for i in $long_opt
|
||||
if test -z $i
|
||||
continue
|
||||
end
|
||||
|
||||
if contains -- --$i (commandline -cpo)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return 1
|
||||
end
|
||||
|
||||
#
|
||||
# Completions for the shell and it's builtin commands and functions
|
||||
#
|
||||
|
@ -231,61 +83,6 @@ end
|
|||
|
||||
|
||||
|
||||
function __fish_print_packages
|
||||
|
||||
# apt-cache is much, much faster than rpm, and can do this in real
|
||||
# time. We use it if available.
|
||||
|
||||
switch (commandline -tc)
|
||||
case '-**'
|
||||
return
|
||||
end
|
||||
|
||||
#Get the word 'Package' in the current language
|
||||
set -l package (_ Package)
|
||||
|
||||
if which apt-cache >/dev/null ^/dev/null
|
||||
# Apply the following filters to output of apt-cache:
|
||||
# 1) Remove package names with parentesis in them, since these seem to not correspond to actual packages as reported by rpm
|
||||
# 2) Remove package names that are .so files, since these seem to not correspond to actual packages as reported by rpm
|
||||
# 3) Remove path information such as /usr/bin/, as rpm packages do not have paths
|
||||
|
||||
apt-cache --no-generate pkgnames (commandline -tc)|grep -v \( |grep -v '\.so\(\.[0-9]\)*$'|sed -e 's/\/.*\///'|sed -e 's/$/\t'$package'/'
|
||||
return
|
||||
end
|
||||
|
||||
# Rpm is too slow for this job, so we set it up to do completions
|
||||
# as a background job and cache the results.
|
||||
|
||||
if which rpm >/dev/null ^/dev/null
|
||||
|
||||
# If the cache is less than five minutes old, we do not recalculate it
|
||||
|
||||
set cache_file /tmp/.rpm-cache.$USER
|
||||
if test -f $cache_file
|
||||
cat $cache_file
|
||||
set age (echo (date +%s) - (stat -c '%Y' $cache_file) | bc)
|
||||
set max_age 250
|
||||
if test $age -lt $max_age
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Remove package version information from output and pipe into cache file
|
||||
rpm -qa >$cache_file |sed -e 's/-[^-]*-[^-]*$//' | sed -e 's/$/\t'$package'/' &
|
||||
end
|
||||
|
||||
# This completes the package name from the portage tree.
|
||||
# True for installing new packages. Function for printing
|
||||
# installed on the system packages is in completions/emerge.fish
|
||||
if which emerge >/dev/null ^/dev/null
|
||||
emerge -s \^(commandline -tc) |grep "^*" |cut -d\ -f3 |cut -d/ -f2
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function __fish_append -d "Internal completion function for appending string to the commandline"
|
||||
set separator $argv[1]
|
||||
set -e argv[1]
|
||||
|
@ -293,35 +90,6 @@ function __fish_append -d "Internal completion function for appending string to
|
|||
printf "%s\n" "$str"$argv "$str"(printf "%s\n" $argv|sed -e "s/\(\t\|\$\)/,\1/")
|
||||
end
|
||||
|
||||
function __fish_gnu_complete -d "Wrapper for the complete builtin. Skips the long completions on non-GNU systems"
|
||||
set is_gnu 0
|
||||
|
||||
# Check if we are using a gnu system
|
||||
for i in (seq (count $argv))
|
||||
switch $argv[$i]
|
||||
|
||||
case -g --is-gnu
|
||||
set -e argv[$i]
|
||||
set is_gnu 1
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Remove long option if not on a gnu system
|
||||
if test $is_gnu = 0
|
||||
for i in (seq (count $argv))
|
||||
if test $argv[$i] = -l
|
||||
set -e argv[$i]
|
||||
set -e argv[$i]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
complete $argv
|
||||
|
||||
end
|
||||
|
||||
function __fish_is_first_token -d 'Test if no non-switch argument has been specified yet'
|
||||
set -- cmd (commandline -poc)
|
||||
set -e -- cmd[1]
|
||||
|
|
|
@ -47,117 +47,6 @@ function contains -d "Test if a key is contained in a set of values"
|
|||
end
|
||||
|
||||
|
||||
#
|
||||
# help should use 'open' to find a suitable browser, but only
|
||||
# if there is a mime database _and_ DISPLAY is set, since the
|
||||
# browser will most likely be graphical. Since most systems which
|
||||
# have a mime databe also have the htmlview program, this is mostly a
|
||||
# theoretical problem.
|
||||
#
|
||||
|
||||
function help -d "Show help for the fish shell"
|
||||
|
||||
# Declare variables to set correct scope
|
||||
set -l fish_browser
|
||||
set -l fish_browser_bg
|
||||
|
||||
set -l h syntax completion editor job-control todo bugs history killring help
|
||||
set h $h color prompt title variables builtin-overview changes expand
|
||||
set h $h expand-variable expand-home expand-brace expand-wildcard
|
||||
set -l help_topics $h expand-command-substitution expand-process
|
||||
|
||||
#
|
||||
# Find a suitable browser for viewing the help pages. This is needed
|
||||
# by the help function defined below.
|
||||
#
|
||||
set -l graphical_browsers htmlview x-www-browser firefox galeon mozilla konqueror epiphany opera netscape
|
||||
set -l text_browsers htmlview www-browser links elinks lynx w3m
|
||||
|
||||
if test $BROWSER
|
||||
# User has manualy set a preferred browser, so we respect that
|
||||
set fish_browser $BROWSER
|
||||
|
||||
# If browser is known to be graphical, put into background
|
||||
if contains -- $BROWSER $graphical_browsers
|
||||
set fish_browser_bg 1
|
||||
end
|
||||
else
|
||||
# Check for a text-based browser.
|
||||
for i in $text_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
set fish_browser $i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# If we are in a graphical environment, check if there is a graphical
|
||||
# browser to use instead.
|
||||
if test "$DISPLAY" -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \)
|
||||
for i in $graphical_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
set fish_browser $i
|
||||
set fish_browser_bg 1
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if test -z $fish_browser
|
||||
printf (_ '%s: Could not find a web browser.\n') help
|
||||
printf (_ 'Please set the variable $BROWSER to a suitable browser and try again\n\n')
|
||||
return 1
|
||||
end
|
||||
|
||||
set fish_help_item $argv[1]
|
||||
|
||||
switch "$fish_help_item"
|
||||
case ""
|
||||
set fish_help_page index.html
|
||||
case "."
|
||||
set fish_help_page "builtins.html\#source"
|
||||
case difference
|
||||
set fish_help_page difference.html
|
||||
case globbing
|
||||
set fish_help_page "index.html\#expand"
|
||||
case (builtin -n)
|
||||
set fish_help_page "builtins.html\#$fish_help_item"
|
||||
case contains count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize psub umask type vared
|
||||
set fish_help_page "commands.html\#$fish_help_item"
|
||||
case $help_topics
|
||||
set fish_help_page "index.html\#$fish_help_item"
|
||||
case "*"
|
||||
if which $fish_help_item >/dev/null ^/dev/null
|
||||
man $fish_help_item
|
||||
return
|
||||
end
|
||||
set fish_help_page "index.html"
|
||||
end
|
||||
|
||||
if test $fish_browser_bg
|
||||
eval $fish_browser file://$__fish_help_dir/$fish_help_page \&
|
||||
else
|
||||
eval $fish_browser file://$__fish_help_dir/$fish_help_page
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Make ls use colors if we are on a system that supports this
|
||||
#
|
||||
|
||||
if ls --version 1>/dev/null 2>/dev/null
|
||||
# This is GNU ls
|
||||
function ls -d "List contents of directory"
|
||||
command ls --color=auto --indicator-style=classify $argv
|
||||
end
|
||||
else
|
||||
# BSD, OS X and a few more support colors through the -G switch instead
|
||||
if ls / -G 1>/dev/null 2>/dev/null
|
||||
function ls -d "List contents of directory"
|
||||
command ls -G $argv
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# These are very common and useful
|
||||
|
@ -170,16 +59,6 @@ function la -d "List contents of directory using long format, showing hidden fil
|
|||
ls -lha $argv
|
||||
end
|
||||
|
||||
#
|
||||
# This allows us to use 'open FILENAME' to open a given file in the default
|
||||
# application for the file.
|
||||
#
|
||||
|
||||
if not test (uname) = Darwin
|
||||
function open -d "Open file in default application"
|
||||
mimedb -l -- $argv
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Print the current working directory in a shortened form.This
|
||||
|
@ -214,52 +93,6 @@ function pwd -d "Print working directory"
|
|||
command pwd | sed -e 's|/private||' -e "s|^$HOME|~|"
|
||||
end
|
||||
|
||||
#
|
||||
# This is a neat function, stolen from zsh. It allows you to edit the
|
||||
# value of a variable interactively.
|
||||
#
|
||||
|
||||
function vared -d "Edit variable value"
|
||||
if test (count $argv) = 1
|
||||
switch $argv
|
||||
|
||||
case '-h' '--h' '--he' '--hel' '--help'
|
||||
help vared
|
||||
|
||||
case '-*'
|
||||
printf (_ "%s: Unknown option %s\n") vared $argv
|
||||
|
||||
case '*'
|
||||
if test (count $$argv ) -lt 2
|
||||
set init ''
|
||||
if test $$argv
|
||||
set -- init $$argv
|
||||
end
|
||||
set prompt 'set_color green; echo '$argv'; set_color normal; echo "> "'
|
||||
read -p $prompt -c $init tmp
|
||||
|
||||
# If variable already exists, do not add any
|
||||
# switches, so we don't change export rules. But
|
||||
# if it does not exist, we make the variable
|
||||
# global, so that it will not die when this
|
||||
# function dies
|
||||
|
||||
if test $$argv
|
||||
set -- $argv $tmp
|
||||
else
|
||||
set -g -- $argv $tmp
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
printf (_ '%s: %s is an array variable. Use %svared%s %s[n] to edit the n:th element of %s\n') $argv (set_color $fish_color_command) (set_color $fish_color_normal) vared $argv $argv
|
||||
end
|
||||
end
|
||||
else
|
||||
printf (_ '%s: Expected exactly one argument, got %s.\n\nSynopsis:\n\t%svared%s VARIABLE\n') vared (count $argv) (set_color $fish_color_command) (set_color $fish_color_normal)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# This function is used internally by the fish command completion code
|
||||
#
|
||||
|
@ -360,160 +193,6 @@ function cd -d "Change directory"
|
|||
end
|
||||
|
||||
|
||||
function __fish_move_last -d "Move the last element of a directory history from src to dest"
|
||||
set -l src $argv[1]
|
||||
set -l dest $argv[2]
|
||||
|
||||
set -l size_src (count $$src)
|
||||
|
||||
if test $size_src = 0
|
||||
# Cannot make this step
|
||||
printf (_ "Hit end of history...\n")
|
||||
return 1
|
||||
end
|
||||
|
||||
# Append current dir to the end of the destination
|
||||
set -g (echo $dest) $$dest (command pwd)
|
||||
|
||||
set ssrc $$src
|
||||
|
||||
# Change dir to the last entry in the source dir-hist
|
||||
builtin cd $ssrc[$size_src]
|
||||
|
||||
# Keep all but the last from the source dir-hist
|
||||
set -e (echo $src)[$size_src]
|
||||
|
||||
# All ok, return success
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
function prevd -d "Move back in the directory history"
|
||||
# Parse arguments
|
||||
set -l show_hist 0
|
||||
set -l times 1
|
||||
for i in (seq (count $argv))
|
||||
switch $argv[$i]
|
||||
case '-l' --l --li --lis --list
|
||||
set show_hist 1
|
||||
continue
|
||||
case '-*'
|
||||
printf (_ "%s: Unknown option %s\n" ) prevd $argv[$i]
|
||||
return 1
|
||||
case '*'
|
||||
if test $argv[$i] -ge 0 ^/dev/null
|
||||
set times $argv[$i]
|
||||
else
|
||||
printf (_ "The number of positions to skip must be a non-negative integer\n")
|
||||
return 1
|
||||
end
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
# Traverse history
|
||||
set -l code 1
|
||||
for i in (seq $times)
|
||||
# Try one step backward
|
||||
if __fish_move_last dirprev dirnext;
|
||||
# We consider it a success if we were able to do at least 1 step
|
||||
# (low expectations are the key to happiness ;)
|
||||
set code 0
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Show history if needed
|
||||
if test $show_hist = 1
|
||||
dirh
|
||||
end
|
||||
|
||||
# Set direction for 'cd -'
|
||||
if test $code = 0 ^/dev/null
|
||||
set -g __fish_cd_direction next
|
||||
end
|
||||
|
||||
# All done
|
||||
return $code
|
||||
end
|
||||
|
||||
|
||||
function nextd -d "Move forward in the directory history"
|
||||
# Parse arguments
|
||||
set -l show_hist 0
|
||||
set -l times 1
|
||||
for i in (seq (count $argv))
|
||||
switch $argv[$i]
|
||||
case '-l' --l --li --lis --list
|
||||
set show_hist 1
|
||||
continue
|
||||
case '-*'
|
||||
printf (_ "%s: Unknown option %s\n" ) nextd $argv[$i]
|
||||
return 1
|
||||
case '*'
|
||||
if test $argv[$i] -ge 0 ^/dev/null
|
||||
set times $argv[$i]
|
||||
else
|
||||
printf (_ "%s: The number of positions to skip must be a non-negative integer\n" ) nextd
|
||||
return 1
|
||||
end
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
# Traverse history
|
||||
set -l code 1
|
||||
for i in (seq $times)
|
||||
# Try one step backward
|
||||
if __fish_move_last dirnext dirprev;
|
||||
# We consider it a success if we were able to do at least 1 step
|
||||
# (low expectations are the key to happiness ;)
|
||||
set code 0
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Show history if needed
|
||||
if test $show_hist = 1
|
||||
dirh
|
||||
end
|
||||
|
||||
# Set direction for 'cd -'
|
||||
if test $code = 0 ^/dev/null
|
||||
set -g __fish_cd_direction prev
|
||||
end
|
||||
|
||||
# All done
|
||||
return $code
|
||||
end
|
||||
|
||||
|
||||
function dirh -d "Print the current directory history (the back- and fwd- lists)"
|
||||
# Avoid set comment
|
||||
set -l current (command pwd)
|
||||
set -l separator " "
|
||||
set -l line_len (echo (count $dirprev) + (echo $dirprev $current $dirnext | wc -m) | bc)
|
||||
if test $line_len -gt $COLUMNS
|
||||
# Print one entry per line if history is long
|
||||
set separator "\n"
|
||||
end
|
||||
|
||||
for i in $dirprev
|
||||
echo -n -e $i$separator
|
||||
end
|
||||
|
||||
set_color $fish_color_history_current
|
||||
echo -n -e $current$separator
|
||||
set_color normal
|
||||
|
||||
for i in (seq (echo (count $dirnext)) -1 1)
|
||||
echo -n -e $dirnext[$i]$separator
|
||||
end
|
||||
|
||||
echo
|
||||
end
|
||||
|
||||
function __bold -d "Print argument in bold"
|
||||
set_color --bold
|
||||
|
@ -522,536 +201,6 @@ function __bold -d "Print argument in bold"
|
|||
end
|
||||
|
||||
|
||||
function __trap_translate_signal
|
||||
set upper (echo $argv[1]|tr a-z A-Z)
|
||||
if expr $upper : 'SIG.*' >/dev/null
|
||||
echo $upper | cut -c 4-
|
||||
else
|
||||
echo $upper
|
||||
end
|
||||
end
|
||||
|
||||
function __trap_switch
|
||||
|
||||
switch $argv[1]
|
||||
case EXIT
|
||||
echo --on-exit %self
|
||||
|
||||
case '*'
|
||||
echo --on-signal $argv[1]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function trap -d 'Perform an action when the shell recives a signal'
|
||||
|
||||
set -l mode
|
||||
set -l cmd
|
||||
set -l sig
|
||||
set -l shortopt
|
||||
set -l longopt
|
||||
|
||||
set -l shortopt -o lph
|
||||
set -l longopt
|
||||
if not getopt -T >/dev/null
|
||||
set longopt -l print,help,list-signals
|
||||
end
|
||||
|
||||
if not getopt -n type -Q $shortopt $longopt -- $argv
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
eval set opt $tmp
|
||||
|
||||
while count $opt >/dev/null
|
||||
switch $opt[1]
|
||||
case -h --help
|
||||
help trap
|
||||
return 0
|
||||
|
||||
case -p --print
|
||||
set mode print
|
||||
|
||||
case -l --list-signals
|
||||
set mode list
|
||||
|
||||
case --
|
||||
set -e opt[1]
|
||||
break
|
||||
|
||||
end
|
||||
set -e opt[1]
|
||||
end
|
||||
|
||||
if not count $mode >/dev/null
|
||||
|
||||
switch (count $opt)
|
||||
|
||||
case 0
|
||||
set mode print
|
||||
|
||||
case 1
|
||||
set mode clear
|
||||
|
||||
case '*'
|
||||
if test opt[1] = -
|
||||
set -e opt[1]
|
||||
set mode clear
|
||||
else
|
||||
set mode set
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
switch $mode
|
||||
case clear
|
||||
for i in $opt
|
||||
set -- sig (__trap_translate_signal $i)
|
||||
if test $sig
|
||||
functions -e __trap_handler_$sig
|
||||
end
|
||||
end
|
||||
|
||||
case set
|
||||
set -l cmd $opt[1]
|
||||
set -e opt[1]
|
||||
|
||||
for i in $opt
|
||||
|
||||
set -l -- sig (__trap_translate_signal $i)
|
||||
set -- sw (__trap_switch $sig)
|
||||
|
||||
if test $sig
|
||||
eval "function __trap_handler_$sig $sw; $cmd; end"
|
||||
else
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
case print
|
||||
set -l names
|
||||
|
||||
if count $opt >/dev/null
|
||||
set -- names $opt
|
||||
else
|
||||
set -- names (functions -na|grep "^__trap_handler_"|sed -e 's/__trap_handler_//' )
|
||||
end
|
||||
|
||||
for i in $names
|
||||
|
||||
set -- sig (__trap_translate_signal $i)
|
||||
|
||||
if test sig
|
||||
functions __trap_handler_$i
|
||||
else
|
||||
return 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
case list
|
||||
kill -l
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function type -d "Print the type of a command"
|
||||
|
||||
# Initialize
|
||||
set -l status 1
|
||||
set -l mode normal
|
||||
set -l selection all
|
||||
|
||||
#
|
||||
# Get options
|
||||
#
|
||||
set -l shortopt -o tpPafh
|
||||
set -l longopt
|
||||
if not getopt -T >/dev/null
|
||||
set longopt -l type,path,force-path,all,no-functions,help
|
||||
end
|
||||
|
||||
if not getopt -n type -Q $shortopt $longopt -- $argv
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
set -l opt
|
||||
eval set opt $tmp
|
||||
|
||||
for i in $opt
|
||||
switch $i
|
||||
case -t --type
|
||||
set mode type
|
||||
|
||||
case -p --path
|
||||
set mode path
|
||||
|
||||
case -P --force-path
|
||||
set mode path
|
||||
set selection files
|
||||
|
||||
case -a --all
|
||||
set selection multi
|
||||
|
||||
case -f --no-functions
|
||||
set selection files
|
||||
|
||||
case -h --help
|
||||
help type
|
||||
return 0
|
||||
|
||||
case --
|
||||
break
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# Check all possible types for the remaining arguments
|
||||
for i in $argv
|
||||
|
||||
switch $i
|
||||
case '-*'
|
||||
continue
|
||||
end
|
||||
|
||||
# Found will be set to 1 if a match is found
|
||||
set found 0
|
||||
|
||||
if test $selection != files
|
||||
|
||||
if contains -- $i (functions -na)
|
||||
set status 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
printf (_ '%s is a function with definition\n') $i
|
||||
functions $i
|
||||
|
||||
case type
|
||||
printf (_ 'function\n')
|
||||
|
||||
case path
|
||||
echo
|
||||
|
||||
end
|
||||
if test $selection != multi
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
if contains -- $i (builtin -n)
|
||||
set status 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
printf (_ '%s is a builtin\n') $i
|
||||
|
||||
case type
|
||||
printf (_ 'builtin\n')
|
||||
|
||||
case path
|
||||
echo
|
||||
end
|
||||
if test $selection != multi
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if which $i ^/dev/null >/dev/null
|
||||
set status 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
printf (_ '%s is %s\n') $i (which $i)
|
||||
|
||||
case type
|
||||
printf (_ 'file\n')
|
||||
|
||||
case path
|
||||
which $i
|
||||
end
|
||||
if test $selection != multi
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
if test $found = 0
|
||||
printf (_ "%s: Could not find '%s'") type $i
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return $status
|
||||
end
|
||||
|
||||
function __fish_umask_parse -d "Parses a file permission specification as into an octal version"
|
||||
# Test if already a valid octal mask, and pad it with zeros
|
||||
if echo $argv | grep -E '^(0|)[0-7]{1,3}$' >/dev/null
|
||||
for i in (seq (echo 5-(echo $argv|wc -c)|bc)); set argv 0$argv; end
|
||||
echo $argv
|
||||
else
|
||||
# Test if argument really is a valid symbolic mask
|
||||
if not echo $argv | grep -E '^(((u|g|o|a|)(=|\+|-)|)(r|w|x)*)(,(((u|g|o|a|)(=|\+|-)|)(r|w|x)*))*$' >/dev/null
|
||||
printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l implicit_all
|
||||
|
||||
# Insert inverted umask into res variable
|
||||
|
||||
set -l mode
|
||||
set -l val
|
||||
set -l tmp $umask
|
||||
set -l res
|
||||
|
||||
for i in 1 2 3
|
||||
set tmp (echo $tmp|cut -c 2-)
|
||||
set res[$i] (echo 7-(echo $tmp|cut -c 1)|bc)
|
||||
end
|
||||
|
||||
set -l el (echo $argv|tr , \n)
|
||||
for i in $el
|
||||
switch $i
|
||||
case 'u*'
|
||||
set idx 1
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case 'g*'
|
||||
set idx 2
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case 'o*'
|
||||
set idx 3
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case 'a*'
|
||||
set idx 1 2 3
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '*'
|
||||
set implicit_all 1
|
||||
set idx 1 2 3
|
||||
end
|
||||
|
||||
switch $i
|
||||
case '=*'
|
||||
set mode set
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '+*'
|
||||
set mode add
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '-*'
|
||||
set mode remove
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '*'
|
||||
if not count $implicit_all >/dev/null
|
||||
printf (_ "%s: Invalid mask %s\n") umask $argv >&2
|
||||
return
|
||||
end
|
||||
set mode set
|
||||
end
|
||||
|
||||
if not echo $perm|grep -E '^(r|w|x)*$' >/dev/null
|
||||
printf (_ "%s: Invalid mask %s\n") umask $argv >&2
|
||||
return
|
||||
end
|
||||
|
||||
set val 0
|
||||
if echo $i |grep 'r' >/dev/null
|
||||
set val 4
|
||||
end
|
||||
if echo $i |grep 'w' >/dev/null
|
||||
set val (echo $val + 2|bc)
|
||||
end
|
||||
if echo $i |grep 'x' >/dev/null
|
||||
set val (echo $val + 1|bc)
|
||||
end
|
||||
|
||||
for j in $idx
|
||||
switch $mode
|
||||
case set
|
||||
set res[$j] $val
|
||||
|
||||
case add
|
||||
set res[$j] (perl -e 'print( ( '$res[$j]'|'$val[$j]' )."\n" )')
|
||||
|
||||
case remove
|
||||
set res[$j] (perl -e 'print( ( (7-'$res[$j]')&'$val[$j]' )."\n" )')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i in 1 2 3
|
||||
set res[$i] (echo 7-$res[$i]|bc)
|
||||
end
|
||||
echo 0$res[1]$res[2]$res[3]
|
||||
end
|
||||
end
|
||||
|
||||
function __fish_umask_print_symbolic
|
||||
set -l res ""
|
||||
set -l letter a u g o
|
||||
|
||||
for i in 2 3 4
|
||||
set res $res,$letter[$i]=
|
||||
set val (echo $umask|cut -c $i)
|
||||
|
||||
if contains $val 0 1 2 3
|
||||
set res {$res}r
|
||||
end
|
||||
|
||||
if contains $val 0 1 4 5
|
||||
set res {$res}w
|
||||
end
|
||||
|
||||
if contains $val 0 2 4 6
|
||||
set res {$res}x
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
echo $res|cut -c 2-
|
||||
end
|
||||
|
||||
function umask -d "Set default file permission mask"
|
||||
|
||||
set -l as_command 0
|
||||
set -l symbolic 0
|
||||
|
||||
set -l shortopt -o pSh
|
||||
set -l longopt
|
||||
if not getopt -T >/dev/null
|
||||
set longopt -l as-command,symbolic,help
|
||||
end
|
||||
|
||||
if not getopt -n umask -Q $shortopt $longopt -- $argv
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
eval set opt $tmp
|
||||
|
||||
while count $opt >/dev/null
|
||||
|
||||
switch $opt[1]
|
||||
case -h --help
|
||||
help umask
|
||||
return 0
|
||||
|
||||
case -p --as-command
|
||||
set as_command 1
|
||||
|
||||
case -S --symbolic
|
||||
set symbolic 1
|
||||
|
||||
case --
|
||||
set -e opt[1]
|
||||
break
|
||||
|
||||
end
|
||||
|
||||
set -e opt[1]
|
||||
|
||||
end
|
||||
|
||||
switch (count $opt)
|
||||
|
||||
case 0
|
||||
if not set -q umask
|
||||
set -g umask 113
|
||||
end
|
||||
if test $as_command -eq 1
|
||||
echo umask $umask
|
||||
else
|
||||
if test $symbolic -eq 1
|
||||
__fish_umask_print_symbolic $umask
|
||||
else
|
||||
echo $umask
|
||||
end
|
||||
end
|
||||
|
||||
case 1
|
||||
set -l parsed (__fish_umask_parse $opt)
|
||||
if test (count $parsed) -eq 1
|
||||
set -g umask $parsed
|
||||
return 0
|
||||
end
|
||||
return 1
|
||||
|
||||
case '*'
|
||||
printf (_ '%s: Too many arguments\n') umask >&2
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function psub -d "Read from stdin into a file and output the filename. Remove the file when the command that calles psub exits."
|
||||
|
||||
set -l filename
|
||||
set -l funcname
|
||||
|
||||
if count $argv >/dev/null
|
||||
switch $argv[1]
|
||||
case '-h*' --h --he --hel --help
|
||||
|
||||
help psub
|
||||
return 0
|
||||
|
||||
case '*'
|
||||
printf (_ "%s: Unknown argument '%s'\n") psub $argv[1]
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
if not status --is-command-substitution
|
||||
echo psub: Not inside of command substitution >&2
|
||||
return
|
||||
end
|
||||
|
||||
# Find unique file name for writing output to
|
||||
while true
|
||||
set filename /tmp/.psub.(echo %self).(random);
|
||||
if not test -e $filename
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
# Write output to pipe. This needs to be done in the background so
|
||||
# that the command substitution exits without needing to wait for
|
||||
# all the commands to exit
|
||||
mkfifo $filename
|
||||
cat >$filename &
|
||||
|
||||
# Write filename to stdout
|
||||
echo $filename
|
||||
|
||||
# Find unique function name
|
||||
while true
|
||||
set funcname __fish_psub_(random);
|
||||
if not functions $funcname >/dev/null ^/dev/null
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
# Make sure we erase file when caller exits
|
||||
eval function $funcname --on-job-exit caller\; rm $filename\; functions -e $funcname\; end
|
||||
|
||||
end
|
||||
|
||||
function prevd-or-backward-word --key-binding
|
||||
if test -z (commandline)
|
||||
prevd
|
||||
|
|
22
init/functions/__fish_complete_directory.fish
Normal file
22
init/functions/__fish_complete_directory.fish
Normal file
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# Find directories that complete $argv[1], output them as completions
|
||||
# with description $argv[2] if defined, otherwise use 'Directory'
|
||||
#
|
||||
|
||||
function __fish_complete_directory -d "Complete using directories"
|
||||
|
||||
set -- comp $argv[1]
|
||||
set -- desc (_ Directory)
|
||||
|
||||
if test (count $argv) -gt 1
|
||||
set desc $argv[2]
|
||||
end
|
||||
|
||||
eval "set -- dirs "$comp"*/"
|
||||
|
||||
if test $dirs[1]
|
||||
printf "%s\t$desc\n" $dirs
|
||||
end
|
||||
|
||||
end
|
||||
|
36
init/functions/__fish_complete_subcommand.fish
Normal file
36
init/functions/__fish_complete_subcommand.fish
Normal file
|
@ -0,0 +1,36 @@
|
|||
function __fish_complete_subcommand -d "Complete subcommand"
|
||||
set -l res ""
|
||||
set -l had_cmd 0
|
||||
set -l cmd (commandline -cop) (commandline -ct)
|
||||
set -l skip_next 1
|
||||
|
||||
for i in $cmd
|
||||
|
||||
if test "$skip_next" = 1
|
||||
set skip_next 0
|
||||
continue
|
||||
end
|
||||
|
||||
if test "$had_cmd" = 1
|
||||
set res "$res $i"
|
||||
else
|
||||
|
||||
if contains -- $i $argv
|
||||
set skip_next 1
|
||||
continue
|
||||
end
|
||||
|
||||
switch $i
|
||||
case '-*'
|
||||
|
||||
case '*'
|
||||
set had_cmd 1
|
||||
set res $i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
printf "%s\n" (commandline -ct)(complete -C $res)
|
||||
|
||||
end
|
||||
|
26
init/functions/__fish_complete_suffix.fish
Normal file
26
init/functions/__fish_complete_suffix.fish
Normal file
|
@ -0,0 +1,26 @@
|
|||
#
|
||||
# Find files that complete $argv[1], has the suffix $argv[2], and
|
||||
# output them as completions with description $argv[3]
|
||||
#
|
||||
|
||||
function __fish_complete_suffix -d "Complete using files"
|
||||
|
||||
set -- comp $argv[1]
|
||||
set -- suff $argv[2]
|
||||
set -- desc $argv[3]
|
||||
|
||||
set -- base (echo $comp |sed -e 's/\.[a-zA-Z0-9]*$//')
|
||||
eval "set -- files $base*$suff"
|
||||
|
||||
if test $files[1]
|
||||
printf "%s\t$desc\n" $files
|
||||
end
|
||||
|
||||
#
|
||||
# Also do directory completion, since there might be files
|
||||
# with the correct suffix in a subdirectory
|
||||
#
|
||||
|
||||
__fish_complete_directory $comp
|
||||
|
||||
end
|
53
init/functions/__fish_contains_opt.fish
Normal file
53
init/functions/__fish_contains_opt.fish
Normal file
|
@ -0,0 +1,53 @@
|
|||
|
||||
function __fish_contains_opt -d "Checks if a specific option has been given in the current commandline"
|
||||
set -l next_short
|
||||
|
||||
set -l short_opt
|
||||
set -l long_opt
|
||||
|
||||
for i in $argv
|
||||
if test $next_short
|
||||
set next_short
|
||||
set -- short_opt $short_opt $i
|
||||
else
|
||||
switch $i
|
||||
case -s
|
||||
set next_short 1
|
||||
case '-*'
|
||||
echo __fish_contains_opt: Unknown option $i
|
||||
return 1
|
||||
|
||||
case '**'
|
||||
set -- long_opt $long_opt $i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i in $short_opt
|
||||
|
||||
if test -z $i
|
||||
continue
|
||||
end
|
||||
|
||||
if commandline -cpo | grep -- "^-"$i"\|^-[^-]*"$i >/dev/null
|
||||
return 0
|
||||
end
|
||||
|
||||
if commandline -ct | grep -- "^-"$i"\|^-[^-]*"$i >/dev/null
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
for i in $long_opt
|
||||
if test -z $i
|
||||
continue
|
||||
end
|
||||
|
||||
if contains -- --$i (commandline -cpo)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return 1
|
||||
end
|
||||
|
29
init/functions/__fish_gnu_complete.fish
Normal file
29
init/functions/__fish_gnu_complete.fish
Normal file
|
@ -0,0 +1,29 @@
|
|||
function __fish_gnu_complete -d "Wrapper for the complete builtin. Skips the long completions on non-GNU systems"
|
||||
set is_gnu 0
|
||||
|
||||
# Check if we are using a gnu system
|
||||
for i in (seq (count $argv))
|
||||
switch $argv[$i]
|
||||
|
||||
case -g --is-gnu
|
||||
set -e argv[$i]
|
||||
set is_gnu 1
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Remove long option if not on a gnu system
|
||||
if test $is_gnu = 0
|
||||
for i in (seq (count $argv))
|
||||
if test $argv[$i] = -l
|
||||
set -e argv[$i]
|
||||
set -e argv[$i]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
complete $argv
|
||||
|
||||
end
|
||||
|
27
init/functions/__fish_move_last.fish
Normal file
27
init/functions/__fish_move_last.fish
Normal file
|
@ -0,0 +1,27 @@
|
|||
function __fish_move_last -d "Move the last element of a directory history from src to dest"
|
||||
set -l src $argv[1]
|
||||
set -l dest $argv[2]
|
||||
|
||||
set -l size_src (count $$src)
|
||||
|
||||
if test $size_src = 0
|
||||
# Cannot make this step
|
||||
printf (_ "Hit end of history...\n")
|
||||
return 1
|
||||
end
|
||||
|
||||
# Append current dir to the end of the destination
|
||||
set -g (echo $dest) $$dest (command pwd)
|
||||
|
||||
set ssrc $$src
|
||||
|
||||
# Change dir to the last entry in the source dir-hist
|
||||
builtin cd $ssrc[$size_src]
|
||||
|
||||
# Keep all but the last from the source dir-hist
|
||||
set -e (echo $src)[$size_src]
|
||||
|
||||
# All ok, return success
|
||||
return 0
|
||||
end
|
||||
|
55
init/functions/__fish_print_packages.fish
Normal file
55
init/functions/__fish_print_packages.fish
Normal file
|
@ -0,0 +1,55 @@
|
|||
|
||||
function __fish_print_packages
|
||||
|
||||
# apt-cache is much, much faster than rpm, and can do this in real
|
||||
# time. We use it if available.
|
||||
|
||||
switch (commandline -tc)
|
||||
case '-**'
|
||||
return
|
||||
end
|
||||
|
||||
#Get the word 'Package' in the current language
|
||||
set -l package (_ Package)
|
||||
|
||||
if which apt-cache >/dev/null ^/dev/null
|
||||
# Apply the following filters to output of apt-cache:
|
||||
# 1) Remove package names with parentesis in them, since these seem to not correspond to actual packages as reported by rpm
|
||||
# 2) Remove package names that are .so files, since these seem to not correspond to actual packages as reported by rpm
|
||||
# 3) Remove path information such as /usr/bin/, as rpm packages do not have paths
|
||||
|
||||
apt-cache --no-generate pkgnames (commandline -tc)|grep -v \( |grep -v '\.so\(\.[0-9]\)*$'|sed -e 's/\/.*\///'|sed -e 's/$/\t'$package'/'
|
||||
return
|
||||
end
|
||||
|
||||
# Rpm is too slow for this job, so we set it up to do completions
|
||||
# as a background job and cache the results.
|
||||
|
||||
if which rpm >/dev/null ^/dev/null
|
||||
|
||||
# If the cache is less than five minutes old, we do not recalculate it
|
||||
|
||||
set cache_file /tmp/.rpm-cache.$USER
|
||||
if test -f $cache_file
|
||||
cat $cache_file
|
||||
set age (echo (date +%s) - (stat -c '%Y' $cache_file) | bc)
|
||||
set max_age 250
|
||||
if test $age -lt $max_age
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Remove package version information from output and pipe into cache file
|
||||
rpm -qa >$cache_file |sed -e 's/-[^-]*-[^-]*$//' | sed -e 's/$/\t'$package'/' &
|
||||
end
|
||||
|
||||
# This completes the package name from the portage tree.
|
||||
# True for installing new packages. Function for printing
|
||||
# installed on the system packages is in completions/emerge.fish
|
||||
if which emerge >/dev/null ^/dev/null
|
||||
emerge -s \^(commandline -tc) |grep "^*" |cut -d\ -f3 |cut -d/ -f2
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
26
init/functions/dirh.fish
Normal file
26
init/functions/dirh.fish
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
function dirh -d "Print the current directory history (the back- and fwd- lists)"
|
||||
# Avoid set comment
|
||||
set -l current (command pwd)
|
||||
set -l separator " "
|
||||
set -l line_len (echo (count $dirprev) + (echo $dirprev $current $dirnext | wc -m) | bc)
|
||||
if test $line_len -gt $COLUMNS
|
||||
# Print one entry per line if history is long
|
||||
set separator "\n"
|
||||
end
|
||||
|
||||
for i in $dirprev
|
||||
echo -n -e $i$separator
|
||||
end
|
||||
|
||||
set_color $fish_color_history_current
|
||||
echo -n -e $current$separator
|
||||
set_color normal
|
||||
|
||||
for i in (seq (echo (count $dirnext)) -1 1)
|
||||
echo -n -e $dirnext[$i]$separator
|
||||
end
|
||||
|
||||
echo
|
||||
end
|
||||
|
94
init/functions/help.fish
Normal file
94
init/functions/help.fish
Normal file
|
@ -0,0 +1,94 @@
|
|||
|
||||
#
|
||||
# help should use 'open' to find a suitable browser, but only
|
||||
# if there is a mime database _and_ DISPLAY is set, since the
|
||||
# browser will most likely be graphical. Since most systems which
|
||||
# have a mime databe also have the htmlview program, this is mostly a
|
||||
# theoretical problem.
|
||||
#
|
||||
|
||||
function help -d "Show help for the fish shell"
|
||||
|
||||
# Declare variables to set correct scope
|
||||
set -l fish_browser
|
||||
set -l fish_browser_bg
|
||||
|
||||
set -l h syntax completion editor job-control todo bugs history killring help
|
||||
set h $h color prompt title variables builtin-overview changes expand
|
||||
set h $h expand-variable expand-home expand-brace expand-wildcard
|
||||
set -l help_topics $h expand-command-substitution expand-process
|
||||
|
||||
#
|
||||
# Find a suitable browser for viewing the help pages. This is needed
|
||||
# by the help function defined below.
|
||||
#
|
||||
set -l graphical_browsers htmlview x-www-browser firefox galeon mozilla konqueror epiphany opera netscape
|
||||
set -l text_browsers htmlview www-browser links elinks lynx w3m
|
||||
|
||||
if test $BROWSER
|
||||
# User has manualy set a preferred browser, so we respect that
|
||||
set fish_browser $BROWSER
|
||||
|
||||
# If browser is known to be graphical, put into background
|
||||
if contains -- $BROWSER $graphical_browsers
|
||||
set fish_browser_bg 1
|
||||
end
|
||||
else
|
||||
# Check for a text-based browser.
|
||||
for i in $text_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
set fish_browser $i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# If we are in a graphical environment, check if there is a graphical
|
||||
# browser to use instead.
|
||||
if test "$DISPLAY" -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \)
|
||||
for i in $graphical_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
set fish_browser $i
|
||||
set fish_browser_bg 1
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if test -z $fish_browser
|
||||
printf (_ '%s: Could not find a web browser.\n') help
|
||||
printf (_ 'Please set the variable $BROWSER to a suitable browser and try again\n\n')
|
||||
return 1
|
||||
end
|
||||
|
||||
set fish_help_item $argv[1]
|
||||
|
||||
switch "$fish_help_item"
|
||||
case ""
|
||||
set fish_help_page index.html
|
||||
case "."
|
||||
set fish_help_page "builtins.html\#source"
|
||||
case difference
|
||||
set fish_help_page difference.html
|
||||
case globbing
|
||||
set fish_help_page "index.html\#expand"
|
||||
case (builtin -n)
|
||||
set fish_help_page "builtins.html\#$fish_help_item"
|
||||
case contains count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize psub umask type vared
|
||||
set fish_help_page "commands.html\#$fish_help_item"
|
||||
case $help_topics
|
||||
set fish_help_page "index.html\#$fish_help_item"
|
||||
case "*"
|
||||
if which $fish_help_item >/dev/null ^/dev/null
|
||||
man $fish_help_item
|
||||
return
|
||||
end
|
||||
set fish_help_page "index.html"
|
||||
end
|
||||
|
||||
if test $fish_browser_bg
|
||||
eval $fish_browser file://$__fish_help_dir/$fish_help_page \&
|
||||
else
|
||||
eval $fish_browser file://$__fish_help_dir/$fish_help_page
|
||||
end
|
||||
end
|
18
init/functions/ls.fish
Normal file
18
init/functions/ls.fish
Normal file
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Make ls use colors if we are on a system that supports this
|
||||
#
|
||||
|
||||
if ls --version 1>/dev/null 2>/dev/null
|
||||
# This is GNU ls
|
||||
function ls -d "List contents of directory"
|
||||
command ls --color=auto --indicator-style=classify $argv
|
||||
end
|
||||
else
|
||||
# BSD, OS X and a few more support colors through the -G switch instead
|
||||
if ls / -G 1>/dev/null 2>/dev/null
|
||||
function ls -d "List contents of directory"
|
||||
command ls -G $argv
|
||||
end
|
||||
end
|
||||
end
|
||||
|
50
init/functions/nextd.fish
Normal file
50
init/functions/nextd.fish
Normal file
|
@ -0,0 +1,50 @@
|
|||
|
||||
function nextd -d "Move forward in the directory history"
|
||||
# Parse arguments
|
||||
set -l show_hist 0
|
||||
set -l times 1
|
||||
for i in (seq (count $argv))
|
||||
switch $argv[$i]
|
||||
case '-l' --l --li --lis --list
|
||||
set show_hist 1
|
||||
continue
|
||||
case '-*'
|
||||
printf (_ "%s: Unknown option %s\n" ) nextd $argv[$i]
|
||||
return 1
|
||||
case '*'
|
||||
if test $argv[$i] -ge 0 ^/dev/null
|
||||
set times $argv[$i]
|
||||
else
|
||||
printf (_ "%s: The number of positions to skip must be a non-negative integer\n" ) nextd
|
||||
return 1
|
||||
end
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
# Traverse history
|
||||
set -l code 1
|
||||
for i in (seq $times)
|
||||
# Try one step backward
|
||||
if __fish_move_last dirnext dirprev;
|
||||
# We consider it a success if we were able to do at least 1 step
|
||||
# (low expectations are the key to happiness ;)
|
||||
set code 0
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Show history if needed
|
||||
if test $show_hist = 1
|
||||
dirh
|
||||
end
|
||||
|
||||
# Set direction for 'cd -'
|
||||
if test $code = 0 ^/dev/null
|
||||
set -g __fish_cd_direction prev
|
||||
end
|
||||
|
||||
# All done
|
||||
return $code
|
||||
end
|
12
init/functions/open.fish
Normal file
12
init/functions/open.fish
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
#
|
||||
# This allows us to use 'open FILENAME' to open a given file in the default
|
||||
# application for the file.
|
||||
#
|
||||
|
||||
if not test (uname) = Darwin
|
||||
function open -d "Open file in default application"
|
||||
mimedb -l -- $argv
|
||||
end
|
||||
end
|
||||
|
51
init/functions/prevd.fish
Normal file
51
init/functions/prevd.fish
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
function prevd -d "Move back in the directory history"
|
||||
# Parse arguments
|
||||
set -l show_hist 0
|
||||
set -l times 1
|
||||
for i in (seq (count $argv))
|
||||
switch $argv[$i]
|
||||
case '-l' --l --li --lis --list
|
||||
set show_hist 1
|
||||
continue
|
||||
case '-*'
|
||||
printf (_ "%s: Unknown option %s\n" ) prevd $argv[$i]
|
||||
return 1
|
||||
case '*'
|
||||
if test $argv[$i] -ge 0 ^/dev/null
|
||||
set times $argv[$i]
|
||||
else
|
||||
printf (_ "The number of positions to skip must be a non-negative integer\n")
|
||||
return 1
|
||||
end
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
# Traverse history
|
||||
set -l code 1
|
||||
for i in (seq $times)
|
||||
# Try one step backward
|
||||
if __fish_move_last dirprev dirnext;
|
||||
# We consider it a success if we were able to do at least 1 step
|
||||
# (low expectations are the key to happiness ;)
|
||||
set code 0
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# Show history if needed
|
||||
if test $show_hist = 1
|
||||
dirh
|
||||
end
|
||||
|
||||
# Set direction for 'cd -'
|
||||
if test $code = 0 ^/dev/null
|
||||
set -g __fish_cd_direction next
|
||||
end
|
||||
|
||||
# All done
|
||||
return $code
|
||||
end
|
||||
|
54
init/functions/psub.fish
Normal file
54
init/functions/psub.fish
Normal file
|
@ -0,0 +1,54 @@
|
|||
|
||||
|
||||
function psub -d "Read from stdin into a file and output the filename. Remove the file when the command that calles psub exits."
|
||||
|
||||
set -l filename
|
||||
set -l funcname
|
||||
|
||||
if count $argv >/dev/null
|
||||
switch $argv[1]
|
||||
case '-h*' --h --he --hel --help
|
||||
|
||||
help psub
|
||||
return 0
|
||||
|
||||
case '*'
|
||||
printf (_ "%s: Unknown argument '%s'\n") psub $argv[1]
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
if not status --is-command-substitution
|
||||
echo psub: Not inside of command substitution >&2
|
||||
return
|
||||
end
|
||||
|
||||
# Find unique file name for writing output to
|
||||
while true
|
||||
set filename /tmp/.psub.(echo %self).(random);
|
||||
if not test -e $filename
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
# Write output to pipe. This needs to be done in the background so
|
||||
# that the command substitution exits without needing to wait for
|
||||
# all the commands to exit
|
||||
mkfifo $filename
|
||||
cat >$filename &
|
||||
|
||||
# Write filename to stdout
|
||||
echo $filename
|
||||
|
||||
# Find unique function name
|
||||
while true
|
||||
set funcname __fish_psub_(random);
|
||||
if not functions $funcname >/dev/null ^/dev/null
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
# Make sure we erase file when caller exits
|
||||
eval function $funcname --on-job-exit caller\; rm $filename\; functions -e $funcname\; end
|
||||
|
||||
end
|
136
init/functions/trap.fish
Normal file
136
init/functions/trap.fish
Normal file
|
@ -0,0 +1,136 @@
|
|||
|
||||
function __trap_translate_signal
|
||||
set upper (echo $argv[1]|tr a-z A-Z)
|
||||
if expr $upper : 'SIG.*' >/dev/null
|
||||
echo $upper | cut -c 4-
|
||||
else
|
||||
echo $upper
|
||||
end
|
||||
end
|
||||
|
||||
function __trap_switch
|
||||
|
||||
switch $argv[1]
|
||||
case EXIT
|
||||
echo --on-exit %self
|
||||
|
||||
case '*'
|
||||
echo --on-signal $argv[1]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function trap -d 'Perform an action when the shell recives a signal'
|
||||
|
||||
set -l mode
|
||||
set -l cmd
|
||||
set -l sig
|
||||
set -l shortopt
|
||||
set -l longopt
|
||||
|
||||
set -l shortopt -o lph
|
||||
set -l longopt
|
||||
if not getopt -T >/dev/null
|
||||
set longopt -l print,help,list-signals
|
||||
end
|
||||
|
||||
if not getopt -n type -Q $shortopt $longopt -- $argv
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
eval set opt $tmp
|
||||
|
||||
while count $opt >/dev/null
|
||||
switch $opt[1]
|
||||
case -h --help
|
||||
help trap
|
||||
return 0
|
||||
|
||||
case -p --print
|
||||
set mode print
|
||||
|
||||
case -l --list-signals
|
||||
set mode list
|
||||
|
||||
case --
|
||||
set -e opt[1]
|
||||
break
|
||||
|
||||
end
|
||||
set -e opt[1]
|
||||
end
|
||||
|
||||
if not count $mode >/dev/null
|
||||
|
||||
switch (count $opt)
|
||||
|
||||
case 0
|
||||
set mode print
|
||||
|
||||
case 1
|
||||
set mode clear
|
||||
|
||||
case '*'
|
||||
if test opt[1] = -
|
||||
set -e opt[1]
|
||||
set mode clear
|
||||
else
|
||||
set mode set
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
switch $mode
|
||||
case clear
|
||||
for i in $opt
|
||||
set -- sig (__trap_translate_signal $i)
|
||||
if test $sig
|
||||
functions -e __trap_handler_$sig
|
||||
end
|
||||
end
|
||||
|
||||
case set
|
||||
set -l cmd $opt[1]
|
||||
set -e opt[1]
|
||||
|
||||
for i in $opt
|
||||
|
||||
set -l -- sig (__trap_translate_signal $i)
|
||||
set -- sw (__trap_switch $sig)
|
||||
|
||||
if test $sig
|
||||
eval "function __trap_handler_$sig $sw; $cmd; end"
|
||||
else
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
case print
|
||||
set -l names
|
||||
|
||||
if count $opt >/dev/null
|
||||
set -- names $opt
|
||||
else
|
||||
set -- names (functions -na|grep "^__trap_handler_"|sed -e 's/__trap_handler_//' )
|
||||
end
|
||||
|
||||
for i in $names
|
||||
|
||||
set -- sig (__trap_translate_signal $i)
|
||||
|
||||
if test sig
|
||||
functions __trap_handler_$i
|
||||
else
|
||||
return 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
case list
|
||||
kill -l
|
||||
|
||||
end
|
||||
|
||||
end
|
134
init/functions/type.fish
Normal file
134
init/functions/type.fish
Normal file
|
@ -0,0 +1,134 @@
|
|||
|
||||
function type -d "Print the type of a command"
|
||||
|
||||
# Initialize
|
||||
set -l status 1
|
||||
set -l mode normal
|
||||
set -l selection all
|
||||
|
||||
#
|
||||
# Get options
|
||||
#
|
||||
set -l shortopt -o tpPafh
|
||||
set -l longopt
|
||||
if not getopt -T >/dev/null
|
||||
set longopt -l type,path,force-path,all,no-functions,help
|
||||
end
|
||||
|
||||
if not getopt -n type -Q $shortopt $longopt -- $argv
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
set -l opt
|
||||
eval set opt $tmp
|
||||
|
||||
for i in $opt
|
||||
switch $i
|
||||
case -t --type
|
||||
set mode type
|
||||
|
||||
case -p --path
|
||||
set mode path
|
||||
|
||||
case -P --force-path
|
||||
set mode path
|
||||
set selection files
|
||||
|
||||
case -a --all
|
||||
set selection multi
|
||||
|
||||
case -f --no-functions
|
||||
set selection files
|
||||
|
||||
case -h --help
|
||||
help type
|
||||
return 0
|
||||
|
||||
case --
|
||||
break
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# Check all possible types for the remaining arguments
|
||||
for i in $argv
|
||||
|
||||
switch $i
|
||||
case '-*'
|
||||
continue
|
||||
end
|
||||
|
||||
# Found will be set to 1 if a match is found
|
||||
set found 0
|
||||
|
||||
if test $selection != files
|
||||
|
||||
if contains -- $i (functions -na)
|
||||
set status 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
printf (_ '%s is a function with definition\n') $i
|
||||
functions $i
|
||||
|
||||
case type
|
||||
printf (_ 'function\n')
|
||||
|
||||
case path
|
||||
echo
|
||||
|
||||
end
|
||||
if test $selection != multi
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
if contains -- $i (builtin -n)
|
||||
set status 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
printf (_ '%s is a builtin\n') $i
|
||||
|
||||
case type
|
||||
printf (_ 'builtin\n')
|
||||
|
||||
case path
|
||||
echo
|
||||
end
|
||||
if test $selection != multi
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if which $i ^/dev/null >/dev/null
|
||||
set status 0
|
||||
set found 1
|
||||
switch $mode
|
||||
case normal
|
||||
printf (_ '%s is %s\n') $i (which $i)
|
||||
|
||||
case type
|
||||
printf (_ 'file\n')
|
||||
|
||||
case path
|
||||
which $i
|
||||
end
|
||||
if test $selection != multi
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
if test $found = 0
|
||||
printf (_ "%s: Could not find '%s'") type $i
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return $status
|
||||
end
|
||||
|
206
init/functions/umask.fish
Normal file
206
init/functions/umask.fish
Normal file
|
@ -0,0 +1,206 @@
|
|||
|
||||
function __fish_umask_parse -d "Parses a file permission specification as into an octal version"
|
||||
# Test if already a valid octal mask, and pad it with zeros
|
||||
if echo $argv | grep -E '^(0|)[0-7]{1,3}$' >/dev/null
|
||||
for i in (seq (echo 5-(echo $argv|wc -c)|bc)); set argv 0$argv; end
|
||||
echo $argv
|
||||
else
|
||||
# Test if argument really is a valid symbolic mask
|
||||
if not echo $argv | grep -E '^(((u|g|o|a|)(=|\+|-)|)(r|w|x)*)(,(((u|g|o|a|)(=|\+|-)|)(r|w|x)*))*$' >/dev/null
|
||||
printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l implicit_all
|
||||
|
||||
# Insert inverted umask into res variable
|
||||
|
||||
set -l mode
|
||||
set -l val
|
||||
set -l tmp $umask
|
||||
set -l res
|
||||
|
||||
for i in 1 2 3
|
||||
set tmp (echo $tmp|cut -c 2-)
|
||||
set res[$i] (echo 7-(echo $tmp|cut -c 1)|bc)
|
||||
end
|
||||
|
||||
set -l el (echo $argv|tr , \n)
|
||||
for i in $el
|
||||
switch $i
|
||||
case 'u*'
|
||||
set idx 1
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case 'g*'
|
||||
set idx 2
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case 'o*'
|
||||
set idx 3
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case 'a*'
|
||||
set idx 1 2 3
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '*'
|
||||
set implicit_all 1
|
||||
set idx 1 2 3
|
||||
end
|
||||
|
||||
switch $i
|
||||
case '=*'
|
||||
set mode set
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '+*'
|
||||
set mode add
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '-*'
|
||||
set mode remove
|
||||
set i (echo $i| cut -c 2-)
|
||||
|
||||
case '*'
|
||||
if not count $implicit_all >/dev/null
|
||||
printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2
|
||||
return
|
||||
end
|
||||
set mode set
|
||||
end
|
||||
|
||||
if not echo $perm|grep -E '^(r|w|x)*$' >/dev/null
|
||||
printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2
|
||||
return
|
||||
end
|
||||
|
||||
set val 0
|
||||
if echo $i |grep 'r' >/dev/null
|
||||
set val 4
|
||||
end
|
||||
if echo $i |grep 'w' >/dev/null
|
||||
set val (echo $val + 2|bc)
|
||||
end
|
||||
if echo $i |grep 'x' >/dev/null
|
||||
set val (echo $val + 1|bc)
|
||||
end
|
||||
|
||||
for j in $idx
|
||||
switch $mode
|
||||
case set
|
||||
set res[$j] $val
|
||||
|
||||
case add
|
||||
set res[$j] (perl -e 'print( ( '$res[$j]'|'$val[$j]' )."\n" )')
|
||||
|
||||
case remove
|
||||
set res[$j] (perl -e 'print( ( (7-'$res[$j]')&'$val[$j]' )."\n" )')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i in 1 2 3
|
||||
set res[$i] (echo 7-$res[$i]|bc)
|
||||
end
|
||||
echo 0$res[1]$res[2]$res[3]
|
||||
end
|
||||
end
|
||||
|
||||
function __fish_umask_print_symbolic
|
||||
set -l res ""
|
||||
set -l letter a u g o
|
||||
|
||||
for i in 2 3 4
|
||||
set res $res,$letter[$i]=
|
||||
set val (echo $umask|cut -c $i)
|
||||
|
||||
if contains $val 0 1 2 3
|
||||
set res {$res}r
|
||||
end
|
||||
|
||||
if contains $val 0 1 4 5
|
||||
set res {$res}w
|
||||
end
|
||||
|
||||
if contains $val 0 2 4 6
|
||||
set res {$res}x
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
echo $res|cut -c 2-
|
||||
end
|
||||
|
||||
function umask -d "Set default file permission mask"
|
||||
|
||||
set -l as_command 0
|
||||
set -l symbolic 0
|
||||
|
||||
set -l shortopt -o pSh
|
||||
set -l longopt
|
||||
if not getopt -T >/dev/null
|
||||
set longopt -l as-command,symbolic,help
|
||||
end
|
||||
|
||||
if not getopt -n umask -Q $shortopt $longopt -- $argv
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
eval set opt $tmp
|
||||
|
||||
while count $opt >/dev/null
|
||||
|
||||
switch $opt[1]
|
||||
case -h --help
|
||||
help umask
|
||||
return 0
|
||||
|
||||
case -p --as-command
|
||||
set as_command 1
|
||||
|
||||
case -S --symbolic
|
||||
set symbolic 1
|
||||
|
||||
case --
|
||||
set -e opt[1]
|
||||
break
|
||||
|
||||
end
|
||||
|
||||
set -e opt[1]
|
||||
|
||||
end
|
||||
|
||||
switch (count $opt)
|
||||
|
||||
case 0
|
||||
if not set -q umask
|
||||
set -g umask 113
|
||||
end
|
||||
if test $as_command -eq 1
|
||||
echo umask $umask
|
||||
else
|
||||
if test $symbolic -eq 1
|
||||
__fish_umask_print_symbolic $umask
|
||||
else
|
||||
echo $umask
|
||||
end
|
||||
end
|
||||
|
||||
case 1
|
||||
set -l parsed (__fish_umask_parse $opt)
|
||||
if test (count $parsed) -eq 1
|
||||
set -g umask $parsed
|
||||
return 0
|
||||
end
|
||||
return 1
|
||||
|
||||
case '*'
|
||||
printf (_ '%s: Too many arguments\n') umask >&2
|
||||
|
||||
end
|
||||
|
||||
end
|
47
init/functions/vared.fish
Normal file
47
init/functions/vared.fish
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
#
|
||||
# This is a neat function, stolen from zsh. It allows you to edit the
|
||||
# value of a variable interactively.
|
||||
#
|
||||
|
||||
function vared -d "Edit variable value"
|
||||
if test (count $argv) = 1
|
||||
switch $argv
|
||||
|
||||
case '-h' '--h' '--he' '--hel' '--help'
|
||||
help vared
|
||||
|
||||
case '-*'
|
||||
printf (_ "%s: Unknown option %s\n") vared $argv
|
||||
|
||||
case '*'
|
||||
if test (count $$argv ) -lt 2
|
||||
set init ''
|
||||
if test $$argv
|
||||
set -- init $$argv
|
||||
end
|
||||
set prompt 'set_color green; echo '$argv'; set_color normal; echo "> "'
|
||||
read -p $prompt -c $init tmp
|
||||
|
||||
# If variable already exists, do not add any
|
||||
# switches, so we don't change export rules. But
|
||||
# if it does not exist, we make the variable
|
||||
# global, so that it will not die when this
|
||||
# function dies
|
||||
|
||||
if test $$argv
|
||||
set -- $argv $tmp
|
||||
else
|
||||
set -g -- $argv $tmp
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
printf (_ '%s: %s is an array variable. Use %svared%s %s[n] to edit the n:th element of %s\n') $argv (set_color $fish_color_command) (set_color $fish_color_normal) vared $argv $argv
|
||||
end
|
||||
end
|
||||
else
|
||||
printf (_ '%s: Expected exactly one argument, got %s.\n\nSynopsis:\n\t%svared%s VARIABLE\n') vared (count $argv) (set_color $fish_color_command) (set_color $fish_color_normal)
|
||||
end
|
||||
end
|
||||
|
2
main.c
2
main.c
|
@ -220,6 +220,7 @@ int main( int argc, char **argv )
|
|||
builtin_init();
|
||||
function_init();
|
||||
env_init();
|
||||
parse_util_init();
|
||||
complete_init();
|
||||
reader_init();
|
||||
|
||||
|
@ -303,6 +304,7 @@ int main( int argc, char **argv )
|
|||
wutil_destroy();
|
||||
common_destroy();
|
||||
exec_destroy();
|
||||
parse_util_destroy();
|
||||
event_destroy();
|
||||
output_destroy();
|
||||
translate_destroy();
|
||||
|
|
156
parse_util.c
156
parse_util.c
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <wchar.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h"
|
||||
|
@ -20,6 +21,14 @@
|
|||
#include "common.h"
|
||||
#include "tokenizer.h"
|
||||
#include "parse_util.h"
|
||||
#include "expand.h"
|
||||
#include "intern.h"
|
||||
#include "exec.h"
|
||||
|
||||
/**
|
||||
Set of files which have been autoloaded
|
||||
*/
|
||||
static hash_table_t *loaded=0;
|
||||
|
||||
int parse_util_lineno( const wchar_t *str, int len )
|
||||
{
|
||||
|
@ -419,4 +428,151 @@ void parse_util_token_extent( const wchar_t *buff,
|
|||
}
|
||||
|
||||
|
||||
int parse_util_load( const wchar_t *cmd,
|
||||
const wchar_t *path_var,
|
||||
void (*on_load)(const wchar_t *cmd),
|
||||
int reload )
|
||||
{
|
||||
array_list_t path_list;
|
||||
int i;
|
||||
string_buffer_t path;
|
||||
time_t *tm;
|
||||
int reloaded = 0;
|
||||
|
||||
/*
|
||||
Do we know where to look
|
||||
*/
|
||||
|
||||
if( !path_var )
|
||||
return 0;
|
||||
|
||||
if( !loaded )
|
||||
{
|
||||
loaded = malloc( sizeof( hash_table_t ) );
|
||||
if( !loaded )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
hash_init( loaded, &hash_wcs_func, &hash_wcs_cmp );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get modification time of file
|
||||
*/
|
||||
tm = (time_t *)hash_get( loaded, cmd );
|
||||
|
||||
/*
|
||||
Did we just check this?
|
||||
*/
|
||||
if( tm )
|
||||
if(tm[1]-time(0)<=1)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
Return if already loaded and we are skipping reloading
|
||||
*/
|
||||
if( !reload && tm )
|
||||
return 0;
|
||||
debug( 1, L"WOO %ls", cmd );
|
||||
|
||||
al_init( &path_list );
|
||||
|
||||
sb_init( &path );
|
||||
|
||||
expand_variable_array( path_var, &path_list );
|
||||
|
||||
/*
|
||||
Iterate over path searching for suitable completion files
|
||||
*/
|
||||
for( i=0; i<al_get_count( &path_list ); i++ )
|
||||
{
|
||||
struct stat buf;
|
||||
wchar_t *next = (wchar_t *)al_get( &path_list, i );
|
||||
sb_clear( &path );
|
||||
sb_append2( &path, next, L"/", cmd, L".fish", (void *)0 );
|
||||
if( (wstat( (wchar_t *)path.buff, &buf )== 0) &&
|
||||
(waccess( (wchar_t *)path.buff, R_OK ) == 0) )
|
||||
{
|
||||
if( !tm || (*tm != buf.st_mtime ) )
|
||||
{
|
||||
wchar_t *esc = escape( (wchar_t *)path.buff, 1 );
|
||||
wchar_t *src_cmd = wcsdupcat( L". ", esc );
|
||||
|
||||
if( !tm )
|
||||
{
|
||||
tm = malloc(sizeof(time_t)*2);
|
||||
if( !tm )
|
||||
die_mem();
|
||||
}
|
||||
|
||||
tm[0] = buf.st_mtime;
|
||||
tm[1] = time(0);
|
||||
hash_put( loaded,
|
||||
intern( cmd ),
|
||||
tm );
|
||||
|
||||
free( esc );
|
||||
|
||||
on_load(cmd );
|
||||
|
||||
/*
|
||||
Source the completion file for the specified completion
|
||||
*/
|
||||
exec_subshell( src_cmd, 0 );
|
||||
free(src_cmd);
|
||||
reloaded = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If no file was found we insert the current time. Later we only
|
||||
research if the current time is at least five seconds later.
|
||||
This way, the files won't be searched over and over again.
|
||||
*/
|
||||
if( !tm )
|
||||
{
|
||||
tm = malloc(sizeof(time_t)*2);
|
||||
if( !tm )
|
||||
die_mem();
|
||||
|
||||
tm[0] = 0;
|
||||
tm[1] = time(0);
|
||||
hash_put( loaded, intern( cmd ), tm );
|
||||
}
|
||||
|
||||
sb_destroy( &path );
|
||||
al_foreach( &path_list, (void (*)(const void *))&free );
|
||||
|
||||
al_destroy( &path_list );
|
||||
|
||||
return reloaded;
|
||||
}
|
||||
|
||||
void parse_util_init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
Free hash value, but not hash key
|
||||
*/
|
||||
static void clear_hash_value( const void *key, const void *data )
|
||||
{
|
||||
free( (void *)data );
|
||||
}
|
||||
|
||||
|
||||
void parse_util_destroy()
|
||||
{
|
||||
if( loaded )
|
||||
{
|
||||
hash_foreach( loaded,
|
||||
&clear_hash_value );
|
||||
hash_destroy( loaded );
|
||||
free( loaded );
|
||||
loaded = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
parse_util.h
11
parse_util.h
|
@ -49,5 +49,16 @@ void parse_util_token_extent( const wchar_t *buff,
|
|||
|
||||
int parse_util_lineno( const wchar_t *str, int len );
|
||||
|
||||
int parse_util_load( const wchar_t *cmd,
|
||||
const wchar_t *path_var,
|
||||
void (*on_load)(const wchar_t *cmd),
|
||||
int reload );
|
||||
|
||||
void parse_util_init();
|
||||
|
||||
|
||||
void parse_util_destroy();
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
2
parser.c
2
parser.c
|
@ -1856,7 +1856,7 @@ static int parse_job( process_t *p,
|
|||
continue;
|
||||
}
|
||||
|
||||
if( use_function)
|
||||
if( use_function && !current_block->skip )
|
||||
{
|
||||
int nxt_forbidden;
|
||||
wchar_t *forbid;
|
||||
|
|
Loading…
Reference in a new issue