Compare commits

..

72 Commits

Author SHA1 Message Date
axel
1eb089d722 Bump version number
darcs-hash:20090308144106-ac50b-e64db4a3009f99b3c1d206bba1781775faef671c.gz
2009-03-09 00:41:06 +10:00
axel
e50d0c18b0 Update todo list
darcs-hash:20090308142007-ac50b-22e9cc31212ff9647f75426327cdf5aff2d30f79.gz
2009-03-09 00:20:07 +10:00
axel
810d5f9548 Fix interactive job in background busy wait bug, reported by Randall D. Wald
darcs-hash:20090301021441-ac50b-a9488a9e55f545c3b8bd52aa0fb00b2b967974a8.gz
2009-03-01 12:14:41 +10:00
James Vega
e0c317dfd4 Prevent potential infinite loop
Ignore-this: 24edfe9248e1b667fcf4d8e151dd50f2

darcs-hash:20090224183601-35ec8-5e86d44c77af33376bd80485689d60c761ff17c6.gz
2009-02-25 04:36:01 +10:00
axel
d5320fb9f9 Update copyright info, minor layout changes to section about licenses in fish
darcs-hash:20090222224540-ac50b-69c4f8dd027e4672b8d25f8240c1d5f625135ad1.gz
2009-02-23 08:45:40 +10:00
axel
14c84ffbcb Check return value of a few write calls and retry on EINTR, and fix a few other warnings, mostly by printing error messages before giving up.
darcs-hash:20090222202852-ac50b-b0e79142af5b7a99e55271d4001fa252d9684a1d.gz
2009-02-23 06:28:52 +10:00
axel
f71c6f3f0e Misc documentation updates
darcs-hash:20090222191714-ac50b-fdd090aafd60f71989ef5c63aac9f876dcad93eb.gz
2009-02-23 05:17:14 +10:00
axel
6dbb9e070d Hopefully make iconv detection work on OS X with non-gnu iconv implementation
darcs-hash:20090222191649-ac50b-4f7010fdbf662b71cb7c4c99d2ae6e00c7cccb83.gz
2009-02-23 05:16:49 +10:00
axel
47ae2a05ce Don't make complete builtin complain when used in non-interactive mode, as we can always launch a debug prompt. Who are we to question why?
darcs-hash:20090222162253-ac50b-bb3c9dc1d1fa33548a2ed7b3c7c4d21d527eba47.gz
2009-02-23 02:22:53 +10:00
axel
810262118a Fix read in noninteractive mode problems reported by James Reeves
darcs-hash:20090222162206-ac50b-c293945986f75103120606a64133b59fe82c02a6.gz
2009-02-23 02:22:06 +10:00
axel
f5be301a2f Handle exit status of processes terminated by signals
darcs-hash:20090221164656-ac50b-7bcbf6cb0bb8384560fbf9bf1059480cb4089def.gz
2009-02-22 02:46:56 +10:00
axel
b1357d11b2 Pressing Control-C (or otherwise changeing the command line content through the commandline builtin) should clear the search buffer.
darcs-hash:20090221154420-ac50b-52641fb6dd6e76aebc6244211e07c0861fb3eff0.gz
2009-02-22 01:44:20 +10:00
axel
5fc42fcaff prompt_pwd broken, this fix by James Reeves
darcs-hash:20090221104759-ac50b-35f7a896d3e62cd002605d47c090c7bec992317b.gz
2009-02-21 20:47:59 +10:00
axel
c1cf6a4071 Oops, I broke recursive wildcard completion
darcs-hash:20090221104330-ac50b-ab9d487d3fc77fab32d9c49045d23b3e9124e618.gz
2009-02-21 20:43:30 +10:00
axel
972f3e121e Document rename of save_function to func_save. Pointed out by Ovchinnikov George
darcs-hash:20090218202037-ac50b-0351e8564d3274cd4fb364c07b4a3260f8a45f20.gz
2009-02-19 06:20:37 +10:00
axel
0dd8ae4843 Added faw entry on history editing, written by Beni Cherniavsky
darcs-hash:20090216211940-ac50b-4175fb2ae8ec2f5a67ac3c6a33a48bc5ac35eea2.gz
2009-02-17 07:19:40 +10:00
axel
8a93b6f26d Make xdg-version of open handle multiple files.
darcs-hash:20090216211103-ac50b-f8268e8d50a84457bb49ac3d1e982cba09dbfec6.gz
2009-02-17 07:11:03 +10:00
axel
07717a3570 Add possibility to define greeting function, suggested by Chris Miller
darcs-hash:20090216210450-ac50b-9b4f7c5bf45afaf21d51e46ff8c2b11d171fcbf2.gz
2009-02-17 07:04:50 +10:00
Nick Pilon
79784d3e18 This patch fixes a problem where prompt_pwd was printing the full path twice under OS X and probably BSDs. (Which, needless to say, made for very long prompts) The problem was that (Free?)BSD sed and GNU sed handle ? differently. For BSD sed, ? is not special unless the -E flag is specified. The {0,1} syntax should work the same way in both.
darcs-hash:20080122180340-5b666-21f1cdb835cbfa458a0f3d7344370837db962388.gz
2008-01-23 04:03:40 +10:00
terceiro
c08c313c0a adds completion for Debian's invoke-rc.d command
Ignore-this: f9ff385e3c239cedfbc9850b06822bba

darcs-hash:20090204191757-69c1e-a55c2a720fd784c7be2534feacecd5e2ebdbeecd.gz
2009-02-05 05:17:57 +10:00
terceiro
dfd70057b3 function to put current git branch on the fish prompt
Ignore-this: 841402742571f399e012514315b8e4f0

darcs-hash:20090204190358-69c1e-2ebcf761a4e55bc049ff1d5bba272d722b2d4501.gz
2009-02-05 05:03:58 +10:00
terceiro
07dec5c3ed better git completion
Ignore-this: af7fede5c1ee1d92c89d2887cbe54c0b

darcs-hash:20090204185826-69c1e-f72e06ad575efee258b392afd17255166ac4a260.gz
2009-02-05 04:58:26 +10:00
axel
1ed5decf2c Fix warnings in FATAL_EXIT macro
darcs-hash:20090204224310-ac50b-111db6c8f5b74dad0a309441063d3d7e9bf8f55d.gz
2009-02-05 08:43:10 +10:00
Isaac Dupree
9b95dda6bf fix help for open
darcs-hash:20080605192305-6c1c4-ccf59a87bf7197b5d07a33d7aaeb31638aa0aa52.gz
2008-06-06 05:23:05 +10:00
axel
41015691db Make all fish that use universal variables binaries include iconv
darcs-hash:20090203002620-ac50b-6be533cd1bf7dd043d96547b2c2f3ab4cda30e10.gz
2009-02-03 10:26:20 +10:00
axel
7e1ac2d806 Actually escape the double-star recursive wildcard char when requested. This will make sure the syntax highlighting doesn't try to perform a recursive wildcard expansion when cheching command name existance, which killed performance
darcs-hash:20090202234751-ac50b-55dfd8b52f842826b02a69d6ab51c222108c30e3.gz
2009-02-03 09:47:51 +10:00
axel
35258bf1fb Make proper autoconf test for availability of posix nan function instead of fudging with the NAN macro.
darcs-hash:20090202232049-ac50b-0176955677ff39fdd05eeefa20dca883863c34e6.gz
2009-02-03 09:20:49 +10:00
axel
72025a6a38 Make fish avoid iterating through user list when completing file part of directory starting with tilde. Also add a timeout to the directory iteration, to protect against humongously large user databases.
darcs-hash:20090202224645-ac50b-353047a73e4d6f494f470fe2ea6c4a34b486d302.gz
2009-02-03 08:46:45 +10:00
axel
05341b055b ish's current hostname completion uses ~/.ssh/known_hosts as one of its sources of information, but ~/.ssh/config may also be useful. Gather all of the 'Host' declarations from ~/.ssh/config and filter out the ones with wildcards. Signed-off-by: James Vega <jamessan@debian.org>
darcs-hash:20090202210242-ac50b-cf50070ee33ab6113e32a4d997d464ac4b1faf24.gz
2009-02-03 07:02:42 +10:00
axel
9d7224d756 Add support for completing aliases in ssh. Written by David Bronke.
darcs-hash:20090201231805-ac50b-196d4c81981efe681677fe8ca7f1cc833a4734da.gz
2009-02-02 09:18:05 +10:00
axel
33ec8b45a0 Add effectv completions, written by Stefano Sabatini.
darcs-hash:20090201225558-ac50b-5704829043880d0264e3e3908d324a39857ada16.gz
2009-02-02 08:55:58 +10:00
axel
1dc49a4062 Fix color ls detection for BSD and OS X systems. Patch by Sven Axelsson.
darcs-hash:20090201222410-ac50b-e1e02244ae950c602d3b7e67fe567920c619024b.gz
2009-02-02 08:24:10 +10:00
axel
1123467991 Fix cd function to handle empty variables correctly. Patch by Sven Axelsson.
darcs-hash:20090201222058-ac50b-31a7ee2db9f68729c21ba153e1439cbeabff84ce.gz
2009-02-02 08:20:58 +10:00
axel
4f54da3795 Fix user completion so it can handle comments in the passwd file. Patch by Sven Axelsson.
darcs-hash:20090201221921-ac50b-ef0883afe4dc68b43c1c705d49b6b5505dbf1e73.gz
2009-02-02 08:19:21 +10:00
axel
c8de3d24c8 Add netcat completions, written by James Stanley
darcs-hash:20090201160411-ac50b-43c34e2a73477cde40f15887a810a7b365ec81c4.gz
2009-02-02 02:04:11 +10:00
axel
31439ffb52 Better warning message when trying to exit with jobs running. PAtch and suggestion from Josef Spillner.
darcs-hash:20090201151601-ac50b-64bf24877419a9087f37eda2486232dfdabea9d2.gz
2009-02-02 01:16:01 +10:00
axel
9111b85437 Fixed bug with configure.ac in autotools shipped with F10. This fix comes from James Reeves.
darcs-hash:20090201140928-ac50b-952a8ba0596e3cf4f4a4a94f226fd04ec607075f.gz
2009-02-02 00:09:28 +10:00
axel
c6427c5a47 Add mimedb infinite loop bug fix from James Reeves
darcs-hash:20090201133734-ac50b-96fb4735af616094ea57ba02266188f8a7038a0c.gz
2009-02-01 23:37:34 +10:00
axel
36c3bd4e8d Switch from ARG_MAX to getting value from sysconf, glibc no longer defines the latter. This was reported from Peter Alfredsen Matthew Wesley, among other people.
darcs-hash:20090201132329-ac50b-5b9d54731c2ea2da3868fd492e68628b7684bb76.gz
2009-02-01 23:23:29 +10:00
axel
dad549afd1 Fix slightly wrong LD_FLAG in Makefile
darcs-hash:20090201125628-ac50b-3e68d7165a6c19558c7c8d7189cb75d71b4a9875.gz
2009-02-01 22:56:28 +10:00
Ori Avtalion
e73c2be216 Add missing commas, letters and \c in the documentation
darcs-hash:20080210210053-57fc3-f7e03b3fca9dff8bdc02256dfb78478b68945015.gz
2008-02-11 07:00:53 +10:00
axel
b0d324f1a7 Fix dumb error causing fish not to compile...
darcs-hash:20080204230945-ac50b-a95529cf19c473f62b6104ae138cf8b8abcbd2ec.gz
2008-02-05 09:09:45 +10:00
axel
d7396ac59f Fix bug causing flood of error messages in terminal when trying to highlight an invalid command, reported by Denilson F. de Sa.
darcs-hash:20080204230905-ac50b-0829b69835347e5875656ae735181b724f10de2a.gz
2008-02-05 09:09:05 +10:00
liljencrantz
3f439e9cd3 Add quilt completions, written by Stefano Sabatini.
darcs-hash:20080123000021-75c98-b27ae979720c55ec2219f451c50e87e79fa38cd6.gz
2008-01-23 10:00:21 +10:00
liljencrantz
0b722864c0 Make string handling a bit more solid be making sure sb_printf returns a null terminated string even on failiure.
darcs-hash:20080120022045-75c98-a47aff63ce7278148ccf027d6ee3ff93b35ee350.gz
2008-01-20 12:20:45 +10:00
liljencrantz
75e26f0f94 Add completions for various user and group adding commands. Skip addgroup, since manual page was actually for adduser, most switches weren't applicable and I was too lazy to guess which ones.
darcs-hash:20080120020816-75c98-f937df6cb6789868a1385bfc3eb48f5ddefb3c43.gz
2008-01-20 12:08:16 +10:00
liljencrantz
8cacb33347 Add completions for m4
darcs-hash:20080119150149-75c98-d8e5060ef78c6103d51e453ee4d5265f0981c4af.gz
2008-01-20 01:01:49 +10:00
liljencrantz
bf7d62fd91 Add completions for badblocks
darcs-hash:20080119145849-75c98-657a11bc69fbf625b01f84f1f6638e0d4b767228.gz
2008-01-20 00:58:49 +10:00
liljencrantz
4ac31e637d Add completions for Battle of Wesnoth
darcs-hash:20080119145414-75c98-6d8f856062ea44cf5de56bb014765a65ac26706b.gz
2008-01-20 00:54:14 +10:00
liljencrantz
0ad64ad2e4 Improve documentaion for bind builtin, clarify how to specify key sequences.
darcs-hash:20080119003820-75c98-b1f9360ddab9206a1cdf77b94ce28e9978badb53.gz
2008-01-19 10:38:20 +10:00
liljencrantz
523096e5d8 Add simple git completions by Diggory Hardy
darcs-hash:20080118160327-75c98-33e4e011de409944143aecf4f7e7aa8995687c75.gz
2008-01-19 02:03:27 +10:00
liljencrantz
0de629e009 Fix spelling in docs and add a help page for the funced builtin. These changes where suggested by Emanuele Rusconi.
darcs-hash:20080118155413-75c98-eadff877b3af3c3271b098903f80a45082111424.gz
2008-01-19 01:54:13 +10:00
liljencrantz
1f6fa1208e Search for command-not-found in PATH on startup, since older implementations place it there
darcs-hash:20080115122953-75c98-05ef8cb650a942c59dfa35aa63b25ccd49614dde.gz
2008-01-15 22:29:53 +10:00
liljencrantz
b86856b454 In prompt_pwd, if a directory name starts with a dot, include first two characters. This patch was written by Denilson F. de Sá
darcs-hash:20080116223621-75c98-46f96c9f25d5e32cd10148d35713622e6eac50d7.gz
2008-01-17 08:36:21 +10:00
liljencrantz
6598320534 Remove useless stray argument in function call
darcs-hash:20080116222628-75c98-a307fbeacdd815edcedea05930dc8b4bb064acb3.gz
2008-01-17 08:26:28 +10:00
liljencrantz
0a66dc4a31 Correct completions for the function builtin
darcs-hash:20080116222602-75c98-c1a48b4a04fe71b25c5e004a282341148a95ab6d.gz
2008-01-17 08:26:02 +10:00
liljencrantz
88a2b622df Add more documentation on events
darcs-hash:20080116222531-75c98-ef30dabc492d7883dbb620c40ef95152469057a3.gz
2008-01-17 08:25:31 +10:00
liljencrantz
e10f75483f Fix minor bug, PWD was incorrectly set on startup
darcs-hash:20080116220738-75c98-2b7c886629857540efee8f1cab9da0aa9ed8f76d.gz
2008-01-17 08:07:38 +10:00
liljencrantz
1a66fc4c5d Drop vim feature of only completing text and gzip files
darcs-hash:20080116180249-75c98-2fdff83afcb286c7cc06d3ed66089c9cc02eca20.gz
2008-01-17 04:02:49 +10:00
liljencrantz
905b792de7 Improve code comment
darcs-hash:20080116010601-75c98-fc7e940543424479bf1016cec26af619f177f5fd.gz
2008-01-16 11:06:01 +10:00
liljencrantz
804f5ab334 Add an extra input validation check
darcs-hash:20080116010548-75c98-e6f198bb1eb5a456ce830c42f061428a9c6f755d.gz
2008-01-16 11:05:48 +10:00
liljencrantz
f974c7c416 Improve error messages on failed execve calls a bit more
darcs-hash:20080116010454-75c98-883050bf00f10bdb205724d7d273f10e6f0a1065.gz
2008-01-16 11:04:54 +10:00
liljencrantz
f3b6b74568 Oops. Made a minor but important typo in previous cleanup patch. :-(
darcs-hash:20080115004050-75c98-3f7f733cca054d8685ec5df68d6467057ea5be53.gz
2008-01-15 10:40:50 +10:00
liljencrantz
ab94a397c3 Drop minor typo, add a few code comments
darcs-hash:20080114225828-75c98-f67f17d7f3148b0bcc74ea53536d52da80667e55.gz
2008-01-15 08:58:28 +10:00
liljencrantz
537ab32dd9 Add support for the Ubuntu 'command-no-found' handler, which suggests a package to install in order to get a command.
darcs-hash:20080114223124-75c98-ab1658d54086394cf13f3a6210543c0b790362c4.gz
2008-01-15 08:31:24 +10:00
liljencrantz
a2660cfb76 Handle case insensitive completions of variables better
darcs-hash:20080114010032-75c98-6e570c2b095baeb2ed2ee4d09e32f4e7d6ae47de.gz
2008-01-14 11:00:32 +10:00
liljencrantz
3743a5758b The max size of the string buffer was too small. Push it up a bit.
darcs-hash:20080114005745-75c98-1bcad5c5e81d4257eb7e96e860f8c667f9ba3267.gz
2008-01-14 10:57:45 +10:00
James Vega
e510d10c77 Fixed various spelling errors.
darcs-hash:20080113200151-35ec8-c587f020aec07a5e613068677bd3dd4f5c6189ac.gz
2008-01-14 06:01:51 +10:00
liljencrantz
f5540ff958 Add canse insensitive tilde completion
darcs-hash:20080113193221-75c98-169804fe128001f73eaee6fab28bfb99dca7c93e.gz
2008-01-14 05:32:21 +10:00
liljencrantz
c2b28063e1 Improve Doxygen documentation generation a bit
darcs-hash:20080113164924-75c98-d9762465de42750728ac6cb9364f4739a29ae376.gz
2008-01-14 02:49:24 +10:00
liljencrantz
8d2564291d Make sure fish_indent handles io erros
darcs-hash:20080113164905-75c98-b090ce79fb50a260874951525218cac65a097a6d.gz
2008-01-14 02:49:05 +10:00
liljencrantz
87db9517e9 Add lots of new code comments.
darcs-hash:20080113164747-75c98-9d0cefd27be7aef7ba60772616d9da7e6bb52912.gz
2008-01-14 02:47:47 +10:00
90 changed files with 1910 additions and 574 deletions

View File

@@ -53,16 +53,6 @@ CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
# This tag can be used to specify the encoding used in the generated output.
# The encoding is not always determined by the language that is chosen,
# but also whether or not the output is meant for Windows or non-Windows users.
# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
# forces the Windows encoding (this is the default for the Windows binary),
# whereas setting the tag to NO uses a Unix-style encoding (the default for
# all platforms other than Windows).
USE_WINDOWS_ENCODING = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
@@ -444,7 +434,8 @@ RECURSIVE = NO
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE =
EXCLUDE = print_help.c xdgmimealias.c xdgmimealias.h xdgmime.c xdgmimeglob.c xdgmimeglob.h xdgmime.h xdgmimeint.c xdgmimeint.h xdgmimemagic.c xdgmimemagic.h xdgmimeparent.c xdgmimeparent.h
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
# that are symbolic links (a Unix filesystem feature) are excluded from the input.
@@ -1112,22 +1103,6 @@ DOT_PATH =
DOTFILE_DIRS =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 750
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
# graphs generated by dot. A depth value of 3 means that only nodes reachable
# from the root by following a path via at most 3 edges will be shown. Nodes that

View File

@@ -749,7 +749,7 @@ fish_indent: $(FISH_INDENT_OBJS)
#
key_reader: key_reader.o input_common.o common.o env_universal.o env_universal_common.o wutil.o
$(CC) key_reader.o input_common.o common.o env_universal.o env_universal_common.o wutil.o $(LDFLAGS) -o $@
$(CC) key_reader.o input_common.o common.o env_universal.o env_universal_common.o wutil.o $(LDFLAGS_FISH) -o $@
#

View File

@@ -407,6 +407,9 @@ static void builtin_missing_argument( const wchar_t *cmd, const wchar_t *opt )
#include "builtin_ulimit.c"
#include "builtin_jobs.c"
/**
List all current key bindings
*/
static void builtin_bind_list()
{
array_list_t lst;
@@ -442,6 +445,13 @@ static void builtin_bind_list()
al_destroy( &lst );
}
/**
Print terminfo key binding names to string buffer used for standard output.
\param all if set, all terminfo key binding names will be
printed. If not set, only ones that are defined for this terminal
are printed.
*/
static void builtin_bind_key_names( int all )
{
array_list_t lst;
@@ -460,6 +470,10 @@ static void builtin_bind_key_names( int all )
al_destroy( &lst );
}
/**
Print all the special key binding functions to string buffer used for standard output.
*/
static void builtin_bind_function_names()
{
array_list_t lst;
@@ -478,6 +492,9 @@ static void builtin_bind_function_names()
al_destroy( &lst );
}
/**
Add specified key binding.
*/
static int builtin_bind_add( wchar_t *seq, wchar_t *cmd, int terminfo )
{
@@ -526,6 +543,12 @@ static int builtin_bind_add( wchar_t *seq, wchar_t *cmd, int terminfo )
}
/**
Erase specified key bindings
\param seq an array of all key bindings to erase
\param all if specified, _all_ key bindings will be erased
*/
static void builtin_bind_erase( wchar_t **seq, int all )
{
if( all )
@@ -983,7 +1006,9 @@ static int builtin_builtin( wchar_t **argv )
return STATUS_BUILTIN_OK;
}
/**
Implementation of the builtin emit command, used to create events.
*/
static int builtin_emit( wchar_t **argv )
{
int argc=builtin_count_args( argv );
@@ -2133,6 +2158,8 @@ static int builtin_read( wchar_t **argv )
reader_set_buffer( commandline, wcslen( commandline ) );
proc_push_interactive( 1 );
event_fire_generic(L"fish_prompt");
line = reader_readline( );
proc_pop_interactive();
if( line )
@@ -2529,23 +2556,6 @@ static int builtin_exit( wchar_t **argv )
return ec;
}
/**
Helper function for builtin_cd, used for seting the current working
directory
*/
static int set_pwd( wchar_t *env)
{
wchar_t dir_path[4096];
wchar_t *res = wgetcwd( dir_path, 4096 );
if( !res )
{
builtin_wperror( L"wgetcwd" );
return STATUS_BUILTIN_OK;
}
env_set( env, dir_path, ENV_EXPORT | ENV_GLOBAL );
return 1;
}
/**
The cd builtin. Changes the current directory to the one specified
or to $HOME if none is specified. The directory can be relative to
@@ -2649,7 +2659,7 @@ static int builtin_cd( wchar_t **argv )
res = 1;
}
else if( !set_pwd(L"PWD") )
else if( !env_set_pwd() )
{
res=1;
sb_printf( sb_err, _( L"%ls: Could not set PWD variable\n" ), argv[0] );
@@ -2660,7 +2670,10 @@ static int builtin_cd( wchar_t **argv )
return res;
}
/**
Implementation of the builtin count command, used to count the
number of arguments sent to it.
*/
static int builtin_count( wchar_t ** argv )
{
int argc;
@@ -2669,6 +2682,10 @@ static int builtin_count( wchar_t ** argv )
return !(argc-1);
}
/**
Implementation of the builtin contains command, used to check if a
specified string is part of a list.
*/
static int builtin_contains( wchar_t ** argv )
{
int argc;
@@ -2832,7 +2849,7 @@ static int builtin_source( wchar_t ** argv )
sb_printf( sb_err,
_( L"%ls: Error while reading file '%ls'\n" ),
argv[0],
fn_intern == L"-" ? L"<stdin>" : fn_intern );
fn_intern == intern_static(L"-") ? L"<stdin>" : fn_intern );
}
else
{
@@ -3408,6 +3425,11 @@ static int builtin_break_continue( wchar_t **argv )
return STATUS_BUILTIN_OK;
}
/**
Implementation of the builtin count command, used to launch the
interactive debugger.
*/
static int builtin_breakpoint( wchar_t **argv )
{
parser_push_block( BREAKPOINT );

View File

@@ -129,6 +129,7 @@ int builtin_exists( wchar_t *cmd );
of the builtin. The list is terminated by a
null pointer. This syntax resembles the syntax
for exec.
\param io the io redirections to perform on this builtin.
\return the exit status of the builtin command
*/

View File

@@ -52,7 +52,15 @@ enum
}
;
/**
Pointer to what the commandline builtin considers to be the current
contents of the command line buffer.
*/
static wchar_t *current_buffer=0;
/**
What the commandline builtin considers to be the current cursor
position.
*/
static int current_cursor_pos = -1;
/**

View File

@@ -308,11 +308,6 @@ static int builtin_complete( wchar_t **argv )
static int recursion_level=0;
if( !is_interactive_session )
{
debug( 1, _(L"%ls: Command only available in interactive sessions"), argv[0] );
}
al_init( &cmd );
al_init( &path );
sb_init( &short_opt );

View File

@@ -578,6 +578,36 @@ int read_blocked(int fd, void *buf, size_t count)
return res;
}
ssize_t write_loop(int fd, char *buff, size_t count)
{
ssize_t out=0;
ssize_t out_cum=0;
while( 1 )
{
out = write( fd,
&buff[out_cum],
count - out_cum );
if (out == -1)
{
if( errno != EAGAIN &&
errno != EINTR )
{
return -1;
}
} else
{
out_cum += out;
}
if( out_cum >= count )
{
break;
}
}
return out_cum;
}
void debug( int level, const wchar_t *msg, ... )
{
va_list va;
@@ -702,6 +732,11 @@ void write_screen( const wchar_t *msg, string_buffer_t *buff )
sb_append_char( buff, L'\n' );
}
/**
Perform string escaping of a strinng by only quoting it. Assumes
the string has already been checked for characters that can not be
escaped this way.
*/
static wchar_t *escape_simple( const wchar_t *in )
{
wchar_t *out;
@@ -1800,3 +1835,25 @@ void sb_format_size( string_buffer_t *sb,
}
}
}
double timef()
{
int time_res;
struct timeval tv;
time_res = gettimeofday(&tv, 0);
if( time_res )
{
/*
Fixme: What on earth is the correct parameter value for NaN?
The man pages and the standard helpfully state that this
parameter is implementation defined. Gcc gives a warning if
a null pointer is used. But not even all mighty Google gives
a hint to what value should actually be returned.
*/
return nan("");
}
return (double)tv.tv_sec + 0.000001*tv.tv_usec;
}

View File

@@ -40,11 +40,12 @@
*/
#define BYTE_MAX 0xffu
/*
Escape special fish syntax characters liek the semicolon
/**
Escape special fish syntax characters like the semicolon
*/
#define UNESCAPE_SPECIAL 1
/*
/**
Allow incomplete escape sequences
*/
#define UNESCAPE_INCOMPLETE 2
@@ -108,13 +109,13 @@ extern wchar_t *program_name;
/**
Pause for input, then exit the program. If supported, print a backtrace first.
*/
#define FATAL_EXIT() \
{ \
char c; \
show_stackframe(); \
read( 0, &c, 1 ); \
exit( 1 ); \
} \
#define FATAL_EXIT() \
{ \
int exit_read_count;char exit_read_buff; \
show_stackframe(); \
exit_read_count=read( 0, &exit_read_buff, 1 ); \
exit( 1 ); \
} \
/**
@@ -155,10 +156,16 @@ extern wchar_t *program_name;
*/
#define N_(wstr) wstr
/**
Check if the specified stringelement is a part of the specified string list
*/
#define contains( str,... ) contains_internal( str, __VA_ARGS__, (void *)0 )
/**
Concatenate all the specified strings into a single newly allocated one
*/
#define wcsdupcat( str,... ) wcsdupcat_internal( str, __VA_ARGS__, (void *)0 )
/*
/**
Print a stack trace to stderr
*/
void show_stackframe();
@@ -324,6 +331,12 @@ __sentinel int contains_internal( const wchar_t *needle, ... );
*/
int read_blocked(int fd, void *buf, size_t count);
/**
Loop a write request while failiure is non-critical. Return -1 and set errno
in case of critical error.
*/
ssize_t write_loop(int fd, char *buff, size_t count);
/**
Issue a debug message with printf-style string formating and
@@ -440,5 +453,15 @@ void bugreport();
void sb_format_size( string_buffer_t *sb,
long long sz );
/**
Return the number of seconds from the UNIX epoch, with subsecond
precision. This function uses the gettimeofday function, and will
have the same precision as that function.
If an error occurs, NAN is returned.
*/
double timef();
#endif

View File

@@ -1,6 +1,6 @@
/** \file complete.c Functions related to tab-completion.
These functions are used for storing and retrieving tab-completion data, as well as for performing tab-completion.
These functions are used for storing and retrieving tab-completion data, as well as for performing tab-completion.
*/
#include "config.h"
@@ -58,7 +58,7 @@ These functions are used for storing and retrieving tab-completion data, as well
/**
Description for ~USER completion
*/
#define COMPLETE_USER_DESC _( L"Home for %s" )
#define COMPLETE_USER_DESC _( L"Home for %ls" )
/**
Description for short variables. The value is concatenated to this description
@@ -107,6 +107,14 @@ These functions are used for storing and retrieving tab-completion data, as well
#endif
/**
The maximum amount of time that we're willing to spend doing
username tilde completion. This special limit has been coded in
because user lookup can be extremely slow in cases of a humongous
LDAP database. (Google, I'm looking at you)
*/
#define MAX_USER_LOOKUP_TIME 0.2
/**
Struct describing a completion option entry.
@@ -180,9 +188,9 @@ static void complete_free_entry( complete_entry_t *c );
*/
void completion_allocate( array_list_t *context,
const wchar_t *comp,
const wchar_t *desc,
int flags )
const wchar_t *comp,
const wchar_t *desc,
int flags )
{
completion_t *res = halloc( context, sizeof( completion_t) );
res->completion = halloc_wcsdup( context, comp );
@@ -378,8 +386,8 @@ static complete_entry_t *complete_get_exact_entry( const wchar_t *cmd,
void complete_set_authoritative( const wchar_t *cmd,
int cmd_type,
int authoritative )
int cmd_type,
int authoritative )
{
complete_entry_t *c;
@@ -473,9 +481,9 @@ static complete_entry_t *complete_remove_entry( complete_entry_t *e,
{
wchar_t *pos;
/* fwprintf( stderr,
L"remove option -%lc --%ls\n",
o->short_opt?o->short_opt:L' ',
o->long_opt );
L"remove option -%lc --%ls\n",
o->short_opt?o->short_opt:L' ',
o->long_opt );
*/
if( o->short_opt )
{
@@ -1067,10 +1075,10 @@ static const wchar_t *complete_function_desc( const wchar_t *fn )
\param comp the list to add all completions to
*/
static void complete_cmd( const wchar_t *cmd,
array_list_t *comp,
int use_function,
int use_builtin,
int use_command )
array_list_t *comp,
int use_function,
int use_builtin,
int use_command )
{
wchar_t *path;
wchar_t *path_cpy;
@@ -1124,18 +1132,18 @@ static void complete_cmd( const wchar_t *cmd,
add_slash = nxt_path[path_len-1]!=L'/';
nxt_completion = wcsdupcat( nxt_path,
add_slash?L"/":L"",
cmd );
add_slash?L"/":L"",
cmd );
if( ! nxt_completion )
continue;
prev_count = al_get_count( comp );
if( expand_string( 0,
nxt_completion,
comp,
ACCEPT_INCOMPLETE |
EXECUTABLES_ONLY ) != EXPAND_ERROR )
nxt_completion,
comp,
ACCEPT_INCOMPLETE |
EXECUTABLES_ONLY ) != EXPAND_ERROR )
{
for( i=prev_count; i<al_get_count( comp ); i++ )
{
@@ -1188,8 +1196,8 @@ static void complete_cmd( const wchar_t *cmd,
{
wchar_t *nxt_completion=
wcsdupcat( nxt_path,
(nxt_path[wcslen(nxt_path)-1]==L'/'?L"":L"/"),
cmd );
(nxt_path[wcslen(nxt_path)-1]==L'/'?L"":L"/"),
cmd );
if( ! nxt_completion )
{
continue;
@@ -1662,7 +1670,7 @@ static int complete_variable( const wchar_t *whole_var,
{
sb_append_substring( &comp, whole_var, start_offset );
sb_append( &comp, name );
flags = COMPLETE_NO_CASE;
flags = COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE;
}
value = expand_escape_variable( value_unescaped );
@@ -1724,111 +1732,86 @@ static int try_complete_variable( const wchar_t *cmd,
static int try_complete_user( const wchar_t *cmd,
array_list_t *comp )
{
const wchar_t *first_char=0;
const wchar_t *p;
int mode = 0;
int res = 0;
for( p=cmd; *p; p++ )
const wchar_t *first_char=cmd;
int res=0;
double start_time = timef();
if( *first_char ==L'~' && !wcschr(first_char, L'/'))
{
switch( mode )
const wchar_t *user_name = first_char+1;
wchar_t *name_end = wcschr( user_name, L'~' );
if( name_end == 0 )
{
/*Between parameters*/
case 0:
switch( *p )
{
case L'\"':
mode=2;
p++;
first_char = p;
break;
case L' ':
case L'\t':
case L'\n':
case L'\r':
break;
default:
mode=1;
first_char = p;
}
break;
/*Inside non-quoted parameter*/
case 1:
switch( *p )
{
case L' ':
case L'\t':
case L'\n':
case L'\r':
mode = 0;
break;
}
break;
case 2:
switch( *p )
{
case L'\"':
if( *(p-1) != L'\\' )
mode =0;
break;
}
break;
}
}
if( mode != 0 )
{
if( *first_char ==L'~' )
{
const wchar_t *user_name = first_char+1;
wchar_t *name_end = wcschr( user_name, L'~' );
if( name_end == 0 )
struct passwd *pw;
int name_len = wcslen( user_name );
setpwent();
while((pw=getpwent()) != 0)
{
struct passwd *pw;
int name_len = wcslen( user_name );
double current_time = timef();
wchar_t *pw_name;
setpwent();
while((pw=getpwent()) != 0)
if( current_time - start_time > 0.2 )
{
wchar_t *pw_name = str2wcs( pw->pw_name );
if( pw_name )
{
if( wcsncmp( user_name, pw_name, name_len )==0 )
{
string_buffer_t desc;
string_buffer_t name;
sb_init( &name );
sb_printf( &name,
L"%ls/",
&pw_name[name_len] );
sb_init( &desc );
sb_printf( &desc,
COMPLETE_USER_DESC,
pw->pw_gecos );
completion_allocate( comp,
(wchar_t *)name.buff,
(wchar_t *)desc.buff,
0 );
res=1;
sb_destroy( &desc );
sb_destroy( &name );
}
free( pw_name );
}
return 1;
}
pw_name = str2wcs( pw->pw_name );
if( pw_name )
{
if( wcsncmp( user_name, pw_name, name_len )==0 )
{
string_buffer_t desc;
sb_init( &desc );
sb_printf( &desc,
COMPLETE_USER_DESC,
pw_name );
completion_allocate( comp,
&pw_name[name_len],
(wchar_t *)desc.buff,
COMPLETE_NO_SPACE );
res=1;
sb_destroy( &desc );
}
else if( wcsncasecmp( user_name, pw_name, name_len )==0 )
{
string_buffer_t name;
string_buffer_t desc;
sb_init( &name );
sb_init( &desc );
sb_printf( &name,
L"~%ls",
pw_name );
sb_printf( &desc,
COMPLETE_USER_DESC,
pw_name );
completion_allocate( comp,
(wchar_t *)name.buff,
(wchar_t *)desc.buff,
COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE );
res=1;
sb_destroy( &desc );
sb_destroy( &name );
}
free( pw_name );
}
endpwent();
}
endpwent();
}
}
return res;}
return res;
}

View File

@@ -94,6 +94,13 @@
*/
#define COMPLETE_AUTO_SPACE 8
/**
This completion should be inserted as-is, without escaping.
*/
#define COMPLETE_DONT_ESCAPE 16
typedef struct
{
@@ -163,34 +170,34 @@ typedef struct
\param comp A space separated list of completions which may contain subshells.
\param desc A description of the completion.
\param condition a command to be run to check it this completion should be used. If \c condition is empty, the completion is always used.
\param flags A set of completion flags
*/
void complete_add( const wchar_t *cmd,
int cmd_type,
wchar_t short_opt,
const wchar_t *long_opt,
int long_mode,
int result_mode,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags );
int cmd_type,
wchar_t short_opt,
const wchar_t *long_opt,
int long_mode,
int result_mode,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags );
/**
Sets whether the completion list for this command is complete. If
true, any options not matching one of the provided options will be
flagged as an error by syntax highlighting.
*/
void complete_set_authoritative( const wchar_t *cmd,
int cmd_type,
int authoritative );
int cmd_type,
int authoritative );
/**
Remove a previously defined completion
*/
void complete_remove( const wchar_t *cmd,
int cmd_type,
wchar_t short_opt,
const wchar_t *long_opt );
int cmd_type,
wchar_t short_opt,
const wchar_t *long_opt );
/**
Find all completions of the command cmd, insert them into out. The
@@ -242,7 +249,7 @@ void complete_load( const wchar_t *cmd, int reload );
Create a new completion entry
\param context The halloc context to use for allocating new memory
\pram comp The completion string
\param comp The completion string
\param desc The description of the completion
\param flags completion flags
*/

View File

@@ -9,29 +9,29 @@
# configure the build process.
#
AC_INIT(fish,1.23.0,fish-users@lists.sf.net)
AC_INIT(fish,1.23.1,fish-users@lists.sf.net)
#
# List of output variables produced by this configure script
#
AC_SUBST( docdir )
AC_SUBST( HAVE_GETTEXT )
AC_SUBST( LDFLAGS_FISH )
AC_SUBST( LIBS_FISH )
AC_SUBST( LIBS_FISH_INDENT )
AC_SUBST( LIBS_FISH_PAGER )
AC_SUBST( LIBS_FISHD )
AC_SUBST( LIBS_MIMEDB )
AC_SUBST( LIBS_SET_COLOR )
AC_SUBST( localedir )
AC_SUBST( optbindirs )
AC_SUBST( prefix )
AC_SUBST( SEQ_FALLBACK )
AC_SUBST( XSEL )
AC_SUBST( XSEL_MAN )
AC_SUBST( XSEL_MAN_PATH )
AC_SUBST(docdir)
AC_SUBST(HAVE_GETTEXT)
AC_SUBST(LDFLAGS_FISH)
AC_SUBST(LIBS_FISH)
AC_SUBST(LIBS_FISH_INDENT)
AC_SUBST(LIBS_FISH_PAGER)
AC_SUBST(LIBS_FISHD)
AC_SUBST(LIBS_MIMEDB)
AC_SUBST(LIBS_SET_COLOR)
AC_SUBST(localedir)
AC_SUBST(optbindirs)
AC_SUBST(prefix)
AC_SUBST(SEQ_FALLBACK)
AC_SUBST(XSEL)
AC_SUBST(XSEL_MAN)
AC_SUBST(XSEL_MAN_PATH)
#
# If needed, run autoconf to regenerate the configure file
@@ -505,6 +505,7 @@ LIBS=""
AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] )
AC_SEARCH_LIBS( nanosleep, rt, , [AC_MSG_ERROR([Cannot find the rt library, needed to build this package.] )] )
AC_SEARCH_LIBS( setupterm, [ncurses curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] )
AC_SEARCH_LIBS( [nan], [m], [AC_DEFINE( [HAVE_NAN], [1], [Define to 1 if you have the nan function])] )
LIBS_SHARED=$LIBS
LIBS=$LIBS_COMMON
@@ -518,8 +519,10 @@ if test x$local_gettext != xno; then
AC_SEARCH_LIBS( gettext, intl,,)
fi
# Check for libiconv_open if we can't find iconv_open. Silly OS X does
# weird macro magic for the sole purpose of amusing me.
AC_SEARCH_LIBS( iconv_open, iconv, , [AC_SEARCH_LIBS( libiconv_open, iconv, , [AC_MSG_ERROR([Could not find an iconv implementation, needed to build fish])] )] )
AC_SEARCH_LIBS( iconv_open, iconv, , [AC_MSG_ERROR([Could not find an iconv implementation, needed to build fish])] )
LIBS_FISH=$LIBS
LIBS=$LIBS_COMMON
@@ -544,6 +547,7 @@ LIBS="$LIBS_SHARED"
if test x$local_gettext != xno; then
AC_SEARCH_LIBS( gettext, intl,,)
fi
AC_SEARCH_LIBS( iconv_open, iconv, , [AC_MSG_ERROR([Could not find an iconv implementation, needed to build fish])] )
LIBS_FISH_PAGER=$LIBS
LIBS=$LIBS_COMMON
@@ -556,6 +560,7 @@ LIBS="$LIBS_SHARED"
if test x$local_gettext != xno; then
AC_SEARCH_LIBS( gettext, intl,,)
fi
AC_SEARCH_LIBS( iconv_open, iconv, , [AC_MSG_ERROR([Could not find an iconv implementation, needed to build fish])] )
LIBS_FISHD=$LIBS
LIBS=$LIBS_COMMON

View File

@@ -17,7 +17,7 @@ variable.
\subsection and-example Example
The following code runs the \c make command to build a program, if the
build succceeds, the program is installed. If either step fails,
build succeeds, the program is installed. If either step fails,
<tt>make clean</tt> is run, which removes the files created by the
build process

View File

@@ -8,9 +8,15 @@
The <tt>bind</tt> builtin causes fish to add a key binding from the specified sequence.
SEQUENCE is the character sequence to bind to. Usually, one would use
fish escape sequences to express them. For example, Alt-w can be
written as <tt>\\ew</tt>, and Control-x can be written as
<tt>\\cx</tt>.
fish escape sequences to express them. For example, because pressing
the Alt key and another character sends that character prefixed with
an escape character, Alt-based key bindings can be written using the
\c \\e escape. For example, Alt-w can be written as
<tt>\\ew</tt>. Control character can be written in much the same way
using the \c \\c escape, for example Control-x can be written as
<tt>\\cx</tt>. Note that Alt-based key bindings are case sensitive and
Control base key bindings are not. This is not a design choice in
fish, it is simply how terminals work.
If SEQUENCE is the empty string, i.e. an empty set of quotes, this is
interpreted as the default keybinding. It will be used whenever no

View File

@@ -19,7 +19,7 @@ regular wildcard expansion using filenames.
Note that fish does not fall through on case statements. Though the
syntax may look a bit like C switch statements, it behaves more like
the case statementes of traditional shells.
the case statements of traditional shells.
Also note that command substitutions in a case statement will be
evaluated even if it's body is not taken. This may seem

View File

@@ -122,8 +122,8 @@ 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 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
- 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.
\section disc The law of discoverability
@@ -147,7 +147,7 @@ until the next time she/he uses the same program.
Examples:
- Everything should be tab-completable, and every tab completion should have a description
- Everything should be tab-completable, and every tab completion should have a description.
- Every syntax error and error in a builtin command should contain an error message describing what went wrong and a relevant help page. Whenever possible, errors should be flagged red by the syntax highlighter.
- The help manual should be easy to read, easily available from the shell, complete and contain many examples
- The language should be uniform, so that once the user understands the command/argument syntax, he will know the whole language, and be able to use tab-completion to discover new featues.

View File

@@ -7,6 +7,7 @@
- <a href='#faq-default'>How do I make fish my default shell?</a>
- <a href='#faq-titlebar'>I'm seeing weird output before each prompt when using screen. What's wrong?</a>
- <a href='#faq-greeting'>How do I change the greeting message?</a>
- <a href='#faq-history'>Why doesn't history substitution ("!$" etc.) work?</a>
<hr>
@@ -56,8 +57,8 @@ feature, write <code>set CDPATH .</code> on the commandline.
If fish is unable to locate a command with a given name, fish will
test if a directory of that name exists. If it does, it is implicitly
assumed that you want to change working directory. For example, the
fastest way to switch to your home directory is to simply type
<code>~</code>.
fastest way to switch to your home directory is to simply press
<code>~</code> and enter.
<hr>
@@ -92,8 +93,8 @@ In order to change your default shell, type:
You may need to adjust the above path to e.g. /usr/bin/fish. Use the command <code>which fish</code> if you are unsure of where fish is installed.
You will need to log out and back in again for the change to take
effect.
Unfortunatly, there is no way to make the changes take effect at once,
you will need to log out and back in again.
<hr>
@@ -104,7 +105,7 @@ Quick answer:
Run the following command in fish:
<pre>
echo function fish_title;end ~/.config/fish/config.fish
echo 'function fish_title;end' &gt; ~/.config/fish/config.fish
</pre>
Problem solved!
@@ -136,5 +137,25 @@ the greeting use:
set fish_greeting
</pre>
<hr>
\section faq-history Why doesn't history substitution ("!$" etc.) work?
Because history substitution is an awkward interface that was invented before
interactive line editing was even possible. Fish drops it in favor of
perfecting the interactive history recall interface. Switching requires a
small change of habits: if you want to modify an old line/word, first recall
it, then edit. E.g. don't type "sudo !!" - first press Up, then Home, then
type "sudo ".
Fish history recall is very simple yet effective:
- As in any modern shell, the Up arrow recalls whole lines, starting from the last line executed. A single press replaces "!!", later presses replace "!-3" and the like.
- If the line you want is far back in the history, type any part of the line and then press Up one or more times. This will constrain the recall to lines that include this text, and you will get to the line you want much faster. This replaces "!vi", "!?bar.c" and the like.
- Alt+Up recalls individual arguments, starting from the last argument in the last line executed. A single press replaces "!$", later presses replace "!!:4" and the like.
- If the argument you want is far back in history (e.g. 2 lines back - that's a lot of words!), type any part of it and then press Alt+Up. This will show only arguments containing that part and you will get what you want much faster. Try it out, this is very convenient!
- If you want to reuse several arguments from the same line ("!!:3*" and the like), consider recalling the whole line and removing what you don't need (Alt+D and Alt+Backspace are your friends).
See <a href='index.html#editor'>documentation</a> for more details about line editing in fish.
*/

View File

@@ -5,11 +5,11 @@
\subsection fish_indent-description Description
\c fish_indent is used to indent or otherwise prettyfy a piece of fish
\c fish_indent is used to indent or otherwise prettify a piece of fish
code. \c fish_indent reads commands from standard input and outputs
them to standard output.
\c fish_indent underatands the following options:
\c fish_indent understands the following options:
- <tt>-h</tt> or <tt>--help</tt> displays this help message and then exits
- <tt>-i</tt> or <tt>--no-indent</tt> do not indent commands

View File

@@ -1,4 +1,4 @@
\section fish_prompt fish_prompt - define the apperance of the command line promp
\section fish_prompt fish_prompt - define the apperance of the command line prompt
\subsection fish_promt-synopsis Synopsis
<pre>function fish_prompt

9
doc_src/funced.txt Normal file
View File

@@ -0,0 +1,9 @@
\section funced funced - edit a function interactively
\subsection funced-synopsis Synopsis
<code>funced NAME</code>
\subsection funced-description Description
Use the funced command to interactively edit the definition of a
function. If there is no function with the name specified, a skeleton function is inserted, if a function exist, the definion will be shown on the command line.

12
doc_src/funcsave.txt Normal file
View File

@@ -0,0 +1,12 @@
\section funcsave funcsave - save the definition of a function to the users autoload directory
\subsection funcsave-synopsis Synopsis
<tt>funcsave FUNCTION_NAME</tt>
\subsection funcsave-description Description
funcsave is used to save the current definition of a function to
a file which will be autoloaded by current and future fish
sessions. This can be useful if you have interactively created a new
function and wish to save it for later use.

View File

@@ -6,6 +6,7 @@
\subsection function-description Description
- <code>-d DESCRIPTION</code> or \c --description=DESCRIPTION is a description of what the function does, suitable as a completion description
- <code>-e</code> or <code>--on-event EVENT_NAME</code> tells fish to run this function when the specified named event is emitted. Fish internally generates named events e.g. when showing the prompt.
- <code>-j PID</code> or <code> --on-job-exit PID</code> tells fish to run this function when the job with group id PID exits. Instead of PID, the string 'caller' can be specified. This is only legal when in a command substitution, and will result in the handler being triggered by the exit of the job which created this command substitution.
- <code>-p PID</code> or <code> --on-process-exit PID</code> tells fish to run this function when the fish child process with process id PID exits
- <code>-s</code> or <code>--on-signal SIGSPEC</code> tells fish to run this function when the signal SIGSPEC is delivered. SIGSPEC can be a signal number, or the signal name, such as SIGHUP (or just HUP)
@@ -26,6 +27,11 @@ will write <code>hello</code> whenever the user enters \c hi.
If the user enters any additional arguments after the function, they
are inserted into the environment <a href="index.html#variables-arrays">variable array</a> argv.
By using one of the event handler switches, a function can be made to run automatically at specific events. The user may generate new events using the <a href='#emit">emit</a> builtin. Fish generates the following named events:
- \c fish_prompt, which is emitted whenever a new fish prompt is about to be displayed
- \c fish_command_not_found, which is emitted whenever a command lookup failed
\subsection function-example Example
<pre>

View File

@@ -138,8 +138,8 @@ these characters, so called escape sequences are provided. These are:
- <code>'\\x<i>xx</i>'</code>, where <code><i>xx</i></code> is a hexadecimal number, escapes the ascii character with the specified value. For example, \\x9 is the tab character.
- <code>'\\X<i>xx</i>'</code>, where <code><i>xx</i></code> is a hexadecimal number, escapes a byte of data with the specified value. If you are using a mutibyte encoding, this can be used to enter invalid strings. Only use this if you know what you are doing.
- <code>'\\<i>ooo</i>'</code>, where <code><i>ooo</i></code> is an octal number, escapes the ascii character with the specified value. For example, \\011 is the tab character.
- <code>'\\u<i>xxxx</i>'</code>, where <code><i>xxxx</i></code> is a hexadecimal number, escapes the 16-bit unicode character with the specified value. For example, \\u9 is the tab character.
- <code>'\\U<i>xxxxxxxx</i>'</code>, where <code><i>xxxxxxxx</i></code> is a hexadecimal number, escapes the 32-bit unicode character with the specified value. For example, \\U9 is the tab character.
- <code>'\\u<i>xxxx</i>'</code>, where <code><i>xxxx</i></code> is a hexadecimal number, escapes the 16-bit Unicode character with the specified value. For example, \\u9 is the tab character.
- <code>'\\U<i>xxxxxxxx</i>'</code>, where <code><i>xxxxxxxx</i></code> is a hexadecimal number, escapes the 32-bit Unicode character with the specified value. For example, \\U9 is the tab character.
- <code>'\\c<i>x</i>'</code>, where <code><i>x</i></code> is a letter of the alphabet, escapes the control sequence generated by pressing the control key and the specified letter. For example, \\ci is the tab character
\subsection redirects IO redirection
@@ -306,7 +306,7 @@ a filename consisting of the name of the function plus the suffix
The default value for \$fish_function_path is \c ~/.config/fish/functions
\c /etc/fish/functions \c /usr/share/fish/functions. The exact path
to the last two of these may be slighly different depending on what
to the last two of these may be slightly different depending on what
install path prefix was chosen at configuration time. The rationale
behind having three different directories is that the first one is for
user specific functions, the second one is for system-wide additional
@@ -466,11 +466,11 @@ prints a list of all user groups with the groups members as description.
<pre>__fish_complete_pids</pre>
prints a list of all procceses IDs with the command name as description.
prints a list of all processes IDs with the command name as description.
<pre>__fish_complete_suffix SUFFIX</pre>
performs file completion allowing only files ending in SUFFIX. The mimetype database is usded to find a suitable description.
performs file completion allowing only files ending in SUFFIX. The mimetype database is used to find a suitable description.
<pre>__fish_complete_users</pre>
@@ -494,7 +494,7 @@ prints a list of all known network interfaces.
<pre>__fish_print_packages</pre>
prints a list of all installed packages. This function currently handles
debian, rpm and gentoo packages.
Debian, rpm and Gentoo packages.
@@ -509,7 +509,7 @@ of the name of the command to complete and the suffix '.fish'.
The default value for \$fish_complete_path is ~/.config/fish/completions,
/etc/fish/completions and /usr/share/fish/completions. The exact
path to the last two of these may be slighly different depending on
path to the last two of these may be slightly different depending on
what install path prefix was chosen at configuration time. If a
suitable file is found in one of these directories, it will be
automatically loaded and the search will be stopped. The rationale
@@ -519,14 +519,14 @@ completions and the last one is for default fish completions.
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>.
href='mailto: fish-users@lists.sf.net'>the fish mailing list</a>.
\section expand Parameter expansion (Globbing)
When an argument for a program is given on the commandline, it
undergoes the process of parameter expansion before it is sent on to
the command. Parameter expansion is a powerful set of mechamisms that
the command. Parameter expansion is a powerful set of mechanisms that
allow you to expand the parameter in various ways, including
performing wildcard matching on files, inserting the value of
environment variables into the parameter or even using the output of
@@ -749,7 +749,7 @@ the shell through <a href="expand-variable">variable expansion</a>.
Example:
To use the value of a the variable \c smurf, write $ (dollar symbol)
To use the value of the variable \c smurf, write $ (dollar symbol)
followed by the name of the variable, like <code>echo Smurfs are
usually $smurf_color</code>, which would print the result 'Smurfs are
usually blue'.
@@ -868,7 +868,7 @@ echo $PATH[3]
</pre>
Note that array indices start at 1 in fish, not 0, as is more common
in other languages. This is because many common unix tools like seq
in other languages. This is because many common Unix tools like seq
are more suited to such use.
If you do not use any brackets, all the elements of the array will be
@@ -928,7 +928,7 @@ values of most of these variables.
- \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 status, which is the exit status of the last foreground job to exit.
- \c status, which is the exit status of the last foreground job to exit. If the job was terminated through a signal, the exit status will be 128 plus the signal number.
- \c USER, which is the username. This variable can only be changed by the root user.
The names of these variables are mostly derived from the csh family of
@@ -967,6 +967,8 @@ variable may also be set to a specific value:
- 126 means that while a file with the specified name was located, it was not executable
- 127 means that no function, builtin or command with the given name could be located
If a process exits through a signal, the exit status will be 128 plus the number of the signal.
\subsection variables-color Variables for changing highlighting colors
The colors used by fish for syntax highlighting can be configured by
@@ -975,7 +977,7 @@ variables can be one of the colors accepted by the <a
href='commands.html#set_color'>set_color</a> command. The \c --bold
or \c -b switches accepted by \c set_color are also accepted.
The following variables are available to change the highligting colors
The following variables are available to change the highlighting colors
in fish:
- \c fish_color_normal, the default color
@@ -1050,7 +1052,7 @@ Here are some of the commands available in the editor:
- 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 respecitvely
- Delete and backspace removes one character forwards or backwards respectively
- Ctrl-c deletes 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 the cursor to the end of line to the <a href="#killring">killring</a>
@@ -1140,7 +1142,7 @@ than a single line:
- Pressing the enter key while a block of commands is unclosed, i.e. when one or more block commands such as 'for', 'begin' or 'if' do not have a corresponding 'end' command.
- Pressing Alt-enter instead of pressing the enter key.
- By backslash escaping a newline, i.e. by inserting a backslash (\\) character pefore pressing the enter key.
- By backslash escaping a newline, i.e. by inserting a backslash (\\) character before pressing the enter key.
The fish commandline editor works exactly the same in single line mode
and in multiline mode. To move between lines use the left and right
@@ -1241,7 +1243,7 @@ fish_title function is executed before and after a new command is
executed or put into the foreground and the output is used as a
titlebar message. The $_ environment variable will always contain the
name of the job to be put into the foreground (Or 'fish' if control is
returning to the shell) when the fish_prompt function is called.
returning to the shell) when the \c fish_prompt function is called.
Example:
<p>
@@ -1256,6 +1258,12 @@ end
</pre>
</p>
\subsection greeting Configurable greeting
If a function named fish_greeting exists after initialization, it will
be run when entering interactive mode. Otherwise,if an environment
variable named fish_greeting exists, it will be printed.
\subsection event Event handlers
When defining a new function in fish, it is possible to make it into an
@@ -1266,6 +1274,7 @@ specific event takes place. Events that can trigger a handler currently are:
- When a process or job exits
- When the value of a variable is updated
- When the prompt is about to be shown
- When a command lookup fails
Example:
@@ -1280,9 +1289,9 @@ For more information on how to define new event handlers, see the
documentation for the <a href='commands.html#function'>function</a>
command.
\subsection debuging Debuging fish scripts
\subsection debugging Debugging fish scripts
Fish includes a built in debuger. The debuger allows you to stop
Fish includes a built in debugger. The debugger allows you to stop
execution of a script at an arbitrary point and launch a prompt. This
prompt can then be used to check or change the value of any variables
or perform any shellscript command. To resume normal execution of the
@@ -1290,15 +1299,15 @@ script, simply exit the prompt.
To start the debugger, simply call the builtin command
'breakpoint'. The default action of the TRAP signal is to call this
builtin, so a running script can be debuged by sending it the TRAP
signal. Once in the debuger, it is easy to insert new breakpoints by
builtin, so a running script can be debugged by sending it the TRAP
signal. Once in the debugger, it is easy to insert new breakpoints by
using the funced function to edit the definition of a function.
\section issues Common issues with fish
If you install fish in your home directory, fish will not work
correctly for any other user than yourself. This is because fish needs
its initalization files to function properly. To solve this
its initialization files to function properly. To solve this
problem, either copy the initialization files to each fish users home
directory, or install them in /etc.
@@ -1310,7 +1319,7 @@ making a translation. Currently, only the shell itself can be
translated, a future version of fish should also include translated
manuals.
To make a translation of fish, you will first need the sourcecode,
To make a translation of fish, you will first need the source code,
available from the <a href='http://www.fishshell.org'>fish
homepage</a>. Download the latest version, and then extract it using a
command like <code>tar -zxf fish-VERSION.tar.gz</code>.
@@ -1318,7 +1327,7 @@ command like <code>tar -zxf fish-VERSION.tar.gz</code>.
Next, cd into the newly created fish directory using <code>cd
fish-VERSION</code>.
You will now need to configure the sourcecode using the command
You will now need to configure the source code using the command
<code>./configure</code>. This step might take a while.
Before you continue, you will need to know the ISO 639 language code
@@ -1326,7 +1335,7 @@ of the language you are translating to. These codes can be found <a
href='http://www.w3.org/WAI/ER/IG/ert/iso639.htm'>here</a>. For
example, the language code for Uighur is ug.
Now you have the sourcecode and it is properly configured. Lets start
Now you have the source code and it is properly configured. Lets start
translating. To do this, first create an empty translation table for
the language you wish to translate to by writing <code>make
po/[LANGUAGE CODE].po</code> in the fish terminal. For example, if you
@@ -1346,7 +1355,7 @@ msgstr ""
</pre>
The first line is the English string to translate, the second line
should contain your translation. For example, in swedish the above
should contain your translation. For example, in Swedish the above
might become:
<pre>
@@ -1395,8 +1404,7 @@ g++, javac, java, gcj, lpr, doxygen, whois)
- Selectable completions in the pager
- Per process output redirection
- Reduce the space of the pager by one line to allow the commandline to remain visible.
- down-arrow could be used to save the current command to the history. Or give the next command in-sequnce. Or both.
- Drop support for inputrc-files. Use shellscripts and the bind builtin. Also, redo the syntax for the bind builtin to something more sane.
- down-arrow could be used to save the current command to the history. Or give the next command in-sequence. Or both.
- History could reload itself when the file is updated. This would need to be done in a clever way to avoid chain reactions
- The error function should probably be moved into it's own library, and be made mere general purpose.
- The code validation functions should be moved from the parser to parse_util.
@@ -1410,6 +1418,8 @@ g++, javac, java, gcj, lpr, doxygen, whois)
- Don't use expand_string to perform completions. wildcard_complete can be called directly, the brace expansion handling should be universal, and the process expansion can be moved to complete.c.
- Make the history search support incremental searching
- An automatic logout feature
- Make tab completions completely silent by default, i.e. kill stderr when running completion commands. This needs to be overridalbe for debugging purposes.
- Move history to an environment variable
\subsection bugs Known bugs and issues
@@ -1417,16 +1427,14 @@ g++, javac, java, gcj, lpr, doxygen, whois)
- delete-word is broken on the commandline 'sudo update-alternatives --config x-'
- Sometimes autoheader needs to be run on a fresh tarball. Fix dates before creating tarballs.
- The completion autoloader does not remember which completions where actually autoloaded, and may unload manually specified completions.
- There have been stray reports of issues with strang values of the PATH variable during startup.
- There have been stray reports of issues with strange values of the PATH variable during startup.
- bindings in config.fish are overwritten by default key bindings.
- Adding 'bind -k ...' doesn't overwrite non-keybinding binds of the same sequence.
- History file does not remove duplicates.
- History file should apply some kind of maximum history length.
- 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 to have this problem.
If you think you have found a bug not described here, please send a
report to <a href="mailto:fish-users@lists.sf.net">fish-users@lists.sf.net</a>.
\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
to have this problem.
*/

View File

@@ -1,28 +1,11 @@
/** \page license Licenses
Fish Copyright (C) 2005-2006 Axel Liljencrantz. Fish is released under
<h2>License for fish</h2>
Fish Copyright (C) 2005-2009 Axel Liljencrantz. Fish is released under
the GNU General Public License, version 2. The license agreement is
included below.
Fish contains code under the BSD license, namely versions of the
two functions strlcat and strlcpy, modified for use with wide
character strings. This code is copyrighted by Todd C. Miller. The
license agreement is included below.
The XSel command, written and copyrighted by Conrad Parker, is
distributed together with, and used by fish. It is released under the MIT
license. The license agreement is included below.
The xdgmime library, written and copyrighted by Red Hat, Inc, is used
by the mimedb command, which is a part of fish. It is released under
the LGPL. The license agreement is included below.
Fish contains code from the glibc library, namely the wcstok
function. This code is licensed under the LGPL. The license agreement
is included below.
<HR>
<H2><A NAME="SEC1" HREF="gpl.html#TOC1">GNU GENERAL PUBLIC LICENSE</A></H2>
<P>
@@ -480,6 +463,18 @@ without express or implied warranty.
<HR>
<h2>License for xdgmime and glibc</h2>
The xdgmime library, written and copyrighted by Red Hat, Inc, is used
by the mimedb command, which is a part of fish. It is released under
the LGPL, version 2 or later, or under the Academic Free License,
version 2. Version 2 of the LGPL license agreement is included below.
Fish contains code from the glibc library, namely the wcstok
function. This code is licensed under the LGPL, version 2 or
later. Version 2 of the LPGL license agreement is included below.
<H2><A NAME="SEC1" HREF="#TOC1">GNU LESSER GENERAL PUBLIC LICENSE</A></H2>
<P>

View File

@@ -1,12 +1,12 @@
\section open open - open file in it's default application
\section open open - open file in its default application
\subsection open-synopsis Synopsis
<tt>open FILES...</tt>
\subsection open-description Description
The \c open command is used to open a file in it's default application. \c open is implemented using the <a href="commands.html#mimedb">mimedb</a> command.
The \c open command is used to open a file in its default application. \c open is implemented using the \c xdg-open command if it exists, or else the <a href="commands.html#mimedb">mimedb</a> command.
\subsection open-example Example
<tt>open *.txt</tt> opens all the text files in the current directory using your systems default text editor.
<tt>open *.txt</tt> opens all the text files in the current directory using your system's default text editor.

View File

@@ -17,7 +17,7 @@ variable.
\subsection or-example Example
The following code runs the \c make command to build a program, if the
build succceeds, the program is installed. If either step fails,
build succeeds, the program is installed. If either step fails,
<tt>make clean</tt> is run, which removes the files created by the
build process

View File

@@ -1,12 +0,0 @@
\section save_function save_function - save the definition of a function to the users autoload directory
\subsection save_function-synopsis Synopsis
<tt>save_function FUNCTION_NAME</tt>
\subsection save_function-description Description
save_function is used to save the current definition of a function to
a file which will be autoloaded by current and future fish
sessions. This can be useful if you have interactively created a new
function and wish to save it for later use.

View File

@@ -26,5 +26,11 @@ in a grey font color, while <code>set_color --bold white</code> will
result in a white font color.
Not all terminal emulators support all these features. This is not a
bug in set_color but a missing feature in the terminal emulator.
bug in set_color but a missing feature in the terminal emulator.
set_color uses the terminfo database to look up how to change terminal
colors on whatever terminal is in use. Some systems have old and
incomplete terminfo databases, and may lack color information for
terminals that support it. Download and install the latest version of
ncurses and recompile fish against it in order to fix this issue.

View File

@@ -14,5 +14,5 @@
- <tt>-f</tt> or <tt>--current-filename</tt> prints the filename of the currently running script
- <tt>-n</tt> or <tt>--current-line-number</tt> prints the line number of the currently running script
- <tt>-j CONTROLTYPE</tt> or <tt>--job-control=CONTROLTYPE</tt> set the job control type. Can be one of: none, full, interactive
- <tt>-t</tt> or <tt>--print-stack-trace</tt>
- <tt>-t</tt> or <tt>--print-stack-trace</tt> prints a stack trace of all function calls on the call stack
- <tt>-h</tt> or <tt>--help</tt> display a help message and exit

View File

@@ -56,7 +56,7 @@ The fish implementation of ulimit should behave identically to the
implementation in bash, except for these differences:
- Fish ulimit supports GNU-style long options for all switches
- Fish ulimit does not support the -p option for getting the pipe size. The bash implementation consists of a compile-time check that empirically guesses this number by writing to a pipe and waiting for SIGPIPE. Fish does not do this because it this method of determining pipe sixe is unreliable. Depending on bash version, there may also be further additional limits to set in bash that do not exist in fish.
- Fish ulimit does not support the -p option for getting the pipe size. The bash implementation consists of a compile-time check that empirically guesses this number by writing to a pipe and waiting for SIGPIPE. Fish does not do this because it this method of determining pipe size is unreliable. Depending on bash version, there may also be further additional limits to set in bash that do not exist in fish.
- Fish ulimit does not support getting or setting multiple limits in one command, except reporting all values using the -a switch
\subsection ulimit-example Example

20
env.c
View File

@@ -480,6 +480,21 @@ static void setup_path()
al_destroy( &l );
}
int env_set_pwd()
{
wchar_t dir_path[4096];
wchar_t *res = wgetcwd( dir_path, 4096 );
if( !res )
{
return 0;
}
env_set( L"PWD", dir_path, ENV_EXPORT | ENV_GLOBAL );
return 1;
}
/**
Set up default values for various variables if not defined.
*/
static void env_set_defaults()
{
@@ -502,6 +517,8 @@ static void env_set_defaults()
free( unam_narrow );
}
env_set_pwd();
}
void env_init()
@@ -1442,6 +1459,9 @@ static void export_func1( void *k, void *v, void *aux )
}
/**
Get list of all exported variables
*/
static void get_exported( env_node_t *n, hash_table_t *h )
{
if( !n )

7
env.h
View File

@@ -132,4 +132,11 @@ char **env_export_arr( int recalc );
*/
void env_get_names( array_list_t *l, int flags );
/**
Update the PWD variable
directory
*/
int env_set_pwd();
#endif

View File

@@ -99,7 +99,7 @@ var_uni_entry_t;
static void parse_message( wchar_t *msg,
connection_t *src );
connection_t *src );
/**
The table of all universal variables
@@ -176,8 +176,10 @@ static char *iconv_wide_names_2[]=
}
;
wchar_t *utf2wcs( const char *in )
/**
Convert utf-8 string to wide string
*/
static wchar_t *utf2wcs( const char *in )
{
iconv_t cd=(iconv_t) -1;
int i,j;
@@ -287,7 +289,10 @@ wchar_t *utf2wcs( const char *in )
return out;
}
char *wcs2utf( const wchar_t *in )
/**
Convert wide string to utf-8
*/
static char *wcs2utf( const wchar_t *in )
{
iconv_t cd=(iconv_t) -1;
int i,j;
@@ -404,6 +409,9 @@ void env_universal_common_destroy()
hash_destroy( &env_universal_var );
}
/**
Read one byte of date form the specified connection
*/
static int read_byte( connection_t *src )
{
@@ -740,6 +748,9 @@ void try_send_all( connection_t *c )
}
}
/**
Escape specified string
*/
static wchar_t *full_escape( const wchar_t *in )
{
string_buffer_t out;

11
event.c
View File

@@ -704,9 +704,11 @@ void event_free( event_t *e )
}
void event_fire_generic(const wchar_t *name)
void event_fire_generic_internal(const wchar_t *name, ...)
{
event_t ev;
va_list va;
wchar_t *arg;
CHECK( name, );
@@ -715,6 +717,13 @@ void event_fire_generic(const wchar_t *name)
ev.function_name=0;
al_init( &ev.arguments );
va_start( va, name );
while( (arg=va_arg(va, wchar_t *) )!= 0 )
{
al_push( &ev.arguments, arg );
}
va_end( va );
event_fire( &ev );
}

View File

@@ -164,7 +164,8 @@ const wchar_t *event_get_desc( event_t *e );
/**
Fire a generic event with the specified name
*/
void event_fire_generic(const wchar_t *name);
#define event_fire_generic( ... ) event_fire_generic_internal( __VA_ARGS__, (void *)0 )
void event_fire_generic_internal(const wchar_t *name,...);
#endif

123
exec.c
View File

@@ -53,6 +53,11 @@
*/
#define FD_ERROR _( L"An error occurred while redirecting file descriptor %d" )
/**
file descriptor redirection error message
*/
#define WRITE_ERROR _( L"An error occurred while writing output" )
/**
file redirection error message
*/
@@ -92,6 +97,18 @@ static array_list_t *open_fds=0;
static int set_child_group( job_t *j, process_t *p, int print_errors );
static void exec_write_and_exit( int fd, char *buff, size_t count, int status )
{
if( write_loop(fd, buff, count) == -1 )
{
debug( 0, WRITE_ERROR);
wperror( L"write" );
exit(status);
}
exit( status );
}
void exec_close( int fd )
{
int i;
@@ -442,7 +459,41 @@ static int setup_child_process( job_t *j, process_t *p )
return res;
}
/**
Returns the interpreter for the specified script. Returns 0 if file
is not a script with a shebang. This function leaks memory on every
call. Only use it in the execve error handler which calls exit
right afterwards, anyway.
*/
static wchar_t *get_interpreter( wchar_t *file )
{
string_buffer_t sb;
FILE *fp = wfopen( file, "r" );
sb_init( &sb );
wchar_t *res = 0;
if( fp )
{
while( 1 )
{
wint_t ch = getwc( fp );
if( ch == WEOF )
break;
if( ch == L'\n' )
break;
sb_append_char( &sb, (wchar_t)ch );
}
}
res = (wchar_t *)sb.buff;
if( !wcsncmp( L"#! /", res, 4 ) )
return res+3;
if( !wcsncmp( L"#!/", res, 3 ) )
return res+2;
return 0;
}
/**
This function is executed by the child process created by a call to
@@ -503,7 +554,7 @@ static void launch_process( process_t *p )
p->argv = res;
p->actual_cmd = L"/bin/sh";
res_real = wcsv2strv( (const wchar_t **) res);
res_real = wcsv2strv( (const wchar_t **) res);
execve ( wcs2str(p->actual_cmd),
res_real,
@@ -549,22 +600,22 @@ static void launch_process( process_t *p )
if( arg_max > 0 )
{
sb_format_size( &sz2, ARG_MAX );
sb_format_size( &sz2, arg_max );
debug( 0,
L"The total size of the argument and environment lists (%ls) exceeds the system limit of %ls.",
L"The total size of the argument and environment lists (%ls) exceeds the operating system limit of %ls.",
(wchar_t *)sz1.buff,
(wchar_t *)sz2.buff);
}
else
{
debug( 0,
L"The total size of the argument and environment lists (%ls) exceeds the system limit.",
L"The total size of the argument and environment lists (%ls) exceeds the operating system limit.",
(wchar_t *)sz1.buff);
}
debug( 0,
L"Please try running the command again with fewer arguments.");
L"Try running the command again with fewer arguments.");
sb_destroy( &sz1 );
sb_destroy( &sz2 );
@@ -573,10 +624,42 @@ static void launch_process( process_t *p )
break;
}
case ENOEXEC:
{
wperror(L"exec");
debug(0, L"The file '%ls' is marked as an executable but could not be run by the operating system.", p->actual_cmd);
exit(STATUS_EXEC_FAIL);
}
case ENOENT:
{
wchar_t *interpreter = get_interpreter( p->actual_cmd );
if( interpreter && waccess( interpreter, X_OK ) )
{
debug(0, L"The file '%ls' specified the interpreter '%ls', which is not an executable command.", p->actual_cmd, interpreter );
}
else
{
debug(0, L"The file '%ls' or a script or ELF interpreter does not exist, or a shared library needed for file or interpreter cannot be found.", p->actual_cmd);
}
exit(STATUS_EXEC_FAIL);
}
case ENOMEM:
{
debug(0, L"Out of memory");
exit(STATUS_EXEC_FAIL);
}
default:
{
debug(0, L"The file '%ls' is marked as an executable but could not be run by the operating system.", p->actual_cmd);
exit(STATUS_EXEC_FAIL);
wperror(L"exec");
// debug(0, L"The file '%ls' is marked as an executable but could not be run by the operating system.", p->actual_cmd);
exit(STATUS_EXEC_FAIL);
}
}
@@ -830,6 +913,9 @@ static pid_t exec_fork()
}
/**
Perform output from builtins
*/
static void do_builtin_io( wchar_t *out, wchar_t *err )
{
@@ -1357,15 +1443,17 @@ void exec( job_t *j )
if( pid == 0 )
{
/*
This is the child process. Write out the contents of the pipeline.
*/
p->pid = getpid();
setup_child_process( j, p );
write( io_buffer->fd,
io_buffer->param2.out_buffer->buff,
io_buffer->param2.out_buffer->used );
exit( status );
exec_write_and_exit(io_buffer->fd,
io_buffer->param2.out_buffer->buff,
io_buffer->param2.out_buffer->used,
status);
}
else
{
@@ -1411,10 +1499,10 @@ void exec( job_t *j )
p->pid = getpid();
setup_child_process( j, p );
write( 1,
input_redirect->param2.out_buffer->buff,
input_redirect->param2.out_buffer->used );
exit( 0 );
exec_write_and_exit( 1,
input_redirect->param2.out_buffer->buff,
input_redirect->param2.out_buffer->used,
0);
}
else
{
@@ -1487,7 +1575,8 @@ void exec( job_t *j )
{
debug( 3, L"Set status of %ls to %d using short circut", j->command, p->status );
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?(!p->status):p->status );
int status = proc_format_status(p->status);
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?(!status):status );
}
break;
}

View File

@@ -109,11 +109,11 @@ parameter expansion.
/**
Characters which make a string unclean if they are the first
character of the string. See \c is_clean().
character of the string. See \c expand_is_clean().
*/
#define UNCLEAN_FIRST L"~%"
/**
Unclean characters. See \c is_clean().
Unclean characters. See \c expand_is_clean().
*/
#define UNCLEAN L"$*?\\\"'({})"
@@ -764,7 +764,9 @@ void expand_variable_error( const wchar_t *token, int token_pos, int error_pos )
}
}
/**
Parse an array slicing specification
*/
static int parse_slice( wchar_t *in, wchar_t **end_ptr, array_list_t *idx )
{
@@ -1517,6 +1519,11 @@ static void remove_internal_separator( const void *s, int conv )
*out++ = conv?L'*':ANY_STRING;
break;
case ANY_STRING_RECURSIVE:
in++;
*out++ = conv?L'*':ANY_STRING_RECURSIVE;
break;
default:
*out++ = *in++;
}

View File

@@ -58,6 +58,10 @@
Use unencoded private-use keycodes for internal characters
*/
#define EXPAND_RESERVED 0xf000
/**
End of range reserved for expand
*/
#define EXPAND_RESERVED_END 0xf000f
enum
{

View File

@@ -1183,5 +1183,12 @@ long sysconf(int name)
return -1;
}
#endif
#ifndef HAVE_NAN
double nan(char *tagp)
{
return 0.0/0.0;
}
#endif

View File

@@ -54,9 +54,18 @@ typedef char tputs_arg_t;
#endif
#ifndef HAVE_WINSIZE
/**
Structure used to get the size of a terminal window
*/
struct winsize
{
/**
Number of rows
*/
unsigned short ws_row;
/**
Number of columns
*/
unsigned short ws_col;
}
;
@@ -400,17 +409,35 @@ extern int _nl_msg_cat_cntr;
#ifndef HAVE_KILLPG
/**
Send specified signal to specified process group.
*/
int killpg( int pgr, int sig );
#endif
#ifndef HAVE_WORKING_GETOPT_LONG
/**
Struct describing a long getopt option
*/
struct option
{
/**
Name of option
*/
const char *name;
/**
Flag
*/
int has_arg;
/**
Flag
*/
int *flag;
/**
Return value
*/
int val;
}
;
@@ -442,4 +469,9 @@ long sysconf(int name);
#endif
#ifndef HAVE_NAN
double nan(char *tagp);
#endif
#endif

3
fish.c
View File

@@ -106,10 +106,9 @@ static int read_init()
}
/*
/**
Parse the argument list, return the index of the first non-switch
arguments.
*/
static int fish_parse_opt( int argc, char **argv, char **cmd_ptr )
{

View File

@@ -16,7 +16,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/** \file main.c
/** \file fish_indent.c
The fish_indent proegram.
*/
@@ -48,13 +48,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define GETOPT_STRING "hvi"
void read_file( FILE *f, string_buffer_t *b )
/**
Read the entire contents of a file into the specified string_Buffer_t
*/
static void read_file( FILE *f, string_buffer_t *b )
{
while( 1 )
{
errno=0;
wint_t c = fgetwc( f );
if( c == WEOF )
{
if( errno )
{
wperror(L"fgetwc");
exit(1);
}
break;
}
@@ -62,6 +72,9 @@ void read_file( FILE *f, string_buffer_t *b )
}
}
/**
Insert the specified number of tabe into the output buffer
*/
static void insert_tabs( string_buffer_t *out, int indent )
{
int i;
@@ -73,6 +86,9 @@ static void insert_tabs( string_buffer_t *out, int indent )
}
/**
Indent the specified input
*/
static int indent( string_buffer_t *out, wchar_t *in, int flags )
{
tokenizer tok;
@@ -217,7 +233,12 @@ static int indent( string_buffer_t *out, wchar_t *in, int flags )
return res;
}
wchar_t *trim( wchar_t *in )
/**
Remove any prefix and suffix newlines from the specified
string. Does not allocete a new string, edits the string in place
and returns a pointer somewhere into the string.
*/
static wchar_t *trim( wchar_t *in )
{
wchar_t *end;
@@ -245,7 +266,9 @@ wchar_t *trim( wchar_t *in )
}
/**
The main mathod. Run the program.
*/
int main( int argc, char **argv )
{
string_buffer_t sb_in;

View File

@@ -351,7 +351,7 @@ static int pager_buffered_writer( char c)
*/
static void pager_flush()
{
write( 1, pager_buffer->buff, pager_buffer->used );
write_loop( 1, pager_buffer->buff, pager_buffer->used );
pager_buffer->used = 0;
}

View File

@@ -750,6 +750,9 @@ static void test_expand()
}
/**
Test path functions
*/
static void test_path()
{
say( L"Testing path functions" );

View File

@@ -521,7 +521,7 @@ static void load_or_save( int save)
if( save )
{
write( c.fd, SAVE_MSG, strlen(SAVE_MSG) );
write_loop( c.fd, SAVE_MSG, strlen(SAVE_MSG) );
enqueue_all( &c );
}
else

View File

@@ -41,9 +41,9 @@
typedef struct
{
/** Function definition */
wchar_t *cmd;
wchar_t *definition;
/** Function description */
wchar_t *desc;
wchar_t *description;
/**
File where this function was defined
*/
@@ -52,7 +52,10 @@ typedef struct
Line where definition started
*/
int definition_offset;
/**
List of all named arguments for this function
*/
array_list_t *named_arguments;
@@ -61,6 +64,10 @@ typedef struct
*/
int is_autoload;
/**
Set to non-zero if invoking this function shadows the variables
of the underlying function.
*/
int shadows;
}
function_internal_data_t;
@@ -155,6 +162,9 @@ void function_init()
&hash_wcs_cmp );
}
/**
Clear specified value, but not key
*/
static void clear_entry( void *key, void *value )
{
halloc_free( value );
@@ -180,7 +190,7 @@ void function_add( function_data_t *data )
d = halloc( 0, sizeof( function_internal_data_t ) );
d->definition_offset = parse_util_lineno( parser_get_buffer(), current_block->tok_pos )-1;
d->cmd = halloc_wcsdup( d, data->definition );
d->definition = halloc_wcsdup( d, data->definition );
if( data->named_arguments )
{
@@ -192,9 +202,9 @@ void function_add( function_data_t *data )
}
}
cmd_end = d->cmd + wcslen(d->cmd)-1;
cmd_end = d->definition + wcslen(d->definition)-1;
d->desc = data->description?halloc_wcsdup( d, data->description ):0;
d->description = data->description?halloc_wcsdup( d, data->description ):0;
d->definition_file = intern(reader_current_filename());
d->is_autoload = is_autoload;
d->shadows = data->shadows;
@@ -266,7 +276,7 @@ const wchar_t *function_get_definition( const wchar_t *name )
data = (function_internal_data_t *)hash_get( &function, name );
if( data == 0 )
return 0;
return data->cmd;
return data->definition;
}
array_list_t *function_get_named_arguments( const wchar_t *name )
@@ -307,7 +317,7 @@ const wchar_t *function_get_desc( const wchar_t *name )
if( data == 0 )
return 0;
return _(data->desc);
return _(data->description);
}
void function_set_desc( const wchar_t *name, const wchar_t *desc )
@@ -322,7 +332,7 @@ void function_set_desc( const wchar_t *name, const wchar_t *desc )
if( data == 0 )
return;
data->desc = halloc_wcsdup( data, desc );
data->description = halloc_wcsdup( data, desc );
}
/**
@@ -331,6 +341,10 @@ void function_set_desc( const wchar_t *name, const wchar_t *desc )
static int al_contains_str( array_list_t *list, const wchar_t * str )
{
int i;
CHECK( list, 0 );
CHECK( str, 0 );
for( i=0; i<al_get_count( list ); i++ )
{
if( wcscmp( al_get( list, i ), str) == 0 )

View File

@@ -15,15 +15,38 @@
#include "util.h"
/**
Structure describing a function
*/
Structure describing a function. This is used by the parser to
store data on a function while parsing it. It is not used
internally to store functions, the function_internal_data_t
structure is used for that purpose. Parhaps these two should be
merged.
*/
typedef struct function_data
{
/**
Name of function
*/
wchar_t *name;
/**
Description of function
*/
wchar_t *description;
/**
Function definition
*/
wchar_t *definition;
/**
List of all event handlers for this function
*/
array_list_t *events;
/**
List of all named arguments for this function
*/
array_list_t *named_arguments;
/**
Set to non-zero if invoking this function shadows the variables
of the underlying function.
*/
int shadows;
}
function_data_t;

View File

@@ -78,6 +78,9 @@ typedef struct halloc
}
halloc_t;
/**
Allign the specified pointer
*/
static char *align_ptr( char *in )
{
unsigned long step = maxi(sizeof(double),sizeof(void *));
@@ -87,6 +90,9 @@ static char *align_ptr( char *in )
return (char *)long_out;
}
/**
Allign specifies size_t
*/
static size_t align_sz( size_t in )
{
size_t step = maxi(sizeof(double),sizeof(void *));

View File

@@ -530,6 +530,20 @@ static void highlight_param( const wchar_t * buff,
}
}
static int has_expand_reserved( wchar_t *str )
{
while( *str )
{
if( *str >= EXPAND_RESERVED &&
*str <= EXPAND_RESERVED_END )
{
return 1;
}
str++;
}
return 0;
}
void highlight_shell( wchar_t * buff,
int *color,
@@ -636,10 +650,10 @@ void highlight_shell( wchar_t * buff,
Command. First check that the command actually exists.
*/
cmd = expand_one( context,
wcsdup(tok_last( &tok )),
EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES);
wcsdup(tok_last( &tok )),
EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES);
if( cmd == 0 )
if( (cmd == 0) || has_expand_reserved( cmd ) )
{
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_ERROR;
}
@@ -698,7 +712,7 @@ void highlight_shell( wchar_t * buff,
}
tok_set_pos( &tok, mark );
}
if( !is_subcommand )
{
wchar_t *tmp;

View File

@@ -252,6 +252,9 @@ static wchar_t *history_unescape_newlines( wchar_t *in )
return (wchar_t *)out->buff;
}
/**
Check if the specified item is already loaded
*/
static int item_is_new( history_mode_t *m, void *d )
{
char *begin = (char *)d;
@@ -409,6 +412,9 @@ static void history_destroy_mode( history_mode_t *m )
}
/**
Free all memory used by specified mistory mode
*/
static void history_destroy_mode_wrapper( void *n, history_mode_t *m )
{
halloc_free( m );

25
input.c
View File

@@ -232,6 +232,9 @@ static const wchar_t code_arr[] =
*/
static array_list_t mappings = {0,0,0};
/**
List of all terminfo mappings
*/
static array_list_t *terminfo_mappings = 0;
@@ -240,28 +243,18 @@ static array_list_t *terminfo_mappings = 0;
*/
static int is_init = 0;
/**
Initialize terminfo.
*/
static void input_terminfo_init();
/**
Deallocate memory used by terminfo. Or at least try to. Terminfo leaks.
*/
static void input_terminfo_destroy();
/**
Returns the function description for the given function code.
*/
/*
static const wchar_t *input_get_desc( wchar_t c )
{
int i;
for( i = 0; i<(sizeof( code_arr )/sizeof(wchar_t)) ; i++ )
{
if( c == code_arr[i] )
{
return desc_arr[i];
}
}
return 0;
}
*/
void input_mapping_add( const wchar_t *sequence,
const wchar_t *command )

19
input.h
View File

@@ -89,19 +89,26 @@ void input_unreadch( wint_t ch );
/**
Add a key mapping from the specified sequence
Add a key mapping from the specified sequence to the specified command
\param mode the name of the mapping mode to add this mapping to
\param s the sequence
\param d a description of the sequence
\param cmd an input function that will be run whenever the key sequence occurs
\param sequence the sequence to bind
\param command an input function that will be run whenever the key sequence occurs
*/
void input_mapping_add( const wchar_t *sequence, const wchar_t *cmd );
void input_mapping_add( const wchar_t *sequence, const wchar_t *command );
/**
Insert all mapping names into the specified array_list_t
*/
void input_mapping_get_names( array_list_t *list );
/**
Erase binding for specified key sequence
*/
int input_mapping_erase( const wchar_t *sequence );
/**
Return the command bound to the specified key sequence
*/
const wchar_t *input_mapping_get( const wchar_t *sequence );
/**

View File

@@ -28,7 +28,7 @@ Implementation file for the low level input library
/**
Time in milliseconds to wait for another byte to be available for
reading after \x1b is read before assuming that escape key was
reading after \\x1b is read before assuming that escape key was
pressed, and not an escape sequence.
*/
#define WAIT_ON_ESCAPE 10

3
io.h
View File

@@ -44,6 +44,9 @@ typedef struct io_data
} param2
;
/**
Set to true if this is an input io redirection
*/
int is_input;
/** Pointer to the next IO redirection */

View File

@@ -94,6 +94,17 @@ license. Read the source code of the library for more information.
*/
#define GETOPT_STRING "tfimdalhv"
/**
Error message if system call goes wrong.
*/
#define ERROR_SYSTEM "%s: Could not execute command \"%s\"\n"
/**
Exit code if system call goes wrong.
*/
#define STATUS_ERROR_SYSTEM 1
/**
All types of input and output possible
*/
@@ -470,7 +481,7 @@ static char *get_description( const char *mimetype )
int fd;
struct stat st;
char *contents;
char *start=0, *stop=0;
char *start=0, *stop=0, *best_start=0;
if( !start_re )
{
@@ -583,6 +594,7 @@ static char *get_description( const char *mimetype )
while( !regexec(start_re, start, 1, match, 0) )
{
int new_w = match[0].rm_eo - match[0].rm_so;
start += match[0].rm_eo;
if( new_w > w )
{
@@ -591,12 +603,13 @@ static char *get_description( const char *mimetype )
match, so we use the new match
*/
w=new_w;
start += match[0].rm_eo;
best_start = start;
}
}
if( w != -1 )
{
start = best_start;
if( !regexec(stop_re, start, 1, match, 0) )
{
/*
@@ -665,7 +678,7 @@ static char *get_action( const char *mimetype )
Core 3) we also test some common subclassings.
*/
if( strncmp( mimetype, "text/", 5 ) == 0 )
if( strncmp( mimetype, "text/plain", 10) != 0 && strncmp( mimetype, "text/", 5 ) == 0 )
return get_action( "text/plain" );
return 0;
@@ -1125,8 +1138,12 @@ static void launch( char *filter, array_list_t *files, int fileno )
writer( '&' );
writer( '\0' );
// fprintf( stderr, "mimedb: %s\n", launch_buff );
system( launch_buff );
if( system( launch_buff ) == -1 )
{
fprintf( stderr, _( ERROR_SYSTEM ), MIMEDB, launch_buff );
exit(STATUS_ERROR_SYSTEM);
}
break;
}
}

View File

@@ -121,6 +121,9 @@ static char *writestr_buff = 0;
static int (*out)(char c) = &writeb_internal;
/**
Name of terminal
*/
static wchar_t *current_term = 0;
@@ -359,7 +362,7 @@ void set_color( int c, int c2 )
*/
static int writeb_internal( char c )
{
write( 1, &c, 1 );
write_loop( 1, &c, 1 );
return 0;
}

View File

@@ -73,7 +73,9 @@ enum
void set_color( int c, int c2 );
/**
Write specified multibyte string
*/
#define writembs( mbs ) \
{ \
char *tmp = mbs; \
@@ -144,10 +146,18 @@ int writeb( tputs_arg_t b );
void output_set_writer( int (*writer)(char) );
//typedef int (*func_ptr_t)(char);
/**
Return the current output writer
*/
int (*output_get_writer())(char) ;
/**
Set the terminal name
*/
void output_set_term( wchar_t *term );
/**
Return the terminal name
*/
wchar_t *output_get_term();
#endif

View File

@@ -436,6 +436,7 @@ typedef struct
/**
Return the current number of block nestings
*/
/*
static int block_count( block_t *b )
{
@@ -443,7 +444,7 @@ static int block_count( block_t *b )
return 0;
return( block_count(b->outer)+1);
}
*/
void parser_push_block( int type )
{
@@ -2086,6 +2087,7 @@ static int parse_job( process_t *p,
current_tokenizer_pos=tmp;
job_set_flag( j, JOB_SKIP, 1 );
event_fire_generic(L"fish_command_not_found", (wchar_t *)al_get( args, 0 ) );
proc_set_last_status( err==ENOENT?STATUS_UNKNOWN_COMMAND:STATUS_NOT_EXECUTABLE );
}
}

10
path.h
View File

@@ -9,6 +9,9 @@
#ifndef FISH_PATH_H
#define FISH_PATH_H
/**
Return value for path_cdpath_get when locatied a rotten symlink
*/
#define EROTTEN 1
/**
@@ -48,6 +51,13 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd );
*/
wchar_t *path_get_cdpath( void *context, wchar_t *in );
/**
Remove doulbe slashes and trailing slashes from a path,
e.g. transform foo//bar/ into foo/bar.
The returned string is allocated using the specified halloc
context.
*/
wchar_t *path_make_canonical( void *context, const wchar_t *path );

View File

@@ -5,18 +5,26 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "print_help.h"
#define CMD_LEN 1024
#define HELP_ERR "Could not show help message\n"
void print_help( char *c, int fd )
{
char cmd[ CMD_LEN];
int printed = snprintf( cmd, CMD_LEN, "fish -c '__fish_print_help %s >&%d'", c, fd );
if( printed < CMD_LEN )
system( cmd );
{
if( (system( cmd ) == -1) )
{
write_loop(2, HELP_ERR, strlen(HELP_ERR));
}
}
}

57
proc.c
View File

@@ -343,30 +343,35 @@ static void mark_process_status( job_t *j,
process_t *p,
int status )
{
p->status = status;
// debug( 0, L"Process %ls %ls", p->argv[0], WIFSTOPPED (status)?L"stopped":(WIFEXITED( status )?L"exited":(WIFSIGNALED( status )?L"signaled to exit":L"BLARGH")) );
p->status = status;
if (WIFSTOPPED (status))
{
p->stopped = 1;
}
else
else if (WIFSIGNALED(status) || WIFEXITED(status))
{
p->completed = 1;
}
else
{
ssize_t ignore;
if (( !WIFEXITED( status ) ) &&
(! WIFSIGNALED( status )) )
{
/* This should never be reached */
char mess[MESS_SIZE];
snprintf( mess,
MESS_SIZE,
"Process %d exited abnormally\n",
(int) p->pid );
write( 2, mess, strlen(mess) );
}
/* This should never be reached */
p->completed = 1;
char mess[MESS_SIZE];
snprintf( mess,
MESS_SIZE,
"Process %d exited abnormally\n",
(int) p->pid );
/*
If write fails, do nothing. We're in a signal handlers error
handler. If things aren't working properly, it's safer to
give up.
*/
ignore = write( 2, mess, strlen(mess) );
}
}
@@ -1106,7 +1111,7 @@ void job_continue (job_t *j, int cont)
while( p->next )
p = p->next;
if( WIFEXITED( p->status ) )
if( WIFEXITED( p->status ) || WIFSIGNALED(p->status))
{
/*
Mark process status only if we are in the foreground
@@ -1114,8 +1119,9 @@ void job_continue (job_t *j, int cont)
*/
if( p->pid )
{
debug( 3, L"Set status of %ls to %d", j->command, WEXITSTATUS(p->status) );
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?(WEXITSTATUS(p->status)?0:1):WEXITSTATUS(p->status) );
int status = proc_format_status(p->status);
proc_set_last_status( job_get_flag( j, JOB_NEGATE )?!status:status);
}
}
}
@@ -1140,6 +1146,21 @@ void job_continue (job_t *j, int cont)
}
int proc_format_status(int status)
{
if( WIFSIGNALED( status ) )
{
return 128+WTERMSIG(status);
}
else if( WIFEXITED( status ) )
{
return WEXITSTATUS(status);
}
return status;
}
void proc_sanity_check()
{
job_t *j;

6
proc.h
View File

@@ -485,4 +485,10 @@ void proc_push_interactive( int value );
*/
void proc_pop_interactive();
/**
Format an exit status code as returned by e.g. wait into a fish exit code number as accepted by proc_set_last_status.
*/
int proc_format_status(int status) ;
#endif

368
reader.c
View File

@@ -117,6 +117,9 @@ commence.
*/
#define DEFAULT_PROMPT L"echo \"$USER@\"; hostname|cut -d . -f 1; echo \" \"; pwd; printf '> ';"
/**
The name of the function that prints the fish prompt
*/
#define PROMPT_FUNCTION_NAME L"fish_prompt"
/**
@@ -132,15 +135,40 @@ commence.
*/
#define READAHEAD_MAX 256
/**
A mode for calling the reader_kill function. In this mode, the new
string is appended to the current contents of the kill buffer.
*/
#define KILL_APPEND 0
/**
A mode for calling the reader_kill function. In this mode, the new
string is prepended to the current contents of the kill buffer.
*/
#define KILL_PREPEND 1
/**
History search mode. This value means that no search is currently
performed.
*/
#define NO_SEARCH 0
/**
History search mode. This value means that we are perforing a line
history search.
*/
#define LINE_SEARCH 1
/**
History search mode. This value means that we are perforing a token
history search.
*/
#define TOKEN_SEARCH 2
/**
History search mode. This value means we are searching backwards.
*/
#define SEARCH_BACKWARD 0
/**
History search mode. This value means we are searching forwards.
*/
#define SEARCH_FORWARD 1
/**
@@ -155,6 +183,9 @@ typedef struct reader_data
*/
wchar_t *buff;
/**
The representation of the current screen contents
*/
screen_t screen;
/**
@@ -252,6 +283,9 @@ typedef struct reader_data
*/
int prev_end_loop;
/**
The current contents of the top item in the kill ring.
*/
string_buffer_t kill_item;
/**
@@ -509,6 +543,9 @@ static int check_size()
}
/**
Compare two completion entrys
*/
static int completion_cmp( const void *a, const void *b )
{
completion_t *c= *((completion_t **)a);
@@ -518,6 +555,9 @@ static int completion_cmp( const void *a, const void *b )
}
/**
Sort an array_list_t containing compltion_t structs.
*/
static void sort_completion_list( array_list_t *comp )
{
qsort( comp->arr,
@@ -949,9 +989,8 @@ static void get_param( wchar_t *cmd,
string.
\param val the string to insert
\param is_complete Whether this completion is the whole string or
just the common prefix of several completions. If the former, end by
printing a space (and an end quote if the parameter is quoted).
\param flags A union of all flags describing the completion to insert. See the completion_t struct for more information on possible values.
*/
static void completion_insert( const wchar_t *val, int flags )
{
@@ -959,7 +998,10 @@ static void completion_insert( const wchar_t *val, int flags )
wchar_t quote;
int add_space = !(flags & COMPLETE_NO_SPACE);
int do_replace = (flags&COMPLETE_NO_CASE);
int do_replace = (flags & COMPLETE_NO_CASE);
int do_escape = !(flags & COMPLETE_DONT_ESCAPE);
// debug( 0, L"Insert completion %ls with flags %d", val, flags);
if( do_replace )
{
@@ -978,11 +1020,18 @@ static void completion_insert( const wchar_t *val, int flags )
sb_init( &sb );
sb_append_substring( &sb, data->buff, begin - data->buff );
escaped = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
sb_append( &sb, escaped );
free( escaped );
if( do_escape )
{
escaped = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
sb_append( &sb, escaped );
free( escaped );
}
else
{
sb_append( &sb, val );
}
if( add_space )
{
sb_append( &sb, L" " );
@@ -1000,52 +1049,60 @@ static void completion_insert( const wchar_t *val, int flags )
else
{
get_param( data->buff,
if( do_escape )
{
get_param( data->buff,
data->buff_pos,
&quote,
0, 0, 0 );
if( quote == L'\0' )
{
replaced = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
if( quote == L'\0' )
{
replaced = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
}
else
{
int unescapable=0;
const wchar_t *pin;
wchar_t *pout;
replaced = pout =
malloc( sizeof(wchar_t)*(wcslen(val) + 1) );
for( pin=val; *pin; pin++ )
{
switch( *pin )
{
case L'\n':
case L'\t':
case L'\b':
case L'\r':
unescapable=1;
break;
default:
*pout++ = *pin;
break;
}
}
if( unescapable )
{
free( replaced );
wchar_t *tmp = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
replaced = wcsdupcat( L" ", tmp );
free( tmp);
replaced[0]=quote;
}
else
*pout = 0;
}
}
else
{
int unescapable=0;
const wchar_t *pin;
wchar_t *pout;
replaced = pout =
malloc( sizeof(wchar_t)*(wcslen(val) + 1) );
for( pin=val; *pin; pin++ )
{
switch( *pin )
{
case L'\n':
case L'\t':
case L'\b':
case L'\r':
unescapable=1;
break;
default:
*pout++ = *pin;
break;
}
}
if( unescapable )
{
free( replaced );
wchar_t *tmp = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
replaced = wcsdupcat( L" ", tmp );
free( tmp);
replaced[0]=quote;
}
else
*pout = 0;
replaced = wcsdup(val);
}
if( insert_str( replaced ) )
{
/*
@@ -1054,8 +1111,8 @@ static void completion_insert( const wchar_t *val, int flags )
if( add_space )
{
if( (quote) &&
(data->buff[data->buff_pos] != quote ) )
if( quote &&
(data->buff[data->buff_pos] != quote ) )
{
/*
This is a quoted parameter, first print a quote
@@ -1225,7 +1282,7 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp )
io_buffer_destroy( in);
}
/*
/**
Flash the screen. This function only changed the color of the
current line, since the flash_screen sequnce is rather painful to
look at in most terminal emulators.
@@ -1253,6 +1310,46 @@ static void reader_flash()
}
/**
Characters that may not be part of a token that is to be replaced
by a case insensitive completion.
*/
#define REPLACE_UNCLEAN L"$*?({})"
/**
Check if the specified string can be replaced by a case insensitive
complition with the specified flags.
Advanced tokens like those containing {}-style expansion can not at
the moment be replaced, other than if the new token is already an
exact replacement, e.g. if the COMPLETE_DONT_ESCAPE flag is set.
*/
int reader_can_replace( const wchar_t *in, int flags )
{
const wchar_t * str = in;
if( flags & COMPLETE_DONT_ESCAPE )
{
return 1;
}
CHECK( in, 1 );
/*
Test characters that have a special meaning in any character position
*/
while( *str )
{
if( wcschr( REPLACE_UNCLEAN, *str ) )
return 0;
str++;
}
return 1;
}
/**
Handle the list of completions. This means the following:
@@ -1288,24 +1385,39 @@ static int handle_completions( array_list_t *comp )
context = halloc( 0, 0 );
tok = halloc_wcsndup( context, begin, end-begin );
/*
Check trivial cases
*/
switch( al_get_count( comp ) )
{
/*
No suitable completions found, flash screen and retur
*/
case 0:
{
reader_flash();
done = 1;
break;
}
/*
Exactly one suitable completion found - insert it
*/
case 1:
{
completion_t *c = (completion_t *)al_get( comp, 0 );
if( !(c->flags & COMPLETE_NO_CASE) || expand_is_clean( tok ) )
/*
If this is a replacement completion, check
that we know how to replace it, e.g. that
the token doesn't contain evil operators
like {}
*/
if( !(c->flags & COMPLETE_NO_CASE) || reader_can_replace( tok, c->flags ) )
{
completion_insert( c->completion,
c->flags );
c->flags );
}
done = 1;
len = 1;
@@ -1316,12 +1428,17 @@ static int handle_completions( array_list_t *comp )
if( !done )
{
/*
Try to find something to insert whith the correct case
*/
for( i=0; i<al_get_count( comp ); i++ )
{
completion_t *c = (completion_t *)al_get( comp, i );
int new_len;
/*
Ignore case insensitive completions for now
*/
if( c->flags & COMPLETE_NO_CASE )
continue;
@@ -1340,6 +1457,9 @@ static int handle_completions( array_list_t *comp )
}
}
/*
If we found something to insert, do it.
*/
if( len > 0 )
{
if( count > 1 )
@@ -1351,53 +1471,62 @@ static int handle_completions( array_list_t *comp )
}
}
if( !done && base == 0 )
{
/*
Try to find something to insert ignoring case
*/
if( begin )
{
if( expand_is_clean( tok ) )
{
int offset = wcslen( tok );
count = 0;
for( i=0; i<al_get_count( comp ); i++ )
{
completion_t *c = (completion_t *)al_get( comp, i );
int new_len;
if( !(c->flags & COMPLETE_NO_CASE) )
continue;
int offset = wcslen( tok );
count++;
count = 0;
for( i=0; i<al_get_count( comp ); i++ )
{
completion_t *c = (completion_t *)al_get( comp, i );
int new_len;
if( base )
{
new_len = offset + comp_ilen( base+offset, c->completion+offset );
len = new_len < len ? new_len: len;
}
else
{
base = wcsdup( c->completion );
len = wcslen( base );
flags = c->flags;
}
if( !(c->flags & COMPLETE_NO_CASE) )
continue;
if( !reader_can_replace( tok, c->flags ) )
{
len=0;
break;
}
if( len > offset )
{
if( count > 1 )
flags = flags | COMPLETE_NO_SPACE;
count++;
base[len]=L'\0';
completion_insert( base, flags );
done = 1;
if( base )
{
new_len = offset + comp_ilen( base+offset, c->completion+offset );
len = new_len < len ? new_len: len;
}
else
{
base = wcsdup( c->completion );
len = wcslen( base );
flags = c->flags;
}
}
if( len > offset )
{
if( count > 1 )
flags = flags | COMPLETE_NO_SPACE;
base[len]=L'\0';
completion_insert( base, flags );
done = 1;
}
}
}
@@ -1448,9 +1577,9 @@ static int handle_completions( array_list_t *comp )
wchar_t quote;
get_param( data->buff, data->buff_pos, &quote, 0, 0, 0 );
is_quoted = (quote != L'\0');
write(1, "\n", 1 );
write_loop(1, "\n", 1 );
run_pager( prefix, is_quoted, comp );
}
@@ -1486,11 +1615,52 @@ static void reader_interactive_init()
not enable it for us.
*/
/* Loop until we are in the foreground. */
while (tcgetpgrp( 0 ) != shell_pgid)
/*
Check if we are in control of the terminal, so that we don't do
semi-expensive things like reset signal handlers unless we
really have to, which we often don't.
*/
if (tcgetpgrp( 0 ) != shell_pgid)
{
killpg( shell_pgid, SIGTTIN);
int block_count = 0;
int i;
/*
Bummer, we are not in control of the terminal. Stop until
parent has given us control of it. Stopping in fish is a bit
of a challange, what with all the signal fidgeting, we need
to reset a bunch of signal state, making this coda a but
unobvious.
In theory, reseting signal handlers could cause us to miss
signal deliveries. In practice, this code should only be run
suring startup, when we're not waiting for any signals.
*/
while (signal_is_blocked())
{
signal_unblock();
block_count++;
}
signal_reset_handlers();
/*
Ok, signal handlers are taken out of the picture. Stop ourself in a loop
until we are in control of the terminal.
*/
while (tcgetpgrp( 0 ) != shell_pgid)
{
killpg( shell_pgid, SIGTTIN);
}
signal_set_handlers();
for( i=0; i<block_count; i++ )
{
signal_block();
}
}
/* Put ourselves in our own process group. */
shell_pgid = getpid ();
@@ -1801,7 +1971,7 @@ static void handle_token_history( int forward, int reset )
\param dir Direction to move/erase. 0 means move left, 1 means move right.
\param erase Whether to erase the characters along the way or only move past them.
\param do_append if erase is true, this flag decides if the new kill item should be appended to the previous kill item.
\param new if the new kill item should be appended to the previous kill item or not.
*/
static void move_word( int dir, int erase, int new )
{
@@ -1970,6 +2140,10 @@ void reader_set_buffer( wchar_t *b, int p )
data->buff_pos=l;
}
data->search_mode = NO_SEARCH;
sb_clear( &data->search_buff );
history_reset();
reader_super_highlight_me_plenty( data->buff_pos,
0 );
reader_repaint_needed();
@@ -2228,7 +2402,7 @@ static void handle_end_loop()
if( !reader_exit_forced() && !data->prev_end_loop && job_count && !is_breakpoint )
{
writestr(_( L"There are stopped jobs\n" ));
writestr(_( L"There are stopped jobs. A second attempt to exit will enforce their termination.\n" ));
reader_exit( 0, 0 );
data->prev_end_loop=1;
@@ -2517,7 +2691,7 @@ wchar_t *reader_readline()
case R_REPAINT:
{
exec_prompt();
write( 1, "\r", 1 );
write_loop( 1, "\r", 1 );
s_reset( &data->screen, 0 );
reader_repaint();
break;
@@ -2563,9 +2737,11 @@ wchar_t *reader_readline()
comp = al_halloc( 0 );
data->complete_func( buffcpy, comp );
sort_completion_list( comp );
remove_duplicates( comp );
free( buffcpy );
comp_empty = handle_completions( comp );

View File

@@ -86,6 +86,10 @@ static int try_sequence( char *seq, wchar_t *str )
return 0;
}
/**
Returns the number of columns left until the next tab stop, given
the current cursor postion.
*/
static int next_tab_stop( int in )
{
/*
@@ -333,7 +337,7 @@ static void s_check_status( screen_t *s)
*/
int prev_line = s->actual_cursor[1];
write( 1, "\r", 1 );
write_loop( 1, "\r", 1 );
s_reset( s, 0 );
s->actual_cursor[1] = prev_line;
}
@@ -752,13 +756,16 @@ static void s_update( screen_t *scr, wchar_t *prompt )
if( output.used )
{
write( 1, output.buff, output.used );
write_loop( 1, output.buff, output.used );
}
b_destroy( &output );
}
/**
Returns non-zero if we are using a dumb terminal.
*/
static int is_dumb()
{
return ( !cursor_up || !cursor_down || !cursor_left || !cursor_right );
@@ -797,9 +804,9 @@ void s_write( screen_t *s,
char *prompt_narrow = wcs2str( prompt );
char *buffer_narrow = wcs2str( b );
write( 1, "\r", 1 );
write( 1, prompt_narrow, strlen( prompt_narrow ) );
write( 1, buffer_narrow, strlen( buffer_narrow ) );
write_loop( 1, "\r", 1 );
write_loop( 1, prompt_narrow, strlen( prompt_narrow ) );
write_loop( 1, buffer_narrow, strlen( buffer_narrow ) );
free( prompt_narrow );
free( buffer_narrow );
@@ -931,7 +938,7 @@ void s_reset( screen_t *s, int reset_cursor )
This should prevent reseting the cursor position during the
next repaint.
*/
write( 1, "\r", 1 );
write_loop( 1, "\r", 1 );
s->actual_cursor[1] = prev_line;
}
fstat( 1, &s->prev_buff_1 );

View File

@@ -2,9 +2,13 @@
The screen library allows the interactive reader to write its
output to screen efficiently by keeping an inetrnal representation
of the current screen contents and trying to find the most
of the current screen contents and trying to find a reasonably
efficient way for transforming that to the desired screen content.
*/
The current implementation is less smart than ncurses allows
and can not for example move blocks of text around to handle text
insertion.
*/
#ifndef FISH_SCREEN_H
#define FISH_SCREEN_H
@@ -13,7 +17,7 @@
*/
typedef struct
{
/*
/**
The internal representation of the desired screen contents.
*/
array_list_t desired;
@@ -35,7 +39,7 @@ typedef struct
*/
string_buffer_t actual_prompt;
/*
/**
The actual width of the screen at the time of the last screen
write.
*/

View File

@@ -0,0 +1,27 @@
#
# Command specific completions for the adduser command.
# These completions where generated from the commands
# man page by the make_completions.py script, but may
# have been hand edited since.
#
complete -c adduser -l conf --description 'Specify config file" -r
complete -c adduser -l disabled-login --description 'Do not run passwd to set the password'
complete -c adduser -l disabled-password --description 'Like --disabled-login, but logins are still possible (for example using SSH RSA keys) but not using password authentication'
complete -c adduser -l force-badname --description 'By default, user and group names are checked against the configurable regular expression NAME_REGEX (or NAME_REGEX if --system is specified) specified in the configuration file'
complete -c adduser -l gecos --description 'Set the gecos field for the new entry generated' -r
complete -c adduser -l gid --description 'When creating a group, this option forces the new groupid to be the given number' -r
complete -c adduser -l group --description 'When combined with --system, a group with the same name and ID as the system user is created'
complete -c adduser -l help --description 'Display brief instructions'
complete -c adduser -l home --description 'Use specified directory as the user's home directory' -x -a '(__fish_complete_directories)'
complete -c adduser -l shell --description 'Use shell as the user's login shell, rather than the default specified by the configuration file' -x -a '(cat /etc/shells)'
complete -c adduser -l ingroup --description 'Add the new user to GROUP instead of a usergroup or the default group defined by USERS_GID in the configuration file' -x -a '(cat /etc/group|cut -d : -f 1)'
complete -c adduser -l no-create-home --description 'Do not create the home directory, even if it doesn't exist'
complete -c adduser -l quiet --description 'Suppress informational messages, only show warnings and errors'
complete -c adduser -l debug --description 'Be verbose, most useful if you want to nail down a problem with adduser'
complete -c adduser -l system --description 'Create a system user or group'
complete -c adduser -l uid --description 'Force the new userid to be the given number' -r
complete -c adduser -l firstuid --description 'Override the first uid in the range that the uid is chosen from (overrides FIRST_UID specified in the configuration file)' -r
complete -c adduser -l lastuid --description 'ID Override the last uid in the range that the uid is chosen from ( LAST_UID )' -r
complete -c adduser -l add_extra_groups --description 'Add new user to extra groups defined in the configuration file'
complete -c adduser -l version --description 'Display version and copyright information'

View File

@@ -0,0 +1,19 @@
#
# Command specific completions for the badblocks command.
# These completions where generated from the commands
# man page by the make_completions.py script, and
# have been hand edited since.
#
complete -c badblocks -s b --description 'Block-size Specify the size of blocks in bytes'
complete -c badblocks -s c --description 'Number of blocks is the number of blocks which are tested at a time'
complete -c badblocks -s f --description 'Normally, badblocks will refuse to do a read/write or a nondestructive test on a device which is mounted, since either can cause the system to potentially crash and/or damage the filesys tem even if it is mounted read-only'
complete -c badblocks -s i --description 'Input_file Read a list of already existing known bad blocks'
complete -c badblocks -s o --description 'Output_file Write the list of bad blocks to the specified file'
complete -c badblocks -s p --description 'Repeat scanning the disk until there are no new blocks discovered in specified number of consecutive scans of the disk'
complete -c badblocks -s t --description 'Test_pattern Specify a test pattern to be read (and written) to disk blocks'
complete -c badblocks -s n --description 'Use non-destructive read-write mode'
complete -c badblocks -s s --description 'Show the progress of the scan by writing out the block numbers as they are checked'
complete -c badblocks -s v --description 'Verbose mode'
complete -c badblocks -s w --description 'Use write-mode test'
complete -c badblocks -s X --description 'Internal flag only to be used by e2fsck(8) and mke2fs(8)'

View File

@@ -0,0 +1,94 @@
# completions for effectv 0.3.9 or similiar
complete -c effectv -f -a "QuarkTV" -d "Dissolves moving objects"
complete -c effectv -f -a "FireTV" -d "Clips incoming objects and burns it"
complete -c effectv -f -a "BurningTV" -d "Burns incoming objects"
complete -c effectv -f -a "RadioacTV" -d "Brightens moving objects and blurs it"
complete -c effectv -f -a "StreakTV" -d "Makes 8 afterimages"
complete -c effectv -f -a "BaltanTV" -d "Makes afterimages longer"
complete -c effectv -f -a "1DTV" -d "Grabs a horizontal line from video every 1/30 sec"
complete -c effectv -f -a "DotTV" -d "Converts the picture into a set of dots"
complete -c effectv -f -a "MosaicTV" -d "Censors incoming objects"
complete -c effectv -f -a "PuzzleTV" -d "Scrambles the picture"
complete -c effectv -f -a "PredatorTV" -d "Makes incoming objects invisible visibly"
complete -c effectv -f -a "SpiralTV" -d "Spiraling effect"
complete -c effectv -f -a "SimuraTV" -d "Color distortion and image mirroring"
complete -c effectv -f -a "EdgeTV" -d "Detects edge and display it like good old computer way"
complete -c effectv -f -a "ShagadelicTV" -d "Go back to swinging '60s"
complete -c effectv -f -a "NoiseTV" -d "Makes incoming objects noisy"
complete -c effectv -f -a "AgingTV" -d "Film-aging effect"
complete -c effectv -f -a "LifeTV" -d "Conway's life game with video input interaction"
complete -c effectv -f -a "TransFormTV" -d "Performs positional translations on images"
complete -c effectv -f -a "SparkTV" -d "Spark effect"
complete -c effectv -f -a "warpTV" -d "Goo'ing effect"
complete -c effectv -f -a "HolographicTV" -d "Holographic vision seen in Star Wars"
complete -c effectv -f -a "cycleTV" -d "Color cycling effect"
complete -c effectv -f -a "RippleTV" -d "Ripple mark effect"
complete -c effectv -f -a "DiceTV" -d "A 'dicing' effect"
complete -c effectv -f -a "VertigoTV" -d "Alpha blending with zoomed and rotated images"
complete -c effectv -f -a "DeinterlaceTV" -d "Deinterlacing video images"
complete -c effectv -f -a "nervousTV" -d "Realtime frame shuffling effect"
complete -c effectv -f -a "RndmTV" -d "Gives you a noisy picture in color or B/W"
complete -c effectv -f -a "RevTV" -d "Waveform monitor effect"
complete -c effectv -f -a "RandomDotStereoTV" -d "Makes random dot stereo stream from video input"
complete -c effectv -f -a "LensTV" -d "Old school demo lens effect"
complete -c effectv -f -a "DiffTV" -d "Hilights interframe differences"
complete -c effectv -f -a "BrokenTV" -d "Simulates broken TV"
complete -c effectv -f -a "WarholTV" -d "Hommage to Andy Warhol"
complete -c effectv -f -a "MatrixTV" -d "A Matrix like effect"
complete -c effectv -f -a "PUPTV" -d "Comes from \"Partial UPdate\", certain part of image is updated at a frame"
complete -c effectv -f -a "ChameleonTV" -d "Vanishing into the wall..."
complete -c effectv -o help -d "show usage information"
complete -c effectv -o device -r -d "[FILE] use device FILE for video4linux (default is /dev/video0)"
complete -c effectv -o channel -r -d "[CHANNEL] channel number of video source (default is 0)"
set __fish_effectv_norms "ntsc
pal
secam
pal-nc
pal-m
pal-n
ntsc-jp"
complete -c effectv -o norm -x -a '(echo $__fish_effectv_norms)' -d "[NORM] set video norm (default is ntsc)"
set __fish_effectv_freqs "argentina
australia
australia-optus
canada-cable
china-bcast
europe-east
europe-west
france
ireland
italy
japan-bcast
japan-cable
newzealand
southafrica
us-bcast
us-cable
us-cable-hrc"
complete -c effectv -o freqtab -x -a '(echo $__fish_effectv_freqs)' -d "[FREQUTAB] set frequency table"
complete -c effectv -o fullscreen -d "enable fullscreen mode"
complete -c effectv -o hardware -d "use direct video memory (if possible)"
complete -c effectv -o doublebuffer -d "enable double buffering mode (if possible)"
complete -c effectv -o fps -d "show frames/sec"
complete -c effectv -o size -x -a "WxH" -d "[WxH] set the size of capturing image to WxH pixels (default 320x240)"
complete -c effectv -o geometry -x -a "WxH" -d "[WxH] set the size of screen to WxH pixels"
complete -c effectv -o scale -x -d "[NUMBER] set the scaling. When the capturing size is set, the screen size is scaled by NUMBER"
complete -c effectv -o autoplay -x -d "[FRAMES] change effects automatically every FRAMES"
set __fish_effectv_palettes "grey
rgb24
rgb555
rgb565
yuv410p
yuv411p
yuv420p
yuv422
yuv422p"
complete -c effectv -o palette -x -a '(echo $__fish_effectv_palettes)' -d "[PALETTE] set the PALETTE of capturing device"
complete -c effectv -o vloopback -r -d "[FILE] use device FILE for output of vloopback device"

View File

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

226
share/completions/git.fish Normal file
View File

@@ -0,0 +1,226 @@
# fish completion for git
function __fish_git_branches
git branch --no-color -a 2>/dev/null | sed 's/^..//'
end
function __fish_git_tags
git tag
end
function __fish_git_heads
__fish_git_branches
__fish_git_tags
end
function __fish_git_remotes
git remote
end
function __fish_git_ranges
set from (commandline -ot | perl -ne 'my @parts = split(/\.\./); print $parts[0]')
set to (commandline -ot | perl -ne 'my @parts = split(/\.\./); print $parts[1]')
if [ "$from" = "" ]
__fish_git_branches
return 0
end
for from_ref in (__fish_git_heads | grep -e "$from")
for to_ref in (__fish_git_heads | grep -e "$to")
printf "%s..%s\n" $from_ref $to_ref
end
end
end
function __fish_git_needs_command
set cmd (commandline -opc)
if [ (count $cmd) -eq 1 -a $cmd[1] = 'git' ]
return 0
end
return 1
end
function __fish_git_using_command
set cmd (commandline -opc)
if [ (count $cmd) -gt 1 ]
if [ $argv[1] = $cmd[2] ]
return 0
end
end
return 1
end
# general options
complete -f -c git -n 'not __fish_git_needs_command' -l help -d 'Display the manual of a git command'
#### fetch
complete -f -c git -n '__fish_git_needs_command' -a fetch -d 'Download objects and refs from another repository'
complete -f -c git -n '__fish_git_using_command fetch' -a '(__fish_git_remotes)' -d 'Remote'
complete -f -c git -n '__fish_git_using_command fetch' -s q -l quiet -d 'Be quiet'
complete -f -c git -n '__fish_git_using_command fetch' -s v -l verbose -d 'Be verbose'
complete -f -c git -n '__fish_git_using_command fetch' -s a -l append -d 'Append ref names and object names'
# TODO --upload-pack
complete -f -c git -n '__fish_git_using_command fetch' -s f -l force -d 'Force update of local branches'
# TODO other options
### remote
complete -f -c git -n '__fish_git_needs_command' -a remote -d 'Manage set of tracked repositories'
complete -f -c git -n '__fish_git_using_command remote' -a '(__fish_git_remotes)'
complete -f -c git -n '__fish_git_using_command remote' -s v -l verbose -d 'Be verbose'
complete -f -c git -n '__fish_git_using_command remote' -a add -d 'Adds a new remote'
complete -f -c git -n '__fish_git_using_command remote' -a rm -d 'Removes a remote'
complete -f -c git -n '__fish_git_using_command remote' -a show -d 'Shows a remote'
complete -f -c git -n '__fish_git_using_command remote' -a prune -d 'Deletes all stale tracking branches'
complete -f -c git -n '__fish_git_using_command remote' -a update -d 'Fetches updates'
# TODO options
### show
complete -f -c git -n '__fish_git_needs_command' -a show -d 'Shows the last commit of a branch'
complete -f -c git -n '__fish_git_using_command show' -a '(__fish_git_branches)' -d 'Branch'
# TODO options
### show-branch
complete -f -c git -n '__fish_git_needs_command' -a show-branch -d 'Shows the commits on branches'
complete -f -c git -n '__fish_git_using_command show-branch' -a '(__fish_git_heads)' --description 'Branch'
# TODO options
### add
complete -c git -n '__fish_git_needs_command' -a add -d 'Add file contents to the index'
# TODO options
### checkout
complete -f -c git -n '__fish_git_needs_command' -a checkout -d 'Checkout and switch to a branch'
complete -c git -n '__fish_git_using_command checkout' -a '(__fish_git_branches)' --description 'Branch'
complete -c git -n '__fish_git_using_command checkout' -a '(__fish_git_tags)' --description 'Tag'
complete -c git -n '__fish_git_using_command checkout' -s b -d 'Create a new branch'
# TODO options
### apply
complete -f -c git -n '__fish_git_needs_command' -a apply -d 'Apply a patch on a git index file and a working tree'
# TODO options
### archive
complete -f -c git -n '__fish_git_needs_command' -a archive -d 'Create an archive of files from a named tree'
# TODO options
### bisect
complete -f -c git -n '__fish_git_needs_command' -a bisect -d 'Find the change that introduced a bug by binary search'
# TODO options
### branch
complete -f -c git -n '__fish_git_needs_command' -a branch -d 'List, create, or delete branches'
complete -f -c git -n '__fish_git_using_command branch' -a '(__fish_git_branches)' -d 'Branch'
complete -f -c git -n '__fish_git_using_command branch' -s d -d 'Delete Branch'
complete -f -c git -n '__fish_git_using_command branch' -s D -d 'Force deletion of branch'
complete -f -c git -n '__fish_git_using_command branch' -s m -d 'Rename branch'
complete -f -c git -n '__fish_git_using_command branch' -s M -d 'Force renaming branch'
complete -f -c git -n '__fish_git_using_command branch' -s a -d 'Lists both local and remote branches'
### cherry-pick
complete -f -c git -n '__fish_git_needs_command' -a cherry-pick -d 'Apply the change introduced by an existing commit'
complete -f -c git -n '__fish_git_using_command cherry-pick' -a '(__fish_git_branches)' -d 'Branch'
# TODO options
### clone
complete -f -c git -n '__fish_git_needs_command' -a clone -d 'Clone a repository into a new directory'
# TODO options
### commit
complete -c git -n '__fish_git_needs_command' -a commit -d 'Record changes to the repository'
complete -c git -n '__fish_git_using_command commit' -l amend -d 'Amend the log message of the last commit'
# TODO options
### diff
complete -c git -n '__fish_git_needs_command' -a diff -d 'Show changes between commits, commit and working tree, etc'
complete -c git -n '__fish_git_using_command diff' -a '(__fish_git_ranges)' -d 'Branch'
complete -c git -n '__fish_git_using_command diff' -l cached -d 'Show diff of changes in the index'
# TODO options
### grep
complete -c git -n '__fish_git_needs_command' -a grep -d 'Print lines matching a pattern'
# TODO options
### init
complete -f -c git -n '__fish_git_needs_command' -a init -d 'Create an empty git repository or reinitialize an existing one'
# TODO options
### log
complete -c git -n '__fish_git_needs_command' -a log -d 'Show commit logs'
complete -c git -n '__fish_git_using_command log' -a '(__fish_git_heads) (__fish_git_ranges)' -d 'Branch'
complete -f -c git -n '__fish_git_using_command log' -l pretty -a 'oneline short medium full fuller email raw format:'
# TODO options
### merge
complete -f -c git -n '__fish_git_needs_command' -a merge -d 'Join two or more development histories together'
complete -f -c git -n '__fish_git_using_command merge' -a '(__fish_git_branches)' -d 'Branch'
complete -f -c git -n '__fish_git_using_command merge' -l commit -d "Autocommit the merge"
complete -f -c git -n '__fish_git_using_command merge' -l no-commit -d "Don't autocommit the merge"
complete -f -c git -n '__fish_git_using_command merge' -l stat -d "Show diffstat of the merge"
complete -f -c git -n '__fish_git_using_command merge' -s n -l no-stat -d "Don't show diffstat of the merge"
complete -f -c git -n '__fish_git_using_command merge' -l squash -d "Squash changes from other branch as a single commit"
complete -f -c git -n '__fish_git_using_command merge' -l no-squash -d "Don't squash changes"
complete -f -c git -n '__fish_git_using_command merge' -l ff -d "Don't generate a merge commit if merge is fast forward"
complete -f -c git -n '__fish_git_using_command merge' -l no-ff -d "Generate a merge commit even if merge is fast forward"
# TODO options
### mv
complete -c git -n '__fish_git_needs_command' -a mv -d 'Move or rename a file, a directory, or a symlink'
# TODO options
### prune
complete -f -c git -n '__fish_git_needs_command' -a prune -d 'Prune all unreachable objects from the object database'
# TODO options
### pull
complete -f -c git -n '__fish_git_needs_command' -a pull -d 'Fetch from and merge with another repository or a local branch'
# TODO options
### push
complete -f -c git -n '__fish_git_needs_command' -a push -d 'Update remote refs along with associated objects'
# TODO options
### rebase
complete -f -c git -n '__fish_git_needs_command' -a rebase -d 'Forward-port local commits to the updated upstream head'
complete -f -c git -n '__fish_git_using_command rebase' -a '(__fish_git_branches)' -d 'Branch'
# TODO options
### reset
complete -c git -n '__fish_git_needs_command' -a reset -d 'Reset current HEAD to the specified state'
complete -f -c git -n '__fish_git_using_command reset' -l hard -d 'Reset files in working directory'
complete -c git -n '__fish_git_using_command reset' -a '(__fish_git_branches)'
# TODO options
### revert
complete -f -c git -n '__fish_git_needs_command' -a revert -d 'Revert an existing commit'
# TODO options
### rm
complete -c git -n '__fish_git_needs_command' -a rm -d 'Remove files from the working tree and from the index'
# TODO options
### status
complete -f -c git -n '__fish_git_needs_command' -a status -d 'Show the working tree status'
# TODO options
### tag
complete -f -c git -n '__fish_git_needs_command' -a tag -d 'Create, list, delete or verify a tag object signed with GPG'
complete -f -c git -n '__fish_git_using_command tag; and __fish_not_contain_opt -s d; and __fish_not_contain_opt -s v; and test (count (commandline -opc | grep -v -e \'^-\')) -eq 3' -a '(__fish_git_branches)' -d 'Branch'
complete -f -c git -n '__fish_git_using_command tag' -s d -d 'Remove a tag'
complete -f -c git -n '__fish_git_using_command tag' -s v -d 'Verify signature of a tag'
complete -f -c git -n '__fish_git_using_command tag' -s f -d 'Force overwriting exising tag'
complete -f -c git -n '__fish_git_using_command tag' -s s -d 'Make a GPG-signed tag'
complete -f -c git -n '__fish_contains_opt -s d' -a '(__fish_git_tags)' -d 'Tag'
complete -f -c git -n '__fish_contains_opt -s v' -a '(__fish_git_tags)' -d 'Tag'
# TODO options
### config
complete -f -c git -n '__fish_git_needs_command' -a config -d 'Set and read git configuration variables'
# TODO options
### format-patch
complete -f -c git -n '__fish_git_needs_command' -a format-patch -d 'Generate patch series to send upstream'
complete -f -c git -n '__fish_git_using_command format-patch' -a '(__fish_git_branches)' -d 'Branch'
### aliases (custom user-definer commands)
complete -c git -n '__fish_git_needs_command' -a '(git config --get-regexp alias | sed -e "s/^alias\.\(\S\+\).*/\1/")' -d 'Alias (user-defined command)'

View File

@@ -0,0 +1,12 @@
#
# Command specific completions for the groupadd command.
# These completions where generated from the commands
# man page by the make_completions.py script, but may
# have been hand edited since.
#
complete -c groupadd -s f --description 'Exit with success status if the specified group already exists'
complete -c groupadd -s g --description 'The numerical value of the group\'s ID'
complete -c groupadd -s h -l help --description 'Display help message and exit'
complete -c groupadd -s K --description 'Overrides default key/value pairs from /etc/login'
complete -c groupadd -s o --description 'This option permits to add group with non-unique GID'

View File

@@ -0,0 +1,18 @@
function __fish_invoke_rcd_has_service
set tokens (commandline -opc)
if [ (count $tokens) -eq 2 ]
return 0
else
return 1
end
end
complete -f -c invoke-rc.d -n 'not __fish_invoke_rcd_has_service' -a '(__fish_print_debian_services)'
complete -f -c invoke-rc.d -n '__fish_invoke_rcd_has_service' -a 'start' -d 'Start the service'
complete -f -c invoke-rc.d -n '__fish_invoke_rcd_has_service' -a 'stop' -d 'Stop the service'
complete -f -c invoke-rc.d -n '__fish_invoke_rcd_has_service' -a 'restart' -d 'Restart the service'
complete -f -c invoke-rc.d -n '__fish_invoke_rcd_has_service' -a 'reload' -d 'Reload Configuration'
complete -f -c invoke-rc.d -n '__fish_invoke_rcd_has_service' -a 'force-reload' -d 'Force reloading configuration'
complete -f -c invoke-rc.d -n '__fish_invoke_rcd_has_service' -a 'status' -d 'Print the status of the service'

27
share/completions/m4.fish Normal file
View File

@@ -0,0 +1,27 @@
#
# Command specific completions for the m4 command.
# These completions where generated from the commands
# man page by the make_completions.py script, but may
# have been hand edited since.
#
complete -c m4 -l help --description 'Display this help and exit'
complete -c m4 -l version --description 'Output version information and exit'
complete -c m4 -s E -l fatal-warnings --description 'Once: warnings become errors, twice: stop execution at first error'
complete -c m4 -s i -l interactive --description 'Unbuffer output, ignore interrupts'
complete -c m4 -s P -l prefix-builtins --description 'Force a \'m4_\' prefix to all builtins'
complete -c m4 -s Q -l quiet -l silent --description 'Suppress some warnings for builtins'
complete -c m4 -l warn-macro-sequence --description 'Warn if macro definition matches REGEXP, default \$\({[^}]*}\|[0-9][0-9]+\)'
complete -c m4 -s D -l define --description 'Define NAME as having VALUE, or empty'
complete -c m4 -s I -l include --description 'Append DIRECTORY to include path'
complete -c m4 -s s -l synclines --description 'Generate \'#line NUM "FILE"\' lines'
complete -c m4 -s U -l undefine --description 'Undefine NAME'
complete -c m4 -s G -l traditional --description 'Suppress all GNU extensions'
complete -c m4 -s H -l hashsize --description 'Set symbol lookup hash table size [509]'
complete -c m4 -s L -l nesting-limit --description 'Change artificial nesting limit [1024]'
complete -c m4 -s F -l freeze-state --description 'Produce a frozen state on FILE at end'
complete -c m4 -s R -l reload-state --description 'Reload a frozen state from FILE at start'
complete -c m4 -s d -l debug --description 'Set debug level (no FLAGS implies \'aeq\')'
complete -c m4 -l debugfile --description 'Redirect debug and trace output'
complete -c m4 -s l -l arglength --description 'Restrict macro tracing size'
complete -c m4 -s t -l trace --description 'Trace NAME when it is defined'

View File

@@ -0,0 +1,25 @@
# NetCat completions for fish
# By James Stanley
complete -r -c nc -d "Remote hostname" -a "(__fish_print_hostnames)"
complete -r -c nc -s c -d "Same as -e, but use /bin/sh"
complete -r -c nc -s e -d "Program to execute after connection"
complete -c nc -s b -d "Allow broadcasts"
complete -r -c nc -s g -d "Source-routing hop points"
complete -r -c nc -s G -d "Source-routing pointer"
complete -c nc -s h -d "Show help"
complete -r -c nc -s i -d "Delay interval for lines sent, ports scaned"
complete -c nc -s k -d "Set keepalive option"
complete -c nc -s l -d "Listen mode, acts as a server"
complete -c nc -s n -d "Numeric-only IP addresses, no DNS"
complete -r -c nc -s o -d "Hex dump of traffic"
complete -r -c nc -s p -d "Local port number"
complete -c nc -s r -d "Randomize local and remote ports"
complete -r -c nc -s q -d "Quit after EOF on stdin and delay of secs"
complete -r -c nc -s s -d "Local source address"
complete -c nc -s t -d "Answer Telnet negotiation"
complete -c nc -s u -d "UDP Mode"
complete -c nc -s v -d "Verbose, use twice to be more verbose"
complete -r -c nc -s w -d "Timeout for connects and final net reads"
complete -r -c nc -s x -d "Set Type of Service"
complete -c nc -s z -d "No I/O - used for scanning"

View File

@@ -0,0 +1,35 @@
# completions for quilt version 0.46 or similiar
complete -c quilt -s h -d "show help"
complete -c quilt -l version -d "show version"
complete -c quilt -l quiltrc -r --no-file -d "specify the file to Run Control file to use"
complete -c quilt -l trace -r --no-file -d "Runs the command in bash trace mode (-x). For internal debugging"
complete -c quilt -a add -r -d "Add one or more files to the topmost or named patch"
complete -c quilt -a annotate -r -d "Print an annotated listing of the specified file"
complete -c quilt -a applied -r -d "Print a list of applied patches"
complete -c quilt -a delete -r -d "Remove the specified or topmost patch from the series file"
complete -c quilt -a diff -r -d "Produces a diff of the specified file(s) in the topmost or specified patch"
complete -c quilt -a edit -r -d "Edit the specified file(s) in $EDITOR"
complete -c quilt -a files -r -d "Print the list of files that the topmost or specified patch changes"
complete -c quilt -a fold -r -d "Integrate the patch read from standard input into the topmost patch"
complete -c quilt -a fork -r --no-file -d " Fork the topmost patch"
complete -c quilt -a graph -r --no-file -d "Generate a dot(1) directed graph showing the dependencies between applied patches"
complete -c quilt -a grep -r --no-file -d "Grep through the source files, recursively, skipping patches and quilt meta-information"
complete -c quilt -a header -r --no-file -d " Print or change the header of the topmost or specified patch"
complete -c quilt -a import -r -d "Import external patches"
complete -c quilt -a mail -r -d "Create mail messages from all patches in the series file, and either store or send them"
complete -c quilt -a new -r -d "Create a new patch with the specified file name, and insert it after the topmost patch"
complete -c quilt -a next -r -d "Print the name of the next patch after the specified or topmost patch in the series file"
complete -c quilt -a patches -r -d "Print the list of patches that modify the specified file"
complete -c quilt -a pop -r -d "Remove patch(es) from the stack of applied patches"
complete -c quilt -a previous -r -d "Print the name of the previous patch before the specified or topmost patch in the series file"
complete -c quilt -a push -r -d "Apply patch(es) from the series file"
complete -c quilt -a refresh -r -d "Refreshes the specified patch, or the topmost patch by default"
complete -c quilt -a remove -r -d "Remove one or more files from the topmost or named patch"
complete -c quilt -a rename -r -d "Rename the topmost or named patch"
complete -c quilt -a series -r --no-file -d "Print the names of all patches in the series file"
complete -c quilt -a setup -r -d " Initializes a source tree from an rpm spec file or a quilt series file"
complete -c quilt -a snapshot -r --no-file -d " Take a snapshot of the current working state"
complete -c quilt -a top -d "Print the name of the topmost patch on the current stack of applied patches"
complete -c quilt -a unapplied -r -d "Print a list of patches that are not applied, or all patches that follow the specified patch in the series file"
complete -c quilt -a upgrade -d "Upgrade the meta-data in a working tree from an old version of quilt to the current version"

View File

@@ -12,6 +12,9 @@ complete -x -c ssh -d Hostname -a "
#Prepend any username specified in the completion to the hostname
echo (commandline -ct)|sed -ne 's/\(.*@\).*/\1/p'
)(__fish_print_hostnames)
"
complete -x -c ssh -d User -a "
(__fish_print_users)@
"

View File

@@ -0,0 +1,22 @@
#
# Command specific completions for the useradd command.
# These completions where generated from the commands
# man page by the make_completions.py script, but may
# have been hand edited since.
#
complete -c useradd -s c -l comment --description 'A comment about this user' -r
complete -c useradd -s d -l home --description 'Home directory for the new user' -x -a '(__fish_complete_directories)'
complete -c useradd -s G -l groups --description 'Supplementary groups' -xa '(__fish_append , (cat /etc/group|cut -d : -f 1))'
complete -c useradd -s h -l help --description 'Display help message and exit'
complete -c useradd -s m -l create-home --description 'The user's home directory will be created if it does not exist'
complete -c useradd -s n --description 'A group having the same name as the user being added to the system will be created by default (when -g is not specified)'
complete -c useradd -s K -l key --description 'Overrides default key/value pairs from /etc/login'
complete -c useradd -s o -l non-unique --description 'Allow the creation of a user account with a duplicate (non-unique) UID'
complete -c useradd -s p -l password --description 'The encrypted password, as returned by crypt(3)' -r
complete -c useradd -s u -l uid --description 'The numerical value of the user's ID' -r
complete -c useradd -s b -l base-dir --description 'The initial path prefix for a new user's home directory' -r -a '(__fish_complete_directories)'
complete -c useradd -s e -l expiredate --description 'The date on which the user account is disabled' -r
complete -c useradd -s f -l inactive --description 'The number of days after a password has expired before the account will be disabled' -r
complete -c useradd -s g -l gid --description 'The group name or ID for a new user's initial group' -x -a '(cat /etc/group|cut -d : -f 1,3|sed -e "s/:/\n/")'
complete -c useradd -s s -l shell --description 'Name of the new user's login shell' -x -a '(cat /etc/shells)'

View File

@@ -0,0 +1,34 @@
#
# Command specific completions for the wesnoth command.
# These completions where generated from the commands
# man page by the make_completions.py script, and
# have been hand edited since.
#
complete -c wesnoth -l bpp --description 'Number sets BitsPerPixel value'
complete -c wesnoth -l compress --description '<infile> <outfile> compresses a savefile (infile) that is in text WML format into binary WML format (outfile)'
complete -c wesnoth -s d -l debug --description 'Shows extra debugging information and enables additional command mode options in-game'
complete -c wesnoth -l decompress --description '<infile> <outfile> decompresses a savefile (infile) that is in binary WML format into text WML format (outfile)'
complete -c wesnoth -s f -l fullscreen --description 'Runs the game in full screen mode'
complete -c wesnoth -l fps --description 'Displays the number of frames per second the game is currently running at, in a corner of the screen'
complete -c wesnoth -s h -l help --description 'Displays a summary of command line options to standard output, and exits'
complete -c wesnoth -l load --description 'Savegame loads the file savegame from the standard save game directory'
complete -c wesnoth -l log-error -l log-warning -l log-info --description 'Set the severity level of debugging domains'
complete -c wesnoth -l multiplayer --description 'Runs a multiplayer game'
complete -c wesnoth -l nocache --description 'Disables caching of game data'
complete -c wesnoth -l nosound --description 'Runs the game without sounds and music'
complete -c wesnoth -l path --description 'Prints the name of the game data directory and exits'
complete -c wesnoth -s r -l resolution --description 'XxY sets the screen resolution'
complete -c wesnoth -s t -l test --description 'Runs the game in a small test scenario'
complete -c wesnoth -s v -l version --description 'Shows the version number and exits'
complete -c wesnoth -s w -l windowed --description 'Runs the game in windowed mode'
complete -c wesnoth -l no-delay --description 'Runs the game without any delays for graphic benchmarking'
complete -c wesnoth -l exit-at-end --description 'Exits once the scenario is over, without displaying victory/defeat dialog which requires the user to click OK'
#complete -c wesnoth -l algorithm<number> --description 'Selects a non-standard algorithm to be used by the AI controller for this side'
#complete -c wesnoth -l controller<number> --description 'Selects the controller for this side'
complete -c wesnoth -l era --description 'Use this option to play in the selected era instead of the "Default" era'
complete -c wesnoth -l nogui --description 'Runs the game without the GUI'
complete -c wesnoth -l parm<number> --description 'Sets additional parameters for this side'
complete -c wesnoth -l scenario --description 'Selects a multiplayer scenario'
complete -c wesnoth -l side<number> --description 'Selects a faction of the current era for this side'
complete -c wesnoth -l turns --description 'Sets the number of turns for the chosen scenario'

View File

@@ -1,4 +1,4 @@
function __fish_complete_users --description "Print a list of local users, with the real user name as a description"
cat /etc/passwd | sed -e "s/^\([^:]*\):[^:]*:[^:]*:[^:]*:\([^:]*\):.*/\1\t\2/"
cat /etc/passwd | grep -ve '^#' | sed -e 's/^\([^:]*\):[^:]*:[^:]*:[^:]*:\([^:]*\):.*$/\1'\t'\2/' ^/dev/null
end

View File

@@ -7,8 +7,6 @@ function __fish_complete_vi -d "Compleletions for vi and its aliases"
set -l cmds -c $argv
complete $cmds -x -a "(__fish_complete_mime 'text/*')"
# vim
if test -n "$is_vim"
@@ -20,10 +18,6 @@ function __fish_complete_vi -d "Compleletions for vi and its aliases"
# +[num] : Position the cursor on line number
# +/{pat} : Position the cursor on the first occurence of {pat}
# +{command} : Execute Ex command after the first file has been read
# Complete gzip-compressed files
complete $cmds -x -a "(__fish_complete_mime 'application/x-gzip')"
complete $cmds -s c -r --description 'Execute Ex command after the first file has been read'
complete $cmds -s S -r --description 'Source file after the first file has been read'
complete $cmds -l cmd -r --description 'Execute Ex command before loading any vimrc'

View File

@@ -146,13 +146,17 @@ function __fish_config_interactive -d "Initializations that should be performed
# Print a greeting
#
if set -q fish_greeting
switch $fish_greeting
case ''
# If variable is empty, don't print anything, saves us a fork
if functions -q fish_greeting
fish_greeting
else
if set -q fish_greeting
switch $fish_greeting
case ''
# If variable is empty, don't print anything, saves us a fork
case '*'
echo $fish_greeting
case '*'
echo $fish_greeting
end
end
end
@@ -195,19 +199,39 @@ function __fish_config_interactive -d "Initializations that should be performed
complete -x -p "/etc/init.d/*" -a restart --description 'Stop and then start service'
complete -x -p "/etc/init.d/*" -a reload --description 'Reload service configuration'
# Make sure some key bindings are set
if not set -q fish_key_bindings
set -U fish_key_bindings fish_default_key_bindings
end
eval $fish_key_bindings ^/dev/null
# Reload keybindings when binding variable change
function __fish_reload_key_bindings -d "Reload keybindings when binding variable change" --on-variable fish_key_bindings
eval $fish_key_bindings ^/dev/null
end
# Load keybindings
__fish_reload_key_bindings
# Repaint screen when window changes size
function __fish_winch_handler --on-signal winch
commandline -f repaint
end
# If the ubuntu command-not-found package can be found, add a handler for it
# First check in /usr/lib, this is where modern Ubuntus place this command
if test -f /usr/lib/command-not-found
function fish_command_not_found_handler --on-event fish_command_not_found
/usr/lib/command-not-found $argv
end
else
# Ubuntu Feisty places this command in the regular path instead
if type -p command-not-found >/dev/null
function fish_command_not_found_handler --on-event fish_command_not_found
command-not-found $argv
end
end
end
end

View File

@@ -0,0 +1,22 @@
# Prints the current git branch, if any
function __fish_git_branch_prompt
set gitdir (git rev-parse --git-dir 2>/dev/null)
if [ -z $gitdir ]
return 0
end
set branch (git-symbolic-ref HEAD 2>/dev/null| cut -d / -f 3)
# check for rebase, bisect, etc
# TODO
# no branch, print hash of HEAD
if [ -z $branch ]
set branch (git log HEAD\^..HEAD --pretty=format:%h 2>/dev/null)
end
if [ ! -z $branch ]
echo " ($branch) "
end
end

View File

@@ -0,0 +1,7 @@
function __fish_print_debian_services --description 'Prints services installed'
for service in /etc/init.d/*
if [ -x $service ]
basename $service
end
end
end

View File

@@ -12,5 +12,10 @@ function __fish_print_hostnames -d "Print a list of known hostnames"
# Print hosts with known ssh keys
cat ~/.ssh/known_hosts{,2} ^/dev/null|cut -d ' ' -f 1| cut -d , -f 1
# Print hosts from ssh configuration file
if [ -e ~/.ssh/config ]
grep '^ *Host' ~/.ssh/config | grep -v '[*?]' | cut -d ' ' -f 2
end
end

View File

@@ -14,7 +14,7 @@ function cd --description "Change directory"
set -l previous $PWD
if test $argv[1] = - ^/dev/null
if test $__fish_cd_direction = next ^/dev/null
if test "$__fish_cd_direction" = next ^/dev/null
nextd
else
prevd
@@ -25,7 +25,7 @@ function cd --description "Change directory"
builtin cd $argv[1]
set -l cd_status $status
if test $cd_status = 0 -a $PWD != $previous
if test $cd_status = 0 -a "$PWD" != "$previous"
set -g dirprev $dirprev $previous
set -e dirnext
set -g __fish_cd_direction prev

View File

@@ -20,7 +20,7 @@ if command ls --version 1>/dev/null 2>/dev/null
else
# BSD, OS X and a few more support colors through the -G switch instead
if command ls / -G 1>/dev/null 2>/dev/null
if command ls -G / 1>/dev/null 2>/dev/null
function ls --description "List contents of directory"
command ls -G $argv
end

View File

@@ -9,13 +9,15 @@ if not test (uname) = Darwin
if count $argv >/dev/null
switch $argv[1]
case -h --h --he --hel --help
__fish_print_help dirh
__fish_print_help open
return 0
end
end
if type -f xdg-open >/dev/null
xdg-open $argv
for i in $argv
xdg-open $i
end
else
mimedb -l -- $argv
end

View File

@@ -2,8 +2,8 @@
if test (uname) = Darwin
function prompt_pwd --description "Print the current working directory, shortend to fit the prompt"
if test "$PWD" != "$HOME"
printf "%s" (echo $PWD|sed -e 's|/private||' -e "s|^$HOME|~|" -e 's-/\([^/]\)\([^/]*\)-/\1-g')
echo $PWD|sed -e 's-.*/[^/]\([^/]*$\)-\1-'
printf "%s" (echo $PWD|sed -e 's|/private||' -e "s|^$HOME|~|" -e 's-/\(\.\{0,1\}[^/]\)\([^/]*\)-/\1-g')
echo $PWD|sed -e 's-.*/\.\{0,1\}[^/]\([^/]*$\)-\1-'
else
echo '~'
end
@@ -15,8 +15,8 @@ else
echo '~'
case '*'
printf "%s" (echo $PWD|sed -e "s|^$HOME|~|" -e 's-/\([^/]\)\([^/]*\)-/\1-g')
echo $PWD|sed -n -e 's-.*/.\([^/]*\)-\1-p'
printf "%s" (echo $PWD|sed -e "s|^$HOME|~|" -e 's-/\(\.\{0,1\}[^/]\)\([^/]*\)-/\1-g')
echo $PWD|sed -n -e 's-.*/\.\{0,1\}.\([^/]*\)-\1-p'
end
end
end

71
util.c
View File

@@ -45,11 +45,17 @@
Maximum number of characters that can be inserted using a single
call to sb_printf. This is needed since vswprintf doesn't tell us
what went wrong. We don't know if we ran out of space or something
else went wrong. Therefore we assume that any error is an out of
memory-error and try again until we reach this size.
else went wrong. We assume that any error is an out of memory-error
and try again until we reach this size. After this size has been
reached, it is instead assumed that something was wrong with the
format string.
*/
#define SB_MAX_SIZE 32767
#define SB_MAX_SIZE (128*1024*1024)
/**
Handle oom condition. Default action is to print a stack trace and
exit, but an alternative action can be specified.
*/
#define oom_handler( p ) \
{ \
if( oom_handler_internal == util_die_on_oom ) \
@@ -77,7 +83,7 @@ void (*util_set_oom_handler( void (*h)(void *) ))(void *)
return old;
}
void util_die_on_oom( void * p)
void util_die_on_oom( void *p )
{
}
@@ -659,7 +665,7 @@ int hash_ptr_cmp( void *a,
}
void pq_init( priority_queue_t *q,
int (*compare)(void *e1, void *e2) )
int (*compare)(void *e1, void *e2) )
{
q->arr=0;
q->size=0;
@@ -669,7 +675,7 @@ void pq_init( priority_queue_t *q,
int pq_put( priority_queue_t *q,
void *e )
void *e )
{
int i;
@@ -790,6 +796,10 @@ void al_destroy( array_list_t *l )
free( l->arr );
}
/**
Real implementation of all al_push_* versions. Pushes arbitrary
element to end of list.
*/
static int al_push_generic( array_list_t *l, anything_t o )
{
if( l->pos >= l->size )
@@ -887,6 +897,10 @@ int al_insert( array_list_t *a, int pos, int count )
return 1;
}
/**
Real implementation of all al_set_* versions. Sets arbitrary
element of list.
*/
static int al_set_generic( array_list_t *l, int pos, anything_t v )
{
@@ -926,13 +940,16 @@ int al_set_long( array_list_t *l, int pos, long o )
return al_set_generic( l, pos, v );
}
int al_set_func( array_list_t *l, int pos, func_ptr_t o )
int al_set_func( array_list_t *l, int pos, func_ptr_t f )
{
anything_t v;
v.func_val = o;
v.func_val = f;
return al_set_generic( l, pos, v );
}
/**
Real implementation of all al_get_* versions. Returns element from list.
*/
static anything_t al_get_generic( array_list_t *l, int pos )
{
anything_t res;
@@ -967,6 +984,10 @@ void al_truncate( array_list_t *l, int new_sz )
l->pos = new_sz;
}
/**
Real implementation of all al_pop_* versions. Pops arbitrary
element from end of list.
*/
static anything_t al_pop_generic( array_list_t *l )
{
anything_t e;
@@ -1014,6 +1035,10 @@ func_ptr_t al_pop_func( array_list_t *l )
return al_pop_generic(l).func_val;
}
/**
Real implementation of all al_peek_* versions. Peeks last element
of list.
*/
static anything_t al_peek_generic( array_list_t *l )
{
anything_t res;
@@ -1177,26 +1202,26 @@ string_buffer_t *sb_new()
void sb_append_substring( string_buffer_t *b, const wchar_t *s, size_t l )
{
wchar_t tmp=0;
wchar_t tmp=0;
CHECK( b, );
CHECK( s, );
b_append( b, s, sizeof(wchar_t)*l );
b_append( b, &tmp, sizeof(wchar_t) );
b->used -= sizeof(wchar_t);
b_append( b, s, sizeof(wchar_t)*l );
b_append( b, &tmp, sizeof(wchar_t) );
b->used -= sizeof(wchar_t);
}
void sb_append_char( string_buffer_t *b, wchar_t c )
{
wchar_t tmp=0;
wchar_t tmp=0;
CHECK( b, );
b_append( b, &c, sizeof(wchar_t) );
b_append( b, &tmp, sizeof(wchar_t) );
b->used -= sizeof(wchar_t);
b_append( b, &tmp, sizeof(wchar_t) );
b->used -= sizeof(wchar_t);
}
void sb_append_internal( string_buffer_t *b, ... )
@@ -1273,15 +1298,21 @@ int sb_vprintf( string_buffer_t *buffer, const wchar_t *format, va_list va_orig
small. In GLIBC, errno seems to be set to EINVAL either way.
Because of this, sb_printf will on failiure try to
increase the buffer size until the free space is larger than
SB_MAX_SIZE, at which point it will conclude that the error
was probably due to a badly formated string option, and
return an error.
increase the buffer size until the free space is
larger than SB_MAX_SIZE, at which point it will
conclude that the error was probably due to a badly
formated string option, and return an error. Make
sure to null terminate string before that, though.
*/
if( buffer->length - buffer->used > SB_MAX_SIZE )
{
wchar_t tmp=0;
b_append( buffer, &tmp, sizeof(wchar_t) );
buffer->used -= sizeof(wchar_t);
break;
}
buffer->buff = realloc( buffer->buff, 2*buffer->length );
if( !buffer->buff )

42
util.h
View File

@@ -15,12 +15,29 @@
#include <stdarg.h>
#include <unistd.h>
/**
Typedef for a generic function pointer
*/
typedef void (*func_ptr_t)();
/**
A union of all types that can be stored in an array_list_t. This is
used to make sure that the pointer type can fit whatever we want to
insert.
*/
typedef union
{
/**
long value
*/
long long_val;
/**
pointer value
*/
void *ptr_val;
/**
function pointer value
*/
func_ptr_t func_val;
}
anything_t;
@@ -163,7 +180,7 @@ buffer_t;
typedef buffer_t string_buffer_t;
/**
Set the out of memory handler callback function. If a memory
Set the out-of-memory handler callback function. If a memory
allocation fails, this function will be called.
*/
void (*util_set_oom_handler( void (*h)(void *) ))(void *);
@@ -175,7 +192,7 @@ void (*util_set_oom_handler( void (*h)(void *) ))(void *);
This is the default out of memory handler.
*/
void util_die_on_oom( void * );
void util_die_on_oom( void *p );
/**
Returns the larger of two ints
@@ -428,11 +445,10 @@ int al_push_long( array_list_t *l, long o );
Append element to list
\param l The list
\param o The element
\return
\param f The element
\return 1 if succesfull, 0 otherwise
*/
int al_push_func( array_list_t *l, void (*f)() );
int al_push_func( array_list_t *l, func_ptr_t f );
/**
Append all elements of a list to another
@@ -443,6 +459,9 @@ int al_push_func( array_list_t *l, void (*f)() );
*/
int al_push_all( array_list_t *a, array_list_t *b );
/**
Insert the specified number of new empty positions at the specified position in the list.
*/
int al_insert( array_list_t *a, int pos, int count );
/**
@@ -458,7 +477,7 @@ int al_set( array_list_t *l, int pos, const void *o );
\param l The array_list_t
\param pos The index
\param o The element
\param v The element to set
*/
int al_set_long( array_list_t *l, int pos, long v );
/**
@@ -466,9 +485,9 @@ int al_set_long( array_list_t *l, int pos, long v );
\param l The array_list_t
\param pos The index
\param o The element
\param f The element to insert
*/
int al_set_func( array_list_t *l, int pos, void (*f)() );
int al_set_func( array_list_t *l, int pos, func_ptr_t f );
/**
Returns the element at the specified index
@@ -599,15 +618,18 @@ void sb_init( string_buffer_t * );
string_buffer_t *sb_new();
/**
Append a part of a string to the buffer
Append a part of a string to the buffer.
*/
void sb_append_substring( string_buffer_t *, const wchar_t *, size_t );
/**
Append a character to the buffer
Append a character to the buffer.
*/
void sb_append_char( string_buffer_t *, wchar_t );
/**
Append all specified items to buffer.
*/
#define sb_append( sb,... ) sb_append_internal( sb, __VA_ARGS__, (void *)0 )
/**

View File

@@ -378,7 +378,11 @@ static wchar_t *make_path( const wchar_t *base_dir, const wchar_t *name )
return long_name;
}
/**
Return a description of a file based on its suffix. This function
does not perform any caching, it directly calls the mimedb command
to do a lookup.
*/
static wchar_t *complete_get_desc_suffix_internal( const wchar_t *suff_orig )
{
@@ -425,15 +429,22 @@ static wchar_t *complete_get_desc_suffix_internal( const wchar_t *suff_orig )
return desc;
}
/**
Free the suffix_hash hash table and all memory used by it.
*/
static void complete_get_desc_destroy_suffix_hash()
{
hash_foreach( suffix_hash, &clear_hash_entry );
hash_destroy( suffix_hash );
free( suffix_hash );
if( suffix_hash )
{
hash_foreach( suffix_hash, &clear_hash_entry );
hash_destroy( suffix_hash );
free( suffix_hash );
}
}
/**
Use the mimedb command to look up a description for a given suffix
*/
@@ -759,7 +770,14 @@ static int test_flags( wchar_t *filename,
return 1;
}
/**
The real implementation of wildcard expansion is in this
function. Other functions are just wrappers around this one.
This function traverses the relevant directory tree looking for
matches, and recurses when needed to handle wildcrards spanning
multiple components and recursive wildcards.
*/
static int wildcard_expand_internal( const wchar_t *wc,
const wchar_t *base_dir,
int flags,