mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-11 11:11:13 -03:00
Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02a3288db7 | ||
|
|
b069489792 | ||
|
|
b37eeb92ef | ||
|
|
b6630b5087 | ||
|
|
3a69fc997c | ||
|
|
c216e36a72 | ||
|
|
00778832f1 | ||
|
|
cdbd233e62 | ||
|
|
9ce93164bb | ||
|
|
20b269130c | ||
|
|
891c2fc379 | ||
|
|
00be44a69a | ||
|
|
b8ea709c1e | ||
|
|
7bdcfacee4 | ||
|
|
61706b4490 | ||
|
|
443ddb509e | ||
|
|
e6774cc944 | ||
|
|
78cd8fa089 | ||
|
|
9229041385 | ||
|
|
e6bd3dbc40 | ||
|
|
a91bf6d88a | ||
|
|
fa75fc3901 | ||
|
|
e4a95cb989 | ||
|
|
9cf4a2a0b3 | ||
|
|
0ff374a4a0 | ||
|
|
0817962300 | ||
|
|
8b69c5416d | ||
|
|
1071fedaee | ||
|
|
ab207b64a3 | ||
|
|
418e26c0ac | ||
|
|
de3a28874e | ||
|
|
9dd842ea96 | ||
|
|
5d069de71d | ||
|
|
16333b0c69 | ||
|
|
e4fa0e1000 | ||
|
|
3e52bd0132 | ||
|
|
211663a549 | ||
|
|
659b99ed1a | ||
|
|
86d7e8bb8e | ||
|
|
8bf0a14bd5 | ||
|
|
9c32709fe1 | ||
|
|
00bdd2cb48 | ||
|
|
0a8284c981 | ||
|
|
ddbb50acd7 | ||
|
|
5262f3ce99 | ||
|
|
28dd48a76a | ||
|
|
b1c61bcf1f | ||
|
|
bb591a69c9 | ||
|
|
1d69e70b7a | ||
|
|
2cac04850b | ||
|
|
2619f1752d | ||
|
|
33e2c81748 | ||
|
|
f05da41159 | ||
|
|
780ecc46fc | ||
|
|
9b98df8310 | ||
|
|
5a8205ac2b | ||
|
|
2490da31ce | ||
|
|
092bb90569 | ||
|
|
39ca027706 | ||
|
|
22433f2717 | ||
|
|
f6e194447d | ||
|
|
e2ed5d0977 | ||
|
|
fe5bf8f80e | ||
|
|
0a713a7939 | ||
|
|
4ba2709452 | ||
|
|
0c877183b9 | ||
|
|
a46be4cadb | ||
|
|
8b4637e900 | ||
|
|
ab13c4caad | ||
|
|
479696a8ec | ||
|
|
acde745e34 | ||
|
|
064d49215a | ||
|
|
78d3b37e11 | ||
|
|
12aa33fad4 | ||
|
|
e4ade8f41b | ||
|
|
9d7723b330 | ||
|
|
2bc2e0b9ec | ||
|
|
02083a1bd7 | ||
|
|
e534a952b7 | ||
|
|
754d8d3712 | ||
|
|
86230813de | ||
|
|
2faba57e5a | ||
|
|
3789127d28 | ||
|
|
32e833f331 | ||
|
|
9b4c34aa4c |
34
Makefile.in
34
Makefile.in
@@ -79,13 +79,13 @@ MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
|
||||
|
||||
BUILTIN_DOC_SRC := doc_src/source.txt doc_src/and.txt \
|
||||
doc_src/begin.txt doc_src/bg.txt doc_src/bind.txt \
|
||||
doc_src/break.txt doc_src/builtin.txt doc_src/case.txt \
|
||||
doc_src/cd.txt doc_src/command.txt doc_src/commandline.txt \
|
||||
doc_src/complete.txt doc_src/continue.txt doc_src/else.txt \
|
||||
doc_src/end.txt doc_src/eval.txt doc_src/exec.txt doc_src/exit.txt \
|
||||
doc_src/fg.txt doc_src/for.txt doc_src/function.txt \
|
||||
doc_src/functions.txt doc_src/if.txt doc_src/jobs.txt \
|
||||
doc_src/not.txt doc_src/or.txt doc_src/random.txt \
|
||||
doc_src/block.txt doc_src/break.txt doc_src/builtin.txt \
|
||||
doc_src/case.txt doc_src/cd.txt doc_src/command.txt \
|
||||
doc_src/commandline.txt doc_src/complete.txt doc_src/continue.txt \
|
||||
doc_src/else.txt doc_src/end.txt doc_src/eval.txt doc_src/exec.txt \
|
||||
doc_src/exit.txt doc_src/fg.txt doc_src/for.txt \
|
||||
doc_src/function.txt doc_src/functions.txt doc_src/if.txt \
|
||||
doc_src/jobs.txt doc_src/not.txt doc_src/or.txt doc_src/random.txt \
|
||||
doc_src/return.txt doc_src/read.txt doc_src/set.txt \
|
||||
doc_src/status.txt doc_src/switch.txt doc_src/ulimit.txt \
|
||||
doc_src/while.txt
|
||||
@@ -105,8 +105,8 @@ CMD_DOC_SRC := doc_src/count.txt doc_src/dirh.txt doc_src/dirs.txt \
|
||||
doc_src/fishd.txt doc_src/help.txt doc_src/mimedb.txt \
|
||||
doc_src/nextd.txt doc_src/open.txt doc_src/popd.txt \
|
||||
doc_src/prevd.txt doc_src/psub.txt doc_src/pushd.txt \
|
||||
doc_src/set_color.txt doc_src/tokenize.txt doc_src/type.txt \
|
||||
doc_src/umask.txt doc_src/vared.txt
|
||||
doc_src/set_color.txt doc_src/tokenize.txt doc_src/trap.txt \
|
||||
doc_src/type.txt doc_src/umask.txt doc_src/vared.txt
|
||||
|
||||
#
|
||||
# Files generated by running doxygen on the files in $(CMD_DOC_SRC)
|
||||
@@ -134,9 +134,9 @@ MAIN_DIR_FILES := Doxyfile Doxyfile.user Makefile.in configure \
|
||||
config.guess fish_tests.c main.c fish_pager.c fishd.c
|
||||
|
||||
# Files in ./init/
|
||||
INIT_DIR_FILES :=init/fish.in init/fish_complete.fish \
|
||||
INIT_DIR_FILES :=init/fish.in init/fish_complete.fish.in \
|
||||
init/fish_function.fish init/fish_inputrc \
|
||||
init/fish_interactive.fish
|
||||
init/fish_interactive.fish.in
|
||||
|
||||
# Files in ./tests/
|
||||
TESTS_DIR_FILES := $(TEST_IN) $(TEST_IN:.in=.out) $(TEST_IN:.in=.err) \
|
||||
@@ -283,7 +283,9 @@ install: all
|
||||
$(INSTALL) -m 644 init/fish_inputrc $(DESTDIR)$(sysconfdir)$(fishinputfile);
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
|
||||
for i in user_doc/html/* ChangeLog; do \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(docdir); \
|
||||
if test -f $$i; then \
|
||||
$(INSTALL) -m 644 $$i $(DESTDIR)$(docdir); \
|
||||
fi; \
|
||||
done;
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
|
||||
for i in $(MANUALS); do \
|
||||
@@ -374,10 +376,16 @@ rpm: fish-@PACKAGE_VERSION@.tar.bz2
|
||||
mv /usr/src/redhat/RPMS/*/fish*@PACKAGE_VERSION@*.rpm .
|
||||
mv /usr/src/redhat/SRPMS/fish*@PACKAGE_VERSION@*.src.rpm .
|
||||
|
||||
distclean: clean
|
||||
rm -f fish.spec doc_src/fish.1 doc_src/Doxyfile
|
||||
rm -f init/fish init/fish_interactive.fish init/fish_complete.fish
|
||||
rm -f config.status config.log config.h Makefile
|
||||
|
||||
clean:
|
||||
rm -f *.o doc.h doc_src/*.doxygen doc_src/*.c builtin_help.c
|
||||
rm -f config.status config.log config.h Makefile
|
||||
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
|
||||
rm -f tokenizer_test fish key_reader set_color tokenize gen_hdr2 mimedb
|
||||
rm -f fishd fish_pager count
|
||||
rm -f fish-@PACKAGE_VERSION@.tar
|
||||
rm -f fish-@PACKAGE_VERSION@.tar.gz
|
||||
rm -f fish-@PACKAGE_VERSION@.tar.bz2
|
||||
|
||||
@@ -42,6 +42,10 @@ enum
|
||||
*/
|
||||
#define BUILTIN_ERR_UNKNOWN L": Unknown option"
|
||||
|
||||
#define BUILTIN_ERR_VARCHAR L"%ls: Invalid character in variable name: '%lc'. Only alphanumerical characters and underscores are valid in a variable name.\n"
|
||||
|
||||
#define BUILTIN_ERR_VARNAME_ZERO L"%ls: Variable name can not be the empty string\n"
|
||||
|
||||
/**
|
||||
Stringbuffer used to represent standard output
|
||||
*/
|
||||
|
||||
@@ -28,10 +28,10 @@ Functions used for implementing the commandline builtin.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
STRING_MODE=1, // Operate on entire buffer
|
||||
JOB_MODE, // Operate on job under cursor
|
||||
PROCESS_MODE, // Operate on process under cursor
|
||||
TOKEN_MODE // Operate on token under cursor
|
||||
STRING_MODE=1, /**< Operate on entire buffer */
|
||||
JOB_MODE, /**< Operate on job under cursor */
|
||||
PROCESS_MODE, /**< Operate on process under cursor */
|
||||
TOKEN_MODE /**< Operate on token under cursor */
|
||||
}
|
||||
;
|
||||
|
||||
@@ -40,9 +40,9 @@ enum
|
||||
*/
|
||||
enum
|
||||
{
|
||||
REPLACE_MODE=1, // Replace current text
|
||||
INSERT_MODE, // Insert at cursor position
|
||||
APPEND_MODE // Insert at end of current token/command/buffer
|
||||
REPLACE_MODE=1, /**< Replace current text */
|
||||
INSERT_MODE, /**< Insert at cursor position */
|
||||
APPEND_MODE /**< Insert at end of current token/command/buffer */
|
||||
}
|
||||
;
|
||||
|
||||
@@ -66,10 +66,6 @@ static void replace_part( wchar_t *begin,
|
||||
|
||||
sb_init( &out );
|
||||
|
||||
// wchar_t *tmp = wcsndup( begin, end-begin );
|
||||
|
||||
// fwprintf( stderr, L"Commandline '%ls', current command '%ls'\n", reader_get_buffer(), tmp );
|
||||
|
||||
sb_append_substring( &out, buff, begin-buff );
|
||||
|
||||
switch( append_mode)
|
||||
@@ -253,7 +249,7 @@ int builtin_commandline( wchar_t **argv )
|
||||
|
||||
int opt = wgetopt_long( argc,
|
||||
argv,
|
||||
L"aijpctwfo",
|
||||
L"aijpctwfor",
|
||||
long_options,
|
||||
&opt_index );
|
||||
if( opt == -1 )
|
||||
@@ -282,7 +278,11 @@ int builtin_commandline( wchar_t **argv )
|
||||
case L'i':
|
||||
append_mode = INSERT_MODE;
|
||||
break;
|
||||
|
||||
|
||||
case L'r':
|
||||
append_mode = REPLACE_MODE;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
cut_at_cursor=1;
|
||||
break;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <wchar.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -40,10 +40,8 @@ static int parse_fill_name( string_buffer_t *name,
|
||||
|
||||
if (*src != L'[' && *src != L'\0')
|
||||
{
|
||||
|
||||
sb_append(sb_err, L"set: Invalid character in variable name: ");
|
||||
sb_append_char(sb_err, *src);
|
||||
sb_append2(sb_err, L"\n", parser_current_line(), L"\n", (void *)0 );
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARCHAR, L"set", *src );
|
||||
sb_append2(sb_err, parser_current_line(), L"\n", (void *)0 );
|
||||
// builtin_print_help( L"set", sb_err );
|
||||
|
||||
return -1;
|
||||
@@ -292,7 +290,7 @@ int builtin_set( wchar_t **argv )
|
||||
}
|
||||
;
|
||||
|
||||
wchar_t short_options[] = L"xglenuUq";
|
||||
wchar_t short_options[] = L"+xglenuUq";
|
||||
|
||||
int argc = builtin_count_args(argv);
|
||||
|
||||
@@ -435,6 +433,13 @@ int builtin_set( wchar_t **argv )
|
||||
{
|
||||
dest = wcsdup(argv[woptind++]);
|
||||
//fwprintf(stderr, L"Dest: %ls\n", dest);
|
||||
|
||||
if( !wcslen( dest ) )
|
||||
{
|
||||
free( dest );
|
||||
sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse values */
|
||||
|
||||
41
common.c
41
common.c
@@ -393,7 +393,7 @@ wchar_t **strv2wcsv( const char **in )
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_WCSNDUP
|
||||
wchar_t *wcsndup( const wchar_t *in, int c )
|
||||
{
|
||||
c3++;
|
||||
@@ -407,6 +407,7 @@ wchar_t *wcsndup( const wchar_t *in, int c )
|
||||
res[c] = L'\0';
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
long convert_digit( wchar_t d, int base )
|
||||
{
|
||||
@@ -574,6 +575,7 @@ wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
|
||||
/* count does not include NUL */
|
||||
}
|
||||
|
||||
#ifndef HAVE_WCSDUP
|
||||
wchar_t *wcsdup( const wchar_t *in )
|
||||
{
|
||||
size_t len=wcslen(in);
|
||||
@@ -587,10 +589,20 @@ wchar_t *wcsdup( const wchar_t *in )
|
||||
return out;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Fallback implementation if missing from libc
|
||||
*/
|
||||
#ifndef HAVE_WCSLEN
|
||||
size_t wcslen(const wchar_t *in)
|
||||
{
|
||||
const wchar_t *end=in;
|
||||
while( *end )
|
||||
end++;
|
||||
return end-in;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_WCSCASECMP
|
||||
int wcscasecmp( const wchar_t *a, const wchar_t *b )
|
||||
{
|
||||
if( *a == 0 )
|
||||
@@ -607,10 +619,10 @@ int wcscasecmp( const wchar_t *a, const wchar_t *b )
|
||||
else
|
||||
return wcscasecmp( a+1,b+1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Fallback implementation if missing from libc
|
||||
*/
|
||||
|
||||
#ifndef HAVE_WCSNCASECMP
|
||||
int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count )
|
||||
{
|
||||
if( count == 0 )
|
||||
@@ -630,6 +642,7 @@ int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count )
|
||||
else
|
||||
return wcsncasecmp( a+1,b+1, count-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int wcsvarname( wchar_t *str )
|
||||
{
|
||||
@@ -920,9 +933,10 @@ wchar_t *escape( const wchar_t *in,
|
||||
case L'^':
|
||||
case L'<':
|
||||
case L'>':
|
||||
case L'@':
|
||||
case L'(':
|
||||
case L')':
|
||||
case L'[':
|
||||
case L']':
|
||||
case L'{':
|
||||
case L'}':
|
||||
case L'?':
|
||||
@@ -931,8 +945,9 @@ wchar_t *escape( const wchar_t *in,
|
||||
case L';':
|
||||
case L':':
|
||||
case L'\'':
|
||||
case L'\"':
|
||||
case L'"':
|
||||
case L'%':
|
||||
case L'~':
|
||||
if( escape_all )
|
||||
*pos++ = L'\\';
|
||||
*pos++ = *in;
|
||||
@@ -1208,14 +1223,14 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
case L'\'':
|
||||
{
|
||||
mode = 1;
|
||||
out_pos--;
|
||||
in[out_pos] = INTERNAL_SEPARATOR;
|
||||
break;
|
||||
}
|
||||
|
||||
case L'\"':
|
||||
{
|
||||
mode = 2;
|
||||
out_pos--;
|
||||
in[out_pos] = INTERNAL_SEPARATOR;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1236,7 +1251,7 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
{
|
||||
if( c == L'\'' )
|
||||
{
|
||||
out_pos--;
|
||||
in[out_pos] = INTERNAL_SEPARATOR;
|
||||
mode = 0;
|
||||
}
|
||||
else
|
||||
@@ -1257,7 +1272,7 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
|
||||
case '"':
|
||||
{
|
||||
mode = 0;
|
||||
out_pos--;
|
||||
in[out_pos] = INTERNAL_SEPARATOR;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
14
common.h
14
common.h
@@ -134,6 +134,7 @@ wchar_t *wcsdupcat( const wchar_t *a, const wchar_t *b );
|
||||
*/
|
||||
wchar_t *wcsdupcat2( const wchar_t *a, ... );
|
||||
|
||||
#ifndef HAVE_WCSNDUP
|
||||
/**
|
||||
Returns a newly allocated wide character string wich is a copy of
|
||||
the string in, but of length c or shorter. The returned string is
|
||||
@@ -141,6 +142,7 @@ wchar_t *wcsdupcat2( const wchar_t *a, ... );
|
||||
length.
|
||||
*/
|
||||
wchar_t *wcsndup( const wchar_t *in, int c );
|
||||
#endif
|
||||
|
||||
/**
|
||||
Converts from wide char to digit in the specified base. If d is not
|
||||
@@ -183,12 +185,19 @@ size_t wcslcat( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
*/
|
||||
size_t wcslcpy( wchar_t *dst, const wchar_t *src, size_t siz );
|
||||
|
||||
#ifndef HAVE_WCSDUP
|
||||
/**
|
||||
Create a dublicate string. Wide string version of strdup. Will
|
||||
Create a duplicate string. Wide string version of strdup. Will
|
||||
automatically exit if out of memory.
|
||||
*/
|
||||
wchar_t *wcsdup(const wchar_t *in);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSLEN
|
||||
size_t wcslen(const wchar_t *in);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSCASECMP
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strcasecmp.
|
||||
@@ -201,7 +210,9 @@ wchar_t *wcsdup(const wchar_t *in);
|
||||
a user-supplied string should be considered a bug.
|
||||
*/
|
||||
int wcscasecmp( const wchar_t *a, const wchar_t *b );
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSNCASECMP
|
||||
/**
|
||||
Case insensitive string compare function. Wide string version of
|
||||
strncasecmp.
|
||||
@@ -214,6 +225,7 @@ int wcscasecmp( const wchar_t *a, const wchar_t *b );
|
||||
a user-supplied string should be considered a bug.
|
||||
*/
|
||||
int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count );
|
||||
#endif
|
||||
|
||||
/**
|
||||
Test if the given string is a valid variable name
|
||||
|
||||
65
complete.c
65
complete.c
@@ -1213,10 +1213,12 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
array_list_t tmp;
|
||||
al_init( &tmp );
|
||||
|
||||
expand_string( wcsdup(cmd),
|
||||
comp,
|
||||
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY );
|
||||
complete_cmd_desc( cmd, comp );
|
||||
if( expand_string( wcsdup(cmd),
|
||||
comp,
|
||||
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY ) != EXPAND_ERROR )
|
||||
{
|
||||
complete_cmd_desc( cmd, comp );
|
||||
}
|
||||
al_destroy( &tmp );
|
||||
}
|
||||
else
|
||||
@@ -1237,14 +1239,15 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
|
||||
al_init( &tmp );
|
||||
|
||||
expand_string( nxt_completion,
|
||||
if( expand_string( nxt_completion,
|
||||
&tmp,
|
||||
ACCEPT_INCOMPLETE |
|
||||
EXECUTABLES_ONLY );
|
||||
|
||||
for( i=0; i<al_get_count(&tmp); i++ )
|
||||
EXECUTABLES_ONLY ) != EXPAND_ERROR )
|
||||
{
|
||||
al_push( comp, al_get( &tmp, i ) );
|
||||
for( i=0; i<al_get_count(&tmp); i++ )
|
||||
{
|
||||
al_push( comp, al_get( &tmp, i ) );
|
||||
}
|
||||
}
|
||||
|
||||
al_destroy( &tmp );
|
||||
@@ -1290,24 +1293,26 @@ static void complete_cmd( const wchar_t *cmd,
|
||||
|
||||
al_init( &tmp );
|
||||
|
||||
expand_string( nxt_completion,
|
||||
if( expand_string( nxt_completion,
|
||||
&tmp,
|
||||
ACCEPT_INCOMPLETE | DIRECTORIES_ONLY );
|
||||
|
||||
for( i=0; i<al_get_count(&tmp); i++ )
|
||||
ACCEPT_INCOMPLETE | DIRECTORIES_ONLY ) != EXPAND_ERROR )
|
||||
{
|
||||
wchar_t *nxt = (wchar_t *)al_get( &tmp, i );
|
||||
|
||||
wchar_t *desc = wcsrchr( nxt, COMPLETE_SEP );
|
||||
int is_valid = (desc && (wcscmp(desc,
|
||||
COMPLETE_DIRECTORY_DESC)==0));
|
||||
if( is_valid )
|
||||
|
||||
for( i=0; i<al_get_count(&tmp); i++ )
|
||||
{
|
||||
al_push( comp, nxt );
|
||||
}
|
||||
else
|
||||
{
|
||||
free(nxt);
|
||||
wchar_t *nxt = (wchar_t *)al_get( &tmp, i );
|
||||
|
||||
wchar_t *desc = wcsrchr( nxt, COMPLETE_SEP );
|
||||
int is_valid = (desc && (wcscmp(desc,
|
||||
COMPLETE_DIRECTORY_DESC)==0));
|
||||
if( is_valid )
|
||||
{
|
||||
al_push( comp, nxt );
|
||||
}
|
||||
else
|
||||
{
|
||||
free(nxt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1766,7 +1771,10 @@ static void complete_param_expand( wchar_t *str,
|
||||
else
|
||||
comp_str = str;
|
||||
|
||||
// fwprintf( stderr, L"expand_string( \"%ls\", [list], EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | %ls )\n", comp_str, do_file?L"0":L"EXPAND_SKIP_WILDCARDS" );
|
||||
debug( 2,
|
||||
L"expand_string( \"%ls\", comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | %ls );",
|
||||
comp_str,
|
||||
do_file?L"0":L"EXPAND_SKIP_WILDCARDS" );
|
||||
|
||||
expand_string( wcsdup(comp_str), comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | (do_file?0:EXPAND_SKIP_WILDCARDS) );
|
||||
}
|
||||
@@ -1963,7 +1971,7 @@ void complete( const wchar_t *cmd,
|
||||
error_max=0;
|
||||
|
||||
/**
|
||||
If we are completing a variable name or a tilde expantion user
|
||||
If we are completing a variable name or a tilde expansion user
|
||||
name, we do that and return. No need for any other competions.
|
||||
*/
|
||||
|
||||
@@ -2009,7 +2017,7 @@ void complete( const wchar_t *cmd,
|
||||
|
||||
tok_init( &tok, buff, TOK_ACCEPT_UNFINISHED );
|
||||
|
||||
while( !end_loop )
|
||||
while( tok_has_next( &tok) && !end_loop )
|
||||
{
|
||||
switch( tok_last_type( &tok ) )
|
||||
{
|
||||
@@ -2055,7 +2063,8 @@ void complete( const wchar_t *cmd,
|
||||
reader_current_token_extent( &begin, &end, &prev_begin, &prev_end );
|
||||
|
||||
current_token = wcsndup( begin, reader_get_cursor_pos()-(begin-reader_get_buffer()) );
|
||||
prev_token = wcsndup( prev_begin, prev_end - prev_begin );
|
||||
|
||||
prev_token = prev_begin ? wcsndup( prev_begin, prev_end - prev_begin ): wcsdup(L"");
|
||||
|
||||
// fwprintf( stderr, L"on_command: %d, %ls %ls\n", on_command, current_compmand, current_token );
|
||||
|
||||
|
||||
16
configure.ac
16
configure.ac
@@ -1,5 +1,5 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(fish,1.17.0,axel@liljencrantz.se)
|
||||
AC_INIT(fish,1.19.0,fish-users@lists.sf.net)
|
||||
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
@@ -18,6 +18,15 @@ AC_PROG_INSTALL
|
||||
#AC_ISC_POSIX
|
||||
#AC_PROG_MAKE_SET
|
||||
|
||||
AC_CHECK_PROG( has_doxygen, [doxygen], "true")
|
||||
|
||||
if ! test $has_doxygen = "true"; then
|
||||
echo Could not find the Doxygen program in your path.
|
||||
echo This program is needed to build fish.
|
||||
echo Please install it and try again.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Optionally drop xsel
|
||||
AC_ARG_WITH( xsel,
|
||||
AC_HELP_STRING([--without-xsel],
|
||||
@@ -56,6 +65,7 @@ fi
|
||||
|
||||
AC_DEFINE_UNQUOTED( DOCDIR, [L"$(eval echo $docdir)"], [Documentation directory] )
|
||||
AC_DEFINE_UNQUOTED( SYSCONFDIR, [L"$(eval echo $sysconfdir)"], [System configuration directory] )
|
||||
AC_SUBST( SYSCONFDIR, ["$(eval echo $sysconfdir)"] )
|
||||
|
||||
# See if Linux procfs is present
|
||||
AC_CHECK_FILES([/proc/self/stat])
|
||||
@@ -119,6 +129,8 @@ fi
|
||||
AC_CHECK_LIB(socket, connect)
|
||||
AC_CHECK_LIB(rt, nanosleep)
|
||||
|
||||
AC_CHECK_FUNCS(wcsdup wcsndup wcslen wcscasecmp wcsncasecmp)
|
||||
|
||||
# Check if we have ncurses, and use it rather than curses if possible.
|
||||
AC_CHECK_HEADERS([ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURSES_H)],[AC_SUBST(CURSESLIB,[curses])])
|
||||
|
||||
@@ -127,5 +139,5 @@ AC_CHECK_HEADERS([ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURS
|
||||
#does not properly support terminfo.
|
||||
AC_CHECK_FILE([/usr/pkg/include/ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURSES_H)])
|
||||
|
||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile init/fish])
|
||||
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile init/fish init/fish_interactive.fish init/fish_complete.fish])
|
||||
AC_OUTPUT
|
||||
|
||||
19
doc_src/block.txt
Normal file
19
doc_src/block.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
\section block block - Temporarily block delivery of events
|
||||
|
||||
\subsection block-synopsis Synopsis
|
||||
<tt>block [OPTIONS...]</tt>
|
||||
|
||||
\subsection block-description Description
|
||||
|
||||
- <tt>-l</tt> or <tt>--local</tt> Release the block at the end of the currently innermost block scope
|
||||
- <tt>-g</tt> or <tt>--global</tt> Never automatically release the lock
|
||||
- <tt>-e</tt> or <tt>--erase</tt> Release global block
|
||||
|
||||
\subsection block-example Example
|
||||
|
||||
<pre>block -g
|
||||
\#Do something that should not be interrupted
|
||||
block -e
|
||||
</pre>
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
<tt>complete (-c|--command|-p|--path) COMMAND [(-s|--short-option) SHORT_OPTION] [(-l|--long-option|-o|--old-option) LONG_OPTION [(-a||--arguments) OPTION_ARGUMENTS] [(-d|--description) DESCRIPTION] </tt>
|
||||
|
||||
\subsection complete-description Description
|
||||
|
||||
For an introduction to how to specify completions, see the section <a
|
||||
href='index.html#completions-own'>Writing your own completions</a> of
|
||||
the fish manual.
|
||||
|
||||
- <tt>COMMAND</tt> is the name of the command for which to add a completion
|
||||
- <tt>SHORT_OPTION</tt> is a one character option for the command
|
||||
- <tt>LONG_OPTION</tt> is a multi character option for the command
|
||||
@@ -61,7 +66,9 @@ are valid, like the \c nodeps switch.
|
||||
|
||||
This can be written as:
|
||||
|
||||
<tt>complete -c rpm -n "__fish_contains_opt -s e erase" -l nodeps -d 'Dont check dependencies'</tt>
|
||||
<tt>complete -c rpm -n "__fish_contains_opt -s e erase" -l nodeps -d
|
||||
"Don't check dependencies"</tt>
|
||||
|
||||
where \c __fish_contains_opt is a function that checks the commandline buffer for the presense of a specified set of options.
|
||||
where \c __fish_contains_opt is a function that checks the commandline
|
||||
buffer for the presense of a specified set of options.
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ the user does not have to worry about an array containing elements
|
||||
such as dashes. \c fish performs a special check when invoking the
|
||||
count program, and if the user uses a help option, this help page is
|
||||
displayed, but if a help option is contained inside of a variable or
|
||||
is the result of expantion, it will be passed on to the count program.
|
||||
is the result of expansion, it will be passed on to the count program.
|
||||
|
||||
\subsection count-example Example
|
||||
|
||||
|
||||
370
doc_src/doc.hdr
370
doc_src/doc.hdr
@@ -1,15 +1,20 @@
|
||||
/** \mainpage fish
|
||||
/** \mainpage Fish user documentation
|
||||
|
||||
\c fish is a user friendly shell intended mostly for interactive use.
|
||||
A shell is a program which allows you to execute other programs by
|
||||
typing their names. For updates on \c fish, go to the <a
|
||||
\section introduction The friendly interactive shell
|
||||
|
||||
This is the documentation for \c fish, the friendly interactive
|
||||
shell. \c fish is a user friendly commandline shell intended
|
||||
mostly for interactive use. A shell is a program used to execute other
|
||||
programs. For the latest information on \c fish, please visit the <a
|
||||
href="http://roo.no-ip.org/fish/"><tt>fish</tt> homepage</a>.
|
||||
|
||||
\section syntax Syntax overview
|
||||
|
||||
Shells like \c fish are used by giving them commands. Every \c fish command follows the same simple syntax.
|
||||
Shells like fish are used by giving them commands. Every \c fish
|
||||
command follows the same simple syntax.
|
||||
|
||||
A command is executed by writing the name of the command followed by any arguments.
|
||||
A command is executed by writing the name of the command followed by
|
||||
any arguments.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -18,7 +23,7 @@ Example:
|
||||
calls the \c echo command. \c echo is a command which will write its
|
||||
arguments to the screen. In the example above, the output will be
|
||||
'hello world'. Everything in fish is done with commands. There are
|
||||
commonds for performing a set of command multiple times, commands for
|
||||
commands for performing a set of command multiple times, commands for
|
||||
assigning variables, commands for treating a group of commands as a
|
||||
single command, etc.. And every single command follows the same simple
|
||||
syntax.
|
||||
@@ -61,11 +66,13 @@ written on the same line by separating them with semicolons.
|
||||
Sometimes features such as <a href="#globbing">parameter expansion</a>
|
||||
and <a href="#escapes">character escapes</a> get in the way. When that
|
||||
happens, the user can write a parameter within quotes, either '
|
||||
(single quote) or " (double quote). There is no difference between
|
||||
single quoted and double quoted strings. A quoted parameter will not
|
||||
be parameter expanded, may contain spaces, and the only escape
|
||||
sequences allowed is the corresponding quote character. Single and
|
||||
double quotes may be nested.
|
||||
(single quote) or " (double quote). There is one important difference
|
||||
between single quoted and double quoted strings: When using double
|
||||
quoted string, <a href='#expand-variable'>variable expansion</a> still
|
||||
takes place. Other than that, a quoted parameter will not be
|
||||
parameter expanded, may contain spaces, and escape sequences are
|
||||
ignored. Single quotes have no special meaning withing double quotes
|
||||
and vice versa.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -113,11 +120,11 @@ a number called a file descriptor (FD). These are:
|
||||
- Standard output, FD 1, for writing, defaults to writing to the screen.
|
||||
- Standard error, FD 2, for writing errors and warnings, defaults to writing to the screen.
|
||||
|
||||
The reason for providing for two methods of output is so errors and
|
||||
The reason for providing for two methods of output is that errors and
|
||||
warnings can be separated from regular program output.
|
||||
|
||||
Any file descriptor can be directed to a different output than it's
|
||||
default through a simple mechanism called a redirecton.
|
||||
default through a simple mechanism called a redirection.
|
||||
|
||||
An example of a file redirection is <tt> echo hello \>output.txt</tt>,
|
||||
which directs the output of the echo command to the file error.txt.
|
||||
@@ -210,7 +217,7 @@ This is a short explanation of some of the commonly used words in fish.
|
||||
- argument, a parameter given to a command
|
||||
- builtin, a command that is implemented as part of the shell
|
||||
- command, a program
|
||||
- function, a command that is implemented as a set of fish commands
|
||||
- function, a block of one or more fish commands that can be called as a single command. By using functions, it is possible to string together multiple smaller commands into one more advanced command.
|
||||
- job, a running pipeline or command
|
||||
- pipeline, a set of commands stringed together so that the output of one command is the input of the next command
|
||||
- redirection, a operation that changes one of the input/output streams associated with a job
|
||||
@@ -240,7 +247,7 @@ differ on the first character, a list of all possible completions is
|
||||
printed. The list features descriptions of the completions and if the
|
||||
list doesn't fit the screen, it is scrollable by using the arrow keys,
|
||||
the page up/page down keys or the space bar. Press any other key will
|
||||
exit the list and insert the presssed key into the command line.
|
||||
exit the list and insert the pressed key into the command line.
|
||||
|
||||
These are the general purpose tab completions that \c fish provides:
|
||||
|
||||
@@ -264,34 +271,62 @@ in the known_hosts file. (see the ssh documentation for more information)
|
||||
- The 'su' command complete using all users on the system
|
||||
- The \c apt-get, \c rpm and \c tym commands complete using all installed packages.
|
||||
|
||||
Specifying your own completions is easy. If the command 'myprog' has
|
||||
an option '-o' which can also be written as '--output', which requires
|
||||
an additional value of either 'yes' or 'no' and decides if the program
|
||||
should write anything, this can be specified by writing:
|
||||
\subsection completion-own Writing your own completions
|
||||
|
||||
<tt>complete -c myprog -s o -l output -r -a "yes no" -d "Write output"</tt>
|
||||
Specifying your own completions is not complicated. To specify a
|
||||
completion, one simply uses the \c complete command. \c complete takes
|
||||
as a parameter the name of the command to specify a completion
|
||||
for. For example, to add a completion for the program \c myprog, one
|
||||
would start the completion command with <tt>complete -c myprog
|
||||
...</tt>. To provide a list of possible completions for myprog, use
|
||||
the \c -a switch. If \c myprog accepts the arguments start and stop,
|
||||
this can be specified as <tt>complete -c myprog -a 'start
|
||||
stop'</tt>. The argument to the \c -a switch is always a single
|
||||
string. At completion time, it will be tokenized on spaces and tabs,
|
||||
and variable expansion, command substitution and other forms of
|
||||
parameter expansion will take place.
|
||||
|
||||
For a more complete description of how to specify your own
|
||||
completions, go <a href="builtins.html#complete">here</a> or write 'complete --help' in the \c fish shell.
|
||||
Fish has a special syntax to support specifying switches accepted by a
|
||||
command. The switches \c -s, \c -l and \c -o are used to specify a
|
||||
short switch (single character, such as -l), a gnu style long switch (such as
|
||||
--color) and an old-style long switch (like -shuffle),
|
||||
respectively. If the command 'myprog' has an option '-o' which can
|
||||
also be written as '--output', and which can take an additional value
|
||||
of either 'yes' or 'no', this can be specified by writing:
|
||||
|
||||
<tt>complete -c myprog -s o -l output -a "yes no"</tt>
|
||||
|
||||
There are also special switches for specifying that a switch requires
|
||||
an argument, to disable filename completion, to create completions
|
||||
that are only available in some combinations, etc.. For a complete
|
||||
description of the various switches accepted by the \c complete
|
||||
command, see the documentation for the <a
|
||||
href="builtins.html#complete">complete</a> builtin, or write 'complete
|
||||
--help' inside the \c fish shell.
|
||||
|
||||
For examples of how to write your own complex completions, study the
|
||||
completions in /etc/fish.d/completions (or ~/etc/fish.d/completions if
|
||||
you installed fish in your home directory).
|
||||
|
||||
If you wish to use a completion, you should consider adding it to your
|
||||
startup files. When completion has been requested for a command \c
|
||||
COMMAND, fish will automatically look for the file
|
||||
~/.fish.d/completions/COMMAND.fish. If it exists, it will be
|
||||
automatically loaded. For examples of how to write your own complex
|
||||
completions, study the completions in /etc/fish.d/completions (or ~/etc/fish.d/completions if you installed fish in your home directory).
|
||||
automatically loaded. If you have written new completions for a common
|
||||
Unix command, please consider sharing your work by sending it to <a
|
||||
href='mailto: fish-users@lists.sf.net'>the fish mailinglist</a>.
|
||||
|
||||
\section expand Parameter expansion (Globbing)
|
||||
|
||||
When an argument for a program is given on the commandline, it
|
||||
undergoes the process of parameter expantion before it is sent on to
|
||||
undergoes the process of parameter expansion before it is sent on to
|
||||
the command. There are many ways in which the user can specify a
|
||||
parameter to be expanded. These include:
|
||||
|
||||
\subsection expand-wildcards Wildcards
|
||||
\subsection expand-wildcard Wildcards
|
||||
|
||||
If a star (*) or a question mark (?) is present in the parameter, \c
|
||||
fish attempts to mach the given parameter to any files in such a
|
||||
fish attempts to match the given parameter to any files in such a
|
||||
way that '?' can match any character except '/' and '*' can match any
|
||||
string of characters not containing '/'.
|
||||
|
||||
@@ -300,17 +335,24 @@ Example:
|
||||
|
||||
<code>???</code> matches any file in the current directory whose name is exactly three characters long.
|
||||
|
||||
If no matches are found for a specific wildcard, it will expand into
|
||||
zero arguments, i.e. to nothing. If none of the wildcarded arguments
|
||||
sent to a command result in any matches, the command will not be
|
||||
executed. If this happens when using the shell interactively, a
|
||||
warning will also be printed.
|
||||
|
||||
\subsection expand-command-substitution Command substitution
|
||||
|
||||
If a parameter contains a set of parenthesis, the text enclosed by the
|
||||
parentesis will be interpreted as a list of commands. Om expantion,
|
||||
parenthesis will be interpreted as a list of commands. Om expansion,
|
||||
this list is executed, and substituted by the output. If the output is
|
||||
more than one line long, each line will be expanded to a new
|
||||
parameter.
|
||||
|
||||
Example:
|
||||
|
||||
The command <code>echo (basename image.jpg .jpg).png</code> will output 'image.png'.
|
||||
The command <code>echo (basename image.jpg .jpg).png</code> will
|
||||
output 'image.png'.
|
||||
|
||||
The command <tt>for i in *.jpg; convert $i (basename $i .jpg).png;
|
||||
end</tt> will convert all Jpeg files in the current directory to the
|
||||
@@ -339,11 +381,44 @@ href="#variables"> Environment variables</a> section.
|
||||
Example:
|
||||
|
||||
<tt> echo \$HOME</tt> prints the home directory of the current
|
||||
user. If you wish to combine environment variables with text, you can
|
||||
user.
|
||||
|
||||
If you wish to combine environment variables with text, you can
|
||||
encase the variables within braces to embed a variable inside running
|
||||
text like <tt>echo Konnichiwa {$USER}san</tt>, which will print a
|
||||
personalized Japanese greeting.
|
||||
|
||||
The {$USER}san syntax might need a bit of an elaboration. Posix
|
||||
shells allow you to specify a variable name using '$VARNAME' or
|
||||
'${VARNAME}'. Fish only supports the former, but has no support
|
||||
whatsoever for the latter or anything remotely like it. So what is
|
||||
'{$VARNAME}' then? Well, '{WHATEVER}' is <a href='#brace'>brace
|
||||
expansion</a>, the same as supported by Posix shells, i.e. 'a{b,c}d'
|
||||
-> 'abd acd' works both in bash and on fish. So '{$VARNAME}' is a
|
||||
bracket-expansion with only a single element, i.e. it becomes
|
||||
expanded to '$VARNAME', which will be variable expanded to the value
|
||||
of the variable 'VARNAME'. So you might think that the brackets don't
|
||||
actually do anything, and that is nearly the truth. The snag is that
|
||||
there once along the way was a '}' in there somewhere, and } is not a
|
||||
valid character in a variable name. So anything after the otherwise
|
||||
pointless bracket expansion becomes NOT a part of the variable name,
|
||||
even if it happens to be a legal variable name character. That's why
|
||||
'{$USER}san' works. A case of one syntax just lending itself so nicely
|
||||
to solving an unrelated problem in it's spare time.
|
||||
|
||||
Variable expansion is the only type of expansion performed on double
|
||||
quoted strings. There is, however, an important difference in how
|
||||
variables are expanded when quoted and when unquoted. An unquoted
|
||||
variable expansion will result in a variable number of arguments. For
|
||||
example, if the variable $foo has zero elements or is undefined, the
|
||||
argument $foo will expand to zero elements. If the variable $foo is an
|
||||
array of five elements, the argument $foo will expand to five
|
||||
elements. When quoted, like "$foo", a variable expansion will always
|
||||
result in exactly one argument. Undefined variables will expand to the
|
||||
empty string, and array variables will be concatenated using the space
|
||||
character.
|
||||
|
||||
|
||||
\subsection expand-home Home directory expansion
|
||||
|
||||
The ~ (tilde) character at the beginning of a parameter, followed by a
|
||||
@@ -354,7 +429,7 @@ directory of the process owner.
|
||||
\subsection expand-process Process expansion
|
||||
|
||||
The \% (percent) character at the beginning of a parameter followed by
|
||||
a string is expanded into a process id. The following expantions are
|
||||
a string is expanded into a process id. The following expansions are
|
||||
performed:
|
||||
|
||||
- If the string is the entire word \c self, the shells pid is the result
|
||||
@@ -394,7 +469,9 @@ will output 'abar1 abar2 abar3 afoo1 afoo2 afoo3'.
|
||||
|
||||
The concept of environment variables are central to any
|
||||
shell. Environment variables are variables, whose values can be set
|
||||
and used by the user.
|
||||
and used by the user. For information on how to use the current value
|
||||
of a variable, see the section on <a href='#expand-variable'>variable
|
||||
expansion</a>.
|
||||
|
||||
To set a variable value, use the <a href="builtins.html#set"> \c set
|
||||
command</a>.
|
||||
@@ -409,25 +486,25 @@ the shell through <a href="expand-variable">variable expansion</a>.
|
||||
|
||||
Example:
|
||||
|
||||
To use the value of a the variable \c smurf, use the command <tt>echo
|
||||
Smurfs are $smurf</tt>, which would print the result 'Smurfs are
|
||||
blue'.
|
||||
To use the value of a the variable \c smurf, write $ (dollar symbol)
|
||||
followed by the name of the variable, like <tt>echo Smurfs are
|
||||
$smurf</tt>, which would print the result 'Smurfs are blue'.
|
||||
|
||||
\subsection variables-scope Variable scope
|
||||
|
||||
There are three kinds of variables in fish, universal, global and
|
||||
local variables. Universal variables are shared between all fish
|
||||
sessions a user is running on one computer. Global variables are
|
||||
specific to the current fish session, and will never be erased unless
|
||||
the user explicitly requests it using <tt>set -e</tt>. Local variables
|
||||
are specific to the current fish session, and associated with a
|
||||
specific block of commands, and is automatically erased when a
|
||||
specific block goes out of scope. A block of commands is a series of
|
||||
commands that begins with one of the commands \c 'for, \c 'while' , \c
|
||||
'if', \c 'function', \c 'begin' or \c 'switch', and ends with the
|
||||
command \c 'end'. The user can specify that a variable should have
|
||||
either global or local scope using the \c -g/--global or \c -l/--local
|
||||
switches.
|
||||
specific to the current fish session, but are not associated with any
|
||||
specific block scope, and will never be erased unless the user
|
||||
explicitly requests it using <tt>set -e</tt>. Local variables are
|
||||
specific to the current fish session, and associated with a specific
|
||||
block of commands, and is automatically erased when a specific block
|
||||
goes out of scope. A block of commands is a series of commands that
|
||||
begins with one of the commands \c 'for, \c 'while' , \c 'if', \c
|
||||
'function', \c 'begin' or \c 'switch', and ends with the command \c
|
||||
'end'. The user can specify that a variable should have either global
|
||||
or local scope using the \c -g/--global or \c -l/--local switches.
|
||||
|
||||
Variables can be explicitly set to be universal with the \c -U or \c
|
||||
--universal switch, global with the \c -g or \c --global switch, or
|
||||
@@ -436,21 +513,24 @@ creating or updating a variable are:
|
||||
|
||||
-# If a variable is explicitly set to either universal, global or local, that setting will be honored
|
||||
-# If a variable is not explicitly set to be either universal, global or local, but has been previously defined, the variable scope is not changed
|
||||
-# If a variable is not explicitly set to be either universal, global or local and has never befor been defined, the variable will be local to the current scope
|
||||
-# If a variable is not explicitly set to be either universal, global or local and has never before been defined, the variable will be local to the currently executing functions. If no function is executing, the variable will be global.
|
||||
|
||||
There may be many variables with the same name, but different scopes.
|
||||
When using a variable, the variable scope will be searched from the
|
||||
inside out, i.e. a local variable will be used rather than a global
|
||||
variable with the same name, a global variable will be used rather
|
||||
than a universal variable with the same name.
|
||||
|
||||
For example, the following code will not output anything:
|
||||
Example:
|
||||
|
||||
The following code will not output anything:
|
||||
<pre>
|
||||
if true
|
||||
begin
|
||||
# This is a nice local scope where all variables will die
|
||||
set pirate 'There be treasure in them thar hills'
|
||||
set -l pirate 'There be treasure in them thar hills'
|
||||
end
|
||||
|
||||
# This will not output anything, since the pirate is dead
|
||||
# This will not output anything, since the pirate was local
|
||||
echo $pirate
|
||||
</pre>
|
||||
|
||||
@@ -472,9 +552,9 @@ prompt will instantly change to blue on both terminals.
|
||||
\subsection variables-functions Variable scope for functions
|
||||
|
||||
When calling a function, all non-global variables temporarily
|
||||
dissapear. This shadowing of the local scope is needed since the
|
||||
disappear. This shadowing of the local scope is needed since the
|
||||
variable namespace would become cluttered, making it very easy to
|
||||
accidentaly overwrite variables from another function.
|
||||
accidentally overwrite variables from another function.
|
||||
|
||||
For example, the following code will output 'Avast, mateys':
|
||||
|
||||
@@ -510,7 +590,7 @@ identical to the scoping rules for variables:
|
||||
|
||||
-# If a variable is explicitly set to either be exported or not exported, that setting will be honored
|
||||
-# If a variable is not explicitly set to be exported or not exported, but has been previously defined, the previous exporting rule for the variable is kept
|
||||
-# If a variable is not explicitly set to be either global or local and has never befor been defined, the variable will not be exported
|
||||
-# If a variable is not explicitly set to be either global or local and has never before been defined, the variable will not be exported
|
||||
|
||||
|
||||
\subsection variables-arrays Arrays
|
||||
@@ -563,22 +643,25 @@ certain environment variables.
|
||||
- \c CDPATH, which is an array of directories in which to search for the new directory for the \c cd builtin.
|
||||
- \c fish_color_normal, \c fish_color_command, \c fish_color_substitution, \c fish_color_redirection, \c fish_color_end, \c fish_color_error, \c fish_color_param, \c fish_color_comment, \c fish_color_match, \c fish_color_search_match, \c fish_color_cwd, \c fish_pager_color_prefix, \c fish_pager_color_completion, \c fish_pager_color_description and \c fish_pager_color_progress are used to change the color of various elements in \c fish. These variables are universal, i.e. when changing them, their new value will be used by all running fish sessions. The new value will also be retained when restarting fish.
|
||||
- \c PATH, which is an array of directories in which to search for commands
|
||||
- \c umask, which is the current file creation mask. The preffered way to change the umask variable is through the <a href="commands.html#umask">umask shellscript function</a>. An attempt to set umask to an invalid value will always fail.
|
||||
- \c umask, which is the current file creation mask. The preferred way to change the umask variable is through the <a href="commands.html#umask">umask shellscript function</a>. An attempt to set umask to an invalid value will always fail.
|
||||
|
||||
\c fish also sends additional information to the user through the
|
||||
values of certain environment variables. The user can not change the values of these variables. They are:
|
||||
values of certain environment variables. The user can not change the
|
||||
values of these variables. They are:
|
||||
|
||||
- \c _, which is the name of the currently running command.
|
||||
- \c history, which is an array containing the last commands that where entered
|
||||
- \c history, which is an array containing the last commands that where entered.
|
||||
- \c HOME, which is the users home directory. This variable can only be changed by the root user.
|
||||
- \c PWD, which is the current working directory.
|
||||
- \c PWD, which is the current working directory.
|
||||
- \c status, which is the exit status of the last foreground job to exit. If a job contains pipelines, the status of the last command in the pipeline is the status for the job.
|
||||
- \c USER, which is the username. This variable can only be changed by the root user.
|
||||
|
||||
Variables whose name are in uppercase are exported to the commands
|
||||
started by fish. \c fish also uses several variables internally. Such
|
||||
variables are prefixed with the string __FISH or __fish. These should
|
||||
be ignored by the user.
|
||||
started by fish. This rule is not enforced by fish, but it is good
|
||||
coding practice to use casing to distinguish between exported and
|
||||
unexported variables. \c fish also uses several variables
|
||||
internally. Such variables are prefixed with the string __FISH or
|
||||
__fish. These should be ignored by the user.
|
||||
|
||||
\section builtin-overview Builtins
|
||||
|
||||
@@ -599,6 +682,7 @@ builtins or shellscript functions, and can only be used inside fish.
|
||||
- <a href="builtins.html#begin">begin</a>, execute a block of commands
|
||||
- <a href="builtins.html#bind">bind</a>, change keyboard bindings
|
||||
- <a href="builtins.html#break">break</a>, stop the execution of a loop
|
||||
- <a href="builtins.html#block">block</a>, Temporarily block delivery of events
|
||||
- <a href="builtins.html#builtin">builtin</a>, execute a builtin command
|
||||
- <a href="builtins.html#case">case</a>, conditionally execute a block of commands
|
||||
- <a href="builtins.html#cd">cd</a>, change the current directory
|
||||
@@ -654,24 +738,26 @@ Here are some of the commands available in the editor:
|
||||
- End or Ctrl-e moves to the end of line
|
||||
- Left and right moves one character left or right
|
||||
- Alt-left and Alt-right moves one word left or right, or moves forward/backward in the directory history if the commandline is empty
|
||||
- Up and down search the command history for the previous/next command containing the string that was specified on the commandline before the search was started. If the commandline was empty when the search started, all commands match. See the <a href='#history'>history </a>section for more information on history searching.
|
||||
- Alt-up and Alt-down search the command history for the previous/next token containing the token under the cursor before the search was started. If the commandline was not on a token when the search started, all tokens match. See the <a href='#history'>history </a>section for more information on history searching.
|
||||
- Delete and backspace removes one character forwards or backwards
|
||||
- Ctrl-c delete entire line
|
||||
- Ctrl-d delete one character to the right of the cursor, unless the buffer is empty, in which case the shell will exit
|
||||
- Ctrl-k move contents from cursor to end of line to <a href="#killring">killring</a>
|
||||
- Ctrl-u move contents from beginning of line to cursor <a href="#killring">killring</a>
|
||||
- Ctrl-k move contents from the cursor to the end of line to the <a href="#killring">killring</a>
|
||||
- Ctrl-u move contents from the beginning of line to the cursor to the <a href="#killring">killring</a>
|
||||
- Ctrl-l clear and repaint screen
|
||||
- Ctrl-w move previous word to <a href="#killring">killring</a>
|
||||
- Alt-d move next word to <a href="#killring">killring</a>
|
||||
- Ctrl-w move previous word to the <a href="#killring">killring</a>
|
||||
- Alt-d move next word to the <a href="#killring">killring</a>
|
||||
- Alt-w prints a short description of the command under the cursor
|
||||
- Alt-l lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed
|
||||
- Alt-k prints a list of all key bindings
|
||||
- Alt-p adds the string '| less;' to the end of the job under the cursor. The result is that the output of the command will be paged.aadddddssss
|
||||
|
||||
You can change these key bindings by making an inputrc file. To do
|
||||
this, copy the file /etc/fish_inputrc to your home directory and
|
||||
rename it to '.fish_inputrc'. Now you can edit the file .fish_inputrc,
|
||||
to change your key bindings. The fileformat of this file is described
|
||||
in the manual page for readline. Use the command <tt>man readline</tt>
|
||||
to read up on this syntax. Please note thet the list of key binding
|
||||
to read up on this syntax. Please note that the list of key binding
|
||||
functions in fish is different to that offered by readline. Currently,
|
||||
the following functions are available:
|
||||
|
||||
@@ -700,7 +786,11 @@ the following functions are available:
|
||||
- \c yank, insert the latest entry of the killring into the buffer
|
||||
- \c yank-pop, rotate to the previous entry of the killring
|
||||
|
||||
You can also bind a pice of shellscript to a key using the same
|
||||
syntax. For example, the Alt-p functionality described above is
|
||||
implemented using the following keybinding.
|
||||
|
||||
<pre>"\M-p": if commandline -j|grep -v 'less *$' >/dev/null; commandline -aj "|less;"; end</pre>
|
||||
|
||||
\subsection killring Copy and paste (Kill Ring)
|
||||
|
||||
@@ -721,24 +811,34 @@ After a command has been entered, it is inserted at the end of a
|
||||
history list. Any duplicate history items are automatically
|
||||
removed. By pressing the up and down keys, the user can search
|
||||
forwards and backwards in the history. If the current command line is
|
||||
not empty when starting a history search, only the commands starting
|
||||
with the string entered into the command line are searched.
|
||||
not empty when starting a history search, only the commands containing
|
||||
the string entered into the command line are shown.
|
||||
|
||||
By pressing Alt-up and Alt-down, a history search is also performed,
|
||||
but instead of searching for a complete commandline, each commandline
|
||||
is tokenized into separate elements just like it would be before
|
||||
execution, and each such token is matched agains the token under the
|
||||
cursor when the search began.
|
||||
|
||||
History searches can be aborted by pressing the escape key.
|
||||
|
||||
The history is stored in the file '.fish_history'. It is automatically
|
||||
read on startup and merged on program exit.
|
||||
|
||||
Example:
|
||||
|
||||
To search for previous entries starting with the letter 'l', type 'l'
|
||||
To search for previous entries containing the word 'make', type 'make'
|
||||
in the console and press the up key.
|
||||
|
||||
\section job-control Running multiple programs
|
||||
|
||||
Normally when \c fish starts a program, this program will be put
|
||||
in the foreground, meaning it will take control of the terminal and
|
||||
\c fish will be stopped until the program finishes. Sometimes
|
||||
this is not desirable. In such cases, there are several ways in which
|
||||
the user can change <tt>fish</tt>'s behaviour.
|
||||
Normally when \c fish starts a program, this program will be put in
|
||||
the foreground, meaning it will take control of the terminal and \c
|
||||
fish will be stopped until the program finishes. Sometimes this is not
|
||||
desirable. For example, you may wish to start an application with a
|
||||
graphical user interface from the terminal, and then be able to
|
||||
continue using the shell. In such cases, there are several ways in
|
||||
which the user can change <tt>fish</tt>'s behaviour.
|
||||
|
||||
-# By ending a command with the \& (ampersand) symbol, the user tells \c fish to put the specified command into the background. A background process will be run simultaneous with \c fish. \c fish will retain control of the terminal, so the program will not be able to read from the keyboard.
|
||||
-# By pressing ^Z, the user stops a currently running foreground program and returns control to \c fish. Some programs do not support this feature, or remap it to another key. Gnu emacs uses ^X z to stop running.
|
||||
@@ -746,14 +846,29 @@ the user can change <tt>fish</tt>'s behaviour.
|
||||
|
||||
\section initialization Initialization files
|
||||
|
||||
On startup, \c fish evaluates the file /etc/fish (Or ~/etc/fish if you installed fish in your home directory) and ~/.fish, in that
|
||||
order. If you want to run a command only on starting an interactive
|
||||
shell, use the output of the 'status --is-interactive' command. If
|
||||
you want to run a command only on starting a login shell, use 'status --is-login' instead.
|
||||
On startup, \c fish evaluates the file /etc/fish (Or ~/etc/fish if you
|
||||
installed fish in your home directory) and ~/.fish, in that order. If
|
||||
you want to run a command only on starting an interactive shell, use
|
||||
the exit status of the command 'status --is-interactive' to determine
|
||||
if the shell is interactive. If you want to run a command only on
|
||||
starting a login shell, use 'status --is-login' instead.
|
||||
|
||||
If you want to run a set of commands when \c fish exits, redefine the
|
||||
<a href="#hooks">function hook</a> \c fish_on_exit. If the \c
|
||||
fish_on_exit is defined, it will be execute before the shell exits.
|
||||
Example:
|
||||
|
||||
If you want to add the directory ~/linux/bin to your PATH variable
|
||||
when loging in, add the following to your ~/.fish file:
|
||||
|
||||
<pre>if status --is-login
|
||||
set PATH $PATH ~/linux/bin
|
||||
end</pre>
|
||||
|
||||
If you want to run a set of commands when \c fish exits, use an <a
|
||||
href='#event'>event handler</a> that is triggered by the exit of the
|
||||
shell:
|
||||
|
||||
<pre>function on_exit --on-process %self
|
||||
echo fish is now exiting
|
||||
end</pre>
|
||||
|
||||
<a href="#variables-universal">Universal variables</a> are stored in
|
||||
the file .fishd.HOSTNAME, where HOSTNAME is the name of your
|
||||
@@ -772,7 +887,7 @@ marked red.
|
||||
Detected errors include:
|
||||
|
||||
- Non existing commands.
|
||||
- Reading or appending from non existing files.
|
||||
- Reading from or appending to a non existing file.
|
||||
- Incorrect use of output redirects
|
||||
- Mismatched parenthesis
|
||||
|
||||
@@ -789,7 +904,7 @@ fish_pager_color_description and \c fish_pager_color_progress. Valid
|
||||
values are \c black, \c red, \c green, \c brown, \c yellow, \c blue,
|
||||
\c magenta, \c purple, \c cyan, \c white or \c normal. Setting one of
|
||||
the above variables to normal will mean that the text color will be
|
||||
set to the default color for the terminal.
|
||||
set to the default foreground color for the terminal.
|
||||
|
||||
\subsection prompt Programmable prompt
|
||||
|
||||
@@ -804,17 +919,11 @@ The default \c fish prompt is
|
||||
<p>
|
||||
<pre>
|
||||
function fish_prompt -d "Write out the prompt"
|
||||
printf '\%s\@\%s\%s\\n\%s\%s\\n> ' (whoami) (hostname|cut -d . -f 1) (set_color \$fish_color_cwd) (prompt_pwd) (set_color normal)
|
||||
printf '\%s\@\%s\%s\%s\%s> ' (whoami) (hostname|cut -d . -f 1) (set_color \$fish_color_cwd) (prompt_pwd) (set_color normal)
|
||||
end
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
If you are using \c set_color or other commands that output escape
|
||||
codes to change the font settings of the terminal, you must always and
|
||||
every such sequence with a newline. This is needed since fish needs to
|
||||
know that exact length of the prompt in order to tetect when the
|
||||
cursor reaches the end of the line. Any newlines in the output of the
|
||||
\c fish_prompt command are ignored.
|
||||
|
||||
\subsection title Programmable title
|
||||
|
||||
@@ -835,15 +944,28 @@ end
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
\subsection hooks Event hooks
|
||||
\subsection event Event handlers
|
||||
|
||||
There are several special function names in fish. If a function is
|
||||
given this name, it will be automatically called when a specific event
|
||||
has occured. These functions are:
|
||||
When defining a new function in fish, it is possible to make it into an
|
||||
event handler, i.e. a function that is automatically run when a
|
||||
specific event takes place. Events that can trigger a handler currently are:
|
||||
|
||||
- \c fish_on_exit, which is called before the shell exits
|
||||
- \c fish_on_exec, which is called before interactively executing a command
|
||||
- \c fish_on_return, which is called when control returns to the shell after interactively executing a command
|
||||
* When a signal is delivered
|
||||
* When a process or job exits
|
||||
* When the value of a variable is updated
|
||||
|
||||
Example:
|
||||
|
||||
To specify a signal handler for the WINCH signal, write:
|
||||
|
||||
<pre>function --on-signal WINCH my_signal_handler
|
||||
echo Got WINCH signal!
|
||||
end
|
||||
</pre>
|
||||
|
||||
For more information on how to define new event handlers, see the
|
||||
documentation for the <a href='builtins.html#function'>function</a>
|
||||
command.
|
||||
|
||||
\section issues Common issues with fish
|
||||
|
||||
@@ -860,9 +982,7 @@ directory, or install them in /etc.
|
||||
\subsection todo-features Missing features
|
||||
|
||||
- Complete vi-mode key bindings
|
||||
- '**' wildcard for recursive wildcard matching
|
||||
- next-history-complete
|
||||
- umask shellscript function
|
||||
- builtin wait command
|
||||
- More completions (for example xterm, vim,
|
||||
konsole, gnome-terminal, dcop, cdrecord, cron, xargs
|
||||
@@ -871,11 +991,10 @@ bibtex, patch, aspell, xpdf,
|
||||
zip, compress, wine, xmms, dig, wine, batch, cron,
|
||||
g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- Undo support
|
||||
- Multiple input characters should be inserted in one batch whenever possible, to avoid flickering
|
||||
- Check keybinding commands for output - if non has happened, don't repaint to reduce flicker
|
||||
- the jobs builtin should be able to give information on a specific job, such as the pids of the processes in the job
|
||||
- The jobs builtin should be able to give information on a specific job, such as the pids of the processes in the job
|
||||
- Syntax highlighting should mark cd to non-existing directories as an error
|
||||
|
||||
- wait shellscript
|
||||
|
||||
\subsection todo-possible Possible features
|
||||
|
||||
@@ -897,6 +1016,8 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- show the whole list of commands on using tab on an empty commandline
|
||||
- Automatically move cursor to the end of the current token before completing
|
||||
- Map variables. (export only the values. When expanding with no key specified, expand to all values.)
|
||||
- Descriptions for variables using 'set -d'.
|
||||
- Parse errors should when possible honor IO redirections
|
||||
|
||||
\subsection bugs Known bugs
|
||||
|
||||
@@ -904,13 +1025,13 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
|
||||
- Many completions are made specifically for the GNU
|
||||
version of a POSIX command
|
||||
- Yanking weird characters from clipboard prints Unicode escapes
|
||||
- Prefix string in completion display is sometimes incorrect
|
||||
- Suspending and then resuming pipelines containing a builtin seems to be broken.
|
||||
|
||||
If you think you have found a bug not described here, please send a
|
||||
report to <a href="mailto:axel@liljencrantz.se"> axel@liljencrantz.se
|
||||
</a>.
|
||||
|
||||
\subsection Known issues
|
||||
\subsection issues Known issues
|
||||
|
||||
Older versions of Doxygen has bugs in the man-page generation which
|
||||
cause the builtin help to render incorrectly. Version 1.2.14 is known
|
||||
@@ -942,6 +1063,10 @@ Most tradeoffs between power and ease of use can be avoided with careful design.
|
||||
-# Whenever possible without breaking the above goals, fish should
|
||||
follow the Posix syntax.
|
||||
|
||||
To achive these high-level goals, the fish design relies on a number
|
||||
of more specific design principles. These are presented below,
|
||||
together with a rationale and a few examples for each.
|
||||
|
||||
\subsection ortho The law of orthogonality
|
||||
|
||||
The shell language should have a small set of orthogonal features. Any
|
||||
@@ -958,7 +1083,10 @@ program harder to maintain and update.
|
||||
Examples:
|
||||
|
||||
- Here documents are too similar to using echo inside of a pipeline.
|
||||
- The different quoting styles are silly. ("", '' and \$'')
|
||||
- Subshells, command substitution and process substitution are strongly related. \c fish only supports command substitution, the others can be achived either using a block or the psub shellscript function.
|
||||
- Having both aliases and functions is confusing, especially since both of them have limitations and problems. \c fish sunctions have none of the drawbacks of either syntax.
|
||||
- The many Posix quoting styles are silly, especially \$''.
|
||||
|
||||
|
||||
\subsection sep The law of minimalism
|
||||
|
||||
@@ -990,9 +1118,8 @@ and many other funtions can easily be done in external programs. They
|
||||
should not be supported internally by the shell.
|
||||
|
||||
The law of minimalism does not imply that a large feature set is
|
||||
bad. So long as a feature is not part of the language itself, but a
|
||||
separate command or at least a shellscript function, bloat is much
|
||||
more acceptable.
|
||||
bad. So long as a feature is not part of the shell itself, but a
|
||||
separate command or at least a shellscript function, bloat is fine.
|
||||
|
||||
\subsection conf Configurability is the root of all evil
|
||||
|
||||
@@ -1015,7 +1142,7 @@ enough approximation of it.
|
||||
Examples:
|
||||
|
||||
- Fish allows the user to set various syntax highlighting colors. This is needed because fish does not know what colors the terminal uses by default, which might make some things unreadable. The proper solution would be for text color preferences to be defined centrally by the user for all programs, and for the terminal emulator to send these color properties to fish.
|
||||
- Fish does not allow you to set the history filename, the number of history entries, different language substyles or any number of other common cshell configuration options
|
||||
- Fish does not allow you to set the history filename, the number of history entries, different language substyles or any number of other common shell configuration options.
|
||||
|
||||
A special note on the evils of configurability is the long list of
|
||||
very useful features found in some shells, that are not turned on by
|
||||
@@ -1033,13 +1160,18 @@ considered once a user interface has been designed.
|
||||
|
||||
Rationale:
|
||||
|
||||
If too much attention is given to what is easy to implement the law of
|
||||
orthogonality and the law of minimalism will by necessity be disobeyed.
|
||||
This design rule is different than the others, since it describes how
|
||||
one should go about designing new features, not what the features
|
||||
should be. The problem with focusing on what can be done, and what is
|
||||
easy to do, is that to much of the implementation is exposed. This
|
||||
means that the user must know a great deal about the underlying system
|
||||
to be able to guess how the shell works, it also means that the
|
||||
language will often be rather low-level.
|
||||
|
||||
Examples:
|
||||
|
||||
- There should only be one type of input to the shell, lists of commands. Loops, conditionals and variable assignments are all performed through regular commands.
|
||||
- The differences between builtin commands, shellscript functions and builtin commands should be made as small as possible. Builtins and shellscript functions should have exactly the same types of argument expantion as other commands, should be possible to use in any position in a pipeline, and should support any io redirection.
|
||||
- The differences between builtin commands, shellscript functions and builtin commands should be made as small as possible. Builtins and shellscript functions should have exactly the same types of argument expansion as other commands, should be possible to use in any position in a pipeline, and should support any io redirection.
|
||||
- Instead of forking when performing command substitution to provide a fake variable scope, all fish commands are performed from the same process, and fish instead supports true scoping
|
||||
- All blocks end with the \c end builtin
|
||||
|
||||
@@ -1074,7 +1206,6 @@ Examples:
|
||||
/** \page about About fish
|
||||
|
||||
|
||||
|
||||
\section about-program About the program
|
||||
|
||||
\c fish is meant to be used for interactive shell tasks on a modern
|
||||
@@ -1255,17 +1386,6 @@ builtin. The are very few builtins, \c fish relies on normal commands
|
||||
like <tt>echo</tt>, <tt>kill</tt>, <tt>printf</tt> and <tt>time</tt>
|
||||
instead of reimplementing them as builtins.
|
||||
|
||||
The globbing in fish is significantly simplified. Since I can never
|
||||
remember all the subtle differences between single and double quotes,
|
||||
which kind of tick is used for command substitution and all the other
|
||||
strange quirks of of the Posix shell language, that aspect of shells
|
||||
has been significantly simplified. This makes \c fish unsuitable for
|
||||
strange shell scripting, but much more suited to interactive needs
|
||||
than regular shells.
|
||||
|
||||
There is no difference between double and single quotes. They both
|
||||
turn of all globbing and escape sequences. They can be nested.
|
||||
|
||||
Token separation is performed before variable expansion. This means
|
||||
that even if a variable contains spaces, it will never be separated
|
||||
into multiple arguments. If you want to tokenize a string, you can use
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
\section jobs jobs - print currently running jobs
|
||||
|
||||
\subsection jobs-synopsis
|
||||
<tt>jobs</tt>
|
||||
<tt>jobs [OPTIONS] [PID]</tt>
|
||||
|
||||
\subsection jobs-description Description
|
||||
The <tt>jobs</tt> builtin causes fish to print a list of the currently
|
||||
running jobs and their status.
|
||||
|
||||
On systems that supports this feature, jobs will also print the CPU
|
||||
usage of each job since the last command was executed. The CPU usage
|
||||
is expressed as a percentage of full CPU activity. Note that on
|
||||
jobs accepts the following switches:
|
||||
|
||||
- <tt>-c</tt> or <tt>--command</tt> print the command name for each process in jobs
|
||||
- <tt>-g</tt> or <tt>--group</tt> only print the group id of each job
|
||||
- <tt>-l</tt> or <tt>--last</tt> only the last job to be started is printed
|
||||
- <tt>-p</tt> or <tt>--process</tt> print the procces id for each process in all jobs
|
||||
|
||||
On systems that supports this feature, jobs will print the CPU usage
|
||||
of each job since the last command was executed. The CPU usage is
|
||||
expressed as a percentage of full CPU activity. Note that on
|
||||
multiprocessor systems, the total activity may be more than 100\%.
|
||||
|
||||
@@ -18,16 +18,12 @@ The <tt>set</tt> builtin causes fish to assign the variable <tt>VARIABLE_NAME</t
|
||||
If set is called with no arguments, the names and values of all
|
||||
environment variables are printed.
|
||||
|
||||
If set is called with only one argument, the scope of the variable
|
||||
with the given name will be changed as specified, but it's value will
|
||||
remain the same. If the variable did not previously exist, it's value
|
||||
will be an empty string.
|
||||
|
||||
If the \c -e or \c --erase option is specified, the variable
|
||||
specified by the following arguments will be erased
|
||||
|
||||
If a variable is set to more than one value, the variable will be an
|
||||
array with the specified elements.
|
||||
array with the specified elements. If a variable is set to zero
|
||||
elements, it will become an array with zero elements.
|
||||
|
||||
If the variable name is one or more array elements, such as <tt>PATH[1
|
||||
3 7]</tt>, only those array elements specified will be changed.
|
||||
|
||||
37
doc_src/trap.txt
Normal file
37
doc_src/trap.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
\section trap trap - perform an action when the shell recives a signal
|
||||
|
||||
\subsection trap-synopsis Synopsis
|
||||
<tt>trap [OPTIONS] [[ARG] SIGSPEC ... ]</tt>
|
||||
|
||||
\subsection trap-description Description
|
||||
|
||||
Trap is a shellscript wrapper around the fish event delivery
|
||||
framework. IT is defined for backwards compatibility reasons. For
|
||||
other uses, it is recomended to define a <a
|
||||
href='index.html#event'>event handler</a>.
|
||||
|
||||
- ARG is the command to be executed on signal delivary
|
||||
- SIGSPEC is the name of the signal to trap
|
||||
- \c -h or \c --help Display help and exit
|
||||
- \c -l or \c --list-signals print a list of signal names
|
||||
- \c -p or \c --print print all defined signal handlers
|
||||
|
||||
If ARG and SIGSPEC are both specified, ARG is the command to be
|
||||
executed when the signal specified by SIGSPEC is delivered.
|
||||
|
||||
If ARG is absent (and there is a single SIGSPEC) or -, each specified
|
||||
signal is reset to its original disposition (the value it had upon
|
||||
entrance to the shell). If ARG is the null string the signal
|
||||
specified by each SIGSPEC is ignored by the shell and by the commands
|
||||
it invokes.
|
||||
|
||||
If ARG is not present and -p has been supplied, then the trap commands
|
||||
associated with each SIGSPEC are displayed. If no arguments are
|
||||
supplied or if only -p is given, trap prints the list of commands
|
||||
associated with each signal.
|
||||
|
||||
Signal names are case insensitive and the SIG prefix is optional.
|
||||
|
||||
The return status is 1 if any SIGSPEC is invalid; otherwise trap
|
||||
returns 0.
|
||||
24
env.c
24
env.c
@@ -236,7 +236,6 @@ static void universal_callback( int type,
|
||||
|
||||
if( str )
|
||||
{
|
||||
array_list_t arg;
|
||||
event_t ev;
|
||||
|
||||
has_changed=1;
|
||||
@@ -245,12 +244,12 @@ static void universal_callback( int type,
|
||||
ev.param1.variable=name;
|
||||
ev.function_name=0;
|
||||
|
||||
al_init( &arg );
|
||||
al_push( &arg, L"VARIABLE" );
|
||||
al_push( &arg, str );
|
||||
al_push( &arg, name );
|
||||
event_fire( &ev, &arg );
|
||||
al_destroy( &arg );
|
||||
al_init( &ev.arguments );
|
||||
al_push( &ev.arguments, L"VARIABLE" );
|
||||
al_push( &ev.arguments, str );
|
||||
al_push( &ev.arguments, name );
|
||||
event_fire( &ev );
|
||||
al_destroy( &ev.arguments );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +488,6 @@ void env_set( const wchar_t *key,
|
||||
int done=0;
|
||||
|
||||
event_t ev;
|
||||
array_list_t ev_list;
|
||||
int is_universal = 0;
|
||||
|
||||
if( (var_mode & ENV_USER ) &&
|
||||
@@ -669,14 +667,14 @@ void env_set( const wchar_t *key,
|
||||
ev.param1.variable = key;
|
||||
ev.function_name = 0;
|
||||
|
||||
al_init( &ev_list );
|
||||
al_push( &ev_list, L"VARIABLE" );
|
||||
al_push( &ev_list, key );
|
||||
al_init( &ev.arguments );
|
||||
al_push( &ev.arguments, L"VARIABLE" );
|
||||
al_push( &ev.arguments, key );
|
||||
|
||||
// debug( 1, L"env_set: fire events on variable %ls", key );
|
||||
event_fire( &ev, &ev_list );
|
||||
event_fire( &ev );
|
||||
// debug( 1, L"env_set: return from event firing" );
|
||||
al_destroy( &ev_list );
|
||||
al_destroy( &ev.arguments );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
154
event.c
154
event.c
@@ -67,6 +67,12 @@ static array_list_t *events;
|
||||
*/
|
||||
static array_list_t *killme;
|
||||
|
||||
/**
|
||||
List of events that have been sent but have not yet been delivered because they are blocked.
|
||||
*/
|
||||
static array_list_t *blocked;
|
||||
|
||||
|
||||
/**
|
||||
Tests if one event instance matches the definition of a event
|
||||
class. If the class defines a function name, that will also be a
|
||||
@@ -120,7 +126,7 @@ static int event_match( event_t *class, event_t *instance )
|
||||
Create an identical copy of an event. Use deep copying, i.e. make
|
||||
duplicates of any strings used as well.
|
||||
*/
|
||||
static event_t *event_copy( event_t *event )
|
||||
static event_t *event_copy( event_t *event, int copy_arguments )
|
||||
{
|
||||
event_t *e = malloc( sizeof( event_t ) );
|
||||
if( !e )
|
||||
@@ -133,12 +139,55 @@ static event_t *event_copy( event_t *event )
|
||||
if( e->type == EVENT_VARIABLE )
|
||||
e->param1.variable = wcsdup( e->param1.variable );
|
||||
|
||||
al_init( &e->arguments );
|
||||
if( copy_arguments )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i<al_get_count( &event->arguments ); i++ )
|
||||
{
|
||||
al_push( &e->arguments, wcsdup( (wchar_t *)al_get( &event->arguments, i ) ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
static int event_is_blocked( event_t *e )
|
||||
{
|
||||
block_t *block;
|
||||
event_block_t *eb;
|
||||
|
||||
for( block = current_block; block; block = block->outer )
|
||||
{
|
||||
for( eb = block->first_event_block; eb; eb=eb->next )
|
||||
{
|
||||
if( eb->type & (1<<EVENT_ANY ) )
|
||||
return 1;
|
||||
if( eb->type & (1<<e->type) )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for( eb = global_event_block; eb; eb=eb->next )
|
||||
{
|
||||
if( eb->type & (1<<EVENT_ANY ) )
|
||||
return 1;
|
||||
if( eb->type & (1<<e->type) )
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void event_add_handler( event_t *event )
|
||||
{
|
||||
event_t *e = event_copy( event );
|
||||
event_t *e;
|
||||
|
||||
e = event_copy( event, 0 );
|
||||
|
||||
if( !events )
|
||||
events = al_new();
|
||||
@@ -268,11 +317,14 @@ static int event_is_killed( event_t *e )
|
||||
matches' path. This means that nothing is allocated/initialized
|
||||
unless that is needed.
|
||||
*/
|
||||
static void event_fire_internal( event_t *event, array_list_t *arguments )
|
||||
static void event_fire_internal( event_t *event )
|
||||
{
|
||||
int i, j;
|
||||
string_buffer_t *b=0;
|
||||
array_list_t *fire=0;
|
||||
|
||||
int was_subshell = is_subshell;
|
||||
int was_interactive = is_interactive;
|
||||
|
||||
/*
|
||||
First we free all events that have been removed
|
||||
@@ -334,9 +386,9 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
|
||||
|
||||
sb_append( b, criterion->function_name );
|
||||
|
||||
for( j=0; j<al_get_count(arguments); j++ )
|
||||
for( j=0; j<al_get_count(&event->arguments); j++ )
|
||||
{
|
||||
wchar_t *arg_esc = escape( (wchar_t *)al_get( arguments, j), 0 );
|
||||
wchar_t *arg_esc = escape( (wchar_t *)al_get( &event->arguments, j), 0 );
|
||||
sb_append( b, L" " );
|
||||
sb_append( b, arg_esc );
|
||||
free( arg_esc );
|
||||
@@ -344,15 +396,22 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
|
||||
|
||||
// debug( 1, L"Event handler fires command '%ls'", (wchar_t *)b->buff );
|
||||
|
||||
/*
|
||||
Event handlers are not part of the main flow of code, so
|
||||
they are marked as non-interactive and as a subshell
|
||||
*/
|
||||
is_subshell=1;
|
||||
is_interactive=1;
|
||||
|
||||
is_interactive=0;
|
||||
eval( (wchar_t *)b->buff, 0, TOP );
|
||||
is_subshell=0;
|
||||
is_interactive=1;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Restore interactivity flags
|
||||
*/
|
||||
is_subshell = was_subshell;
|
||||
is_interactive = was_interactive;
|
||||
|
||||
if( b )
|
||||
{
|
||||
sb_destroy( b );
|
||||
@@ -375,15 +434,40 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
|
||||
/**
|
||||
Handle all pending signal events
|
||||
*/
|
||||
static void event_fire_signal_events()
|
||||
static void event_fire_delayed()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
if( blocked && is_event==1)
|
||||
{
|
||||
array_list_t *new_blocked = 0;
|
||||
|
||||
for( i=0; i<al_get_count( blocked ); i++ )
|
||||
{
|
||||
event_t *e = (event_t *)al_get( blocked, i );
|
||||
if( event_is_blocked( e ) )
|
||||
{
|
||||
if( !new_blocked )
|
||||
new_blocked = al_new();
|
||||
al_push( new_blocked, e );
|
||||
}
|
||||
else
|
||||
{
|
||||
event_fire_internal( e );
|
||||
event_free( e );
|
||||
}
|
||||
}
|
||||
al_destroy( blocked );
|
||||
free( blocked );
|
||||
blocked = new_blocked;
|
||||
}
|
||||
|
||||
while( sig_list[active_list].count > 0 )
|
||||
{
|
||||
int i;
|
||||
signal_list_t *lst;
|
||||
event_t e;
|
||||
array_list_t a;
|
||||
al_init( &a );
|
||||
al_init( &e.arguments );
|
||||
|
||||
/*
|
||||
Switch signal lists
|
||||
@@ -411,19 +495,27 @@ static void event_fire_signal_events()
|
||||
for( i=0; i<lst->count; i++ )
|
||||
{
|
||||
e.param1.signal = lst->signal[i];
|
||||
al_set( &a, 0, sig2wcs( e.param1.signal ) );
|
||||
event_fire_internal( &e, &a );
|
||||
al_set( &e.arguments, 0, sig2wcs( e.param1.signal ) );
|
||||
if( event_is_blocked( &e ) )
|
||||
{
|
||||
if( !blocked )
|
||||
blocked = al_new();
|
||||
al_push( blocked, event_copy(&e, 1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
event_fire_internal( &e );
|
||||
}
|
||||
}
|
||||
|
||||
al_destroy( &a );
|
||||
al_destroy( &e.arguments );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void event_fire( event_t *event, array_list_t *arguments )
|
||||
void event_fire( event_t *event )
|
||||
{
|
||||
//int is_event_old = is_event;
|
||||
is_event++;
|
||||
|
||||
if( event && (event->type == EVENT_SIGNAL) )
|
||||
@@ -442,13 +534,26 @@ void event_fire( event_t *event, array_list_t *arguments )
|
||||
}
|
||||
else
|
||||
{
|
||||
event_fire_signal_events();
|
||||
|
||||
event_fire_delayed();
|
||||
|
||||
if( event )
|
||||
event_fire_internal( event, arguments );
|
||||
{
|
||||
if( event_is_blocked( event ) )
|
||||
{
|
||||
if( !blocked )
|
||||
blocked = al_new();
|
||||
|
||||
al_push( blocked, event_copy(event, 1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
event_fire_internal( event );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is_event--;// = is_event_old;
|
||||
is_event--;
|
||||
}
|
||||
|
||||
|
||||
@@ -477,9 +582,14 @@ void event_destroy()
|
||||
|
||||
void event_free( event_t *e )
|
||||
{
|
||||
/*
|
||||
When apropriate, we clear the argument vector
|
||||
*/
|
||||
al_foreach( &e->arguments, (void (*)(const void *))&free );
|
||||
al_destroy( &e->arguments );
|
||||
|
||||
free( (void *)e->function_name );
|
||||
if( e->type == EVENT_VARIABLE )
|
||||
free( (void *)e->param1.variable );
|
||||
free( e );
|
||||
}
|
||||
|
||||
|
||||
27
event.h
27
event.h
@@ -17,6 +17,9 @@
|
||||
*/
|
||||
#define EVENT_ANY_PID 0
|
||||
|
||||
/**
|
||||
Enumeration of event types
|
||||
*/
|
||||
enum
|
||||
{
|
||||
EVENT_ANY, /**< Matches any event type (Not always any event, as the function name may limit the choice as well */
|
||||
@@ -40,18 +43,24 @@ typedef struct
|
||||
Type of event
|
||||
*/
|
||||
int type;
|
||||
|
||||
/**
|
||||
The type-specific parameter
|
||||
*/
|
||||
union
|
||||
{
|
||||
/**
|
||||
Signal number for signal-type events.Use EVENT_ANY_SIGNAL to match any signal
|
||||
Signal number for signal-type events.Use EVENT_ANY_SIGNAL
|
||||
to match any signal
|
||||
*/
|
||||
int signal;
|
||||
/**
|
||||
Variable name for variable-type events.
|
||||
Variable name for variable-type events.
|
||||
*/
|
||||
const wchar_t *variable;
|
||||
/**
|
||||
Process id for process-type events. Use EVENT_ANY_PID to match any pid.
|
||||
Process id for process-type events. Use EVENT_ANY_PID to
|
||||
match any pid.
|
||||
*/
|
||||
pid_t pid;
|
||||
/**
|
||||
@@ -61,7 +70,17 @@ typedef struct
|
||||
|
||||
} param1;
|
||||
|
||||
/**
|
||||
The name of the event handler function
|
||||
*/
|
||||
const wchar_t *function_name;
|
||||
|
||||
/**
|
||||
The argument list. Only used when sending a new event using
|
||||
event_fire. In all other situations, the value of this variable
|
||||
is ignored.
|
||||
*/
|
||||
array_list_t arguments;
|
||||
}
|
||||
event_t;
|
||||
|
||||
@@ -95,7 +114,7 @@ int event_get( event_t *criterion, array_list_t *out );
|
||||
\param event the specific event whose handlers should fire
|
||||
\param arguments the argument string to send to the event handler function
|
||||
*/
|
||||
void event_fire( event_t *event, array_list_t *arguments );
|
||||
void event_fire( event_t *event );
|
||||
|
||||
/**
|
||||
Initialize the event-handling library
|
||||
|
||||
2
exec.c
2
exec.c
@@ -1201,7 +1201,7 @@ int exec_subshell( const wchar_t *cmd,
|
||||
if( !cmd )
|
||||
{
|
||||
debug( 1,
|
||||
L"Sent null command to subshell. This is a fish bug. If it can be reproduced, please send a bug report to %ls",
|
||||
L"Sent null command to subshell. This is a fish bug. If it can be reproduced, please send a bug report to %s",
|
||||
PACKAGE_BUGREPORT );
|
||||
return 0;
|
||||
}
|
||||
|
||||
105
expand.c
105
expand.c
@@ -20,6 +20,8 @@ parameter expansion.
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef SunOS
|
||||
#include <procfs.h>
|
||||
#endif
|
||||
@@ -67,6 +69,9 @@ parameter expansion.
|
||||
*/
|
||||
#define COMPLETE_LAST_DESC COMPLETE_SEP_STR L"Last background job"
|
||||
|
||||
#define COMPLETE_VAR_DESC L"Variable name is zero characters long."
|
||||
#define COMPLETE_VAR2_DESC L"Variable name is zero characters long. Did you mean{$VARIABLE}? To learn about variable expansion in fish, type 'help expand-variable'."
|
||||
|
||||
/**
|
||||
String in process expansion denoting ourself
|
||||
*/
|
||||
@@ -92,8 +97,8 @@ parameter expansion.
|
||||
any tokens which need to be expanded or otherwise altered. Clean
|
||||
strings can be passed through expand_string and expand_one without
|
||||
changing them. About 90% of all strings are clean, so skipping
|
||||
expantion on them actually does save a small amount of time, since
|
||||
it avoids multiple memory allocations during the expantion process.
|
||||
expansion on them actually does save a small amount of time, since
|
||||
it avoids multiple memory allocations during the expansion process.
|
||||
*/
|
||||
static int is_clean( const wchar_t *in )
|
||||
{
|
||||
@@ -710,7 +715,7 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
||||
wchar_t * new_in;
|
||||
array_list_t l;
|
||||
int is_single = (c==VARIABLE_EXPAND_SINGLE);
|
||||
|
||||
|
||||
stop_pos = start_pos;
|
||||
|
||||
while( 1 )
|
||||
@@ -727,6 +732,27 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
||||
/* printf( "Stop for '%c'\n", in[stop_pos]);*/
|
||||
|
||||
var_len = stop_pos - start_pos;
|
||||
|
||||
if( var_len == 0 )
|
||||
{
|
||||
if( in[stop_pos] == BRACKET_BEGIN )
|
||||
{
|
||||
|
||||
error( SYNTAX_ERROR,
|
||||
-1, COMPLETE_VAR_DESC
|
||||
COMPLETE_VAR2_DESC );
|
||||
}
|
||||
else
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
COMPLETE_VAR_DESC);
|
||||
}
|
||||
|
||||
is_ok = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if( !(var_name = malloc( sizeof(wchar_t)*(var_len+1) )))
|
||||
{
|
||||
@@ -770,8 +796,9 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
||||
if( ( errno ) || ( end == &in[stop_pos] ) )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
L"Expected integer or \']\'",
|
||||
-1 );
|
||||
-1,
|
||||
L"Expected integer or \']\'" );
|
||||
|
||||
is_ok = 0;
|
||||
break;
|
||||
}
|
||||
@@ -791,7 +818,9 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
||||
int tmp = (int)al_get( &idx, j );
|
||||
if( tmp < 1 || tmp > al_get_count( &l ) )
|
||||
{
|
||||
error( SYNTAX_ERROR, L"Array index out of bounds", -1 );
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
L"Array index out of bounds" );
|
||||
is_ok=0;
|
||||
al_truncate( &idx, j );
|
||||
break;
|
||||
@@ -820,6 +849,7 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
||||
in[i]=0;
|
||||
|
||||
sb_append( &res, in );
|
||||
sb_append_char( &res, INTERNAL_SEPARATOR );
|
||||
|
||||
for( j=0; j<al_get_count( &l); j++ )
|
||||
{
|
||||
@@ -852,8 +882,7 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
||||
|
||||
if( !(new_in = malloc( sizeof(wchar_t)*new_len )))
|
||||
{
|
||||
error( OOM, L"Out of memory", -1 );
|
||||
is_ok = 0;
|
||||
die_mem();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -893,14 +922,14 @@ static int expand_variables( wchar_t *in, array_list_t *out )
|
||||
if( c == VARIABLE_EXPAND )
|
||||
{
|
||||
/*
|
||||
Regular expantion, i.e. expand this argument to nothing
|
||||
Regular expansion, i.e. expand this argument to nothing
|
||||
*/
|
||||
empty = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Expantion to single argument.
|
||||
Expansion to single argument.
|
||||
*/
|
||||
string_buffer_t res;
|
||||
sb_init( &res );
|
||||
@@ -1022,7 +1051,9 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out )
|
||||
|
||||
if( syntax_error )
|
||||
{
|
||||
error( SYNTAX_ERROR, L"Mismatched brackets", -1 );
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
L"Mismatched brackets" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1145,6 +1176,11 @@ int expand_locate_subshell( wchar_t *in,
|
||||
*begin = paran_begin;
|
||||
*end = paran_count?in+wcslen(in):paran_end;
|
||||
|
||||
/* assert( *begin >= in );
|
||||
assert( *begin < (in+wcslen(in) ) );
|
||||
assert( *end >= *begin );
|
||||
assert( *end < (in+wcslen(in) ) );
|
||||
*/
|
||||
return 1;
|
||||
|
||||
}
|
||||
@@ -1168,7 +1204,9 @@ static int expand_subshell( wchar_t *in, array_list_t *out )
|
||||
0 ) )
|
||||
{
|
||||
case -1:
|
||||
error( SYNTAX_ERROR, L"Mismatched parans", -1 );
|
||||
error( SYNTAX_ERROR,
|
||||
-1,
|
||||
L"Mismatched parans" );
|
||||
return 0;
|
||||
case 0:
|
||||
al_push( out, in );
|
||||
@@ -1247,7 +1285,7 @@ wchar_t *expand_unescape( const wchar_t * in, int escape_special )
|
||||
{
|
||||
wchar_t *res = unescape( in, escape_special );
|
||||
if( !res )
|
||||
error( SYNTAX_ERROR, L"Unexpected end of string", -1 );
|
||||
error( SYNTAX_ERROR, -1, L"Unexpected end of string" );
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1379,7 +1417,7 @@ static void remove_internal_separator( const void *s, int conv )
|
||||
|
||||
|
||||
/**
|
||||
The real expantion function. expand_one is just a wrapper around this one.
|
||||
The real expansion function. expand_one is just a wrapper around this one.
|
||||
*/
|
||||
int expand_string( wchar_t *str,
|
||||
array_list_t *end_out,
|
||||
@@ -1390,11 +1428,15 @@ int expand_string( wchar_t *str,
|
||||
|
||||
int i;
|
||||
int subshell_ok = 1;
|
||||
int res = EXPAND_OK;
|
||||
|
||||
// debug( 1, L"Expand %ls", str );
|
||||
|
||||
|
||||
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( str ) )
|
||||
{
|
||||
al_push( end_out, str );
|
||||
return 1;
|
||||
return EXPAND_OK;
|
||||
}
|
||||
|
||||
al_init( &list1 );
|
||||
@@ -1412,11 +1454,11 @@ int expand_string( wchar_t *str,
|
||||
|
||||
if( (pos == str) || ( *(pos-1) != L'\\' ) )
|
||||
{
|
||||
error( SUBSHELL_ERROR, L"Subshells not allowed", -1 );
|
||||
error( SUBSHELL_ERROR, -1, L"Subshells not allowed" );
|
||||
free( str );
|
||||
al_destroy( &list1 );
|
||||
al_destroy( &list2 );
|
||||
return 0;
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
@@ -1430,7 +1472,7 @@ int expand_string( wchar_t *str,
|
||||
if( !subshell_ok )
|
||||
{
|
||||
al_destroy( &list1 );
|
||||
return 0;
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1464,7 +1506,7 @@ int expand_string( wchar_t *str,
|
||||
{
|
||||
al_destroy( in );
|
||||
al_destroy( out );
|
||||
return 0;
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1481,7 +1523,7 @@ int expand_string( wchar_t *str,
|
||||
{
|
||||
al_destroy( in );
|
||||
al_destroy( out );
|
||||
return 0;
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
}
|
||||
al_truncate( in, 0 );
|
||||
@@ -1496,17 +1538,22 @@ int expand_string( wchar_t *str,
|
||||
{
|
||||
al_destroy( in );
|
||||
al_destroy( out );
|
||||
return 0;
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
if( *next == PROCESS_EXPAND )
|
||||
{
|
||||
/*
|
||||
If process expansion matches, we are not
|
||||
interested in other completions, so we
|
||||
short-circut and return
|
||||
*/
|
||||
expand_pid( next, flags, end_out );
|
||||
al_destroy( in );
|
||||
al_destroy( out );
|
||||
return 1;
|
||||
return EXPAND_OK;
|
||||
}
|
||||
else
|
||||
al_push( out, next );
|
||||
@@ -1517,7 +1564,7 @@ int expand_string( wchar_t *str,
|
||||
{
|
||||
al_destroy( in );
|
||||
al_destroy( out );
|
||||
return 0;
|
||||
return EXPAND_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1550,19 +1597,18 @@ int expand_string( wchar_t *str,
|
||||
case 0:
|
||||
if( !(flags & ACCEPT_INCOMPLETE) )
|
||||
{
|
||||
if( res == EXPAND_OK )
|
||||
res = EXPAND_WILDCARD_NO_MATCH;
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
res = EXPAND_WILDCARD_MATCH;
|
||||
sort_list( out );
|
||||
al_push_all( end_out, out );
|
||||
al_truncate( out, 0 );
|
||||
break;
|
||||
|
||||
default:
|
||||
fwprintf( stderr, L"error\n" );
|
||||
/*al_destroy( &list1 );*/
|
||||
/*al_destroy( &list2 );*/
|
||||
/*return 0;*/
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1577,7 +1623,8 @@ int expand_string( wchar_t *str,
|
||||
al_destroy( out );
|
||||
}
|
||||
|
||||
return 1;
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
60
expand.h
60
expand.h
@@ -1,12 +1,12 @@
|
||||
/**\file expand.h
|
||||
|
||||
Prototypes for string expantion functions. These functions perform
|
||||
several kinds of parameter expantion. There are a lot of issues
|
||||
Prototypes for string expansion functions. These functions perform
|
||||
several kinds of parameter expansion. There are a lot of issues
|
||||
with regards to memory allocation. Overall, these functions would
|
||||
benefit from using a more clever memory allocation scheme, perhaps
|
||||
an evil combination of talloc, string buffers and reference
|
||||
counting.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FISH_EXPAND_H
|
||||
@@ -20,17 +20,17 @@
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
Flag specifying that subshell expantion should be skipped
|
||||
Flag specifying that subshell expansion should be skipped
|
||||
*/
|
||||
#define EXPAND_SKIP_SUBSHELL 1
|
||||
|
||||
/**
|
||||
Flag specifying that variable expantion should be skipped
|
||||
Flag specifying that variable expansion should be skipped
|
||||
*/
|
||||
#define EXPAND_SKIP_VARIABLES 2
|
||||
|
||||
/**
|
||||
Flag specifying that wildcard expantion should be skipped
|
||||
Flag specifying that wildcard expansion should be skipped
|
||||
*/
|
||||
#define EXPAND_SKIP_WILDCARDS 4
|
||||
|
||||
@@ -64,23 +64,45 @@ enum
|
||||
/** Character represeting a home directory */
|
||||
HOME_DIRECTORY = EXPAND_RESERVED,
|
||||
|
||||
/** Character represeting process expantion */
|
||||
/** Character represeting process expansion */
|
||||
PROCESS_EXPAND,
|
||||
|
||||
/** Character representing variable expantion */
|
||||
/** Character representing variable expansion */
|
||||
VARIABLE_EXPAND,
|
||||
|
||||
/** Character rpresenting variable expantion into a single element*/
|
||||
/** Character rpresenting variable expansion into a single element*/
|
||||
VARIABLE_EXPAND_SINGLE,
|
||||
|
||||
/** Character representing the start of a bracket expantion */
|
||||
/** Character representing the start of a bracket expansion */
|
||||
BRACKET_BEGIN,
|
||||
|
||||
/** Character representing the end of a bracket expantion */
|
||||
/** Character representing the end of a bracket expansion */
|
||||
BRACKET_END,
|
||||
|
||||
/** Character representing separation between two bracket elements */
|
||||
BRACKET_SEP,
|
||||
/**
|
||||
Separate subtokens in a token with this character.
|
||||
*/
|
||||
INTERNAL_SEPARATOR,
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/**
|
||||
These are the possible return values for expand_string
|
||||
*/
|
||||
enum
|
||||
{
|
||||
/** Error */
|
||||
EXPAND_ERROR,
|
||||
/** Ok */
|
||||
EXPAND_OK,
|
||||
/** Ok, a wildcard in the string matched no files */
|
||||
EXPAND_WILDCARD_NO_MATCH,
|
||||
/* Ok, a wildcard in the string matched a file */
|
||||
EXPAND_WILDCARD_MATCH
|
||||
}
|
||||
;
|
||||
|
||||
@@ -90,18 +112,13 @@ enum
|
||||
/** String containing the character for separating two array elements */
|
||||
#define ARRAY_SEP_STR L"\x1e"
|
||||
|
||||
/**
|
||||
Separate subtokens in a token with this character.
|
||||
*/
|
||||
#define INTERNAL_SEPARATOR 0xfffffff0
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Perform various forms of expansion on in, such as tilde expansion
|
||||
(~USER becomes the users home directory), variable expansion
|
||||
($VAR_NAME becomes the value of the environment variable VAR_NAME),
|
||||
subshell expantion and wildcard expansion. The results are inserted
|
||||
subshell expansion and wildcard expansion. The results are inserted
|
||||
into the list out.
|
||||
|
||||
If the parameter does not need expansion, it is copied into the list
|
||||
@@ -109,8 +126,9 @@ enum
|
||||
newly allocated strings are inserted into the list out.
|
||||
|
||||
\param in The parameter to expand
|
||||
\param flag Specifies if any expantion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
\param out The list to which the result will be appended.
|
||||
\return One of EXPAND_OK, EXPAND_ERROR, EXPAND_WILDCARD_MATCH and EXPAND_WILDCARD_NO_MATCH
|
||||
*/
|
||||
int expand_string( wchar_t *in, array_list_t *out, int flag );
|
||||
|
||||
@@ -120,7 +138,7 @@ int expand_string( wchar_t *in, array_list_t *out, int flag );
|
||||
names.
|
||||
|
||||
\param in The parameter to expand
|
||||
\param flag Specifies if any expantion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
|
||||
\return The expanded parameter, or 0 on failiure
|
||||
*/
|
||||
wchar_t *expand_one( wchar_t *in, int flag );
|
||||
@@ -157,9 +175,9 @@ wchar_t *expand_escape_variable( const wchar_t *in );
|
||||
|
||||
|
||||
/**
|
||||
Perform tilde expantion and nothing else on the specified string.
|
||||
Perform tilde expansion and nothing else on the specified string.
|
||||
|
||||
If tilde expantion is needed, the original string is freed and a
|
||||
If tilde expansion is needed, the original string is freed and a
|
||||
new string, allocated using malloc, is returned.
|
||||
*/
|
||||
wchar_t *expand_tilde(wchar_t *in);
|
||||
|
||||
10
fish_tests.c
10
fish_tests.c
@@ -518,7 +518,7 @@ static void test_parser()
|
||||
}
|
||||
|
||||
/**
|
||||
Perform parameter expantion and test if the output equals the zero-terminated parameter list supplied.
|
||||
Perform parameter expansion and test if the output equals the zero-terminated parameter list supplied.
|
||||
|
||||
\param in the string to expand
|
||||
\param flags the flags to send to expand_string
|
||||
@@ -561,11 +561,11 @@ static int expand_test( const wchar_t *in, int flags, ... )
|
||||
}
|
||||
|
||||
/**
|
||||
Test globbing and other parameter expantion
|
||||
Test globbing and other parameter expansion
|
||||
*/
|
||||
static void test_expand()
|
||||
{
|
||||
say( L"Testing parameter expantion" );
|
||||
say( L"Testing parameter expansion" );
|
||||
|
||||
if( !expand_test( L"foo", 0, L"foo", 0 ))
|
||||
{
|
||||
@@ -574,12 +574,12 @@ static void test_expand()
|
||||
|
||||
if( !expand_test( L"a{b,c,d}e", 0, L"abe", L"ace", L"ade", 0 ) )
|
||||
{
|
||||
err( L"Bracket expantion is broken" );
|
||||
err( L"Bracket expansion is broken" );
|
||||
}
|
||||
|
||||
if( !expand_test( L"a*", EXPAND_SKIP_WILDCARDS, L"a*", 0 ) )
|
||||
{
|
||||
err( L"Cannot skip wildcard expantion" );
|
||||
err( L"Cannot skip wildcard expansion" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -127,8 +127,8 @@ static void history_load( wchar_t *name )
|
||||
|
||||
Use a hashtable to check for duplicates instead.
|
||||
*/
|
||||
if( !hash_get( &used,
|
||||
buff ) )
|
||||
if( wcslen(buff) && !hash_get( &used,
|
||||
buff ) )
|
||||
{
|
||||
history_count++;
|
||||
|
||||
@@ -465,10 +465,7 @@ const wchar_t *history_prev_match( const wchar_t *str )
|
||||
|
||||
if( history_current->prev == 0 )
|
||||
{
|
||||
if( history_test( str, history_current->data ) )
|
||||
return (wchar_t *)history_current->data;
|
||||
else
|
||||
return str;
|
||||
return str;
|
||||
}
|
||||
if( past_end )
|
||||
past_end = 0;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
|
||||
function __fish_use_subcommand
|
||||
set -l cmd -- (commandline -poc)
|
||||
set -l -- cmd (commandline -poc)
|
||||
set -e cmd[1]
|
||||
for i in $cmd
|
||||
switch $i
|
||||
@@ -69,7 +69,7 @@ complete -c darcs -s v -l verbose -d "give verbose output"
|
||||
# Here follows a huge list of subcommand-specific completions
|
||||
#
|
||||
|
||||
set record_opt -- -c darcs -n 'contains record (commandline -poc)'
|
||||
set -- record_opt -c darcs -n 'contains record (commandline -poc)'
|
||||
complete $record_opt -s m -l patch-name -d "Name of patch" -x
|
||||
complete $record_opt -s A -l author -d "Specify author id" -x
|
||||
complete $record_opt -l logfile -d "Give patch name and comment in file" -r
|
||||
@@ -95,7 +95,7 @@ complete $record_opt -l dont-look-for-adds -d "Don"\'"t look for any files or di
|
||||
set -e record_opt
|
||||
|
||||
|
||||
set pull_opt -- -c darcs -n 'contains pull (commandline -poc)'
|
||||
set -- pull_opt -c darcs -n 'contains pull (commandline -poc)'
|
||||
complete $pull_opt -s p -l patches -d "select patches matching REGEXP" -x
|
||||
complete $pull_opt -s t -l tags -d "select tags matching REGEXP" -x
|
||||
complete $pull_opt -s a -l all -d "answer yes to all patches"
|
||||
@@ -120,7 +120,7 @@ complete $pull_opt -l dont-set-scripts-executable -d "don"\'"t make scripts exec
|
||||
set -e pull_opt
|
||||
|
||||
|
||||
set apply_opt -- -c darcs -n 'contains apply (commandline -poc)'
|
||||
set -- apply_opt -c darcs -n 'contains apply (commandline -poc)'
|
||||
complete $apply_opt -s a -l all -d "answer yes to all patches"
|
||||
complete $apply_opt -l verify -d "verify that the patch was signed by a key in PUBRING" -r
|
||||
complete $apply_opt -l verify-ssl -d "verify using openSSL with authorized keys from file "\'"KEYS"\'"" -r
|
||||
@@ -147,7 +147,7 @@ complete $apply_opt -l set-scripts-executable -d "make scripts executable"
|
||||
complete $apply_opt -l dont-set-scripts-executable -d "don"\'"t make scripts executable"
|
||||
set -e apply_opt
|
||||
|
||||
set check_opt -- -c darcs -n 'contains check (commandline -poc)'
|
||||
set -- check_opt -c darcs -n 'contains check (commandline -poc)'
|
||||
complete $check_opt -s v -l verbose -d "give verbose output"
|
||||
complete $check_opt -s q -l quiet -d "suppress informational output"
|
||||
complete $check_opt -l complete -d "check the entire repository"
|
||||
@@ -159,13 +159,13 @@ complete $check_opt -l leave-test-directory -d "don"\'"t remove the test directo
|
||||
complete $check_opt -l remove-test-directory -d "remove the test directory"
|
||||
set -e check_opt
|
||||
|
||||
set mv_opt -- -c darcs -n 'contains mv (commandline -poc)'
|
||||
set -- mv_opt -c darcs -n 'contains mv (commandline -poc)'
|
||||
complete $mv_opt -s v -l verbose -d "give verbose output"
|
||||
complete $mv_opt -l case-ok -d "don"\'"t refuse to add files differing only in case"
|
||||
complete $mv_opt -l standard-verbosity -d "don"\'"t give verbose output"
|
||||
set -e mv_opt
|
||||
|
||||
set send_opt -- -c darcs -n 'contains send (commandline -poc)'
|
||||
set -- send_opt -c darcs -n 'contains send (commandline -poc)'
|
||||
complete $send_opt -s v -l verbose -d "give verbose output"
|
||||
complete $send_opt -s q -l quiet -d "suppress informational output"
|
||||
complete $send_opt -xs p -l patches -d "select patches matching REGEXP"
|
||||
@@ -194,7 +194,7 @@ complete $send_opt -l no-set-default -d "don"\'"t set default repository"
|
||||
complete $send_opt -rl sendmail-command -d "specify sendmail command"
|
||||
set -e send_opt
|
||||
|
||||
set init_opt -- -c darcs -n 'contains initialize (commandline -poc)'
|
||||
set -- init_opt -c darcs -n 'contains initialize (commandline -poc)'
|
||||
complete $init_opt -l plain-pristine-tree -d "Use a plain pristine tree [DEFAULT]"
|
||||
complete $init_opt -l no-pristine-tree -d "Use no pristine tree"
|
||||
set -e init_opt
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
complete -c fish -s c -l "command" -d "Run fish with this command"
|
||||
complete -c fish -s h -l help -d "Display help and exit"
|
||||
complete -c fish -l version -d "Display version and exit"
|
||||
complete -c fish -s v -l version -d "Display version and exit"
|
||||
complete -c fish -s i -l interactive -d "Run in interactive mode"
|
||||
complete -c fish -s p -l profile -d "Output profiling information to specified file" -f
|
||||
|
||||
@@ -22,8 +22,6 @@ complete -c help -x -a prompt -d "Help on how to set the prompt"
|
||||
complete -c help -x -a title -d "Help on how to set the titlebar message"
|
||||
complete -c help -x -a killring -d "Help on how to copy and paste"
|
||||
complete -c help -x -a editor -d "Help on editor shortcuts"
|
||||
complete -c help -x -a expand -d "Help on parameter expantion (Globbing)"
|
||||
complete -c help -x -a globbing -d "Help on parameter expantion (Globbing)"
|
||||
complete -c help -x -a variables -d "Help on environment variables"
|
||||
complete -c help -x -a color -d "Help on setting syntax highlighting colors"
|
||||
complete -c help -x -a prompt -d "Help on changing the prompt"
|
||||
@@ -31,3 +29,11 @@ complete -c help -x -a title -d "Help on changing the titlebar messages"
|
||||
complete -c help -x -a builtin-overview -d "A short summary of all builtin commands"
|
||||
complete -c help -x -a changes -d "The changelog"
|
||||
|
||||
complete -c help -x -a globbing -d "Help on parameter expansion (Globbing)"
|
||||
complete -c help -x -a expand -d "Help on parameter expansion (Globbing)"
|
||||
complete -c help -x -a expand-variable -d "Help on variable exapantion \$VARNAME"
|
||||
complete -c help -x -a expand-home -d "Help on home directory expansion ~USER"
|
||||
complete -c help -x -a expand-brace -d "Help on brace expansion {a,b,c}"
|
||||
complete -c help -x -a expand-wildcard -d "Help on wildcard expansion *.*"
|
||||
complete -c help -x -a expand-command-substitution -d "Help on command substututions (SUBCOMMAND)"
|
||||
complete -c help -x -a expand-process -d "Help on process expansion %JOB"
|
||||
|
||||
6
init/completions/jobs.fish
Normal file
6
init/completions/jobs.fish
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
complete -c jobs -s p -l pid -d 'Show the process id of each process in the job'
|
||||
complete -c jobs -s g -l group -d 'Show group id of job'
|
||||
complete -c jobs -s c -l command -d 'Show commandname of each job'
|
||||
complete -c jobs -s l -l last -d 'Show status for last be started'
|
||||
@@ -7,7 +7,7 @@ if kill -L ^/dev/null >/dev/null
|
||||
|
||||
complete -c kill -s L -d "List codes and names of available signals"
|
||||
|
||||
set -- signals (kill -L | sed -r 's/([0-9]+) +([A-Z,0-9]+)/\1 \2\n/g;s/ +/ /g' | sed 's/^ //' | grep -E '^[^ ]+')
|
||||
set -- signals (kill -L | sed -e 's/\([0-9][0-9]*\) *([A-Z,0-9][A-Z,0-9]*\)/\1 \2\n/g;s/ +/ /g' | sed -e 's/^ //' | grep -E '^[^ ]+')
|
||||
for i in $signals
|
||||
set -- number (echo $i | cut -d " " -f 1)
|
||||
set -- name (echo $i | cut -d " " -f 2)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
function __fish_print_make_targets
|
||||
set files Makefile makefile GNUmakefile
|
||||
grep -h -E '^[^#%=$[:space:]][^#%=$]*:([^=]|$)' $files | cut -d ":" -f 1 | sed -r 's/^ *//;s/ *$//;s/ +/\n/g' ^/dev/null
|
||||
grep -h -E '^[^#%=$[:space:]][^#%=$]*:([^=]|$)' $files | cut -d ":" -f 1 | sed -e 's/^ *//;s/ *$//;s/ */\n/g' ^/dev/null
|
||||
end
|
||||
|
||||
complete -x -c make -a "(__fish_print_make_targets)" -d "Target"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Completions for the modprobe command
|
||||
#
|
||||
|
||||
complete -c modprobe -d Module -a "(/sbin/modprobe -l | sed -re 's/\/.*\/([^\/.]*).*/\1/')"
|
||||
complete -c modprobe -d Module -a "(/sbin/modprobe -l | sed -e 's/\/.*\/\([^\/.]*\).*/\1/')"
|
||||
complete -c modprobe -s v -l verbose -d "Print messages about what the program is doing"
|
||||
complete -c modprobe -s C -l config -d "Configuration file" -r
|
||||
complete -c modprobe -s c -l showconfig -d "Dump configuration file"
|
||||
|
||||
@@ -17,7 +17,7 @@ complete -c scp -d Hostname -a "
|
||||
|
||||
(
|
||||
#Prepend any username specified in the completion to the hostname
|
||||
echo (commandline -ct)|grep -o '.*@'
|
||||
echo (commandline -ct)|sed -ne 's/\(.*@\).*/\1/p'
|
||||
)(
|
||||
cat ~/.ssh/known_hosts{,2} ^/dev/null|cut -d ' ' -f 1| cut -d , -f 1
|
||||
):
|
||||
|
||||
@@ -71,7 +71,7 @@ complete -x -c ssh -d Hostname -a "
|
||||
|
||||
(
|
||||
#Prepend any username specified in the completion to the hostname
|
||||
echo (commandline -ct)|grep -o '.*@'
|
||||
echo (commandline -ct)|sed -ne 's/\(.*@\).*/\1/p'
|
||||
)(__fish_print_hostnames)
|
||||
|
||||
(__fish_print_users)@
|
||||
|
||||
4
init/completions/trap.fish
Normal file
4
init/completions/trap.fish
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
complete -c trap -s l -l list-signals -d 'Display names of all signals'
|
||||
complete -c trap -s p -l print -d 'Display all currently defined trap handlers'
|
||||
complete -c trap -s h -l help -d 'Display help and exit'
|
||||
@@ -10,7 +10,7 @@ complete -y mount
|
||||
#
|
||||
# Find all mountpoints
|
||||
#
|
||||
complete -c umount -d "Mount point" -x -a '(cat /etc/mtab | cut -d " " -f 1-2|tr " " \n|sed -re "s/[0-9\.]*:\//\//"|grep "^/")'
|
||||
complete -c umount -d "Mount point" -x -a '(cat /etc/mtab | cut -d " " -f 1-2|tr " " \n|sed -e "s/[0-9\.]*:\//\//"|grep "^/")'
|
||||
|
||||
complete -c umount -s V -d "Display version and exit"
|
||||
complete -c umount -s h -d "Display help and exit"
|
||||
|
||||
@@ -75,4 +75,4 @@ complete -c yum -n 'contains clean (commandline -poc)' -x -a "
|
||||
packages\t'Delete cached package files'
|
||||
headers\t'Delete cached header files'
|
||||
all\t'Delete all cache contents'
|
||||
"
|
||||
"
|
||||
|
||||
11
init/fish.in
11
init/fish.in
@@ -15,7 +15,14 @@ set -g IFS \ \t\n
|
||||
# want this even for text-only terminals.
|
||||
#
|
||||
|
||||
for i in /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin
|
||||
set -l path_list /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin
|
||||
|
||||
set -l uid (id -u 2>/dev/null)
|
||||
if test "$uid" = 0
|
||||
set path_list $path_list /sbin /usr/sbin /usr/local/sbin
|
||||
end
|
||||
|
||||
for i in $path_list
|
||||
if not expr "$PATH" : .\*$i.\* >/dev/null
|
||||
if test -d $i
|
||||
set PATH $PATH $i
|
||||
@@ -24,6 +31,8 @@ for i in /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Set some value for LANG if nothing was set before
|
||||
#
|
||||
|
||||
@@ -10,7 +10,7 @@ if not status --is-interactive
|
||||
exit
|
||||
end
|
||||
|
||||
set -g fish_complete_path /etc/fish.d/completions ~/.fish.d/completions
|
||||
set -g fish_complete_path @SYSCONFDIR@/fish.d/completions ~/.fish.d/completions
|
||||
|
||||
# Knowing the location of the whatis database speeds up command
|
||||
# description lookup.
|
||||
@@ -115,7 +115,7 @@ function help -d "Show help for the fish shell"
|
||||
|
||||
# If we are in a graphical environment, we check if there is a
|
||||
# graphical browser to use instead.
|
||||
if test (echo $DISPLAY)
|
||||
if test (echo $DISPLAY) -a \( "$XAUTHORITY" = "$HOME/.Xauthority" -o "$XAUTHORITY" = "" \)
|
||||
for i in $graphical_browsers
|
||||
if which $i 2>/dev/null >/dev/null
|
||||
set fish_browser $i
|
||||
@@ -132,18 +132,20 @@ function help -d "Show help for the fish shell"
|
||||
return 1
|
||||
end
|
||||
|
||||
set fish_help_item $argv[1]
|
||||
if count $argv >/dev/null
|
||||
set fish_help_item $argv[1]
|
||||
end
|
||||
set fish_help_page ""
|
||||
|
||||
if test $fish_help_item = .
|
||||
if test "$fish_help_item" = .
|
||||
set fish_help_page "builtins.html\#source"
|
||||
end
|
||||
|
||||
if test $fish_help_item = difference
|
||||
if test "$fish_help_item" = difference
|
||||
set fish_help_page difference.html
|
||||
end
|
||||
|
||||
if test $fish_help_item = globbing
|
||||
if test "$fish_help_item" = globbing
|
||||
set fish_help_page "index.html\#expand"
|
||||
end
|
||||
|
||||
@@ -156,8 +158,9 @@ function help -d "Show help for the fish shell"
|
||||
end
|
||||
|
||||
set idx_subj syntax completion editor job-control todo bugs history
|
||||
set idx_subj $idx_subj killring help color prompt title expand variables
|
||||
set idx_subj $idx_subj builtin-overview changes
|
||||
set idx_subj $idx_subj killring help color prompt title variables
|
||||
set idx_subj $idx_subj builtin-overview changes
|
||||
set idx_subj $idx_subj expand expand-variable expand-home expand-brace expand-wildcard expand-command-substitution expand-process
|
||||
|
||||
if contains -- $fish_help_item $idx_subj
|
||||
set fish_help_page "index.html\#"$fish_help_item
|
||||
@@ -213,20 +216,11 @@ end
|
||||
# ellipsised. This function is used by the default prompt command.
|
||||
#
|
||||
|
||||
function prompt_pwd -d "Print the current working directory, ellipsise it if it is longer than 1/4 of the terminal width"
|
||||
set wd (pwd)
|
||||
set len (echo $wd|wc -c)
|
||||
set max_width (echo $COLUMNS/4|bc)
|
||||
if test $len -gt $max_width
|
||||
#Write ellipsis character if known to be using UTF
|
||||
#else use $
|
||||
set -l ellipsis '$' #default
|
||||
if expr match "$LANG" ".*UTF" >/dev/null
|
||||
set ellipsis \u2026
|
||||
end
|
||||
printf %s%s $ellipsis (echo $wd|cut -c (echo $len-$max_width-1|bc)- ^/dev/null )
|
||||
else
|
||||
echo $wd
|
||||
function prompt_pwd -d "Print the current working directory, shortend to fit the prompt"
|
||||
set -l wd (pwd)
|
||||
printf "%s" $wd|sed -e 's-/\([^/]\)\([^/]*\)-/\1-g'
|
||||
if test $wd != '~'
|
||||
printf "%s\n" $wd|sed -e 's-.*/[^/]\([^/]*$\)-\1-'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -235,13 +229,7 @@ end
|
||||
#
|
||||
|
||||
function pwd -d "Print working directory"
|
||||
set out (command pwd $argv)
|
||||
if echo $out| grep \^$HOME >/dev/null
|
||||
printf \~
|
||||
echo $out |cut -b (echo $HOME|wc -c)- ^/dev/null
|
||||
else
|
||||
printf "%s\n" $out
|
||||
end
|
||||
command pwd | sed -e "s|^$HOME|~|"
|
||||
end
|
||||
|
||||
#
|
||||
@@ -263,7 +251,7 @@ function vared -d "Edit variable value"
|
||||
if test (count $$argv ) -lt 2
|
||||
set init ''
|
||||
if test $$argv
|
||||
set init -- $$argv
|
||||
set -- init $$argv
|
||||
end
|
||||
set prompt 'set_color green; echo '$argv'; set_color normal; echo "> "'
|
||||
read -p $prompt -c $init tmp
|
||||
@@ -373,7 +361,7 @@ function cd -d "Change directory"
|
||||
end
|
||||
|
||||
# Avoid set completions
|
||||
set -- previous (command pwd)
|
||||
set previous (command pwd)
|
||||
|
||||
if test $argv[1] = - ^/dev/null
|
||||
if test $__fish_cd_direction = next ^/dev/null
|
||||
@@ -557,11 +545,149 @@ function __bold -d "Print argument in bold"
|
||||
set_color normal
|
||||
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 shortopt -o lph
|
||||
if getopt -T >/dev/null
|
||||
set longopt
|
||||
else
|
||||
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 __fish_type_help -d "Help for the type shellscript function"
|
||||
|
||||
set bullet \*
|
||||
if expr match "$LANG" ".*UTF" >/dev/null
|
||||
set bullet \u2022
|
||||
set bullet \u2022
|
||||
end
|
||||
|
||||
echo \ttype - Indicate how a name would be interpreted if used as a \n\tcommand name
|
||||
@@ -606,7 +732,7 @@ function type -d "Print the type of a command"
|
||||
return 1
|
||||
end
|
||||
|
||||
set tmp -- (getopt $shortopt $longopt -- $argv)
|
||||
set -- tmp (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
eval set opt -- $tmp
|
||||
|
||||
@@ -650,7 +776,7 @@ function type -d "Print the type of a command"
|
||||
|
||||
if test $selection != files
|
||||
|
||||
if contains -- $i (functions -n)
|
||||
if contains -- $i (functions -na)
|
||||
set status 0
|
||||
set found 1
|
||||
switch $mode
|
||||
@@ -855,7 +981,7 @@ function umask -d "Set default file permission mask"
|
||||
if getopt -T >/dev/null
|
||||
set longopt
|
||||
else
|
||||
set longopt -- -l as-command,symbolic,help
|
||||
set -- longopt -l as-command,symbolic,help
|
||||
end
|
||||
|
||||
if not getopt -n umask -Q $shortopt $longopt -- $argv
|
||||
@@ -864,7 +990,7 @@ function umask -d "Set default file permission mask"
|
||||
|
||||
set tmp -- (getopt $shortopt $longopt -- $argv)
|
||||
|
||||
eval set opt -- $tmp
|
||||
eval set -- opt $tmp
|
||||
|
||||
while count $opt >/dev/null
|
||||
|
||||
@@ -1002,3 +1128,4 @@ function delete-or-exit --key-binding
|
||||
exit
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ $if fish
|
||||
"\M-d": if test -z (commandline); dirh; else; commandline -f kill-word; end
|
||||
"\C-d": delete-or-exit
|
||||
# This will make sure the output of the current command is paged using the less pager when you press Meta-p
|
||||
"\M-p": if commandline -j|grep -v "less *$" >/dev/null; commandline -aj "|less;"; end
|
||||
"\M-p": if commandline -j|grep -v 'less *$' >/dev/null; commandline -aj "|less;"; end
|
||||
$endif
|
||||
|
||||
# Include user-specific inputrc file after including fish-specific
|
||||
|
||||
@@ -10,17 +10,14 @@ end
|
||||
# Print a greeting
|
||||
#
|
||||
|
||||
printf 'Welcome to fish, the friendly interactive shell\nType '
|
||||
set_color green
|
||||
printf 'help '
|
||||
set_color normal
|
||||
printf 'for instructions on how to use fish\n'
|
||||
printf 'Welcome to fish, the friendly interactive shell\n'
|
||||
printf 'Type %shelp%s for instructions on how to use fish\n' (set_color green) (set_color normal)
|
||||
|
||||
#
|
||||
# Set exit message
|
||||
#
|
||||
|
||||
function fish_on_exit -d "Commands to execute when fish exits"
|
||||
function fish_on_exit -d "Commands to execute when fish exits" --on-process %self
|
||||
echo Good bye
|
||||
end
|
||||
|
||||
@@ -29,7 +26,7 @@ end
|
||||
# long it is.
|
||||
|
||||
function fish_prompt -d "Write out the prompt"
|
||||
printf '%s@%s \n%s\n%s\n%s\n> ' (whoami) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
|
||||
printf '%s@%s %s%s%s> \n' (whoami) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
|
||||
end
|
||||
|
||||
#
|
||||
@@ -39,9 +36,11 @@ end
|
||||
# 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.
|
||||
# Give priority to the default file installed with fish in
|
||||
# @SYSCONFDIR@/fish_inputrc.
|
||||
#
|
||||
|
||||
for i in ~/.fish_inputrc ~/etc/fish_inputrc /etc/fish_inputrc ~/.inputrc /etc/inputrc
|
||||
for i in ~/.fish_inputrc @SYSCONFDIR@/fish_inputrc ~/etc/fish_inputrc /etc/fish_inputrc ~/.inputrc /etc/inputrc
|
||||
if test -f $i
|
||||
set -xg INPUTRC $i
|
||||
break
|
||||
4
input.c
4
input.c
@@ -698,7 +698,7 @@ static wchar_t *input_expand_sequence( const wchar_t *in )
|
||||
}
|
||||
debug( 1, L"Invalid sequence - Control-nothing?\n" );
|
||||
error = 1;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1270,7 +1270,7 @@ static int interrupt_handler()
|
||||
/*
|
||||
Fire any pending events
|
||||
*/
|
||||
event_fire( 0, 0 );
|
||||
event_fire( 0 );
|
||||
if( job_reap( 1 ) )
|
||||
repaint();
|
||||
if( reader_interupted() )
|
||||
|
||||
8
io.c
8
io.c
@@ -42,12 +42,12 @@ void io_buffer_read( io_data_t *d )
|
||||
|
||||
if( d->io_mode == IO_BUFFER )
|
||||
{
|
||||
if( fcntl( d->param1.pipe_fd[0], F_SETFL, 0 ) )
|
||||
/* if( fcntl( d->param1.pipe_fd[0], F_SETFL, 0 ) )
|
||||
{
|
||||
wperror( L"fcntl" );
|
||||
return;
|
||||
}
|
||||
debug( 4, L"exec_read_io_buffer: blocking read on fd %d", d->param1.pipe_fd[0] );
|
||||
} */
|
||||
debug( 4, L"io_buffer_read: blocking read on fd %d", d->param1.pipe_fd[0] );
|
||||
while(1)
|
||||
{
|
||||
char b[4096];
|
||||
@@ -71,7 +71,7 @@ void io_buffer_read( io_data_t *d )
|
||||
debug( 1,
|
||||
L"An error occured while reading output from code block on fd %d",
|
||||
d->param1.pipe_fd[0] );
|
||||
wperror( L"exec_read_io_buffer" );
|
||||
wperror( L"io_buffer_read" );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
6
main.c
6
main.c
@@ -284,11 +284,7 @@ int main( int argc, char **argv )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( function_exists(L"fish_on_exit"))
|
||||
{
|
||||
eval( L"fish_on_exit", 0, TOP );
|
||||
}
|
||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
||||
|
||||
reader_pop_current_filename();
|
||||
|
||||
|
||||
2
output.c
2
output.c
@@ -128,7 +128,7 @@ void set_color( int c, int c2 )
|
||||
{
|
||||
c = c2 = FISH_COLOR_NORMAL;
|
||||
if( fg )
|
||||
writembs( tparm( set_a_foreground, 0 ) );
|
||||
writembs( tparm( fg, 0 ) );
|
||||
writembs( exit_attribute_mode );
|
||||
return;
|
||||
}
|
||||
|
||||
61
parser.h
61
parser.h
@@ -11,6 +11,27 @@
|
||||
#include "util.h"
|
||||
#include "parser.h"
|
||||
|
||||
typedef struct event_block
|
||||
{
|
||||
/**
|
||||
The types of events to block. This is interpreted as a bitset
|
||||
whete the value is 1 for every bit corresponding to a blocked
|
||||
event type. For example, if EVENT_VARIABLE type events should
|
||||
be blocked, (type & 1<<EVENT_BLOCKED) should be set.
|
||||
|
||||
Note that EVENT_ANY can be used to specify any event.
|
||||
*/
|
||||
int type;
|
||||
|
||||
/**
|
||||
The next event_block struct
|
||||
*/
|
||||
struct event_block *next;
|
||||
}
|
||||
event_block_t;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
block_t represents a block of commands.
|
||||
*/
|
||||
@@ -21,12 +42,12 @@ typedef struct block
|
||||
int tok_pos; /**< The start index of the block */
|
||||
|
||||
/**
|
||||
Status for the current loop block. Can be anu of the values from the loop_status enum.
|
||||
Status for the current loop block. Can be any of the values from the loop_status enum.
|
||||
*/
|
||||
int loop_status;
|
||||
|
||||
/**
|
||||
The log that is currently evaluated in the specified block.
|
||||
The job that is currently evaluated in the specified block.
|
||||
*/
|
||||
job_t *job;
|
||||
|
||||
@@ -68,8 +89,11 @@ typedef struct block
|
||||
array_list_t *function_events;
|
||||
} param4;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Some naming confusion. This is a pointer to the first element in the list of all event blocks.
|
||||
*/
|
||||
event_block_t *first_event_block;
|
||||
|
||||
/**
|
||||
Next outer block
|
||||
*/
|
||||
@@ -125,18 +149,32 @@ enum while_status
|
||||
*/
|
||||
enum parser_error
|
||||
{
|
||||
/**
|
||||
No error
|
||||
*/
|
||||
NO_ERR=0,
|
||||
/**
|
||||
An error in the syntax
|
||||
*/
|
||||
SYNTAX_ERROR,
|
||||
/**
|
||||
Error occured while evaluating commands
|
||||
*/
|
||||
EVAL_ERROR,
|
||||
OOM,
|
||||
STACK_ERROR,
|
||||
SUBSHELL_ERROR
|
||||
/**
|
||||
Error while evaluating subshell
|
||||
*/
|
||||
SUBSHELL_ERROR,
|
||||
}
|
||||
;
|
||||
|
||||
/** The current innermost block */
|
||||
extern block_t *current_block;
|
||||
|
||||
/** Global event blocks */
|
||||
extern event_block_t *global_event_block;
|
||||
|
||||
|
||||
/** The current error code */
|
||||
extern int error_code;
|
||||
|
||||
@@ -178,10 +216,11 @@ int eval_args( const wchar_t *line,
|
||||
Sets the current error
|
||||
|
||||
\param ec The new error code
|
||||
\param str The new error message
|
||||
\param p The character offset at which the error occured
|
||||
\param str The printf-style error message filter
|
||||
*/
|
||||
void error( int ec, const wchar_t *str, int p );
|
||||
void error( int ec, int p, const wchar_t *str, ... );
|
||||
|
||||
|
||||
/**
|
||||
Tests if the specified commands parameters should be interpreted as another command, which will be true if the command is either 'command', 'exec', 'if', 'while' or 'builtin'.
|
||||
@@ -274,12 +313,12 @@ void parser_forbid_function( wchar_t *function );
|
||||
void parser_allow_function();
|
||||
|
||||
/**
|
||||
Initialize the parser
|
||||
Initialize static parser data
|
||||
*/
|
||||
void parser_init();
|
||||
|
||||
/**
|
||||
Destroy the parser
|
||||
Destroy static parser data
|
||||
*/
|
||||
void parser_destroy();
|
||||
|
||||
|
||||
36
proc.c
36
proc.c
@@ -76,9 +76,10 @@ int proc_had_barrier;
|
||||
pid_t proc_last_bg_pid = 0;
|
||||
|
||||
/**
|
||||
List used to store arguments when firing events
|
||||
The event variable used to send all process event
|
||||
*/
|
||||
static array_list_t event_arg;
|
||||
static event_t event;
|
||||
|
||||
/**
|
||||
Stringbuffer used to create arguments when firing events
|
||||
*/
|
||||
@@ -91,7 +92,7 @@ static string_buffer_t event_status;
|
||||
|
||||
void proc_init()
|
||||
{
|
||||
al_init( &event_arg );
|
||||
al_init( &event.arguments );
|
||||
sb_init( &event_pid );
|
||||
sb_init( &event_status );
|
||||
}
|
||||
@@ -185,7 +186,7 @@ void job_free( job_t * j )
|
||||
|
||||
void proc_destroy()
|
||||
{
|
||||
al_destroy( &event_arg );
|
||||
al_destroy( &event.arguments );
|
||||
sb_destroy( &event_pid );
|
||||
sb_destroy( &event_status );
|
||||
while( first_job )
|
||||
@@ -482,26 +483,23 @@ static void format_job_info( const job_t *j, const wchar_t *status )
|
||||
fwprintf (stdout, L"\n" );
|
||||
}
|
||||
|
||||
static void fire_process_event( const wchar_t *msg, int type, pid_t pid, int status )
|
||||
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status )
|
||||
{
|
||||
static event_t ev;
|
||||
event_t e;
|
||||
|
||||
e.function_name=0;
|
||||
event.type=type;
|
||||
event.param1.pid = pid;
|
||||
|
||||
ev.type=type;
|
||||
ev.param1.pid = pid;
|
||||
|
||||
al_push( &event_arg, msg );
|
||||
al_push( &event.arguments, msg );
|
||||
|
||||
sb_printf( &event_pid, L"%d", pid );
|
||||
al_push( &event_arg, event_pid.buff );
|
||||
al_push( &event.arguments, event_pid.buff );
|
||||
|
||||
sb_printf( &event_status, L"%d", status );
|
||||
al_push( &event_arg, event_status.buff );
|
||||
al_push( &event.arguments, event_status.buff );
|
||||
|
||||
event_fire( &ev, &event_arg );
|
||||
al_truncate( &event_arg, 0 );
|
||||
event_fire( &event );
|
||||
|
||||
al_truncate( &event.arguments, 0 );
|
||||
sb_clear( &event_pid );
|
||||
sb_clear( &event_status );
|
||||
}
|
||||
@@ -538,7 +536,7 @@ int job_reap( int interactive )
|
||||
|
||||
s = p->status;
|
||||
|
||||
fire_process_event( L"PROCESS_EXIT", EVENT_EXIT, p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) );
|
||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) );
|
||||
|
||||
if( WIFSIGNALED(s) )
|
||||
{
|
||||
@@ -596,8 +594,8 @@ int job_reap( int interactive )
|
||||
found=1;
|
||||
}
|
||||
}
|
||||
fire_process_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
|
||||
fire_process_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
|
||||
proc_fire_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
|
||||
proc_fire_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
|
||||
|
||||
job_free(j);
|
||||
}
|
||||
|
||||
66
proc.h
66
proc.h
@@ -20,15 +20,30 @@
|
||||
|
||||
|
||||
/**
|
||||
Types of internal processes
|
||||
Types of processes
|
||||
*/
|
||||
enum
|
||||
{
|
||||
/**
|
||||
A regular external command
|
||||
*/
|
||||
EXTERNAL,
|
||||
/**
|
||||
A builtin command
|
||||
*/
|
||||
INTERNAL_BUILTIN,
|
||||
/**
|
||||
A shellscript function
|
||||
*/
|
||||
INTERNAL_FUNCTION,
|
||||
/**
|
||||
A block of commands
|
||||
*/
|
||||
INTERNAL_BLOCK,
|
||||
INTERNAL_EXEC
|
||||
/**
|
||||
The exec builtin
|
||||
*/
|
||||
INTERNAL_EXEC,
|
||||
}
|
||||
;
|
||||
|
||||
@@ -134,24 +149,47 @@ typedef struct job
|
||||
/** Should the exit status be negated? This flag can only be set by the not builtin. */
|
||||
int negate;
|
||||
|
||||
/** This flag is set to one on wildcard expansion errors. It means that the current command should not be executed */
|
||||
int wildcard_error;
|
||||
|
||||
/** Pointer to the next job */
|
||||
struct job *next;
|
||||
}
|
||||
job_t;
|
||||
|
||||
/** Whether we are running a subshell command */
|
||||
/**
|
||||
Whether we are running a subshell command
|
||||
*/
|
||||
extern int is_subshell;
|
||||
/** Whether we are running a block of commands */
|
||||
|
||||
/**
|
||||
Whether we are running a block of commands
|
||||
*/
|
||||
extern int is_block;
|
||||
/** Whether we are reading from the keyboard right now*/
|
||||
|
||||
/**
|
||||
Whether we are reading from the keyboard right now
|
||||
*/
|
||||
extern int is_interactive;
|
||||
/** Whether this shell is attached to the keyboard at all*/
|
||||
|
||||
/**
|
||||
Whether this shell is attached to the keyboard at all
|
||||
*/
|
||||
extern int is_interactive_session;
|
||||
/** Whether we are a login shell*/
|
||||
|
||||
/**
|
||||
Whether we are a login shell
|
||||
*/
|
||||
extern int is_login;
|
||||
/** Whether we are a event handler*/
|
||||
|
||||
/**
|
||||
Whether we are a event handler
|
||||
*/
|
||||
extern int is_event;
|
||||
/** Linked list of all jobs */
|
||||
|
||||
/**
|
||||
Linked list of all jobs
|
||||
*/
|
||||
extern job_t *first_job;
|
||||
|
||||
/**
|
||||
@@ -172,6 +210,7 @@ extern pid_t proc_last_bg_pid;
|
||||
Sets the status of the last process to exit
|
||||
*/
|
||||
void proc_set_last_status( int s );
|
||||
|
||||
/**
|
||||
Returns the status of the last process to exit
|
||||
*/
|
||||
@@ -181,6 +220,7 @@ int proc_get_last_status();
|
||||
Remove the specified job
|
||||
*/
|
||||
void job_free( job_t* j );
|
||||
|
||||
/**
|
||||
Create a new job
|
||||
*/
|
||||
@@ -216,6 +256,7 @@ int job_is_completed( const job_t *j );
|
||||
\param cont Whether the function should wait for the job to complete before returning
|
||||
*/
|
||||
void job_continue( job_t *j, int cont );
|
||||
|
||||
/**
|
||||
Notify user of nog events. Notify the user about stopped or
|
||||
terminated jobs. Delete terminated jobs from the active job list.
|
||||
@@ -223,10 +264,10 @@ void job_continue( job_t *j, int cont );
|
||||
\param interactive whether interactive jobs should be reaped as well
|
||||
*/
|
||||
int job_reap( int interactive );
|
||||
|
||||
/**
|
||||
Signal handler for SIGCHLD. Mark any processes with relevant
|
||||
information.
|
||||
|
||||
*/
|
||||
void job_handle_signal( int signal, siginfo_t *info, void *con );
|
||||
|
||||
@@ -254,6 +295,11 @@ void proc_update_jiffies();
|
||||
*/
|
||||
void proc_sanity_check();
|
||||
|
||||
/**
|
||||
Send of an process/job exit event notification. This function is a conveniance wrapper around event_fire().
|
||||
*/
|
||||
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status );
|
||||
|
||||
/*
|
||||
Initializations
|
||||
*/
|
||||
|
||||
243
reader.c
243
reader.c
@@ -52,6 +52,8 @@ commence.
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "wutil.h"
|
||||
#include "highlight.h"
|
||||
@@ -620,6 +622,129 @@ void reader_write_title()
|
||||
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
|
||||
}
|
||||
|
||||
/**
|
||||
Tests if the specified narrow character sequence is present at the
|
||||
specified position of the specified wide character string. All of
|
||||
\c seq must match, but str may be longer than seq.
|
||||
*/
|
||||
static int try_sequence( char *seq, wchar_t *str )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0;; i++ )
|
||||
{
|
||||
if( !seq[i] )
|
||||
return i;
|
||||
|
||||
if( seq[i] != str[i] )
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Calculate the width of the specified prompt. Does some clever magic
|
||||
to detect common escape sequences that may be embeded in a prompt,
|
||||
such as color codes.
|
||||
*/
|
||||
static int calc_prompt_width( array_list_t *arr )
|
||||
{
|
||||
int res = 0;
|
||||
int i, j, k;
|
||||
|
||||
for( i=0; i<al_get_count( arr ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( arr, i );
|
||||
|
||||
for( j=0; next[j]; j++ )
|
||||
{
|
||||
if( next[j] == L'\e' )
|
||||
{
|
||||
/*
|
||||
This is the start of an escape code. Try to guess it's width.
|
||||
*/
|
||||
int l;
|
||||
int len=0;
|
||||
int found = 0;
|
||||
|
||||
/*
|
||||
Test these color escapes with parameter value 0..7
|
||||
*/
|
||||
char * esc[] =
|
||||
{
|
||||
set_a_foreground,
|
||||
set_a_background,
|
||||
set_foreground,
|
||||
set_background,
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
Test these regular escapes without any parameter values
|
||||
*/
|
||||
char *esc2[] =
|
||||
{
|
||||
enter_bold_mode,
|
||||
exit_attribute_mode,
|
||||
enter_underline_mode,
|
||||
exit_underline_mode,
|
||||
enter_standout_mode,
|
||||
exit_standout_mode,
|
||||
flash_screen
|
||||
}
|
||||
;
|
||||
|
||||
for( l=0; l < (sizeof(esc)/sizeof(char *)) && !found; l++ )
|
||||
{
|
||||
if( !esc[l] )
|
||||
continue;
|
||||
|
||||
for( k=0; k<8; k++ )
|
||||
{
|
||||
len = try_sequence( tparm(esc[l],k), &next[j] );
|
||||
if( len )
|
||||
{
|
||||
j += (len-1);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( l=0; l < (sizeof(esc2)/sizeof(char *)) && !found; l++ )
|
||||
{
|
||||
if( !esc2[l] )
|
||||
continue;
|
||||
/*
|
||||
Test both padded and unpadded version, just to
|
||||
be safe. Most versions of tparm don't actually
|
||||
seem to do anything these days.
|
||||
*/
|
||||
len = maxi( try_sequence( tparm(esc2[l]), &next[j] ),
|
||||
try_sequence( esc2[l], &next[j] ));
|
||||
|
||||
if( len )
|
||||
{
|
||||
j += (len-1);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Ordinary decent character. Just add width.
|
||||
*/
|
||||
res += wcwidth( next[j] );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Write the prompt to screen. If data->exec_prompt is set, the prompt
|
||||
command is first evaluated, and the title will be reexecuted as
|
||||
@@ -649,14 +774,8 @@ static void write_prompt()
|
||||
al_init( &prompt_list );
|
||||
}
|
||||
}
|
||||
data->prompt_width=0;
|
||||
for( i=0; i<al_get_count( &prompt_list ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( &prompt_list, i );
|
||||
if( *next == L'\e' )
|
||||
continue;
|
||||
data->prompt_width += my_wcswidth( next );
|
||||
}
|
||||
|
||||
data->prompt_width=calc_prompt_width( &prompt_list );
|
||||
|
||||
data->exec_prompt = 0;
|
||||
reader_write_title();
|
||||
@@ -1093,7 +1212,7 @@ static wchar_t get_quote( wchar_t *cmd, int l )
|
||||
\param pos An index in the string which is inside the parameter
|
||||
\param quote If not 0, store the type of quote this parameter has, can be either ', " or \\0, meaning the string is not quoted.
|
||||
\param offset If not 0, get_param will store a pointer to the beginning of the parameter.
|
||||
\param string If not o, get_parm will store a copy of the parameter string as returned by the tokenizer.
|
||||
\param string If not 0, get_parm will store a copy of the parameter string as returned by the tokenizer.
|
||||
\param type If not 0, get_param will store the token type as returned by tok_last.
|
||||
*/
|
||||
static void get_param( wchar_t *cmd,
|
||||
@@ -1123,6 +1242,7 @@ static void get_param( wchar_t *cmd,
|
||||
*type = tok_last_type( &tok );
|
||||
if( string != 0 )
|
||||
wcscpy( *string, tok_last( &tok ) );
|
||||
|
||||
prev_pos = tok_get_pos( &tok );
|
||||
}
|
||||
|
||||
@@ -1381,13 +1501,12 @@ static int handle_completions( array_list_t *comp )
|
||||
0,
|
||||
0 );
|
||||
|
||||
|
||||
len = &data->buff[data->buff_pos]-prefix_start;
|
||||
len = &data->buff[data->buff_pos]-prefix_start+1;
|
||||
|
||||
if( len <= PREFIX_MAX_LEN )
|
||||
{
|
||||
prefix = malloc( sizeof(wchar_t)*(len+1) );
|
||||
wcsncpy( prefix, prefix_start, len );
|
||||
wcslcpy( prefix, prefix_start, len );
|
||||
prefix[len]=L'\0';
|
||||
}
|
||||
else
|
||||
@@ -1400,7 +1519,9 @@ static int handle_completions( array_list_t *comp )
|
||||
;
|
||||
|
||||
prefix = wcsdupcat( tmp,
|
||||
prefix_start + (len - PREFIX_MAX_LEN+1) );
|
||||
prefix_start + (len - PREFIX_MAX_LEN) );
|
||||
prefix[PREFIX_MAX_LEN] = 0;
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1710,8 +1831,6 @@ void reader_current_token_extent( wchar_t **tok_begin,
|
||||
|
||||
reader_current_subshell_extent( &begin, &end );
|
||||
|
||||
// fwprintf( stderr, L"Lalala: %d %d %d\n", begin-data->buff, end-data->buff, pos );
|
||||
|
||||
if( !end || !begin )
|
||||
return;
|
||||
|
||||
@@ -1722,6 +1841,11 @@ void reader_current_token_extent( wchar_t **tok_begin,
|
||||
pa = data->buff + pos;
|
||||
pb = pa;
|
||||
|
||||
assert( begin >= data->buff );
|
||||
assert( begin <= (data->buff+wcslen(data->buff) ) );
|
||||
assert( end >= begin );
|
||||
assert( end <= (data->buff+wcslen(data->buff) ) );
|
||||
|
||||
buffcpy = wcsndup( begin, end-begin );
|
||||
|
||||
if( !buffcpy )
|
||||
@@ -1736,15 +1860,27 @@ void reader_current_token_extent( wchar_t **tok_begin,
|
||||
int tok_begin = tok_get_pos( &tok );
|
||||
int tok_end=tok_begin;
|
||||
|
||||
/*
|
||||
Calculate end of token
|
||||
*/
|
||||
if( tok_last_type( &tok ) == TOK_STRING )
|
||||
tok_end +=wcslen(tok_last(&tok));
|
||||
|
||||
|
||||
/*
|
||||
Cursor was before beginning of this token, means that the
|
||||
cursor is between two tokens, so we set it to a zero element
|
||||
string and break
|
||||
*/
|
||||
if( tok_begin > pos )
|
||||
{
|
||||
a = b = data->buff + pos;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
If cursor is inside the token, this is the token we are
|
||||
looking for. If so, set a and b and break
|
||||
*/
|
||||
if( tok_end >= pos )
|
||||
{
|
||||
a = begin + tok_get_pos( &tok );
|
||||
@@ -1754,11 +1890,17 @@ void reader_current_token_extent( wchar_t **tok_begin,
|
||||
|
||||
break;
|
||||
}
|
||||
pa = begin + tok_get_pos( &tok );
|
||||
pb = pa + wcslen(tok_last(&tok));
|
||||
|
||||
/*
|
||||
Remember previous string token
|
||||
*/
|
||||
if( tok_last_type( &tok ) == TOK_STRING )
|
||||
{
|
||||
pa = begin + tok_get_pos( &tok );
|
||||
pb = pa + wcslen(tok_last(&tok));
|
||||
}
|
||||
}
|
||||
|
||||
// fwprintf( stderr, L"Res: %d %d\n", *a-data->buff, *b-data->buff );
|
||||
free( buffcpy);
|
||||
|
||||
tok_destroy( &tok );
|
||||
@@ -1772,7 +1914,10 @@ void reader_current_token_extent( wchar_t **tok_begin,
|
||||
if( prev_end )
|
||||
*prev_end = pb;
|
||||
|
||||
// fwprintf( stderr, L"w00t\n" );
|
||||
assert( pa >= data->buff );
|
||||
assert( pa <= (data->buff+wcslen(data->buff) ) );
|
||||
assert( pb >= pa );
|
||||
assert( pb <= (data->buff+wcslen(data->buff) ) );
|
||||
|
||||
}
|
||||
|
||||
@@ -1874,7 +2019,7 @@ static void handle_token_history( int forward, int reset )
|
||||
int current_pos;
|
||||
tokenizer tok;
|
||||
|
||||
if(reset )
|
||||
if( reset )
|
||||
{
|
||||
/*
|
||||
Start a new token search using the current token
|
||||
@@ -1883,6 +2028,7 @@ static void handle_token_history( int forward, int reset )
|
||||
|
||||
}
|
||||
|
||||
|
||||
current_pos = data->token_history_pos;
|
||||
|
||||
if( forward || data->search_pos < (al_get_count( &data->search_prev )-1) )
|
||||
@@ -1924,6 +2070,7 @@ static void handle_token_history( int forward, int reset )
|
||||
history already contains the search string itself, if so
|
||||
return, otherwise add it.
|
||||
*/
|
||||
|
||||
const wchar_t *last = al_get( &data->search_prev, al_get_count( &data->search_prev ) -1 );
|
||||
if( wcscmp( last, data->search_buff ) )
|
||||
{
|
||||
@@ -1936,6 +2083,9 @@ static void handle_token_history( int forward, int reset )
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
debug( 3, L"new '%ls'", data->token_history_buff );
|
||||
|
||||
for( tok_init( &tok, data->token_history_buff, TOK_ACCEPT_UNFINISHED );
|
||||
tok_has_next( &tok);
|
||||
tok_next( &tok ))
|
||||
@@ -1946,11 +2096,12 @@ static void handle_token_history( int forward, int reset )
|
||||
{
|
||||
if( wcsstr( tok_last( &tok ), data->search_buff ) )
|
||||
{
|
||||
// fwprintf( stderr, L"Found token at pos %d\n", tok_get_pos( &tok ) );
|
||||
debug( 3, L"Found token at pos %d\n", tok_get_pos( &tok ) );
|
||||
if( tok_get_pos( &tok ) >= current_pos )
|
||||
{
|
||||
break;
|
||||
}
|
||||
debug( 3, L"ok pos" );
|
||||
|
||||
if( !contains( tok_last( &tok ), &data->search_prev ) )
|
||||
{
|
||||
@@ -2347,21 +2498,13 @@ static int read_i()
|
||||
that we can handle a call to reader_set_buffer
|
||||
during evaluation.
|
||||
*/
|
||||
|
||||
|
||||
tmp = wcsdup( reader_readline() );
|
||||
|
||||
|
||||
data->buff_pos=data->buff_len=0;
|
||||
data->buff[data->buff_len]=L'\0';
|
||||
if( function_exists(L"fish_on_exec"))
|
||||
{
|
||||
eval( L"fish_on_exec", 0, TOP );
|
||||
}
|
||||
reader_run_command( tmp );
|
||||
free( tmp );
|
||||
if( function_exists(L"fish_on_return"))
|
||||
{
|
||||
eval( L"fish_on_return", 0, TOP );
|
||||
}
|
||||
|
||||
if( data->end_loop)
|
||||
{
|
||||
@@ -2405,7 +2548,6 @@ static int can_read( int fd )
|
||||
static int wchar_private( wchar_t c )
|
||||
{
|
||||
return ( (c >= 0xe000) && (c <= 0xf8ff ) );
|
||||
|
||||
}
|
||||
|
||||
wchar_t *reader_readline()
|
||||
@@ -2506,9 +2648,7 @@ wchar_t *reader_readline()
|
||||
if( last_char != R_YANK && last_char != R_YANK_POP )
|
||||
yank=0;
|
||||
|
||||
|
||||
|
||||
switch (c)
|
||||
switch( c )
|
||||
{
|
||||
|
||||
/* go to beginning of line*/
|
||||
@@ -2593,10 +2733,13 @@ wchar_t *reader_readline()
|
||||
|
||||
case R_BACKWARD_KILL_LINE:
|
||||
{
|
||||
wchar_t prev = data->buff[data->buff_pos];
|
||||
data->buff[data->buff_pos]=0;
|
||||
kill_add( data->buff );
|
||||
data->buff[data->buff_pos]=prev;
|
||||
wchar_t *str = wcsndup( data->buff, data->buff_pos );
|
||||
if( !str )
|
||||
die_mem();
|
||||
|
||||
kill_add( str );
|
||||
free( str );
|
||||
|
||||
data->buff_len = wcslen(data->buff +data->buff_pos);
|
||||
memmove( data->buff, data->buff +data->buff_pos, sizeof(wchar_t)*data->buff_len );
|
||||
data->buff[data->buff_len]=L'\0';
|
||||
@@ -2761,8 +2904,8 @@ wchar_t *reader_readline()
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Move left*/
|
||||
case R_BACKWARD_CHAR:
|
||||
if( data->buff_pos > 0 )
|
||||
@@ -2916,7 +3059,21 @@ static int read_ni( int fd )
|
||||
while(!feof( in_stream ))
|
||||
{
|
||||
char buff[4096];
|
||||
int c = fread(buff, 1, 4096, in_stream);
|
||||
int c;
|
||||
|
||||
c = fread(buff, 1, 4096, in_stream);
|
||||
if( ferror( in_stream ) )
|
||||
{
|
||||
debug( 1,
|
||||
L"Error while reading commands" );
|
||||
|
||||
/*
|
||||
Reset buffer. We won't evaluate incomplete files.
|
||||
*/
|
||||
acc.used=0;
|
||||
break;
|
||||
}
|
||||
|
||||
b_append( &acc, buff, c );
|
||||
}
|
||||
b_append( &acc, "\0", 1 );
|
||||
|
||||
2
signal.c
2
signal.c
@@ -305,7 +305,7 @@ static void default_handler(int signal, siginfo_t *info, void *context)
|
||||
e.param1.signal = signal;
|
||||
e.function_name=0;
|
||||
|
||||
event_fire( &e, 0 );
|
||||
event_fire( &e );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
26
tokenizer.c
26
tokenizer.c
@@ -119,12 +119,9 @@ void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
|
||||
memset( tok, 0, sizeof( tokenizer) );
|
||||
|
||||
tok ->last = 0;
|
||||
tok ->last_len = 0;
|
||||
tok->accept_unfinished = flags & TOK_ACCEPT_UNFINISHED;
|
||||
tok->show_comments = flags & TOK_SHOW_COMMENTS;
|
||||
tok->has_next=1;
|
||||
|
||||
tok->has_next=1;
|
||||
|
||||
/*
|
||||
Before we copy the buffer we need to check that it is not
|
||||
@@ -138,13 +135,7 @@ void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
}
|
||||
|
||||
tok->has_next = (*b != L'\0');
|
||||
tok->orig_buff = tok->buff = /*wcsdup*/(b);
|
||||
|
||||
if( !tok->orig_buff )
|
||||
{
|
||||
die_mem();
|
||||
|
||||
}
|
||||
tok->orig_buff = tok->buff = (wchar_t *)(b);
|
||||
|
||||
if( tok->accept_unfinished )
|
||||
{
|
||||
@@ -152,7 +143,15 @@ void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
if( l != 0 )
|
||||
{
|
||||
if( tok->orig_buff[l-1] == L'\\' )
|
||||
{
|
||||
tok->free_orig = 1;
|
||||
tok->orig_buff = tok->buff = wcsdup( tok->orig_buff );
|
||||
if( !tok->orig_buff )
|
||||
{
|
||||
die_mem();
|
||||
}
|
||||
tok->orig_buff[l-1] = L'\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +162,8 @@ void tok_init( tokenizer *tok, const wchar_t *b, int flags )
|
||||
void tok_destroy( tokenizer *tok )
|
||||
{
|
||||
free( tok->last );
|
||||
// free( tok->orig_buff );
|
||||
if( tok->free_orig )
|
||||
free( tok->orig_buff );
|
||||
}
|
||||
|
||||
int tok_last_type( tokenizer *tok )
|
||||
@@ -619,7 +619,7 @@ wchar_t *tok_first( const wchar_t *str )
|
||||
|
||||
int tok_get_pos( tokenizer *tok )
|
||||
{
|
||||
return tok->last_pos;
|
||||
return tok->last_pos + (tok->free_orig?1:0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ typedef struct
|
||||
int accept_unfinished;
|
||||
/** Whether commants should be returned*/
|
||||
int show_comments;
|
||||
/** Flag set to true of the orig_buff points to an internal string that needs to be free()d when deallocating the tokenizer. */
|
||||
int free_orig;
|
||||
/** Type of last quote, can be either ' or ".*/
|
||||
wchar_t last_quote;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
|
||||
<a class="qindex" href="index.html">Main documentation page</a>
|
||||
|
|
||||
<a class="qindex" href="design.html">Design document</a>
|
||||
|
|
||||
<a class="qindex" href="about.html">About fish</a>
|
||||
|
|
||||
<a class="qindex" href="commands.html">External commands</a>
|
||||
|
||||
18
wgetopt.c
18
wgetopt.c
@@ -7,12 +7,18 @@
|
||||
internal commands use wide characters and hence this library is
|
||||
useful.
|
||||
|
||||
If you want to use this version of getopt in your program, simply
|
||||
copy wgetopt.c and wgetopt.h into your program, include wgetopt.h,
|
||||
and use all the regular getopt functions, prefixing every
|
||||
function, global variable and structure with a 'w', and use only
|
||||
wide character strings. There are no other functional changes in
|
||||
this version of getopt besides using wide character strings.
|
||||
If you want to use this version of getopt in your program,
|
||||
download the fish sourcecode, available at <a
|
||||
href='http://roo.no-ip.org/fish/'>the fish homepage</a>. Extract
|
||||
the sourcode, copy wgetopt.c and wgetopt.h into your program
|
||||
directory, include wgetopt.h in your program, and use all the
|
||||
regular getopt functions, prefixing every function, global
|
||||
variable and structure with a 'w', and use only wide character
|
||||
strings. There are no other functional changes in this version of
|
||||
getopt besides using wide character strings.
|
||||
|
||||
For examples of how to use wgetopt, see the fish builtin
|
||||
functions, many of which are defined in builtin.c.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
18
wgetopt.h
18
wgetopt.h
@@ -7,12 +7,18 @@
|
||||
internal commands use wide characters and hence this library is
|
||||
useful.
|
||||
|
||||
If you want to use this version of getopt in your program, simply
|
||||
copy wgetopt.c and wgetopt.h into your program, include wgetopt.h,
|
||||
and use all the regular getopt functions, prefixing every
|
||||
function, global variable and structure with a 'w', and use only
|
||||
wide character strings. There are no other functional changes in
|
||||
this version of getopt besides using wide character strings.
|
||||
If you want to use this version of getopt in your program,
|
||||
download the fish sourcecode, available at <a
|
||||
href='http://roo.no-ip.org/fish/'>the fish homepage</a>. Extract
|
||||
the sourcode, copy wgetopt.c and wgetopt.h into your program
|
||||
directory, include wgetopt.h in your program, and use all the
|
||||
regular getopt functions, prefixing every function, global
|
||||
variable and structure with a 'w', and use only wide character
|
||||
strings. There are no other functional changes in this version of
|
||||
getopt besides using wide character strings.
|
||||
|
||||
For examples of how to use wgetopt, see the fish builtin
|
||||
functions, many of which are defined in builtin.c.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
15
wildcard.c
15
wildcard.c
@@ -70,7 +70,7 @@ int wildcard_has( const wchar_t *str, int internal )
|
||||
|
||||
\param str String to be matched.
|
||||
\param wc The wildcard.
|
||||
\param is_first Whether files beginning with dots should not be matched against wildcards.
|
||||
\param is_first Whether files beginning with dots should not be matched against wildcards.
|
||||
\param wc_unescaped Whether the unescaped special character ANY_CHAR abd ANY_STRING should be used instead of '?' and '*' for wildcard matching
|
||||
*/
|
||||
|
||||
@@ -307,7 +307,7 @@ void get_desc( wchar_t *fn, string_buffer_t *sb, int is_cmd )
|
||||
|
||||
/*
|
||||
Test if the file specified by the given filename matches the
|
||||
expantion flags specified. flags can be a combination of
|
||||
expansion flags specified. flags can be a combination of
|
||||
EXECUTABLES_ONLY and DIRECTORIES_ONLY.
|
||||
*/
|
||||
static int test_flags( wchar_t *filename,
|
||||
@@ -317,8 +317,11 @@ static int test_flags( wchar_t *filename,
|
||||
return 1;
|
||||
|
||||
struct stat buf;
|
||||
wstat( filename, &buf );
|
||||
|
||||
if( wstat( filename, &buf ) == -1 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( S_IFDIR & buf.st_mode )
|
||||
return 1;
|
||||
|
||||
@@ -358,7 +361,7 @@ int wildcard_expand( const wchar_t *wc,
|
||||
/* Description for completions */
|
||||
string_buffer_t sb_desc;
|
||||
|
||||
// debug( 3, L"WILDCARD_EXPAND %ls in %ls", wc, base_dir );
|
||||
// debug( 3, L"WILDCARD_EXPAND %ls in %ls", wc, base_dir );
|
||||
|
||||
if( flags & ACCEPT_INCOMPLETE )
|
||||
{
|
||||
@@ -671,7 +674,7 @@ void al_push_check( array_list_t *l, const wchar_t *new )
|
||||
{
|
||||
if( !wcscmp( al_get(l, i), new ) )
|
||||
{
|
||||
free( new );
|
||||
free( (void *)new );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
|
||||
/** \file wildcard.h
|
||||
|
||||
My own globbing implementation. Needed to implement this instead
|
||||
of using libs globbing to support tab-expantion of globbed
|
||||
of using libs globbing to support tab-expansion of globbed
|
||||
paramaters.
|
||||
|
||||
*/
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
static const unsigned char _xdg_utf8_skip_data[256] = {
|
||||
static const char _xdg_utf8_skip_data[256] = {
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
|
||||
@@ -156,11 +156,11 @@ _xdg_mime_magic_match_free (XdgMimeMagicMatch *mime_magic_match)
|
||||
/* Reads in a hunk of data until a newline character or a '\000' is hit. The
|
||||
* returned string is null terminated, and doesn't include the newline.
|
||||
*/
|
||||
static unsigned char *
|
||||
static char *
|
||||
_xdg_mime_magic_read_to_newline (FILE *magic_file,
|
||||
int *end_of_file)
|
||||
{
|
||||
unsigned char *retval;
|
||||
char *retval;
|
||||
int c;
|
||||
int len, pos;
|
||||
|
||||
@@ -179,7 +179,7 @@ _xdg_mime_magic_read_to_newline (FILE *magic_file,
|
||||
}
|
||||
if (c == '\n' || c == '\000')
|
||||
break;
|
||||
retval[pos++] = (unsigned char) c;
|
||||
retval[pos++] = (char) c;
|
||||
if (pos % 128 == 127)
|
||||
{
|
||||
len = len + 128;
|
||||
|
||||
Reference in New Issue
Block a user