Compare commits

...

1234 Commits

Author SHA1 Message Date
David Adam
1e68508b0c Authenticate connections to web_config service
- Require all requests to use a session path.
 - Use a redirect file to avoid exposing the URL on the command line, as
   it contains the session path.

Fix for CVE-2014-2914.
Closes #1438.
2014-08-07 18:53:31 +08:00
David Adam
2aac8e5dde Further fixes to universal variable server socket management
- Change fishd_path to std::string
- Warn, rather than exiting with an error, if the universal variable
  server path is not available, and provide more useful advice.
- Export the new __fishd_runtime_dir variable.
2014-08-07 18:53:16 +08:00
David Adam
209d8b7f2f Fix for CVE-2014-2905 - fishd restart required.
- Use a secure path for sockets (some code used under license from
   tmux).
 - Provide the secure path in the environment as $__fish_runtime_dir.
 - Link the new path to the old path to ease migration from earlier
   versions.

Closes #1359.

After installing fish built from or after this commit, you MUST
terminate all running fishd processes (`killall fishd`, `pkill fishd`
or similar). Distributors are encouraged to do this from within their
packaging scripts. fishd will restart automatically, and no data should
be lost.
2014-08-07 18:53:16 +08:00
David Adam
26663e042f Revert "Check effective credentials of socket peers"
This reverts commit aea9ad4965.

Just checking the credentials of the peer turns out to be
insufficient.
See https://github.com/fish-shell/fish-shell/issues/1436.
2014-08-07 18:52:27 +08:00
David Adam
55986120aa use mktemp(1) to generate temporary file names
Fix for CVE-2014-2906.

Closes a race condition in funced which would allow execution of
arbitrary code; closes a race condition in psub which would allow
alternation of the data stream.

Note that `psub -f` does not work (#1040); a fix should be committed
separately for ease of maintenance.
2014-04-27 12:23:24 +08:00
David Adam
aea9ad4965 Check effective credentials of socket peers
Fix for CVE-2014-2905.

Code for getpeereid() on non-BSD systems imported from the PostgreSQL
project under a BSD-style license.
2014-04-27 12:23:13 +08:00
Anders Bergh
216d32055d fish_config: Listen on both IPv6 and IPv4.
A subclass of TCPServer was created to deny any non-local connections and to
listen using an IPv6 socket.
2014-04-27 11:36:41 +08:00
ridiculousfish
84978b7132 Fix for AppleScript error in fish.app 2013-05-17 00:40:33 -07:00
ridiculousfish
e4e9f6f221 Added missing osx/install.sh for building fish.app 2013-05-16 20:20:31 -07:00
ridiculousfish
77ec902ca7 Fix for failing to weak link wcsncasecmp - binary dies on SnowLeopard 2013-05-16 19:45:47 -07:00
ridiculousfish
7d9b0a00e4 Add note about uninstalling fish 2013-05-16 09:32:31 -07:00
ridiculousfish
f3c1ca3564 Merge branch 'Integration_2.0.0' 2013-05-15 01:03:15 -07:00
ridiculousfish
f109fa227d Release notes for fish 2.0 2013-05-15 01:02:55 -07:00
ridiculousfish
8befc474c1 Ugly hack to move functions in sample prompts inside fish_prompt to address #736 2013-05-13 10:17:31 -07:00
ridiculousfish
622efba247 Space -> tab in ack completion to match rest of file 2013-05-13 02:06:18 -07:00
Dag Odenhall
ce0c52d353 Silence errors when ack doesn't support --dump
It seems to be new in ack 2.x and with 1.96 I get error messages when
the ack completions are loaded.
2013-05-13 02:04:53 -07:00
David Adam (zanchey)
b03515276e update darcs completions 2013-05-13 01:59:50 -07:00
David Adam (zanchey)
30af350be0 update cvs completions 2013-05-13 01:59:50 -07:00
David Adam (zanchey)
1287b9d823 Help cleanup
Large list of changes, including formatting and typos for most commands.

More substantive changes have been made to alias, bind, block, break,
builtin, case, cd, commandline, count, else, emit, fish_config, funced,
function, functions, history, math, mimedb, nextd, not, popd, prevd,
pushd, pwd, random, read, set, set_color, switch, test, trap, type,
ulimit, umask, and while.
2013-05-13 01:48:20 -07:00
David Adam (zanchey)
91aab03b90 Document that fish functions cannot be background
(Documentation for #238, #563)
2013-05-13 01:48:20 -07:00
David Adam (zanchey)
e921dc50e0 FAQ updates - implicit cd and autosuggestions 2013-05-13 01:48:20 -07:00
David Adam (zanchey)
dd6bb04ba7 documentation typos 2013-05-13 01:48:20 -07:00
ridiculousfish
c80bd104d2 Add errret param to other calls to setupterm 2013-05-13 01:41:50 -07:00
Ian Munsie
22d1aaa27d Prevent fish dying if setupterm() fails in builtin_set_color()
Since set_color was changed to a built-in command, the entire shell will
exit in the event that setupterm() fails for some reason since ncurses
does an exit() if an errret was not passed in.

setupterm() can fail if the TERM environment variable is not set. This can
cause the shell to die prematurely if set_color is called from a startup
file like config.fish (such as vi-mode.fish which caches the results of
set_color when it is loaded) and fish is started without a TERM set
(e.g. when started from .xsession, or when being used as a remote shell
by a command such as rsync, scp or git)

A simple repro case for this issue is:

ian@delenn~ [i]> echo set_color normal > ~/.config/fish/config.fish
ian@delenn~ [i]> scp localhost:test .
TERM environment variable not set.
ian@delenn~ [i]>

This patch passes in an errret variable to setupterm(), which causes
ncurses to return the error to builtin_set_color() rather than calling
exit():

ian@delenn~ [i]> scp localhost:test .
test                                                 100%    0     0.0KB/s   00:00
ian@delenn~ [i]>

Signed-off-by: Ian Munsie <darkstarsword@gmail.com>
2013-05-13 01:35:57 -07:00
ridiculousfish
2f5016262a Attempt again to fix UnicodeDecodeError (issue #658) 2013-05-12 01:57:42 -07:00
ridiculousfish
47583877f1 Doc fix where wrong file was referenced in an example 2013-05-12 00:44:41 -07:00
ridiculousfish
1dbff80691 Correct sizes of certain fish.app icons 2013-05-05 03:35:37 -07:00
ridiculousfish
7abf6c71ad Typos in the fish OS X package installer rtf file 2013-05-05 02:42:31 -07:00
ridiculousfish
2da81b0ae7 Formatting and style updates 2013-05-05 02:33:17 -07:00
Siteshwar Vashisht
d4c881791f Avoid generating man page and help section for printf (to fallback on system man page for printf) 2013-05-05 14:59:34 +05:30
Siteshwar Vashisht
516be01366 Added documentation for printf
Fix for https://github.com/fish-shell/fish-shell/issues/488
2013-05-05 12:27:38 +05:30
Dag Odenhall
2b99190a1b Add completions for cabal; closes #567 2013-05-04 12:48:38 -07:00
Tin Tvrtkovic
3087f57453 Manually cleaned up Mercurial completions. 2013-05-04 12:44:03 -07:00
ridiculousfish
4a4f8ec523 Clarify "input/output methods" in documentation 2013-05-04 11:53:50 -07:00
ridiculousfish
0c004147c0 Merge branch 'zanchey-docs'
Conflicts:
	doc_src/index.hdr.in
2013-05-04 11:47:07 -07:00
ridiculousfish
451eb13e0e Add a note about getting help through man pages 2013-05-04 11:43:15 -07:00
Kurtis Nusbaum
4e84cf1d38 Fixed small typo
Fixed a small typo that I noticed in the design docs.
Pretty sure it was meant to say "turned off" instead
of "turned of".
2013-05-01 18:37:52 -05:00
Eivind Uggedal
72b7e64ad8 Tiny typo. 2013-05-01 12:27:55 +02:00
David Adam
c3690b0878 index.hdr.in: slightly more controversial changes
- Clarify wording in functions section
 - Use the term aliases rather than wrappers
 - Clarification of concepts and better? examples in variable expansion
 - Likewise in environment variables
 - Using the phrase builtin commands rather than builtins
 - Tidy up keybindings a bit
 - Another example in the history section
 - Remove TODO section in favour of mailing list, GitHub and IRC link
2013-04-30 18:24:23 +08:00
David Adam
b3f248fd19 index.hdr.in: (hopefully) non-controversial edits 2013-04-30 18:24:23 +08:00
David Adam
d4686e6a59 index.hdr.in: add code markup 2013-04-30 18:09:34 +08:00
David Adam
14af6ba2af status command: improve help text 2013-04-29 13:46:00 +08:00
David Adam
c3ee3af201 miscellaneous typos 2013-04-29 13:45:48 +08:00
ridiculousfish
6496adf101 Make trap sort of work on OS X
https://github.com/fish-shell/fish-shell/issues/607
2013-04-28 16:31:25 -07:00
ridiculousfish
79f8d5c51e Fix __fish_filter_mime to not pass 0 to seq 2013-04-28 15:59:33 -07:00
ridiculousfish
74ef1bc8ff Fix typos in count documentation 2013-04-28 15:59:21 -07:00
Eivind Uggedal
26eeb9f37a Fix broken sentence in the Job Control section of the user doc. 2013-04-28 14:51:13 -07:00
ridiculousfish
ab385cd609 Teach fish about rxvt's special key bindings
https://github.com/fish-shell/fish-shell/issues/657
2013-04-28 14:36:11 -07:00
ridiculousfish
0f12f2b6b1 Formatting cleanup of builtin_contains 2013-04-28 14:35:00 -07:00
Tin Tvrtkovic
32c1d50887 Refactored out individual VCS completions.
Autogenerated completions for Mercurial using a recent version (no extensions installed).
2013-04-28 14:54:59 +02:00
ridiculousfish
956c94f30a Teach the Makefile to only instruct the user to edit /etc/shells if it needs to be edited 2013-04-27 16:36:35 -07:00
ridiculousfish
3e69e5b082 Large set of changes to improve history atomicity on filesystems that do not support locking
Should address https://github.com/fish-shell/fish-shell/issues/685
2013-04-27 15:21:14 -07:00
Adam
330faab6cd Typo in tar completion (vevrify->verify) 2013-04-27 14:48:33 +02:00
ridiculousfish
fe6699f0bf Rely on $PWD instead of getcwd() more often
Fixes https://github.com/fish-shell/fish-shell/issues/696
2013-04-27 00:45:38 -07:00
ridiculousfish
807c5f2ef2 Squashed commit of the following:
commit 839e9c2ec00fcd72b19f1d415bee26af7f51f8aa
Author: lledey <lledey@gmail.com>
Date:   Tue Apr 23 13:28:23 2013 +0200

    Fix git branch completion if grep output is not the default one

    Signed-off-by: lledey <lledey@gmail.com>

commit 7798ed05744636f67d177bcb47d48d6aeca12787
Author: lledey <lledey@gmail.com>
Date:   Tue Apr 23 10:35:35 2013 +0200

    Fix git branch completion if grep output is not the default one

    Signed-off-by: lledey <lledey@gmail.com>
2013-04-26 21:42:31 -07:00
ridiculousfish
f7708955b6 Make ack completion not spew to stderr if ack is not installed 2013-04-26 21:33:17 -07:00
Konrad Borowski
be9024767e Allow dynamicly adding types 2013-04-26 12:08:11 -07:00
Konrad Borowski
a1a83f8880 Insanely long ack completion 2013-04-26 12:08:11 -07:00
ridiculousfish
eb3a1f6739 Fix for reported "out of memory" for filesystems that return -1 as _PC_NAME_MAX 2013-04-26 11:46:49 -07:00
Steven Fackler
03c1f2ef5b Some documentation cleanup 2013-04-21 21:36:48 -04:00
ridiculousfish
d215e86662 Fix for issue where tab completing an empty string would produce no results 2013-04-21 15:49:45 -07:00
ridiculousfish
10962d7175 Remove code that disabled tests (oops) 2013-04-21 15:49:45 -07:00
Siteshwar Vashisht
6889232b41 Moved lein.fish under share/completions 2013-04-21 10:55:41 +05:30
Dmitry Chestnykh
c54097af20 Fix typo in docs 2013-04-20 13:30:40 -07:00
Thomas Kühnel
7c6695354e Append / to the end of directories for scp completion as suggested by https://github.com/fish-shell/fish-shell/issues/42#issuecomment-7205032 2013-04-20 13:26:06 -07:00
ridiculousfish
2d7fbf2476 Teach xcode build about $BINDIR 2013-04-20 13:18:51 -07:00
Brent Sanders
1ef8206db1 Changed paths.bin to respect BINDIR
The compiled-in path to bin dir was not correct; it made the
common assumption that `$(prefix)` == `$(prefix)/bin` which is
usually true, but not in all cases.

1. [machine specific files](http://www.gnu.org/prep/standards/html_node/Directory-Variables.html#index-exec_005fprefix)
   should use `$(exec_prefix)` (`@exec_prefix@` in Makefile.in)
   instead of the usual `$(prefix)`.

2. [executable programs](http://www.gnu.org/prep/standards/html_node/Directory-Variables.html#index-bindir)
   should use the more-specific `$(bindir)` (`@bindir@` in Makefile.in)
   instead of assuming `$(exec_prefix)/bin` as this allows the
   executable install location to be changed with the
   `--bindir=_foo_` option to `./configure`.

Fortunately, the makefile is mostly correct and *installs* the
executable in the correct location. The problem shows up later
such as during tab-completion, when fish_pager is run - the
compiled-in path it uses was the incorrect `$(prefix)/bin`
resulting in an "Unknown command" error, which only required
this small fix.
2013-04-20 13:18:51 -07:00
ridiculousfish
b65f8d81fc Don't block "hidden files" for wildcard expansions that aren't files (like case)
https://github.com/fish-shell/fish-shell/issues/667
2013-04-20 12:41:02 -07:00
ridiculousfish
e285d2939b Teach fish to exit without destructors in the normal path 2013-04-19 10:24:33 -07:00
ridiculousfish
6b602a4589 Minor cleanup in syntax highlighting 2013-04-19 10:24:33 -07:00
ridiculousfish
084542b943 print_variables should use ellipsis_char instead of literal ellipsis 2013-04-19 10:24:33 -07:00
ridiculousfish
ef8ea97044 Prevent inline destructor of completion_t to reduce compiled code size a bit 2013-04-19 10:24:33 -07:00
ridiculousfish
dd6d0e774c Rearrange some macros in configure.ac so that CXXFLAGS can default to -g -O2 again 2013-04-19 10:24:33 -07:00
ridiculousfish
f934310337 Build with -fno-exceptions
https://github.com/fish-shell/fish-shell/issues/664
2013-04-19 10:24:33 -07:00
Siteshwar Vashisht
afe293c20a Fixed compilation by adding missing header libintl.h 2013-04-17 06:41:58 +02:00
Siteshwar Vashisht
7f0a68f8d6 Fixed check for msgfmt in configure.ac 2013-04-16 15:13:05 +02:00
ridiculousfish
2517832718 Teach fish_config how to find fish from __fish_bin_dir
Fixes https://github.com/fish-shell/fish-shell/issues/621
2013-04-15 14:15:47 -07:00
ridiculousfish
bcf3accb74 Eliminate a static string from input_terminfo_get_sequence 2013-04-15 13:07:17 -07:00
ridiculousfish
1c5556334d Try to fix UnicodeDecodeError in create_manpage_completions.py
https://github.com/fish-shell/fish-shell/issues/658
2013-04-15 01:05:56 -07:00
hansstimer
299d803396 Update go.fish
Fix typo for vet subcommand
2013-04-14 16:13:50 -07:00
Hans Stimer
d513ace39d add completion for the Go tool 2013-04-14 16:13:50 -07:00
ridiculousfish
d5a9a4463c Turn off RTTI when building with libstdc++ 2013-04-14 15:59:41 -07:00
ridiculousfish
cf0baada2c Removed INSTALL file, since it mostly duplicates what's present in README.md 2013-04-14 13:42:12 -07:00
ridiculousfish
49589e2da0 Added note about how to install ncurses, and what to do on EC2
Addresses https://github.com/fish-shell/fish-shell/pull/509
2013-04-14 13:38:56 -07:00
ridiculousfish
0e24676144 Fix to make create_manpage_completions work with Python 3
Fixes https://github.com/fish-shell/fish-shell/issues/658 ?
2013-04-14 02:03:53 -07:00
ridiculousfish
b0132821ac Use 'command git' instead of git to defeat certain git aliases
https://github.com/fish-shell/fish-shell/pull/622
2013-04-14 02:03:53 -07:00
nmeum
24afe544a3 Typos 2013-04-14 12:19:56 +05:30
ridiculousfish
3d7ff9f758 Remove "law of minimalism" since echo is now a builtin and we're pretty clearly prioritizing performance over modularity.
https://github.com/fish-shell/fish-shell/issues/612
2013-04-13 23:13:18 -07:00
ridiculousfish
a81e70350b Teach OS X package builder script to look up the version dynamically 2013-04-13 23:13:18 -07:00
nmeum
7f6f0ca103 Fixed a typo
It should be 'directory' not 'direcotry'
2013-04-13 22:38:29 +02:00
ridiculousfish
c89bc73740 Added WorkspaceSettings.xcsettings to prevent auto-creation of schemes 2013-04-13 12:21:10 -07:00
ridiculousfish
3100669b79 Add the Xcode schemes 2013-04-13 11:04:44 -07:00
ridiculousfish
22c670c3d3 Replace OS X installer PackageMaker document with a distribution file and script 2013-04-13 02:00:32 -07:00
ridiculousfish
c37c7cee05 Reduce compiled code size a bit 2013-04-13 02:00:31 -07:00
Siteshwar Vashisht
46579f3799 Removed xsel tarball from repository 2013-04-13 12:12:39 +05:30
Greg Dietsche
6de30028a8 tmux: make session auto-completion user friendly
make it more user friendly by matching the output of:
  tmux list-sessions

Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-12 14:03:26 -07:00
Greg Dietsche
c78c1427be tmux: use status-left short flags
Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

Conflicts:
	share/completions/tmux.fish
2013-04-12 14:03:26 -07:00
Greg Dietsche
953e7fd717 tmux: implement Status Line
Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-12 14:03:26 -07:00
Greg Dietsche
1ae08cfedf tmux: implement ENVIRONMENT
Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-12 14:03:26 -07:00
ridiculousfish
3c116cd077 Change Makefile to not delete legacy binaries, but instead just notify the user about them. Change Makefile to only look for legacy binaries in $PREFIX instead of using which.
https://github.com/fish-shell/fish-shell/pull/655
2013-04-12 13:49:08 -07:00
ridiculousfish
bcab703e31 Fix a comment 2013-04-10 00:12:55 -07:00
ridiculousfish
73046ec838 Stomp exit status of initialization scripts so that fish starts out with $status 0
https://github.com/fish-shell/fish-shell/issues/635
2013-04-09 23:48:03 -07:00
ridiculousfish
e1734468f5 Support for building with C++11 2013-04-09 14:07:19 -07:00
Konrad Borowski
aa78292c2a Update apt-get completion. Fixes #652. 2013-04-09 22:04:04 +05:30
ridiculousfish
8bbd8ab073 Hack up dcgettext to try to fix CentOS build
https://github.com/fish-shell/fish-shell/issues/645
2013-04-08 12:02:43 -07:00
ridiculousfish
b936be8e34 Hack up gettext to try to fix CentOS build
https://github.com/fish-shell/fish-shell/issues/645
2013-04-08 10:20:56 -07:00
ridiculousfish
b8f34cdd35 Teach case-insensitive completions about tildes. Fixes https://github.com/fish-shell/fish-shell/issues/647 2013-04-07 23:54:43 -07:00
Greg Dietsche
993c028579 make punctuation consistent
Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-07 16:49:47 -07:00
Greg Dietsche
9285ade8a8 ftp: add support for ftp and pftp
Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-07 16:49:46 -07:00
Greg Dietsche
83e9f0dd91 grep: add support for egrep, fgrep, rgrep
Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-07 16:42:28 -07:00
Greg Dietsche
c641f5cbdc grep: fix and add completions
Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-07 16:42:28 -07:00
ridiculousfish
c6302e3b3f Add some more cancellability to autosuggestions 2013-04-07 16:40:14 -07:00
ridiculousfish
94acb6ed5d Rewrite unescape_yaml to be faster and not needlessly trigger COW behavior of std::string 2013-04-07 14:59:48 -07:00
ridiculousfish
42497d9932 Fix for issue where a file may be incompletely read on receipt of a signal. 2013-04-07 14:52:16 -07:00
ridiculousfish
3f172d13b2 Add thread assertion to proc_set_last_status 2013-04-07 14:38:57 -07:00
ridiculousfish
437b4397b9 Mark stdin as nonblocking if we get EWOULDBLOCK, and before handing it off to child processes when either starting them or moving them to the foreground.
https://github.com/fish-shell/fish-shell/issues/176
2013-04-07 12:40:08 -07:00
ridiculousfish
3a7ab3f030 Teaching history how to exit early on thread cancellation 2013-04-06 00:28:55 -07:00
ridiculousfish
fccf38a4d6 Don't pass 0 to seq because BSDs are dumb. Pipe tmux stderr to /dev/null 2013-04-04 21:52:23 -07:00
ridiculousfish
46edc49ede Squashed commit of the following:
commit 6259665e972d478f1ce4ab3d233033ec1dd7eef2
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Thu Apr 4 11:02:35 2013 -0500

    change spaces to tabs

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 465333d982db441f430767b645fdcd95e44cc5d6
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Wed Apr 3 11:15:22 2013 -0500

    tmux: implement completion for panes

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 684baf98a6ac070847f20a02838abe58e8c22d5b
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Tue Apr 2 23:56:27 2013 -0500

    tmux: don't suggest dirs

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 8c4a9854a1f173866439f976301b743354c945c8
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Tue Apr 2 21:57:40 2013 -0500

    move front flags to the top of the tmux file

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 7f2321e9cd20a5aa2bcbfe940e20ec57bcca2609
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Tue Apr 2 20:06:54 2013 -0500

    fix some of the initial parameters

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit f70fc55bed40c0ccd2a00921c0e7373e7c18b5d7
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Tue Apr 2 21:47:25 2013 -0500

    implement tmux KEY BINDINGS

    implement the commands in the KEY BINDINGS man page section

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit ec423040dba742f67c06dbb932417f6d19b90fba
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Tue Apr 2 00:10:43 2013 -0500

    implement tmux completion for CLIENTS AND SESSIONS

    Fully implement all tmux commands found in the tmux man
    page section titled: "CLIENTS AND SESSIONS"

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-04 21:52:06 -07:00
Valerii Hiora
c05281492d Improved brew completion
Using arg completion
Context-based completion for most of commands (i.e. only installed
packages for upgrade or remove, only outdated for upgrade and so on)
2013-04-04 21:41:59 -07:00
ridiculousfish
5cebd3abf7 Teach git completion about difftool. Change __fish_git_ranges to output branches as designed. 2013-04-04 21:36:13 -07:00
ridiculousfish
5ed5d637b8 Fix %s format specifier for printf. No more elpfor at login. 2013-04-04 15:56:58 -07:00
ridiculousfish
516e18900c Repaint after completions
Fixes #643, #644
2013-04-04 11:51:23 -07:00
ridiculousfish
0970487cca Some spaces to tabs in __fish_print_hostnames 2013-04-03 18:46:50 -07:00
Greg Dietsche
d38f1380e9 Ignore hashed host names in ssh/known_hosts
Valid DNS names cannot have a | character and hashed ssh hosts
always begin with the | character. Therefore we ignore lines that
begin with |.

Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-03 18:45:13 -07:00
Greg Dietsche
2626b83b08 the host keyword in ssh/.config is case insensitive
Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-03 18:45:13 -07:00
ridiculousfish
db0659aab4 Fix a sign warning 2013-04-03 18:27:18 -07:00
ridiculousfish
e23a60a6bb Another attempt to fix the printf tests on 32 bit Linux 2013-04-03 18:23:31 -07:00
ridiculousfish
3ea8d83d3f Try to fix printf tests on Linux 2013-04-03 18:04:17 -07:00
ridiculousfish
d9445f04b1 Use the new input_common_add_callback mechanism to not execute callbacks while signals are blocked. Should fix https://github.com/fish-shell/fish-shell/issues/608 2013-04-03 17:26:02 -07:00
ridiculousfish
1543d02f96 Add callbacks that get invoked before the next call to select(), which will allow for a nice fix to https://github.com/fish-shell/fish-shell/issues/608. Eliminate the poll handler, and replace it with this mechanism. 2013-04-03 13:49:58 -07:00
ridiculousfish
11a444e914 Replace a formatted string with just a character copy 2013-04-03 13:30:45 -07:00
ridiculousfish
2a6412481e Fix a few more spelling / grammar issues in functions and completions 2013-04-01 10:52:27 -07:00
ridiculousfish
b4447bfa4d Squashed commit of the following:
commit 1bbde16b17f04903340206bada9935ea64f785ba
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 01:12:22 2013 -0500

    fix spelling in xterm.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 392dd59da76e6a1293db79733e1975dbb9ef4032
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 01:10:08 2013 -0500

    fix spelling in type.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit f82026828e4c08bdf355176f86489783c57efc80
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 01:09:34 2013 -0500

    fix spelling in top.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 196f2ec59c0904eb13159d1063e2e6c6edbd50a8
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 01:08:16 2013 -0500

    fix spelling in scrot.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 8400d97dce93afe48612c66eb8ddc2bd06b40968
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 01:07:48 2013 -0500

    fix spelling in scp.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit b68bb3f36915520d2c271e48e2d5356e087e9fcf
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 01:04:30 2013 -0500

    fix spelling in mount.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 97000184afde10ca26b6dda8597baa0593bb4e09
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 01:01:46 2013 -0500

    fix spelling in hg.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 87ca4e71ce57842ab98e4d6b6f9274aafd9713a5
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 01:00:37 2013 -0500

    fix spelling in gzip.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 17246a21ad3df39660e6b4c86bf8c6a2239b416b
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 01:00:07 2013 -0500

    fix spelling in gunzip.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 0f618600508695ed5a93110568343f8a783db8c5
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:59:37 2013 -0500

    fix spelling in grep.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit bacf6a62041d13f1766e90748cfc2c76e1b04b98
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:58:16 2013 -0500

    fix spelling in git.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit f8f6a1914a8f2f60a14dac532f1d63dd8269f676
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:56:45 2013 -0500

    fix spelling in fuser.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit dcdfd1552dfd360d1ce808706bc401d52cce22ce
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:54:58 2013 -0500

    fix spelling in effectv.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 7b4388364f546b81f0557c500bb6a5207931c3be
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:53:45 2013 -0500

    fix spelling in du.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 0450070e98adae2ebe19806f4fb74386a50de003
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:52:55 2013 -0500

    fix spelling in df.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 49ae24ae0dbd06c72e6c994f1ea4ca9b385fdda5
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:49:00 2013 -0500

    fix spelling in cut.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 4eccc923f389e2fc0c498fc63e4bbeeccc177e9a
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:47:21 2013 -0500

    fix spelling in compare.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 8c0cfb91c596ef7a1583877c8f38fab7e867cff2
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:46:46 2013 -0500

    fix spelling in chown.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 4518b06c3fc8c565038ccbeeb0d2f8aea73e1ee0
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:46:08 2013 -0500

    fix spelling in chgrp.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit a0a4fb3dc271c469482e87a0f9efab4016596f82
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:43:04 2013 -0500

    fix spelling in apt-setup.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 740e75e5316e73fb03c00bd9b482786d1f387cc5
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:42:25 2013 -0500

    fix spelling in apt-rdepends.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 7a2727bcb96e58a023d0f8ab807f839e76555375
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:27:27 2013 -0500

    fix spelling in fish_complete_pacman.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 0e28ff4c1c90bdbf1e1b780d0ab3c2ba04b3a463
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:26:17 2013 -0500

    fix spelling in fish_complete_pgrep.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 1ca9fad713c460debcd851dfcffa135f3b579561
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:24:13 2013 -0500

    fix spelling in trap.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit deb0c2129d50d627d720cbd549cf8aadc3113243
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:19:00 2013 -0500

    fix spelling in fish_not_contain_opt.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 8a40bd08b37d5c80041b7beb58fb82d9b0592b5d
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:18:16 2013 -0500

    fix spelling in fish_make_completion.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit f1c48dc8236a8eb5ba0e45e985e8dd7eadfb88e5
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:17:09 2013 -0500

    fix spelling in fish_gnu_complete.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit b6813883d9355f8e15917769d46b58cc8fab840d
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:16:33 2013 -0500

    fix spelling in fish_git_prompt.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 97e3e74ddb743061a8e4349bf7895cf98cf9d9b2
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:13:11 2013 -0500

    fix spelling in fish_complete_vi.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 7c31d5fec8f855fbc3496be7200915a1d2dc4d46
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:10:47 2013 -0500

    fix spelling of in fish_complete_tex.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 3f06bdb91942c4d0e686d1bb8b5eff1983a91304
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:06:45 2013 -0500

    fix spelling in fish_complete_list.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit 5bfd9ef40547b744c9bbfb4cc6f8a7d880d8f3d6
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Mon Apr 1 00:03:14 2013 -0500

    fix spelling in fish_complete_atool.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>

commit b84a43ff0bad5e206a591891b6c7ff9028e14eb5
Author: Greg Dietsche <Gregory.Dietsche@cuw.edu>
Date:   Sun Mar 31 23:40:28 2013 -0500

    fix spelling of protocol in fish_complete_ssh.fish

    Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
2013-04-01 10:49:02 -07:00
ridiculousfish
72b5988e56 Merge pull request #630 from vhbit/e02e5e503d9078e9f0ef8942f57f3cf93eb07718
Lein command completion
2013-04-01 10:06:21 -07:00
ridiculousfish
3a2c3c2288 Remove some GNU-makeisms from the Makefile to try to get us to build with BSD make. Not quite there yet. 2013-03-31 19:08:18 -07:00
ridiculousfish
9762a8ca1e Remove xsel from the build
https://github.com/fish-shell/fish-shell/issues/633
2013-03-30 00:13:44 -07:00
Valerii Hiora
e02e5e503d Basic completion for leiningen 2013-03-30 05:33:53 +02:00
ridiculousfish
e4329f3ae7 Fix the build (oops) 2013-03-29 18:05:01 -07:00
ridiculousfish
f7082ee034 Make xsel work as designed
Fixes https://github.com/fish-shell/fish-shell/issues/559
2013-03-29 17:57:44 -07:00
Siteshwar Vashisht
3ac9621f87 Enabled test cases for unicode characters in printf builtin 2013-03-29 12:26:15 +05:30
Siteshwar Vashisht
46e92e998e Fixed compilation caused by misplaced '}' in builtin_printf.cpp 2013-03-29 12:02:50 +05:30
ridiculousfish
77dfd7b783 Fix printf's Unicode support
https://github.com/fish-shell/fish-shell/issues/625
2013-03-28 17:45:49 -07:00
ridiculousfish
7d480ff579 Make __fish_filter_mime not spew if there's no results
https://github.com/fish-shell/fish-shell/issues/628
2013-03-28 17:01:07 -07:00
ridiculousfish
37140d5e10 Fix builtin_printf compilation on FreeBSD 8.x
https://github.com/fish-shell/fish-shell/issues/626
2013-03-27 11:35:30 -07:00
ridiculousfish
b04e874e43 Teach fish how to push and pop blocks even in the face of no_exec. All tests finally pass.
https://github.com/fish-shell/fish-shell/issues/624
2013-03-25 16:06:12 -07:00
ridiculousfish
d146f578a4 Fix printf output to store \r instead of \n
Is git breaking line endings?
2013-03-24 15:58:24 -07:00
ridiculousfish
40c0c5a298 Fix for errno-style error reporting in printf 2013-03-24 15:58:24 -07:00
ridiculousfish
3a475a99fc Fix gettext macro to stop casting everything to wchar_t * (oops) 2013-03-24 15:58:24 -07:00
ridiculousfish
9394583f96 Implement actual error handling for builtin_printf. Fix the tests. 2013-03-24 15:58:24 -07:00
ridiculousfish
3b4f4c5f59 remove a variable length stack allocated array and simplify builtin printf 2013-03-24 15:58:24 -07:00
Siteshwar Vashisht
34f2f77067 Updated 'Contact Us' section in README.md 2013-03-25 01:34:24 +05:30
ridiculousfish
6b94708508 Add builtin_printf to xcode project 2013-03-23 14:48:06 -07:00
ridiculousfish
1d93e89eed Replace some append_format with push_back 2013-03-21 22:36:21 -07:00
ridiculousfish
e0e0bcdc1e Update code formatting 2013-03-21 17:44:51 -07:00
ridiculousfish
1ed8af2ee8 Some cleanup of builtin_printf. Eliminate global variables and a nasty macro. 2013-03-21 17:40:12 -07:00
ridiculousfish
3830c0adc4 Merge branch 'builtin_printf' of git://github.com/siteshwar/fish-shell into siteshwar-builtin_printf 2013-03-20 16:18:52 -07:00
Siteshwar Vashisht
5dbda6cd95 Fixed some case statements in hextobin function 2013-03-17 00:43:06 +05:30
Siteshwar Vashisht
d8dbdc83c0 Cleaned up some code in printf builtin 2013-03-17 00:28:12 +05:30
Siteshwar Vashisht
359a7cebde Use wcstoimax and wcstoumax instead of strtoimax and strtoumax in printf builtin 2013-03-17 00:20:02 +05:30
Siteshwar Vashisht
490ead52eb Changed octtobin, hextobin and isodigit macros into functions 2013-03-17 00:04:11 +05:30
Siteshwar Vashisht
a5a7a32447 Use fixed value "lld" instead of PRIdMAX 2013-03-16 23:32:26 +05:30
Terje Larsen
7e9652787b Add completion for ruby-build 2013-03-13 23:19:03 +01:00
ridiculousfish
3b00d06a62 Return key should only insert a newline if backslashed character is whitespace, or backslash terminates the line
https://github.com/fish-shell/fish-shell/issues/613
2013-03-12 13:00:37 -07:00
ridiculousfish
234fb7c2fe Rename print_service_names to __fish_service_print_names 2013-03-12 12:00:02 -07:00
aliva
2c7e0ef577 service name completion for "systemd service manager" added 2013-03-12 19:13:52 +03:30
ridiculousfish
2cbcc82968 Add some headers to fix the build on OpenBSD
https://github.com/fish-shell/fish-shell/issues/616
2013-03-11 13:38:18 -07:00
ridiculousfish
b48e504522 Spelling mistake in comment 2013-03-11 10:55:47 -07:00
ridiculousfish
4cce303c89 Add support for making a leading space not save to history
https://github.com/fish-shell/fish-shell/pull/615
2013-03-10 14:25:43 -07:00
Kenneth Vestergaard
6a97b45ad1 Add note to docs. 2013-03-10 14:24:16 -07:00
Kenneth Vestergaard
1afdbb848e Minor fix to order of arguments in error-message. 2013-03-09 13:03:28 -08:00
ridiculousfish
4d19bb17a9 Break out COMPLETE_NO_CASE and COMPLETE_REPLACES_TOKEN into separate flags, in preparation for upcoming fuzzy completion work 2013-03-05 20:54:16 -08:00
ridiculousfish
b2012467b3 Document -e and -E flags for echo, and provide some examples 2013-03-05 17:37:44 -08:00
David Adam (zanchey)
daf5ef1bbd Kill termio.h and sys/termios.h
On FreeBSD, compilation complains that "this file includes
<sys/termios.h> which is deprecated, use <termios.h> instead". On Linux
and FreeBSD, <sys/termios.h> literally just pulls in <termios.h>. On OS
X and Solaris, <termios.h> pulls in <sys/termios.h>.

<termio.h> doesn't exist on FreeBSD or Mac OS X, and on Linux is marked
as deprecated and just includes <termios.h>. It does exist on Solaris,
but no `struct termio` is ever actually used in the codebase.
2013-03-05 12:25:00 -08:00
ridiculousfish
85a5319c4b Add some examples to set_color 2013-03-04 12:05:21 -08:00
Daniel James
6ca11044a4 Remove -v flag from set_color synopsis.
The -v documentation was removed when set_color was made a builtin, but wasn't removed from the synopsis.
2013-03-04 11:33:50 -08:00
Siteshwar Vashisht
42be7733fe Return EXIT_FAILURE in printf builtin if conversion to number fails 2013-03-04 23:25:14 +05:30
ridiculousfish
1d75c232ff Teach builtin_test about the special precedence rules in IEEE 1003.1
https://github.com/fish-shell/fish-shell/issues/601
2013-03-03 13:22:00 -08:00
Siteshwar Vashisht
97c9c9c9d1 Use wmemcpy instead of mempcpy in printf builtin 2013-03-03 16:22:26 +05:30
Siteshwar Vashisht
ab52469fbb Changed type of ok array in builtin_printf.cpp to bool 2013-03-03 15:32:32 +05:30
Siteshwar Vashisht
fba984272a Fixed indentation in builtin_printf.cpp 2013-03-03 15:16:18 +05:30
Siteshwar Vashisht
fb3a41d3ad Merge branch 'builtin_printf' of github.com:siteshwar/fish-shell into builtin_printf
Conflicts:
	Makefile.in
	builtin.cpp
	builtin_printf.cpp
2013-03-03 00:49:56 +05:30
Siteshwar Vashisht
be7d02ebdd Added test cases for printf builtin 2013-03-03 00:45:34 +05:30
Siteshwar Vashisht
b989978dd3 Fixed code to support field width and precision 2013-03-02 20:54:12 +05:30
Siteshwar Vashisht
d9c9760aac Initial version of printf builtin 2013-03-02 20:54:12 +05:30
Siteshwar Vashisht
6ff88a44f0 Fixed code to support field width and precision 2013-03-02 16:02:20 +01:00
ridiculousfish
cbcc439e03 Merge branch 'master' of git://github.com/aliva/fish-shell into aliva-master 2013-03-01 15:10:50 -08:00
David Adam (zanchey)
bf282e9bd7 configure: disable gettext support if msgfmt isn't found (fixes https://github.com/fish-shell/fish-shell/issues/548) 2013-03-01 14:54:46 -08:00
David Adam (zanchey)
4c3d3af73e configure: only check for gettext/dcgettext if we want them (makes --without-gettext work on platforms where gettext exists but isn't wanted) 2013-03-01 14:54:46 -08:00
David Adam (zanchey)
10648cac5b configure: only check for libintl if we want to use gettext (makes --without-gettext actually work) 2013-03-01 14:54:45 -08:00
aliva
3bfcd5e105 recreate yum-cache file every six hours. 2013-03-02 01:48:56 +03:30
aliva
87aca05e7f autocomplete 'yum install' using yum cache 2013-03-01 23:27:03 +03:30
ridiculousfish
94b1d58cc2 Additional changes related to https://github.com/fish-shell/fish-shell/pull/592 2013-02-28 10:25:32 -08:00
ridiculousfish
c55cbd3f2f Hopeful fix for https://github.com/fish-shell/fish-shell/issues/594 2013-02-26 18:31:08 -08:00
ormris debian
d89fcdcc5f Add proper desriptions to "git submodule" 2013-02-26 16:24:28 -08:00
Cheer Xiao
76f715c486 add class scoped_push to automatically restore variable on function exit 2013-02-26 12:17:28 -08:00
lledey
bbab6b2fdc Fix compilation by using std::ptrdiff_t instead of ptrdiff_t
Signed-off-by: lledey <lledey@gmail.com>
2013-02-23 21:47:10 +01:00
ridiculousfish
a8e92639af Cleanup and simplify null_terminated_array_t and its clients 2013-02-22 16:22:56 -08:00
ridiculousfish
d99c2cb9a7 Support /etc/paths and /etc/paths.d/* on OS X
https://github.com/fish-shell/fish-shell/issues/417
2013-02-22 14:01:17 -08:00
ridiculousfish
9f8fe3d5e3 Hopeful fix to avoid forking for certain builtins like echo when they have an input redirection only 2013-02-22 13:20:27 -08:00
Konrad Borowski
3c8c8a7559 Remove useless __fish_complete_perl function 2013-02-21 12:53:35 -08:00
Konrad Borowski
a61e2caadb Update Perl completion 2013-02-21 12:53:35 -08:00
ridiculousfish
f109d535b1 Add a null check to avoid passing null to io_chain_t::push_back
https://github.com/fish-shell/fish-shell/issues/590
2013-02-21 12:44:01 -08:00
ridiculousfish
12095c721c Remove unnecessary eval in __fish_complete_cd
https://github.com/fish-shell/fish-shell/pull/589
2013-02-20 18:43:54 -08:00
ridiculousfish
7b873179ad Use swap instead of copying in reader_repaint_without_autosuggestion 2013-02-20 18:18:08 -08:00
Yannis Chatzimichos
f1d923714a Clear the autosuggestion from the old commandline when showing the completion list. Fixes #561 2013-02-20 18:07:38 -08:00
Yannis Chatzimichos
b9ba227733 Clean up comments and fix spelling errors 2013-02-20 18:07:38 -08:00
Deyton Sehn
f7754a2927 Turn on COMBINE_HIDPI_IMAGES to comply with Xcode 4.6 recommended settings 2013-02-20 17:31:30 -08:00
Deyton Sehn
125d12798d Adds Xcode-generated contents.xcworkspacedata 2013-02-20 17:31:30 -08:00
Deyton Sehn
d3bec4e686 Ignore build directory and xcuserdata so Xcode-generated artifacts don't clog up index 2013-02-20 17:31:30 -08:00
Jacob Johnson
1b0e4a0067 Update doc_src/contains.txt
Escaped the $
2013-02-20 17:17:53 -08:00
Kenneth Vestergaard
286bef5eb7 Fix crash when /etc/{fstab,hosts} is unreadable. 2013-02-20 12:30:36 -08:00
ridiculousfish
c9b4163e23 Fix a crash when redirecting a nonexistent file to a function
https://github.com/fish-shell/fish-shell/pull/574
2013-02-20 12:25:01 -08:00
ridiculousfish
fbedf020bc Null initialize an ivar (oops) 2013-02-19 23:16:44 -08:00
ridiculousfish
d3e9183303 Add a note to the documentation about fish_user_paths 2013-02-19 18:05:20 -08:00
ridiculousfish
aaa0c25ff7 Large set of changes to how PATH is handled. Changed fish to no longer modify PATH in share/config.fish. Introduced variable fish_user_paths, and a glue function __fish_reconstruct_path that splices together PATH with fish_user_paths. Changed fish to no longer validate changes to PATH unless the paths are new (i.e. don't recheck what's already there). Modified certain sets to store const wchar_t instead of wcstring to save a few allocations.
https://github.com/fish-shell/fish-shell/issues/527
2013-02-19 18:05:20 -08:00
Jan Kanis
2f43584727 small tweak to alias.fish: always add some prefix if in danger of infinite recursion 2013-02-19 22:58:55 +01:00
ridiculousfish
e7c1cb7185 Move autogenerated completions to ~/.config/fish/generated_completions/
https://github.com/fish-shell/fish-shell/issues/576
2013-02-17 16:14:36 -08:00
ridiculousfish
911c37e63e Fix for issue where backward kill line crashes if performed while the cursor is on a newline
https://github.com/fish-shell/fish-shell/pull/580
2013-02-17 14:22:27 -08:00
ridiculousfish
8b40f09e17 Add function wrapper for mimedb 2013-02-17 12:56:56 -08:00
ridiculousfish
93dfb6f7d6 Teach build_documentation.sh to not generate the test man page on any platform, or the open man page on OS X. The system man pages are better. 2013-02-16 13:35:59 -08:00
ridiculousfish
547b0a9850 Fix warning about realloc in xdgmimemagic 2013-02-16 13:17:43 -08:00
ridiculousfish
4416753df0 More cleanup based on static analysis
https://github.com/fish-shell/fish-shell/issues/575
2013-02-16 02:38:13 -08:00
ridiculousfish
dc54ec5b2b Migrate connection_t from storing a huge buffer to a std::vector 2013-02-16 01:28:46 -08:00
ridiculousfish
b682c4102e Eliminate next pointer from connection_t, turn connections into a std::list 2013-02-16 00:32:15 -08:00
ridiculousfish
6d522e6ed6 First round of fixes based on cppcheck
https://github.com/fish-shell/fish-shell/issues/575
2013-02-16 00:02:40 -08:00
ridiculousfish
635c87d629 Teach fish how to clean up installed versions of set_color 2013-02-15 15:38:08 -08:00
ridiculousfish
a355cf24f1 Teach set_color to call setupterm so it doesn't crash when run non-interactively 2013-02-15 14:00:25 -08:00
ridiculousfish
bc7ad955a3 Remove set_color.cpp from Xcode project 2013-02-15 12:24:52 -08:00
ridiculousfish
05125341f1 bulitin_set_color.cpp -> builtin_set_color.cpp 2013-02-14 16:56:10 -08:00
ridiculousfish
12332328c1 Remove set_color from Makefile. Fix issue where builtin_set_color would mix output modes up 2013-02-14 16:46:54 -08:00
ridiculousfish
8d95d0834d First stab at builtin set_color. Moved set_color.cpp to builtin_set_color.cpp and taught fish about it. 2013-02-14 15:52:24 -08:00
ridiculousfish
db5eebd372 Add function for fish_indent so that it does not need to be in PATH, in preparation for making fish no longer need to set PATH 2013-02-13 14:44:10 -08:00
ridiculousfish
b119b4f1da Fix to look up fish_pager in __fish_bin_dir instead of by using PATH, in preparation for making fish no longer need to modify PATH 2013-02-13 13:22:29 -08:00
Siteshwar Vashisht
694ab455cd Fixed broken export_func
Fix for https://github.com/fish-shell/fish-shell/issues/573
2013-02-12 13:50:43 +01:00
ridiculousfish
46edc07ae4 Clean up export_func 2013-02-12 00:14:27 -08:00
ridiculousfish
2a7fc9c3a5 Clean up env_var_table_t. Switch from storing var_uni_entry_t* to var_uni_entry_t. Various other cleanups. 2013-02-11 23:16:50 -08:00
Cheer Xiao
be23c0755e exec(): Fix a stupid crash. Remove commented debug code that became invalidated. 2013-02-11 22:05:48 -08:00
Cheer Xiao
db55176212 In exec(), only add and remove pipe_{read,write} when necessary 2013-02-11 22:05:48 -08:00
Cheer Xiao
66a445f043 Make io_file_t members const 2013-02-11 22:05:47 -08:00
Cheer Xiao
6527a48897 Make io_fd_t members const, make close_fd bool 2013-02-11 22:05:47 -08:00
Cheer Xiao
3f9706a7f3 Make io_data_t::fd const
In exec(), pipe_{write,read} no longer get reused.
2013-02-11 22:05:47 -08:00
ridiculousfish
41fc3bcb74 Remove some debugging code inadverently left in __fish_complete_cd.fish 2013-02-11 14:42:23 -08:00
ridiculousfish
d46859b9e8 Add an icon to fish.app 2013-02-05 21:50:33 -08:00
Jan Kanis
51a955c75c remove __warn_unused attribute from exec_subshell 2013-02-06 01:11:46 +01:00
Jan Kanis
9a89da3b33 merge branch 'bug-537' and branch 'bug-read-ctrlC'. This should fix both #537 and #516 2013-02-05 23:16:18 +01:00
Jan Kanis
e8da9999f6 optimize 'alias', fixing bug #486. Also some minor optimizations in 'type' 2013-02-05 23:14:06 +01:00
Jan Kanis
3f5c02bf92 rename reader_cancel_thread to reader_thread_job_is_stale, update comments 2013-02-05 21:28:23 +01:00
ridiculousfish
e918851902 Formatting 2013-02-03 11:38:22 -08:00
Cheer Xiao
e411bac592 Fix comments in proc.h (spelling, wording, format) 2013-02-03 09:33:26 +08:00
ridiculousfish
ded81ec186 Teach fish how to put completion data inside a closing quote
Fixes https://github.com/fish-shell/fish-shell/issues/552
2013-02-02 14:50:22 -08:00
ridiculousfish
cd276030c1 Tweak config.fish to only modify PATH once, for performance 2013-02-01 17:18:12 -08:00
ridiculousfish
818533f9f0 Add a newline to prevent a comment from being cut off 2013-02-01 17:15:35 -08:00
ridiculousfish
ff7cbab991 Add man function to promote fish's man pages so it can serve as a suitable replacement for help 2013-02-01 17:11:22 -08:00
ridiculousfish
ad8d68dd43 Make subcommands modify $status, and make builtin_set not modify status unless it fails
https://github.com/fish-shell/fish-shell/issues/547
https://github.com/fish-shell/fish-shell/issues/214
2013-01-31 15:57:08 -08:00
jonkerz
0db1b6ce44 Update share/completions/uname.fish
Typo: verion --> version
2013-01-31 00:09:06 -08:00
ridiculousfish
843d5a5977 Make a git variable local 2013-01-31 00:07:16 -08:00
ridiculousfish
406d7f1a47 commit bc4f3476cded71a096adf46534784cdd84edb913
Author: U0 <rhyzix@gmail.com>
Date:   Wed Jan 30 15:02:23 2013 +0800

    add completion support for aliased command
    Make a variable local
2013-01-30 23:59:52 -08:00
Kevin Ballard
7df89566f3 Fix __fish_git_prompt's upstream indicator for git-svn branches 2013-01-30 22:02:51 -08:00
Kevin Ballard
32b2c9fc9e Update __fish_git_prompt.fish to use 'else if' 2013-01-30 21:57:59 -08:00
ridiculousfish
3f8baeba20 Attempt to further improve fish's handling when it runs out of fds, and plug some fd leaks 2013-01-30 03:08:06 -08:00
ridiculousfish
1879dc4b59 Initial set of changes working to make fish robust against running out of file descriptors 2013-01-30 02:22:38 -08:00
ridiculousfish
ea8c6bc15e Try to make Valgrind completion not complain if valgrind is not installed 2013-01-30 02:22:22 -08:00
ridiculousfish
4683ce2771 Fix unused return value warning a different way 2013-01-27 14:04:44 -08:00
ridiculousfish
798537d47b Fixed an unused variable warning 2013-01-27 13:50:30 -08:00
ridiculousfish
0257b02a8c Fix to output the prompt even if fish_prompt fails 2013-01-27 13:44:32 -08:00
ridiculousfish
27e71c5f37 Fix funced to stop outputing an error if no EDITOR is set 2013-01-27 13:14:24 -08:00
ridiculousfish
cddf7e0986 Clean up man page parser output a bit 2013-01-27 12:58:52 -08:00
ridiculousfish
2b35b3f06e Fix umask in Linux https://gist.github.com/4627181 2013-01-26 12:49:37 -08:00
ridiculousfish
92b2376c23 Indent switch + case properly. https://github.com/fish-shell/fish-shell/issues/530 2013-01-24 14:59:52 -08:00
ridiculousfish
412902e4ae Fix for an issue where the newline character would appear on blank lines. Instead of inverting the newline character, draw it in gray. 2013-01-24 12:08:32 -08:00
Jan Kanis
29fda9cb6c make the casting magic standards compliant and avoid compiler warnings; add error check 2013-01-24 15:09:45 +01:00
Jan Kanis
e7b3f5745c replace compiler-supported TLS with pthread_get/setspecific; remove GPLv3 code from two commits ago 2013-01-24 14:29:13 +01:00
Cheer Xiao
268d64d244 Fix spelling: s/inetrnal/internal/g 2013-01-24 19:20:09 +08:00
Cheer Xiao
8f045b9ec5 Fix spelling: s/circut/circuit/g 2013-01-24 19:20:06 +08:00
Cheer Xiao
2ea1c2be92 Fix spelling: s/compeltion/completion/g 2013-01-24 19:20:02 +08:00
ridiculousfish
5e9ca72731 Break up $EDITOR before passing it to type to allow it to contain flags
More work on https://github.com/fish-shell/fish-shell/issues/541
2013-01-23 18:24:49 -08:00
ridiculousfish
debfc0f712 Allow $EDITOR to be an array. Fixes https://github.com/fish-shell/fish-shell/issues/541 2013-01-23 17:14:22 -08:00
Jan Kanis
1e65e7c996 extra comments 2013-01-23 01:29:24 +01:00
Jan Kanis
d12b1650aa make threadlocal use conditional on configure check. NB: This revision mixes GPLv2-only and GPLv3+ code so should be considered proof of concept. 2013-01-23 01:03:12 +01:00
Jan Kanis
70a75dc88a implement reader_cancel_thread using __thread thread-local storage 2013-01-23 00:19:29 +01:00
Siteshwar Vashisht
fa090f2c9f Initial version of printf builtin 2013-01-22 18:07:28 +01:00
Jan Kanis
b6bd6e399d tweak reader interrupt behavior 2013-01-22 11:57:47 +01:00
Jan Kanis
a3b497b271 rename reader_data_t.interruptible to exit_on_interrupt 2013-01-22 11:28:04 +01:00
Jan Kanis
55b3cf4627 move work out of interrupt handler (which is safer as well) 2013-01-22 11:19:01 +01:00
Jan Kanis
eb1c00c56b fix comments on #516. Split reader_interrupted into a reader_interrupted and a reader_reading_interrupted 2013-01-22 11:00:02 +01:00
Jan Kanis
c58278758c reader_interrupted() should only be called on the main thread. fixes #537 2013-01-22 10:27:14 +01:00
ridiculousfish
3d0d9a250b Remove Goodbye message. https://github.com/fish-shell/fish-shell/issues/521 2013-01-21 14:54:15 -08:00
Cheer Xiao
274f018494 Remove trailing whitespaces 2013-01-21 10:34:18 +08:00
Jan Kanis
970d05df39 make the read builtin respect ctrl-C 2013-01-20 23:38:21 +01:00
Jan Kanis
abae08a9fb create reader_data_t.interruptible flag and infrastructure to make it work. 2013-01-20 23:38:21 +01:00
Cheer Xiao
a0edee51fa Fix typo 2013-01-21 00:29:23 +08:00
Cheer Xiao
887474d607 Use double quotes in eval.fish 2013-01-20 15:55:10 +01:00
Siteshwar Vashisht
3bf3c11b0b Added reference to packages built on OBS repository in README.md 2013-01-20 13:12:10 +05:30
ridiculousfish
6d61919941 Rearrange some variables for possibly better alignment. int -> bool 2013-01-19 13:32:12 -08:00
ridiculousfish
e07de09460 Big cleanup of env_set. Changed var_table_t to use direct var_entry_t instead of pointers. Changed some ints to bools. 2013-01-19 13:32:06 -08:00
ridiculousfish
98a17f4046 Remove some functions which were rendered trivial by xiaq's changes. Make io_file_t take its path directly. Make io_buffer_t no longer use a shared_ptr for its data. 2013-01-19 10:59:43 -08:00
ridiculousfish
f850c021b7 Merge branch 'split-io' of git://github.com/xiaq/fish-shell into xiaq-split-io 2013-01-18 16:17:31 -08:00
Cheer Xiao
8600243683 Fix two clang warnings 2013-01-17 22:45:06 +08:00
Jan Kanis
c6e5987480 add a JOIN_THREADS_BEFORE_FORK preprocessor flag to help debug locking problems 2013-01-17 13:14:05 +01:00
Cheer Xiao
e0c858478a Revert "Make io_buffer_t::out_buffer a raw pointer, initialize in io_buffer_t's constructor"
This reverts commit d48ffab9d67da48cf45c2f5560c21a767144545f.

Conflicts:
	io.cpp
	io.h
2013-01-17 15:55:06 +08:00
Cheer Xiao
a3b15b995e Make io_data_t::io_mode const
A protected constructor is needed in io_pipe_t to let io_buffer_t override
its io_mode.
2013-01-17 15:55:06 +08:00
Cheer Xiao
57ef5289fe Make is_input a member of io_pipe_t 2013-01-17 15:55:06 +08:00
Cheer Xiao
a63c0311bb Make io_buffer_t::out_buffer a raw pointer, initialize in io_buffer_t's constructor 2013-01-17 15:55:05 +08:00
Cheer Xiao
9808829ece Make io_data_t pure virtual, its constructor protected 2013-01-17 15:55:05 +08:00
Cheer Xiao
00b6431ad9 Split out io_pipe_t, let io_buffer_t inherit it 2013-01-17 15:55:05 +08:00
Cheer Xiao
e020ad0c06 Convert io_buffer_read to io_buffer_t::read 2013-01-17 15:55:05 +08:00
Cheer Xiao
df0c1eb32c Add missing virtual qualifier to ~io_buffer_t 2013-01-17 15:55:05 +08:00
Cheer Xiao
9057801c4b Convert io_buffer_create to static io_buffer_t::create, make io_buffer_t constructor private 2013-01-17 15:55:05 +08:00
Cheer Xiao
0f443ef37b Convert io_buffer_destroy to ~io_buffer_t 2013-01-17 15:55:05 +08:00
Cheer Xiao
a20e0b9e2e Split out io_buffer_t, make input_redirect in exec() a raw pointer 2013-01-17 15:55:05 +08:00
Cheer Xiao
4b6bd7cae5 Split out io_file_t 2013-01-17 15:55:05 +08:00
Cheer Xiao
6f35792c74 Split out io_fd_t 2013-01-17 14:58:53 +08:00
Cheer Xiao
f1b375b042 Split out io_close_t 2013-01-17 14:58:53 +08:00
Cheer Xiao
4e672427bc parser.cpp: Put off initialization of new_io until mode is known 2013-01-17 14:58:53 +08:00
Cheer Xiao
165068c81d Put io_data_t detail printing in virtual io_data_t::print 2013-01-17 14:58:53 +08:00
Cheer Xiao
89993e9cbf Let io_data_t constructor take optional io_mode and fd 2013-01-17 14:58:52 +08:00
Cheer Xiao
78ab7e7ba1 Introduce a macro CAST_INIT to abbreviate common static_cast's a bit
This macro doesn't work with type names containing commas, but that doesn't
seem to be too common in fish.
2013-01-17 14:58:48 +08:00
Cheer Xiao
424bb589a2 Make io_data_t destructor virtual 2013-01-17 14:54:18 +08:00
Cheer Xiao
664fee5c6e Use new IO_INVALID as default value of io_data_t::io_mode 2013-01-17 14:54:18 +08:00
Cheer Xiao
146a353085 rename enum io_mode -> io_mode_t; make io_data_t::io_mode that type 2013-01-17 14:54:18 +08:00
ridiculousfish
214ef3dd0b Formatting 2013-01-16 14:50:08 -08:00
ciembor
406c8a6d1e Ajax fix for Firefox, it isn't XML. 2013-01-16 14:45:59 -08:00
ridiculousfish
6416cb45fb Fix proc and pid completion on OS X, and improve it on Linux.
https://github.com/fish-shell/fish-shell/pull/129
2013-01-16 14:11:43 -08:00
ridiculousfish
1db7c6233b Fix for missing first character in completions 2013-01-13 21:56:23 -08:00
Jan Kanis
640beafa8c fix a memory leak in profiling, add a profiling test 2013-01-14 01:38:05 +01:00
Jan Kanis
44f70d2b52 stop profile switch from crashing (issue #517); also make print_profile use a loop instead of recursion 2013-01-14 00:49:32 +01:00
ridiculousfish
acbb6fb8e2 Make umask work on OS X
https://github.com/fish-shell/fish-shell/issues/515
2013-01-12 15:35:40 -08:00
ridiculousfish
1163961927 Actually add the seq function (oops) 2013-01-12 15:22:09 -08:00
ridiculousfish
e1190eb1f3 Remove seq.in, in favor of the new function. Remove seq detection from configure.ac. Teach the Makefile how to remove old installed seqs. 2013-01-12 15:18:19 -08:00
ridiculousfish
dc37a8079e Added a seq function that defers to the seq command if present
https://github.com/fish-shell/fish-shell/issues/137
2013-01-12 14:18:34 -08:00
ridiculousfish
373cca0bf6 Formatting 2013-01-12 12:55:23 -08:00
ridiculousfish
b32fcc7a8e Don't call expand_home_directory from within parser_t::test - it may hang
https://github.com/fish-shell/fish-shell/issues/512
2013-01-12 12:53:40 -08:00
ridiculousfish
e9c226b8be Fix for issue where completing in the middle of a command may append extra junk at the end of the completions in the list
https://github.com/fish-shell/fish-shell/issues/301
2013-01-12 11:54:02 -08:00
Jan Kanis
af9d611847 use debug_safe in postfork do_builtin_io. Closes #495 2013-01-12 19:13:45 +01:00
ridiculousfish
9d6c4fa678 Make do_builtin_io multi-fork safe, moved it to postfork.cpp
Addresses https://github.com/fish-shell/fish-shell/issues/495
2013-01-11 15:09:53 -08:00
Cheer Xiao
b66233de78 Revert "Revert shared_ptr<io_data_t> changes until kinks are ironed out"
This reverts commit 77f1b1f0fe.
2013-01-11 14:18:10 -08:00
Cheer Xiao
ff49792f44 exec.cpp:exec: Don't remove block_io elements from j->io
When dulicate_prepend prepend copies of block_io elements to j->io, the
removing simply does nothing. Now that the same pointers are prepended to
j->io, don't remove them.
2013-01-11 14:18:10 -08:00
ridiculousfish
b2abd963f0 Fix an exception when parsing a multi-line command that ends in cd
https://github.com/fish-shell/fish-shell/issues/511
2013-01-11 12:58:52 -08:00
Liam Howell
0ab9cf8054 Fixed a minor typo: standrard -> standard 2013-01-10 20:50:52 +05:30
ridiculousfish
c70e92e98d Don't call strerror or perror after fork, it's unsafe. Added safe_strerror and safe_perror replacements.
Fixes https://github.com/fish-shell/fish-shell/issues/495
2013-01-09 17:06:20 -08:00
ridiculousfish
bf10d6c03b Tweak test_fork to exercise strerror 2013-01-09 09:36:52 -08:00
ridiculousfish
de084b4a0d Make create_manpage_completions not generate empty files
https://github.com/fish-shell/fish-shell/issues/506
2013-01-08 14:58:27 -08:00
Christian Rishøj
e46cbea251 completions for mosh (http://mosh.mit.edu) 2013-01-08 12:32:49 -08:00
Cheer Xiao
7f6e63aba5 Make "Checking how to use..." lower case.
The configure script generated by autoconf uses lower case "checking". Let's
keep in line. :)
2013-01-08 23:05:19 +08:00
ridiculousfish
25081f60c4 Make fish_config prompt color changes work more often
Fixes https://github.com/fish-shell/fish-shell/issues/505
2013-01-08 02:56:45 -08:00
ridiculousfish
91bf41cfce Document new MAC address behavior 2013-01-08 02:43:14 -08:00
ridiculousfish
552d8f394e Make fishd base its variable files on the MAC address instead of hostname
Fixes https://github.com/fish-shell/fish-shell/issues/183
2013-01-08 02:39:22 -08:00
Cheer Xiao
f8e01628b2 Keybinding of \ew and \ed: Insert a newline before displaying info 2013-01-07 19:32:38 -08:00
ridiculousfish
3d1ad89963 Teach build_documentation.sh to look in /Applications/Doxygen.app 2013-01-07 19:29:33 -08:00
ridiculousfish
2188bb9b88 Teach Xcode project how to build successfully without Doxygen 2013-01-07 14:58:56 -08:00
lledey
f0000ea7d2 Re-enable alias redefinition
Fixes #494

Signed-off-by: lledey <lledey@gmail.com>
2013-01-07 15:09:32 +01:00
Jan Kanis
5b173dafae remove -fno-optimize-sibling-calls flag for non-buggy setups; add extra comment regarding ./configure arguments 2013-01-07 14:32:20 +01:00
ridiculousfish
c939f2ee45 Fix for an out-of-range exception when resizing the window during funced
Addresses https://github.com/fish-shell/fish-shell/issues/498
2013-01-06 15:33:50 -08:00
ridiculousfish
309dfeb6a8 Wrong sense for is_interactive_session check
Fixes https://github.com/fish-shell/fish-shell/issues/499
2013-01-06 15:19:37 -08:00
ridiculousfish
bf3e4126b2 Fix for builtin_test crash
https://github.com/fish-shell/fish-shell/issues/497
2013-01-06 14:48:46 -08:00
ridiculousfish
8a357e1866 Add some more tests for autosuggestion combining 2013-01-06 14:10:03 -08:00
ridiculousfish
b8135574c3 Pass -f to rm share/man/man1 to avoid a benign error message 2013-01-06 14:03:29 -08:00
ridiculousfish
85fdf587c0 When the user input contains capital letters, use its case rather than the autosuggestion's case
Fixes https://github.com/fish-shell/fish-shell/issues/335
2013-01-05 15:21:42 -08:00
ridiculousfish
8d4a701f86 Implement builtin [ via builtin test 2013-01-05 01:30:03 -08:00
ridiculousfish
1c83144773 Reset the color before we clear to eol
Fixes https://github.com/fish-shell/fish-shell/issues/493
2013-01-04 22:32:40 -08:00
ridiculousfish
edb973fadc Hack around xdm's dumb assumption that the login shell is POSIX compliant so we no longer kill OpenSUSE
https://github.com/fish-shell/fish-shell/issues/367
Also fix some formatting
2013-01-04 13:09:01 -08:00
ridiculousfish
77f1b1f0fe Revert shared_ptr<io_data_t> changes until kinks are ironed out
https://github.com/fish-shell/fish-shell/pull/487

Revert "Merge branch 'oo-io' of git://github.com/xiaq/fish-shell into xiaq-oo-io"

This reverts commit f3c8f535a4, reversing
changes made to b02f6cf3bc.

Also reverts ac023f7588 and a79d3c680c
2013-01-04 02:05:30 -08:00
ridiculousfish
a79d3c680c Remove io_duplicate, which is no longer used 2013-01-04 01:05:35 -08:00
ridiculousfish
ac023f7588 Replace some shared_ptrs with const shared_ptr &. Don't use shared_ptr in postfork.cpp. Eliminate copy constructor in io_data_t. Simplify some other uses of shared_ptr<io_data_t> 2013-01-04 00:22:12 -08:00
ridiculousfish
f3c8f535a4 Merge branch 'oo-io' of git://github.com/xiaq/fish-shell into xiaq-oo-io 2013-01-03 16:52:56 -08:00
ridiculousfish
b02f6cf3bc Teach the Xcode project how to install the man pages 2013-01-03 16:35:23 -08:00
ridiculousfish
b7c4a4fc3b Teach Xcode how to pass arguments to build_documentation.sh 2013-01-03 15:26:29 -08:00
ridiculousfish
9f33050a32 Change build_documentation to take its paths as arguments, and the Makefile.in to pass them 2013-01-03 15:17:48 -08:00
ridiculousfish
f73caeb6a3 Make the Makefile mv man pages instead of cp them from help_doc, because help_doc is about to be deleted 2013-01-03 10:58:08 -08:00
ridiculousfish
15da4aaec7 Make share/man/man1 manpages get built again
Addresses https://github.com/fish-shell/fish-shell/issues/491
2013-01-03 10:50:19 -08:00
Jan Kanis
9ee7b0a501 really fix bug in export status of universal vars; add tests for that bug 2013-01-02 23:31:30 -08:00
Jan Kanis
3c116f6ab3 fix bug in export status of universal variable assignment 2013-01-02 23:31:30 -08:00
Vincent Driessen
431ef224e0 Remove origin/HEAD lines from __fish_git_branches.
Related discussion:
http://stackoverflow.com/questions/354312/why-is-origin-head-shown-when-running-git-branch-r
2013-01-02 08:16:42 +01:00
Jan Kanis
600aeb6ccc re-enable tests that were accidentally disabled in 0b1e3718 2013-01-01 23:06:41 +01:00
Jan Kanis
a4c646f75c make 'alias' check for recursive calls and insert 'command'; update docs, fix #486 2013-01-01 22:56:08 +01:00
Cheer Xiao
7f35f98d7d Use const shared_ptr<io_data_t>& instead of copying where appropriate. 2013-01-01 15:51:36 +08:00
Cheer Xiao
8b10b0a614 Convert all io_data_t copying to shared_ptr copying.
Copy constructor of io_data_t is removed.
2013-01-01 00:37:50 +08:00
Cheer Xiao
a9ada13a23 Use shared_ptr to manage io_data_t*. 2012-12-31 23:54:17 +08:00
Jan Kanis
1ae0e5d7cb parsing numbers imho better uses + rather than | 2012-12-30 01:55:48 +01:00
Jan Kanis
808fac9b14 document set -L/--long option 2012-12-29 11:56:11 -08:00
Jan Kanis
737972be2f clarify docs on variable scope in functions 2012-12-29 11:56:10 -08:00
ridiculousfish
4cb70e8e2a Fix a bad use of test 2012-12-27 21:40:23 -08:00
ridiculousfish
abf3ee6563 Another attempt to make build_documentation.sh work in Linux 2012-12-27 21:39:11 -08:00
ridiculousfish
1a0a3d85ca Try to make mktemp work on Linux 2012-12-27 21:12:22 -08:00
ridiculousfish
1bbac9e5ce Make the Makefile use the new build_documentation.sh script (gulp) 2012-12-27 20:33:13 -08:00
ridiculousfish
705793eae6 Make fish more robust when multiple instances are started at once 2012-12-27 20:26:16 -08:00
ridiculousfish
efa6e38741 Factored out help_doc generation into build_tools/build_documentation.sh 2012-12-27 17:31:13 -08:00
ridiculousfish
183aea5c96 Teach help how to not drop fragments on OS X 2012-12-27 14:04:11 -08:00
ridiculousfish
97ddf9a4f3 Teach help how to go to the web if documentation is not installed 2012-12-27 13:39:43 -08:00
ridiculousfish
489366290a Re-point some URLs at the fish homepage fishshell.com 2012-12-27 02:17:14 -08:00
ridiculousfish
fb8f16373f Teach fish_print_commands how to use __fish_datadir 2012-12-27 00:46:54 -08:00
ridiculousfish
fed352653d Re-teach Makefile.in how to generate proper version numbers in man pages 2012-12-27 00:38:29 -08:00
ridiculousfish
a697b2b60e Made autoconf stop generating Doxyfile.help in preparation for Xcode documentation build phase 2012-12-26 23:48:11 -08:00
ridiculousfish
efe9c82bc6 Formatting 2012-12-26 22:08:49 -08:00
ridiculousfish
2bdb199169 Update OS X build instructions 2012-12-26 21:30:03 -08:00
David Adam (zanchey)
d0dabb0ff6 documentation TOC: remove duplicate name attributes, use id attribute instead 2012-12-26 21:10:29 -08:00
David Adam (zanchey)
27e4ece24f add __fish_print_commands and use it for help 2012-12-26 21:09:50 -08:00
ridiculousfish
fc898eff65 Move make_vcs_completions.py to build_tools, and eliminate make_completions.py, which was a manage parser - we have a much better one now 2012-12-26 18:57:47 -08:00
ridiculousfish
dd317709f8 Fix to avoid suggesting files for empty tokens 2012-12-26 15:28:25 -08:00
Jan Kanis
fde9842a8e fix signal race 2012-12-24 23:06:09 -08:00
ridiculousfish
3bf88110aa Removal of more lingering wcs2str() 2012-12-24 20:55:35 -08:00
Daniel James
cc5c411039 Remove leftover use of str2wcs. 2012-12-24 12:25:04 +00:00
ridiculousfish
37bdb20092 Make event_block_t.event not a reference
Stylistic tweaks
2012-12-22 12:40:34 -08:00
ridiculousfish
e31431140a Formatting 2012-12-22 12:21:31 -08:00
ridiculousfish
8a66ba6c35 Merge branch 'event-bug-test' of git://github.com/JanKanis/fish-shell into JanKanis-event-bug-test 2012-12-22 12:20:41 -08:00
Jan Kanis
8a446f43ff include fixes and suggestions from code review 2012-12-22 18:38:28 +01:00
Cheer Xiao
d6b5558cf2 Clean up initialization of pipe_{read,write} in exec() a bit. 2012-12-21 15:45:35 -08:00
ridiculousfish
50c04752f5 Make skip_fork a bool 2012-12-21 15:43:38 -08:00
ridiculousfish
2a91a7640c Make echo recognize -ne 2012-12-20 18:10:08 -08:00
ridiculousfish
6b35250099 Make meta-backspace less aggressive about what it deletes 2012-12-20 17:58:09 -08:00
ridiculousfish
2ba92f92b7 Fix for an exception in a non-interactive shell with empty input 2012-12-20 17:45:35 -08:00
ridiculousfish
0b1e371880 Changes to work recognition per https://github.com/fish-shell/fish-shell/issues/384
Word movement should be very similar to fish 1.x
backward-kill-word remains more liberal, but now stops at any of {,'"=}
2012-12-20 17:37:09 -08:00
ridiculousfish
ce15abd577 Rewrite str2wcstring to properly handle embedded nulls, and be simpler 2012-12-20 12:25:35 -08:00
Jan Kanis
30392bf66a reference'ize event.cpp/h 2012-12-20 16:13:14 +01:00
Jan Kanis
71233ee894 Make event_t.arguments into a vector instead of an auto_ptr<vector>.
Yay for less indirection and less code! The resulting event_t structure is two pointers larger, but cuts out an indirection and allocation.
2012-12-20 16:13:14 +01:00
Jan Kanis
af3059ab2a Allow 'emit' to accept event arguments 2012-12-20 16:13:00 +01:00
Jan Kanis
1f0ae8b06d fixed #449, added test 2012-12-20 16:11:46 +01:00
ridiculousfish
d5af389d2e Simplify exec_subshell_internal 2012-12-19 16:40:10 -08:00
ridiculousfish
644607c29f Eliminate str2wcs 2012-12-19 13:31:06 -08:00
Jan Kanis
aa477195d4 testing for bug #449 2012-12-19 16:57:11 +01:00
Mikko Viitamäki
b0a9a5a756 Replace darcs repositories by git repos. 2012-12-18 11:45:47 -08:00
ridiculousfish
882a62ad52 Attempt to fix process expansion on Linux
Hopefully addresses https://github.com/fish-shell/fish-shell/issues/455
2012-12-18 11:37:54 -08:00
Cheer Xiao
f9697c8e36 Apply the same fix to help completion too. 2012-12-17 20:08:45 -08:00
Cheer Xiao
0479060858 A quick fix to issue #456. 2012-12-17 20:08:45 -08:00
Alex Rosenberg
c2e5403408 Add confdefs.h to .gitignore 2012-12-17 20:07:24 -08:00
Cheer Xiao
3d2b12e72a Fix spelling of "available" in complete functions. 2012-12-16 12:24:05 +08:00
Cheer Xiao
09b1eee5d0 Random fixes to comments. 2012-12-16 12:23:24 +08:00
Cheer Xiao
28264423a4 Fix man completion: suppress stderr of aprops 2012-12-16 01:25:27 +08:00
ridiculousfish
87baa4d3d2 Eliminate usage of __mb_cur_max, try to fix Linux build 2012-12-12 21:09:42 -08:00
ridiculousfish
c5031c2b39 Output embedded null characters more often
https://github.com/fish-shell/fish-shell/issues/444
2012-12-12 15:44:01 -08:00
lledey
82223d3bad Remove -rdynamic compilation flag for OSX
This flag is used for the backtrace() function. It provides more information
for the backtrace on Linux, but is useless on OSX.
Signed-off-by: lledey <lledey@gmail.com>
2012-12-12 13:23:16 -08:00
Anders Bergh
56dd25667d Make fish_config compatible with Python 2.5
Try to import parse_qs from the cgi module, and simplejson instead of json.
Use old string formatting. str.format() was backported from Python 3
to 2.6 and isn't available in 2.5.
2012-12-12 12:51:55 +01:00
ridiculousfish
d4a171a791 Fix to make fish_command_not_found_handler run the first time 2012-12-11 16:08:37 -08:00
ridiculousfish
978066a6de Attempt to delay looking up command-not-found until the first not-found command to speed up startup 2012-12-11 16:00:49 -08:00
ridiculousfish
2628da4a59 Removed some debugging code used in determining autosuggestion truncation
Fixed a busted link in the function doc
2012-12-11 14:44:41 -08:00
ridiculousfish
ccb157c7a3 Remove tokenizer_test target and codeT 2012-12-11 13:22:13 -08:00
ridiculousfish
d43c803bfe Fix for build errors with g++ 4.0.1 2012-12-11 13:18:40 -08:00
ridiculousfish
eec6db0a23 forward-word should accept a word of an autosuggestion
https://github.com/fish-shell/fish-shell/issues/435
2012-12-10 16:23:08 -08:00
David Adam (zanchey)
983bc5cecc scp completions - describe usernames as usernames 2012-12-10 01:30:40 +05:30
David Adam (zanchey)
60435f99b9 fix typo in hostname completion 2012-12-10 01:30:40 +05:30
ridiculousfish
332cda6b16 Merge pull request #430 from lledey/master
Fix compilation for Python dependencies suppression.
2012-12-08 23:05:48 -08:00
lledey
8d73f2af34 Fix compilation with Python dependencies suppression.
Signed-off-by: lledey <lledey@gmail.com>
2012-12-09 07:48:08 +01:00
ridiculousfish
6a8219a02e Remove Python dependency from Makefile and Xcode build
https://github.com/fish-shell/fish-shell/issues/429
2012-12-08 21:41:38 -08:00
ridiculousfish
c8f7d33a9a Hopeful fix for wrapping lines issue on Linux
https://github.com/fish-shell/fish-shell/issues/409
2012-12-06 02:54:25 -08:00
ridiculousfish
40ec2303ff Make fish try to detect when it's an orphaned process and then exit politely
Fixes https://github.com/fish-shell/fish-shell/issues/422
2012-12-05 13:33:07 -08:00
ridiculousfish
19eddddcff Fix for issue where history file would be read immediately on launch 2012-12-04 16:00:35 -08:00
Siteshwar Vashisht
b1e86d6fea Fixed test statement in binding for Alt-D
Fix for https://github.com/fish-shell/fish-shell/issues/421
2012-12-05 00:16:22 +05:30
ridiculousfish
b9283d48b5 Added a history speed test
Profile driven caching of config directory
Style fixes
2012-12-03 02:25:08 -08:00
ridiculousfish
33fc5c99ea Fix for a long standing race where multiple shells can overwrite each others' .tmp files, and lose history.
Added a long description of the incremental history strategy
Fixes https://github.com/fish-shell/fish-shell/issues/371
2012-12-03 01:53:52 -08:00
ridiculousfish
a4581cb233 Change the timestamp behavior for history to include items whose timestamp is the same as our birth, to better illustrate the incremental history improvements 2012-12-03 00:25:08 -08:00
ridiculousfish
36dfc9f1bf Reorder some fields to avoid a warning 2012-12-03 00:21:58 -08:00
ridiculousfish
4a55fff3b9 Turn off logging in incremental saving 2012-12-03 00:14:39 -08:00
ridiculousfish
02f16e90b6 Turn on incremental history saving (cross your fingers) 2012-12-03 00:14:22 -08:00
ridiculousfish
984a498063 More work towards incremental history. Added some tests. 2012-12-02 23:38:38 -08:00
ridiculousfish
c1b51c6530 First attempt towards supporting incremental history writes 2012-12-02 16:39:35 -08:00
ridiculousfish
224de547b3 Ensure we repaint the prompt after resetting it, when colors change.
Fixes https://github.com/fish-shell/fish-shell/issues/418
2012-12-02 11:53:34 -08:00
Jean-Daniel Dupas
43d2e15bb7 Try to fix create_manpage_completions script for system where sysgetdefaultencoding() returns ASCII. 2012-12-02 15:31:44 +01:00
ridiculousfish
ac70772070 Remove code that tries to load files in include directory
https://github.com/fish-shell/fish-shell/issues/416
2012-12-01 21:17:16 -08:00
ridiculousfish
1feea366ca Fix for off by one error with "missing newline" code 2012-12-01 20:05:49 -08:00
ridiculousfish
f599239fd4 Added xcodebuild target in Makefile 2012-12-01 20:05:35 -08:00
ridiculousfish
a122d2eb50 First attempt at appending a "missing new line" character
https://github.com/fish-shell/fish-shell/issues/397
2012-12-01 15:44:09 -08:00
ridiculousfish
17e7860700 Fix chsh completion
https://github.com/fish-shell/fish-shell/issues/415
2012-12-01 14:12:11 -08:00
ridiculousfish
34fab879cb Fix to xcodebuild
https://github.com/fish-shell/fish-shell/issues/229
2012-12-01 13:28:30 -08:00
David Adam (zanchey)
b02ed0bbe6 use sgrep instead of grep 2012-11-27 13:02:13 +08:00
David Adam (zanchey)
165ba535f0 use getent for hosts if available, otherwise use more resilient processing of /etc/hosts 2012-11-27 11:49:52 +08:00
David Adam (zanchey)
8253df7c3d use getent for passwd and group if available 2012-11-27 11:49:52 +08:00
ridiculousfish
4788da204b Additional improvements to line wrapping reliability 2012-11-26 12:31:44 -08:00
ridiculousfish
cf11d1e4e6 Additional changes to try to improve line wrapping 2012-11-25 01:26:58 -08:00
ridiculousfish
e557327860 Coalesce redundant repaints, prepare to address some resizing issues (again!) 2012-11-24 21:06:42 -08:00
ridiculousfish
e152cfac34 Change to make the lookahead array a std::stack instead of a static 4k list(!) 2012-11-24 16:58:30 -08:00
ridiculousfish
464f1f44aa Improvements to avoid clearing the screen as often, which addresses a problem where the screen may be blank
Fixes https://github.com/fish-shell/fish-shell/issues/402
2012-11-24 16:42:25 -08:00
ridiculousfish
bf27cb1f5e Further fixes to newline escaping
Addresses issue described in https://github.com/fish-shell/fish-shell/issues/347#issuecomment-10650443
2012-11-23 12:03:36 -08:00
ridiculousfish
654010f639 Grammar fix in a comment 2012-11-23 11:25:33 -08:00
ridiculousfish
918f84438f Don't autosuggest files until after we've tried (and maybe failed) to load completions
Fixes https://github.com/fish-shell/fish-shell/issues/378
2012-11-23 11:22:58 -08:00
ridiculousfish
93e2415924 Fix a memory leak 2012-11-23 11:14:16 -08:00
ridiculousfish
4837a2d0df Replaced some usage of wchar_t * with wcstring in complete(). Some style fixes. 2012-11-23 11:12:22 -08:00
ridiculousfish
be80e1a863 Improvements to man page parser, and to description truncation
Fixes https://github.com/fish-shell/fish-shell/issues/98
2012-11-22 20:32:19 -08:00
situ
e53e00c4f9 Fixed compilation error in expand.cpp
Fixed https://github.com/fish-shell/fish-shell/issues/401
2012-11-22 22:41:36 +05:30
ridiculousfish
90495f3ac5 Implement new newline-escaping behavior. Backslashes at the end of lines now essentially delete the newline, within normal text or double quotes. Backslashes are retained within single quotes.
Fixes https://github.com/fish-shell/fish-shell/issues/347
Fixes https://github.com/fish-shell/fish-shell/issues/52
2012-11-22 01:09:07 -08:00
ridiculousfish
6fc9e6f21e Make tok_first return a wcstring instead of a wchar_t* 2012-11-21 22:23:48 -08:00
ridiculousfish
7117c4a5ee Remove tok_destroy 2012-11-21 22:14:28 -08:00
ridiculousfish
a3a7c48799 Modify tokenizer to store last token in a wcstring 2012-11-21 22:09:35 -08:00
ridiculousfish
f545fb2491 Work towards refactoring tokenizer to be a real object 2012-11-21 17:48:35 -08:00
ridiculousfish
e73be48d96 Escape arguments to certain shell invocations in Makefile
https://github.com/fish-shell/fish-shell/issues/387
2012-11-21 13:42:30 -08:00
ridiculousfish
04b1b83039 Fix for buffer overrun in tokenizer for strings that end with backslash
Fixes https://github.com/fish-shell/fish-shell/issues/389
2012-11-20 14:51:30 -08:00
ridiculousfish
e9d216bc84 Fixed recursive brace expansion
https://github.com/fish-shell/fish-shell/issues/399
2012-11-20 13:52:53 -08:00
ridiculousfish
87510ac77d Hungary notation -> Hungarian notation 2012-11-19 13:16:50 -08:00
ridiculousfish
44ce3e6731 Changes to make word movement less aggressive
https://github.com/fish-shell/fish-shell/issues/384
2012-11-19 02:41:57 -08:00
ridiculousfish
26678682ca Fix indentation of switch statements 2012-11-19 00:31:03 -08:00
ridiculousfish
7d63900fb8 Modified project file to reflect new name 2012-11-19 00:17:54 -08:00
ridiculousfish
e47d56a84f FishsFish.xcodeproj -> fish.xcodeproj 2012-11-19 00:17:25 -08:00
ridiculousfish
9b52269a5b Updated style guide to reflect modified style 2012-11-18 16:30:53 -08:00
ridiculousfish
9992b8eb0e Apply new indentation, brace, and whitespace style 2012-11-18 16:30:30 -08:00
ridiculousfish
bab69f2672 Merge branch 'master' into fix-indentation-merge 2012-11-18 15:12:22 -08:00
Łukasz Niemier
2e33633698 More stylefixes 2012-11-18 13:52:21 +01:00
Łukasz Niemier
eb7601d116 Add styleguide 2012-11-18 13:39:37 +01:00
ridiculousfish
5827bfd9a2 Default fish_pager_color_description to '555 yellow'
Fixes https://github.com/fish-shell/fish-shell/issues/280
2012-11-18 03:17:51 -08:00
ridiculousfish
dc8cc39bc8 Don't autosuggest in builtin_read
https://github.com/fish-shell/fish-shell/issues/29
2012-11-18 02:43:35 -08:00
Łukasz Niemier
47df1ae40a Remove trailing whitespaces and change tabs to spaces 2012-11-18 11:23:22 +01:00
ridiculousfish
c9c2fc5ee3 Restore terminal foreground process group on exit
Fixes https://github.com/fish-shell/fish-shell/issues/197
2012-11-18 02:16:14 -08:00
Terje Larsen
b79854ad1a Optimize staged logic 2012-11-17 13:37:32 -08:00
Terje Larsen
8229b17f0d Use double-dollar vars for dynamic variables 2012-11-17 13:37:32 -08:00
Terje Larsen
4a5d02aab4 Add configurable status signs again 2012-11-17 13:37:32 -08:00
Terje Larsen
ed4e6cd3a5 Fix uniqueness and escape question-marks 2012-11-17 13:37:32 -08:00
Sławek Piotrowski
7d45e6f12f Fix: args -> argv in __fish_git_prompt 2012-11-14 19:00:17 +01:00
ridiculousfish
0302162d8e Make tab-completion truncation less dumb
Fixes https://github.com/fish-shell/fish-shell/issues/259
2012-11-09 16:02:19 -08:00
ridiculousfish
1dfa404210 Revert "Another attempt to improve right prompt on Linux"
It didn't work

This reverts commit bd4551e2ef.
2012-11-09 15:21:08 -08:00
ridiculousfish
bd4551e2ef Another attempt to improve right prompt on Linux 2012-11-09 15:19:54 -08:00
ridiculousfish
d6a56428d1 Attempt to fix fish_right_prompt under Linux 2012-11-09 15:09:54 -08:00
David Adam (zanchey)
a10fa3a20b add $FISH_VERSION as unexported global variable to complement version 2012-11-08 10:09:51 -08:00
David Adam (zanchey)
be5fde9e54 test documentation - format examples properly 2012-11-08 10:08:06 -08:00
David Adam (zanchey)
abfc7e16a1 test documentation - correct argument listing 2012-11-08 10:08:06 -08:00
ridiculousfish
d76f880faf Support for fish_right_prompt
Fixes https://github.com/fish-shell/fish-shell/issues/80
2012-11-07 19:59:20 -08:00
ridiculousfish
21e83a881e Bring back ellipsis 2012-11-05 00:05:42 -08:00
ridiculousfish
5ba1261285 Initial right_prompt work 2012-11-04 23:21:37 -08:00
ridiculousfish
7bb844a778 Fix bug where 'else if' does not support functions and redirections
https://github.com/fish-shell/fish-shell/issues/359
2012-11-04 17:11:02 -08:00
ridiculousfish
8c24d49c73 Removed unused commented out code and fixed some indentation 2012-11-04 15:47:55 -08:00
ridiculousfish
5e371e8fe7 Don't use posix_spawn for commands that need to be put into foreground to avoid a race
Fix for race where a command's output may not be fully drained
2012-11-04 15:45:52 -08:00
ridiculousfish
e46324ced9 Wrong sense of check for initializing key bindings
Fix for https://github.com/fish-shell/fish-shell/pull/373
2012-10-30 14:36:37 -07:00
ridiculousfish
5ea486b20a Fix help completion to not barf if html file is absent 2012-10-29 01:53:10 -07:00
ridiculousfish
425afa63ce Don't use posix_spawn when file redirections are involved (except /dev/null) because the error handling is too difficult
Fix exec to correctly handle the case where a pid could not be created due to posix_spawn failing
Should fix https://github.com/fish-shell/fish-shell/issues/364
2012-10-29 01:45:51 -07:00
ridiculousfish
7c09a767b6 Don't expand jobs during syntax highlighting
Fixes https://github.com/fish-shell/fish-shell/issues/366
2012-10-28 16:35:17 -07:00
Siteshwar Vashisht
768f92303e Removed python scripts to import bash settings 2012-10-27 23:57:15 +05:30
ridiculousfish
34054fa1fb Merge pull request #362 from terlar/git-completions
Git completions
2012-10-25 18:56:59 -07:00
Terje Larsen
4a37d6d1f9 Remove remotes prefix from branches 2012-10-22 20:54:33 +02:00
Terje Larsen
8dfc8625a7 Add git completions for tracking (branch/checkout) 2012-10-22 20:50:38 +02:00
Terje Larsen
e878947cb2 Fix broken git alias completion
The previous command outputs a lot of junk, does not strip after the
white-space in OSX (10.8.2).

Tried out the new command on both Ubuntu (12.04.1) and OSX (10.8.2)
2012-10-22 20:37:47 +02:00
Terje Larsen
f56f84c6ac Use echo -n instead of printf
- Remove useless comment, because multi-line prompt works good now.
2012-10-20 12:52:53 -07:00
Terje Larsen
239d43dac4 Improve the git prompt
- Fix branch for older git version (--short for symbolic-ref was not
  available on git 1.7.9.5)
- Use index (git status) for checking if staged
- Add status indication for copied
- Remove variables for statuses (less litter in the variables)
- Remove usage of eval to echo and set_color
- Replace printf where possible with echo -n
2012-10-20 12:52:53 -07:00
ridiculousfish
8a63326411 Removed backwards compatibility check for fish_user_keybindings 2012-10-20 12:21:41 -07:00
Nate Soares
01608cf062 Normalized some inconsistent whitespace. 2012-10-20 12:15:49 -07:00
Nate Soares
e06d6ce4a2 Revive support for fish_user_keybindings
This is undocumented and here to preserve backwards compatibility.
2012-10-20 12:15:49 -07:00
Nate Soares
58a0c6f9d3 added missing underscore 2012-10-20 12:15:49 -07:00
Nate Soares
f310f1e96c keybindings → key_bindings (for consistency) 2012-10-20 12:15:49 -07:00
ridiculousfish
c7bf1aa222 Handle some more escapes in de-groffing man pages
Fixes https://github.com/fish-shell/fish-shell/issues/10
2012-10-17 18:22:57 -07:00
Adrien
be3fff9282 Add apt-cache completion for package names
Signed-off-by: Gustavo Noronha Silva <kov@kov.eti.br>
2012-10-17 18:05:49 -07:00
ridiculousfish
e52cf09bc1 Simplify handling of escape sequences in echo -e 2012-10-17 17:08:45 -07:00
ridiculousfish
57de1388e8 Make the \c special character in echo suppress the newline too 2012-10-17 02:59:43 -07:00
ridiculousfish
7ee0ce745e Implement -e option to echo (to interpret special characters), and -E to not interpret them
https://github.com/fish-shell/fish-shell/issues/337
2012-10-17 02:56:03 -07:00
ridiculousfish
469743cd23 Made set_color with no arguments not complain, so that prompts like Terlar don't produce errors for missing colors. 2012-10-17 01:25:21 -07:00
ridiculousfish
91e1d59869 Fix for issue where else if would fail to pass arguments to commands. Also implements short-circuiting for and/or so that non-existent commands don't produce error messages.
Fixes https://github.com/fish-shell/fish-shell/issues/345
Fixes https://github.com/fish-shell/fish-shell/issues/349
2012-10-17 01:07:34 -07:00
ridiculousfish
5fb97f05a3 Fixed "Expansion not correctly handling literal path components in dotfiles" test 2012-10-16 11:51:36 -07:00
ridiculousfish
618b42980d Prevent multi-line prompts from repeating during window resize
Fixes https://github.com/fish-shell/fish-shell/issues/321
2012-10-15 19:25:56 -07:00
ridiculousfish
211b9ea8b9 Added terlar's prompt, and robbyrussell which was inadvertently omitted
https://github.com/fish-shell/fish-shell/issues/329
2012-10-15 18:45:46 -07:00
ridiculousfish
833abc27cc Make wildcards beginning with dots not match . and ..
https://github.com/fish-shell/fish-shell/issues/270
2012-10-15 18:16:47 -07:00
ridiculousfish
3d5a3f03fa Fix to prevent buff_pos from underflowing in reader_kill 2012-10-08 23:47:32 -07:00
ridiculousfish
51de26960c Make escaping consistent for fish <-> fishd protocol
Fix fork guards to work in fishd
https://github.com/fish-shell/fish-shell/issues/339
2012-10-08 14:47:25 -07:00
ridiculousfish
b67526aae8 Don't reset the terminal mode in certain circumstances. Fixes issue in Linux with e.g. echo foo ; ftp
Introduce patch from 9d229cd18c
2012-10-05 18:23:38 -07:00
ridiculousfish
14bf057c62 Remove bogus path from example of "." (source) command
https://github.com/fish-shell/fish-shell/issues/297
2012-10-04 14:57:23 -07:00
ridiculousfish
8eb53ea7ca Rewrite kill behavior (aka control-W) to do something better
Fixes https://github.com/fish-shell/fish-shell/issues/327
2012-10-04 14:35:03 -07:00
ridiculousfish
9b60af4d52 Fix to propagate the last color before highlighting completes, and to avoid repainting when highlighting completes if the color does not change 2012-10-03 12:19:27 -07:00
SanskritFritz
956f99365a Some new completions and modified some others. 2012-10-02 17:54:30 -07:00
SanskritFritz
9904415144 Facelift for pacman completions. 2012-10-02 17:54:30 -07:00
SanskritFritz
83febbdc7d Package groups were completed as repos. Fixed.
By default fish expands arguments along with options. This is not desired,
so made sure they are expanded only when needed, for performance reasons.
2012-10-02 17:54:30 -07:00
ridiculousfish
6b026e399c Prevent some cases where garbage gets dumped on the screen during window resize under new soft wrapping architecture 2012-10-02 17:30:07 -07:00
ridiculousfish
a661c03743 Work on soft wrapping to address https://github.com/fish-shell/fish-shell/issues/300
Resizing is still wonky
2012-10-01 03:29:18 -07:00
Ian Munsie
ffc03735e8 Don't barf when ending a FAKE block
After updating, fish would immediately die when started in an xterm from
my window manager (wmii) with a message like:

fish: builtin.cpp:3357: int builtin_end(parser_t&, wchar_t**): Assertion `false' failed.
fish: Job 1, “~/code/fish-shell/fish” terminated by signal SIGABRT (Abort)

Starting fish from an existing shell worked, and running it on other
machines that I was only SSHing into worked as well. I did discover that
on one machine starting git from one specific directory
(/home/ian/bml/kernel) would cause this failure, but starting from any
other directory worked as normal. I'm not entirely sure what
circumstances contribute to this failure - starting from a copy of the
kernel directory works fine.

The failure only started with the following commit, which introduced the
assert(false):

commit d788c84440
Made type property of block_t constant and private
Further work towards cleaning up block_t hierarchy

Looking at this fail in gdb:

(gdb) r
Starting program: /home/ian/code/fish-shell/fish
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
fish: builtin.cpp:3357: int builtin_end(parser_t&, wchar_t**): Assertion `false' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff6c82475 in *__GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
    function=0x548520 "int builtin_end(parser_t&, wchar_t**)") at assert.c:81
(gdb) up 3
3357                    assert(false); //should never get here
(gdb) p parser.current_block->type()
$1 = FAKE

So this happens when we run an end command for a FAKE block.

The below patch adds an empty case for FAKE blocks to avoid hitting the
assert. I would need to study the code in more detail to understand if
we should even be executing this code if we are in a FAKE block, but
this patch seems to solve the issue for me.

Signed-off-by: Ian Munsie <darkstarsword@gmail.com>
2012-09-22 23:51:41 -07:00
maxfl
c7e24488eb fix output 2012-09-22 23:49:26 -07:00
maxfl
fe7d2c57e3 nmcli completions 2012-09-22 23:49:26 -07:00
Siteshwar Vashisht
4fc80b5057 Fix for displaying multiline prompts 2012-09-20 00:47:31 +05:30
Siteshwar Vashisht
12f3f5dcbb Print autocompletion description after installing
Print autocompletion shortcut description at end of 'make install'
2012-09-19 13:21:49 +05:30
Siteshwar Vashisht
16f2ffc29d Remove ellipsis and newlines from long lines
Fix for issue https://github.com/fish-shell/fish-shell/issues/300
2012-09-18 00:42:11 +05:30
Peter Ammon
86a978d9ee Fixed web_config prompt to work with Python 2.6.1 2012-09-10 02:11:06 -07:00
ridiculousfish
f6fe3df59b Fix to make prompt chooser work in Python3 2012-09-06 19:01:07 -07:00
ridiculousfish
e0764bb25e Improve python3 compatibility in webconfig.py 2012-09-06 02:03:21 -07:00
ridiculousfish
1ba0bfd10c Renamed hyperminamlist prompt 2012-09-06 01:52:21 -07:00
ridiculousfish
593ab75a76 Fix to make Makefile copy sample prompts 2012-09-06 01:40:15 -07:00
ridiculousfish
3589554028 Allow setting the prompt from web_config 2012-09-06 01:30:26 -07:00
ridiculousfish
1a59346b51 Changed "elseif" to "else if" 2012-09-03 13:24:01 -07:00
ridiculousfish
ff124465fd Clean up some warnings and some unused if-related code 2012-09-01 12:29:00 -07:00
ridiculousfish
de5223db66 Improve documentation and error reporting for elseif. 2012-09-01 02:14:13 -07:00
ridiculousfish
cc1395797e First stab at elseif implementation 2012-09-01 01:46:14 -07:00
Torsten Grust
122791646e Fix check for non-empty argument (= initial tab) in fish_config
The original version (based on 'test') was creating spurious files named "0" in the current working directory
2012-08-30 13:17:32 +02:00
ridiculousfish
a3c4de52d6 Fix braces style 2012-08-26 23:34:34 -07:00
ridiculousfish
95de6cf5a7 Migrated function_data_t out of base block class
Removed an auto_ptr (yay)
2012-08-26 23:30:23 -07:00
ridiculousfish
d788c84440 Made type property of block_t constant and private
Further work towards cleaning up block_t hierarchy
2012-08-26 23:16:20 -07:00
ridiculousfish
96046ffd30 First stab at getting rid of the ugly state1, state2 properties of block_t 2012-08-26 22:42:29 -07:00
ridiculousfish
b5e92a831b Use xdg-open instead of BROWSER, if available
https://github.com/fish-shell/fish-shell/issues/293
2012-08-25 13:02:58 -07:00
maxfl
a2788129ff Minor updates
* Add -L/--long completion for 'set' command.
* Fix completion description color.
2012-08-25 00:54:47 -07:00
ridiculousfish
5bbf220077 Fix bug where underlining was failing for paths prefixed with ~
Fixes https://github.com/fish-shell/fish-shell/issues/292
2012-08-23 11:21:35 -07:00
ridiculousfish
f5d4e3f94c Reintroduce IO transmorgrification (yuck) to fix problems with fish_config and complicated IO redirections 2012-08-22 13:41:21 -07:00
ridiculousfish
04ea680e9a Support for tab cyling through completions
https://github.com/fish-shell/fish-shell/issues/84
2012-08-21 17:18:52 -07:00
ridiculousfish
3a940781d9 Replaced README with README.md for github
Changed 'root' Xcode target to 'install_tree' to avoid confusion
2012-08-21 02:08:49 -07:00
ridiculousfish
00fcd63b88 Clean up fish.app target to build correctly. Still won't run from Xcode, but will run from Finder 2012-08-21 01:20:19 -07:00
ridiculousfish
f3093649de Improve Xcode build process to provide a real target for xcodebuild install 2012-08-20 23:50:11 -07:00
ridiculousfish
670e33ab27 Properly handle empty completions (e.g. tab-complete 'foo' with extant files 'foo' and 'foobar' should offer both)
Fixes issue described in https://github.com/fish-shell/fish-shell/issues/290
2012-08-20 13:09:21 -07:00
ridiculousfish
3606664cf7 Merge branch 'webserver' of git://github.com/simukis/fish-shell into simukis-webserver
Conflicts:
	share/tools/web_config/webconfig.py
2012-08-20 12:03:39 -07:00
ridiculousfish
81f45208b0 Make history deletion from web config work properly with Unicode under both Python2 and Python3
Make the filter search field hide properly in tabs where it's non-functional
Fixes https://github.com/fish-shell/fish-shell/issues/265
2012-08-20 11:58:54 -07:00
ridiculousfish
9145d05397 Restore correct order of IO redirections
Fixes https://github.com/fish-shell/fish-shell/issues/281
2012-08-19 14:09:39 -07:00
Simonas Kazlauskas
ef566836c4 Wipe unnecessary as statement 2012-08-19 23:26:15 +03:00
Simonas Kazlauskas
10dfca1a75 Decode data in python3 – Fixes #265.
In both in python2 and python3 parse_qs expects str object. In
python2 it worked ok, because self.rfile was open in binary mode and
str in python2 is actually a string of bytes. However in python3 str is
actually string of unicode literals, not bytes and file was still open
in binary mode. Thus, deleting any file with non-ascii byte inside
filename failed in python3.

Also, cgi.parse_qs is deprecated and shouldn't be used.
2012-08-19 23:19:07 +03:00
Simonas Kazlauskas
b3e3f041fe Remove trailing spaces and replace tabs with spaces 2012-08-19 22:55:50 +03:00
ridiculousfish
e3ec361552 Fixed indentation in next_tab_stop 2012-08-17 17:41:55 -07:00
ridiculousfish
bfccc7133d Fix for issue where init_tabs can't be modified on NetBSD 2012-08-17 17:36:52 -07:00
ridiculousfish
f41a699f5d Fix to make the choose-a-port loop work correctly for webconfig.py under Python3 2012-08-17 01:14:05 -07:00
ridiculousfish
7d029778e6 Disable file completion descriptions per https://github.com/fish-shell/fish-shell/issues/279 2012-08-15 18:20:44 -07:00
ridiculousfish
26857fabdc Real fix for https://github.com/fish-shell/fish-shell/issues/278
We forget to set the parent group ID in posix_spawn (!)
2012-08-15 17:32:57 -07:00
ridiculousfish
a9b119833a Actually work around https://github.com/fish-shell/fish-shell/issues/278 2012-08-15 17:26:54 -07:00
ridiculousfish
c5ffe8a974 Temporary workaround for SIGTIN and SIGTOU unhappiness with posix_spawn
Fixes https://github.com/fish-shell/fish-shell/issues/278
2012-08-15 17:25:33 -07:00
ridiculousfish
df1b4e1f21 Fix for missing copy-files phase in Xcode build 2012-08-15 16:54:30 -07:00
ridiculousfish
61686aff34 Adopt posix_spawn (!)
Rewrite IO chains to be a vector of pointers, instead of a linked list
Removed io_transmogrify
2012-08-15 00:57:56 -07:00
Scott Leggett
ad6645c48d Implement completion for 'dd'.
Closes #267.
2012-08-12 22:05:12 +10:00
ridiculousfish
1e328c3546 Better handle symlink loops in recursive wildcards (**)
https://github.com/fish-shell/fish-shell/issues/268
2012-08-07 02:50:12 -07:00
ridiculousfish
0e2a625815 Added some limited support for autosuggesting processes 2012-08-07 00:01:48 -07:00
ridiculousfish
6eb66770a4 Fix to make completions non-authoritative by default, which is why unknown options were always colored like errors (e.g. --rebase) 2012-08-06 23:34:55 -07:00
ridiculousfish
84729c4dfa Additional warnings cleanup, effective C++ violations, dead code removal 2012-08-05 13:24:33 -07:00
ridiculousfish
8de8877c7c Fix OS X compilation 2012-08-05 12:05:05 -07:00
ridiculousfish
fdc6c3722a Fixed a bunch of clang analyzer warnings
Simplified some memory allocations by migrating to std::string
2012-08-05 12:01:53 -07:00
Siteshwar Vashisht
deca475972 Fixed compilation on Linux
Addresses issue https://github.com/fish-shell/fish-shell/issues/264
2012-08-05 18:37:51 +05:30
ridiculousfish
ba070e21e4 Fix for stack overflow when overflowing a line 2012-08-04 18:41:14 -07:00
ridiculousfish
35e9fd1bb0 Fix for weird issues when a line becomes very long introduced by my warning fixes 2012-08-04 18:32:15 -07:00
ridiculousfish
4906609dd9 Fix for assertion failure in syntax highlighting 2012-08-04 18:02:13 -07:00
ridiculousfish
682353f9cc Fix to restore an optimization from parse_util_get_line_from_offset in a more thread-safe way 2012-08-04 17:44:14 -07:00
ridiculousfish
25c6671a87 Fix for inability to go backwards through history 2012-08-04 16:06:40 -07:00
ridiculousfish
c67702a498 Cleaned up lots of typecasts, simplified some string handling 2012-08-04 15:11:43 -07:00
ridiculousfish
5880cd88c8 Switch from int cursor[2] to struct cursor { int x; int y; } 2012-08-04 13:54:20 -07:00
ridiculousfish
54ceb4211e Additional warning fixes and migration from int to size_t or long where appropriate 2012-08-04 13:47:56 -07:00
ridiculousfish
7a46227141 More warning fixes and switching from int to long or size_t 2012-08-04 13:02:44 -07:00
ridiculousfish
b904aa78e8 Additional warning cleanup and switching from int to size_t where appropriate 2012-08-04 11:34:45 -07:00
ridiculousfish
8185bee4b8 Lots of work towards making fish build without warnings on Mountain Lion, mostly in terms of using size_t instead of int 2012-08-04 11:34:45 -07:00
ridiculousfish
2e1b3325c6 Warning cleanup 2012-08-04 11:34:45 -07:00
Rubycut
1b8f1650dc explain how to load binds automatically 2012-08-04 11:32:04 -07:00
maxfl
1070b34996 Get rid of 'nothing appropriate' output when completing.
Add watch completion.
2012-08-04 11:20:03 -07:00
Anders Bergh
13b1b73c15 Replaced references to http://fishshell.org/ with http://ridiculousfish.com/shell/. 2012-08-01 18:09:50 +02:00
ridiculousfish
e1de72d0ac Merge pull request #251 from bpinto/rbenv
completion for rbenv
2012-07-28 17:50:27 -07:00
Bruno Pinto
dc837eb8a3 completion for rbenv 2012-07-28 13:45:47 -03:00
ridiculousfish
f6b76e6ecb Fix to allow specifying an initial tab in fish_config
For example, you can run "fish_config history"
2012-07-27 13:40:43 -07:00
ridiculousfish
e7cbcc83a4 Implemented history deletion from fish_config
Fixes https://github.com/fish-shell/fish-shell/issues/250
2012-07-27 00:31:00 -07:00
ridiculousfish
390700ca71 Merge pull request #249 from kballard/git_prompt_showupstream
Fix showupstream behavior in __fish_git_prompt
2012-07-27 00:26:23 -07:00
Kevin Ballard
b604321169 Fix showupstream behavior in __fish_git_prompt
The __fish_git_prompt_show_upstream helper function was inadvertently
looking at the misnamed variable __fish_git_prompt_show_upstream in some
cases, including when implementing the bash.showUpstream override.
Fixing the script to use __fish_git_prompt_showupstream triggered an
infinite loop because the --on-variable hook does not distinguish
between local and global variables.

Update the script to set a completely different local variable to
__fish_git_prompt_showupstream and to override this local variable for
bash.showUpstream.

Also update the code that looks at bash.showUpstream to also read
bash.showupstream, because the bash script appears to have a bug where
it looks for bash.showupstream despite documenting bash.showUpstream.
2012-07-26 15:32:27 -07:00
ridiculousfish
62c49f13ce Switch from std::list to std::vector in a few places to reduce compiled code size 2012-07-24 22:32:11 -07:00
Colin Woodbury
eba75dbc2e Fixed two small spelling mistakes
- Saw these during normal usage today.
  "parens" or "parenthesis" was spelled as "parans".
  Fixed two instances of this to "parenthesis".
2012-07-24 22:39:03 +09:00
Siteshwar Vashisht
32d2d0f0d0 Minor refactoring and fixed a bug in history function 2012-07-24 04:35:37 +05:30
maxfl
81e0342bf6 index range doc 2012-07-24 03:56:34 +05:30
ridiculousfish
56599621cc Make add-shell correctly handle /etc/shells files that do not end with newlines
Fixes https://github.com/fish-shell/fish-shell/issues/77
2012-07-22 17:00:44 -07:00
ridiculousfish
261bf12c91 Lots of miscellaneous cleanup. Unified the path_get_cd_path, path_allocate_cd_path, etc. functions 2012-07-20 22:11:05 -07:00
ridiculousfish
b08fb86637 Renamed env_vars to env_vars_snapshot_t
Cleanup of non-wcstring version of path_get_path
2012-07-20 20:39:31 -07:00
ridiculousfish
b290fd33b9 Switch to more uses of wcstokenizer from wcstok()
Work towards cleaning up path_get_path
2012-07-20 15:01:56 -07:00
ridiculousfish
966bbd476f Use weak linking of wcsdup and wcscasecmp on OS X
Fixes https://github.com/fish-shell/fish-shell/issues/240
2012-07-20 14:33:29 -07:00
Siteshwar Vashisht
cf9bfe9e66 Print fish prompt when command is longer than a line
Fix for https://github.com/fish-shell/fish-shell/issues/239
2012-07-21 00:24:48 +05:30
ridiculousfish
bb4a05032b Merge branch 'index_range' 2012-07-19 10:59:11 -07:00
ridiculousfish
7039e01136 Fixed fish_pager build on Xcode (it was building fish_indent instead. D'oh!) 2012-07-18 12:28:26 -07:00
ridiculousfish
e9f43f1097 Changes to make fish use the relocated fishd instead of the installed one, if it exists 2012-07-18 10:50:56 -07:00
ridiculousfish
150789690f Merge pull request #234 from maxfl/completions
pacmatic and dmesg completions
2012-07-18 10:49:28 -07:00
Siteshwar Vashisht
e284233013 Don't add space at the end of tab completion for cd
Fix for https://github.com/fish-shell/fish-shell/issues/235
2012-07-18 19:48:19 +05:30
ridiculousfish
d06d6c6964 Various changes to reduce fish's compiled code size
OS X release build executable size dropped from 672k to 511k
2012-07-17 12:47:01 -07:00
ridiculousfish
977a4477f6 Fix for process completion on Linux 2012-07-16 12:19:41 -07:00
ridiculousfish
33c6410809 Implemented process expansion on OS X
Also fixed issue where process expansion would always fail for processes with spaces
Fixes https://github.com/fish-shell/fish-shell/issues/56
2012-07-16 12:06:02 -07:00
maxfl
7e321afd2a pacmatic and dmesg completions 2012-07-16 10:03:01 +08:00
ridiculousfish
548ea1e54a Added binding for accepting an autosuggestion
Fixes https://github.com/fish-shell/fish-shell/issues/226
2012-07-15 14:02:34 -07:00
ridiculousfish
4755c5f8c8 Deliver SIGHUP when we're exiting, even if stdin is not closed.
Fixes https://github.com/fish-shell/fish-shell/issues/138
2012-07-15 12:46:40 -07:00
ridiculousfish
ea1bfd715e Set of changes to improve Unicode support with respect to combining characters.
Should address https://github.com/fish-shell/fish-shell/issues/155
2012-07-15 10:45:18 -07:00
Kevin Ballard
b1281c3fb9 Update __fish_git_prompt.fish to handle git-svn better
Git-svn remotes can have a prefix for their remotes. If I set a prefix
of 'svn/' then my remote trunk branch is called svn/trunk. Update the
script to use the svn-remote.*.fetch key to figure out how the 'trunk'
branch is mapped into the remotes namespace and apply this to the
current branch. This assumes branches are mapped into the same
namespace, which is likely. It also doesn't work for tags, but neither
did the old code.
2012-07-13 21:46:57 -07:00
Alex Rosenberg
257e9b04fe Add auto-generated builtin_scripts.[cpp|h] to .gitignore 2012-07-13 21:40:11 -07:00
ridiculousfish
8643870822 Tweaked fish_prompt document in a way I hope clarifies it 2012-07-13 21:32:50 -07:00
Dario Bertini
6819696222 Added small note to the fish_prompt doc 2012-07-12 14:52:15 -07:00
ridiculousfish
193bbd4e00 Tweaked pwd note about symbolic links 2012-07-12 14:48:51 -07:00
Dario Bertini
1bf168348e Added doc for pwd 2012-07-12 14:45:37 -07:00
ridiculousfish
f8b4c1b389 First pass at making autosuggestions not trigger wrapping
Addresses https://github.com/fish-shell/fish-shell/issues/167
2012-07-12 12:51:47 -07:00
ridiculousfish
830fba64b1 Fix for https://github.com/fish-shell/fish-shell/issues/42
Remote completions in scp
2012-07-11 17:20:58 -07:00
ridiculousfish
1cd61952b0 Fix for https://github.com/fish-shell/fish-shell/issues/223
Use -rpath instead of -R
2012-07-11 17:18:49 -07:00
ridiculousfish
4ee1cc3b37 Fix for https://github.com/fish-shell/fish-shell/issues/168
Make ^ only act as a redirect at the beginning of a token
2012-07-10 20:30:54 -07:00
maxfl
11dd904b6d Tests for contains -i 2012-07-10 16:21:00 -07:00
maxfl
0c03b6ddc7 Allow 'contains' builtin to return index
Add an option -i/--index to the contains builtin to print the index
of first coincidence.
2012-07-10 16:21:00 -07:00
ridiculousfish
176a3913aa Fix for https://github.com/fish-shell/fish-shell/issues/106
Lets us configure and build on FreeBSD
2012-07-10 15:37:16 -07:00
ridiculousfish
6f0b00f983 Fix for https://github.com/fish-shell/fish-shell/issues/66
Make fish import .bash_history if regular history is not found
2012-07-09 22:54:08 -07:00
ridiculousfish
69ace201f8 Fix for https://github.com/fish-shell/fish-shell/issues/79
Release tarballs with the user docs already build, removing the doxygen dependency
2012-07-09 19:41:51 -07:00
ridiculousfish
a04f31c5c0 Fix for https://github.com/fish-shell/fish-shell/issues/218
make help smarter on OS X (don't show useless builtin man page)
2012-07-09 18:46:14 -07:00
ridiculousfish
1d9f47d1e5 https://github.com/fish-shell/fish-shell/issues/207
Improve error message for infinite loop detection
2012-07-09 15:18:22 -07:00
ridiculousfish
36a91fc6ff Fix for https://github.com/fish-shell/fish-shell/issues/28
Use pthread_sigmask instead of sigprocmask
2012-07-09 14:15:55 -07:00
ridiculousfish
cd3ed71137 Fixes Solaris kludge https://github.com/fish-shell/fish-shell/issues/76 2012-07-08 22:36:04 -07:00
ridiculousfish
73e56527bf Improve error message for $? 2012-07-08 18:51:52 -07:00
ridiculousfish
24059924b1 Fix for https://github.com/fish-shell/fish-shell/issues/50
Unescape characters before calling parser.error
2012-07-08 18:40:50 -07:00
ridiculousfish
bb100a2511 Turn on debugging symbols correctly for OS X build 2012-07-08 18:04:31 -07:00
ridiculousfish
0c8c32cd03 Fix for https://github.com/fish-shell/fish-shell/issues/105
Not sure why the escape character was being printed in the manpage completions script
2012-07-08 17:35:07 -07:00
ridiculousfish
a38d6e74f5 Renamed a target in the OS X build system 2012-07-08 16:51:39 -07:00
ridiculousfish
05d8dacb27 Simplified native OS X build system 2012-07-08 16:17:49 -07:00
ridiculousfish
d6a0859eab Updated doc dir path in fish.cpp 2012-07-08 15:42:47 -07:00
ridiculousfish
4912967eab Large set of changes related to making fish relocatable, and improving the build and install story.
- etc/config.fish and share/config.fish are now "universal" and no longer reference install paths or need to be touched by autotools. They've been removed from config.fish.in to config.fish.
- fish now attempts to determine __fish_datadir and __fish_sysconfdir relative to the path of the fish executable itself (typically by walking up one directory). This means that you can copy the directory hierarchy around and things will still work. The compiled-in paths are used as a backup.
- The fish Xcode project now can build fish natively, without needing autotools.
- Version bumped to 2.0
2012-07-08 15:20:39 -07:00
maxfl
76e1cda495 Set single-line default prompt
Fish now doesn't join the fish_prompt output. This breaks the default
fish_prompt. Make default fish_prompt single-line. Fixes #203.

Add -l flag to 'read' documentation. Remove ambiguous '-x' description.
Fixes #157.
2012-07-07 23:34:16 -07:00
ridiculousfish
c1a23bf450 Fix for https://github.com/fish-shell/fish-shell/issues/199
Don't hard-fail on setting the PATH or CDPATH just because it contains an invalid entry
2012-07-07 23:04:02 -07:00
maxfl
b25b5bf5f6 restore tabs instead of spaces 2012-07-08 10:55:48 +08:00
maxfl
079f17761c Fix case when first index is command substitution 2012-07-08 09:45:34 +08:00
maxfl
e1b8c425da Fix case when second limit is a variable:
echo $PATH[1..$n]
2012-07-08 09:39:39 +08:00
maxfl
5f05756e65 Add variable expand ranges
echo $PATH[-1..1] #now works

Add tests for ranges
2012-07-08 09:19:11 +08:00
maxfl
c0e996acf8 Implemented index ranges for command substitution
Now the following code works:
> echo (seq 10)[-1..1]
With output:
10
9
8
7
6
5
4
3
2
1
2012-07-07 22:01:28 +08:00
maxfl
41ec58a524 misc 2012-07-07 11:04:29 +08:00
maxfl
0a5e7be129 Add index ranges
Builtin 'set' now can set variable index ranges:
  set test[1..3] a b c #works
  set test[-1..-3] a b c #works if variable have enough elements
  set test[2..-2]  a b c #works
  set test[1..3 -1..-2] a b c b b #works

Expand now can parse index ranges. But not handle for now.

TODO:
  * Add variable substitution index ranges: echo $PATH[-1..1]
  * Add command substitution index range: echo (seq 10)[-1..-4]
  * Add process substitution indexes and ranges: echo %vim[-1]
2012-07-07 10:57:28 +08:00
maxfl
b23d65b014 Set single-line default prompt
Fish now doesn't join the fish_prompt output. This breaks the default
fish_prompt. Make default fish_prompt single-line. Fixes #203.

Add -l flag to 'read' documentation. Remove ambiguous '-x' description.
Fixes #157.
2012-07-07 10:17:24 +08:00
ridiculousfish
60ef7903e2 Tweaked __fish_print_help to not spew errors 2012-07-06 16:31:06 -07:00
ridiculousfish
ee8fd21d28 Fix for https://github.com/fish-shell/fish-shell/issues/209
Don't hang if stdin is closed and we have no bindings
2012-07-06 16:25:59 -07:00
maxfl
232ed91ec7 Fix read default prompt. It's now single line. 2012-07-06 15:31:45 -07:00
maxfl
7fccad156e Fix fish_prompt event
I've found that this modification fixes fish_prompt event
Fixes #164
2012-07-06 15:31:45 -07:00
ridiculousfish
11e56456a0 Fix for wrong sense for determining when an autoloaded function has changed
Addresses some of the complaints in https://github.com/fish-shell/fish-shell/pull/201
2012-07-06 15:30:41 -07:00
Emily Eisenberg
d07e78c59a Make prompt_pwd make a lot more sense
Remove the case statements, which were handled by the sed blocks anyway
Move around the '/' character in the regex, so only one regex is needed
Fix a bug where '/' is output as '//'
2012-07-06 14:46:50 -07:00
Sean DuBois
c45479a6e5 Created the man page for echo and test 2012-07-06 14:41:44 -07:00
ridiculousfish
345a528625 Untangle unescaping responsibilities in highlight.cpp. Fix cd autosuggestions to properly handle quotes. Factor out some of the quote unescaping behavior from reader.cpp to parse_util.cpp.
Add some autosuggestion tests
2012-07-06 14:34:53 -07:00
maxfl
01d8490255 Return the previous logic for '\\'.
The following expression now works:
```sh
switch '\\'
  case '\\'
  echo 1
end
```

Due to ambiguity, the following expression also works:
```sh
switch '\a'
  case '\\a'
  echo 1
end
```

By the way, the following expression now doesn't work, which was not the
case before, because of wrong escaping:
```sh
switch 'nn'
  case '\n'
  echo 1
end
```
2012-07-05 14:17:25 -07:00
maxfl
ea4b37d5c5 Fixed case behaviour
* case no properly handles -h and --help flags, i.e. treats it as
  pattern
* fixed case escaping:
The following expressions now work correctly:
switch '*'
  echo '*'
  echo Match any string
end
switch '*'
  echo '\*'
  echo Match asterix
end
switch '\\'
  echo '\\\\'
  echo Match slash
end

The same for '?' sign
2012-07-05 14:17:25 -07:00
Siteshwar Vashisht
a1319cb8aa Fixed crash caused by pressing pageup button when no match (for typed command) in history is found 2012-07-05 16:06:39 +05:30
ridiculousfish
35c49d62d7 Fix a class/struct disparity 2012-07-01 16:11:14 -07:00
ridiculousfish
0576a11a6f Added missing break in case R_SUPPRESS_AUTOSUGGESTION 2012-07-01 15:40:06 -07:00
Ian Munsie
c8f86d94c9 Add command to temporarily suppress the autosuggestion feature
Autosuggestion will be automatically re-enabled next time a character is
inserted. An alternative implementation would require another command to
explicitly re-enable it.

Signed-off-by: Ian Munsie <darkstarsword@gmail.com>
2012-07-01 15:37:10 -07:00
Ian Munsie
2b24eab26a Fix off by two in move_word left
This can be demonstrated with something like:

echo howdy hi<control-w>
echo howdy I<alt-b>

Previousely this would delete/move all the way to the start of 'howdy',
rather than just the word 'hi'/'I'.

It seems that the code to ignore the character under the cursor was
redundant, as all the cases I've tried with it removed seem to do the
right thing.

Signed-off-by: Ian Munsie <darkstarsword@gmail.com>
2012-07-01 15:37:10 -07:00
ridiculousfish
7bbc7a61ce Clarify the function name deferral in functions_def
Prohibit making a function with an empty name
2012-07-01 15:33:50 -07:00
maxfl
fe26284376 Doc is updated
btw. funced completion is updated
2012-07-01 14:20:43 -07:00
maxfl
ab62fe6496 Update funced
* Editor mode is no the default
* Use -i or --interactive or -e fish to edit function in interactive
  mode
* tmpname is now created with random number added and check that file
  do not already exist
* check $TMPDIR existence and put /tmp if it does not exist
* There is an undocumented feature to use functions, started with dash.
  Introduce necessary changes to funced, functions, def_function()
  in order to make it work properly.
* Delete editor guessing. Use $EDITOR variable or -e key
2012-07-01 14:20:43 -07:00
ridiculousfish
bc9bae0f7f Update make_tarball.sh to respect new branch name 2012-07-01 14:19:39 -07:00
maxfl
e5939d1a18 Disable default fish_pager_color_secondary
since it should be different, depending on terminal background
2012-06-29 18:53:22 -07:00
maxfl
5fadb7f200 fix logic 2012-06-29 18:53:22 -07:00
maxfl
a02aa7a316 Step coloring for fish_pager introduces new variable
fish_pager_color_secondary to set background of every second completion
line. It simplifies finding the options corresponding to given
description. Default color is 151515.
2012-06-29 18:53:22 -07:00
ridiculousfish
3ab26a5d40 Updated funced documentation to reflect new behavior 2012-06-29 18:41:37 -07:00
ridiculousfish
a8bae31939 Change funced script to default to using $EDITOR if set, and to allow -e to specify a particular editor (with fish meaning the builtin editor) 2012-06-29 18:35:26 -07:00
maxfl
faea588fb8 Support editing functions starting with dot 2012-06-29 16:42:34 -07:00
maxfl
792e246262 Add emacs to 'funced -e'
The order is also changed.
2012-06-29 16:42:34 -07:00
maxfl
85f19f9b8c Add -e option to funced
New option -e or --editor allows to edit function inside external
editor, rather than in reader.
2012-06-29 16:42:34 -07:00
ridiculousfish
40e4f49dbe Disable process expansion in autosuggestions
Addresses https://github.com/fish-shell/fish-shell/issues/39
2012-06-29 16:40:54 -07:00
Siteshwar Vashisht
05c721bebb Some improvements to validate commands suggested from history 2012-06-29 00:24:37 +05:30
maxfl
e995cc9329 fix #177 (complete 'cd' only with paths) 2012-06-26 19:17:32 -07:00
ridiculousfish
9457c115be Merge pull request #181 from kballard/fish_git_switch
Remove __fish_git_prompt's switch bug workaround
2012-06-26 13:00:31 -07:00
Kevin Ballard
1eddc79a90 Remove __fish_git_prompt's switch bug workaround
With the switch bug fixed, __fish_git_prompt can be very slightly
simplified by not recording the exit status of every case in the
describe style switch individually.
2012-06-25 15:19:47 -07:00
Siteshwar Vashisht
ccfc909eb2 Fixed crash caused by pressing pageup button 2012-06-25 03:02:37 +05:30
Kevin Ballard
1a93cbba1e Bring prompt_pwd under Darwin to parity with non-Darwin
The echo command to print the last path segment got a couplel of fixes,
but these fixes were only applied to the non-Darwin version. Copy these
fixes over to the Darwin version. Notably, this makes `/` stop
displaying as `//`.
2012-06-24 14:04:43 -07:00
Kevin Ballard
529d410bec Fix prompt_cwd on darwin systems when $PWD is "/private"
When $PWD is "/private", the prompt was printing "rivate". Skip the
"/private" stripping if there's nothing after it.

Prevent "/private" from being stripped anywhere but the beginning of the
PWD.

Fixes #173
2012-06-24 14:04:43 -07:00
Kevin Ballard
4d1c0eaa52 Fix var set in __fish_config_interactive.fish
__fish_config_interactive.fish uses the presence of __fish_init_1_50_0
to decide whether it should perform a one-time initialization of
universal variables. Unfortunately, it sets the variable
__fish_init_1_23_0. Fix this to set __fish_init_1_50_0 instead.
2012-06-24 13:57:15 -07:00
Kevin Ballard
adfd3c1098 Don't blow away $status in switch statements
Tweak the switch and case builtins to not blow away $status
inappropriately. Fixes issue #161.
2012-06-24 13:43:44 -07:00
Kevin Ballard
f7d0c4b065 Add a test case for switch error code (issue #161) 2012-06-24 13:43:44 -07:00
Siteshwar Vashisht
5fb32f1e2d Fixed declaration of wrealpath() function on FreeBSD 2012-06-23 10:59:53 +05:30
ridiculousfish
f69489a4fc Mostly fix https://github.com/fish-shell/fish-shell/issues/72 2012-06-21 16:58:26 -07:00
ridiculousfish
d34ce26c4e Merge pull request #169 from kballard/git_prompt_docs
Tweak documentation for __fish_git_prompt
2012-06-21 16:34:12 -07:00
Kevin Ballard
3f7fe94009 Tweak documentation for __fish_git_prompt
Add mention of the __fish_git_prompt_color variable.
2012-06-21 11:14:01 -07:00
Kevin Ballard
ae593decfc Replace __fish_git_branch_prompt.fish with __fish_git_prompt.fish
__fish_git_prompt.fish is a complete port of the __git_ps1 function from
git-completion.bash, with the relevant configuration variables changed
and some extra configuration added (namely, control over individual
colors and the status indicator characters).
2012-06-21 11:03:15 -07:00
Emil Eriksson
eea62125a1 Fixes title update in tmux and screen
* Seems that writestr( L"\x1b];" ); doesn't work in tmux and
	  screen. As discussed in fish-shell/fish-shell#47 the 2 was
	  removed. This commit adds the zero (L"\x1b]0;").
	* Tested in screen,tmux,iTerm and xterm.
2012-06-21 10:30:12 -07:00
Emil Eriksson
96f36a63dc Enable window title update when TERM is screen-X
* Uses the same logic as when TERM is
	  xterm-X to enable window-title updates when
	  running in screen.
2012-06-21 10:30:12 -07:00
ridiculousfish
19e183f02f Squashed commit of the following:
commit 5b7659ec3d5e67b8dad8d3543d87a0169dc9a9e9
Merge: 57f3df3 22a4cd6
Author: ridiculousfish <corydoras@ridiculousfish.com>
Date:   Thu Jun 21 10:15:41 2012 -0700

    Merge branch 'master' of https://github.com/maxfl/fish-shell into maxfl-master-base

commit 22a4cd686f
Author: maxfl <gmaxfl@gmail.com>
Date:   Tue Jun 19 15:51:43 2012 +0400

    set now expands the variable size, if index is outside it

commit 9b0ffa8315
Author: maxfl <gmaxfl@gmail.com>
Date:   Mon Jun 18 21:30:44 2012 +0400

    fixes #78

commit 78387fb391
Merge: c0e6096 93dc7d4
Author: maxfl <gmaxfl@gmail.com>
Date:   Mon Jun 18 21:27:47 2012 +0400

    Merge remote-tracking branch 'fishfish/master'

commit c0e60963c1
Merge: 32a98e7 1bead8a
Author: maxfl <gmaxfl@gmail.com>
Date:   Mon Jun 18 10:29:42 2012 +0400

    Merge remote-tracking branch 'fishfish/master'

commit 32a98e799e
Merge: 6e71021 f2b5292
Author: maxfl <gmaxfl@gmail.com>
Date:   Sat Jun 16 18:42:07 2012 +0400

    Merge remote-tracking branch 'fishfish/master'

commit 6e710211bc
Author: maxfl <gmaxfl@gmail.com>
Date:   Thu Jun 14 11:01:13 2012 +0400

    revert fish_pager

commit 731a29f35b
Author: maxfl <gmaxfl@gmail.com>
Date:   Thu Jun 14 10:57:41 2012 +0400

    revert fish_pager.cpp

commit 72c1bfc7bf
Merge: ea74ffa 9b781c4
Author: maxfl <gmaxfl@gmail.com>
Date:   Wed Jun 13 17:54:11 2012 +0400

    Merge branch 'master' into maxfl_completions

commit ea74ffa086
Author: maxfl <gmaxfl@gmail.com>
Date:   Wed Jun 13 17:35:20 2012 +0400

    __fish_complete_command now can understand '--arg=option' tokens
    latexmk completion is updated

commit 45b667826f
Author: maxfl <gmaxfl@gmail.com>
Date:   Wed Jun 13 16:46:47 2012 +0400

    . completion

commit 1c9f8ffc9e
Author: maxfl <gmaxfl@gmail.com>
Date:   Wed Jun 13 16:46:13 2012 +0400

    a lot of new completions

commit 8224d9f984
Author: Maxim Gonchar <gonchar@myhost.localdomain>
Date:   Tue Jun 12 20:19:31 2012 +0400

    A lot of new completions.
    Some small updates and fixes of old functions and completions.

commit 234ed8f5da
Author: Maxim Gonchar <gonchar@myhost.localdomain>
Date:   Tue Jun 12 20:03:44 2012 +0400

    step-coloring initial
    set_color correction
2012-06-21 10:24:49 -07:00
Siteshwar Vashisht
57f3df3cab Fix for crash while editing multiple lines requested in issue #143 2012-06-21 21:05:14 +05:30
David Adam (zanchey)
08e78e63cf docs: fix percentage sign escape character
(Patch taken from Debian packaging.)
2012-06-18 14:01:22 -07:00
ridiculousfish
9228dffe5e Don't generate completions if we already have bespoke completions in the data directory
Fixes https://github.com/fish-shell/fish-shell/issues/148
Also fix some Python3 issues
2012-06-18 13:59:34 -07:00
Siteshwar Vashisht
93dc7d4cc1 Add support for querying variables with scope options as requested in issue #132 2012-06-18 22:52:33 +05:30
ridiculousfish
1bead8adf7 Fix to create_manpage_completions.py to flush after every line (so you see more progress) and to put the cursor at the beginning (so it doesn't jump around) 2012-06-17 15:19:55 -07:00
David Adam (zanchey)
6681f3bfec only touch user_doc if doxygen installed
If doxygen isn't installed, an empty file called user_doc will be created.
If doxygen is later installed, the documentation will not generate correctly.
2012-06-17 15:04:20 -07:00
David Adam (zanchey)
71f8960ef1 make clean should remove all generated documentation 2012-06-17 15:04:20 -07:00
Evan Jones
01780f19b1 Fix other usages of \n in sed replacements. 2012-06-17 15:01:04 -07:00
Evan Jones
1fa0c4d4d3 alias: Support seds that don't support \n in replacements.
This makes the alias command work on Mac OS X.
2012-06-17 15:01:04 -07:00
ridiculousfish
eebe126842 Fix for a busted format string 2012-06-17 14:49:45 -07:00
ridiculousfish
ebfa285122 Teach __fish_print_help.fish about the new man path 2012-06-17 14:46:24 -07:00
ridiculousfish
27212719dc Removed an errant printf 2012-06-17 13:20:31 -07:00
Siteshwar Vashisht
17567028da Fixed a bug in wsetlocale() 2012-06-17 11:25:21 +05:30
ridiculousfish
34fd8e0e00 Tweak fork guards to be more forgiving
Fixes https://github.com/fish-shell/fish-shell/issues/101
2012-06-16 21:25:33 -07:00
ridiculousfish
6cf42075fc Fix to check for case insensitive filesystems in is_potential_path
Addresses https://github.com/fish-shell/fish-shell/issues/119
2012-06-16 14:08:58 -07:00
ridiculousfish
afd8d2f9ba Fix for https://github.com/fish-shell/fish-shell/issues/135
Don't use std::map::insert when we need to overwrite values
2012-06-16 13:05:58 -07:00
ridiculousfish
1d54bff385 Disble futimes() calls in hopes of fixing https://github.com/fish-shell/fish-shell/issues/122
This should keep sudo from thinking that the tty has changed as part of its tty_tickets feature.
2012-06-16 12:30:20 -07:00
ridiculousfish
6dd0013a5d Fix for extra space in some completions
Addresses https://github.com/fish-shell/fish-shell/issues/60
2012-06-16 10:30:05 -07:00
ridiculousfish
f2b5292bcb Squashed commit of the following:
commit 33358874f1c275d8b08186e29f24a7889d2b5224
Author: maxfl <gmaxfl@gmail.com>
Date:   Thu Jun 14 11:01:13 2012 +0400

    revert fish_pager

commit cee1bc8a66ec3adc9573b76e1aca3131cd32db83
Author: maxfl <gmaxfl@gmail.com>
Date:   Thu Jun 14 10:57:41 2012 +0400

    revert fish_pager.cpp

commit 27f3bd39dd9903009503d20a59a9e2ba84add07a
Author: maxfl <gmaxfl@gmail.com>
Date:   Wed Jun 13 17:35:20 2012 +0400

    __fish_complete_command now can understand '--arg=option' tokens
    latexmk completion is updated

commit 97b53a4b53de9389675783f3e90f58215d936356
Author: maxfl <gmaxfl@gmail.com>
Date:   Wed Jun 13 16:46:47 2012 +0400

    . completion

commit d5b63b9963b0a02a71f564e7392171c5eab005cd
Author: maxfl <gmaxfl@gmail.com>
Date:   Wed Jun 13 16:46:13 2012 +0400

    a lot of new completions

commit ceab87d99425124aa010c64ed062e27202b850d2
Author: Maxim Gonchar <gonchar@myhost.localdomain>
Date:   Tue Jun 12 20:19:31 2012 +0400

    A lot of new completions.
    Some small updates and fixes of old functions and completions.

commit 950aecd570b51e1b9dc444cc651b282a220e8d94
Author: Maxim Gonchar <gonchar@myhost.localdomain>
Date:   Tue Jun 12 20:03:44 2012 +0400

    step-coloring initial
    set_color correction
2012-06-15 17:30:33 -07:00
Gour-Gadadhara Dasa
3a94f6e8b3 initial version of Bazaar completion (created automatically) 2012-06-15 17:18:15 -07:00
Peter Feigl
f2846a0b78 correcting path of man-pages to ./man/man1/ instead of ./man/
Change the path where man-pages are installed to
/usr/share/fish/man/man1 instead of /usr/share/fish/man, so that tools
like mandb can process it.
2012-06-15 16:31:35 -07:00
Tim Gray
dbde7033d8 Added completions for brew (Homebrew)
An OS X package manager.
http://mxcl.github.com/homebrew/
2012-06-15 16:29:26 -07:00
ridiculousfish
18f04adccb Support for importing fish 1.x's history and format, and also bash 2012-06-15 16:24:05 -07:00
ridiculousfish
1ed65b6bd7 Fixed token search (note: this didn't work properly even in the original fish!)
Fixes https://github.com/fish-shell/fish-shell/issues/61
2012-06-15 16:24:05 -07:00
Siteshwar Vashisht
9b781c4c06 Modified alias.fish to show help message when executed with 0 arguments 2012-06-13 00:29:05 +05:30
Siteshwar Vashisht
25f9105a97 Made history --help show history man page and history is now saved only once while deleting items 2012-06-12 14:20:07 +05:30
Siteshwar Vashisht
602109bd8d Some improvements in bash configuration importer script 2012-06-12 11:08:30 +05:30
ridiculousfish
631d27f7a8 Merge pull request #104 from Teggy/master
Please consider to pull: formatting glitch in doc_src/history.txt makes Doxygen stumble
2012-06-11 15:48:00 -07:00
Torsten Grust
aad27a7a68 Fixed closing <pre> tag
- Was an opening tag, should have been a closing tag
- Confused Doxygen 1.8.1.1 on my machine (OS X 10.7), resulting in the fish man pages not being installed at all
2012-06-11 13:46:47 +02:00
ridiculousfish
4ac01154d9 SIGXCPY should be SIGXCPU
Fixes https://github.com/fish-shell/fish-shell/issues/97
2012-06-10 03:36:02 -07:00
ridiculousfish
4e2c7c57d7 Add text to INSTALL describing how to go back to the old shell.
This was requested in https://github.com/ridiculousfish/fishfish/pull/92
2012-06-10 01:35:30 -07:00
Robin Deits
6e65cfcc9a fish_title now sets both tab and window titles in iTerm2 2012-06-10 00:50:00 -07:00
Carl Johan Crafoord
96a4b7eaa7 Check for libiconv_open if we can't find iconv_open 2012-06-10 00:33:01 -07:00
ridiculousfish
64afada7f0 Switched from using 'type' to 'functions --query' since it's a lot cheaper 2012-06-10 00:21:11 -07:00
adisbladis
9f563f4873 Introduced fish_user_keybindings 2012-06-10 00:21:11 -07:00
Siteshwar Vashisht
ca61d0ee8b Fixed crash in history builtin for inputs like : history --search -prefix "echo" 2012-06-10 01:08:19 +05:30
Siteshwar Vashisht
e96dabadf1 Add Rekonq in list of browsers to display help 2012-06-08 21:11:26 +05:30
Siteshwar Vashisht
b6601338c2 Made C-d delete characters in multiple lines. 2012-06-07 21:18:02 +05:30
Siteshwar Vashisht
8167e1e07e Add new line after printing job information with jobs builtin. 2012-06-07 21:07:34 +05:30
Siteshwar Vashisht
23ce927301 Fixed a bug in manpage generator. 2012-06-07 20:48:54 +05:30
Siteshwar Vashisht
c7941fc7b0 Use manpath instead of man --path to find man page paths. 2012-06-07 00:00:43 +05:30
Siteshwar Vashisht
1078ad9ae9 Fixed following bugs in history function:
1. history function without any argument now correctly shows user's command history.
2. history --save now saves user's command history.
2012-06-06 20:54:27 +05:30
adisbladis
c0085cbc61 Python3 fixes in import_bash_settings.py 2012-06-05 20:40:51 -07:00
Adam
a49d245b92 Python3 fixes for webconfig.py 2012-06-05 20:40:51 -07:00
Adam
0ce6829e4c Python3 fixes in make_completions.py 2012-06-05 20:40:51 -07:00
Adam
4e3acdcbdc Unicode error fix in manpage completion with python3 2012-06-05 15:26:11 -07:00
Adam
85f808130d Manpage generation now works with python3 2012-06-05 15:26:11 -07:00
ridiculousfish
b187538339 Bump OS X installer package version 2012-06-05 02:06:44 -07:00
ridiculousfish
93f6aabe12 Fix to stop identifying SnowLeopard's terminal as term256 2012-06-05 02:06:33 -07:00
ridiculousfish
10aa107380 Updated relnotes 2012-06-05 01:22:25 -07:00
ridiculousfish
53cba2a2e6 Improved webconfig.py's handling of combined term256 and classic colors 2012-06-05 01:19:59 -07:00
ridiculousfish
d871095d0b Updated "last run version" to __fish_init_1_50_0. Updated colors for non term-256 compatibility 2012-06-05 01:01:30 -07:00
ridiculousfish
9bf8a5e877 Updated release notes for new history syntax 2012-06-05 00:42:45 -07:00
ridiculousfish
3836bfe5a1 Added history completion file
Updated history function to assume --search as the default behavior
2012-06-05 00:40:42 -07:00
ridiculousfish
7698553c3a Made a bare history call end with a newline 2012-06-04 23:59:04 -07:00
ridiculousfish
be1d216b34 Relnoted history builtin
Tweaked validation regex to use extended regexs
2012-06-04 23:54:43 -07:00
ridiculousfish
85cbb943b5 Tweaks to the history function 2012-06-04 23:40:08 -07:00
Siteshwar Vashisht
ec34f2527a Adding history builtin 2012-06-05 09:54:42 +05:30
ridiculousfish
b877181e17 Fix for what I believe to be a bug in fish trunk where you can't always successfully control-C out of some while loops 2012-06-04 15:10:35 -07:00
ridiculousfish
69446be1ee Signal handling cleanup and improved safety
Fixes issue where you couldn't control-C out of a loop (https://github.com/ridiculousfish/fishfish/issues/13)
Also stops doing memory allocation in the signal handler (oops) https://github.com/ridiculousfish/fishfish/issues/27
2012-06-04 14:20:01 -07:00
ridiculousfish
cc90f9cf80 path_make_canonical mishandles empty string.
Fixes https://github.com/ridiculousfish/fishfish/issues/26
2012-06-04 12:00:59 -07:00
ridiculousfish
457e6a5f46 Updated some relnotes for beta r2 2012-06-03 17:58:25 -07:00
ridiculousfish
e7db18bae2 Added Debian description-pak file 2012-06-02 18:07:11 -07:00
ridiculousfish
f8e3e853aa Fix to disable VDSUSP, which allows control-Y to serve as yank on OS X 2012-06-02 15:43:18 -07:00
ridiculousfish
b7ba252965 Restore implicit cd for paths starting with ., .., or ~ 2012-06-02 14:04:25 -07:00
ridiculousfish
ae12e1b537 insert_tabs called wcstring::append with arguments in the wrong order
Should fix https://github.com/ridiculousfish/fishfish/issues/18
2012-06-01 14:38:41 -07:00
ridiculousfish
9255f625fa Disable internalized scripts 2012-06-01 14:00:04 -07:00
adisbladis
377d93d1cf Missing -s to which fixed 2012-05-30 21:08:44 +02:00
adisbladis
19d14c7c3a Python 3 compatibility fix in make_completions.py 2012-05-30 11:52:49 +02:00
adisbladis
6e3a823b7b Python 3 compatibility fix in internalize_scripts.py 2012-05-30 11:42:32 +02:00
ridiculousfish
51f9ff5389 Updated make_tarball.sh to stop dumping files in the extract directory 2012-05-30 01:06:25 -07:00
ridiculousfish
4986e6e3f9 Fix to set up 10.6 SDK correctly when building on 10.7 2012-05-30 00:27:50 -07:00
Peter Ammon
9d8ae184c9 Fix for annoying messages when launching on SnowLeopard
Fix for missing .o file in Makefile.in
2012-05-30 00:22:45 -07:00
ridiculousfish
4afdcf56fc Tweak a few default colors
Fix the make_pkg script to actually build an installable package that doesn't immediately barf
2012-05-29 21:14:19 -07:00
ridiculousfish
0fe43eb880 Fix to (really) no longer require Doxygen to build fish 2012-05-29 20:50:27 -07:00
ridiculousfish
4edfd6d9d6 Update set_color documentation 2012-05-25 02:14:26 -07:00
ridiculousfish
8351ec0afd Document some of the new commands 2012-05-25 02:07:21 -07:00
ridiculousfish
92ce84c26a More tweaks to Debian build script 2012-05-25 00:48:39 -07:00
ridiculousfish
9d31e52b2a Updated Debian package build script 2012-05-24 23:58:16 -07:00
ridiculousfish
dcd7d6769d Updated some build scripts 2012-05-24 23:56:07 -07:00
ridiculousfish
87c0e0e971 Tweaked make_deb script 2012-05-22 00:09:39 -07:00
ridiculousfish
6f9a523151 Some tweaks to build tools
Started make_deb.sh for Debian package
2012-05-22 00:05:41 -07:00
ridiculousfish
673faf7152 Fixed builtin_test to properly handle "just a strings" in combining expressions, like 'test foo -a bar'. This was causing error messages in the help function.
Fixed help function to know about OS X and use the open command to open web pages.
2012-05-20 12:58:03 -07:00
ridiculousfish
18ace555b0 Added release notes for beta 1 2012-05-19 17:04:45 -07:00
ridiculousfish
d09c9fba02 Added a -s option to echo to mean "don't output spaces"
Replaced default prompt to stop calling printf. I opened a bug to replace the default prompt entirely with one that's cheaper.
2012-05-19 16:59:56 -07:00
ridiculousfish
f1d22b6300 Got function.h and function.cpp off of shared_ptr (hooray) 2012-05-18 14:00:36 -07:00
ridiculousfish
da6295c428 More work towards getting function.h off of shared_ptr 2012-05-17 19:46:08 -07:00
ridiculousfish
86645b32e1 Work towards getting function.h off of shared_ptr 2012-05-17 19:38:08 -07:00
ridiculousfish
977c585f8b Made the OS X installer package flat 2012-05-17 19:37:26 -07:00
ridiculousfish
4c1ddab560 Tweaked Makefile.in to show off a few of our new features 2012-05-17 19:37:03 -07:00
ridiculousfish
f5442bdd4a Fixed cd autosuggestion for absolute paths
Removed some unnecessary path cleanup that is_potential_path now handles
2012-05-13 20:49:14 -07:00
ridiculousfish
129525af21 Fix for https://github.com/ridiculousfish/fishfish/issues/3
cd's special autosuggestion was broken, now fixed. Also, there's some tests for it now.
2012-05-13 20:19:02 -07:00
ridiculousfish
c15975113a Fix for https://github.com/ridiculousfish/fishfish/issues/2 2012-05-11 18:59:38 -07:00
ridiculousfish
2d3d6e1c17 Added PackageMaker file
Updated make_pkg.sh to use it
2012-05-11 17:26:08 -07:00
ridiculousfish
b0f4ff2879 Added build_tools folder so we can automate release builds 2012-05-10 02:11:28 -07:00
ridiculousfish
070b10689c Added .gitattributes to ignore new build_tools directory from archival 2012-05-10 02:10:39 -07:00
ridiculousfish
39863ce4d7 Fix for longstanding bug where set -e would fail to erase elements from an array.
This was introduced in 7b3377e78c
2012-05-10 01:04:18 -07:00
ridiculousfish
7cae1ae415 Make key_reader build and work 2012-05-09 03:30:09 -07:00
ridiculousfish
eca2100312 Cleanup SHLVL variable 2012-05-09 03:23:31 -07:00
ridiculousfish
175249b455 Adopt wcstring in env_set 2012-05-09 03:06:10 -07:00
ridiculousfish
294fbc8309 Replaced some calls to unescape with unescape_string 2012-05-09 02:55:36 -07:00
ridiculousfish
9bcc7df96f Lots of modernization changed
Removed wcsdupcat
2012-05-09 02:33:42 -07:00
ridiculousfish
4bd63020ca Fix to add a little explanatory text to colors in the web config interface 2012-05-08 17:10:38 -07:00
ridiculousfish
4885842ae8 Fix to do really nice syntax highlighting of cd command where it colors paths that cannot match any directory with error color 2012-05-07 17:52:02 -07:00
ridiculousfish
4df6b599b8 Eliminate the silly autosuggest_parsed_command_t class; make it just a function 2012-05-07 17:43:05 -07:00
ridiculousfish
0c79bb6e7c Factor is_potential_path to properly handle CDPATH
This will let us color cd commands better
2012-05-07 17:31:24 -07:00
ridiculousfish
1a264ab7c2 Made tests compile again
Renamed autosuggest_handle_special to autosuggest_special_validate_from_history
Began work to factor autosuggest_special_validate_from_history together with autosuggest_suggest_special
2012-05-07 12:55:13 -07:00
ridiculousfish
99b51ce6ea Fix to better support CDPATH 2012-05-06 14:53:19 -07:00
ridiculousfish
e0baab2722 Another effort to make the cd completion work without running command substitutions off of the main thread 2012-05-06 13:51:11 -07:00
ridiculousfish
71a8d39372 Fix to restore completions that use command substitution (like cd)
Fix to adopt the same escaping code for both completions and autosuggestions
2012-05-06 13:36:51 -07:00
ridiculousfish
90826e4031 Oops, had the wrong sense for when to call proc_push_interactive 2012-05-05 14:39:08 -07:00
ridiculousfish
0e4f2cca01 Fix to stop setting a default CDPATH 2012-05-05 14:34:59 -07:00
ridiculousfish
ac3dce38f0 Better fix to make cd completions work again 2012-05-05 14:33:24 -07:00
ridiculousfish
3be07cc645 Fix to start re-respecting CDPATH 2012-05-05 14:30:20 -07:00
ridiculousfish
07f5319472 Fix for failing to properly complete cd command 2012-05-05 14:21:21 -07:00
ridiculousfish
47019e315a Some work towards refactoring how completions are inserted to support escaping in autosuggestions 2012-05-05 13:34:09 -07:00
ridiculousfish
fe7fa46d57 Make dirh, nextd, prevd work on OS X 2012-05-04 18:53:38 -07:00
ridiculousfish
007c5bc9f0 Workaround difference between BSD and GNU seq in dirh
dirh still doesn't make any sense
2012-05-04 18:37:24 -07:00
ridiculousfish
8c423b56df Define a virtual destructor for lru.h 2012-05-04 18:37:12 -07:00
ridiculousfish
a868abb55a Minor cleanup of proc.cpp 2012-04-25 13:38:40 -07:00
ridiculousfish
ecab34c787 Make gettext function use echo instead of printf to save a fork 2012-04-25 13:37:41 -07:00
ridiculousfish
307ea6dce2 Removed extra newline from Goodbye output 2012-04-25 13:37:01 -07:00
ridiculousfish
d456b4f68e Removed useless deroff.py import from bash settings 2012-04-25 13:36:21 -07:00
ridiculousfish
17e815348b Fix to drain command output from quit commands before returning from job_continue
This should fix the bug where output from commands and builtins gets incorrectly interleaved.
I think this is a very long-standing bug that predates my work on the shell
2012-04-25 13:26:56 -07:00
ridiculousfish
953ab4b3cf Clean up __fish_config_interactive a little bit 2012-04-24 11:12:04 -07:00
ridiculousfish
9204780c1b Fix for a missing lock in complete_remove 2012-04-24 11:01:04 -07:00
ridiculousfish
fb2ed355ec Improve fork reporting
Save a couple of forks during init
2012-04-24 10:10:43 -07:00
ridiculousfish
675106cfa5 Include algorithm header so we can build on Linux 2012-04-23 19:29:44 -07:00
ridiculousfish
3aeadd9fb7 Fix for a deadlock when env_get_string ends up calling env_get_string 2012-04-23 11:08:29 -07:00
ridiculousfish
0e3eb38f11 Improved fork reporting
Made autosuggestion work properly for tilde expansion
2012-04-21 20:08:44 -07:00
Siteshwar Vashisht
dc23af6b32 Fixed setting PATH variable in import_bash_settings.py 2012-04-22 00:18:40 +05:30
ridiculousfish
b1bfa71338 Merge branch 'master' into CPlusPlus
Conflicts:
	builtin_commandline.cpp
	util.c
2012-04-18 13:41:39 -07:00
ridiculousfish
3c190374b4 Wrote tests for history merging, then made them pass. 2012-04-16 20:26:50 -07:00
ridiculousfish
d8428463d8 Fix to better handle merging histories between separate sessions 2012-04-15 22:49:27 -07:00
ridiculousfish
725982cc5b Fix to try to remove Python 2.7 dependency 2012-04-15 19:45:44 -07:00
ridiculousfish
f977dfcfe7 Deroffer optimizations 2012-04-15 19:22:30 -07:00
ridiculousfish
15079fa3bd Some more deroff optimizations 2012-04-15 04:41:20 -07:00
ridiculousfish
79a92120ef Speed improvements to deroffer 2012-04-15 01:15:10 -07:00
ridiculousfish
a34565ca0f Make screen.cpp properly compute the length of term256 escape codes 2012-04-13 14:40:16 -07:00
ridiculousfish
49ece586d5 Added a fish_update_completions function to run the manpage completion file
Added some pretty progress reporting to that script
Added some comments to deroff.py
2012-04-11 19:05:43 -07:00
ridiculousfish
2ec0778d78 Make create_manpage_completions output to ~/.config/fish/completions by default, and also discover man pages from reading the manpath 2012-04-11 18:26:26 -07:00
ridiculousfish
cccd1cefbe Make the web config page have a title and pass W3C validation 2012-04-11 18:26:10 -07:00
ridiculousfish
8f145fa7fa Fix for complete.cpp to print out completions in-order 2012-04-11 18:25:37 -07:00
ridiculousfish
ceb32f63e7 Deroffing completion work 2012-04-09 20:17:54 -07:00
ridiculousfish
576c12b184 Deroffer work 2012-04-09 20:17:54 -07:00
ridiculousfish
e2c3ca9950 Move completions from linked list to std::set 2012-04-09 20:17:06 -07:00
ridiculousfish
8585e0e9b8 Various improvements on completion tool 2012-04-04 12:43:12 -07:00
ridiculousfish
7394374a15 Work on improving the output of the manpage completion script 2012-04-03 18:38:25 -07:00
ridiculousfish
37defa739b Fix for an extra line at the end of the variable listing
Once again, fix the issue where some color cells aren't clickable
2012-04-01 01:31:38 -07:00
ridiculousfish
51ed3fbc4b More work to try to make webconfig's layout correct under firefox 2012-04-01 00:53:53 -07:00
ridiculousfish
ab78075d06 Default all xterms into term256 2012-04-01 00:53:47 -07:00
ridiculousfish
52070ea577 Fix to properly update colors for non-native term256 support 2012-03-31 17:24:11 -07:00
ridiculousfish
f930303d3e Fix for an issue where you can't select the top row of colors 2012-03-31 15:38:30 -07:00
ridiculousfish
268fb37517 Cleanup proc_had_barrier
Ensure we don't try to do a universal barrier off of the main thread
2012-03-31 15:33:34 -07:00
ridiculousfish
ff17101316 A little better support for non-term-256 colors in web config
Fix for a deadlock when autoloading a function triggers autoloading another function
2012-03-31 15:17:14 -07:00
ridiculousfish
ab536e5199 Fix for incorrectly highlighted parameters 2012-03-31 14:05:14 -07:00
ridiculousfish
c10b3017d6 Improve autosuggesting of cd command 2012-03-30 11:16:24 -07:00
ridiculousfish
0f63e1f988 Some work towards improving manpage completions 2012-03-30 10:00:01 -07:00
ridiculousfish
3bb537c183 Fix for failing to highlight last quote (or quoted string contents) 2012-03-30 09:58:25 -07:00
ridiculousfish
ff23bf6f0c Fix for bug where fish would not autosuggest certain executables 2012-03-27 19:22:33 -07:00
ridiculousfish
00d3e18780 Fix compile error (oops) 2012-03-27 19:10:21 -07:00
ridiculousfish
a62f300753 Make the color picker cell borders appear correctly in Firefox 2012-03-27 19:00:03 -07:00
ridiculousfish
0bc644abf0 Fix lots of bugs related to the static analyzer
Improved how screen.cpp interacts with output_set_writer()
2012-03-26 01:21:10 -07:00
ridiculousfish
31b7d076b7 Remove some dead variables.
Fix screwy output for invalid tilde expansion in expand.cpp
Some cleanup per clang static analyzer
2012-03-25 23:31:03 -07:00
ridiculousfish
a11687fc5c Make the functions builtin have a bit nicer output
Stop autosuggesting things with newlines
Make webconfig a little nicer
2012-03-25 22:41:22 -07:00
ridiculousfish
fa346cec3b Moved some Python scripts into new share/tools/ directory.
Added fish_config function to launch web config
2012-03-25 18:38:33 -07:00
ridiculousfish
0bdf7a598a More work on web_config 2012-03-25 16:00:17 -07:00
ridiculousfish
0c9a1a56c2 Lots of work on web config
Change to make fish immediately show color changes
2012-03-25 16:00:17 -07:00
ridiculousfish
c0655b6b08 Web config 2012-03-25 16:00:17 -07:00
Siteshwar Vashisht
dca9b83ec0 Enclose descriptions inside double quotes, and escape any enclosed double quotes. 2012-03-23 21:34:52 +05:30
Siteshwar Vashisht
7ded90ae6a Add trimmed descriptions with complete command while parsing man pages. 2012-03-22 23:41:36 +05:30
Peter Ammon
a6ab66080e Additional tweak to color order 2012-03-20 11:33:44 -07:00
Siteshwar Vashisht
89e1cad470 Append $argv only to the last command in an alias. 2012-03-20 22:07:34 +05:30
Peter Ammon
e55bc92d1f Tweak the color order 2012-03-20 03:05:00 -07:00
Peter Ammon
d6a59b538f Work on web config color ordering 2012-03-20 03:01:00 -07:00
ridiculousfish
1a87f44325 Re-implement $history variable
Added -L option to set to mean "don't abbreviate"
2012-03-19 11:52:18 -07:00
ridiculousfish
c8bc535f22 Big improvement to web config history speed
Nice dashed table seprators
2012-03-19 11:51:44 -07:00
Peter Ammon
1889db3263 web_config work 2012-03-19 00:03:38 -07:00
Siteshwar Vashisht
73b88f2304 Added method to find a character outside quotes in a string. 2012-03-18 15:14:34 +05:30
Siteshwar Vashisht
21b8e5a5c6 Some additions to make scripted aliases work 2012-03-18 15:00:27 +05:30
ridiculousfish
b1ff14162f More work on web config 2012-03-16 17:21:37 -07:00
Peter Ammon
c6c55823ac More work on web config 2012-03-16 03:05:51 -07:00
ridiculousfish
8b8a970098 Made builtin_test handle parenthesis 2012-03-15 20:40:57 -07:00
Siteshwar Vashisht
ebfcee6e67 Fixed a crash on inputs like ls x>| less, where x doesn't exist in current directory. 2012-03-16 00:34:09 +05:30
Peter Ammon
63b330439e Initial work towards web config UI 2012-03-15 03:43:45 -07:00
ridiculousfish
52d8fb301c Added term256 support to set_color tool 2012-03-13 14:23:10 -07:00
Siteshwar Vashisht
dfe159e719 Fixed a crash on Linux caused while inserting \ in quotes. 2012-03-13 05:39:17 +05:30
Siteshwar Vashisht
4e7e45a431 Adding scripts to import aliases, environment variables and prompt from bash. 2012-03-11 22:46:58 +05:30
ridiculousfish
d81bd296fc Tweak rgb_color_t back down to 4 bytes 2012-03-10 16:15:56 -08:00
ridiculousfish
6d3f257439 Shortened the "no matches found" error message 2012-03-10 13:44:35 -08:00
ridiculousfish
f92b24221a Made pwd a builtin
Fixed a thread error when autosuggesting with a command substitution
2012-03-09 20:16:26 -08:00
ridiculousfish
afd78f3f0b Allow g_log_forks to be set by fish_log_forks env var 2012-03-09 11:56:33 -08:00
ridiculousfish
44f3f51e0d Attempt to not fork just to output the result of simple builtins. I'm unsure of why this was necessary, if it ever was. 2012-03-09 11:49:29 -08:00
ridiculousfish
14a35e7c21 Flip the switch to stop draining threads before exec (!) 2012-03-09 11:28:24 -08:00
ridiculousfish
d173bb6e0a A bunch of changes working towards eliminating all memory allocation after fork() 2012-03-08 23:21:07 -08:00
ridiculousfish
ce859c9e92 Added some missing calls to setup_fork_guards() in utilities.
Made echo a builtin
2012-03-07 11:35:22 -08:00
ridiculousfish
8ed20f3c28 Removed pwd.fish, which made the home directory print out with ~ (annoying) 2012-03-07 10:53:08 -08:00
ridiculousfish
0ced7d8e56 Improve error reporting for builtin_test 2012-03-07 01:16:50 -08:00
ridiculousfish
143ead8d00 Fix builtin_test to properly handle last expression in a combining expression 2012-03-07 01:13:24 -08:00
ridiculousfish
6788c2710f Improved error reporting for builtin_test 2012-03-07 01:02:46 -08:00
ridiculousfish
ed7c10f366 Implemented test as a builtin (!) 2012-03-07 00:54:01 -08:00
ridiculousfish
68b93c624f Move special handling of DISPLAY environment variable from etc/config.fish to fish itself to reduce number of fork calls made at launch 2012-03-06 15:52:16 -08:00
ridiculousfish
36fe1e4a46 Some initial work towards cutting down the number of fork calls we do 2012-03-06 15:12:37 -08:00
ridiculousfish
9ee4e4e05c Tweak fork guards to use getpid() instead of pthread_atfork 2012-03-06 14:34:18 -08:00
ridiculousfish
ea65a0c519 Updated a comment 2012-03-06 14:32:00 -08:00
ridiculousfish
f35d2629d4 Notice when fish_term256 changes and react to it 2012-03-05 14:18:16 -08:00
ridiculousfish
0e5578204e Additional work towards "forcing" term256 mode on supported terms 2012-03-05 13:39:01 -08:00
ridiculousfish
063a465227 Begin to rework term256 support 2012-03-05 10:44:08 -08:00
ridiculousfish
230fb921ec We had identical format_val and to_string; standardize on to_string 2012-03-05 10:18:42 -08:00
ridiculousfish
82a93d8406 Fix for completions only printing one item 2012-03-05 10:03:26 -08:00
ridiculousfish
2dda8634e9 Fix to stop autosuggesting on whitespace 2012-03-05 09:34:54 -08:00
Siteshwar Vashisht
2f313b799a Made fish_tests.cpp compile on Linux. 2012-03-05 21:57:31 +05:30
ridiculousfish
d371256913 Fix for crash on "less test <tab>" 2012-03-04 18:11:21 -08:00
Siteshwar Vashisht
a7ec93b287 Fixed compilation on Linux. 2012-03-04 16:57:41 +05:30
ridiculousfish
2c5001a5b3 Removed buffer_t 2012-03-04 02:45:51 -08:00
ridiculousfish
191221eec5 Final cleanup of io_data_t now that I recognize the bizarre way in which it shares output buffers (not sure how this ever worked before) 2012-03-04 02:35:30 -08:00
ridiculousfish
27f374a38b Some initial work on removing buffer_t from io_data_t 2012-03-03 23:56:35 -08:00
ridiculousfish
baa813c46f Fix for history being saved too often 2012-03-03 23:10:15 -08:00
ridiculousfish
79a22b1f8d Replace some string_buffer_t 2012-03-03 23:01:42 -08:00
ridiculousfish
087940ec9e Fix a bug where wfopen would always fail
Removed some buffer_t
2012-03-03 22:48:21 -08:00
ridiculousfish
8a46931e34 Remove string_buffer_t (!) 2012-03-03 22:08:34 -08:00
ridiculousfish
a9313fc0c3 Cleanup reader.cpp's usage of string_buffer, remove some other unused data structures 2012-03-03 21:59:45 -08:00
ridiculousfish
dfba35aee8 Clean up the kill ring 2012-03-03 21:46:06 -08:00
ridiculousfish
5ae77b4317 For for crash when typing backslash c 2012-03-03 20:38:16 -08:00
ridiculousfish
a0bb2cdc6e removed some string_buffer 2012-03-03 19:37:55 -08:00
ridiculousfish
0a5680c3e8 Rewrite vformat_string to not use string_buffer 2012-03-03 19:12:06 -08:00
ridiculousfish
00764406d7 Fix to preserve errno across certain calls to stop printing EOVERFLOW messages in weird places 2012-03-03 15:28:16 -08:00
ridiculousfish
3ead99b088 Put fish on a diet. Tracked down the biggest memory hogs and fixed them. Total allocations down by a factor of 3 or so, live allocations a few KB. 2012-03-03 15:22:03 -08:00
Siteshwar Vashisht
8c0803e3c5 Setting cdpath to current directory in path.cpp. 2012-03-04 01:28:09 +05:30
ridiculousfish
2da8df6202 Rearrange wopen and stat to avoid a race and hopefully improve performance a little bit. 2012-03-02 11:12:08 -08:00
ridiculousfish
17a75a5aa5 Change to detect and use O_CLOEXEC 2012-03-02 09:58:29 -08:00
Peter Ammon
8b26d0104c Some initial changes to use CLO_EXEC, with an eye towards some day using it correctly. 2012-03-02 00:27:40 -08:00
ridiculousfish
36622c3578 Fix to properly handle case insensitive autosuggestions 2012-03-01 17:31:45 -08:00
ridiculousfish
fd4df6f9bb Changed iterators from iter++ to ++iter
Large set of changes to history to ensure that histories from other sessions don't "bleed" into the current session
2012-03-01 14:56:34 -08:00
ridiculousfish
5d18d60e3b Squash some leaks 2012-02-29 18:09:20 -08:00
ridiculousfish
e4d98597c7 Added some fork tests, fixed some bugs it found 2012-02-29 17:55:50 -08:00
ridiculousfish
72da14e414 Fix a leak 2012-02-29 17:55:28 -08:00
ridiculousfish
8ada404c5f More work towards improving relationship between multithreading and fork 2012-02-29 16:14:51 -08:00
ridiculousfish
ebba30d671 Fix a "class <-> struct" warning with clang++ 2012-02-29 16:14:51 -08:00
ridiculousfish
909d24cde6 More work on improving interaction between fork and pthreads. Added null_terminated_array_t class. 2012-02-29 16:14:51 -08:00
ridiculousfish
4e912ef83d Added postfork 2012-02-29 16:14:51 -08:00
ridiculousfish
b17dfff3fd Fix for out-of-bounds write in highlight_param 2012-02-29 16:14:03 -08:00
ridiculousfish
52dc415d0b Fix to add a generation count to threaded operations so they abort early 2012-02-28 12:40:59 -08:00
Siteshwar Vashisht
392232246e Fixed compilation on Linux with some minor changes. 2012-02-28 21:20:09 +05:30
ridiculousfish
cf54ad8242 Change to wait for all outstanding iothreads before calling fork(). This should prevent a whole host of threading/fork interactions, but may also compromise performance...we'll see. 2012-02-27 19:46:15 -08:00
ridiculousfish
fdfa5c0602 Some initial work towards resolving nasty fork/pthread issues, and to having a per-parser job list 2012-02-27 18:43:24 -08:00
ridiculousfish
50ee5d28cd Fix to finally turn on multithreaded completions for autosuggestion 2012-02-27 15:33:46 -08:00
ridiculousfish
f74a82776f Some more changes in preparation for turning on complete-based autosuggestions 2012-02-26 20:11:34 -08:00
ridiculousfish
3553e65089 Add some more locking and const correctness to completion_entry_t in preparation for supporting better multithreading 2012-02-26 14:32:06 -08:00
ridiculousfish
ad7c5886bc Fix a crash in complete -C 2012-02-26 13:46:21 -08:00
ridiculousfish
b30090f946 Some cleanup of completions in preparation for more multithreading 2012-02-26 13:27:31 -08:00
ridiculousfish
8f637975a4 Temporarily disable background completions 2012-02-26 12:16:22 -08:00
ridiculousfish
94a764d6ea Fix for error messages when loading completions 2012-02-26 01:15:53 -08:00
ridiculousfish
38e40862fe More work towards autosuggesting completions 2012-02-25 18:54:49 -08:00
ridiculousfish
5ea78f55f2 Some more work on threaded completions 2012-02-24 18:43:10 -08:00
ridiculousfish
a515db4aea Some work to allow completions to be evaluated off of the main thread 2012-02-24 12:19:31 -08:00
ridiculousfish
90e979d0d9 Added some const correctness 2012-02-24 09:33:30 -08:00
Siteshwar Vashisht
8232857d07 Modified env_get_string() to accept wcstring instead of wchar_t*. 2012-02-24 00:58:01 +05:30
ridiculousfish
2ae56564ef Changes to block signals for a smaller time interval during saving 2012-02-23 10:49:30 -08:00
ridiculousfish
f24a0170be Fix for failing to unescape history properly, resulting in a backslash explosion 2012-02-23 10:29:42 -08:00
Siteshwar Vashisht
fd56465931 Fixed initialization of va_list variable in debug() in common.cpp, and mismatched new/free() in io.cpp 2012-02-23 23:10:51 +05:30
ridiculousfish
376e199ebb Removed a lot of string_buffer_t 2012-02-22 12:00:02 -08:00
ridiculousfish
a837a27b34 Replace some string_buffer_t with wcstring 2012-02-22 11:07:34 -08:00
ridiculousfish
62bd43f17f Large set of changes to migrate sb_out and sb_err to wcstring 2012-02-22 10:51:06 -08:00
ridiculousfish
917b4ff8bc Fix for crash on redirections 2012-02-21 19:39:29 -08:00
ridiculousfish
5fe7c065dc Squash a bunch of leaks 2012-02-21 19:33:11 -08:00
ridiculousfish
e074ad4807 Removed a leaking wcsdup 2012-02-21 18:18:10 -08:00
ridiculousfish
5f3fe4acff Removed an optimization obviated by our use of wcstring from env.cpp 2012-02-21 18:12:51 -08:00
ridiculousfish
4ccc197451 Fix to change highlighting functions to take wcstring& instead of const wchar_t * 2012-02-21 17:55:56 -08:00
ridiculousfish
237cf19a77 Switch to using std::vector instead of int* for colors in highlight.cpp, for better range bounds checking 2012-02-21 11:45:13 -08:00
ridiculousfish
2206e221bd Removed array_list_t (!) 2012-02-21 10:47:21 -08:00
ridiculousfish
d9bb9b73ad Change to allow building without doxygen 2012-02-20 16:18:10 -08:00
ridiculousfish
d5c382bb1a Piling on more code to make autosuggestion try to guess directories even when they're not in the history 2012-02-20 02:13:31 -08:00
Peter Ammon
52daf6cf41 Fix to allow color.cpp to use fallback wcscasecmp 2012-02-19 11:07:02 -08:00
Siteshwar Vashisht
74a7303c23 Modified functions in function.h/.cpp to use wcstring instead wchar_t*, other files also modified to use wcstring. 2012-02-19 22:55:15 +05:30
ridiculousfish
d8a9991738 Fix to avoid calling signal_block off of hte main thread 2012-02-18 23:26:39 -08:00
ridiculousfish
ca1c8243c8 Fix to prevent autosuggesting cd'ing to the current working directory 2012-02-18 21:56:30 -08:00
ridiculousfish
14b3a5be56 Changes to make autosuggestion even smarter by specially recognizing the cd command. 2012-02-18 18:54:36 -08:00
ridiculousfish
ed89df7e9d Some minor cleanup of reader.cpp in preparation to unify highlighting with autosuggestion 2012-02-18 18:51:11 -08:00
ridiculousfish
1bedc16544 Enhanced directory detection in a way we don't actually need yet 2012-02-18 18:51:11 -08:00
ridiculousfish
ac0b97a571 Squash some warnings 2012-02-18 18:49:55 -08:00
Siteshwar Vashisht
7b3d670e23 Removing some unnecessary calls to c_str(), and added str2wcstring(std::string) in common.cpp. 2012-02-18 23:28:54 +05:30
Siteshwar Vashisht
c9f4e91df8 Modified most functions in wutil.h/.cpp to use wcstring instead of wchar_t*, removing calls to c_str() while calling these functions in other files. 2012-02-18 22:41:22 +05:30
Siteshwar Vashisht
c0ed169fdc Getting rid of hash_table_t and it's helper functions completely. Bye bye hash_table_t ! 2012-02-18 21:21:10 +05:30
Siteshwar Vashisht
412894bfc8 Removed tests for hash_table_t from fish_tests.cpp 2012-02-18 21:04:09 +05:30
Siteshwar Vashisht
aad6e5648b Fix for properly removing universal variable. 2012-02-18 14:42:02 +05:30
ridiculousfish
8f1423946f Fix a crash when using quotes due to wgettext thread safety issues. 2012-02-17 15:55:54 -08:00
ridiculousfish
51da4856e2 Squash a leak in LRU caches 2012-02-17 14:54:58 -08:00
ridiculousfish
3b56c58f00 Fix for crash in env.cpp where a deleted entry was not removed from the map 2012-02-17 12:23:30 -08:00
ridiculousfish
4fd2531302 Fix to properly null-terminate export list 2012-02-17 11:42:53 -08:00
ridiculousfish
fdef238a83 Fix to stop spamming console with event messages (oops) 2012-02-17 11:40:26 -08:00
ridiculousfish
9787901ddb Fix for removing too many event handlers (that's why "Goodbye" never got printed") 2012-02-17 11:37:25 -08:00
Siteshwar Vashisht
6e58c9f7c8 Switched to std::map instead of hash_table_t in env.cpp and env_universal_common.cpp. 2012-02-18 00:25:29 +05:30
ridiculousfish
a08450bcb6 Changes to make autosuggestion smarter about not suggesting commands that could never succeed. 2012-02-16 00:24:27 -08:00
ridiculousfish
a92d9d442b Initial work towards making autosuggestion smarter by recognizing paths 2012-02-15 11:33:41 -08:00
ridiculousfish
e2ff77b4ec Clean up make_path and some memory allocations 2012-02-13 22:44:29 -08:00
ridiculousfish
caf7a93382 Fix for busted completions (tab completion of directories was failing) 2012-02-13 22:37:09 -08:00
ridiculousfish
afcda2f724 Fix a leak 2012-02-13 19:39:20 -08:00
ridiculousfish
fcea723aa7 Fixed parenthesis causing a crash or bizarre layout. 2012-02-13 17:15:41 -08:00
ridiculousfish
faf80588ab Fix for busted directory check 2012-02-13 16:38:35 -08:00
ridiculousfish
fc589611e2 Attempt to make fish_pager.cpp compile on Linux 2012-02-13 14:25:07 -08:00
ridiculousfish
5ecd350311 Another attempt to make mimedb.cpp compile on Linux 2012-02-13 14:22:07 -08:00
ridiculousfish
4b6c6c59b5 Squash warnings in mimedb, hopefully get it compiling on Linux 2012-02-13 12:14:26 -08:00
ridiculousfish
0f8ffa6226 For for crash printing backtrace for command "eval cd sldkfjsdlfk" 2012-02-13 11:55:02 -08:00
ridiculousfish
6def61dfe9 A bit more debugging to parser class to try to track down a crash 2012-02-13 11:42:58 -08:00
ridiculousfish
b39bebee06 Fix for problem where we'd never use a cached placeholder function. Also upped the staleness interval from its testing value of 1 to 15 seconds. 2012-02-13 10:28:04 -08:00
ridiculousfish
dce189fc6d Support for setting both RGB and named colors on the same line, so the same config can work for multiple term types 2012-02-13 09:52:17 -08:00
ridiculousfish
0a4c72e78b Added color.h, color.cpp. Got term256 colors working. 2012-02-12 18:05:59 -08:00
ridiculousfish
d66700a0e4 Color work 2012-02-11 17:07:56 -08:00
ridiculousfish
b59a22bef0 Colors 2012-02-10 17:57:20 -08:00
ridiculousfish
9b1930588f Migrate errors from array_list_t to wcstring_list_t 2012-02-10 17:54:38 -08:00
Siteshwar Vashisht
18bb64cd43 Fixed compilation with recent changes on Linux. 2012-02-10 21:25:06 +05:30
ridiculousfish
d975187433 Removed some al_list functions 2012-02-10 01:37:30 -08:00
ridiculousfish
910863e9ea Final removal of halloc. It's like Christmas Morning. 2012-02-09 19:26:44 -08:00
ridiculousfish
a38490429b Removed a halloc_register_function_void 2012-02-09 19:00:05 -08:00
ridiculousfish
80e8f6a0d1 Removed halloc_wcsdup 2012-02-09 18:59:15 -08:00
ridiculousfish
e5ff5f7484 Some hopefully good changes to get IOs off of halloc 2012-02-09 18:43:36 -08:00
ridiculousfish
646240fc54 Changed the Makefile to no longer fail if man pages are missing, etc. 2012-02-09 16:36:35 -08:00
ridiculousfish
19cd7a248d Cleanup of wildcard.cpp, removing ad-hoc hash table and halloc 2012-02-09 16:06:24 -08:00
ridiculousfish
f1b1d1ca75 Get rid of some string buffer 2012-02-09 10:14:06 -08:00
ridiculousfish
e5bba2294d Removed some more halloc 2012-02-09 02:01:49 -08:00
ridiculousfish
19cfd9b5d6 Fix for pager regression 2012-02-09 01:54:46 -08:00
ridiculousfish
7e1b15a0cc More changes to fish pager to fix regressions. It didn't actually work. 2012-02-09 01:39:08 -08:00
ridiculousfish
19858c574d Removed halloc and al_list from fish_pager. paging still seems to work 2012-02-09 01:02:12 -08:00
ridiculousfish
f891ea5713 Fixed named_arguments to be wcstring_list_t instead of al_list 2012-02-08 23:53:23 -08:00
ridiculousfish
d3311c81e5 REmoved al_list from exec.cpp 2012-02-08 22:56:42 -08:00
ridiculousfish
b6bc4381fb Get event_t off of halloc (!) 2012-02-08 19:02:25 -08:00
ridiculousfish
b3d0561c09 Cleanup event_get_desc 2012-02-08 16:20:48 -08:00
ridiculousfish
1bbe901bcd Eliminated halloc usage from complete.cpp 2012-02-08 16:15:53 -08:00
ridiculousfish
4f8b4379f5 Cleanup of completion_entry in complete.cpp 2012-02-08 14:48:22 -08:00
Siteshwar Vashisht
bc8a288386 Got rid of multiple cd paths, only current directory will be searched while changing directories, implicit cd (entering directory just by typing it's name) is removed. 2012-02-09 01:18:51 +05:30
ridiculousfish
3dc56de0ae Excised some more halloc and array_list_t 2012-02-08 02:34:31 -08:00
ridiculousfish
b2e5809180 Removed halloc from highlight.cpp 2012-02-08 02:13:39 -08:00
ridiculousfish
7e52523541 Migrate mimedb off of al_init 2012-02-08 01:55:35 -08:00
ridiculousfish
8bc83c5967 Removed al_list from mimedb.cpp 2012-02-08 01:22:08 -08:00
ridiculousfish
029c8c06c2 Remove old env_get_names implementation 2012-02-08 00:59:46 -08:00
ridiculousfish
063fc0c48b Cleanup al_list from builtin_complete.cpp 2012-02-08 00:45:07 -08:00
ridiculousfish
191eeab589 Cleanup expand_escape_variable 2012-02-08 00:15:06 -08:00
ridiculousfish
3f8621e566 CLeanup the io_stack in builtin.cpp, other changes to migrate away from al_list 2012-02-07 23:53:34 -08:00
ridiculousfish
5f686ebb47 Clean up exec_subshell, removing al_list from it 2012-02-07 23:35:41 -08:00
ridiculousfish
6a31457c6d Really excise halloc from input.cpp 2012-02-07 23:17:20 -08:00
ridiculousfish
e6f7912a25 Removed halloc from input.cpp 2012-02-07 23:15:32 -08:00
ridiculousfish
8a2737566c Excised some more halloc 2012-02-07 22:44:10 -08:00
ridiculousfish
006523ac59 Replaced void*data with auto_ptr<function_data_t>, eliminating antoher halloc. 2012-02-07 22:10:35 -08:00
ridiculousfish
c0e783eb6e Excised some halloc 2012-02-07 21:23:12 -08:00
ridiculousfish
399c78fbf7 Fix event_block_t list from ad-hoc linked list to std::dequeue 2012-02-07 21:04:51 -08:00
ridiculousfish
a0a43046b3 Removed discriminated union from block_t type, allowing us to store wcstrings in it 2012-02-07 17:36:54 -08:00
Siteshwar Vashisht
e8af86017a Fixed a bug caused while highlighting double quoted strings. For e.g. ls "abc" shows up as invalid write for color of closing quote in valgrind. 2012-02-07 21:37:53 +05:30
ridiculousfish
382ffe9b6a Added autosuggestion color variable fish_color_autosuggestion
Fixed that nasty bug where fish would apply a color to both the foreground and background (yuck)
2012-02-06 20:14:19 -08:00
ridiculousfish
e5b34d5cd5 Suppress autosuggesting during backspacing like browsers do 2012-02-06 19:31:06 -08:00
ridiculousfish
0dba7b3313 Use right arrow to accept autosuggestions 2012-02-06 11:59:34 -08:00
ridiculousfish
27f2859258 Make history searching skip the autosuggestion 2012-02-06 11:52:24 -08:00
ridiculousfish
eeed45da0f Fix some bugs related to not updating our buffer size as our command line changes 2012-02-06 11:34:49 -08:00
ridiculousfish
067dff8489 Initial stab at autosuggestions 2012-02-06 10:52:13 -08:00
ridiculousfish
7d3151191d Removed builtin_scripts.h and builtin_scripts.cpp from Xcode project because they're annoying in searches 2012-02-06 10:47:55 -08:00
ridiculousfish
98fa1325f5 insert_str -> insert_string 2012-02-06 02:20:50 -08:00
ridiculousfish
bd45b79ed8 Removed buff_len field. One fewer field, hooray. 2012-02-06 01:53:03 -08:00
ridiculousfish
0a616a9dbb Large set of changes to migrate reader_data_t's buffer to std::wstring 2012-02-06 01:45:16 -08:00
ridiculousfish
a534c397f5 Const correctness changes 2012-02-06 00:57:43 -08:00
ridiculousfish
737589ec01 Removed lru.cpp (double oops) 2012-02-06 00:53:08 -08:00
ridiculousfish
a7f8ee90c0 Added LRU.cpp (oops) 2012-02-06 00:52:22 -08:00
ridiculousfish
b14683200a Change the history so that when you go forwards, it no longer highlights 2012-02-05 23:22:18 -08:00
ridiculousfish
c82410bfda Fixed history tests 2012-02-05 22:48:43 -08:00
ridiculousfish
00ad837eb4 Final cleanup of history 2012-02-05 22:30:42 -08:00
ridiculousfish
9ab54030b9 Moved LRU to its own file 2012-02-05 20:54:41 -08:00
ridiculousfish
5ad6849d4e Work on new history implementation 2012-02-05 16:42:24 -08:00
ridiculousfish
7fcf25a78f Removed the "don't highlight with stale data" code, that caused "flashing" as we typed 2012-02-03 20:06:48 -08:00
ridiculousfish
5c205c43d1 Fix to highlight search results range matching again 2012-02-03 20:05:50 -08:00
ridiculousfish
f20f49d872 Migrate search_buff to wcstring 2012-02-03 20:01:01 -08:00
ridiculousfish
fb63c3908c Minor cleanup of background_highlight_context_t 2012-02-03 18:39:41 -08:00
ridiculousfish
623eb42a6a CLean up current_filename, make it a std::stack 2012-02-02 15:05:08 -08:00
ridiculousfish
6afc06b97e Migrate some al_list to std::vector 2012-02-02 14:27:13 -08:00
ridiculousfish
cdd5b1ed26 Fixed a crash doing completion of commands 2012-02-02 14:11:20 -08:00
ridiculousfish
884b4026dd Cleanup complete_cmd_desc 2012-02-02 12:04:04 -08:00
ridiculousfish
62f49c55ce Clean up uses of completion_t 2012-02-01 16:27:14 -08:00
ridiculousfish
0b4b6c498d Migrated off of old variant of expand_one that used halloc 2012-01-31 21:30:09 -08:00
ridiculousfish
409f70c7f3 Remove some old functions from expand.cpp that now have modern replacements 2012-01-31 21:09:11 -08:00
ridiculousfish
bb19fe703a Fixup wsetlocale to use wcstring 2012-01-31 21:06:52 -08:00
ridiculousfish
eef1e3e77e More cleanup of static string buffers in favor of wcstring 2012-01-31 20:22:25 -08:00
ridiculousfish
562ba1291e Stop using placement new like a weirdo 2012-01-31 20:03:48 -08:00
ridiculousfish
3adf6d25f6 Cleanup of builtins. No more hashes. 2012-01-31 19:47:56 -08:00
ridiculousfish
beece6a828 Clean up how argv is stored in process_t 2012-01-31 18:06:20 -08:00
ridiculousfish
207ab2aa5b Squashed all known remaining leaks! 2012-01-31 17:06:47 -08:00
ridiculousfish
4ccc2550d0 Squash a bunch of warnings 2012-01-31 17:01:19 -08:00
ridiculousfish
0c9e398bef Change parser_t::parse_job's args array to be a local, rather than just leak it, which no longer seems to crash 2012-01-31 16:50:03 -08:00
ridiculousfish
af2d348543 Substantial modifications of expand_variables to modernize, normalize memory management, adopt C++ types 2012-01-30 21:33:15 -08:00
ridiculousfish
13f72decf4 Fix a leak 2012-01-30 11:23:09 -08:00
ridiculousfish
3ad7de0fcb Fix some leaks and clean up expand_pid to use wcstring 2012-01-30 11:15:06 -08:00
Siteshwar Vashisht
48408b0a0b Merge branch 'CPlusPlus' of gitorious.org:~ridiculousfish/fish-shell/fishfish into CPlusPlus 2012-01-31 00:04:15 +05:30
Siteshwar Vashisht
cd7d1f2bfe Fix to not show thread debugging warning when entering characters like "~%". expand_string2() now uses it's own parser instead of principal_parser. Added PARSER_TYPE_ERRORS_ONLY in parser_type_t. 2012-01-30 23:58:30 +05:30
ridiculousfish
ed66a46113 Fix for is_potential_path that caused all strings to be reported as paths 2012-01-30 09:59:48 -08:00
ridiculousfish
8e4e30d266 Migrate functions like parser_keywords_is_block to wcstring 2012-01-30 09:46:33 -08:00
Siteshwar Vashisht
f988dcd6f9 Fixed compilation errors caused by latest commits 2012-01-30 21:45:02 +05:30
ridiculousfish
143091edad More work to excise halloc 2012-01-30 02:45:55 -08:00
ridiculousfish
79e0405f6a Yet more un-hallocing 2012-01-30 02:23:58 -08:00
ridiculousfish
316f81119f Excised some more halloc 2012-01-29 23:22:42 -08:00
ridiculousfish
8d016040ab Back out removing a halloc_register to fix a leak 2012-01-29 22:32:01 -08:00
ridiculousfish
4da6986a68 Fix to finally make builtin_scripts.h and builtin_scripts.cpp be generated by the Makefile 2012-01-29 22:29:13 -08:00
ridiculousfish
3b8a4e56b0 A bunch of work to move towards a sane memory model in job_t 2012-01-29 22:06:58 -08:00
ridiculousfish
966cd6a8ca Began migration of job_t away from halloc 2012-01-29 18:25:54 -08:00
ridiculousfish
f243cd86c9 Convert jobs list to std::list 2012-01-29 16:36:21 -08:00
Siteshwar Vashisht
1a5d866a91 buggy-auto-complete is not so buggy now. Merged branch 'buggy-auto-complete' into CPlusPlus 2012-01-29 14:11:39 +05:30
Siteshwar Vashisht
a1d8ed83dd Putting a copyright statement on my script :) 2012-01-29 13:02:40 +05:30
Peter Ammon
7f284c404f Fixed for comment in create_manpage_completions.py to refer to new filename 2012-01-28 22:48:47 -08:00
ridiculousfish
d1b3b6a0ed Added create_manpage_completions.py file for generating completions from man pages 2012-01-28 22:25:45 -08:00
ridiculousfish
9b37bc667f Fix for issue where we treated all cached files as accessible for the purpose of highlighting, instead of using their cached accessible variable 2012-01-28 15:49:50 -08:00
ridiculousfish
4eea68b5a4 LRU work to load functions off of the main thread.
We'll have to reevaluate this after we fix function autocomplete
2012-01-28 14:56:13 -08:00
ridiculousfish
87429bc03c More work on LRU cache and adopting it in function and completion autoloading 2012-01-27 11:43:52 -08:00
ridiculousfish
6c28448e84 Added LRU tests, and made tests work again 2012-01-27 11:43:45 -08:00
ridiculousfish
843ba4ac2c Move autoload class into autoload.h and cpp 2012-01-25 18:59:35 -08:00
ridiculousfish
d6545588a3 Have to remember to evict nodes from our LRU cache 2012-01-25 18:51:26 -08:00
ridiculousfish
26b375a0de Removed access_tracker since we don't need it after all 2012-01-25 18:42:41 -08:00
ridiculousfish
2f1cac604d Implemented LRU cache for autoloading. 2012-01-25 18:40:08 -08:00
ridiculousfish
8e56763c98 LRU cache work 2012-01-25 11:47:45 -08:00
ridiculousfish
e94e1cc72f New file autoload.h that will ultimately handle autoloading completions and functions 2012-01-25 00:36:55 -08:00
ridiculousfish
4dfe36feb1 Migrate input_function_get_names to wcstring_list_t 2012-01-23 20:48:47 -08:00
ridiculousfish
0d1c2a3b2a Migrated function.cpp to use the new function_get() call. Lots of nice short code now. 2012-01-23 20:43:39 -08:00
ridiculousfish
378fd60756 Migrate function.cpp to scoped_lock and shared_ptr 2012-01-23 20:32:36 -08:00
ridiculousfish
fa569b32fb Made intern'd strings thread safe.
Removed intern_free_all().
2012-01-23 20:02:15 -08:00
ridiculousfish
78f8317de8 Typo fixes 2012-01-23 19:33:57 -08:00
ridiculousfish
6e8637fbc9 Move autoloading from a map of path names to a real object autoload_t.
Moved the various things we can autoload into static objects.
Next step is to make them thread safe.
2012-01-23 11:42:41 -08:00
ridiculousfish
8403aae928 Convert some cases where parsers are created to using PARSER_TYPE_GENERAL 2012-01-22 21:57:30 -08:00
ridiculousfish
b43c8da66b More work towards instanced parser. First successful compilation 2012-01-22 21:40:08 -08:00
ridiculousfish
da85bdc401 More work on the instanced parser 2012-01-22 20:47:13 -08:00
ridiculousfish
7e486e3b5c More work towards instanced parser 2012-01-20 11:24:43 -08:00
Siteshwar Vashisht
062e423125 Fixed more known auto completion bugs; auto completion calls working fine now 2012-01-20 22:20:31 +05:30
ridiculousfish
3d8face1f9 More work on instancing the parser 2012-01-19 10:28:44 -08:00
Siteshwar Vashisht
0c99fc5b4d Removed unnecessary const_cast in wildcard.cpp 2012-01-19 22:23:25 +05:30
Siteshwar Vashisht
51d7d5d0da Fixed calls to expand_variables2() in expand.cpp 2012-01-19 21:49:24 +05:30
Siteshwar Vashisht
c959584831 Fixed reader.cpp to not show garbage while showing help on auto completing (on pressin tab) for executables like "ls -" 2012-01-19 00:03:19 +05:30
ridiculousfish
fa796d668f Get some basic function signatures right for new instanced parser 2012-01-16 12:10:08 -08:00
ridiculousfish
e4ee4ec3d1 Some const correctness 2012-01-16 11:16:12 -08:00
ridiculousfish
0073a93079 Beginnings of instance parser work 2012-01-16 11:09:19 -08:00
Siteshwar Vashisht
7e124cf95e Added constructor to completion_t for guarranted initialzation of flags attribute. 2012-01-16 23:54:57 +05:30
ridiculousfish
c647bed9d5 Fix for bogus check for IFS environment variable 2012-01-16 09:43:34 -08:00
Siteshwar Vashisht
6f330f961b Merge branch 'CPlusPlus' of gitorious.org:~ridiculousfish/fish-shell/fishfish into CPlusPlus 2012-01-16 22:27:55 +05:30
Siteshwar Vashisht
140ead65b6 Converted all auto completion calls (on pressing tab) to use std::vector<completion_t>, bugs are yet to be fixed 2012-01-16 22:26:47 +05:30
ridiculousfish
55091d9deb Fix to prevent autoloading of completions on highlight thread 2012-01-15 14:24:58 -08:00
Peter Ammon
1b3427acd9 Changes to make completions internalized scripts.
This about doubles the size of fish. These things are huge. We may not want to ship it like this.
2012-01-15 00:25:21 -08:00
Peter Ammon
60d1ac4fec More const and signed correctness. Warnings now fit on one page! 2012-01-14 22:48:53 -08:00
Peter Ammon
9b133a978d Improve const and signed/unsigned correctness 2012-01-14 22:32:45 -08:00
Peter Ammon
203c749e6c Improved const-correctness, eliminating warnings.
Migrated some int to size_t
2012-01-14 22:00:00 -08:00
Peter Ammon
f3e2d2f68f Lots of warnings fixes and const correctness 2012-01-14 03:41:50 -08:00
Peter Ammon
a359f45df2 Redesign new environment variables to use env_var_t instead of wcstring
Migrate uses of empty() to missing() to distinguish between empty variable and unset variable
2012-01-14 02:42:17 -08:00
Peter Ammon
e8b6d48ad0 Introduce env_var_t to replace empty string as missing environment variable 2012-01-14 01:06:47 -08:00
ridiculousfish
8ba79d6ab9 Migrate function.cpp to STL types. 2012-01-13 23:54:49 -08:00
ridiculousfish
57c9eeeecb Changes related to supporting "intern scripts." These are scripts that used to be installed in /share/functions, but now are just compiled-in strings. This should reduce the amount of I/O done at launch time. 2012-01-13 23:54:16 -08:00
Siteshwar Vashisht
f78c4fa751 Removed multiple delcartions of path_list from autoload_names() in fuction.cpp 2012-01-14 12:06:16 +05:30
Siteshwar Vashisht
3ba6e9db5d Merge branch 'Use_env_get_string' into CPlusPlus
Conflicts:
	function.cpp
2012-01-14 11:59:48 +05:30
Siteshwar Vashisht
610246c48f Modified function.cpp to use env_get_string(). 2012-01-12 23:22:38 +05:30
Siteshwar Vashisht
d0e18e3d20 Modified highlight.cpp to use env_get_string(). 2012-01-12 23:19:05 +05:30
Siteshwar Vashisht
72cfdbbb4e Modified input.cpp, output.cpp to use env_get_string() 2012-01-12 23:11:07 +05:30
Siteshwar Vashisht
15296dedd5 Modified kill.cpp to use env_get_string(). 2012-01-12 23:07:10 +05:30
Siteshwar Vashisht
943cc68f54 Modified parse_util.cpp, parser.cpp, path.cpp to use env_get_string() 2012-01-12 22:56:53 +05:30
Siteshwar Vashisht
3bb4d0b276 Modified reader.cpp to use env_get_string() 2012-01-12 22:32:50 +05:30
Siteshwar Vashisht
9cc2217a26 Fixed connection error to fishd server in env.cpp 2012-01-12 21:58:42 +05:30
Siteshwar Vashisht
ee687ee433 Modified exec.cpp to use env_get_string(); rolled back changes to expand.cpp in last commit, because pressing ^D results into an error with the changes 2012-01-12 21:39:00 +05:30
Siteshwar Vashisht
9b56b67c0e Revert "Modified expand.cpp and exec.cpp to use env_get_string()"
This reverts commit 48655e882e.
2012-01-12 04:21:11 +05:30
Siteshwar Vashisht
48655e882e Modified expand.cpp and exec.cpp to use env_get_string() 2012-01-12 04:19:04 +05:30
Siteshwar Vashisht
7f49d37a51 Modified exec.cpp to use env_get_string() 2012-01-12 04:01:08 +05:30
Siteshwar Vashisht
9f8a1168e6 Modified env.cpp to use env_get_string() 2012-01-12 03:57:38 +05:30
ridiculousfish
c18d177b8c Additional migration to STL data structures 2012-01-10 12:55:22 -08:00
Siteshwar Vashisht
7bde2b5cbf Modified complete.cpp to use env_get_string(); Fixed env_get_string() return an empty wcstring instead of returning 0. 2012-01-10 01:40:03 +05:30
Siteshwar Vashisht
7b3377e78c Modified builtin_set.cpp to use env_get(), added functions like update_values2(), env_set2() etc. to support wcstring and vector instead of using array_list_t 2012-01-10 01:19:37 +05:30
Siteshwar Vashisht
feed900f3d Further changes in builtin.cpp to use env_get_string() 2012-01-10 00:05:51 +05:30
Siteshwar Vashisht
7530057c6e Modified builting.cpp to use env_get_string() 2012-01-10 00:00:54 +05:30
Siteshwar Vashisht
a6b3f6b5d4 Modified screen.cpp to compile on Linux. 2012-01-07 16:35:49 +05:30
ridiculousfish
76f870a30a Improved check for pthread library to build successfully on Linux 2012-01-06 11:50:17 -08:00
ridiculousfish
02092f315e More work towards incorporating C++ build steps into Makefile.in and configure.ac 2012-01-06 11:29:03 -08:00
ridiculousfish
9ef9284a34 Fix for bogus cast warning in configure script that was breaking local_cv_use__posix_c_source 2012-01-06 10:43:27 -08:00
ridiculousfish
820acb981b Fix to incorporate C++ build changes into configure.ac and Makefile.in 2012-01-06 10:23:38 -08:00
ridiculousfish
2516fd90eb Updated dependencies in Makefile.in 2012-01-05 14:10:02 -08:00
ridiculousfish
de23368d03 Updated Makefile.cpp with updated header dependencies 2012-01-05 14:06:09 -08:00
ridiculousfish
4df57fda09 Incorporate Siteshwar's patch for building on Linux 2012-01-05 13:58:48 -08:00
ridiculousfish
6f45832aed Switch from std::set to std::map in parse_util.cpp 2012-01-04 17:56:02 -08:00
ridiculousfish
fec0415d4e Rewrote parse_util.cpp data structures to use STL types and classes 2012-01-04 17:40:36 -08:00
ridiculousfish
04c7d87261 More work towards supporting builtin scripts 2012-01-03 10:54:06 -08:00
ridiculousfish
6abf3db13e Added internalize_scripts.py in preparation for ending reliance on "standard" scripts in /usr/local/share 2012-01-02 17:02:30 -08:00
ridiculousfish
99000e68b7 Fix for crash when unescaping a string with unbalanced quotes
Add Mac OS X's default term name to terms for which we know how to set a title
2012-01-02 13:40:03 -08:00
ridiculousfish
bef046a51a More work to migrate off of ad-hoc data structures 2011-12-31 15:57:30 -08:00
ridiculousfish
78322a6321 Migrate some more away from array_list_t 2011-12-28 12:36:47 -08:00
ridiculousfish
46fa2dd2f0 Migration of screen away from ad-hoc lists 2011-12-27 18:41:38 -08:00
ridiculousfish
451399b344 Migrate to std::vector in event class 2011-12-27 00:06:07 -08:00
ridiculousfish
22a8e57a57 More migration away from al_list 2011-12-26 23:29:57 -08:00
ridiculousfish
9cd279e0e9 Migrate some more off of al_list 2011-12-26 23:13:05 -08:00
ridiculousfish
b67eaa3abd More migration to the STL 2011-12-26 22:51:34 -08:00
ridiculousfish
046c9b56f5 Migrate blocked to std::vector 2011-12-26 22:27:58 -08:00
ridiculousfish
6ad80247ce Migrate killme to std::vector 2011-12-26 22:22:55 -08:00
ridiculousfish
0b744edfa4 Migrate events to std::vector 2011-12-26 22:18:16 -08:00
ridiculousfish
0d8bb78f66 Fixed a build failure
Added a thread assertion to function.cpp
2011-12-26 21:56:23 -08:00
ridiculousfish
28ecc68841 Migrated some more data structures to the STL. Removed some ad-hoc data structure implementations. 2011-12-26 21:50:23 -08:00
ridiculousfish
7c7aba1202 Fix to migrate the universal variable server off of dyn_queue_t 2011-12-26 21:39:08 -08:00
ridiculousfish
74a1d70b8a Added iothread 2011-12-26 21:21:12 -08:00
ridiculousfish
165a5aaa83 Merge branch 'master' into CPlusPlus 2011-12-26 21:09:26 -08:00
ridiculousfish
04856aded0 IO port 2011-12-26 21:05:25 -08:00
ridiculousfish
a9c238a1fc Removed a log 2011-12-26 21:05:07 -08:00
ridiculousfish
8d2f107d61 Some changes to migrate towards C++ and a multithreaded model 2011-12-26 19:18:46 -08:00
ridiculousfish
3f16ace678 Initial C++ conversion 2011-12-26 19:11:54 -08:00
615 changed files with 78004 additions and 56814 deletions

4
.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
.gitattributes export-ignore
.gitignore export-ignore
/build_tools export-ignore

5
.gitignore vendored
View File

@@ -4,7 +4,9 @@
Doxyfile.help
Makefile
autom4te.cache/
build/
command_list.txt
confdefs.h
config.h
config.h.in
config.log
@@ -13,7 +15,6 @@ configure
doc.h
doc_src/commands.hdr
doc_src/index.hdr
etc/config.fish
po/*.gmo
fish
fish.spec
@@ -28,6 +29,6 @@ share/config.fish
share/man/
toc.txt
user_doc/
xsel-1.2.0/
xcuserdata
tests/*tmp.*
tests/foo.txt

View File

@@ -1,3 +1,3 @@
24-01-2012 Jan Kanis
* Added a changelog file
* removed unescaping if the 'commandline' builtin is called without the -o (tokenise) flag
* Added a changelog file
* removed unescaping if the 'commandline' builtin is called without the -o (tokenise) flag

73
INSTALL
View File

@@ -1,73 +0,0 @@
Known issues
============
Fish is developed using GCC, with the goal of using only C89 language
features. Fish does, however use the *wprintf family of functions,
which are new to the C99 standrard. It is not unlikely that any given
release contains a few GCC:isms, but ICC 9.0.030 has been found to
produce working binaries. GCC 2.95.* won't compile fish, but GCC 3.2.3
is known to work. Patches to fix any remaining GNU:isms are welcome.
Older versions of Doxygen has bugs in the man-page generation which
cause the builtin help to render incorrectly. Doxygen 1.2.14 is known
to have this problem.
Prerequisites
=============
Fish requires the following programs and libraries to build:
- Doxygen
- Curses or Ncurses
- GNU make
- GCC
fish also relies on standard unix tools such as cat, cut, grep, sed,
whoami, bc and echo. Fish does not yet support cross-compilation,
separate build directories or any other fancy configure options.
Simple install procedure
========================
Always begin by uninstalling any previous fish versions. This is done
by running the command 'make uninstall' in the source directory of
your previous fish installation.
Next, if you have downloaded a fresh copy of the darcs repository of
fish, you need to run the 'autoconf' command.
Then, use following commands to compile fish:
./configure
make # Compile fish
make install # Install fish
echo /usr/local/bin/fish >>/etc/shells # Add fish to list of shells
Finally, if you wish to use fish as your default shell, use the
following command:
% chsh -s /usr/local/bin/fish
chsh will prompt you for your password, and change your default shell.
Local install procedure
=======================
If you have downloaded the darcs repository of fish, you need to run
autoconf to generate the configure script.
To install fish in your own home directory (typically as non-root),
type:
% ./configure --prefix=$HOME
% make # Compile fish
% make install # Install fish
You will not be able to use fish as the default shell unless you also
add the corresponding line to /etc/shells, which mostly defeats the
point of a local install. As a workaround, you can add fish as the
last command of the init files for your regular shell.

View File

@@ -38,7 +38,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
# Programs
#
CC := @CC@
CXX := @CXX@
INSTALL:=@INSTALL@
@@ -55,23 +55,20 @@ mandir = @mandir@
sysconfdir = @sysconfdir@
docdir = @docdir@
localedir = @localedir@
prefix = @prefix@
optbindirs = @optbindirs@
#
# Various flags
#
MACROS = -DLOCALEDIR=\"$(localedir)\" -DPREFIX=L\"$(prefix)\" -DDATADIR=L\"$(datadir)\" -DSYSCONFDIR=L\"$(sysconfdir)\"
CFLAGS = @CFLAGS@ $(MACROS) $(EXTRA_CFLAGS)
CPPFLAGS = @CPPFLAGS@
MACROS = -DLOCALEDIR=\"$(localedir)\" -DPREFIX=L\"$(prefix)\" -DDATADIR=L\"$(datadir)\" -DSYSCONFDIR=L\"$(sysconfdir)\" -DBINDIR=L\"$(bindir)\"
CXXFLAGS = @CXXFLAGS@ $(MACROS) $(EXTRA_CXXFLAGS)
LDFLAGS = @LIBS@ @LDFLAGS@
LDFLAGS_FISH = ${LDFLAGS} @LIBS_FISH@ @LDFLAGS_FISH@
LDFLAGS_FISH_INDENT = ${LDFLAGS} @LIBS_FISH_INDENT@
LDFLAGS_FISH_PAGER = ${LDFLAGS} @LIBS_FISH_PAGER@
LDFLAGS_FISHD = ${LDFLAGS} @LIBS_FISHD@
LDFLAGS_MIMEDB = ${LDFLAGS} @LIBS_MIMEDB@
LDFLAGS_SET_COLOR = ${LDFLAGS} @LIBS_SET_COLOR@
#
# Set to 1 if we have gettext
@@ -81,11 +78,11 @@ HAVE_GETTEXT=@HAVE_GETTEXT@
#
#Additional .c files used by common.o. These also have a corresponding
#Additional .cpp files used by common.o. These also have a corresponding
#.h file.
#
COMMON_FILES := util.c halloc.c halloc_util.c fallback.c
COMMON_FILES := util.cpp fallback.cpp
#
@@ -96,8 +93,9 @@ FISH_OBJS := function.o builtin.o complete.o env.o exec.o expand.o \
highlight.o history.o kill.o parser.o proc.o reader.o sanity.o \
tokenizer.o wildcard.o wgetopt.o wutil.o input.o output.o intern.o \
env_universal.o env_universal_common.o input_common.o event.o \
signal.o io.o parse_util.o common.o screen.o path.o \
parser_keywords.o
signal.o io.o parse_util.o common.o screen.o path.o autoload.o \
parser_keywords.o iothread.o color.o postfork.o \
builtin_test.o
FISH_INDENT_OBJS := fish_indent.o print_help.o common.o \
parser_keywords.o wutil.o tokenizer.o
@@ -106,8 +104,9 @@ parser_keywords.o wutil.o tokenizer.o
# Additional files used by builtin.o
#
BUILTIN_FILES := builtin_set.c builtin_commandline.c \
builtin_ulimit.c builtin_complete.c builtin_jobs.c
BUILTIN_FILES := builtin_set.cpp builtin_commandline.cpp \
builtin_ulimit.cpp builtin_complete.cpp builtin_jobs.cpp \
builtin_set_color.cpp builtin_printf.cpp
#
@@ -116,7 +115,7 @@ BUILTIN_FILES := builtin_set.c builtin_commandline.c \
FISH_PAGER_OBJS := fish_pager.o output.o wutil.o \
input_common.o env_universal.o env_universal_common.o common.o \
print_help.o
print_help.o iothread.o color.o
#
@@ -158,7 +157,16 @@ HDR_FILES_SRC := doc_src/index.hdr.in doc_src/commands.hdr.in doc_src/design.hdr
# These are the generated result files
#
HDR_FILES := $(subst .hdr.in,.hdr,$(HDR_FILES_SRC))
HDR_FILES := $(HDR_FILES_SRC:.hdr.in=.hdr)
# Use a pattern rule so that Make knows to only issue one invocation
# per http://www.gnu.org/software/make/manual/make.html#Pattern-Intro
# Internalized scripts are currently disabled.
# For now, we just generate empty arrays.
# To generate them again, you would run this:
# ./internalize_scripts.py share/functions/*.fish share/completions/*.fish
#
# Files containing documentation for external commands.
@@ -189,14 +197,14 @@ DOC_SRC_DIR_FILES := $(HDR_FILES_SRC) $(HELP_SRC)
# Files in ./
#
MAIN_DIR_FILES_UNSORTED := Doxyfile Doxyfile.user Doxyfile.help.in \
Makefile.in configure configure.ac config.h.in install-sh \
set_color.c key_reader.c $(MIME_OBJS:.o=.h) \
$(MIME_OBJS:.o=.c) $(FISH_OBJS:.o=.h) $(BUILTIN_FILES) \
$(COMMON_FILES) $(COMMON_FILES:.c=.h) $(FISH_OBJS:.o=.c) \
fish.spec.in INSTALL README user_doc.head.html xsel-0.9.6.tar \
ChangeLog config.sub config.guess fish_tests.c fish.c fish_pager.c \
fishd.c seq.in make_vcs_completions.fish $(FISH_INDENT_OBJS:.o=.c)
MAIN_DIR_FILES_UNSORTED := Doxyfile Doxyfile.user Doxyfile.help \
Makefile.in configure configure.ac config.h.in install-sh \
key_reader.cpp $(MIME_OBJS:.o=.h) \
$(MIME_OBJS:.o=.cpp) $(FISH_OBJS:.o=.h) $(BUILTIN_FILES) \
$(COMMON_FILES) $(COMMON_FILES:.cpp=.h) $(FISH_OBJS:.o=.cpp) \
fish.spec.in INSTALL README user_doc.head.html \
ChangeLog config.sub config.guess fish_tests.cpp fish.cpp fish_pager.cpp \
fishd.cpp make_vcs_completions.fish $(FISH_INDENT_OBJS:.o=.cpp)
#
# The sorting is not meaningful in itself, but it has the side effect
@@ -207,20 +215,6 @@ MAIN_DIR_FILES_UNSORTED := Doxyfile Doxyfile.user Doxyfile.help.in \
MAIN_DIR_FILES := $(sort $(MAIN_DIR_FILES_UNSORTED))
#
# Files in ./etc/
#
ETC_DIR_FILES :=etc/config.fish.in
#
# Files in ./share/
#
SHARE_DIR_FILES :=share/config.fish.in
#
# Files in ./tests/
#
@@ -247,16 +241,14 @@ FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish)
# Programs to install
#
SIMPLE_PROGRAMS := fish set_color mimedb fish_pager fishd fish_indent
PROGRAMS := $(SIMPLE_PROGRAMS) @XSEL_BIN@ @SEQ_FALLBACK@
PROGRAMS := fish mimedb fish_pager fishd fish_indent
#
# Manual pages to install
#
MANUALS := $(addsuffix .1, $(addprefix share/man/, \
$(SIMPLE_PROGRAMS))) @XSEL_MAN_PATH@
MANUALS := $(addsuffix .1, $(addprefix share/man/man1/, \
$(PROGRAMS)))
#
@@ -267,18 +259,11 @@ TRANSLATIONS_SRC := $(wildcard po/*.po)
TRANSLATIONS := $(TRANSLATIONS_SRC:.po=.gmo)
#
# Extra util
#
XSEL := @XSEL@
XSEL_BIN := @XSEL_BIN@
#
# Make everything needed for installing fish
#
all: $(PROGRAMS) user_doc share/man etc/config.fish share/config.fish $(TRANSLATIONS)
all: $(PROGRAMS) user_doc share/man $(TRANSLATIONS)
@echo fish has now been built.
@echo Use \'$(MAKE) install\' to install fish.
.PHONY: all
@@ -301,12 +286,9 @@ Makefile: Makefile.in configure
# and should only be used when debuging fish.
#
debug:
$(MAKE) all EXTRA_CFLAGS="-O0 -Wno-unused -Werror -g"
.PHONY: debug
prof:
$(MAKE) all EXTRA_CFLAGS="-pg" LDFLAGS="-pg"
prof: EXTRA_CXXFLAGS += -pg
prof: LDFLAGS += -pg
prof: all
.PHONY: prof
#
@@ -315,19 +297,18 @@ prof:
# Depend on the sources (*.hdr.in) and manually make the
# intermediate *.hdr and doc.h files if needed
# Allow doxygen to fail, e.g. if it does not exist
user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC)
$(MAKE) doc.h $(HDR_FILES)
doxygen Doxyfile.user
touch user_doc
user_doc: $(HDR_FILES_SRC) Doxyfile.user user_doc.head.html $(HELP_SRC) doc.h $(HDR_FILES)
- (cat Doxyfile.user ; echo PROJECT_NUMBER=@PACKAGE_VERSION@) | doxygen - && touch user_doc
#
# Source code documentation. Also includes user documentation.
#
doc: *.h *.c doc.h Doxyfile
doxygen;
doc: *.h *.cpp doc.h Doxyfile
(cat Doxyfile ; echo PROJECT_NUMBER=@PACKAGE_VERSION@) | doxygen - ;
#
@@ -351,14 +332,6 @@ test: $(PROGRAMS) fish_tests
.PHONY: test
#
# Build the xsel program, which is maintained in its own tarball
#
$(XSEL_BIN):
$(MAKE) -C $(XSEL) || echo "Failed to build xsel - either add the required dependencies or use './configure --without-xsel' to disable it."
#
# commands.hdr collects documentation on all commands, functions and
# builtins
@@ -377,14 +350,14 @@ doc_src/commands.hdr:$(HELP_SRC) doc_src/commands.hdr.in
cat $@.in | awk '{if ($$0 ~ /@command_list@/){ system("cat command_list.txt");} else{ print $$0;}}' >$@
toc.txt: $(subst index.hdr,index.hdr.in,$(HDR_FILES))
toc.txt: $(HDR_FILES:index.hdr=index.hdr.in)
-rm toc.tmp $@
for i in $(subst index.hdr,index.hdr.in,$(HDR_FILES)); do\
for i in $(HDR_FILES:index.hdr=index.hdr.in); do\
NAME=`basename $$i .hdr`; \
NAME=`basename $$NAME .hdr.in`; \
sed <$$i >>toc.tmp -n \
-e 's,.*\\page *\([^ ]*\) *\(.*\)$$,- <a href="'$$NAME'.html" name="toc-'$$NAME'">\2</a>,p' \
-e 's,.*\\section *\([^ ]*\) *\(.*\)$$, - <a href="'$$NAME'.html#\1" name="toc-'$$NAME'">\2</a>,p'; \
-e 's,.*\\page *\([^ ]*\) *\(.*\)$$,- <a href="'$$NAME'.html" id="toc-'$$NAME'">\2</a>,p' \
-e 's,.*\\section *\([^ ]*\) *\(.*\)$$, - <a href="'$$NAME'.html#\1">\2</a>,p'; \
done
mv toc.tmp $@
@@ -453,10 +426,10 @@ doc.h: $(HDR_FILES)
# Create a template translation object
#
messages.pot: *.c *.h etc/*.in share/*.in share/completions/*.fish share/functions/*.fish seq
messages.pot: *.cpp *.h share/completions/*.fish share/functions/*.fish
if test $(HAVE_GETTEXT) = 1;then \
xgettext -k_ -kN_ *.c *.h -o messages.pot; \
if xgettext -j -k_ -kN_ -k--description -LShell etc/*.in share/*.in share/completions/*.fish share/functions/*.fish seq -o messages.pot; then true; else \
xgettext -k_ -kN_ *.cpp *.h -o messages.pot; \
if xgettext -j -k_ -kN_ -k--description -LShell share/completions/*.fish share/functions/*.fish -o messages.pot; then true; else \
echo "Your xgettext version is too old to build the messages.pot file"\
rm messages.pot\
false;\
@@ -496,23 +469,10 @@ common.o: $(COMMON_FILES)
#
share/man: $(HELP_SRC)
-rm doc_src/*.doxygen # Remove temp files from previous run
-rm -r help_doc
-mkdir share/man
touch share/man
for i in $(HELP_SRC); do \
FILE=doc_src/`basename $$i .txt`.doxygen; \
echo "/** \page" `basename $$i .txt` >$$FILE; \
cat $$i >>$$FILE; \
echo "*/" >>$$FILE; \
done
doxygen Doxyfile.help
for i in $(HELP_SRC); do \
CMD_NAME=`basename $$i .txt`; \
sed -e "s/\(.\)\\.SH/\1/" -e "s/$$CMD_NAME *\\\\- *\"\(.*\)\"/\1/" <help_doc/man/man1/$$CMD_NAME.1 >share/man/$$CMD_NAME.1; \
done
rm doc_src/*.doxygen # Clean up intermediate files in doc_src/
rm -r help_doc # Clean up intermediate help_doc tree
-rm -Rf share/man/man1
./build_tools/build_documentation.sh Doxyfile.help ./doc_src ./share
#
# The build rules for installing/uninstalling fish
@@ -549,6 +509,20 @@ check-uninstall:
fi;
.PHONY: check-uninstall
check-legacy-binaries:
@SEQLOC=$(prefix)/bin/seq;\
if test -f "$$SEQLOC" && grep -q '\(^#!/.*/fish\|^#!/usr/bin/env fish\)' "$$SEQLOC"; then\
echo "An outdated seq from a previous fish install was found. You should remove it with:";\
echo " rm '$$SEQLOC'";\
fi;
@SETCOLOR_LOC=$(prefix)/bin/set_color;\
if test -x "$$SETCOLOR_LOC" && $$SETCOLOR_LOC -v 2>&1 >/dev/null | grep -q "^set_color, version "; then\
echo "An outdated set_color from a previous fish install was found. You should remove it with:";\
echo " rm '$$SETCOLOR_LOC'";\
fi;
@true;
.PHONY: check-legacy-binaries
#
# This check makes sure that the install-sh script is executable. The
@@ -565,36 +539,69 @@ install-sh:
# Try to install after checking for incompatible installed versions.
#
install: all install-sh check-uninstall install-force
install: all install-sh check-uninstall install-force check-legacy-binaries
.PHONY: install
#
# Xcode install
#
xcode-install:
rm -Rf /tmp/fish_build;\
xcodebuild install DSTROOT=/tmp/fish_build;\
ditto /tmp/fish_build /
.PHONY: xcode-install
#
# Force installation, even in presense of incompatible previous
# version. This may fail.
# These 'true' lines are to prevent installs from failing for (e.g.) missing man pages.
#
install-force: all install-translations
$(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
for i in $(PROGRAMS); do\
$(INSTALL) -m 755 $$i $(DESTDIR)$(bindir) ; \
true ;\
done;
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)/fish
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/completions
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/functions
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/man
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/man/man1
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/tools
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/tools/web_config
$(INSTALL) -m 755 -d $(DESTDIR)$(datadir)/fish/tools/web_config/sample_prompts
$(INSTALL) -m 644 etc/config.fish $(DESTDIR)$(sysconfdir)/fish/
$(INSTALL) -m 644 share/config.fish $(DESTDIR)$(datadir)/fish/
for i in $(COMPLETIONS_DIR_FILES); do \
for i in $(COMPLETIONS_DIR_FILES:%='%'); do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/completions/; \
true; \
done;
for i in $(FUNCTIONS_DIR_FILES); do \
for i in $(FUNCTIONS_DIR_FILES:%='%'); do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/functions/; \
true; \
done;
for i in share/man/*.1; do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/man/; \
for i in share/man/man1/*.1; do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/man/man1/; \
true; \
done;
for i in share/tools/*.py; do\
$(INSTALL) -m 755 $$i $(DESTDIR)$(datadir)/fish/tools/; \
true; \
done;
for i in share/tools/web_config/*; do\
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/tools/web_config/; \
true; \
done;
for i in share/tools/web_config/sample_prompts/*.fish; do\
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/tools/web_config/sample_prompts/; \
true; \
done;
for i in share/tools/web_config/*.py; do\
$(INSTALL) -m 755 $$i $(DESTDIR)$(datadir)/fish/tools/web_config/; \
true; \
done;
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
for i in user_doc/html/* ChangeLog; do \
if test -f $$i; then \
@@ -604,14 +611,19 @@ install-force: all install-translations
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
for i in $(MANUALS); do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(mandir)/man1/; \
true; \
done;
@echo fish is now installed on your system.
@echo To run fish, type \'fish\' in your terminal.
@echo
@echo To use fish as your login shell:
@echo \* add the line \'$(DESTDIR)$(bindir)/fish\' to the file \'/etc/shells\'.
@grep -q -- "$(DESTDIR)$(bindir)/fish" /etc/shells || echo \* add the line \'$(DESTDIR)$(bindir)/fish\' to the file \'/etc/shells\'.
@echo \* use the command \'chsh -s $(DESTDIR)$(bindir)/fish\'.
@echo
@echo To set your colors, run \'fish_config\'
@echo To scan your man pages for completions, run \'fish_update_completions\'
@echo To autocomplete command suggestions press Ctrl + F or right arrow key.
@echo
@echo Have fun!
.PHONY: install-force
@@ -624,17 +636,15 @@ uninstall: uninstall-translations
-for i in $(PROGRAMS); do \
rm -f $(DESTDIR)$(bindir)/$$i; \
done;
-rm -f $(DESTDIR)$(bindir)/xsel
-rm -f $(DESTDIR)$(sysconfdir)/fish/config.fish
-rmdir $(DESTDIR)$(sysconfdir)/fish
-rm -rf $(DESTDIR)$(sysconfdir)/fish
-if test -d $(DESTDIR)$(datadir)/fish; then \
rm -r $(DESTDIR)$(datadir)/fish; \
fi
-if test -d $(DESTDIR)$(docdir); then \
rm -r $(DESTDIR)$(docdir);\
rm -rf $(DESTDIR)$(docdir);\
fi
-for i in $(MANUALS); do \
rm -f $(DESTDIR)$(mandir)/man1/`basename $$i`*; \
rm -rf $(DESTDIR)$(mandir)/man1/`basename $$i`*; \
done;
.PHONY: uninstall
@@ -693,7 +703,7 @@ uninstall-translations:
#
fish: $(FISH_OBJS) fish.o
$(CC) $(FISH_OBJS) fish.o $(LDFLAGS_FISH) -o $@
$(CXX) $(FISH_OBJS) fish.o $(LDFLAGS_FISH) -o $@
#
@@ -701,7 +711,7 @@ fish: $(FISH_OBJS) fish.o
#
fish_pager: $(FISH_PAGER_OBJS)
$(CC) $(FISH_PAGER_OBJS) $(LDFLAGS_FISH_PAGER) -o $@
$(CXX) $(FISH_PAGER_OBJS) $(LDFLAGS_FISH_PAGER) -o $@
#
@@ -709,7 +719,7 @@ fish_pager: $(FISH_PAGER_OBJS)
#
fishd: $(FISHD_OBJS)
$(CC) $(FISHD_OBJS) $(LDFLAGS_FISHD) -o $@
$(CXX) $(FISHD_OBJS) $(LDFLAGS_FISHD) -o $@
#
@@ -717,7 +727,7 @@ fishd: $(FISHD_OBJS)
#
fish_tests: $(FISH_TESTS_OBJS)
$(CC) $(FISH_TESTS_OBJS) $(LDFLAGS_FISH) -o $@
$(CXX) $(FISH_TESTS_OBJS) $(LDFLAGS_FISH) -o $@
#
@@ -727,23 +737,7 @@ fish_tests: $(FISH_TESTS_OBJS)
#
mimedb: $(MIME_OBJS)
$(CC) $(MIME_OBJS) $(LDFLAGS_MIMEDB) -o $@
#
# Build the set_color program
#
set_color: set_color.o print_help.o common.o
$(CC) set_color.o print_help.o common.o wutil.o $(LDFLAGS_SET_COLOR) -o $@
#
# Test program for the tokenizer library
#
tokenizer_test: tokenizer.c tokenizer.h wutil.o common.o
$(CC) $(CFLAGS) tokenizer.c wutil.o common.o -D TOKENIZER_TEST $(LDFLAGS) -o $@
$(CXX) $(MIME_OBJS) $(LDFLAGS_MIMEDB) -o $@
#
@@ -751,68 +745,25 @@ tokenizer_test: tokenizer.c tokenizer.h wutil.o common.o
#
fish_indent: $(FISH_INDENT_OBJS)
$(CC) $(FISH_INDENT_OBJS) $(LDFLAGS_FISH_INDENT) -o $@
$(CXX) $(FISH_INDENT_OBJS) $(LDFLAGS_FISH_INDENT) -o $@
#
# Neat little program to show output from terminal
#
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_FISH) -o $@
key_reader: key_reader.o input_common.o common.o env_universal.o env_universal_common.o wutil.o iothread.o
$(CXX) key_reader.o input_common.o common.o env_universal.o env_universal_common.o wutil.o iothread.o $(LDFLAGS_FISH) -o $@
#
# Update dependencies
#
depend:
makedepend -fMakefile.in -Y *.c
makedepend -fMakefile.in -Y *.cpp
./config.status
.PHONY: depend
#
# Copy all the source files into a new directory and use tar to create
# an archive from it. Simplest way I could think of to make an archive
# witout backups, autogenerated files, etc.
#
# Uses install instead of mkdir so build won't fail if the directory
# exists
#
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(ETC_DIR_FILES) $(TEST_DIR_FILES) $(SHARE_DIR_FILES) $(FUNCTIONS_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog user_doc share/man
rm -rf fish-@PACKAGE_VERSION@
$(INSTALL) -d fish-@PACKAGE_VERSION@
$(INSTALL) -d fish-@PACKAGE_VERSION@/doc_src
$(INSTALL) -d fish-@PACKAGE_VERSION@/user_doc
$(INSTALL) -d fish-@PACKAGE_VERSION@/etc
$(INSTALL) -d fish-@PACKAGE_VERSION@/share
$(INSTALL) -d fish-@PACKAGE_VERSION@/share/completions
$(INSTALL) -d fish-@PACKAGE_VERSION@/share/functions
$(INSTALL) -d fish-@PACKAGE_VERSION@/share/man
$(INSTALL) -d fish-@PACKAGE_VERSION@/tests
$(INSTALL) -d fish-@PACKAGE_VERSION@/po
cp -f $(DOC_SRC_DIR_FILES) fish-@PACKAGE_VERSION@/doc_src
cp -f $(MAIN_DIR_FILES) fish-@PACKAGE_VERSION@/
cp -f $(ETC_DIR_FILES) fish-@PACKAGE_VERSION@/etc/
cp -f $(SHARE_DIR_FILES) fish-@PACKAGE_VERSION@/share/
cp -f $(COMPLETIONS_DIR_FILES) fish-@PACKAGE_VERSION@/share/completions/
cp -f $(FUNCTIONS_DIR_FILES) fish-@PACKAGE_VERSION@/share/functions/
cp -f $(TESTS_DIR_FILES) fish-@PACKAGE_VERSION@/tests/
cp -f $(TRANSLATIONS_SRC) fish-@PACKAGE_VERSION@/po/
cp -f share/man/*.1 fish-@PACKAGE_VERSION@/share/man/
cp -rf user_doc fish-@PACKAGE_VERSION@/
tar -c fish-@PACKAGE_VERSION@ >fish-@PACKAGE_VERSION@.tar
rm -rf fish-@PACKAGE_VERSION@
#
# Just an alias for fish-@PACKAGE_VERSION@.tar
#
tar: fish-@PACKAGE_VERSION@.tar
.PHONY: tar
#
# Make compressed tar archives
#
@@ -864,10 +815,8 @@ rpm: fish-@PACKAGE_VERSION@.tar.bz2 fish.spec
#
distclean: clean
rm -f fish.spec Doxyfile.help
rm -f etc/config.fish seq share/config.fish
rm -f fish.spec
rm -f config.status config.log config.h Makefile
rm -rf $(XSEL)
.PHONY: distclean
@@ -876,139 +825,157 @@ distclean: clean
# are created by the configure script.
#
# Don't delete the docs unless we have Doxygen installed
# We provide pre-built docs in the tarball, and if they get
# deleted we won't be able to regenerate them
clean:
rm -f *.o doc.h doc.tmp doc_src/*.doxygen doc_src/*.c doc_src/*.o doc_src/commands.hdr
rm -f *.o doc.h doc.tmp doc_src/*.doxygen doc_src/*.cpp doc_src/*.o doc_src/commands.hdr
rm -f $(GENERATED_INTERN_SCRIPT_FILES)
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
rm -f $(PROGRAMS) fish_tests tokenizer_test key_reader
rm -f share/config.fish etc/config.fish doc_src/index.hdr doc_src/commands.hdr
rm -f $(PROGRAMS) fish_tests key_reader
rm -f command_list.txt toc.txt
rm -f doc_src/index.hdr doc_src/commands.hdr
rm -f fish-@PACKAGE_VERSION@.tar
rm -f fish-@PACKAGE_VERSION@.tar.gz
rm -f fish-@PACKAGE_VERSION@.tar.bz2
rm -rf doc;
if command -v doxygen; then \
rm -rf doc user_doc share/man; \
fi
rm -rf fish-@PACKAGE_VERSION@
rm -f $(TRANSLATIONS)
test ! -d "$(XSEL)" || make -C $(XSEL) clean
.PHONY: clean
# DO NOT DELETE THIS LINE -- make depend depends on it.
builtin.o: config.h fallback.h util.h wutil.h builtin.h io.h function.h
builtin.o: complete.h proc.h parser.h event.h reader.h env.h common.h
builtin.o: wgetopt.h sanity.h tokenizer.h wildcard.h input_common.h input.h
builtin.o: intern.h signal.h exec.h highlight.h halloc.h halloc_util.h
builtin.o: parse_util.h parser_keywords.h expand.h path.h builtin_set.c
builtin.o: builtin_commandline.c builtin_complete.c builtin_ulimit.c
builtin.o: builtin_jobs.c
builtin_commandline.o: config.h signal.h fallback.h util.h wutil.h builtin.h
builtin_commandline.o: io.h common.h wgetopt.h reader.h proc.h parser.h
builtin_commandline.o: event.h tokenizer.h input_common.h input.h
builtin_commandline.o: parse_util.h
builtin_complete.o: config.h signal.h fallback.h util.h wutil.h builtin.h
builtin_complete.o: io.h common.h complete.h wgetopt.h parser.h proc.h
builtin_complete.o: event.h reader.h
builtin_jobs.o: config.h fallback.h util.h wutil.h builtin.h io.h proc.h
builtin_jobs.o: parser.h event.h common.h wgetopt.h
builtin_set.o: config.h signal.h fallback.h util.h wutil.h builtin.h io.h
builtin_set.o: env.h expand.h common.h wgetopt.h proc.h parser.h event.h
builtin_ulimit.o: config.h fallback.h util.h builtin.h io.h common.h
autoload.o: config.h autoload.h common.h util.h lru.h wutil.h signal.h env.h
autoload.o: exec.h proc.h io.h
builtin.o: config.h signal.h fallback.h util.h wutil.h common.h builtin.h
builtin.o: io.h function.h event.h complete.h proc.h parser.h reader.h env.h
builtin.o: wgetopt.h sanity.h tokenizer.h wildcard.h expand.h input_common.h
builtin.o: input.h intern.h exec.h highlight.h screen.h color.h parse_util.h
builtin.o: autoload.h lru.h parser_keywords.h path.h history.h
builtin.o: builtin_set.cpp builtin_commandline.cpp builtin_complete.cpp
builtin.o: builtin_ulimit.cpp builtin_jobs.cpp builtin_printf.cpp
builtin_commandline.o: config.h signal.h fallback.h util.h wutil.h common.h
builtin_commandline.o: builtin.h io.h wgetopt.h reader.h complete.h proc.h
builtin_commandline.o: parser.h event.h function.h tokenizer.h input_common.h
builtin_commandline.o: input.h parse_util.h autoload.h lru.h
builtin_complete.o: config.h signal.h fallback.h util.h wutil.h common.h
builtin_complete.o: builtin.h io.h complete.h wgetopt.h parser.h proc.h
builtin_complete.o: event.h function.h reader.h
builtin_jobs.o: config.h fallback.h signal.h util.h wutil.h common.h
builtin_jobs.o: builtin.h io.h proc.h parser.h event.h function.h wgetopt.h
builtin_set.o: config.h signal.h fallback.h util.h wutil.h common.h builtin.h
builtin_set.o: io.h env.h expand.h wgetopt.h proc.h parser.h event.h
builtin_set.o: function.h
builtin_test.o: config.h common.h util.h builtin.h io.h wutil.h proc.h
builtin_test.o: signal.h
builtin_ulimit.o: config.h fallback.h signal.h util.h builtin.h io.h common.h
builtin_ulimit.o: wgetopt.h
common.o: config.h fallback.h util.h wutil.h common.h expand.h proc.h io.h
common.o: wildcard.h parser.h event.h util.c halloc.c halloc.h halloc_util.c
common.o: fallback.c
complete.o: config.h signal.h fallback.h util.h tokenizer.h wildcard.h proc.h
complete.o: io.h parser.h event.h function.h complete.h builtin.h env.h
complete.o: exec.h expand.h common.h reader.h history.h intern.h parse_util.h
complete.o: parser_keywords.h halloc.h halloc_util.h wutil.h path.h
env.o: config.h signal.h fallback.h util.h wutil.h proc.h io.h common.h env.h
env.o: sanity.h expand.h history.h reader.h parser.h event.h env_universal.h
env.o: env_universal_common.h input_common.h path.h halloc.h halloc_util.h
env.o: complete.h
builtin_printf.o: wgetopt.h
color.o: color.h config.h common.h util.h fallback.h signal.h
common.o: config.h fallback.h signal.h util.h wutil.h common.h expand.h
common.o: proc.h io.h wildcard.h parser.h event.h function.h complete.h
common.o: util.cpp fallback.cpp
complete.o: config.h signal.h fallback.h util.h tokenizer.h common.h
complete.o: wildcard.h expand.h proc.h io.h parser.h event.h function.h
complete.o: complete.h builtin.h env.h exec.h reader.h history.h wutil.h
complete.o: intern.h parse_util.h autoload.h lru.h parser_keywords.h path.h
env.o: config.h signal.h fallback.h util.h wutil.h common.h proc.h io.h env.h
env.o: sanity.h expand.h history.h reader.h complete.h parser.h event.h
env.o: function.h env_universal.h env_universal_common.h input.h
env.o: input_common.h path.h
env_universal.o: config.h signal.h fallback.h util.h common.h wutil.h
env_universal.o: env_universal_common.h env_universal.h
env_universal_common.o: config.h signal.h fallback.h util.h common.h wutil.h
env_universal_common.o: env_universal_common.h
event.o: config.h signal.h fallback.h util.h wutil.h function.h proc.h io.h
event.o: parser.h event.h common.h halloc_util.h
exec.o: config.h signal.h fallback.h util.h common.h wutil.h proc.h io.h
exec.o: exec.h parser.h event.h builtin.h function.h env.h wildcard.h
exec.o: sanity.h expand.h halloc.h halloc_util.h parse_util.h
event.o: config.h signal.h fallback.h util.h wutil.h common.h function.h
event.o: event.h proc.h io.h parser.h
exec.o: config.h signal.h fallback.h util.h iothread.h postfork.h common.h
exec.o: proc.h io.h wutil.h exec.h parser.h event.h function.h builtin.h
exec.o: env.h wildcard.h expand.h sanity.h parse_util.h autoload.h lru.h
expand.o: config.h signal.h fallback.h util.h common.h wutil.h env.h proc.h
expand.o: io.h parser.h event.h expand.h wildcard.h exec.h tokenizer.h
expand.o: complete.h parse_util.h halloc.h halloc_util.h
fallback.o: config.h fallback.h util.h
fish.o: config.h signal.h fallback.h util.h common.h reader.h io.h builtin.h
fish.o: function.h complete.h wutil.h env.h sanity.h proc.h parser.h event.h
fish.o: expand.h intern.h exec.h output.h halloc.h halloc_util.h history.h
fish.o: path.h
fish_indent.o: config.h fallback.h util.h common.h wutil.h halloc.h
fish_indent.o: halloc_util.h tokenizer.h print_help.h parser_keywords.h
expand.o: io.h parser.h event.h function.h expand.h wildcard.h exec.h
expand.o: tokenizer.h complete.h parse_util.h autoload.h lru.h
fallback.o: config.h fallback.h signal.h util.h
fish.o: config.h signal.h fallback.h util.h common.h reader.h io.h complete.h
fish.o: builtin.h function.h event.h wutil.h env.h sanity.h proc.h parser.h
fish.o: expand.h intern.h exec.h output.h screen.h color.h history.h path.h
fish_indent.o: config.h fallback.h signal.h util.h common.h wutil.h
fish_indent.o: tokenizer.h print_help.h parser_keywords.h
fish_pager.o: config.h signal.h fallback.h util.h wutil.h common.h complete.h
fish_pager.o: output.h input_common.h env_universal.h env_universal_common.h
fish_pager.o: halloc.h halloc_util.h print_help.h
fish_pager.o: output.h screen.h color.h input_common.h env_universal.h
fish_pager.o: env_universal_common.h print_help.h
fish_tests.o: config.h signal.h fallback.h util.h common.h proc.h io.h
fish_tests.o: reader.h builtin.h function.h complete.h wutil.h env.h expand.h
fish_tests.o: parser.h event.h tokenizer.h output.h exec.h path.h halloc.h
fish_tests.o: halloc_util.h
fish_tests.o: reader.h complete.h builtin.h function.h event.h autoload.h
fish_tests.o: lru.h wutil.h env.h expand.h parser.h tokenizer.h output.h
fish_tests.o: screen.h color.h exec.h path.h history.h highlight.h iothread.h
fish_tests.o: postfork.h
fishd.o: config.h signal.h fallback.h util.h common.h wutil.h
fishd.o: env_universal_common.h halloc.h halloc_util.h path.h print_help.h
function.o: config.h signal.h wutil.h fallback.h util.h function.h proc.h
function.o: io.h parser.h event.h common.h intern.h reader.h parse_util.h
function.o: parser_keywords.h env.h expand.h halloc.h halloc_util.h
halloc.o: config.h fallback.h util.h common.h halloc.h
halloc_util.o: config.h fallback.h util.h common.h halloc.h
highlight.o: config.h signal.h fallback.h util.h wutil.h highlight.h
highlight.o: tokenizer.h proc.h io.h parser.h event.h parse_util.h
highlight.o: parser_keywords.h builtin.h function.h env.h expand.h sanity.h
highlight.o: common.h complete.h output.h halloc.h halloc_util.h wildcard.h
highlight.o: path.h
history.o: config.h fallback.h util.h wutil.h history.h common.h halloc.h
history.o: halloc_util.h intern.h path.h signal.h
input.o: config.h signal.h fallback.h util.h wutil.h reader.h io.h proc.h
input.o: common.h sanity.h input_common.h input.h parser.h event.h env.h
input.o: expand.h output.h intern.h halloc.h halloc_util.h
input_common.o: config.h fallback.h util.h common.h wutil.h input_common.h
input_common.o: env_universal.h env_universal_common.h
intern.o: config.h fallback.h util.h wutil.h common.h intern.h
io.o: config.h fallback.h util.h wutil.h exec.h proc.h io.h common.h halloc.h
key_reader.o: config.h fallback.h input_common.h
kill.o: config.h signal.h fallback.h util.h wutil.h kill.h proc.h io.h
kill.o: sanity.h common.h env.h exec.h halloc.h path.h
mimedb.o: config.h xdgmime.h fallback.h util.h print_help.h
output.o: config.h signal.h fallback.h util.h wutil.h expand.h common.h
output.o: output.h halloc_util.h highlight.h
parse_util.o: config.h fallback.h util.h wutil.h common.h tokenizer.h
parse_util.o: parse_util.h expand.h intern.h exec.h proc.h io.h env.h
parse_util.o: signal.h wildcard.h halloc_util.h
fishd.o: env_universal_common.h path.h env.h print_help.h
function.o: config.h signal.h wutil.h common.h util.h fallback.h function.h
function.o: event.h proc.h io.h parser.h intern.h reader.h complete.h
function.o: parse_util.h autoload.h lru.h parser_keywords.h env.h expand.h
highlight.o: config.h signal.h fallback.h util.h wutil.h common.h highlight.h
highlight.o: env.h screen.h color.h tokenizer.h proc.h io.h parser.h event.h
highlight.o: function.h parse_util.h autoload.h lru.h parser_keywords.h
highlight.o: builtin.h expand.h sanity.h complete.h output.h wildcard.h
highlight.o: path.h history.h
history.o: config.h fallback.h signal.h util.h sanity.h tokenizer.h common.h
history.o: wutil.h history.h intern.h path.h env.h autoload.h lru.h
history.o: iothread.h
input.o: config.h signal.h fallback.h util.h wutil.h common.h reader.h io.h
input.o: complete.h proc.h sanity.h input_common.h input.h parser.h event.h
input.o: function.h env.h expand.h output.h screen.h color.h intern.h
input_common.o: config.h fallback.h signal.h util.h common.h wutil.h
input_common.o: input_common.h env_universal.h env_universal_common.h
input_common.o: iothread.h
intern.o: config.h fallback.h signal.h util.h wutil.h common.h intern.h
io.o: config.h fallback.h signal.h util.h wutil.h common.h exec.h proc.h io.h
iothread.o: config.h iothread.h common.h util.h signal.h
key_reader.o: config.h common.h util.h fallback.h signal.h input_common.h
kill.o: config.h signal.h fallback.h util.h wutil.h common.h kill.h proc.h
kill.o: io.h sanity.h env.h exec.h path.h
mimedb.o: config.h xdgmime.h fallback.h signal.h util.h print_help.h
output.o: config.h signal.h fallback.h util.h wutil.h common.h expand.h
output.o: output.h screen.h color.h highlight.h env.h
parse_util.o: config.h fallback.h signal.h util.h wutil.h common.h
parse_util.o: tokenizer.h parse_util.h autoload.h lru.h expand.h intern.h
parse_util.o: exec.h proc.h io.h env.h wildcard.h
parser.o: config.h signal.h fallback.h util.h common.h wutil.h proc.h io.h
parser.o: parser.h event.h parser_keywords.h tokenizer.h exec.h wildcard.h
parser.o: function.h builtin.h env.h expand.h reader.h sanity.h
parser.o: parser.h event.h function.h parser_keywords.h tokenizer.h exec.h
parser.o: wildcard.h expand.h builtin.h env.h reader.h complete.h sanity.h
parser.o: env_universal.h env_universal_common.h intern.h parse_util.h
parser.o: halloc.h halloc_util.h path.h
parser_keywords.o: config.h fallback.h common.h util.h parser_keywords.h
path.o: config.h fallback.h util.h common.h env.h wutil.h halloc.h
path.o: halloc_util.h path.h expand.h
parser.o: autoload.h lru.h path.h
parser_keywords.o: config.h fallback.h signal.h common.h util.h
parser_keywords.o: parser_keywords.h
path.o: config.h fallback.h signal.h util.h common.h env.h wutil.h path.h
path.o: expand.h
postfork.o: signal.h postfork.h config.h common.h util.h proc.h io.h wutil.h
postfork.o: iothread.h exec.h
print_help.o: print_help.h
proc.o: config.h signal.h fallback.h util.h wutil.h proc.h io.h common.h
proc.o: reader.h sanity.h env.h parser.h event.h halloc.h halloc_util.h
proc.o: output.h
reader.o: config.h signal.h fallback.h util.h wutil.h highlight.h reader.h
reader.o: io.h proc.h parser.h event.h complete.h history.h common.h sanity.h
reader.o: env.h exec.h expand.h tokenizer.h kill.h input_common.h input.h
reader.o: function.h output.h screen.h halloc.h halloc_util.h parse_util.h
proc.o: config.h signal.h fallback.h util.h wutil.h common.h proc.h io.h
proc.o: reader.h complete.h sanity.h env.h parser.h event.h function.h
proc.o: output.h screen.h color.h
reader.o: config.h signal.h fallback.h util.h wutil.h common.h highlight.h
reader.o: env.h screen.h color.h reader.h io.h complete.h proc.h parser.h
reader.o: event.h function.h history.h sanity.h exec.h expand.h tokenizer.h
reader.o: kill.h input_common.h input.h output.h iothread.h intern.h path.h
reader.o: parse_util.h autoload.h lru.h
sanity.o: config.h signal.h fallback.h util.h common.h sanity.h proc.h io.h
sanity.o: history.h reader.h kill.h wutil.h
screen.o: config.h fallback.h common.h util.h wutil.h output.h highlight.h
screen.o: screen.h env.h
set_color.o: config.h fallback.h print_help.h
sanity.o: history.h wutil.h reader.h complete.h kill.h
screen.o: config.h fallback.h signal.h common.h util.h wutil.h output.h
screen.o: screen.h color.h highlight.h env.h
signal.o: config.h signal.h common.h util.h fallback.h wutil.h event.h
signal.o: reader.h io.h proc.h
tokenizer.o: config.h fallback.h util.h wutil.h tokenizer.h common.h
util.o: config.h fallback.h util.h common.h wutil.h
wgetopt.o: config.h wgetopt.h wutil.h fallback.h
wildcard.o: config.h fallback.h util.h wutil.h complete.h common.h wildcard.h
wildcard.o: reader.h io.h expand.h exec.h proc.h halloc_util.h
wutil.o: config.h fallback.h util.h common.h wutil.h halloc.h halloc_util.h
signal.o: reader.h io.h complete.h proc.h
tokenizer.o: config.h fallback.h signal.h util.h wutil.h common.h tokenizer.h
util.o: config.h fallback.h signal.h util.h common.h wutil.h
wgetopt.o: config.h wgetopt.h wutil.h common.h util.h fallback.h signal.h
wildcard.o: config.h fallback.h signal.h util.h wutil.h common.h complete.h
wildcard.o: wildcard.h expand.h reader.h io.h exec.h proc.h
wutil.o: config.h fallback.h signal.h util.h common.h wutil.h
xdgmime.o: xdgmime.h xdgmimeint.h xdgmimeglob.h xdgmimemagic.h xdgmimealias.h
xdgmime.o: xdgmimeparent.h
xdgmimealias.o: xdgmimealias.h xdgmime.h xdgmimeint.h

15
README
View File

@@ -1,15 +0,0 @@
How to find documentation for fish
==================================
The fish documentation is distributed in an intermediate format. To
view it, you have to type:
% make user_doc
Which will create the directory user_doc, containing html
documentation for fish. If you build and install fish, the
documentation will be available through the 'help' builtin.
After installation, you can start fish by typing fish in the
terminal. After fish has started, try using the help command for more
information.

71
README.md Normal file
View File

@@ -0,0 +1,71 @@
[fish](http://ridiculousfish.com/shell/) - the friendly interactive shell
================================================
fish is a smart and user-friendly command line shell for OS X, Linux, and the rest of the family. fish includes features like syntax highlighting, autosuggest-as-you-type, and fancy tab completions that just work, with no configuration required.
For more on fish's design philosophy, see the [design document](http://ridiculousfish.com/shell/user_doc/html/design.html).
## Quick Start
fish generally works like other shells, like bash or zsh. A few important differences are documented at <http://ridiculousfish.com/shell/faq.html>
Detailed user documentation is available by running `help` within fish, and also at <http://ridiculousfish.com/shell/user_doc/html/>
## Building
fish is written in a sane subset of C++98, with a few components from C++TR1. It builds successfully with g++ 4.2 or later, and with clang. It also will build as C++11.
fish can be built using autotools or Xcode.
### Autotools Build
autoconf
./configure
make [gmake on BSD]
sudo make install
### Xcode Development Build
* Build the `base` target in Xcode
* Run the fish executable, for example, in `DerivedData/fish/Build/Products/Debug/base/bin/fish`
### Xcode Build and Install
xcodebuild install
sudo ditto /tmp/fish.dst /
## Help, it didn't build!
If fish reports that it could not find curses, try installing a curses development package and build again.
On Debian or Ubuntu you want:
sudo apt-get install libncurses5-dev libncursesw5-dev
on RedHat, CentOS, or Amazon EC2:
sudo yum install ncurses-devel
## Packages for Linux
Nightly builds for several Linux distros can be downloaded from <http://download.opensuse.org/repositories/home:/siteshwar/>
## Switching to fish
If you wish to use fish as your default shell, use the following command:
chsh -s /usr/local/bin/fish
chsh will prompt you for your password, and change your default shell.
To switch your default shell back, you can run:
chsh -s /bin/bash
Substitute /bin/bash with /bin/tcsh or /bin/zsh as appropriate.
## Contact Us
Questions, comments, rants and raves can be posted to the official fish mailing list at <https://lists.sourceforge.net/lists/listinfo/fish-users> or join us on our IRC channel #fish at irc.oftc.net
Found a bug? Have an awesome idea? Please open an issue on this github page.

105
STYLEGUIDE.md Normal file
View File

@@ -0,0 +1,105 @@
# Style guide
This is style guide for fish contributors. You should use it for any new code
that you would add to this project and try to format existing code to use this
style.
## Formatting
1. fish uses the Allman/BSD style of indentation.
2. Indent with spaces, not tabs.
3. Use 4 spaces per indent (unless needed like `Makefile`).
4. Opening curly bracket is on the following line:
// ✔:
struct name
{
// code
};
void func()
{
// code
}
if (...)
{
// code
}
// ✗:
void func() {
// code
}
5. Put space after `if`, `while` and `for` before conditions.
// ✔:
if () {}
// ✗:
if() {}
6. Put spaces before and after operators excluding increment and decrement;
// ✔:
int a = 1 + 2 * 3;
a++;
// ✗:
int a=1+2*3;
a ++;
7. Never put spaces between function name and parameters list.
// ✔:
func(args);
// ✗:
func (args);
8. Never put spaces after `(` and before `)`.
9. Always put space after comma and semicolon.
// ✔:
func(arg1, arg2);
for (int i = 0; i < LENGTH; i++) {}
// ✗:
func(arg1,arg2);
for (int i = 0;i<LENGTH;i++) {}
## Documentation
Document your code using [Doxygen][dox].
1. Documentation comment should use double star notation or tripple slash:
// ✔:
/// Some var
int var;
/**
* Some func
*/
void func();
2. Use slash as tag mark:
// ✔:
/**
* \param a an integer argument.
* \param s a constant character pointer.
* \return The results
*/
int foo(int a, const char *s);
## Naming
All names in code should be `small_snake_case`. No Hungarian notation is used.
Classes and structs names should be followed by `_t`.
[dox]: http://www.stack.nl/~dimitri/doxygen/ "Doxygen homepage"

376
autoload.cpp Normal file
View File

@@ -0,0 +1,376 @@
/** \file autoload.cpp
The classes responsible for autoloading functions and completions.
*/
#include "config.h"
#include "autoload.h"
#include "wutil.h"
#include "common.h"
#include "signal.h"
#include "env.h"
#include "exec.h"
#include <assert.h>
#include <algorithm>
/* The time before we'll recheck an autoloaded file */
static const int kAutoloadStalenessInterval = 15;
file_access_attempt_t access_file(const wcstring &path, int mode)
{
//printf("Touch %ls\n", path.c_str());
file_access_attempt_t result = {0};
struct stat statbuf;
if (wstat(path, &statbuf))
{
result.error = errno;
}
else
{
result.mod_time = statbuf.st_mtime;
if (waccess(path, mode))
{
result.error = errno;
}
else
{
result.accessible = true;
}
}
// Note that we record the last checked time after the call, on the assumption that in a slow filesystem, the lag comes before the kernel check, not after.
result.stale = false;
result.last_checked = time(NULL);
return result;
}
autoload_t::autoload_t(const wcstring &env_var_name_var, const builtin_script_t * const scripts, size_t script_count) :
lock(),
env_var_name(env_var_name_var),
builtin_scripts(scripts),
builtin_script_count(script_count),
last_path(),
is_loading_set()
{
pthread_mutex_init(&lock, NULL);
}
autoload_t::~autoload_t()
{
pthread_mutex_destroy(&lock);
}
void autoload_t::node_was_evicted(autoload_function_t *node)
{
// This should only ever happen on the main thread
ASSERT_IS_MAIN_THREAD();
// Tell ourselves that the command was removed if it was loaded
if (! node->is_loaded)
this->command_removed(node->key);
delete node;
}
int autoload_t::unload(const wcstring &cmd)
{
return this->evict_node(cmd);
}
int autoload_t::load(const wcstring &cmd, bool reload)
{
int res;
CHECK_BLOCK(0);
ASSERT_IS_MAIN_THREAD();
env_var_t path_var = env_get_string(env_var_name);
/*
Do we know where to look?
*/
if (path_var.empty())
return 0;
/* Check if the lookup path has changed. If so, drop all loaded files. path_var may only be inspected on the main thread. */
if (path_var != this->last_path)
{
this->last_path = path_var;
scoped_lock locker(lock);
this->evict_all_nodes();
}
/** Warn and fail on infinite recursion. It's OK to do this because this function is only called on the main thread. */
if (this->is_loading(cmd))
{
debug(0,
_(L"Could not autoload item '%ls', it is already being autoloaded. "
L"This is a circular dependency in the autoloading scripts, please remove it."),
cmd.c_str());
return 1;
}
/* Mark that we're loading this */
is_loading_set.insert(cmd);
/* Get the list of paths from which we will try to load */
std::vector<wcstring> path_list;
tokenize_variable_array(path_var, path_list);
/* Try loading it */
res = this->locate_file_and_maybe_load_it(cmd, true, reload, path_list);
/* Clean up */
bool erased = !! is_loading_set.erase(cmd);
assert(erased);
return res;
}
bool autoload_t::can_load(const wcstring &cmd, const env_vars_snapshot_t &vars)
{
const env_var_t path_var = vars.get(env_var_name);
if (path_var.missing_or_empty())
return false;
std::vector<wcstring> path_list;
tokenize_variable_array(path_var, path_list);
return this->locate_file_and_maybe_load_it(cmd, false, false, path_list);
}
static bool script_name_precedes_script_name(const builtin_script_t &script1, const builtin_script_t &script2)
{
return wcscmp(script1.name, script2.name) < 0;
}
void autoload_t::unload_all(void)
{
scoped_lock locker(lock);
this->evict_all_nodes();
}
/** Check whether the given command is loaded. */
bool autoload_t::has_tried_loading(const wcstring &cmd)
{
scoped_lock locker(lock);
autoload_function_t * func = this->get_node(cmd);
return func != NULL;
}
static bool is_stale(const autoload_function_t *func)
{
/** Return whether this function is stale. Internalized functions can never be stale. */
return ! func->is_internalized && time(NULL) - func->access.last_checked > kAutoloadStalenessInterval;
}
autoload_function_t *autoload_t::get_autoloaded_function_with_creation(const wcstring &cmd, bool allow_eviction)
{
ASSERT_IS_LOCKED(lock);
autoload_function_t *func = this->get_node(cmd);
if (! func)
{
func = new autoload_function_t(cmd);
if (allow_eviction)
{
this->add_node(func);
}
else
{
this->add_node_without_eviction(func);
}
}
return func;
}
/**
This internal helper function does all the real work. By using two
functions, the internal function can return on various places in
the code, and the caller can take care of various cleanup work.
cmd: the command name ('grep')
really_load: whether to actually parse it as a function, or just check it it exists
reload: whether to reload it if it's already loaded
path_list: the set of paths to check
Result: if really_load is true, returns whether the function was loaded. Otherwise returns whether the function existed.
*/
bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_load, bool reload, const wcstring_list_t &path_list)
{
/* Note that we are NOT locked in this function! */
size_t i;
bool reloaded = 0;
/* Try using a cached function. If we really want the function to be loaded, require that it be really loaded. If we're not reloading, allow stale functions. */
{
bool allow_stale_functions = ! reload;
/* Take a lock */
scoped_lock locker(lock);
/* Get the function */
autoload_function_t * func = this->get_node(cmd);
/* Determine if we can use this cached function */
bool use_cached;
if (! func)
{
/* Can't use a function that doesn't exist */
use_cached = false;
}
else if (really_load && ! func->is_placeholder && ! func->is_loaded)
{
/* Can't use an unloaded function */
use_cached = false;
}
else if (! allow_stale_functions && is_stale(func))
{
/* Can't use a stale function */
use_cached = false;
}
else
{
/* I guess we can use it */
use_cached = true;
}
/* If we can use this function, return whether we were able to access it */
if (use_cached)
{
return func->is_internalized || func->access.accessible;
}
}
/* The source of the script will end up here */
wcstring script_source;
bool has_script_source = false;
/* Whether we found an accessible file */
bool found_file = false;
/* Look for built-in scripts via a binary search */
const builtin_script_t *matching_builtin_script = NULL;
if (builtin_script_count > 0)
{
const builtin_script_t test_script = {cmd.c_str(), NULL};
const builtin_script_t *array_end = builtin_scripts + builtin_script_count;
const builtin_script_t *found = std::lower_bound(builtin_scripts, array_end, test_script, script_name_precedes_script_name);
if (found != array_end && ! wcscmp(found->name, test_script.name))
{
/* We found it */
matching_builtin_script = found;
}
}
if (matching_builtin_script)
{
has_script_source = true;
script_source = str2wcstring(matching_builtin_script->def);
/* Make a node representing this function */
scoped_lock locker(lock);
autoload_function_t *func = this->get_autoloaded_function_with_creation(cmd, really_load);
/* This function is internalized */
func->is_internalized = true;
/* It's a fiction to say the script is loaded at this point, but we're definitely going to load it down below. */
if (really_load) func->is_loaded = true;
}
if (! has_script_source)
{
/* Iterate over path searching for suitable completion files */
for (i=0; i<path_list.size(); i++)
{
wcstring next = path_list.at(i);
wcstring path = next + L"/" + cmd + L".fish";
const file_access_attempt_t access = access_file(path, R_OK);
if (access.accessible)
{
/* Found it! */
found_file = true;
/* Now we're actually going to take the lock. */
scoped_lock locker(lock);
autoload_function_t *func = this->get_node(cmd);
/* Generate the source if we need to load it */
bool need_to_load_function = really_load && (func == NULL || func->access.mod_time != access.mod_time || ! func->is_loaded);
if (need_to_load_function)
{
/* Generate the script source */
wcstring esc = escape_string(path, 1);
script_source = L". " + esc;
has_script_source = true;
/* Remove any loaded command because we are going to reload it. Note that this will deadlock if command_removed calls back into us. */
if (func && func->is_loaded)
{
command_removed(cmd);
func->is_placeholder = false;
}
/* Mark that we're reloading it */
reloaded = true;
}
/* Create the function if we haven't yet. This does not load it. Do not trigger eviction unless we are actually loading, because we don't want to evict off of the main thread. */
if (! func)
{
func = get_autoloaded_function_with_creation(cmd, really_load);
}
/* It's a fiction to say the script is loaded at this point, but we're definitely going to load it down below. */
if (need_to_load_function) func->is_loaded = true;
/* Unconditionally record our access time */
func->access = access;
break;
}
}
/*
If no file or builtin script was found we insert a placeholder function.
Later we only research if the current time is at least five seconds later.
This way, the files won't be searched over and over again.
*/
if (! found_file && ! has_script_source)
{
scoped_lock locker(lock);
/* Generate a placeholder */
autoload_function_t *func = this->get_node(cmd);
if (! func)
{
func = new autoload_function_t(cmd);
func->is_placeholder = true;
if (really_load)
{
this->add_node(func);
}
else
{
this->add_node_without_eviction(func);
}
}
func->access.last_checked = time(NULL);
}
}
/* If we have a script, either built-in or a file source, then run it */
if (really_load && has_script_source)
{
if (exec_subshell(script_source, false /* do not apply exit status */) == -1)
{
/* Do nothing on failure */
}
}
if (really_load)
{
return reloaded;
}
else
{
return found_file || has_script_source;
}
}

138
autoload.h Normal file
View File

@@ -0,0 +1,138 @@
/** \file autoload.h
The classes responsible for autoloading functions and completions.
*/
#ifndef FISH_AUTOLOAD_H
#define FISH_AUTOLOAD_H
#include <wchar.h>
#include <map>
#include <set>
#include <list>
#include "common.h"
#include "lru.h"
/** A struct responsible for recording an attempt to access a file. */
struct file_access_attempt_t
{
time_t mod_time; /** The modification time of the file */
time_t last_checked; /** When we last checked the file */
bool accessible; /** Whether we believe we could access this file */
bool stale; /** Whether the access attempt is stale */
int error; /** If we could not access the file, the error code */
};
file_access_attempt_t access_file(const wcstring &path, int mode);
struct autoload_function_t : public lru_node_t
{
autoload_function_t(const wcstring &key) : lru_node_t(key), access(), is_loaded(false), is_placeholder(false), is_internalized(false) { }
file_access_attempt_t access; /** The last access attempt */
bool is_loaded; /** Whether we have actually loaded this function */
bool is_placeholder; /** Whether we are a placeholder that stands in for "no such function". If this is true, then is_loaded must be false. */
bool is_internalized; /** Whether this function came from a builtin "internalized" script */
};
struct builtin_script_t
{
const wchar_t *name;
const char *def;
};
struct builtin_script_t;
class env_vars_snapshot_t;
/**
A class that represents a path from which we can autoload, and the autoloaded contents.
*/
class autoload_t : private lru_cache_t<autoload_function_t>
{
private:
/** Lock for thread safety */
pthread_mutex_t lock;
/** The environment variable name */
const wcstring env_var_name;
/** Builtin script array */
const struct builtin_script_t *const builtin_scripts;
/** Builtin script count */
const size_t builtin_script_count;
/** The path from which we most recently autoloaded */
wcstring last_path;
/**
A table containing all the files that are currently being
loaded. This is here to help prevent recursion.
*/
std::set<wcstring> is_loading_set;
bool is_loading(const wcstring &name) const
{
return is_loading_set.find(name) != is_loading_set.end();
}
void remove_all_functions(void)
{
this->evict_all_nodes();
}
bool locate_file_and_maybe_load_it(const wcstring &cmd, bool really_load, bool reload, const wcstring_list_t &path_list);
virtual void node_was_evicted(autoload_function_t *node);
autoload_function_t *get_autoloaded_function_with_creation(const wcstring &cmd, bool allow_eviction);
protected:
/** Overridable callback for when a command is removed */
virtual void command_removed(const wcstring &cmd) { }
public:
/** Create an autoload_t for the given environment variable name */
autoload_t(const wcstring &env_var_name_var, const builtin_script_t *scripts, size_t script_count);
/** Destructor */
virtual ~autoload_t();
/**
Autoload the specified file, if it exists in the specified path. Do
not load it multiple times unless its timestamp changes or
parse_util_unload is called.
Autoloading one file may unload another.
\param cmd the filename to search for. The suffix '.fish' is always added to this name
\param on_unload a callback function to run if a suitable file is found, which has not already been run. unload will also be called for old files which are unloaded.
\param reload wheter to recheck file timestamps on already loaded files
*/
int load(const wcstring &cmd, bool reload);
/** Check whether we have tried loading the given command. Does not do any I/O. */
bool has_tried_loading(const wcstring &cmd);
/**
Tell the autoloader that the specified file, in the specified path,
is no longer loaded.
\param cmd the filename to search for. The suffix '.fish' is always added to this name
\param on_unload a callback function which will be called before (re)loading a file, may be used to unload the previous file.
\return non-zero if the file was removed, zero if the file had not yet been loaded
*/
int unload(const wcstring &cmd);
/**
Unloads all files.
*/
void unload_all();
/** Check whether the given command could be loaded, but do not load it. */
bool can_load(const wcstring &cmd, const env_vars_snapshot_t &vars);
};
#endif

View File

@@ -0,0 +1,136 @@
#!/bin/sh
# This script is run as part of the build process
if test $# -eq 0
then
# Use fish's defaults
DOXYFILE=Doxyfile.help
INPUTDIR=doc_src
OUTPUTDIR=share
echo "Using defaults: $0 ${DOXYFILE} ${INPUTDIR} ${OUTPUTDIR}"
elif test $# -eq 3
then
DOXYFILE="$1"
INPUTDIR="$2"
OUTPUTDIR="$3"
else
echo "Usage: $0 doxygen_file input_directory output_directory"
exit 1
fi
# Determine which man pages we don't want to generate.
# Don't make a test man page. fish's test is conforming, so the system man pages
# are applicable and generally better.
# on OS X, don't make a man page for open, since we defeat fish's open function on OS X.
CONDEMNED_PAGES=test.1
if test `uname` = 'Darwin'; then
CONDEMNED_PAGES="$CONDEMNED_PAGES open.1"
fi
# Helper function to turn a relative path into an absolute path
resolve_path()
{
D=`command dirname "$1"`
B=`command basename "$1"`
echo "`cd \"$D\" 2>/dev/null && pwd || echo \"$D\"`/$B"
}
# Expand relative paths
DOXYFILE=`resolve_path "$DOXYFILE"`
INPUTDIR=`resolve_path "$INPUTDIR"`
OUTPUTDIR=`resolve_path "$OUTPUTDIR"`
echo " doxygen file: $DOXYFILE"
echo " input directory: $INPUTDIR"
echo " output directory: $OUTPUTDIR"
echo " skipping: $CONDEMNED_PAGES"
# Make sure INPUTDIR is found
if test ! -d "$INPUTDIR"; then
echo >&2 "Could not find input directory '${INPUTDIR}'"
exit 1
fi
# Make sure doxygen is found
DOXYGENPATH=`command -v doxygen`
if test -z "$DOXYGENPATH" ; then
for i in /usr/local/bin/doxygen /opt/bin/doxygen /Applications/Doxygen.app/Contents/Resources/doxygen ~/Applications/Doxygen.app/Contents/Resources/doxygen ; do
if test -f "$i"; then
DOXYGENPATH="$i"
break
fi
done
fi
if test -z "$DOXYGENPATH"; then
echo >&2 "doxygen is not installed, so documentation will not be built."
exit 0
fi
# Determine where our output should go
if ! mkdir -p "${OUTPUTDIR}" ; then
echo "Could not create output directory '${OUTPUTDIR}'"
fi
# Make a temporary directory
TMPLOC=`mktemp -d -t fish_doc_build_XXXXXX` || { echo >&2 "Could not build documentation because mktemp failed"; exit 1; }
# Copy stuff to the temp directory
for i in "$INPUTDIR"/*.txt; do
INPUTFILE=$TMPLOC/`basename $i .txt`.doxygen
echo "/** \page" `basename $i .txt` > $INPUTFILE
cat $i >>$INPUTFILE
echo "*/" >>$INPUTFILE
done
# Make some extra stuff to pass to doxygen
# Input is kept as . because we cd to the input directory beforehand
# This prevents doxygen from generating "documentation" for intermediate directories
DOXYPARAMS=$(cat <<EOF
PROJECT_NUMBER=2.0.0
INPUT=.
OUTPUT_DIRECTORY=$OUTPUTDIR
QUIET=YES
EOF
);
# echo "$DOXYPARAMS"
# Clear out the output directory first
find "${OUTPUTDIR}" -name "*.1" -delete
# Run doxygen
cd "$TMPLOC"
(cat "${DOXYFILE}" ; echo "$DOXYPARAMS";) | "$DOXYGENPATH" -
# Remember errors
RESULT=$?
cd "${OUTPUTDIR}/man/man1/"
if test "$RESULT" = 0 ; then
# Postprocess the files
for i in "$INPUTDIR"/*.txt; do
# It would be nice to use -i here for edit in place, but that is not portable
CMD_NAME=`basename "$i" .txt`;
sed -e "s/\(.\)\\.SH/\1/" -e "s/$CMD_NAME *\\\\- *\"\(.*\)\"/\1/" "${CMD_NAME}.1" > "${CMD_NAME}.1.tmp"
mv "${CMD_NAME}.1.tmp" "${CMD_NAME}.1"
done
# Erase condemned pages
rm -f $CONDEMNED_PAGES
fi
# Destroy TMPLOC
echo "Cleaning up '$TMPLOC'"
rm -Rf "$TMPLOC"
if test "$RESULT" = 0; then
# Tell the user what we did
echo "Output man pages into '${OUTPUTDIR}'"
else
echo "Doxygen failed. See the output log for details."
fi
exit $RESULT

View File

@@ -0,0 +1,3 @@
This is the_ridiculous'fish s delightful fork of, fish friendly interactive shell. For more information, visit http://ridiculousfish.com/shell/ .
This installer will install fish, but will not modify your /etc/shells file or your default shell. I trust you know how to do that yourself if you care to!

View File

@@ -0,0 +1,8 @@
#!/usr/bin/env fish
#
# This file produces command specific completions for csv. Meant to be executed
# from the root directory (so the completions get put in the right place).
. build_tools/make_vcs_completions_generic.fish
write_completions csv >share/completions/csv.fish

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env fish
#
# This file produces command specific completions for darcs. Meant to be
# executed from the root directory (so the completions get put in the right
# place).
. build_tools/make_vcs_completions_generic.fish
set darcs_comp 'complete -c darcs -n "not __fish_use_subcommand" -a "(test -f _darcs/prefs/repos; and cat _darcs/prefs/repos)" --description "Darcs repo"'
set darcs_comp $darcs_comp 'complete -c darcs -a "test predist boringfile binariesfile" -n "contains setpref (commandline -poc)" --description "Set the specified option" -x'
write_completions darcs $darcs_comp >share/completions/darcs.fish

18
build_tools/make_deb.sh Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/sh
# Terminate on error
set -e
sudo rm -Rf /tmp/fishfish
mkdir /tmp/fishfish
git archive --format=tar fish_fish | tar -x -C /tmp/fishfish
mkdir /tmp/fishfish/doc-pak
cp README INSTALL CHANGELOG release_notes.html /tmp/fishfish/doc-pak/
cp build_tools/description-pak /tmp/fishfish/
cd /tmp/fishfish
autoconf
./configure
make -j 3
sudo checkinstall --default --pakdir ~/fish_built/ --pkgversion 0.9 make install
mv ~/fish_built/fishfish_0.9-1_i386.deb ~/fish_built/fishfish_0.9_i386.deb

View File

@@ -0,0 +1,8 @@
#!/usr/bin/env fish
#
# This file produces command specific completions for hg. Meant to be executed
# from the root directory (so the completions get put in the right place).
. build_tools/make_vcs_completions_generic.fish
write_completions hg >share/completions/hg.fish

23
build_tools/make_pkg.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/sh
VERSION=`sed -E -n 's/^.*PACKAGE_VERSION "([0-9.]+)"/\1/p' osx/config.h`
if test -z "$VERSION" ; then
echo "Could not get version from osx/config.h"
exit 1
fi
echo "Version is $VERSION"
set -x
make distclean
rm -Rf /tmp/fish_pkg
#Exit on error
set -e
mkdir -p /tmp/fish_pkg/root /tmp/fish_pkg/intermediates /tmp/fish_pkg/dst
xcodebuild install -scheme install_tree -configuration Release DSTROOT=/tmp/fish_pkg/root/
pkgbuild --scripts build_tools/osx_package_scripts --root /tmp/fish_pkg/root/ --identifier 'com.ridiculousfish.fish-shell-pkg' --version "$VERSION" /tmp/fish_pkg/intermediates/fish.pkg
productbuild --package-path /tmp/fish_pkg/intermediates --distribution build_tools/osx_distribution.xml --resources build_tools/osx_package_resources/ ~/fish_built/fish.pkg

View File

@@ -0,0 +1,8 @@
#!/usr/bin/env fish
#
# This file produces command specific completions for svn. Meant to be executed
# from the root directory (so the completions get put in the right place).
. build_tools/make_vcs_completions_generic.fish
write_completions svn >share/completions/svn.fish

46
build_tools/make_tarball.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/sh
# Script to generate a tarball
# We use git to output a tree. But we also want to build the user documentation
# and put that in the tarball, so that nobody needs to have doxygen installed
# to build it.
# Exit on error
set -e
# We wil generate a tarball with a prefix "fish"
# git can do that automatically for us via git-archive
# but to get the documentation in, we need to make a symlink called "fish"
# and tar from that, so that the documentation gets the right prefix
# Get the current directory, which we'll use for symlinks
wd="$PWD"
# The name of the prefix, which is the directory that you get when you untar
prefix="fish"
# The path where we will output the tar file
path=~/fish_built/fish-2.0.tar
# Clean up stuff we've written before
rm -f "$path" "$path".gz
# git starts the archive
git archive --format=tar --prefix="$prefix"/ master > "$path"
# tarball out the documentation
make user_doc
make share/man
cd /tmp
rm -f "$prefix"
ln -s "$wd" "$prefix"
tar --append --file="$path" "$prefix"/user_doc/html
tar --append --file="$path" "$prefix"/share/man
rm -f "$prefix"
# gzip it
gzip "$path"
# Output what we did, and the sha1 hash
echo "Tarball written to $path".gz
openssl sha1 "$path".gz

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env fish
#
# This file produces command specific completions for hg, darcs and a
# few other vcs systems.
build_tools/make_darcs_completions.fish
build_tools/make_hg_completions.fish
build_tools/make_svn_completions.fish
build_tools/make_csv_completions.fish

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env fish
#
# This file produces command specific completions for hg, darcs and a
# few other vcs systems. It uses the fact that all these systems have a
# somewhat uniform command line help mechanism.
# This file provides generic functions for generating specific completions for
# hg, darcs and a few other vcs systems. It uses the fact that all these
# systems have a somewhat uniform command line help mechanism.
#
function cap
@@ -227,11 +227,3 @@ function write_completions
echo \n\n
end
set darcs_comp 'complete -c darcs -n "not __fish_use_subcommand" -a "(test -f _darcs/prefs/repos; and cat _darcs/prefs/repos)" --description "Darcs repo"'
set darcs_comp $darcs_comp 'complete -c darcs -a "test predist boringfile binariesfile" -n "contains setpref (commandline -poc)" --description "Set the specified option" -x'
write_completions darcs $darcs_comp >share/completions/darcs.fish
write_completions hg >share/completions/hg.fish
write_completions svn >share/completions/svn.fish
write_completions cvs >share/completions/cvs.fish

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<installer-gui-script minSpecVersion="1">
<title>fish shell</title>
<welcome file="welcome.rtf"/>
<background file="terminal_logo.png" scaling="proportional" alignment="bottomleft"/>
<pkg-ref id="com.ridiculousfish.fish-shell-pkg"/>
<options customize="never" require-scripts="false"/>
<choices-outline>
<line choice="default">
<line choice="com.ridiculousfish.fish-shell-pkg"/>
</line>
</choices-outline>
<choice id="default"/>
<choice id="com.ridiculousfish.fish-shell-pkg" visible="false">
<pkg-ref id="com.ridiculousfish.fish-shell-pkg"/>
</choice>
<pkg-ref id="com.ridiculousfish.fish-shell-pkg" version="0" onConclusion="none">fish.pkg</pkg-ref>
</installer-gui-script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -0,0 +1,25 @@
{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370
{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Monaco;}
{\colortbl;\red255\green255\blue255;}
{\info
{\author dlkfjslfjsfdlkfk}}\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
\f0\fs30 \cf0 The fish shell is a smart and user friendly command line shell. For more information, visit {\field{\*\fldinst{HYPERLINK "http://fishshell.com"}}{\fldrslt http://fishshell.com}}.\
\
fish will be installed into
\f1\fs26 /usr/local/
\f0\fs30 , and fish will be added to
\f1\fs26 /etc/shells
\f0\fs30 if necessary.\
\
Your default shell will
\i not
\i0 be changed. To make fish your default, run:\
\
\f1 chsh -s /usr/local/bin/fish
\f0 \
\
Enjoy!\
}

View File

@@ -0,0 +1,53 @@
#!/bin/sh -e
# Modified from Debian's add-shell to work on OS X
if test $# -eq 0
then
echo usage: $0 shellname [shellname ...]
exit 1
fi
scriptname=`basename "$0"`
if [[ $UID -ne 0 ]]; then
echo "${scriptname} must be run as root"
exit 1
fi
file=/etc/shells
# I want this to be GUARANTEED to be on the same filesystem as $file
tmpfile=${file}.tmp
set -o noclobber
trap "rm -f $tmpfile" EXIT
if ! cat $file > $tmpfile
then
cat 1>&2 <<EOF
Either another instance of $0 is running, or it was previously interrupted.
Please examine ${tmpfile} to see if it should be moved onto ${file}.
EOF
exit 1
fi
# Append a newline if it doesn't exist
if [ "$(tail -c1 "$tmpfile"; echo x)" != $'\nx' ]; then
echo "" >> "$tmpfile"
fi
for i
do
if ! grep -q "^${i}$" "$tmpfile"
then
echo $i >> "$tmpfile"
fi
done
chmod 0644 $tmpfile
chown root:wheel $tmpfile
mv $tmpfile $file
trap "" EXIT
exit 0

View File

@@ -0,0 +1,3 @@
#!/bin/sh -x
./add-shell /usr/local/bin/fish > /tmp/fish_postinstall_output.log

3976
builtin.c

File diff suppressed because it is too large Load Diff

4147
builtin.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/** \file builtin.h
Prototypes for functions for executing builtin functions.
Prototypes for functions for executing builtin functions.
*/
#ifndef FISH_BUILTIN_H
@@ -9,12 +9,15 @@
#include "util.h"
#include "io.h"
#include "common.h"
class parser_t;
enum
{
COMMAND_NOT_BUILTIN,
BUILTIN_REGULAR,
BUILTIN_FUNCTION
COMMAND_NOT_BUILTIN,
BUILTIN_REGULAR,
BUILTIN_FUNCTION
}
;
@@ -46,7 +49,7 @@ enum
/**
Error message for unknown switch
*/
#define BUILTIN_ERR_UNKNOWN _( L"%ls: Unknown option '%ls'\n" )
#define BUILTIN_ERR_UNKNOWN _( L"%ls: Unknown option '%ls'\n" )
/**
Error message for invalid character in variable name
@@ -70,6 +73,10 @@ enum
#define BUILTIN_FOR_ERR_NAME _( L"%ls: '%ls' is not a valid variable name\n" )
/** Error messages for 'else if' */
#define BUILTIN_ELSEIF_ERR_COUNT _( L"%ls: can only take 'if' and then another command as an argument\n")
#define BUILTIN_ELSEIF_ERR_ARGUMENT _( L"%ls: any second argument must be 'if'\n")
/**
Error message when too many arguments are supplied to a builtin
*/
@@ -86,15 +93,13 @@ enum
#define BUILTIN_END_BLOCK_UNKNOWN _( L"%ls: Unknown block type '%ls'\n" )
#define BUILTIN_ERR_NOT_NUMBER _( L"%ls: Argument '%ls' is not a number\n" )
/**
Stringbuffer used to represent standard output
*/
extern string_buffer_t *sb_out;
/**
Stringbuffer used to represent standard error
*/
extern string_buffer_t *sb_err;
/** Get the string used to represent stdout and stderr */
const wcstring &get_stdout_buffer();
const wcstring &get_stderr_buffer();
/** Output an error */
void builtin_show_error(const wcstring &err);
/**
Kludge. Tells builtins if output is to screen
@@ -120,11 +125,12 @@ void builtin_destroy();
/**
Is there a builtin command with the given name?
*/
int builtin_exists( wchar_t *cmd );
int builtin_exists(const wcstring &cmd);
/**
Execute a builtin command
\param parser The parser being used
\param argv Array containing the command and parameters
of the builtin. The list is terminated by a
null pointer. This syntax resembles the syntax
@@ -133,28 +139,29 @@ int builtin_exists( wchar_t *cmd );
\return the exit status of the builtin command
*/
int builtin_run( wchar_t **argv, io_data_t *io );
int builtin_run(parser_t &parser, const wchar_t * const *argv, const io_chain_t &io);
/** Returns a list of all builtin names */
wcstring_list_t builtin_get_names(void);
/** Insert all builtin names into list. */
void builtin_get_names(std::vector<completion_t> &list);
/**
Insert all builtin names into l. These are not copies of the strings and should not be freed after use.
Pushes a new set of input/output to the stack. The new stdin is supplied, a new set of output strings is created.
*/
void builtin_get_names( array_list_t *list );
void builtin_push_io(parser_t &parser, int stdin_fd);
/**
Pushes a new set of input/output to the stack. The new stdin is supplied, a new set of output string_buffer_ts is created.
Pops a set of input/output from the stack. The output strings are destroued, but the input file is not closed.
*/
void builtin_push_io( int stdin_fd );
/**
Pops a set of input/output from the stack. The output string_buffer_ts are destroued, but the input file is not closed.
*/
void builtin_pop_io();
void builtin_pop_io(parser_t &parser);
/**
Return a one-line description of the specified builtin
Return a one-line description of the specified builtin.
*/
const wchar_t *builtin_get_desc( const wchar_t *b );
wcstring builtin_get_desc(const wcstring &b);
/**
@@ -167,10 +174,9 @@ const wchar_t *builtin_complete_get_temporary_buffer();
/**
Run the __fish_print_help function to obtain the help information
for the specified command. The resulting string will be valid until
the next time this function is called, and must never be free'd manually.
for the specified command.
*/
wchar_t *builtin_help_get( const wchar_t *cmd );
wcstring builtin_help_get(parser_t &parser, const wchar_t *cmd);
#endif

View File

@@ -1,664 +0,0 @@
/** \file builtin_commandline.c Functions defining the commandline builtin
Functions used for implementing the commandline builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/types.h>
#include <termios.h>
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "common.h"
#include "wgetopt.h"
#include "reader.h"
#include "proc.h"
#include "parser.h"
#include "tokenizer.h"
#include "input_common.h"
#include "input.h"
#include "parse_util.h"
/**
Which part of the comandbuffer are we operating on
*/
enum
{
STRING_MODE=1, /**< Operate on entire buffer */
JOB_MODE, /**< Operate on job under cursor */
PROCESS_MODE, /**< Operate on process under cursor */
TOKEN_MODE /**< Operate on token under cursor */
}
;
/**
For text insertion, how should it be done
*/
enum
{
REPLACE_MODE=1, /**< Replace current text */
INSERT_MODE, /**< Insert at cursor position */
APPEND_MODE /**< Insert at end of current token/command/buffer */
}
;
/**
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;
/**
Returns the current commandline buffer.
*/
static wchar_t *get_buffer()
{
return current_buffer;
}
/**
Returns the position of the cursor
*/
static int get_cursor_pos()
{
return current_cursor_pos;
}
/**
Replace/append/insert the selection with/at/after the specified string.
\param begin beginning of selection
\param end end of selection
\param insert the string to insert
\param append_mode can be one of REPLACE_MODE, INSERT_MODE or APPEND_MODE, affects the way the test update is performed
*/
static void replace_part( const wchar_t *begin,
const wchar_t *end,
wchar_t *insert,
int append_mode )
{
const wchar_t *buff = get_buffer();
string_buffer_t out;
int out_pos=get_cursor_pos();
sb_init( &out );
sb_append_substring( &out, buff, begin-buff );
switch( append_mode)
{
case REPLACE_MODE:
{
sb_append( &out, insert );
out_pos = wcslen( insert ) + (begin-buff);
break;
}
case APPEND_MODE:
{
sb_append_substring( &out, begin, end-begin );
sb_append( &out, insert );
break;
}
case INSERT_MODE:
{
int cursor = get_cursor_pos() -(begin-buff);
sb_append_substring( &out, begin, cursor );
sb_append( &out, insert );
sb_append_substring( &out, begin+cursor, end-begin-cursor );
out_pos += wcslen( insert );
break;
}
}
sb_append( &out, end );
reader_set_buffer( (wchar_t *)out.buff, out_pos );
sb_destroy( &out );
}
/**
Output the specified selection.
\param begin start of selection
\param end end of selection
\param cut_at_cursor whether printing should stop at the surrent cursor position
\param tokenize whether the string should be tokenized, printing one string token on every line and skipping non-string tokens
*/
static void write_part( const wchar_t *begin,
const wchar_t *end,
int cut_at_cursor,
int tokenize )
{
tokenizer tok;
string_buffer_t out;
wchar_t *buff;
int pos;
pos = get_cursor_pos()-(begin-get_buffer());
if( tokenize )
{
buff = wcsndup( begin, end-begin );
// fwprintf( stderr, L"Subshell: %ls, end char %lc\n", buff, *end );
sb_init( &out );
for( tok_init( &tok, buff, TOK_ACCEPT_UNFINISHED );
tok_has_next( &tok );
tok_next( &tok ) )
{
if( (cut_at_cursor) &&
(tok_get_pos( &tok)+wcslen(tok_last( &tok)) >= pos) )
break;
switch( tok_last_type( &tok ) )
{
case TOK_STRING:
{
wchar_t *tmp = unescape( tok_last( &tok ), UNESCAPE_INCOMPLETE );
sb_append( &out, tmp, L"\n", (void *)0 );
free( tmp );
break;
}
}
}
sb_append( sb_out,
(wchar_t *)out.buff );
free( buff );
tok_destroy( &tok );
sb_destroy( &out );
}
else
{
wchar_t *buff;
if( cut_at_cursor )
{
end = begin+pos;
}
buff = wcsndup( begin, end-begin );
// debug( 0, L"woot2 %ls -> %ls", buff, esc );
sb_append( sb_out, buff );
sb_append( sb_out, L"\n" );
free( buff );
}
}
/**
The commandline builtin. It is used for specifying a new value for
the commandline.
*/
static int builtin_commandline( wchar_t **argv )
{
int buffer_part=0;
int cut_at_cursor=0;
int argc = builtin_count_args( argv );
int append_mode=0;
int function_mode = 0;
int tokenize = 0;
int cursor_mode = 0;
int line_mode = 0;
int search_mode = 0;
wchar_t *begin, *end;
current_buffer = (wchar_t *)builtin_complete_get_temporary_buffer();
if( current_buffer )
{
current_cursor_pos = wcslen( current_buffer );
}
else
{
current_buffer = reader_get_buffer();
current_cursor_pos = reader_get_cursor_pos();
}
if( !get_buffer() )
{
if (is_interactive_session)
{
/*
Prompt change requested while we don't have
a prompt, most probably while reading the
init files. Just ignore it.
*/
return 1;
}
sb_append( sb_err,
argv[0],
L": Can not set commandline in non-interactive mode\n",
(void *)0 );
builtin_print_help( argv[0], sb_err );
return 1;
}
woptind=0;
while( 1 )
{
static const struct woption
long_options[] =
{
{
L"append", no_argument, 0, 'a'
}
,
{
L"insert", no_argument, 0, 'i'
}
,
{
L"replace", no_argument, 0, 'r'
}
,
{
L"current-job", no_argument, 0, 'j'
}
,
{
L"current-process", no_argument, 0, 'p'
}
,
{
L"current-token", no_argument, 0, 't'
}
,
{
L"current-buffer", no_argument, 0, 'b'
}
,
{
L"cut-at-cursor", no_argument, 0, 'c'
}
,
{
L"function", no_argument, 0, 'f'
}
,
{
L"tokenize", no_argument, 0, 'o'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
L"input", required_argument, 0, 'I'
}
,
{
L"cursor", no_argument, 0, 'C'
}
,
{
L"line", no_argument, 0, 'L'
}
,
{
L"search-mode", no_argument, 0, 'S'
}
,
{
0, 0, 0, 0
}
}
;
int opt_index = 0;
int opt = wgetopt_long( argc,
argv,
L"abijpctwforhI:CLS",
long_options,
&opt_index );
if( opt == -1 )
break;
switch( opt )
{
case 0:
if(long_options[opt_index].flag != 0)
break;
sb_printf( sb_err,
BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name );
builtin_print_help( argv[0], sb_err );
return 1;
case L'a':
append_mode = APPEND_MODE;
break;
case L'b':
buffer_part = STRING_MODE;
break;
case L'i':
append_mode = INSERT_MODE;
break;
case L'r':
append_mode = REPLACE_MODE;
break;
case 'c':
cut_at_cursor=1;
break;
case 't':
buffer_part = TOKEN_MODE;
break;
case 'j':
buffer_part = JOB_MODE;
break;
case 'p':
buffer_part = PROCESS_MODE;
break;
case 'f':
function_mode=1;
break;
case 'o':
tokenize=1;
break;
case 'I':
current_buffer = woptarg;
current_cursor_pos = wcslen( woptarg );
break;
case 'C':
cursor_mode = 1;
break;
case 'L':
line_mode = 1;
break;
case 'S':
search_mode = 1;
break;
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case L'?':
builtin_unknown_option( argv[0], argv[woptind-1] );
return 1;
}
}
if( function_mode )
{
int i;
/*
Check for invalid switch combinations
*/
if( buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode || search_mode )
{
sb_printf(sb_err,
BUILTIN_ERR_COMBO,
argv[0] );
builtin_print_help( argv[0], sb_err );
return 1;
}
if( argc == woptind )
{
sb_printf( sb_err,
BUILTIN_ERR_MISSING,
argv[0] );
builtin_print_help( argv[0], sb_err );
return 1;
}
for( i=woptind; i<argc; i++ )
{
wint_t c = input_function_get_code( argv[i] );
if( c != -1 )
{
/*
input_unreadch inserts the specified keypress or
readline function at the top of the stack of unused
keypresses
*/
input_unreadch(c);
}
else
{
sb_printf( sb_err,
_(L"%ls: Unknown input function '%ls'\n"),
argv[0],
argv[i] );
builtin_print_help( argv[0], sb_err );
return 1;
}
}
return 0;
}
/*
Check for invalid switch combinations
*/
if( (search_mode || line_mode || cursor_mode) && (argc-woptind > 1) )
{
sb_append( sb_err,
argv[0],
L": Too many arguments\n",
(void *)0 );
builtin_print_help( argv[0], sb_err );
return 1;
}
if( (buffer_part || tokenize || cut_at_cursor) && (cursor_mode || line_mode || search_mode) )
{
sb_printf( sb_err,
BUILTIN_ERR_COMBO,
argv[0] );
builtin_print_help( argv[0], sb_err );
return 1;
}
if( (tokenize || cut_at_cursor) && (argc-woptind) )
{
sb_printf( sb_err,
BUILTIN_ERR_COMBO2,
argv[0],
L"--cut-at-cursor and --tokenize can not be used when setting the commandline" );
builtin_print_help( argv[0], sb_err );
return 1;
}
if( append_mode && !(argc-woptind) )
{
sb_printf( sb_err,
BUILTIN_ERR_COMBO2,
argv[0],
L"insertion mode switches can not be used when not in insertion mode" );
builtin_print_help( argv[0], sb_err );
return 1;
}
/*
Set default modes
*/
if( !append_mode )
{
append_mode = REPLACE_MODE;
}
if( !buffer_part )
{
buffer_part = STRING_MODE;
}
if( cursor_mode )
{
if( argc-woptind )
{
wchar_t *endptr;
int new_pos;
errno = 0;
new_pos = wcstol( argv[woptind], &endptr, 10 );
if( *endptr || errno )
{
sb_printf( sb_err,
BUILTIN_ERR_NOT_NUMBER,
argv[0],
argv[woptind] );
builtin_print_help( argv[0], sb_err );
}
current_buffer = reader_get_buffer();
new_pos = maxi( 0, mini( new_pos, wcslen( current_buffer ) ) );
reader_set_buffer( current_buffer, new_pos );
return 0;
}
else
{
sb_printf( sb_out, L"%d\n", reader_get_cursor_pos() );
return 0;
}
}
if( line_mode )
{
int pos = reader_get_cursor_pos();
wchar_t *buff = reader_get_buffer();
sb_printf( sb_out, L"%d\n", parse_util_lineno( buff, pos ) );
return 0;
}
if( search_mode )
{
return !reader_search_mode();
}
switch( buffer_part )
{
case STRING_MODE:
{
begin = get_buffer();
end = begin+wcslen(begin);
break;
}
case PROCESS_MODE:
{
parse_util_process_extent( get_buffer(),
get_cursor_pos(),
&begin,
&end );
break;
}
case JOB_MODE:
{
parse_util_job_extent( get_buffer(),
get_cursor_pos(),
&begin,
&end );
break;
}
case TOKEN_MODE:
{
parse_util_token_extent( get_buffer(),
get_cursor_pos(),
&begin,
&end,
0, 0 );
break;
}
}
switch(argc-woptind)
{
case 0:
{
write_part( begin, end, cut_at_cursor, tokenize );
break;
}
case 1:
{
replace_part( begin, end, argv[woptind], append_mode );
break;
}
default:
{
string_buffer_t sb;
int i;
sb_init( &sb );
sb_append( &sb, argv[woptind] );
for( i=woptind+1; i<argc; i++ )
{
sb_append( &sb, L"\n" );
sb_append( &sb, argv[i] );
}
replace_part( begin, end, (wchar_t *)sb.buff, append_mode );
sb_destroy( &sb );
break;
}
}
return 0;
}

642
builtin_commandline.cpp Normal file
View File

@@ -0,0 +1,642 @@
/** \file builtin_commandline.c Functions defining the commandline builtin
Functions used for implementing the commandline builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/types.h>
#include <termios.h>
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "common.h"
#include "wgetopt.h"
#include "reader.h"
#include "proc.h"
#include "parser.h"
#include "tokenizer.h"
#include "input_common.h"
#include "input.h"
#include "parse_util.h"
/**
Which part of the comandbuffer are we operating on
*/
enum
{
STRING_MODE=1, /**< Operate on entire buffer */
JOB_MODE, /**< Operate on job under cursor */
PROCESS_MODE, /**< Operate on process under cursor */
TOKEN_MODE /**< Operate on token under cursor */
}
;
/**
For text insertion, how should it be done
*/
enum
{
REPLACE_MODE=1, /**< Replace current text */
INSERT_MODE, /**< Insert at cursor position */
APPEND_MODE /**< Insert at end of current token/command/buffer */
}
;
/**
Pointer to what the commandline builtin considers to be the current
contents of the command line buffer.
*/
static const wchar_t *current_buffer=0;
/**
What the commandline builtin considers to be the current cursor
position.
*/
static size_t current_cursor_pos = (size_t)(-1);
/**
Returns the current commandline buffer.
*/
static const wchar_t *get_buffer()
{
return current_buffer;
}
/**
Returns the position of the cursor
*/
static size_t get_cursor_pos()
{
return current_cursor_pos;
}
/**
Replace/append/insert the selection with/at/after the specified string.
\param begin beginning of selection
\param end end of selection
\param insert the string to insert
\param append_mode can be one of REPLACE_MODE, INSERT_MODE or APPEND_MODE, affects the way the test update is performed
*/
static void replace_part(const wchar_t *begin,
const wchar_t *end,
const wchar_t *insert,
int append_mode)
{
const wchar_t *buff = get_buffer();
size_t out_pos = get_cursor_pos();
wcstring out;
out.append(buff, begin - buff);
switch (append_mode)
{
case REPLACE_MODE:
{
out.append(insert);
out_pos = wcslen(insert) + (begin-buff);
break;
}
case APPEND_MODE:
{
out.append(begin, end-begin);
out.append(insert);
break;
}
case INSERT_MODE:
{
long cursor = get_cursor_pos() -(begin-buff);
out.append(begin, cursor);
out.append(insert);
out.append(begin+cursor, end-begin-cursor);
out_pos += wcslen(insert);
break;
}
}
out.append(end);
reader_set_buffer(out, out_pos);
}
/**
Output the specified selection.
\param begin start of selection
\param end end of selection
\param cut_at_cursor whether printing should stop at the surrent cursor position
\param tokenize whether the string should be tokenized, printing one string token on every line and skipping non-string tokens
*/
static void write_part(const wchar_t *begin,
const wchar_t *end,
int cut_at_cursor,
int tokenize)
{
wcstring out;
wchar_t *buff;
size_t pos;
pos = get_cursor_pos()-(begin-get_buffer());
if (tokenize)
{
buff = wcsndup(begin, end-begin);
// fwprintf( stderr, L"Subshell: %ls, end char %lc\n", buff, *end );
out.clear();
tokenizer_t tok(buff, TOK_ACCEPT_UNFINISHED);
for (; tok_has_next(&tok); tok_next(&tok))
{
if ((cut_at_cursor) &&
(tok_get_pos(&tok)+wcslen(tok_last(&tok)) >= pos))
break;
switch (tok_last_type(&tok))
{
case TOK_STRING:
{
out.append(escape_string(tok_last(&tok), UNESCAPE_INCOMPLETE));
out.push_back(L'\n');
break;
}
}
}
stdout_buffer.append(out);
free(buff);
}
else
{
if (cut_at_cursor)
{
end = begin+pos;
}
// debug( 0, L"woot2 %ls -> %ls", buff, esc );
stdout_buffer.append(begin, end - begin);
stdout_buffer.append(L"\n");
}
}
/**
The commandline builtin. It is used for specifying a new value for
the commandline.
*/
static int builtin_commandline(parser_t &parser, wchar_t **argv)
{
int buffer_part=0;
int cut_at_cursor=0;
int argc = builtin_count_args(argv);
int append_mode=0;
int function_mode = 0;
int tokenize = 0;
int cursor_mode = 0;
int line_mode = 0;
int search_mode = 0;
const wchar_t *begin, *end;
current_buffer = (wchar_t *)builtin_complete_get_temporary_buffer();
if (current_buffer)
{
current_cursor_pos = wcslen(current_buffer);
}
else
{
current_buffer = reader_get_buffer();
current_cursor_pos = reader_get_cursor_pos();
}
if (!get_buffer())
{
if (is_interactive_session)
{
/*
Prompt change requested while we don't have
a prompt, most probably while reading the
init files. Just ignore it.
*/
return 1;
}
stderr_buffer.append(argv[0]);
stderr_buffer.append(L": Can not set commandline in non-interactive mode\n");
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
woptind=0;
while (1)
{
static const struct woption
long_options[] =
{
{
L"append", no_argument, 0, 'a'
}
,
{
L"insert", no_argument, 0, 'i'
}
,
{
L"replace", no_argument, 0, 'r'
}
,
{
L"current-job", no_argument, 0, 'j'
}
,
{
L"current-process", no_argument, 0, 'p'
}
,
{
L"current-token", no_argument, 0, 't'
}
,
{
L"current-buffer", no_argument, 0, 'b'
}
,
{
L"cut-at-cursor", no_argument, 0, 'c'
}
,
{
L"function", no_argument, 0, 'f'
}
,
{
L"tokenize", no_argument, 0, 'o'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
L"input", required_argument, 0, 'I'
}
,
{
L"cursor", no_argument, 0, 'C'
}
,
{
L"line", no_argument, 0, 'L'
}
,
{
L"search-mode", no_argument, 0, 'S'
}
,
{
0, 0, 0, 0
}
}
;
int opt_index = 0;
int opt = wgetopt_long(argc,
argv,
L"abijpctwforhI:CLS",
long_options,
&opt_index);
if (opt == -1)
break;
switch (opt)
{
case 0:
if (long_options[opt_index].flag != 0)
break;
append_format(stderr_buffer,
BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
case L'a':
append_mode = APPEND_MODE;
break;
case L'b':
buffer_part = STRING_MODE;
break;
case L'i':
append_mode = INSERT_MODE;
break;
case L'r':
append_mode = REPLACE_MODE;
break;
case 'c':
cut_at_cursor=1;
break;
case 't':
buffer_part = TOKEN_MODE;
break;
case 'j':
buffer_part = JOB_MODE;
break;
case 'p':
buffer_part = PROCESS_MODE;
break;
case 'f':
function_mode=1;
break;
case 'o':
tokenize=1;
break;
case 'I':
current_buffer = woptarg;
current_cursor_pos = wcslen(woptarg);
break;
case 'C':
cursor_mode = 1;
break;
case 'L':
line_mode = 1;
break;
case 'S':
search_mode = 1;
break;
case 'h':
builtin_print_help(parser, argv[0], stdout_buffer);
return 0;
case L'?':
builtin_unknown_option(parser, argv[0], argv[woptind-1]);
return 1;
}
}
if (function_mode)
{
int i;
/*
Check for invalid switch combinations
*/
if (buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode || search_mode)
{
append_format(stderr_buffer,
BUILTIN_ERR_COMBO,
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
if (argc == woptind)
{
append_format(stderr_buffer,
BUILTIN_ERR_MISSING,
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
for (i=woptind; i<argc; i++)
{
wchar_t c = input_function_get_code(argv[i]);
if (c != (wchar_t)(-1))
{
/*
input_unreadch inserts the specified keypress or
readline function at the top of the stack of unused
keypresses
*/
input_unreadch(c);
}
else
{
append_format(stderr_buffer,
_(L"%ls: Unknown input function '%ls'\n"),
argv[0],
argv[i]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
}
return 0;
}
/*
Check for invalid switch combinations
*/
if ((search_mode || line_mode || cursor_mode) && (argc-woptind > 1))
{
append_format(stderr_buffer,
argv[0],
L": Too many arguments\n",
NULL);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
if ((buffer_part || tokenize || cut_at_cursor) && (cursor_mode || line_mode || search_mode))
{
append_format(stderr_buffer,
BUILTIN_ERR_COMBO,
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
if ((tokenize || cut_at_cursor) && (argc-woptind))
{
append_format(stderr_buffer,
BUILTIN_ERR_COMBO2,
argv[0],
L"--cut-at-cursor and --tokenize can not be used when setting the commandline");
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
if (append_mode && !(argc-woptind))
{
append_format(stderr_buffer,
BUILTIN_ERR_COMBO2,
argv[0],
L"insertion mode switches can not be used when not in insertion mode");
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
/*
Set default modes
*/
if (!append_mode)
{
append_mode = REPLACE_MODE;
}
if (!buffer_part)
{
buffer_part = STRING_MODE;
}
if (cursor_mode)
{
if (argc-woptind)
{
wchar_t *endptr;
long new_pos;
errno = 0;
new_pos = wcstol(argv[woptind], &endptr, 10);
if (*endptr || errno)
{
append_format(stderr_buffer,
BUILTIN_ERR_NOT_NUMBER,
argv[0],
argv[woptind]);
builtin_print_help(parser, argv[0], stderr_buffer);
}
current_buffer = reader_get_buffer();
new_pos = maxi(0L, mini(new_pos, (long)wcslen(current_buffer)));
reader_set_buffer(current_buffer, (size_t)new_pos);
return 0;
}
else
{
append_format(stdout_buffer, L"%lu\n", (unsigned long)reader_get_cursor_pos());
return 0;
}
}
if (line_mode)
{
size_t pos = reader_get_cursor_pos();
const wchar_t *buff = reader_get_buffer();
append_format(stdout_buffer, L"%lu\n", (unsigned long)parse_util_lineno(buff, pos));
return 0;
}
if (search_mode)
{
return !reader_search_mode();
}
switch (buffer_part)
{
case STRING_MODE:
{
begin = get_buffer();
end = begin+wcslen(begin);
break;
}
case PROCESS_MODE:
{
parse_util_process_extent(get_buffer(),
get_cursor_pos(),
&begin,
&end);
break;
}
case JOB_MODE:
{
parse_util_job_extent(get_buffer(),
get_cursor_pos(),
&begin,
&end);
break;
}
case TOKEN_MODE:
{
parse_util_token_extent(get_buffer(),
get_cursor_pos(),
&begin,
&end,
0, 0);
break;
}
}
switch (argc-woptind)
{
case 0:
{
write_part(begin, end, cut_at_cursor, tokenize);
break;
}
case 1:
{
replace_part(begin, end, argv[woptind], append_mode);
break;
}
default:
{
wcstring sb = argv[woptind];
int i;
for (i=woptind+1; i<argc; i++)
{
sb.push_back(L'\n');
sb.append(argv[i]);
}
replace_part(begin, end, sb.c_str(), append_mode);
break;
}
}
return 0;
}

View File

@@ -1,646 +0,0 @@
/** \file builtin_complete.c Functions defining the complete builtin
Functions used for implementing the complete builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/types.h>
#include <termios.h>
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "common.h"
#include "complete.h"
#include "wgetopt.h"
#include "parser.h"
#include "reader.h"
/**
Internal storage for the builtin_get_temporary_buffer() function.
*/
static const wchar_t *temporary_buffer;
/*
builtin_complete_* are a set of rather silly looping functions that
make sure that all the proper combinations of complete_add or
complete_remove get called. This is needed since complete allows you
to specify multiple switches on a single commandline, like 'complete
-s a -s b -s c', but the complete_add function only accepts one
short switch and one long switch.
*/
/**
Silly function
*/
static void builtin_complete_add2( const wchar_t *cmd,
int cmd_type,
const wchar_t *short_opt,
array_list_t *gnu_opt,
array_list_t *old_opt,
int result_mode,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags )
{
int i;
const wchar_t *s;
for( s=short_opt; *s; s++ )
{
complete_add( cmd,
cmd_type,
*s,
0,
0,
result_mode,
condition,
comp,
desc,
flags );
}
for( i=0; i<al_get_count( gnu_opt ); i++ )
{
complete_add( cmd,
cmd_type,
0,
(wchar_t *)al_get(gnu_opt, i ),
0,
result_mode,
condition,
comp,
desc,
flags );
}
for( i=0; i<al_get_count( old_opt ); i++ )
{
complete_add( cmd,
cmd_type,
0,
(wchar_t *)al_get(old_opt, i ),
1,
result_mode,
condition,
comp,
desc,
flags );
}
if( al_get_count( old_opt )+al_get_count( gnu_opt )+wcslen(short_opt) == 0 )
{
complete_add( cmd,
cmd_type,
0,
0,
0,
result_mode,
condition,
comp,
desc,
flags );
}
}
/**
Silly function
*/
static void builtin_complete_add( array_list_t *cmd,
array_list_t *path,
const wchar_t *short_opt,
array_list_t *gnu_opt,
array_list_t *old_opt,
int result_mode,
int authoritative,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags )
{
int i;
for( i=0; i<al_get_count( cmd ); i++ )
{
builtin_complete_add2( al_get( cmd, i ),
COMMAND,
short_opt,
gnu_opt,
old_opt,
result_mode,
condition,
comp,
desc,
flags );
if( authoritative != -1 )
{
complete_set_authoritative( al_get( cmd, i ),
COMMAND,
authoritative );
}
}
for( i=0; i<al_get_count( path ); i++ )
{
builtin_complete_add2( al_get( path, i ),
PATH,
short_opt,
gnu_opt,
old_opt,
result_mode,
condition,
comp,
desc,
flags );
if( authoritative != -1 )
{
complete_set_authoritative( al_get( path, i ),
PATH,
authoritative );
}
}
}
/**
Silly function
*/
static void builtin_complete_remove3( wchar_t *cmd,
int cmd_type,
wchar_t short_opt,
array_list_t *long_opt )
{
int i;
for( i=0; i<al_get_count( long_opt ); i++ )
{
complete_remove( cmd,
cmd_type,
short_opt,
(wchar_t *)al_get( long_opt, i ) );
}
}
/**
Silly function
*/
static void builtin_complete_remove2( wchar_t *cmd,
int cmd_type,
const wchar_t *short_opt,
array_list_t *gnu_opt,
array_list_t *old_opt )
{
const wchar_t *s = (wchar_t *)short_opt;
if( *s )
{
for( ; *s; s++ )
{
if( al_get_count( old_opt) + al_get_count( gnu_opt ) == 0 )
{
complete_remove(cmd,
cmd_type,
*s,
0 );
}
else
{
builtin_complete_remove3( cmd,
cmd_type,
*s,
gnu_opt );
builtin_complete_remove3( cmd,
cmd_type,
*s,
old_opt );
}
}
}
else
{
builtin_complete_remove3( cmd,
cmd_type,
0,
gnu_opt );
builtin_complete_remove3( cmd,
cmd_type,
0,
old_opt );
}
}
/**
Silly function
*/
static void builtin_complete_remove( array_list_t *cmd,
array_list_t *path,
const wchar_t *short_opt,
array_list_t *gnu_opt,
array_list_t *old_opt )
{
int i;
for( i=0; i<al_get_count( cmd ); i++ )
{
builtin_complete_remove2( (wchar_t *)al_get( cmd, i ),
COMMAND,
short_opt,
gnu_opt,
old_opt );
}
for( i=0; i<al_get_count( path ); i++ )
{
builtin_complete_remove2( (wchar_t *)al_get( path, i ),
PATH,
short_opt,
gnu_opt,
old_opt );
}
}
const wchar_t *builtin_complete_get_temporary_buffer()
{
return temporary_buffer;
}
/**
The complete builtin. Used for specifying programmable
tab-completions. Calls the functions in complete.c for any heavy
lifting. Defined in builtin_complete.c
*/
static int builtin_complete( wchar_t **argv )
{
int res=0;
int argc=0;
int result_mode=SHARED;
int remove = 0;
int authoritative = -1;
int flags = COMPLETE_AUTO_SPACE;
string_buffer_t short_opt;
array_list_t gnu_opt, old_opt;
wchar_t *comp=L"", *desc=L"", *condition=L"";
wchar_t *do_complete = 0;
array_list_t cmd;
array_list_t path;
static int recursion_level=0;
al_init( &cmd );
al_init( &path );
sb_init( &short_opt );
al_init( &gnu_opt );
al_init( &old_opt );
argc = builtin_count_args( argv );
woptind=0;
while( res == 0 )
{
static const struct woption
long_options[] =
{
{
L"exclusive", no_argument, 0, 'x'
}
,
{
L"no-files", no_argument, 0, 'f'
}
,
{
L"require-parameter", no_argument, 0, 'r'
}
,
{
L"path", required_argument, 0, 'p'
}
,
{
L"command", required_argument, 0, 'c'
}
,
{
L"short-option", required_argument, 0, 's'
}
,
{
L"long-option", required_argument, 0, 'l'
}
,
{
L"old-option", required_argument, 0, 'o'
}
,
{
L"description", required_argument, 0, 'd'
}
,
{
L"arguments", required_argument, 0, 'a'
}
,
{
L"erase", no_argument, 0, 'e'
}
,
{
L"unauthoritative", no_argument, 0, 'u'
}
,
{
L"authoritative", no_argument, 0, 'A'
}
,
{
L"condition", required_argument, 0, 'n'
}
,
{
L"do-complete", optional_argument, 0, 'C'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
int opt_index = 0;
int opt = wgetopt_long( argc,
argv,
L"a:c:p:s:l:o:d:frxeuAn:C::h",
long_options,
&opt_index );
if( opt == -1 )
break;
switch( opt )
{
case 0:
if(long_options[opt_index].flag != 0)
break;
sb_printf( sb_err,
BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name );
builtin_print_help( argv[0], sb_err );
res = 1;
break;
case 'x':
result_mode |= EXCLUSIVE;
break;
case 'f':
result_mode |= NO_FILES;
break;
case 'r':
result_mode |= NO_COMMON;
break;
case 'p':
case 'c':
{
wchar_t *a = unescape( woptarg, 1);
if( a )
{
al_push( (opt=='p'?&path:&cmd), a );
}
else
{
sb_printf( sb_err, L"%ls: Invalid token '%ls'\n", argv[0], woptarg );
res = 1;
}
break;
}
case 'd':
desc = woptarg;
break;
case 'u':
authoritative=0;
break;
case 'A':
authoritative=1;
break;
case 's':
sb_append( &short_opt, woptarg );
break;
case 'l':
al_push( &gnu_opt, woptarg );
break;
case 'o':
al_push( &old_opt, woptarg );
break;
case 'a':
comp = woptarg;
break;
case 'e':
remove = 1;
break;
case 'n':
condition = woptarg;
break;
case 'C':
do_complete = woptarg?woptarg:reader_get_buffer();
break;
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case '?':
builtin_unknown_option( argv[0], argv[woptind-1] );
res = 1;
break;
}
}
if( !res )
{
if( condition && wcslen( condition ) )
{
if( parser_test( condition, 0, 0, 0 ) )
{
sb_printf( sb_err,
L"%ls: Condition '%ls' contained a syntax error\n",
argv[0],
condition );
parser_test( condition, 0, sb_err, argv[0] );
res = 1;
}
}
}
if( !res )
{
if( comp && wcslen( comp ) )
{
if( parser_test_args( comp, 0, 0 ) )
{
sb_printf( sb_err,
L"%ls: Completion '%ls' contained a syntax error\n",
argv[0],
comp );
parser_test_args( comp, sb_err, argv[0] );
res = 1;
}
}
}
if( !res )
{
if( do_complete )
{
array_list_t *comp;
int i;
const wchar_t *prev_temporary_buffer = temporary_buffer;
wchar_t *token;
parse_util_token_extent( do_complete, wcslen( do_complete ), &token, 0, 0, 0 );
temporary_buffer = do_complete;
if( recursion_level < 1 )
{
recursion_level++;
comp = al_halloc( 0 );
complete( do_complete, comp );
for( i=0; i<al_get_count( comp ); i++ )
{
completion_t *next = (completion_t *)al_get( comp, i );
wchar_t *prepend;
if( next->flags & COMPLETE_NO_CASE )
{
prepend = L"";
}
else
{
prepend = token;
}
if( next->description )
{
sb_printf( sb_out, L"%ls%ls\t%ls\n", prepend, next->completion, next->description );
}
else
{
sb_printf( sb_out, L"%ls%ls\n", prepend, next->completion );
}
}
halloc_free( comp );
recursion_level--;
}
temporary_buffer = prev_temporary_buffer;
}
else if( woptind != argc )
{
sb_printf( sb_err,
_( L"%ls: Too many arguments\n" ),
argv[0] );
builtin_print_help( argv[0], sb_err );
res = 1;
}
else if( (al_get_count( &cmd) == 0 ) && (al_get_count( &path) == 0 ) )
{
/* No arguments specified, meaning we print the definitions of
* all specified completions to stdout.*/
complete_print( sb_out );
}
else
{
if( remove )
{
builtin_complete_remove( &cmd,
&path,
(wchar_t *)short_opt.buff,
&gnu_opt,
&old_opt );
}
else
{
builtin_complete_add( &cmd,
&path,
(wchar_t *)short_opt.buff,
&gnu_opt,
&old_opt,
result_mode,
authoritative,
condition,
comp,
desc,
flags );
}
}
}
al_foreach( &cmd, &free );
al_foreach( &path, &free );
al_destroy( &cmd );
al_destroy( &path );
sb_destroy( &short_opt );
al_destroy( &gnu_opt );
al_destroy( &old_opt );
return res;
}

626
builtin_complete.cpp Normal file
View File

@@ -0,0 +1,626 @@
/** \file builtin_complete.c Functions defining the complete builtin
Functions used for implementing the complete builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/types.h>
#include <termios.h>
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "common.h"
#include "complete.h"
#include "wgetopt.h"
#include "parser.h"
#include "reader.h"
/**
Internal storage for the builtin_complete_get_temporary_buffer() function.
*/
static const wchar_t *temporary_buffer;
/*
builtin_complete_* are a set of rather silly looping functions that
make sure that all the proper combinations of complete_add or
complete_remove get called. This is needed since complete allows you
to specify multiple switches on a single commandline, like 'complete
-s a -s b -s c', but the complete_add function only accepts one
short switch and one long switch.
*/
/**
Silly function
*/
static void builtin_complete_add2(const wchar_t *cmd,
int cmd_type,
const wchar_t *short_opt,
const wcstring_list_t &gnu_opt,
const wcstring_list_t &old_opt,
int result_mode,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags)
{
size_t i;
const wchar_t *s;
for (s=short_opt; *s; s++)
{
complete_add(cmd,
cmd_type,
*s,
0,
0,
result_mode,
condition,
comp,
desc,
flags);
}
for (i=0; i<gnu_opt.size(); i++)
{
complete_add(cmd,
cmd_type,
0,
gnu_opt.at(i).c_str(),
0,
result_mode,
condition,
comp,
desc,
flags);
}
for (i=0; i<old_opt.size(); i++)
{
complete_add(cmd,
cmd_type,
0,
old_opt.at(i).c_str(),
1,
result_mode,
condition,
comp,
desc,
flags);
}
if (old_opt.empty() && gnu_opt.empty() && wcslen(short_opt) == 0)
{
complete_add(cmd,
cmd_type,
0,
0,
0,
result_mode,
condition,
comp,
desc,
flags);
}
}
/**
Silly function
*/
static void builtin_complete_add(const wcstring_list_t &cmd,
const wcstring_list_t &path,
const wchar_t *short_opt,
wcstring_list_t &gnu_opt,
wcstring_list_t &old_opt,
int result_mode,
int authoritative,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags)
{
for (size_t i=0; i<cmd.size(); i++)
{
builtin_complete_add2(cmd.at(i).c_str(),
COMMAND,
short_opt,
gnu_opt,
old_opt,
result_mode,
condition,
comp,
desc,
flags);
if (authoritative != -1)
{
complete_set_authoritative(cmd.at(i).c_str(),
COMMAND,
authoritative);
}
}
for (size_t i=0; i<path.size(); i++)
{
builtin_complete_add2(path.at(i).c_str(),
PATH,
short_opt,
gnu_opt,
old_opt,
result_mode,
condition,
comp,
desc,
flags);
if (authoritative != -1)
{
complete_set_authoritative(path.at(i).c_str(),
PATH,
authoritative);
}
}
}
/**
Silly function
*/
static void builtin_complete_remove3(const wchar_t *cmd,
int cmd_type,
wchar_t short_opt,
const wcstring_list_t &long_opt)
{
for (size_t i=0; i<long_opt.size(); i++)
{
complete_remove(cmd,
cmd_type,
short_opt,
long_opt.at(i).c_str());
}
}
/**
Silly function
*/
static void builtin_complete_remove2(const wchar_t *cmd,
int cmd_type,
const wchar_t *short_opt,
const wcstring_list_t &gnu_opt,
const wcstring_list_t &old_opt)
{
const wchar_t *s = (wchar_t *)short_opt;
if (*s)
{
for (; *s; s++)
{
if (old_opt.empty() && gnu_opt.empty())
{
complete_remove(cmd,
cmd_type,
*s,
0);
}
else
{
builtin_complete_remove3(cmd,
cmd_type,
*s,
gnu_opt);
builtin_complete_remove3(cmd,
cmd_type,
*s,
old_opt);
}
}
}
else
{
builtin_complete_remove3(cmd,
cmd_type,
0,
gnu_opt);
builtin_complete_remove3(cmd,
cmd_type,
0,
old_opt);
}
}
/**
Silly function
*/
static void builtin_complete_remove(const wcstring_list_t &cmd,
const wcstring_list_t &path,
const wchar_t *short_opt,
const wcstring_list_t &gnu_opt,
const wcstring_list_t &old_opt)
{
for (size_t i=0; i<cmd.size(); i++)
{
builtin_complete_remove2(cmd.at(i).c_str(),
COMMAND,
short_opt,
gnu_opt,
old_opt);
}
for (size_t i=0; i<path.size(); i++)
{
builtin_complete_remove2(path.at(i).c_str(),
PATH,
short_opt,
gnu_opt,
old_opt);
}
}
const wchar_t *builtin_complete_get_temporary_buffer()
{
ASSERT_IS_MAIN_THREAD();
return temporary_buffer;
}
/**
The complete builtin. Used for specifying programmable
tab-completions. Calls the functions in complete.c for any heavy
lifting. Defined in builtin_complete.c
*/
static int builtin_complete(parser_t &parser, wchar_t **argv)
{
ASSERT_IS_MAIN_THREAD();
bool res=false;
int argc=0;
int result_mode=SHARED;
int remove = 0;
int authoritative = -1;
int flags = COMPLETE_AUTO_SPACE;
wcstring short_opt;
wcstring_list_t gnu_opt, old_opt;
const wchar_t *comp=L"", *desc=L"", *condition=L"";
bool do_complete = false;
wcstring do_complete_param;
wcstring_list_t cmd;
wcstring_list_t path;
static int recursion_level=0;
argc = builtin_count_args(argv);
woptind=0;
while (! res)
{
static const struct woption
long_options[] =
{
{
L"exclusive", no_argument, 0, 'x'
}
,
{
L"no-files", no_argument, 0, 'f'
}
,
{
L"require-parameter", no_argument, 0, 'r'
}
,
{
L"path", required_argument, 0, 'p'
}
,
{
L"command", required_argument, 0, 'c'
}
,
{
L"short-option", required_argument, 0, 's'
}
,
{
L"long-option", required_argument, 0, 'l'
}
,
{
L"old-option", required_argument, 0, 'o'
}
,
{
L"description", required_argument, 0, 'd'
}
,
{
L"arguments", required_argument, 0, 'a'
}
,
{
L"erase", no_argument, 0, 'e'
}
,
{
L"unauthoritative", no_argument, 0, 'u'
}
,
{
L"authoritative", no_argument, 0, 'A'
}
,
{
L"condition", required_argument, 0, 'n'
}
,
{
L"do-complete", optional_argument, 0, 'C'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
int opt_index = 0;
int opt = wgetopt_long(argc,
argv,
L"a:c:p:s:l:o:d:frxeuAn:C::h",
long_options,
&opt_index);
if (opt == -1)
break;
switch (opt)
{
case 0:
if (long_options[opt_index].flag != 0)
break;
append_format(stderr_buffer,
BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name);
builtin_print_help(parser, argv[0], stderr_buffer);
res = true;
break;
case 'x':
result_mode |= EXCLUSIVE;
break;
case 'f':
result_mode |= NO_FILES;
break;
case 'r':
result_mode |= NO_COMMON;
break;
case 'p':
case 'c':
{
wcstring tmp = woptarg;
if (unescape_string(tmp, 1))
{
if (opt=='p')
path.push_back(tmp);
else
cmd.push_back(tmp);
}
else
{
append_format(stderr_buffer, L"%ls: Invalid token '%ls'\n", argv[0], woptarg);
res = true;
}
break;
}
case 'd':
desc = woptarg;
break;
case 'u':
authoritative=0;
break;
case 'A':
authoritative=1;
break;
case 's':
short_opt.append(woptarg);
break;
case 'l':
gnu_opt.push_back(woptarg);
break;
case 'o':
old_opt.push_back(woptarg);
break;
case 'a':
comp = woptarg;
break;
case 'e':
remove = 1;
break;
case 'n':
condition = woptarg;
break;
case 'C':
do_complete = true;
do_complete_param = woptarg ? woptarg : reader_get_buffer();
break;
case 'h':
builtin_print_help(parser, argv[0], stdout_buffer);
return 0;
case '?':
builtin_unknown_option(parser, argv[0], argv[woptind-1]);
res = true;
break;
}
}
if (!res)
{
if (condition && wcslen(condition))
{
if (parser.test(condition))
{
append_format(stderr_buffer,
L"%ls: Condition '%ls' contained a syntax error\n",
argv[0],
condition);
parser.test(condition, NULL, &stderr_buffer, argv[0]);
res = true;
}
}
}
if (!res)
{
if (comp && wcslen(comp))
{
if (parser.test_args(comp, 0, 0))
{
append_format(stderr_buffer,
L"%ls: Completion '%ls' contained a syntax error\n",
argv[0],
comp);
parser.test_args(comp, &stderr_buffer, argv[0]);
res = true;
}
}
}
if (!res)
{
if (do_complete)
{
const wchar_t *token;
parse_util_token_extent(do_complete_param.c_str(), do_complete_param.size(), &token, 0, 0, 0);
const wchar_t *prev_temporary_buffer = temporary_buffer;
temporary_buffer = do_complete_param.c_str();
if (recursion_level < 1)
{
recursion_level++;
std::vector<completion_t> comp;
complete(do_complete_param, comp, COMPLETION_REQUEST_DEFAULT);
for (size_t i=0; i< comp.size() ; i++)
{
const completion_t &next = comp.at(i);
const wchar_t *prepend;
if (next.flags & COMPLETE_REPLACES_TOKEN)
{
prepend = L"";
}
else
{
prepend = token;
}
if (!(next.description).empty())
{
append_format(stdout_buffer, L"%ls%ls\t%ls\n", prepend, next.completion.c_str(), next.description.c_str());
}
else
{
append_format(stdout_buffer, L"%ls%ls\n", prepend, next.completion.c_str());
}
}
recursion_level--;
}
temporary_buffer = prev_temporary_buffer;
}
else if (woptind != argc)
{
append_format(stderr_buffer,
_(L"%ls: Too many arguments\n"),
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
res = true;
}
else if (cmd.empty() && path.empty())
{
/* No arguments specified, meaning we print the definitions of
* all specified completions to stdout.*/
complete_print(stdout_buffer);
}
else
{
if (remove)
{
builtin_complete_remove(cmd,
path,
short_opt.c_str(),
gnu_opt,
old_opt);
}
else
{
builtin_complete_add(cmd,
path,
short_opt.c_str(),
gnu_opt,
old_opt,
result_mode,
authoritative,
condition,
comp,
desc,
flags);
}
}
}
return res ? 1 : 0;
}

View File

@@ -1,348 +0,0 @@
/** \file builtin_jobs.c
Functions for executing the jobs builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <wctype.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "proc.h"
#include "parser.h"
#include "common.h"
#include "wgetopt.h"
/**
Print modes for the jobs builtin
*/
enum
{
JOBS_DEFAULT, /**< Print lots of general info */
JOBS_PRINT_PID, /**< Print pid of each process in job */
JOBS_PRINT_COMMAND, /**< Print command name of each process in job */
JOBS_PRINT_GROUP, /**< Print group id of job */
}
;
#ifdef HAVE__PROC_SELF_STAT
/**
Calculates the cpu usage (in percent) of the specified job.
*/
static int cpu_use( job_t *j )
{
double u=0;
process_t *p;
for( p=j->first_process; p; p=p->next )
{
struct timeval t;
int jiffies;
gettimeofday( &t, 0 );
jiffies = proc_get_jiffies( p );
double t1 = 1000000.0*p->last_time.tv_sec+p->last_time.tv_usec;
double t2 = 1000000.0*t.tv_sec+t.tv_usec;
/* fwprintf( stderr, L"t1 %f t2 %f p1 %d p2 %d\n",
t1, t2, jiffies, p->last_jiffies );
*/
u += ((double)(jiffies-p->last_jiffies))/(t2-t1);
}
return u*1000000;
}
#endif
/**
Print information about the specified job
*/
static void builtin_jobs_print( job_t *j, int mode, int header )
{
process_t *p;
switch( mode )
{
case JOBS_DEFAULT:
{
if( header )
{
/*
Print table header before first job
*/
sb_append( sb_out, _( L"Job\tGroup\t" ));
#ifdef HAVE__PROC_SELF_STAT
sb_append( sb_out, _( L"CPU\t" ) );
#endif
sb_append( sb_out, _( L"State\tCommand\n" ) );
}
sb_printf( sb_out, L"%d\t%d\t", j->job_id, j->pgid );
#ifdef HAVE__PROC_SELF_STAT
sb_printf( sb_out, L"%d%%\t", cpu_use(j) );
#endif
sb_append( sb_out,
job_is_stopped(j)?_(L"stopped"):_(L"running"),
L"\t",
j->command,
L"\n",
(void *)0 );
break;
}
case JOBS_PRINT_GROUP:
{
if( header )
{
/*
Print table header before first job
*/
sb_append( sb_out, _( L"Group\n" ));
}
sb_printf( sb_out, L"%d\n", j->pgid );
break;
}
case JOBS_PRINT_PID:
{
if( header )
{
/*
Print table header before first job
*/
sb_append( sb_out, _( L"Procces\n" ));
}
for( p=j->first_process; p; p=p->next )
{
sb_printf( sb_out, L"%d\n", p->pid );
}
break;
}
case JOBS_PRINT_COMMAND:
{
if( header )
{
/*
Print table header before first job
*/
sb_append( sb_out, _( L"Command\n" ));
}
for( p=j->first_process; p; p=p->next )
{
sb_printf( sb_out, L"%ls\n", p->argv[0] );
}
break;
}
}
}
/**
The jobs builtin. Used fopr printing running jobs. Defined in builtin_jobs.c.
*/
static int builtin_jobs( wchar_t **argv )
{
int argc=0;
int found=0;
int mode=JOBS_DEFAULT;
int print_last = 0;
job_t *j;
argc = builtin_count_args( argv );
woptind=0;
while( 1 )
{
static const struct woption
long_options[] =
{
{
L"pid", no_argument, 0, 'p'
}
,
{
L"command", no_argument, 0, 'c'
}
,
{
L"group", no_argument, 0, 'g'
}
,
{
L"last", no_argument, 0, 'l'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
int opt_index = 0;
int opt = wgetopt_long( argc,
argv,
L"pclgh",
long_options,
&opt_index );
if( opt == -1 )
break;
switch( opt )
{
case 0:
if(long_options[opt_index].flag != 0)
break;
sb_printf( sb_err,
BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name );
builtin_print_help( argv[0], sb_err );
return 1;
case 'p':
mode=JOBS_PRINT_PID;
break;
case 'c':
mode=JOBS_PRINT_COMMAND;
break;
case 'g':
mode=JOBS_PRINT_GROUP;
break;
case 'l':
{
print_last = 1;
break;
}
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case '?':
builtin_unknown_option( argv[0], argv[woptind-1] );
return 1;
}
}
/*
Do not babble if not interactive
*/
if( builtin_out_redirect )
{
found=1;
}
if( print_last )
{
/*
Ignore unconstructed jobs, i.e. ourself.
*/
for( j=first_job; j; j=j->next )
{
if( (j->flags & JOB_CONSTRUCTED) && !job_is_completed(j) )
{
builtin_jobs_print( j, mode, !found );
return 0;
}
}
}
else
{
if( woptind < argc )
{
int i;
found = 1;
for( i=woptind; i<argc; i++ )
{
long pid;
wchar_t *end;
errno=0;
pid=wcstol( argv[i], &end, 10 );
if( errno || *end )
{
sb_printf( sb_err,
_( L"%ls: '%ls' is not a job\n" ),
argv[0],
argv[i] );
return 1;
}
j = job_get_from_pid( pid );
if( j && !job_is_completed( j ) )
{
builtin_jobs_print( j, mode, !found );
}
else
{
sb_printf( sb_err,
_( L"%ls: No suitable job: %d\n" ),
argv[0],
pid );
return 1;
}
}
}
else
{
for( j= first_job; j; j=j->next )
{
/*
Ignore unconstructed jobs, i.e. ourself.
*/
if( (j->flags & JOB_CONSTRUCTED) && !job_is_completed(j) )
{
builtin_jobs_print( j, mode, !found );
found = 1;
}
}
}
}
if( !found )
{
sb_printf( sb_out,
_( L"%ls: There are no jobs\n" ),
argv[0] );
}
return 0;
}

351
builtin_jobs.cpp Normal file
View File

@@ -0,0 +1,351 @@
/** \file builtin_jobs.c
Functions for executing the jobs builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <wctype.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "proc.h"
#include "parser.h"
#include "common.h"
#include "wgetopt.h"
/**
Print modes for the jobs builtin
*/
enum
{
JOBS_DEFAULT, /**< Print lots of general info */
JOBS_PRINT_PID, /**< Print pid of each process in job */
JOBS_PRINT_COMMAND, /**< Print command name of each process in job */
JOBS_PRINT_GROUP, /**< Print group id of job */
}
;
#ifdef HAVE__PROC_SELF_STAT
/**
Calculates the cpu usage (in percent) of the specified job.
*/
static int cpu_use(const job_t *j)
{
double u=0;
process_t *p;
for (p=j->first_process; p; p=p->next)
{
struct timeval t;
int jiffies;
gettimeofday(&t, 0);
jiffies = proc_get_jiffies(p);
double t1 = 1000000.0*p->last_time.tv_sec+p->last_time.tv_usec;
double t2 = 1000000.0*t.tv_sec+t.tv_usec;
/* fwprintf( stderr, L"t1 %f t2 %f p1 %d p2 %d\n",
t1, t2, jiffies, p->last_jiffies );
*/
u += ((double)(jiffies-p->last_jiffies))/(t2-t1);
}
return u*1000000;
}
#endif
/**
Print information about the specified job
*/
static void builtin_jobs_print(const job_t *j, int mode, int header)
{
process_t *p;
switch (mode)
{
case JOBS_DEFAULT:
{
if (header)
{
/*
Print table header before first job
*/
stdout_buffer.append(_(L"Job\tGroup\t"));
#ifdef HAVE__PROC_SELF_STAT
stdout_buffer.append(_(L"CPU\t"));
#endif
stdout_buffer.append(_(L"State\tCommand\n"));
}
append_format(stdout_buffer, L"%d\t%d\t", j->job_id, j->pgid);
#ifdef HAVE__PROC_SELF_STAT
append_format(stdout_buffer, L"%d%%\t", cpu_use(j));
#endif
stdout_buffer.append(job_is_stopped(j)?_(L"stopped"):_(L"running"));
stdout_buffer.append(L"\t");
stdout_buffer.append(j->command_wcstr());
stdout_buffer.append(L"\n");
break;
}
case JOBS_PRINT_GROUP:
{
if (header)
{
/*
Print table header before first job
*/
stdout_buffer.append(_(L"Group\n"));
}
append_format(stdout_buffer, L"%d\n", j->pgid);
break;
}
case JOBS_PRINT_PID:
{
if (header)
{
/*
Print table header before first job
*/
stdout_buffer.append(_(L"Procces\n"));
}
for (p=j->first_process; p; p=p->next)
{
append_format(stdout_buffer, L"%d\n", p->pid);
}
break;
}
case JOBS_PRINT_COMMAND:
{
if (header)
{
/*
Print table header before first job
*/
stdout_buffer.append(_(L"Command\n"));
}
for (p=j->first_process; p; p=p->next)
{
append_format(stdout_buffer, L"%ls\n", p->argv0());
}
break;
}
}
}
/**
The jobs builtin. Used fopr printing running jobs. Defined in builtin_jobs.c.
*/
static int builtin_jobs(parser_t &parser, wchar_t **argv)
{
int argc=0;
int found=0;
int mode=JOBS_DEFAULT;
int print_last = 0;
const job_t *j;
argc = builtin_count_args(argv);
woptind=0;
while (1)
{
static const struct woption
long_options[] =
{
{
L"pid", no_argument, 0, 'p'
}
,
{
L"command", no_argument, 0, 'c'
}
,
{
L"group", no_argument, 0, 'g'
}
,
{
L"last", no_argument, 0, 'l'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
int opt_index = 0;
int opt = wgetopt_long(argc,
argv,
L"pclgh",
long_options,
&opt_index);
if (opt == -1)
break;
switch (opt)
{
case 0:
if (long_options[opt_index].flag != 0)
break;
append_format(stderr_buffer,
BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
case 'p':
mode=JOBS_PRINT_PID;
break;
case 'c':
mode=JOBS_PRINT_COMMAND;
break;
case 'g':
mode=JOBS_PRINT_GROUP;
break;
case 'l':
{
print_last = 1;
break;
}
case 'h':
builtin_print_help(parser, argv[0], stdout_buffer);
return 0;
case '?':
builtin_unknown_option(parser, argv[0], argv[woptind-1]);
return 1;
}
}
/*
Do not babble if not interactive
*/
if (builtin_out_redirect)
{
found=1;
}
if (print_last)
{
/*
Ignore unconstructed jobs, i.e. ourself.
*/
job_iterator_t jobs;
const job_t *j;
while ((j = jobs.next()))
{
if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j))
{
builtin_jobs_print(j, mode, !found);
return 0;
}
}
}
else
{
if (woptind < argc)
{
int i;
found = 1;
for (i=woptind; i<argc; i++)
{
int pid;
wchar_t *end;
errno=0;
pid=fish_wcstoi(argv[i], &end, 10);
if (errno || *end)
{
append_format(stderr_buffer,
_(L"%ls: '%ls' is not a job\n"),
argv[0],
argv[i]);
return 1;
}
j = job_get_from_pid(pid);
if (j && !job_is_completed(j))
{
builtin_jobs_print(j, mode, !found);
}
else
{
append_format(stderr_buffer,
_(L"%ls: No suitable job: %d\n"),
argv[0],
pid);
return 1;
}
}
}
else
{
job_iterator_t jobs;
const job_t *j;
while ((j = jobs.next()))
{
/*
Ignore unconstructed jobs, i.e. ourself.
*/
if ((j->flags & JOB_CONSTRUCTED) && !job_is_completed(j))
{
builtin_jobs_print(j, mode, !found);
found = 1;
}
}
}
}
if (!found)
{
append_format(stdout_buffer,
_(L"%ls: There are no jobs\n"),
argv[0]);
}
return 0;
}

777
builtin_printf.cpp Normal file
View File

@@ -0,0 +1,777 @@
/* printf - format and print data
Copyright (C) 1990-2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Usage: printf format [argument...]
A front end to the printf function that lets it be used from the shell.
Backslash escapes:
\" = double quote
\\ = backslash
\a = alert (bell)
\b = backspace
\c = produce no further output
\f = form feed
\n = new line
\r = carriage return
\t = horizontal tab
\v = vertical tab
\ooo = octal number (ooo is 1 to 3 digits)
\xhh = hexadecimal number (hhh is 1 to 2 digits)
\uhhhh = 16-bit Unicode character (hhhh is 4 digits)
\Uhhhhhhhh = 32-bit Unicode character (hhhhhhhh is 8 digits)
Additional directive:
%b = print an argument string, interpreting backslash escapes,
except that octal escapes are of the form \0 or \0ooo.
The `format' argument is re-used as many times as necessary
to convert all of the given arguments.
David MacKenzie <djm@gnu.ai.mit.edu> */
/* This file has been imported from source code of printf command in GNU Coreutils version 6.9 */
#include <stdio.h>
#include <sys/types.h>
#include <inttypes.h>
#include "common.h"
struct builtin_printf_state_t
{
/* The status of the operation */
int exit_code;
/* Whether we should stop outputting. This gets set in the case of an error, and also with the \c escape. */
bool early_exit;
builtin_printf_state_t() : exit_code(0), early_exit(false)
{
}
void verify_numeric(const wchar_t *s, const wchar_t *end, int errcode);
void print_direc(const wchar_t *start, size_t length, wchar_t conversion,
bool have_field_width, int field_width,
bool have_precision, int precision,
wchar_t const *argument);
int print_formatted(const wchar_t *format, int argc, wchar_t **argv);
void fatal_error(const wchar_t *format, ...);
long print_esc(const wchar_t *escstart, bool octal_0);
void print_esc_string(const wchar_t *str);
void print_esc_char(wchar_t c);
void append_output(wchar_t c);
void append_output(const wchar_t *c);
void append_format_output(const wchar_t *fmt, ...);
};
static bool is_octal_digit(wchar_t c)
{
return c != L'\0' && wcschr(L"01234567", c) != NULL;
}
static bool is_hex_digit(wchar_t c)
{
return c != L'\0' && wcschr(L"0123456789ABCDEFabcdef", c) != NULL;
}
static int hex_to_bin(const wchar_t &c)
{
switch (c)
{
case L'0':
return 0;
case L'1':
return 1;
case L'2':
return 2;
case L'3':
return 3;
case L'4':
return 4;
case L'5':
return 5;
case L'6':
return 6;
case L'7':
return 7;
case L'8':
return 8;
case L'9':
return 9;
case L'a':
case L'A':
return 10;
case L'b':
case L'B':
return 11;
case L'c':
case L'C':
return 12;
case L'd':
case L'D':
return 13;
case L'e':
case L'E':
return 14;
case L'f':
case L'F':
return 15;
default:
return -1;
}
}
static int octal_to_bin(wchar_t c)
{
switch (c)
{
case L'0':
return 0;
case L'1':
return 1;
case L'2':
return 2;
case L'3':
return 3;
case L'4':
return 4;
case L'5':
return 5;
case L'6':
return 6;
case L'7':
return 7;
default:
return -1;
}
}
/* This message appears in N_() here rather than just in _() below because
the sole use would have been in a #define. */
static wchar_t const *const cfcc_msg =
N_(L"warning: %ls: character(s) following character constant have been ignored");
double C_STRTOD(wchar_t const *nptr, wchar_t **endptr)
{
double r;
const wcstring saved_locale = wsetlocale(LC_NUMERIC, NULL);
if (!saved_locale.empty())
{
wsetlocale(LC_NUMERIC, L"C");
}
r = wcstod(nptr, endptr);
if (!saved_locale.empty())
{
wsetlocale(LC_NUMERIC, saved_locale.c_str());
}
return r;
}
static inline unsigned wchar_t to_uwchar_t(wchar_t ch)
{
return ch;
}
void builtin_printf_state_t::fatal_error(const wchar_t *fmt, ...)
{
// Don't error twice
if (early_exit)
return;
va_list va;
va_start(va, fmt);
wcstring errstr = vformat_string(fmt, va);
va_end(va);
stderr_buffer.append(errstr);
if (! string_suffixes_string(L"\n", errstr))
stderr_buffer.push_back(L'\n');
this->exit_code = STATUS_BUILTIN_ERROR;
this->early_exit = true;
}
void builtin_printf_state_t::append_output(wchar_t c)
{
// Don't output if we're done
if (early_exit)
return;
stdout_buffer.push_back(c);
}
void builtin_printf_state_t::append_output(const wchar_t *c)
{
// Don't output if we're done
if (early_exit)
return;
stdout_buffer.append(c);
}
void builtin_printf_state_t::append_format_output(const wchar_t *fmt, ...)
{
// Don't output if we're done
if (early_exit)
return;
va_list va;
va_start(va, fmt);
append_formatv(stdout_buffer, fmt, va);
va_end(va);
}
void builtin_printf_state_t::verify_numeric(const wchar_t *s, const wchar_t *end, int errcode)
{
if (errcode != 0)
{
this->fatal_error(L"%ls: %s", s, strerror(errcode));
}
else if (*end)
{
if (s == end)
this->fatal_error(_(L"%ls: expected a numeric value"), s);
else
this->fatal_error(_(L"%ls: value not completely converted"), s);
}
}
template<typename T>
static T raw_string_to_scalar_type(const wchar_t *s, wchar_t ** end);
// we use wcstoll instead of wcstoimax because FreeBSD 8 has busted wcstoumax and wcstoimax - see #626
template<>
intmax_t raw_string_to_scalar_type(const wchar_t *s, wchar_t ** end)
{
return wcstoll(s, end, 0);
}
template<>
uintmax_t raw_string_to_scalar_type(const wchar_t *s, wchar_t ** end)
{
return wcstoull(s, end, 0);
}
template<>
long double raw_string_to_scalar_type(const wchar_t *s, wchar_t ** end)
{
return C_STRTOD(s, end);
}
template<typename T>
static T string_to_scalar_type(const wchar_t *s, builtin_printf_state_t *state)
{
T val;
if (*s == L'\"' || *s == L'\'')
{
unsigned wchar_t ch = *++s;
val = ch;
}
else
{
wchar_t *end = NULL;
errno = 0;
val = raw_string_to_scalar_type<T>(s, &end);
state->verify_numeric(s, end, errno);
}
return val;
}
/* Output a single-character \ escape. */
void builtin_printf_state_t::print_esc_char(wchar_t c)
{
switch (c)
{
case L'a': /* Alert. */
this->append_output(L'\a');
break;
case L'b': /* Backspace. */
this->append_output(L'\b');
break;
case L'c': /* Cancel the rest of the output. */
this->early_exit = true;
break;
case L'f': /* Form feed. */
this->append_output(L'\f');
break;
case L'n': /* New line. */
this->append_output(L'\n');
break;
case L'r': /* Carriage return. */
this->append_output(L'\r');
break;
case L't': /* Horizontal tab. */
this->append_output(L'\t');
break;
case L'v': /* Vertical tab. */
this->append_output(L'\v');
break;
default:
this->append_output(c);
break;
}
}
/* Print a \ escape sequence starting at ESCSTART.
Return the number of characters in the escape sequence
besides the backslash.
If OCTAL_0 is nonzero, octal escapes are of the form \0ooo, where o
is an octal digit; otherwise they are of the form \ooo. */
long builtin_printf_state_t::print_esc(const wchar_t *escstart, bool octal_0)
{
const wchar_t *p = escstart + 1;
int esc_value = 0; /* Value of \nnn escape. */
int esc_length; /* Length of \nnn escape. */
if (*p == L'x')
{
/* A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits. */
for (esc_length = 0, ++p; esc_length < 2 && is_hex_digit(*p); ++esc_length, ++p)
esc_value = esc_value * 16 + hex_to_bin(*p);
if (esc_length == 0)
this->fatal_error(_(L"missing hexadecimal number in escape"));
this->append_format_output(L"%lc", esc_value);
}
else if (is_octal_digit(*p))
{
/* Parse \0ooo (if octal_0 && *p == L'0') or \ooo (otherwise).
Allow \ooo if octal_0 && *p != L'0'; this is an undocumented
extension to POSIX that is compatible with Bash 2.05b. */
for (esc_length = 0, p += octal_0 && *p == L'0'; esc_length < 3 && is_octal_digit(*p); ++esc_length, ++p)
esc_value = esc_value * 8 + octal_to_bin(*p);
this->append_format_output(L"%c", esc_value);
}
else if (*p && wcschr(L"\"\\abcfnrtv", *p))
print_esc_char(*p++);
else if (*p == L'u' || *p == L'U')
{
wchar_t esc_char = *p;
p++;
uint32_t uni_value = 0;
for (size_t esc_length = 0; esc_length < (esc_char == L'u' ? 4 : 8); esc_length++)
{
if (! is_hex_digit(*p))
{
/* Escape sequence must be done. Complain if we didn't get anything */
if (esc_length == 0)
{
this->fatal_error(_(L"Missing hexadecimal number in Unicode escape"));
}
break;
}
uni_value = uni_value * 16 + hex_to_bin(*p);
p++;
}
/* PCA GNU printf respects the limitations described in ISO N717, about which universal characters "shall not" be specified. I believe this limitation is for the benefit of compilers; I see no reason to impose it in builtin_printf.
If __STDC_ISO_10646__ is defined, then it means wchar_t can and does hold Unicode code points, so just use that. If not defined, use the %lc printf conversion; this probably won't do anything good if your wide character set is not Unicode, but such platforms are exceedingly rare.
*/
if (uni_value > 0x10FFFF)
{
this->fatal_error(_(L"Unicode character out of range: \\%c%0*x"), esc_char, (esc_char == L'u' ? 4 : 8), uni_value);
}
else
{
#if defined(__STDC_ISO_10646__)
this->append_output(uni_value);
#else
this->append_format_output(L"%lc", uni_value);
#endif
}
}
else
{
this->append_output(L'\\');
if (*p)
{
this->append_output(*p);
p++;
}
}
return p - escstart - 1;
}
/* Print string STR, evaluating \ escapes. */
void builtin_printf_state_t::print_esc_string(const wchar_t *str)
{
for (; *str; str++)
if (*str == L'\\')
str += print_esc(str, true);
else
this->append_output(*str);
}
/* Evaluate a printf conversion specification. START is the start of
the directive, LENGTH is its length, and CONVERSION specifies the
type of conversion. LENGTH does not include any length modifier or
the conversion specifier itself. FIELD_WIDTH and PRECISION are the
field width and precision for '*' values, if HAVE_FIELD_WIDTH and
HAVE_PRECISION are true, respectively. ARGUMENT is the argument to
be formatted. */
void builtin_printf_state_t::print_direc(const wchar_t *start, size_t length, wchar_t conversion,
bool have_field_width, int field_width,
bool have_precision, int precision,
wchar_t const *argument)
{
// Start with everything except the conversion specifier
wcstring fmt(start, length);
/* Create a copy of the % directive, with an intmax_t-wide width modifier substituted for any existing integer length modifier. */
switch (conversion)
{
case L'd':
case L'i':
case L'u':
fmt.append(L"ll");
break;
case L'a':
case L'e':
case L'f':
case L'g':
case L'A':
case L'E':
case L'F':
case L'G':
fmt.append(L"L");
break;
case L's':
fmt.append(L"l");
break;
default:
break;
}
// Append the conversion itself
fmt.push_back(conversion);
switch (conversion)
{
case L'd':
case L'i':
{
intmax_t arg = string_to_scalar_type<intmax_t>(argument, this);
if (! have_field_width)
{
if (! have_precision)
this->append_format_output(fmt.c_str(), arg);
else
this->append_format_output(fmt.c_str(), precision, arg);
}
else
{
if (! have_precision)
this->append_format_output(fmt.c_str(), field_width, arg);
else
this->append_format_output(fmt.c_str(), field_width, precision, arg);
}
}
break;
case L'o':
case L'u':
case L'x':
case L'X':
{
uintmax_t arg = string_to_scalar_type<uintmax_t>(argument, this);
if (!have_field_width)
{
if (!have_precision)
this->append_format_output(fmt.c_str(), arg);
else
this->append_format_output(fmt.c_str(), precision, arg);
}
else
{
if (!have_precision)
this->append_format_output(fmt.c_str(), field_width, arg);
else
this->append_format_output(fmt.c_str(), field_width, precision, arg);
}
}
break;
case L'a':
case L'A':
case L'e':
case L'E':
case L'f':
case L'F':
case L'g':
case L'G':
{
long double arg = string_to_scalar_type<long double>(argument, this);
if (!have_field_width)
{
if (!have_precision)
this->append_format_output(fmt.c_str(), arg);
else
this->append_format_output(fmt.c_str(), precision, arg);
}
else
{
if (!have_precision)
this->append_format_output(fmt.c_str(), field_width, arg);
else
this->append_format_output(fmt.c_str(), field_width, precision, arg);
}
}
break;
case L'c':
if (!have_field_width)
this->append_format_output(fmt.c_str(), *argument);
else
this->append_format_output(fmt.c_str(), field_width, *argument);
break;
case L's':
if (!have_field_width)
{
if (!have_precision)
{
this->append_format_output(fmt.c_str(), argument);
}
else
this->append_format_output(fmt.c_str(), precision, argument);
}
else
{
if (!have_precision)
this->append_format_output(fmt.c_str(), field_width, argument);
else
this->append_format_output(fmt.c_str(), field_width, precision, argument);
}
break;
}
}
/* Print the text in FORMAT, using ARGV (with ARGC elements) for
arguments to any `%' directives.
Return the number of elements of ARGV used. */
int builtin_printf_state_t::print_formatted(const wchar_t *format, int argc, wchar_t **argv)
{
int save_argc = argc; /* Preserve original value. */
const wchar_t *f; /* Pointer into `format'. */
const wchar_t *direc_start; /* Start of % directive. */
size_t direc_length; /* Length of % directive. */
bool have_field_width; /* True if FIELD_WIDTH is valid. */
int field_width = 0; /* Arg to first '*'. */
bool have_precision; /* True if PRECISION is valid. */
int precision = 0; /* Arg to second '*'. */
bool ok[UCHAR_MAX + 1] = { }; /* ok['x'] is true if %x is allowed. */
for (f = format; *f != L'\0'; ++f)
{
switch (*f)
{
case L'%':
direc_start = f++;
direc_length = 1;
have_field_width = have_precision = false;
if (*f == L'%')
{
this->append_output(L'%');
break;
}
if (*f == L'b')
{
/* FIXME: Field width and precision are not supported
for %b, even though POSIX requires it. */
if (argc > 0)
{
print_esc_string(*argv);
++argv;
--argc;
}
break;
}
ok['a'] = ok['A'] = ok['c'] = ok['d'] = ok['e'] = ok['E'] =
ok['f'] = ok['F'] = ok['g'] = ok['G'] = ok['i'] = ok['o'] =
ok['s'] = ok['u'] = ok['x'] = ok['X'] = true;
for (;; f++, direc_length++)
{
switch (*f)
{
case L'I':
case L'\'':
ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] =
ok['o'] = ok['s'] = ok['x'] = ok['X'] = false;
break;
case '-':
case '+':
case ' ':
break;
case L'#':
ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = false;
break;
case '0':
ok['c'] = ok['s'] = false;
break;
default:
goto no_more_flag_characters;
}
}
no_more_flag_characters:
;
if (*f == L'*')
{
++f;
++direc_length;
if (argc > 0)
{
intmax_t width = string_to_scalar_type<intmax_t>(*argv, this);
if (INT_MIN <= width && width <= INT_MAX)
field_width = static_cast<int>(width);
else
this->fatal_error(_(L"invalid field width: %ls"), *argv);
++argv;
--argc;
}
else
{
field_width = 0;
}
have_field_width = true;
}
else
{
while (iswdigit(*f))
{
++f;
++direc_length;
}
}
if (*f == L'.')
{
++f;
++direc_length;
ok['c'] = false;
if (*f == L'*')
{
++f;
++direc_length;
if (argc > 0)
{
intmax_t prec = string_to_scalar_type<intmax_t>(*argv, this);
if (prec < 0)
{
/* A negative precision is taken as if the
precision were omitted, so -1 is safe
here even if prec < INT_MIN. */
precision = -1;
}
else if (INT_MAX < prec)
this->fatal_error(_(L"invalid precision: %ls"), *argv);
else
{
precision = static_cast<int>(prec);
}
++argv;
--argc;
}
else
{
precision = 0;
}
have_precision = true;
}
else
{
while (iswdigit(*f))
{
++f;
++direc_length;
}
}
}
while (*f == L'l' || *f == L'L' || *f == L'h' || *f == L'j' || *f == L't' || *f == L'z')
++f;
{
unsigned wchar_t conversion = *f;
if (! ok[conversion])
{
this->fatal_error(_(L"%.*ls: invalid conversion specification"), (int)(f + 1 - direc_start), direc_start);
return 0;
}
}
print_direc(direc_start, direc_length, *f,
have_field_width, field_width,
have_precision, precision,
(argc <= 0 ? L"" : (argc--, *argv++)));
break;
case L'\\':
f += print_esc(f, false);
break;
default:
this->append_output(*f);
}
}
return save_argc - argc;
}
static int builtin_printf(parser_t &parser, wchar_t **argv)
{
builtin_printf_state_t state;
wchar_t *format;
int args_used;
int argc = builtin_count_args(argv);
if (argc <= 1)
{
state.fatal_error(_(L"printf: not enough arguments"));
return STATUS_BUILTIN_ERROR;
}
format = argv[1];
argc -= 2;
argv += 2;
do
{
args_used = state.print_formatted(format, argc, argv);
argc -= args_used;
argv += args_used;
}
while (args_used > 0 && argc > 0 && ! state.early_exit);
return state.exit_code;
}

View File

@@ -1,879 +0,0 @@
/** \file builtin_set.c Functions defining the set builtin
Functions used for implementing the set builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/types.h>
#include <termios.h>
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "env.h"
#include "expand.h"
#include "common.h"
#include "wgetopt.h"
#include "proc.h"
#include "parser.h"
/**
Error message for invalid path operations
*/
#define BUILTIN_SET_PATH_ERROR L"%ls: Could not add component %ls to %ls.\n"
/**
Hint for invalid path operation with a colon
*/
#define BUILTIN_SET_PATH_HINT L"%ls: Did you mean 'set %ls $%ls %ls'?\n"
/**
Error for mismatch between index count and elements
*/
#define BUILTIN_SET_ARG_COUNT L"%ls: The number of variable indexes does not match the number of values\n"
/**
Test if the specified variable should be subject to path validation
*/
static int is_path_variable( const wchar_t *env )
{
return contains( env,
L"PATH",
L"CDPATH" );
}
/**
Call env_set. If this is a path variable, e.g. PATH, validate the
elements. On error, print a description of the problem to stderr.
*/
static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
{
string_buffer_t sb;
int i;
int retcode = 0;
wchar_t *val_str=0;
if( is_path_variable( key ) )
{
int error = 0;
for( i=0; i<al_get_count( val ); i++ )
{
int show_perror = 0;
int show_hint = 0;
struct stat buff;
wchar_t *dir = (wchar_t *)al_get( val, i );
if( wstat( dir, &buff ) )
{
error = 1;
show_perror = 1;
}
if( !( S_ISDIR(buff.st_mode) ) )
{
error = 1;
}
if( error )
{
wchar_t *colon;
sb_printf( sb_err,
_(BUILTIN_SET_PATH_ERROR),
L"set",
dir,
key );
colon = wcschr( dir, L':' );
if( colon && *(colon+1) )
{
show_hint = 1;
}
}
if( show_perror )
{
builtin_wperror( L"set" );
}
if( show_hint )
{
sb_printf( sb_err,
_(BUILTIN_SET_PATH_HINT),
L"set",
key,
key,
wcschr( dir, L':' )+1);
}
if( error )
{
break;
}
}
if( error )
{
return 1;
}
}
sb_init( &sb );
if( al_get_count( val ) )
{
for( i=0; i<al_get_count( val ); i++ )
{
wchar_t *next =(wchar_t *)al_get( val, i );
sb_append( &sb, next?next:L"" );
if( i<al_get_count( val )-1 )
{
sb_append( &sb, ARRAY_SEP_STR );
}
}
val_str = (wchar_t *)sb.buff;
}
switch( env_set( key, val_str, scope | ENV_USER ) )
{
case ENV_PERM:
{
sb_printf( sb_err, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key );
retcode=1;
break;
}
case ENV_INVALID:
{
sb_printf( sb_err, _(L"%ls: Unknown error"), L"set" );
retcode=1;
break;
}
}
sb_destroy( &sb );
return retcode;
}
/**
Extract indexes from a destination argument of the form name[index1 index2...]
\param indexes the list to insert the new indexes into
\param src the source string to parse
\param name the name of the element. Return null if the name in \c src does not match this name
\param var_count the number of elements in the array to parse.
\return the total number of indexes parsed, or -1 on error
*/
static int parse_index( array_list_t *indexes,
const wchar_t *src,
const wchar_t *name,
int var_count )
{
int len;
int count = 0;
const wchar_t *src_orig = src;
if (src == 0)
{
return 0;
}
while (*src != L'\0' && (iswalnum(*src) || *src == L'_'))
{
src++;
}
if (*src != L'[')
{
sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), L"set" );
return 0;
}
len = src-src_orig;
if( (wcsncmp( src_orig, name, len )!=0) || (wcslen(name) != (len)) )
{
sb_printf( sb_err,
_(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"),
L"set",
name,
len,
src_orig);
return 0;
}
src++;
while (iswspace(*src))
{
src++;
}
while (*src != L']')
{
wchar_t *end;
long l_ind;
errno = 0;
l_ind = wcstol(src, &end, 10);
if( end==src || errno )
{
sb_printf(sb_err, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
return 0;
}
if( l_ind < 0 )
{
l_ind = var_count+l_ind+1;
}
al_push_long(indexes, l_ind);
src = end;
count++;
while (iswspace(*src)) src++;
}
return count;
}
/**
Update a list \c list by writing copies (using wcsdup) of the
values specified by \c values to the indexes specified by \c
indexes. The previous entries at the specidied position will be
free'd.
\return 0 if the operation was successfull, non-zero otherwise
*/
static int update_values( array_list_t *list,
array_list_t *indexes,
array_list_t *values )
{
int i;
/* Replace values where needed */
for( i = 0; i < al_get_count(indexes); i++ )
{
/*
The '- 1' below is because the indices in fish are
one-based, but the array_list_t uses zero-based indices
*/
long ind = al_get_long(indexes, i) - 1;
void *new = (void *) al_get(values, i);
if( ind < 0 )
{
return 1;
}
free((void *) al_get(list, ind));
al_set(list, ind, new != 0 ? wcsdup(new) : wcsdup(L""));
}
return 0;
}
/**
Return 1 if an array list of longs contains the specified
value, 0 otherwise
*/
static int al_contains_long( array_list_t *list,
long val)
{
int i;
for (i = 0; i < al_get_count(list); i++)
{
long current = al_get_long(list, i);
if( current != 0 && current == val )
{
return 1;
}
}
return 0;
}
/**
Erase from a list values at specified indexes
*/
static void erase_values(array_list_t *list, array_list_t *indexes)
{
long i;
array_list_t result;
al_init(&result);
for (i = 0; i < al_get_count(list); i++)
{
if (!al_contains_long(indexes, i + 1))
{
al_push(&result, al_get(list, i));
}
else
{
free( (void *)al_get(list, i));
}
}
al_truncate(list,0);
al_push_all( list, &result );
al_destroy(&result);
}
/**
Print the names of all environment variables in the scope, with or without values,
with or without escaping
*/
static void print_variables(int include_values, int esc, int scope)
{
array_list_t names;
int i;
al_init( &names );
env_get_names( &names, scope );
sort_list( &names );
for( i = 0; i < al_get_count(&names); i++ )
{
wchar_t *key = (wchar_t *)al_get( &names, i );
wchar_t *e_key = esc ? escape(key, 0) : wcsdup(key);
sb_append(sb_out, e_key);
if( include_values )
{
wchar_t *value = env_get(key);
wchar_t *e_value;
if( value )
{
int shorten = 0;
if( wcslen( value ) > 64 )
{
shorten = 1;
value = wcsndup( value, 60 );
if( !value )
{
DIE_MEM();
}
}
e_value = esc ? expand_escape_variable(value) : wcsdup(value);
sb_append(sb_out, L" ", e_value, (void *)0);
free(e_value);
if( shorten )
{
sb_append(sb_out, L"\u2026");
free( value );
}
}
}
sb_append(sb_out, L"\n");
free(e_key);
}
al_destroy(&names);
}
/**
The set builtin. Creates, updates and erases environment variables
and environemnt variable arrays.
*/
static int builtin_set( wchar_t **argv )
{
/**
Variables used for parsing the argument list
*/
static const struct woption
long_options[] =
{
{
L"export", no_argument, 0, 'x'
}
,
{
L"global", no_argument, 0, 'g'
}
,
{
L"local", no_argument, 0, 'l'
}
,
{
L"erase", no_argument, 0, 'e'
}
,
{
L"names", no_argument, 0, 'n'
}
,
{
L"unexport", no_argument, 0, 'u'
}
,
{
L"universal", no_argument, 0, 'U'
}
,
{
L"query", no_argument, 0, 'q'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
const wchar_t *short_options = L"+xglenuUqh";
int argc = builtin_count_args(argv);
/*
Flags to set the work mode
*/
int local = 0, global = 0, export = 0;
int erase = 0, list = 0, unexport=0;
int universal = 0, query=0;
/*
Variables used for performing the actual work
*/
wchar_t *dest = 0;
int retcode=0;
int scope;
int slice=0;
int i;
wchar_t *bad_char;
/* Parse options to obtain the requested operation and the modifiers */
woptind = 0;
while (1)
{
int c = wgetopt_long(argc, argv, short_options, long_options, 0);
if (c == -1)
{
break;
}
switch(c)
{
case 0:
break;
case 'e':
erase = 1;
break;
case 'n':
list = 1;
break;
case 'x':
export = 1;
break;
case 'l':
local = 1;
break;
case 'g':
global = 1;
break;
case 'u':
unexport = 1;
break;
case 'U':
universal = 1;
break;
case 'q':
query = 1;
break;
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case '?':
builtin_unknown_option( argv[0], argv[woptind-1] );
return 1;
default:
break;
}
}
/*
Ok, all arguments have been parsed, let's validate them
*/
/*
If we are checking the existance of a variable (-q) we can not
also specify scope
*/
if( query && (erase || list || global || local || universal || export || unexport ) )
{
sb_printf(sb_err,
BUILTIN_ERR_COMBO,
argv[0] );
builtin_print_help( argv[0], sb_err );
return 1;
}
/* We can't both list and erase varaibles */
if( erase && list )
{
sb_printf(sb_err,
BUILTIN_ERR_COMBO,
argv[0] );
builtin_print_help( argv[0], sb_err );
return 1;
}
/*
Variables can only have one scope
*/
if( local + global + universal > 1 )
{
sb_printf( sb_err,
BUILTIN_ERR_GLOCAL,
argv[0] );
builtin_print_help( argv[0], sb_err );
return 1;
}
/*
Variables can only have one export status
*/
if( export && unexport )
{
sb_printf( sb_err,
BUILTIN_ERR_EXPUNEXP,
argv[0] );
builtin_print_help( argv[0], sb_err );
return 1;
}
/*
Calculate the scope value for variable assignement
*/
scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (export ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
if( query )
{
/*
Query mode. Return the number of variables that do not exist
out of the specified variables.
*/
int i;
for( i=woptind; i<argc; i++ )
{
wchar_t *arg = argv[i];
int slice=0;
if( !(dest = wcsdup(arg)))
{
DIE_MEM();
}
if( wcschr( dest, L'[' ) )
{
slice = 1;
*wcschr( dest, L'[' )=0;
}
if( slice )
{
array_list_t indexes;
array_list_t result;
int j;
al_init( &result );
al_init( &indexes );
tokenize_variable_array( env_get( dest ), &result );
if( !parse_index( &indexes, arg, dest, al_get_count( &result ) ) )
{
builtin_print_help( argv[0], sb_err );
retcode = 1;
break;
}
for( j=0; j<al_get_count( &indexes ); j++ )
{
long idx = al_get_long( &indexes, j );
if( idx < 1 || idx > al_get_count( &result ) )
{
retcode++;
}
}
}
else
{
if( !env_exist( arg, scope ) )
{
retcode++;
}
}
free( dest );
}
return retcode;
}
if( list )
{
/* Maybe we should issue an error if there are any other arguments? */
print_variables(0, 0, scope);
return 0;
}
if( woptind == argc )
{
/*
Print values of variables
*/
if( erase )
{
sb_printf( sb_err,
_(L"%ls: Erase needs a variable name\n%ls\n"),
argv[0] );
builtin_print_help( argv[0], sb_err );
retcode = 1;
}
else
{
print_variables( 1, 1, scope );
}
return retcode;
}
if( !(dest = wcsdup(argv[woptind])))
{
DIE_MEM();
}
if( wcschr( dest, L'[' ) )
{
slice = 1;
*wcschr( dest, L'[' )=0;
}
if( !wcslen( dest ) )
{
free( dest );
sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] );
builtin_print_help( argv[0], sb_err );
return 1;
}
if( (bad_char = wcsvarname( dest ) ) )
{
sb_printf( sb_err, BUILTIN_ERR_VARCHAR, argv[0], *bad_char );
builtin_print_help( argv[0], sb_err );
free( dest );
return 1;
}
if( slice && erase && (scope != ENV_USER) )
{
free( dest );
sb_printf( sb_err, _(L"%ls: Can not specify scope when erasing array slice\n"), argv[0] );
builtin_print_help( argv[0], sb_err );
return 1;
}
/*
set assignment can work in two modes, either using slices or
using the whole array. We detect which mode is used here.
*/
if( slice )
{
/*
Slice mode
*/
int idx_count, val_count;
array_list_t values;
array_list_t indexes;
array_list_t result;
al_init(&values);
al_init(&indexes);
al_init(&result);
tokenize_variable_array( env_get(dest), &result );
for( ; woptind<argc; woptind++ )
{
if( !parse_index( &indexes, argv[woptind], dest, al_get_count( &result ) ) )
{
builtin_print_help( argv[0], sb_err );
retcode = 1;
break;
}
val_count = argc-woptind-1;
idx_count = al_get_count( &indexes );
if( !erase )
{
if( val_count < idx_count )
{
sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), argv[0] );
builtin_print_help( argv[0], sb_err );
retcode=1;
break;
}
if( val_count == idx_count )
{
woptind++;
break;
}
}
}
if( !retcode )
{
/*
Slice indexes have been calculated, do the actual work
*/
if( erase )
{
erase_values(&result, &indexes);
my_env_set( dest, &result, scope);
}
else
{
array_list_t value;
al_init(&value);
while( woptind < argc )
{
al_push(&value, argv[woptind++]);
}
if( update_values( &result,
&indexes,
&value ) )
{
sb_printf( sb_err, L"%ls: ", argv[0] );
sb_printf( sb_err, ARRAY_BOUNDS_ERR );
sb_append( sb_err, L"\n" );
}
my_env_set(dest,
&result,
scope);
al_destroy( &value );
}
}
al_foreach( &result, &free );
al_destroy( &result );
al_destroy(&indexes);
al_destroy(&values);
}
else
{
woptind++;
/*
No slicing
*/
if( erase )
{
if( woptind != argc )
{
sb_printf( sb_err,
_(L"%ls: Values cannot be specfied with erase\n"),
argv[0] );
builtin_print_help( argv[0], sb_err );
retcode=1;
}
else
{
retcode = env_remove( dest, scope );
}
}
else
{
array_list_t val;
al_init( &val );
for( i=woptind; i<argc; i++ )
{
al_push( &val, argv[i] );
}
retcode = my_env_set( dest, &val, scope );
al_destroy( &val );
}
}
free( dest );
return retcode;
}

811
builtin_set.cpp Normal file
View File

@@ -0,0 +1,811 @@
/** \file builtin_set.c Functions defining the set builtin
Functions used for implementing the set builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/types.h>
#include <termios.h>
#include <signal.h>
#include <vector>
#include <algorithm>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "env.h"
#include "expand.h"
#include "common.h"
#include "wgetopt.h"
#include "proc.h"
#include "parser.h"
/* We know about these buffers */
extern wcstring stdout_buffer, stderr_buffer;
/**
Error message for invalid path operations
*/
#define BUILTIN_SET_PATH_ERROR L"%ls: Warning: path component %ls may not be valid in %ls.\n"
/**
Hint for invalid path operation with a colon
*/
#define BUILTIN_SET_PATH_HINT L"%ls: Did you mean 'set %ls $%ls %ls'?\n"
/**
Error for mismatch between index count and elements
*/
#define BUILTIN_SET_ARG_COUNT L"%ls: The number of variable indexes does not match the number of values\n"
/**
Test if the specified variable should be subject to path validation
*/
static int is_path_variable(const wchar_t *env)
{
return contains(env, L"PATH", L"CDPATH");
}
/**
Call env_set. If this is a path variable, e.g. PATH, validate the
elements. On error, print a description of the problem to stderr.
*/
static int my_env_set(const wchar_t *key, const wcstring_list_t &val, int scope)
{
size_t i;
int retcode = 0;
const wchar_t *val_str=NULL;
if (is_path_variable(key))
{
/* Fix for https://github.com/fish-shell/fish-shell/issues/199 . Return success if any path setting succeeds. */
bool any_success = false;
/* Don't bother validating (or complaining about) values that are already present */
wcstring_list_t existing_values;
const env_var_t existing_variable = env_get_string(key);
if (! existing_variable.missing_or_empty())
tokenize_variable_array(existing_variable, existing_values);
for (i=0; i< val.size() ; i++)
{
const wcstring &dir = val.at(i);
if (list_contains_string(existing_values, dir))
{
any_success = true;
continue;
}
bool show_perror = false;
int show_hint = 0;
bool error = false;
struct stat buff;
if (wstat(dir, &buff))
{
error = true;
show_perror = true;
}
if (!(S_ISDIR(buff.st_mode)))
{
error = true;
}
if (!error)
{
any_success = true;
}
else
{
append_format(stderr_buffer, _(BUILTIN_SET_PATH_ERROR), L"set", dir.c_str(), key);
const wchar_t *colon = wcschr(dir.c_str(), L':');
if (colon && *(colon+1))
{
show_hint = 1;
}
}
if (show_perror)
{
builtin_wperror(L"set");
}
if (show_hint)
{
append_format(stderr_buffer, _(BUILTIN_SET_PATH_HINT), L"set", key, key, wcschr(dir.c_str(), L':')+1);
}
}
/* Fail at setting the path if we tried to set it to something non-empty, but it wound up empty. */
if (! val.empty() && ! any_success)
{
return 1;
}
}
wcstring sb;
if (! val.empty())
{
for (i=0; i< val.size() ; i++)
{
sb.append(val[i]);
if (i<val.size() - 1)
{
sb.append(ARRAY_SEP_STR);
}
}
val_str = sb.c_str();
}
switch (env_set(key, val_str, scope | ENV_USER))
{
case ENV_PERM:
{
append_format(stderr_buffer, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key);
retcode=1;
break;
}
case ENV_INVALID:
{
append_format(stderr_buffer, _(L"%ls: Unknown error"), L"set");
retcode=1;
break;
}
}
return retcode;
}
/**
Extract indexes from a destination argument of the form name[index1 index2...]
\param indexes the list to insert the new indexes into
\param src the source string to parse
\param name the name of the element. Return null if the name in \c src does not match this name
\param var_count the number of elements in the array to parse.
\return the total number of indexes parsed, or -1 on error
*/
static int parse_index(std::vector<long> &indexes,
const wchar_t *src,
const wchar_t *name,
size_t var_count)
{
size_t len;
int count = 0;
const wchar_t *src_orig = src;
if (src == 0)
{
return 0;
}
while (*src != L'\0' && (iswalnum(*src) || *src == L'_'))
{
src++;
}
if (*src != L'[')
{
append_format(stderr_buffer, _(BUILTIN_SET_ARG_COUNT), L"set");
return 0;
}
len = src-src_orig;
if ((wcsncmp(src_orig, name, len)!=0) || (wcslen(name) != (len)))
{
append_format(stderr_buffer,
_(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"),
L"set",
name,
len,
src_orig);
return 0;
}
src++;
while (iswspace(*src))
{
src++;
}
while (*src != L']')
{
wchar_t *end;
long l_ind;
errno = 0;
l_ind = wcstol(src, &end, 10);
if (end==src || errno)
{
append_format(stderr_buffer, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
return 0;
}
if (l_ind < 0)
{
l_ind = var_count+l_ind+1;
}
src = end;
if (*src==L'.' && *(src+1)==L'.')
{
src+=2;
long l_ind2 = wcstol(src, &end, 10);
if (end==src || errno)
{
return 1;
}
src = end;
if (l_ind2 < 0)
{
l_ind2 = var_count+l_ind2+1;
}
int direction = l_ind2<l_ind ? -1 : 1 ;
for (long jjj = l_ind; jjj*direction <= l_ind2*direction; jjj+=direction)
{
// debug(0, L"Expand range [set]: %i\n", jjj);
indexes.push_back(jjj);
count++;
}
}
else
{
indexes.push_back(l_ind);
count++;
}
while (iswspace(*src)) src++;
}
return count;
}
static int update_values(wcstring_list_t &list,
std::vector<long> &indexes,
wcstring_list_t &values)
{
size_t i;
/* Replace values where needed */
for (i = 0; i < indexes.size(); i++)
{
/*
The '- 1' below is because the indices in fish are
one-based, but the vector uses zero-based indices
*/
long ind = indexes[i] - 1;
const wcstring newv = values[ i ];
if (ind < 0)
{
return 1;
}
if ((size_t)ind >= list.size())
{
list.resize(ind+1);
}
// free((void *) al_get(list, ind));
list[ ind ] = newv;
}
return 0;
}
/**
Erase from a list of wcstring values at specified indexes
*/
static void erase_values(wcstring_list_t &list, const std::vector<long> &indexes)
{
// Make a set of indexes.
// This both sorts them into ascending order and removes duplicates.
const std::set<long> indexes_set(indexes.begin(), indexes.end());
// Now walk the set backwards, so we encounter larger indexes first, and remove elements at the given (1-based) indexes.
std::set<long>::const_reverse_iterator iter;
for (iter = indexes_set.rbegin(); iter != indexes_set.rend(); ++iter)
{
long val = *iter;
if (val > 0 && (size_t)val <= list.size())
{
// One-based indexing!
list.erase(list.begin() + val - 1);
}
}
}
/**
Print the names of all environment variables in the scope, with or without shortening,
with or without values, with or without escaping
*/
static void print_variables(int include_values, int esc, bool shorten_ok, int scope)
{
wcstring_list_t names = env_get_names(scope);
sort(names.begin(), names.end());
for (size_t i = 0; i < names.size(); i++)
{
const wcstring key = names.at(i);
const wcstring e_key = escape_string(key, 0);
stdout_buffer.append(e_key);
if (include_values)
{
env_var_t value = env_get_string(key);
if (!value.missing())
{
int shorten = 0;
if (shorten_ok && value.length() > 64)
{
shorten = 1;
value.resize(60);
}
wcstring e_value = esc ? expand_escape_variable(value) : value;
stdout_buffer.append(L" ");
stdout_buffer.append(e_value);
if (shorten)
{
stdout_buffer.push_back(ellipsis_char);
}
}
}
stdout_buffer.append(L"\n");
}
}
/**
The set builtin. Creates, updates and erases environment variables
and environemnt variable arrays.
*/
static int builtin_set(parser_t &parser, wchar_t **argv)
{
/** Variables used for parsing the argument list */
const struct woption long_options[] =
{
{ L"export", no_argument, 0, 'x' },
{ L"global", no_argument, 0, 'g' },
{ L"local", no_argument, 0, 'l' },
{ L"erase", no_argument, 0, 'e' },
{ L"names", no_argument, 0, 'n' },
{ L"unexport", no_argument, 0, 'u' },
{ L"universal", no_argument, 0, 'U' },
{ L"long", no_argument, 0, 'L' },
{ L"query", no_argument, 0, 'q' },
{ L"help", no_argument, 0, 'h' },
{ 0, 0, 0, 0 }
} ;
const wchar_t *short_options = L"+xglenuULqh";
int argc = builtin_count_args(argv);
/*
Flags to set the work mode
*/
int local = 0, global = 0, exportv = 0;
int erase = 0, list = 0, unexport=0;
int universal = 0, query=0;
bool shorten_ok = true;
bool preserve_incoming_failure_exit_status = true;
const int incoming_exit_status = proc_get_last_status();
/*
Variables used for performing the actual work
*/
wchar_t *dest = 0;
int retcode=0;
int scope;
int slice=0;
int i;
wchar_t *bad_char;
/* Parse options to obtain the requested operation and the modifiers */
woptind = 0;
while (1)
{
int c = wgetopt_long(argc, argv, short_options, long_options, 0);
if (c == -1)
{
break;
}
switch (c)
{
case 0:
break;
case 'e':
erase = 1;
preserve_incoming_failure_exit_status = false;
break;
case 'n':
list = 1;
preserve_incoming_failure_exit_status = false;
break;
case 'x':
exportv = 1;
break;
case 'l':
local = 1;
break;
case 'g':
global = 1;
break;
case 'u':
unexport = 1;
break;
case 'U':
universal = 1;
break;
case 'L':
shorten_ok = false;
break;
case 'q':
query = 1;
preserve_incoming_failure_exit_status = false;
break;
case 'h':
builtin_print_help(parser, argv[0], stdout_buffer);
return 0;
case '?':
builtin_unknown_option(parser, argv[0], argv[woptind-1]);
return 1;
default:
break;
}
}
/*
Ok, all arguments have been parsed, let's validate them
*/
/*
If we are checking the existance of a variable (-q) we can not
also specify scope
*/
if (query && (erase || list))
{
append_format(stderr_buffer,
BUILTIN_ERR_COMBO,
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
/* We can't both list and erase varaibles */
if (erase && list)
{
append_format(stderr_buffer,
BUILTIN_ERR_COMBO,
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
/*
Variables can only have one scope
*/
if (local + global + universal > 1)
{
append_format(stderr_buffer,
BUILTIN_ERR_GLOCAL,
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
/*
Variables can only have one export status
*/
if (exportv && unexport)
{
append_format(stderr_buffer,
BUILTIN_ERR_EXPUNEXP,
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
/*
Calculate the scope value for variable assignement
*/
scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (exportv ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
if (query)
{
/*
Query mode. Return the number of variables that do not exist
out of the specified variables.
*/
int i;
for (i=woptind; i<argc; i++)
{
wchar_t *arg = argv[i];
int slice=0;
if (!(dest = wcsdup(arg)))
{
DIE_MEM();
}
if (wcschr(dest, L'['))
{
slice = 1;
*wcschr(dest, L'[')=0;
}
if (slice)
{
std::vector<long> indexes;
wcstring_list_t result;
size_t j;
env_var_t dest_str = env_get_string(dest);
if (! dest_str.missing())
tokenize_variable_array(dest_str, result);
if (!parse_index(indexes, arg, dest, result.size()))
{
builtin_print_help(parser, argv[0], stderr_buffer);
retcode = 1;
break;
}
for (j=0; j < indexes.size() ; j++)
{
long idx = indexes[j];
if (idx < 1 || (size_t)idx > result.size())
{
retcode++;
}
}
}
else
{
if (!env_exist(arg, scope))
{
retcode++;
}
}
free(dest);
}
return retcode;
}
if (list)
{
/* Maybe we should issue an error if there are any other arguments? */
print_variables(0, 0, shorten_ok, scope);
return 0;
}
if (woptind == argc)
{
/*
Print values of variables
*/
if (erase)
{
append_format(stderr_buffer,
_(L"%ls: Erase needs a variable name\n"),
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
retcode = 1;
}
else
{
print_variables(1, 1, shorten_ok, scope);
}
return retcode;
}
if (!(dest = wcsdup(argv[woptind])))
{
DIE_MEM();
}
if (wcschr(dest, L'['))
{
slice = 1;
*wcschr(dest, L'[')=0;
}
if (!wcslen(dest))
{
free(dest);
append_format(stderr_buffer, BUILTIN_ERR_VARNAME_ZERO, argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
if ((bad_char = wcsvarname(dest)))
{
append_format(stderr_buffer, BUILTIN_ERR_VARCHAR, argv[0], *bad_char);
builtin_print_help(parser, argv[0], stderr_buffer);
free(dest);
return 1;
}
if (slice && erase && (scope != ENV_USER))
{
free(dest);
append_format(stderr_buffer, _(L"%ls: Can not specify scope when erasing array slice\n"), argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
/*
set assignment can work in two modes, either using slices or
using the whole array. We detect which mode is used here.
*/
if (slice)
{
/*
Slice mode
*/
size_t idx_count, val_count;
wcstring_list_t values;
std::vector<long> indexes;
wcstring_list_t result;
const env_var_t dest_str = env_get_string(dest);
if (! dest_str.missing())
tokenize_variable_array(dest_str, result);
for (; woptind<argc; woptind++)
{
if (!parse_index(indexes, argv[woptind], dest, result.size()))
{
builtin_print_help(parser, argv[0], stderr_buffer);
retcode = 1;
break;
}
val_count = argc-woptind-1;
idx_count = indexes.size();
if (!erase)
{
if (val_count < idx_count)
{
append_format(stderr_buffer, _(BUILTIN_SET_ARG_COUNT), argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
retcode=1;
break;
}
if (val_count == idx_count)
{
woptind++;
break;
}
}
}
if (!retcode)
{
/*
Slice indexes have been calculated, do the actual work
*/
if (erase)
{
erase_values(result, indexes);
my_env_set(dest, result, scope);
}
else
{
wcstring_list_t value;
while (woptind < argc)
{
value.push_back(argv[woptind++]);
}
if (update_values(result,
indexes,
value))
{
append_format(stderr_buffer, L"%ls: ", argv[0]);
append_format(stderr_buffer, ARRAY_BOUNDS_ERR);
stderr_buffer.push_back(L'\n');
}
my_env_set(dest, result, scope);
}
}
}
else
{
woptind++;
/*
No slicing
*/
if (erase)
{
if (woptind != argc)
{
append_format(stderr_buffer,
_(L"%ls: Values cannot be specfied with erase\n"),
argv[0]);
builtin_print_help(parser, argv[0], stderr_buffer);
retcode=1;
}
else
{
retcode = env_remove(dest, scope);
}
}
else
{
wcstring_list_t val;
for (i=woptind; i<argc; i++)
val.push_back(argv[i]);
retcode = my_env_set(dest, val, scope);
}
}
free(dest);
if (retcode == STATUS_BUILTIN_OK && preserve_incoming_failure_exit_status)
retcode = incoming_exit_status;
return retcode;
}

243
builtin_set_color.cpp Normal file
View File

@@ -0,0 +1,243 @@
/** \file builtin_set_color.cpp Functions defining the set_color builtin
Functions used for implementing the set_color builtin.
*/
#include "config.h"
#include "builtin.h"
#include "color.h"
#include "output.h"
#if HAVE_NCURSES_H
#include <ncurses.h>
#else
#include <curses.h>
#endif
#if HAVE_TERM_H
#include <term.h>
#elif HAVE_NCURSES_TERM_H
#include <ncurses/term.h>
#endif
/* We know about these buffers */
extern wcstring stdout_buffer, stderr_buffer;
/**
Error message for invalid path operations
*/
#define BUILTIN_SET_PATH_ERROR L"%ls: Warning: path component %ls may not be valid in %ls.\n"
/**
Hint for invalid path operation with a colon
*/
#define BUILTIN_SET_PATH_HINT L"%ls: Did you mean 'set %ls $%ls %ls'?\n"
/**
Error for mismatch between index count and elements
*/
#define BUILTIN_SET_ARG_COUNT L"%ls: The number of variable indexes does not match the number of values\n"
static void print_colors(void)
{
const wcstring_list_t result = rgb_color_t::named_color_names();
size_t i;
for (i=0; i < result.size(); i++)
{
stdout_buffer.append(result.at(i));
stdout_buffer.push_back(L'\n');
}
}
/* function we set as the output writer */
static std::string builtin_set_color_output;
static int set_color_builtin_outputter(char c)
{
ASSERT_IS_MAIN_THREAD();
builtin_set_color_output.push_back(c);
return 0;
}
/**
set_color builtin
*/
static int builtin_set_color(parser_t &parser, wchar_t **argv)
{
/** Variables used for parsing the argument list */
const struct woption long_options[] =
{
{ L"background", required_argument, 0, 'b'},
{ L"help", no_argument, 0, 'h' },
{ L"bold", no_argument, 0, 'o' },
{ L"underline", no_argument, 0, 'u' },
{ L"version", no_argument, 0, 'v' },
{ L"print-colors", no_argument, 0, 'c' },
{ 0, 0, 0, 0 }
};
const wchar_t *short_options = L"b:hvocu";
int argc = builtin_count_args(argv);
const wchar_t *bgcolor = NULL;
bool bold = false, underline=false;
int errret;
/* Parse options to obtain the requested operation and the modifiers */
woptind = 0;
while (1)
{
int c = wgetopt_long(argc, argv, short_options, long_options, 0);
if (c == -1)
{
break;
}
switch (c)
{
case 0:
break;
case 'b':
bgcolor = woptarg;
break;
case 'h':
builtin_print_help(parser, argv[0], stdout_buffer);
return STATUS_BUILTIN_OK;
case 'o':
bold = true;
break;
case 'u':
underline = true;
break;
case 'c':
print_colors();
return STATUS_BUILTIN_OK;
case '?':
return STATUS_BUILTIN_ERROR;
}
}
/* Remaining argument is foreground color */
const wchar_t *fgcolor = NULL;
if (woptind < argc)
{
if (woptind + 1 == argc)
{
fgcolor = argv[woptind];
}
else
{
append_format(stderr_buffer,
_(L"%ls: Too many arguments\n"),
argv[0]);
return STATUS_BUILTIN_ERROR;
}
}
if (fgcolor == NULL && bgcolor == NULL && !bold && !underline)
{
append_format(stderr_buffer,
_(L"%ls: Expected an argument\n"),
argv[0]);
return STATUS_BUILTIN_ERROR;
}
const rgb_color_t fg = rgb_color_t(fgcolor ? fgcolor : L"");
if (fgcolor && fg.is_none())
{
append_format(stderr_buffer, _(L"%ls: Unknown color '%ls'\n"), argv[0], fgcolor);
return STATUS_BUILTIN_ERROR;
}
const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L"");
if (bgcolor && bg.is_none())
{
append_format(stderr_buffer, _(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
return STATUS_BUILTIN_ERROR;
}
/* Make sure that the term exists */
if (cur_term == NULL && setupterm(0, STDOUT_FILENO, &errret) == ERR)
{
append_format(stderr_buffer, _(L"%ls: Could not set up terminal\n"), argv[0]);
return STATUS_BUILTIN_ERROR;
}
/*
Test if we have at least basic support for setting fonts, colors
and related bits - otherwise just give up...
*/
if (! exit_attribute_mode)
{
return STATUS_BUILTIN_ERROR;
}
/* Save old output function so we can restore it */
int (* const saved_writer_func)(char) = output_get_writer();
/* Set our output function, which writes to a std::string */
builtin_set_color_output.clear();
output_set_writer(set_color_builtin_outputter);
if (bold)
{
if (enter_bold_mode)
writembs(tparm(enter_bold_mode));
}
if (underline)
{
if (enter_underline_mode)
writembs(enter_underline_mode);
}
if (bgcolor != NULL)
{
if (bg.is_normal())
{
write_background_color(0);
writembs(tparm(exit_attribute_mode));
}
}
if (fgcolor != NULL)
{
if (fg.is_normal())
{
write_foreground_color(0);
writembs(tparm(exit_attribute_mode));
}
else
{
write_foreground_color(index_for_color(fg));
}
}
if (bgcolor != NULL)
{
if (! bg.is_normal())
{
write_background_color(index_for_color(bg));
}
}
/* Restore saved writer function */
output_set_writer(saved_writer_func);
/* Output the collected string */
std::string local_output;
std::swap(builtin_set_color_output, local_output);
stdout_buffer.append(str2wcstring(local_output));
return STATUS_BUILTIN_OK;
}

970
builtin_test.cpp Normal file
View File

@@ -0,0 +1,970 @@
/** \file builtin_test.cpp Functions defining the test builtin
Functions used for implementing the test builtin.
Implemented from scratch (yes, really) by way of IEEE 1003.1 as reference.
*/
#include "config.h"
#include "common.h"
#include "builtin.h"
#include "wutil.h"
#include "proc.h"
#include <sys/stat.h>
#include <memory>
enum
{
BUILTIN_TEST_SUCCESS = STATUS_BUILTIN_OK,
BUILTIN_TEST_FAIL = STATUS_BUILTIN_ERROR
};
int builtin_test(parser_t &parser, wchar_t **argv);
static const wchar_t * const condstr[] =
{
L"!", L"&&", L"||", L"==", L"!=", L"<", L">", L"-nt", L"-ot", L"-ef", L"-eq",
L"-ne", L"-lt", L"-gt", L"-le", L"-ge", L"=~"
};
namespace test_expressions
{
enum token_t
{
test_unknown, // arbitrary string
test_bang, // "!", inverts sense
test_filetype_b, // "-b", for block special files
test_filetype_c, // "-c" for character special files
test_filetype_d, // "-d" for directories
test_filetype_e, // "-e" for files that exist
test_filetype_f, // "-f" for for regular files
test_filetype_g, // "-g" for set-group-id
test_filetype_h, // "-h" for symbolic links
test_filetype_L, // "-L", same as -h
test_filetype_p, // "-p", for FIFO
test_filetype_S, // "-S", socket
test_filesize_s, // "-s", size greater than zero
test_filedesc_t, // "-t", whether the fd is associated with a terminal
test_fileperm_r, // "-r", read permission
test_fileperm_u, // "-u", whether file is setuid
test_fileperm_w, // "-w", whether file write permission is allowed
test_fileperm_x, // "-x", whether file execute/search is allowed
test_string_n, // "-n", non-empty string
test_string_z, // "-z", true if length of string is 0
test_string_equal, // "=", true if strings are identical
test_string_not_equal, // "!=", true if strings are not identical
test_number_equal, // "-eq", true if numbers are equal
test_number_not_equal, // "-ne", true if numbers are not equal
test_number_greater, // "-gt", true if first number is larger than second
test_number_greater_equal, // "-ge", true if first number is at least second
test_number_lesser, // "-lt", true if first number is smaller than second
test_number_lesser_equal, // "-le", true if first number is at most second
test_combine_and, // "-a", true if left and right are both true
test_combine_or, // "-o", true if either left or right is true
test_paren_open, // "(", open paren
test_paren_close, // ")", close paren
};
static bool binary_primary_evaluate(test_expressions::token_t token, const wcstring &left, const wcstring &right, wcstring_list_t &errors);
static bool unary_primary_evaluate(test_expressions::token_t token, const wcstring &arg, wcstring_list_t &errors);
enum
{
UNARY_PRIMARY = 1 << 0,
BINARY_PRIMARY = 1 << 1
};
static const struct token_info_t
{
token_t tok;
const wchar_t *string;
unsigned int flags;
} token_infos[] =
{
{test_unknown, L"", 0},
{test_bang, L"!", 0},
{test_filetype_b, L"-b", UNARY_PRIMARY},
{test_filetype_c, L"-c", UNARY_PRIMARY},
{test_filetype_d, L"-d", UNARY_PRIMARY},
{test_filetype_e, L"-e", UNARY_PRIMARY},
{test_filetype_f, L"-f", UNARY_PRIMARY},
{test_filetype_g, L"-g", UNARY_PRIMARY},
{test_filetype_h, L"-h", UNARY_PRIMARY},
{test_filetype_L, L"-L", UNARY_PRIMARY},
{test_filetype_p, L"-p", UNARY_PRIMARY},
{test_filetype_S, L"-S", UNARY_PRIMARY},
{test_filesize_s, L"-s", UNARY_PRIMARY},
{test_filedesc_t, L"-t", UNARY_PRIMARY},
{test_fileperm_r, L"-r", UNARY_PRIMARY},
{test_fileperm_u, L"-u", UNARY_PRIMARY},
{test_fileperm_w, L"-w", UNARY_PRIMARY},
{test_fileperm_x, L"-x", UNARY_PRIMARY},
{test_string_n, L"-n", UNARY_PRIMARY},
{test_string_z, L"-z", UNARY_PRIMARY},
{test_string_equal, L"=", BINARY_PRIMARY},
{test_string_not_equal, L"!=", BINARY_PRIMARY},
{test_number_equal, L"-eq", BINARY_PRIMARY},
{test_number_not_equal, L"-ne", BINARY_PRIMARY},
{test_number_greater, L"-gt", BINARY_PRIMARY},
{test_number_greater_equal, L"-ge", BINARY_PRIMARY},
{test_number_lesser, L"-lt", BINARY_PRIMARY},
{test_number_lesser_equal, L"-le", BINARY_PRIMARY},
{test_combine_and, L"-a", 0},
{test_combine_or, L"-o", 0},
{test_paren_open, L"(", 0},
{test_paren_close, L")", 0}
};
const token_info_t *token_for_string(const wcstring &str)
{
for (size_t i=0; i < sizeof token_infos / sizeof *token_infos; i++)
{
if (str == token_infos[i].string)
{
return &token_infos[i];
}
}
return &token_infos[0]; //unknown
}
/* Grammar.
<expr> = <combining_expr>
<combining_expr> = <unary_expr> and/or <combining_expr> |
<unary_expr>
<unary_expr> = bang <unary_expr> |
<primary>
<primary> = <unary_primary> arg |
arg <binary_primary> arg |
'(' <expr> ')'
*/
class expression;
class test_parser
{
private:
wcstring_list_t strings;
wcstring_list_t errors;
expression *error(const wchar_t *fmt, ...);
void add_error(const wchar_t *fmt, ...);
const wcstring &arg(unsigned int idx)
{
return strings.at(idx);
}
public:
test_parser(const wcstring_list_t &val) : strings(val)
{ }
expression *parse_expression(unsigned int start, unsigned int end);
expression *parse_3_arg_expression(unsigned int start, unsigned int end);
expression *parse_4_arg_expression(unsigned int start, unsigned int end);
expression *parse_combining_expression(unsigned int start, unsigned int end);
expression *parse_unary_expression(unsigned int start, unsigned int end);
expression *parse_primary(unsigned int start, unsigned int end);
expression *parse_parenthentical(unsigned int start, unsigned int end);
expression *parse_unary_primary(unsigned int start, unsigned int end);
expression *parse_binary_primary(unsigned int start, unsigned int end);
expression *parse_just_a_string(unsigned int start, unsigned int end);
static expression *parse_args(const wcstring_list_t &args, wcstring &err);
};
struct range_t
{
unsigned int start;
unsigned int end;
range_t(unsigned s, unsigned e) : start(s), end(e) { }
};
/* Base class for expressions */
class expression
{
protected:
expression(token_t what, range_t where) : token(what), range(where) { }
public:
const token_t token;
range_t range;
virtual ~expression() { }
// evaluate returns true if the expression is true (i.e. BUILTIN_TEST_SUCCESS)
virtual bool evaluate(wcstring_list_t &errors) = 0;
};
typedef std::auto_ptr<expression> expr_ref_t;
/* Single argument like -n foo or "just a string" */
class unary_primary : public expression
{
public:
wcstring arg;
unary_primary(token_t tok, range_t where, const wcstring &what) : expression(tok, where), arg(what) { }
bool evaluate(wcstring_list_t &errors);
};
/* Two argument primary like foo != bar */
class binary_primary : public expression
{
public:
wcstring arg_left;
wcstring arg_right;
binary_primary(token_t tok, range_t where, const wcstring &left, const wcstring &right) : expression(tok, where), arg_left(left), arg_right(right)
{ }
bool evaluate(wcstring_list_t &errors);
};
/* Unary operator like bang */
class unary_operator : public expression
{
public:
expr_ref_t subject;
unary_operator(token_t tok, range_t where, expr_ref_t &exp) : expression(tok, where), subject(exp) { }
bool evaluate(wcstring_list_t &errors);
};
/* Combining expression. Contains a list of AND or OR expressions. It takes more than two so that we don't have to worry about precedence in the parser. */
class combining_expression : public expression
{
public:
const std::vector<expression *> subjects;
const std::vector<token_t> combiners;
combining_expression(token_t tok, range_t where, const std::vector<expression *> &exprs, const std::vector<token_t> &combs) : expression(tok, where), subjects(exprs), combiners(combs)
{
/* We should have one more subject than combiner */
assert(subjects.size() == combiners.size() + 1);
}
/* We are responsible for destroying our expressions */
virtual ~combining_expression()
{
for (size_t i=0; i < subjects.size(); i++)
{
delete subjects[i];
}
}
bool evaluate(wcstring_list_t &errors);
};
/* Parenthetical expression */
class parenthetical_expression : public expression
{
public:
expr_ref_t contents;
parenthetical_expression(token_t tok, range_t where, expr_ref_t &expr) : expression(tok, where), contents(expr) { }
virtual bool evaluate(wcstring_list_t &errors);
};
void test_parser::add_error(const wchar_t *fmt, ...)
{
assert(fmt != NULL);
va_list va;
va_start(va, fmt);
this->errors.push_back(vformat_string(fmt, va));
va_end(va);
}
expression *test_parser::error(const wchar_t *fmt, ...)
{
assert(fmt != NULL);
va_list va;
va_start(va, fmt);
this->errors.push_back(vformat_string(fmt, va));
va_end(va);
return NULL;
}
expression *test_parser::parse_unary_expression(unsigned int start, unsigned int end)
{
if (start >= end)
{
return error(L"Missing argument at index %u", start);
}
token_t tok = token_for_string(arg(start))->tok;
if (tok == test_bang)
{
expr_ref_t subject(parse_unary_expression(start + 1, end));
if (subject.get())
{
return new unary_operator(tok, range_t(start, subject->range.end), subject);
}
else
{
return NULL;
}
}
else
{
return parse_primary(start, end);
}
}
/* Parse a combining expression (AND, OR) */
expression *test_parser::parse_combining_expression(unsigned int start, unsigned int end)
{
if (start >= end)
return NULL;
std::vector<expression *> subjects;
std::vector<token_t> combiners;
unsigned int idx = start;
bool first = true;
while (idx < end)
{
if (! first)
{
/* This is not the first expression, so we expect a combiner. */
token_t combiner = token_for_string(arg(idx))->tok;
if (combiner != test_combine_and && combiner != test_combine_or)
{
/* Not a combiner, we're done */
this->errors.insert(this->errors.begin(), format_string(L"Expected a combining operator like '-a' at index %u", idx));
break;
}
combiners.push_back(combiner);
idx++;
}
/* Parse another expression */
expression *expr = parse_unary_expression(idx, end);
if (! expr)
{
add_error(L"Missing argument at index %u", idx);
if (! first)
{
/* Clean up the dangling combiner, since it never got its right hand expression */
combiners.pop_back();
}
break;
}
/* Go to the end of this expression */
idx = expr->range.end;
subjects.push_back(expr);
first = false;
}
if (! subjects.empty())
{
/* Our new expression takes ownership of all expressions we created. The token we pass is irrelevant. */
return new combining_expression(test_combine_and, range_t(start, idx), subjects, combiners);
}
else
{
/* No subjects */
return NULL;
}
}
expression *test_parser::parse_unary_primary(unsigned int start, unsigned int end)
{
/* We need two arguments */
if (start >= end)
{
return error(L"Missing argument at index %u", start);
}
if (start + 1 >= end)
{
return error(L"Missing argument at index %u", start + 1);
}
/* All our unary primaries are prefix, so the operator is at start. */
const token_info_t *info = token_for_string(arg(start));
if (!(info->flags & UNARY_PRIMARY))
return NULL;
return new unary_primary(info->tok, range_t(start, start + 2), arg(start + 1));
}
expression *test_parser::parse_just_a_string(unsigned int start, unsigned int end)
{
/* Handle a string as a unary primary that is not a token of any other type.
e.g. 'test foo -a bar' should evaluate to true
We handle this with a unary primary of test_string_n
*/
/* We need one arguments */
if (start >= end)
{
return error(L"Missing argument at index %u", start);
}
const token_info_t *info = token_for_string(arg(start));
if (info->tok != test_unknown)
{
return error(L"Unexpected argument type at index %u", start);
}
/* This is hackish; a nicer way to implement this would be with a "just a string" expression type */
return new unary_primary(test_string_n, range_t(start, start + 1), arg(start));
}
#if 0
expression *test_parser::parse_unary_primary(unsigned int start, unsigned int end)
{
/* We need either one or two arguments */
if (start >= end)
{
return error(L"Missing argument at index %u", start);
}
/* The index of the argument to the unary primary */
unsigned int arg_idx;
/* All our unary primaries are prefix, so any operator is at start. But it also may just be a string, with no operator. */
const token_info_t *info = token_for_string(arg(start));
if (info->flags & UNARY_PRIMARY)
{
/* We have an operator. Skip the operator argument */
arg_idx = start + 1;
/* We have some freedom here...do we allow other tokens for the argument to operate on?
For example, should 'test -n =' work? I say yes. So no typechecking on the next token. */
}
else if (info->tok == test_unknown)
{
/* "Just a string. */
arg_idx = start;
}
else
{
/* Here we don't allow arbitrary tokens as "just a string." I.e. 'test = -a =' should have a parse error. We could relax this at some point. */
return error(L"Parse error at argument index %u", start);
}
/* Verify we have the argument we want, i.e. test -n should fail to parse */
if (arg_idx >= end)
{
return error(L"Missing argument at index %u", arg_idx);
}
return new unary_primary(info->tok, range_t(start, arg_idx + 1), arg(arg_idx));
}
#endif
expression *test_parser::parse_binary_primary(unsigned int start, unsigned int end)
{
/* We need three arguments */
for (unsigned int idx = start; idx < start + 3; idx++)
{
if (idx >= end)
{
return error(L"Missing argument at index %u", idx);
}
}
/* All our binary primaries are infix, so the operator is at start + 1. */
const token_info_t *info = token_for_string(arg(start + 1));
if (!(info->flags & BINARY_PRIMARY))
return NULL;
return new binary_primary(info->tok, range_t(start, start + 3), arg(start), arg(start + 2));
}
expression *test_parser::parse_parenthentical(unsigned int start, unsigned int end)
{
/* We need at least three arguments: open paren, argument, close paren */
if (start + 3 >= end)
return NULL;
/* Must start with an open expression */
const token_info_t *open_paren = token_for_string(arg(start));
if (open_paren->tok != test_paren_open)
return NULL;
/* Parse a subexpression */
expression *subexr_ptr = parse_expression(start + 1, end);
if (! subexr_ptr)
return NULL;
expr_ref_t subexpr(subexr_ptr);
/* Parse a close paren */
unsigned close_index = subexpr->range.end;
assert(close_index <= end);
if (close_index == end)
{
return error(L"Missing close paren at index %u", close_index);
}
const token_info_t *close_paren = token_for_string(arg(close_index));
if (close_paren->tok != test_paren_close)
{
return error(L"Expected close paren at index %u", close_index);
}
/* Success */
return new parenthetical_expression(test_paren_open, range_t(start, close_index+1), subexpr);
}
expression *test_parser::parse_primary(unsigned int start, unsigned int end)
{
if (start >= end)
{
return error(L"Missing argument at index %u", start);
}
expression *expr = NULL;
if (! expr) expr = parse_parenthentical(start, end);
if (! expr) expr = parse_unary_primary(start, end);
if (! expr) expr = parse_binary_primary(start, end);
if (! expr) expr = parse_just_a_string(start, end);
return expr;
}
// See IEEE 1003.1 breakdown of the behavior for different parameter counts
expression *test_parser::parse_3_arg_expression(unsigned int start, unsigned int end)
{
assert(end - start == 3);
expression *result = NULL;
const token_info_t *center_token = token_for_string(arg(start + 1));
if (center_token->flags & BINARY_PRIMARY)
{
result = parse_binary_primary(start, end);
}
else if (center_token->tok == test_combine_and || center_token->tok == test_combine_or)
{
expr_ref_t left(parse_unary_expression(start, start + 1));
expr_ref_t right(parse_unary_expression(start + 2, start + 3));
if (left.get() && right.get())
{
// Transfer ownership to the vector of subjects
std::vector<token_t> combiners(1, center_token->tok);
std::vector<expression *> subjects;
subjects.push_back(left.release());
subjects.push_back(right.release());
result = new combining_expression(center_token->tok, range_t(start, end), subjects, combiners);
}
}
else
{
result = parse_unary_expression(start, end);
}
return result;
}
expression *test_parser::parse_4_arg_expression(unsigned int start, unsigned int end)
{
assert(end - start == 4);
expression *result = NULL;
token_t first_token = token_for_string(arg(start))->tok;
if (first_token == test_bang)
{
expr_ref_t subject(parse_3_arg_expression(start + 1, end));
if (subject.get())
{
result = new unary_operator(first_token, range_t(start, subject->range.end), subject);
}
}
else if (first_token == test_paren_open)
{
result = parse_parenthentical(start, end);
}
else
{
result = parse_combining_expression(start, end);
}
return result;
}
expression *test_parser::parse_expression(unsigned int start, unsigned int end)
{
if (start >= end)
{
return error(L"Missing argument at index %u", start);
}
unsigned int argc = end - start;
switch (argc)
{
case 0:
assert(0); //should have been caught by the above test
return NULL;
case 1:
{
return error(L"Missing argument at index %u", start + 1);
}
case 2:
{
return parse_unary_expression(start, end);
}
case 3:
{
return parse_3_arg_expression(start, end);
}
case 4:
{
return parse_4_arg_expression(start, end);
}
default:
{
return parse_combining_expression(start, end);
}
}
}
expression *test_parser::parse_args(const wcstring_list_t &args, wcstring &err)
{
/* Empty list and one-arg list should be handled by caller */
assert(args.size() > 1);
test_parser parser(args);
expression *result = parser.parse_expression(0, (unsigned int)args.size());
/* Handle errors */
bool errored = false;
for (size_t i = 0; i < parser.errors.size(); i++)
{
err.append(L"test: ");
err.append(parser.errors.at(i));
err.push_back(L'\n');
errored = true;
// For now we only show the first error
break;
}
if (result)
{
/* It's also an error if there are any unused arguments. This is not detected by parse_expression() */
assert(result->range.end <= args.size());
if (result->range.end < args.size())
{
if (err.empty())
{
append_format(err, L"test: unexpected argument at index %lu: '%ls'\n", (unsigned long)result->range.end, args.at(result->range.end).c_str());
}
errored = true;
delete result;
result = NULL;
}
}
return result;
}
bool unary_primary::evaluate(wcstring_list_t &errors)
{
return unary_primary_evaluate(token, arg, errors);
}
bool binary_primary::evaluate(wcstring_list_t &errors)
{
return binary_primary_evaluate(token, arg_left, arg_right, errors);
}
bool unary_operator::evaluate(wcstring_list_t &errors)
{
switch (token)
{
case test_bang:
assert(subject.get());
return ! subject->evaluate(errors);
default:
errors.push_back(format_string(L"Unknown token type in %s", __func__));
return false;
}
}
bool combining_expression::evaluate(wcstring_list_t &errors)
{
switch (token)
{
case test_combine_and:
case test_combine_or:
{
/* One-element case */
if (subjects.size() == 1)
return subjects.at(0)->evaluate(errors);
/* Evaluate our lists, remembering that AND has higher precedence than OR. We can visualize this as a sequence of OR expressions of AND expressions. */
assert(combiners.size() + 1 == subjects.size());
assert(! subjects.empty());
size_t idx = 0, max = subjects.size();
bool or_result = false;
while (idx < max)
{
if (or_result)
{
/* Short circuit */
break;
}
/* Evaluate a stream of AND starting at given subject index. It may only have one element. */
bool and_result = true;
for (; idx < max; idx++)
{
/* Evaluate it, short-circuiting */
and_result = and_result && subjects.at(idx)->evaluate(errors);
/* If the combiner at this index (which corresponding to how we combine with the next subject) is not AND, then exit the loop */
if (idx + 1 < max && combiners.at(idx) != test_combine_and)
{
idx++;
break;
}
}
/* OR it in */
or_result = or_result || and_result;
}
return or_result;
}
default:
errors.push_back(format_string(L"Unknown token type in %s", __func__));
return BUILTIN_TEST_FAIL;
}
}
bool parenthetical_expression::evaluate(wcstring_list_t &errors)
{
return contents->evaluate(errors);
}
/* IEEE 1003.1 says nothing about what it means for two strings to be "algebraically equal". For example, should we interpret 0x10 as 0, 10, or 16? Here we use only base 10 and use wcstoll, which allows for leading + and -, and leading whitespace. This matches bash. */
static bool parse_number(const wcstring &arg, long long *out)
{
const wchar_t *str = arg.c_str();
wchar_t *endptr = NULL;
*out = wcstoll(str, &endptr, 10);
return endptr && *endptr == L'\0';
}
static bool binary_primary_evaluate(test_expressions::token_t token, const wcstring &left, const wcstring &right, wcstring_list_t &errors)
{
using namespace test_expressions;
long long left_num, right_num;
switch (token)
{
case test_string_equal:
return left == right;
case test_string_not_equal:
return left != right;
case test_number_equal:
return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num == right_num;
case test_number_not_equal:
return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num != right_num;
case test_number_greater:
return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num > right_num;
case test_number_greater_equal:
return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num >= right_num;
case test_number_lesser:
return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num < right_num;
case test_number_lesser_equal:
return parse_number(left, &left_num) && parse_number(right, &right_num) && left_num <= right_num;
default:
errors.push_back(format_string(L"Unknown token type in %s", __func__));
return false;
}
}
static bool unary_primary_evaluate(test_expressions::token_t token, const wcstring &arg, wcstring_list_t &errors)
{
using namespace test_expressions;
struct stat buf;
long long num;
switch (token)
{
case test_filetype_b: // "-b", for block special files
return !wstat(arg, &buf) && S_ISBLK(buf.st_mode);
case test_filetype_c: // "-c" for character special files
return !wstat(arg, &buf) && S_ISCHR(buf.st_mode);
case test_filetype_d: // "-d" for directories
return !wstat(arg, &buf) && S_ISDIR(buf.st_mode);
case test_filetype_e: // "-e" for files that exist
return !wstat(arg, &buf);
case test_filetype_f: // "-f" for for regular files
return !wstat(arg, &buf) && S_ISREG(buf.st_mode);
case test_filetype_g: // "-g" for set-group-id
return !wstat(arg, &buf) && (S_ISGID & buf.st_mode);
case test_filetype_h: // "-h" for symbolic links
case test_filetype_L: // "-L", same as -h
return !lwstat(arg, &buf) && S_ISLNK(buf.st_mode);
case test_filetype_p: // "-p", for FIFO
return !wstat(arg, &buf) && S_ISFIFO(buf.st_mode);
case test_filetype_S: // "-S", socket
return !wstat(arg, &buf) && S_ISSOCK(buf.st_mode);
case test_filesize_s: // "-s", size greater than zero
return !wstat(arg, &buf) && buf.st_size > 0;
case test_filedesc_t: // "-t", whether the fd is associated with a terminal
return parse_number(arg, &num) && num == (int)num && isatty((int)num);
case test_fileperm_r: // "-r", read permission
return !waccess(arg, R_OK);
case test_fileperm_u: // "-u", whether file is setuid
return !wstat(arg, &buf) && (S_ISUID & buf.st_mode);
case test_fileperm_w: // "-w", whether file write permission is allowed
return !waccess(arg, W_OK);
case test_fileperm_x: // "-x", whether file execute/search is allowed
return !waccess(arg, X_OK);
case test_string_n: // "-n", non-empty string
return ! arg.empty();
case test_string_z: // "-z", true if length of string is 0
return arg.empty();
default:
errors.push_back(format_string(L"Unknown token type in %s", __func__));
return false;
}
}
};
/*
* Evaluate a conditional expression given the arguments.
* If fromtest is set, the caller is the test or [ builtin;
* with the pointer giving the name of the command.
* for POSIX conformance this supports a more limited range
* of functionality.
*
* Return status is the final shell status, i.e. 0 for true,
* 1 for false and 2 for error.
*/
int builtin_test(parser_t &parser, wchar_t **argv)
{
using namespace test_expressions;
/* The first argument should be the name of the command ('test') */
if (! argv[0])
return BUILTIN_TEST_FAIL;
/* Whether we are invoked with bracket '[' or not */
const bool is_bracket = ! wcscmp(argv[0], L"[");
size_t argc = 0;
while (argv[argc + 1])
argc++;
/* If we're bracket, the last argument ought to be ]; we ignore it. Note that argc is the number of arguments after the command name; thus argv[argc] is the last argument. */
if (is_bracket)
{
if (! wcscmp(argv[argc], L"]"))
{
/* Ignore the closing bracketp */
argc--;
}
else
{
builtin_show_error(L"[: the last argument must be ']'\n");
return BUILTIN_TEST_FAIL;
}
}
/* Collect the arguments into a list */
const wcstring_list_t args(argv + 1, argv + 1 + argc);
switch (argc)
{
case 0:
{
// Per 1003.1, exit false
return BUILTIN_TEST_FAIL;
}
case 1:
{
// Per 1003.1, exit true if the arg is non-empty
return args.at(0).empty() ? BUILTIN_TEST_FAIL : BUILTIN_TEST_SUCCESS;
}
default:
{
// Try parsing. If expr is not nil, we are responsible for deleting it.
wcstring err;
expression *expr = test_parser::parse_args(args, err);
if (! expr)
{
#if 0
printf("Oops! test was given args:\n");
for (size_t i=0; i < argc; i++)
{
printf("\t%ls\n", args.at(i).c_str());
}
printf("and returned parse error: %ls\n", err.c_str());
#endif
builtin_show_error(err);
return BUILTIN_TEST_FAIL;
}
else
{
wcstring_list_t eval_errors;
bool result = expr->evaluate(eval_errors);
if (! eval_errors.empty())
{
printf("test returned eval errors:\n");
for (size_t i=0; i < eval_errors.size(); i++)
{
printf("\t%ls\n", eval_errors.at(i).c_str());
}
}
delete expr;
return result ? BUILTIN_TEST_SUCCESS : BUILTIN_TEST_FAIL;
}
}
}
return 1;
}

View File

@@ -1,516 +0,0 @@
/** \file builtin_ulimit.c Functions defining the ulimit builtin
Functions used for implementing the ulimit builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <errno.h>
#include "fallback.h"
#include "util.h"
#include "builtin.h"
#include "common.h"
#include "wgetopt.h"
/**
Struct describing a resource limit
*/
struct resource_t
{
/**
Resource id
*/
int resource;
/**
Description of resource
*/
const wchar_t *desc;
/**
Switch used on commandline to specify resource
*/
wchar_t switch_char;
/**
The implicit multiplier used when setting getting values
*/
int multiplier;
}
;
/**
Array of resource_t structs, describing all known resource types.
*/
static const struct resource_t resource_arr[] =
{
{
RLIMIT_CORE, L"Maximum size of core files created", L'c', 1024
}
,
{
RLIMIT_DATA, L"Maximum size of a processs data segment", L'd', 1024
}
,
{
RLIMIT_FSIZE, L"Maximum size of files created by the shell", L'f', 1024
}
,
#ifdef RLIMIT_MEMLOCK
{
RLIMIT_MEMLOCK, L"Maximum size that may be locked into memory", L'l', 1024
}
,
#endif
#ifdef RLIMIT_RSS
{
RLIMIT_RSS, L"Maximum resident set size", L'm', 1024
}
,
#endif
{
RLIMIT_NOFILE, L"Maximum number of open file descriptors", L'n', 1
}
,
{
RLIMIT_STACK, L"Maximum stack size", L's', 1024
}
,
{
RLIMIT_CPU, L"Maximum amount of cpu time in seconds", L't', 1
}
,
#ifdef RLIMIT_NPROC
{
RLIMIT_NPROC, L"Maximum number of processes available to a single user", L'u', 1
}
,
#endif
#ifdef RLIMIT_AS
{
RLIMIT_AS, L"Maximum amount of virtual memory available to the shell", L'v', 1024
}
,
#endif
{
0, 0, 0, 0
}
}
;
/**
Get the implicit multiplication factor for the specified resource limit
*/
static int get_multiplier( int what )
{
int i;
for( i=0; resource_arr[i].desc; i++ )
{
if( resource_arr[i].resource == what )
{
return resource_arr[i].multiplier;
}
}
return -1;
}
/**
Return the value for the specified resource limit. This function
does _not_ multiply the limit value by the multiplier constant used
by the commandline ulimit.
*/
static rlim_t get( int resource, int hard )
{
struct rlimit ls;
getrlimit( resource, &ls );
return hard ? ls.rlim_max:ls.rlim_cur;
}
/**
Print the value of the specified resource limit
*/
static void print( int resource, int hard )
{
rlim_t l = get( resource, hard );
if( l == RLIM_INFINITY )
sb_append( sb_out, L"unlimited\n" );
else
sb_printf( sb_out, L"%d\n", l / get_multiplier( resource ) );
}
/**
Print values of all resource limits
*/
static void print_all( int hard )
{
int i;
int w=0;
for( i=0; resource_arr[i].desc; i++ )
{
w=maxi( w, my_wcswidth(resource_arr[i].desc));
}
for( i=0; resource_arr[i].desc; i++ )
{
struct rlimit ls;
rlim_t l;
getrlimit( resource_arr[i].resource, &ls );
l = hard ? ls.rlim_max:ls.rlim_cur;
wchar_t *unit = ((resource_arr[i].resource==RLIMIT_CPU)?L"(seconds, ":(get_multiplier(resource_arr[i].resource)==1?L"(":L"(kB, "));
sb_printf( sb_out,
L"%-*ls %10ls-%lc) ",
w,
resource_arr[i].desc,
unit,
resource_arr[i].switch_char);
if( l == RLIM_INFINITY )
{
sb_append( sb_out, L"unlimited\n" );
}
else
{
sb_printf( sb_out, L"%d\n", l/get_multiplier(resource_arr[i].resource) );
}
}
}
/**
Returns the description for the specified resource limit
*/
static const wchar_t *get_desc( int what )
{
int i;
for( i=0; resource_arr[i].desc; i++ )
{
if( resource_arr[i].resource == what )
{
return resource_arr[i].desc;
}
}
return L"Not a resource";
}
/**
Set the new value of the specified resource limit. This function
does _not_ multiply the limit value by the multiplier constant used
by the commandline ulimit.
*/
static int set( int resource, int hard, int soft, rlim_t value )
{
struct rlimit ls;
getrlimit( resource, &ls );
if( hard )
{
ls.rlim_max = value;
}
if( soft )
{
ls.rlim_cur = value;
/*
Do not attempt to set the soft limit higher than the hard limit
*/
if( ( value == RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY ) ||
( value != RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY && value > ls.rlim_max))
{
ls.rlim_cur = ls.rlim_max;
}
}
if( setrlimit( resource, &ls ) )
{
if( errno == EPERM )
sb_printf( sb_err, L"ulimit: Permission denied when changing resource of type '%ls'\n", get_desc( resource ) );
else
builtin_wperror( L"ulimit" );
return 1;
}
return 0;
}
/**
The ulimit builtin, used for setting resource limits. Defined in
builtin_ulimit.c.
*/
static int builtin_ulimit( wchar_t ** argv )
{
int hard=0;
int soft=0;
int what = RLIMIT_FSIZE;
int report_all = 0;
int argc = builtin_count_args( argv );
woptind=0;
while( 1 )
{
static const struct woption
long_options[] =
{
{
L"all", no_argument, 0, 'a'
}
,
{
L"hard", no_argument, 0, 'H'
}
,
{
L"soft", no_argument, 0, 'S'
}
,
{
L"core-size", no_argument, 0, 'c'
}
,
{
L"data-size", no_argument, 0, 'd'
}
,
{
L"file-size", no_argument, 0, 'f'
}
,
{
L"lock-size", no_argument, 0, 'l'
}
,
{
L"resident-set-size", no_argument, 0, 'm'
}
,
{
L"file-descriptor-count", no_argument, 0, 'n'
}
,
{
L"stack-size", no_argument, 0, 's'
}
,
{
L"cpu-time", no_argument, 0, 't'
}
,
{
L"process-count", no_argument, 0, 'u'
}
,
{
L"virtual-memory-size", no_argument, 0, 'v'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
int opt_index = 0;
int opt = wgetopt_long( argc,
argv,
L"aHScdflmnstuvh",
long_options,
&opt_index );
if( opt == -1 )
break;
switch( opt )
{
case 0:
if(long_options[opt_index].flag != 0)
break;
sb_printf( sb_err,
BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name );
builtin_print_help( argv[0], sb_err );
return 1;
case L'a':
report_all=1;
break;
case L'H':
hard=1;
break;
case L'S':
soft=1;
break;
case L'c':
what=RLIMIT_CORE;
break;
case L'd':
what=RLIMIT_DATA;
break;
case L'f':
what=RLIMIT_FSIZE;
break;
#ifdef RLIMIT_MEMLOCK
case L'l':
what=RLIMIT_MEMLOCK;
break;
#endif
#ifdef RLIMIT_RSS
case L'm':
what=RLIMIT_RSS;
break;
#endif
case L'n':
what=RLIMIT_NOFILE;
break;
case L's':
what=RLIMIT_STACK;
break;
case L't':
what=RLIMIT_CPU;
break;
#ifdef RLIMIT_NPROC
case L'u':
what=RLIMIT_NPROC;
break;
#endif
#ifdef RLIMIT_AS
case L'v':
what=RLIMIT_AS;
break;
#endif
case L'h':
builtin_print_help( argv[0], sb_out );
return 0;
case L'?':
builtin_unknown_option( argv[0], argv[woptind-1] );
return 1;
}
}
if( report_all )
{
if( argc - woptind == 0 )
{
print_all( hard );
}
else
{
sb_append( sb_err,
argv[0],
L": Too many arguments\n",
(void *)0 );
builtin_print_help( argv[0], sb_err );
return 1;
}
return 0;
}
switch( argc - woptind )
{
case 0:
{
/*
Show current limit value
*/
print( what, hard );
break;
}
case 1:
{
/*
Change current limit value
*/
rlim_t new_limit;
wchar_t *end;
/*
Set both hard and soft limits if nothing else was specified
*/
if( !(hard+soft) )
{
hard=soft=1;
}
if( wcscasecmp( argv[woptind], L"unlimited" )==0)
{
new_limit = RLIM_INFINITY;
}
else if( wcscasecmp( argv[woptind], L"hard" )==0)
{
new_limit = get( what, 1 );
}
else if( wcscasecmp( argv[woptind], L"soft" )==0)
{
new_limit = get( what, soft );
}
else
{
errno=0;
new_limit = wcstol( argv[woptind], &end, 10 );
if( errno || *end )
{
sb_printf( sb_err,
L"%ls: Invalid limit '%ls'\n",
argv[0],
argv[woptind] );
builtin_print_help( argv[0], sb_err );
return 1;
}
new_limit *= get_multiplier( what );
}
return set( what, hard, soft, new_limit );
}
default:
{
sb_append( sb_err,
argv[0],
L": Too many arguments\n",
(void *)0 );
builtin_print_help( argv[0], sb_err );
return 1;
}
}
return 0;
}

512
builtin_ulimit.cpp Normal file
View File

@@ -0,0 +1,512 @@
/** \file builtin_ulimit.c Functions defining the ulimit builtin
Functions used for implementing the ulimit builtin.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <errno.h>
#include "fallback.h"
#include "util.h"
#include "builtin.h"
#include "common.h"
#include "wgetopt.h"
/**
Struct describing a resource limit
*/
struct resource_t
{
/**
Resource id
*/
int resource;
/**
Description of resource
*/
const wchar_t *desc;
/**
Switch used on commandline to specify resource
*/
wchar_t switch_char;
/**
The implicit multiplier used when setting getting values
*/
int multiplier;
}
;
/**
Array of resource_t structs, describing all known resource types.
*/
static const struct resource_t resource_arr[] =
{
{
RLIMIT_CORE, L"Maximum size of core files created", L'c', 1024
}
,
{
RLIMIT_DATA, L"Maximum size of a processs data segment", L'd', 1024
}
,
{
RLIMIT_FSIZE, L"Maximum size of files created by the shell", L'f', 1024
}
,
#ifdef RLIMIT_MEMLOCK
{
RLIMIT_MEMLOCK, L"Maximum size that may be locked into memory", L'l', 1024
}
,
#endif
#ifdef RLIMIT_RSS
{
RLIMIT_RSS, L"Maximum resident set size", L'm', 1024
}
,
#endif
{
RLIMIT_NOFILE, L"Maximum number of open file descriptors", L'n', 1
}
,
{
RLIMIT_STACK, L"Maximum stack size", L's', 1024
}
,
{
RLIMIT_CPU, L"Maximum amount of cpu time in seconds", L't', 1
}
,
#ifdef RLIMIT_NPROC
{
RLIMIT_NPROC, L"Maximum number of processes available to a single user", L'u', 1
}
,
#endif
#ifdef RLIMIT_AS
{
RLIMIT_AS, L"Maximum amount of virtual memory available to the shell", L'v', 1024
}
,
#endif
{
0, 0, 0, 0
}
}
;
/**
Get the implicit multiplication factor for the specified resource limit
*/
static int get_multiplier(int what)
{
int i;
for (i=0; resource_arr[i].desc; i++)
{
if (resource_arr[i].resource == what)
{
return resource_arr[i].multiplier;
}
}
return -1;
}
/**
Return the value for the specified resource limit. This function
does _not_ multiply the limit value by the multiplier constant used
by the commandline ulimit.
*/
static rlim_t get(int resource, int hard)
{
struct rlimit ls;
getrlimit(resource, &ls);
return hard ? ls.rlim_max:ls.rlim_cur;
}
/**
Print the value of the specified resource limit
*/
static void print(int resource, int hard)
{
rlim_t l = get(resource, hard);
if (l == RLIM_INFINITY)
stdout_buffer.append(L"unlimited\n");
else
append_format(stdout_buffer, L"%d\n", l / get_multiplier(resource));
}
/**
Print values of all resource limits
*/
static void print_all(int hard)
{
int i;
int w=0;
for (i=0; resource_arr[i].desc; i++)
{
w=maxi(w, my_wcswidth(resource_arr[i].desc));
}
for (i=0; resource_arr[i].desc; i++)
{
struct rlimit ls;
rlim_t l;
getrlimit(resource_arr[i].resource, &ls);
l = hard ? ls.rlim_max:ls.rlim_cur;
const wchar_t *unit = ((resource_arr[i].resource==RLIMIT_CPU)?L"(seconds, ":(get_multiplier(resource_arr[i].resource)==1?L"(":L"(kB, "));
append_format(stdout_buffer,
L"%-*ls %10ls-%lc) ",
w,
resource_arr[i].desc,
unit,
resource_arr[i].switch_char);
if (l == RLIM_INFINITY)
{
stdout_buffer.append(L"unlimited\n");
}
else
{
append_format(stdout_buffer, L"%d\n", l/get_multiplier(resource_arr[i].resource));
}
}
}
/**
Returns the description for the specified resource limit
*/
static const wchar_t *get_desc(int what)
{
int i;
for (i=0; resource_arr[i].desc; i++)
{
if (resource_arr[i].resource == what)
{
return resource_arr[i].desc;
}
}
return L"Not a resource";
}
/**
Set the new value of the specified resource limit. This function
does _not_ multiply the limit value by the multiplier constant used
by the commandline ulimit.
*/
static int set(int resource, int hard, int soft, rlim_t value)
{
struct rlimit ls;
getrlimit(resource, &ls);
if (hard)
{
ls.rlim_max = value;
}
if (soft)
{
ls.rlim_cur = value;
/*
Do not attempt to set the soft limit higher than the hard limit
*/
if ((value == RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY) ||
(value != RLIM_INFINITY && ls.rlim_max != RLIM_INFINITY && value > ls.rlim_max))
{
ls.rlim_cur = ls.rlim_max;
}
}
if (setrlimit(resource, &ls))
{
if (errno == EPERM)
append_format(stderr_buffer, L"ulimit: Permission denied when changing resource of type '%ls'\n", get_desc(resource));
else
builtin_wperror(L"ulimit");
return 1;
}
return 0;
}
/**
The ulimit builtin, used for setting resource limits. Defined in
builtin_ulimit.c.
*/
static int builtin_ulimit(parser_t &parser, wchar_t ** argv)
{
int hard=0;
int soft=0;
int what = RLIMIT_FSIZE;
int report_all = 0;
int argc = builtin_count_args(argv);
woptind=0;
while (1)
{
static const struct woption
long_options[] =
{
{
L"all", no_argument, 0, 'a'
}
,
{
L"hard", no_argument, 0, 'H'
}
,
{
L"soft", no_argument, 0, 'S'
}
,
{
L"core-size", no_argument, 0, 'c'
}
,
{
L"data-size", no_argument, 0, 'd'
}
,
{
L"file-size", no_argument, 0, 'f'
}
,
{
L"lock-size", no_argument, 0, 'l'
}
,
{
L"resident-set-size", no_argument, 0, 'm'
}
,
{
L"file-descriptor-count", no_argument, 0, 'n'
}
,
{
L"stack-size", no_argument, 0, 's'
}
,
{
L"cpu-time", no_argument, 0, 't'
}
,
{
L"process-count", no_argument, 0, 'u'
}
,
{
L"virtual-memory-size", no_argument, 0, 'v'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
int opt_index = 0;
int opt = wgetopt_long(argc,
argv,
L"aHScdflmnstuvh",
long_options,
&opt_index);
if (opt == -1)
break;
switch (opt)
{
case 0:
if (long_options[opt_index].flag != 0)
break;
append_format(stderr_buffer,
BUILTIN_ERR_UNKNOWN,
argv[0],
long_options[opt_index].name);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
case L'a':
report_all=1;
break;
case L'H':
hard=1;
break;
case L'S':
soft=1;
break;
case L'c':
what=RLIMIT_CORE;
break;
case L'd':
what=RLIMIT_DATA;
break;
case L'f':
what=RLIMIT_FSIZE;
break;
#ifdef RLIMIT_MEMLOCK
case L'l':
what=RLIMIT_MEMLOCK;
break;
#endif
#ifdef RLIMIT_RSS
case L'm':
what=RLIMIT_RSS;
break;
#endif
case L'n':
what=RLIMIT_NOFILE;
break;
case L's':
what=RLIMIT_STACK;
break;
case L't':
what=RLIMIT_CPU;
break;
#ifdef RLIMIT_NPROC
case L'u':
what=RLIMIT_NPROC;
break;
#endif
#ifdef RLIMIT_AS
case L'v':
what=RLIMIT_AS;
break;
#endif
case L'h':
builtin_print_help(parser, argv[0], stdout_buffer);
return 0;
case L'?':
builtin_unknown_option(parser, argv[0], argv[woptind-1]);
return 1;
}
}
if (report_all)
{
if (argc - woptind == 0)
{
print_all(hard);
}
else
{
stderr_buffer.append(argv[0]);
stderr_buffer.append(L": Too many arguments\n");
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
return 0;
}
switch (argc - woptind)
{
case 0:
{
/*
Show current limit value
*/
print(what, hard);
break;
}
case 1:
{
/*
Change current limit value
*/
rlim_t new_limit;
wchar_t *end;
/*
Set both hard and soft limits if nothing else was specified
*/
if (!(hard+soft))
{
hard=soft=1;
}
if (wcscasecmp(argv[woptind], L"unlimited")==0)
{
new_limit = RLIM_INFINITY;
}
else if (wcscasecmp(argv[woptind], L"hard")==0)
{
new_limit = get(what, 1);
}
else if (wcscasecmp(argv[woptind], L"soft")==0)
{
new_limit = get(what, soft);
}
else
{
errno=0;
new_limit = wcstol(argv[woptind], &end, 10);
if (errno || *end)
{
append_format(stderr_buffer,
L"%ls: Invalid limit '%ls'\n",
argv[0],
argv[woptind]);
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
new_limit *= get_multiplier(what);
}
return set(what, hard, soft, new_limit);
}
default:
{
stderr_buffer.append(argv[0]);
stderr_buffer.append(L": Too many arguments\n");
builtin_print_help(parser, argv[0], stderr_buffer);
return 1;
}
}
return 0;
}

365
color.cpp Normal file
View File

@@ -0,0 +1,365 @@
/** \file color.cpp Color class implementation
*/
#include "color.h"
#include "fallback.h"
bool rgb_color_t::try_parse_special(const wcstring &special)
{
bzero(&data, sizeof data);
const wchar_t *name = special.c_str();
if (! wcscasecmp(name, L"normal"))
{
this->type = type_normal;
}
else if (! wcscasecmp(name, L"reset"))
{
this->type = type_reset;
}
else if (! wcscasecmp(name, L"ignore"))
{
this->type = type_ignore;
}
else
{
this->type = type_none;
}
return this->type != type_none;
}
static int parse_hex_digit(wchar_t x)
{
switch (x)
{
case L'0':
return 0x0;
case L'1':
return 0x1;
case L'2':
return 0x2;
case L'3':
return 0x3;
case L'4':
return 0x4;
case L'5':
return 0x5;
case L'6':
return 0x6;
case L'7':
return 0x7;
case L'8':
return 0x8;
case L'9':
return 0x9;
case L'a':
case L'A':
return 0xA;
case L'b':
case L'B':
return 0xB;
case L'c':
case L'C':
return 0xC;
case L'd':
case L'D':
return 0xD;
case L'e':
case L'E':
return 0xE;
case L'f':
case L'F':
return 0xF;
default:
return -1;
}
}
static unsigned long squared_difference(long p1, long p2)
{
unsigned long diff = (unsigned long)labs(p1 - p2);
return diff * diff;
}
static unsigned char convert_color(const unsigned char rgb[3], const uint32_t *colors, size_t color_count)
{
long r = rgb[0], g = rgb[1], b = rgb[2];
unsigned long best_distance = (unsigned long)(-1);
unsigned char best_index = (unsigned char)(-1);
for (unsigned char idx = 0; idx < color_count; idx++)
{
uint32_t color = colors[idx];
long test_r = (color >> 16) & 0xFF, test_g = (color >> 8) & 0xFF, test_b = (color >> 0) & 0xFF;
unsigned long distance = squared_difference(r, test_r) + squared_difference(g, test_g) + squared_difference(b, test_b);
if (distance <= best_distance)
{
best_index = idx;
best_distance = distance;
}
}
return best_index;
}
bool rgb_color_t::try_parse_rgb(const wcstring &name)
{
bzero(&data, sizeof data);
/* We support the following style of rgb formats (case insensitive):
#FA3
#F3A035
FA3
F3A035
*/
size_t digit_idx = 0, len = name.size();
/* Skip any leading # */
if (len > 0 && name.at(0) == L'#')
digit_idx++;
bool success = false;
size_t i;
if (len - digit_idx == 3)
{
// type FA3
for (i=0; i < 3; i++)
{
int val = parse_hex_digit(name.at(digit_idx++));
if (val < 0) break;
data.rgb[i] = val*16+val;
}
success = (i == 3);
}
else if (len - digit_idx == 6)
{
// type F3A035
for (i=0; i < 3; i++)
{
int hi = parse_hex_digit(name.at(digit_idx++));
int lo = parse_hex_digit(name.at(digit_idx++));
if (lo < 0 || hi < 0) break;
data.rgb[i] = hi*16+lo;
}
success = (i == 3);
}
if (success)
{
this->type = type_rgb;
}
return success;
}
struct named_color_t
{
const wchar_t * name;
unsigned char idx;
unsigned char rgb[3];
};
static const named_color_t named_colors[11] =
{
{L"black", 0, {0, 0, 0}},
{L"red", 1, {0xFF, 0, 0}},
{L"green", 2, {0, 0xFF, 0}},
{L"brown", 3, {0x72, 0x50, 0}},
{L"yellow", 3, {0xFF, 0xFF, 0}},
{L"blue", 4, {0, 0, 0xFF}},
{L"magenta", 5, {0xFF, 0, 0xFF}},
{L"purple", 5, {0xFF, 0, 0xFF}},
{L"cyan", 6, {0, 0xFF, 0xFF}},
{L"white", 7, {0xFF, 0xFF, 0xFF}},
{L"normal", 8, {0xFF, 0xFF, 0XFF}}
};
wcstring_list_t rgb_color_t::named_color_names(void)
{
size_t count = sizeof named_colors / sizeof *named_colors;
wcstring_list_t result;
result.reserve(count);
for (size_t i=0; i < count; i++)
{
result.push_back(named_colors[i].name);
}
return result;
}
bool rgb_color_t::try_parse_named(const wcstring &str)
{
bzero(&data, sizeof data);
size_t max = sizeof named_colors / sizeof *named_colors;
for (size_t idx=0; idx < max; idx++)
{
if (0 == wcscasecmp(str.c_str(), named_colors[idx].name))
{
data.name_idx = named_colors[idx].idx;
this->type = type_named;
return true;
}
}
return false;
}
static const wchar_t *name_for_color_idx(unsigned char idx)
{
size_t max = sizeof named_colors / sizeof *named_colors;
for (size_t i=0; i < max; i++)
{
if (named_colors[i].idx == idx)
{
return named_colors[i].name;
}
}
return L"unknown";
}
rgb_color_t::rgb_color_t(unsigned char t, unsigned char i) : type(t), flags(), data()
{
data.name_idx = i;
}
rgb_color_t rgb_color_t::normal()
{
return rgb_color_t(type_normal);
}
rgb_color_t rgb_color_t::reset()
{
return rgb_color_t(type_reset);
}
rgb_color_t rgb_color_t::ignore()
{
return rgb_color_t(type_ignore);
}
rgb_color_t rgb_color_t::none()
{
return rgb_color_t(type_none);
}
rgb_color_t rgb_color_t::white()
{
return rgb_color_t(type_named, 7);
}
rgb_color_t rgb_color_t::black()
{
return rgb_color_t(type_named, 0);
}
static unsigned char term8_color_for_rgb(const unsigned char rgb[3])
{
const uint32_t kColors[] =
{
0x000000, //Black
0xFF0000, //Red
0x00FF00, //Green
0xFFFF00, //Yellow
0x0000FF, //Blue
0xFF00FF, //Magenta
0x00FFFF, //Cyan
0xFFFFFF, //White
};
return convert_color(rgb, kColors, sizeof kColors / sizeof *kColors);
}
static unsigned char term256_color_for_rgb(const unsigned char rgb[3])
{
const uint32_t kColors[240] =
{
0x000000, 0x00005f, 0x000087, 0x0000af, 0x0000d7, 0x0000ff, 0x005f00, 0x005f5f,
0x005f87, 0x005faf, 0x005fd7, 0x005fff, 0x008700, 0x00875f, 0x008787, 0x0087af,
0x0087d7, 0x0087ff, 0x00af00, 0x00af5f, 0x00af87, 0x00afaf, 0x00afd7, 0x00afff,
0x00d700, 0x00d75f, 0x00d787, 0x00d7af, 0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f,
0x00ff87, 0x00ffaf, 0x00ffd7, 0x00ffff, 0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af,
0x5f00d7, 0x5f00ff, 0x5f5f00, 0x5f5f5f, 0x5f5f87, 0x5f5faf, 0x5f5fd7, 0x5f5fff,
0x5f8700, 0x5f875f, 0x5f8787, 0x5f87af, 0x5f87d7, 0x5f87ff, 0x5faf00, 0x5faf5f,
0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff, 0x5fd700, 0x5fd75f, 0x5fd787, 0x5fd7af,
0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f, 0x5fff87, 0x5fffaf, 0x5fffd7, 0x5fffff,
0x870000, 0x87005f, 0x870087, 0x8700af, 0x8700d7, 0x8700ff, 0x875f00, 0x875f5f,
0x875f87, 0x875faf, 0x875fd7, 0x875fff, 0x878700, 0x87875f, 0x878787, 0x8787af,
0x8787d7, 0x8787ff, 0x87af00, 0x87af5f, 0x87af87, 0x87afaf, 0x87afd7, 0x87afff,
0x87d700, 0x87d75f, 0x87d787, 0x87d7af, 0x87d7d7, 0x87d7ff, 0x87ff00, 0x87ff5f,
0x87ff87, 0x87ffaf, 0x87ffd7, 0x87ffff, 0xaf0000, 0xaf005f, 0xaf0087, 0xaf00af,
0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f, 0xaf5f87, 0xaf5faf, 0xaf5fd7, 0xaf5fff,
0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af, 0xaf87d7, 0xaf87ff, 0xafaf00, 0xafaf5f,
0xafaf87, 0xafafaf, 0xafafd7, 0xafafff, 0xafd700, 0xafd75f, 0xafd787, 0xafd7af,
0xafd7d7, 0xafd7ff, 0xafff00, 0xafff5f, 0xafff87, 0xafffaf, 0xafffd7, 0xafffff,
0xd70000, 0xd7005f, 0xd70087, 0xd700af, 0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f,
0xd75f87, 0xd75faf, 0xd75fd7, 0xd75fff, 0xd78700, 0xd7875f, 0xd78787, 0xd787af,
0xd787d7, 0xd787ff, 0xd7af00, 0xd7af5f, 0xd7af87, 0xd7afaf, 0xd7afd7, 0xd7afff,
0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af, 0xd7d7d7, 0xd7d7ff, 0xd7ff00, 0xd7ff5f,
0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff, 0xff0000, 0xff005f, 0xff0087, 0xff00af,
0xff00d7, 0xff00ff, 0xff5f00, 0xff5f5f, 0xff5f87, 0xff5faf, 0xff5fd7, 0xff5fff,
0xff8700, 0xff875f, 0xff8787, 0xff87af, 0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f,
0xffaf87, 0xffafaf, 0xffafd7, 0xffafff, 0xffd700, 0xffd75f, 0xffd787, 0xffd7af,
0xffd7d7, 0xffd7ff, 0xffff00, 0xffff5f, 0xffff87, 0xffffaf, 0xffffd7, 0xffffff,
0x080808, 0x121212, 0x1c1c1c, 0x262626, 0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e,
0x585858, 0x626262, 0x6c6c6c, 0x767676, 0x808080, 0x8a8a8a, 0x949494, 0x9e9e9e,
0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6, 0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee
};
return 16 + convert_color(rgb, kColors, sizeof kColors / sizeof *kColors);
}
unsigned char rgb_color_t::to_term256_index() const
{
assert(type == type_rgb);
return term256_color_for_rgb(data.rgb);
}
unsigned char rgb_color_t::to_name_index() const
{
assert(type == type_named || type == type_rgb);
if (type == type_named)
{
return data.name_idx;
}
else if (type == type_rgb)
{
return term8_color_for_rgb(data.rgb);
}
else
{
/* This is an error */
return (unsigned char)(-1);
}
}
void rgb_color_t::parse(const wcstring &str)
{
bool success = false;
if (! success) success = try_parse_special(str);
if (! success) success = try_parse_named(str);
if (! success) success = try_parse_rgb(str);
if (! success)
{
bzero(this->data.rgb, sizeof this->data.rgb);
this->type = type_none;
}
}
rgb_color_t::rgb_color_t(const wcstring &str)
{
this->parse(str);
}
rgb_color_t::rgb_color_t(const std::string &str)
{
this->parse(str2wcstring(str));
}
wcstring rgb_color_t::description() const
{
switch (type)
{
case type_none:
return L"none";
case type_named:
return format_string(L"named(%d: %ls)", (int)data.name_idx, name_for_color_idx(data.name_idx));
case type_rgb:
return format_string(L"rgb(0x%02x%02x%02x)", data.rgb[0], data.rgb[1], data.rgb[2]);
case type_reset:
return L"reset";
case type_normal:
return L"normal";
case type_ignore:
return L"ignore";
default:
abort();
return L"";
}
}

177
color.h Normal file
View File

@@ -0,0 +1,177 @@
/** \file color.h Color class.
*/
#ifndef FISH_COLOR_H
#define FISH_COLOR_H
#include <stdint.h>
#include <cstddef>
#include "config.h"
#include "common.h"
/* A type that represents a color. We work hard to keep it at a size of 4 bytes. */
class rgb_color_t
{
/* Types */
enum
{
type_none,
type_named,
type_rgb,
type_normal,
type_reset,
type_ignore
};
unsigned char type:4;
/* Flags */
enum
{
flag_bold = 1 << 0,
flag_underline = 1 << 1
};
unsigned char flags:4;
union
{
unsigned char name_idx; //0-10
unsigned char rgb[3];
} data;
/** Try parsing a special color name like "normal" */
bool try_parse_special(const wcstring &str);
/** Try parsing an rgb color like "#F0A030" */
bool try_parse_rgb(const wcstring &str);
/** Try parsing an explicit color name like "magenta" */
bool try_parse_named(const wcstring &str);
/* Parsing entry point */
void parse(const wcstring &str);
/** Private constructor */
explicit rgb_color_t(unsigned char t, unsigned char i=0);
public:
/** Default constructor of type none */
explicit rgb_color_t() : type(type_none), flags(), data() {}
/** Parse a color from a string */
explicit rgb_color_t(const wcstring &str);
explicit rgb_color_t(const std::string &str);
/** Returns white */
static rgb_color_t white();
/** Returns black */
static rgb_color_t black();
/** Returns the reset special color */
static rgb_color_t reset();
/** Returns the normal special color */
static rgb_color_t normal();
/** Returns the ignore special color */
static rgb_color_t ignore();
/** Returns the none special color */
static rgb_color_t none();
/** Returns whether the color is the ignore special color */
bool is_ignore(void) const
{
return type == type_ignore;
}
/** Returns whether the color is the normal special color */
bool is_normal(void) const
{
return type == type_normal;
}
/** Returns whether the color is the reset special color */
bool is_reset(void) const
{
return type == type_reset;
}
/** Returns whether the color is the none special color */
bool is_none(void) const
{
return type == type_none;
}
/** Returns whether the color is a named color (like "magenta") */
bool is_named(void) const
{
return type == type_named;
}
/** Returns whether the color is specified via RGB components */
bool is_rgb(void) const
{
return type == type_rgb;
}
/** Returns whether the color is special, that is, not rgb or named */
bool is_special(void) const
{
return type != type_named && type != type_rgb;
}
/** Returns a description of the color */
wcstring description() const;
/** Returns the name index for the given color. Requires that the color be named or RGB. */
unsigned char to_name_index() const;
/** Returns the term256 index for the given color. Requires that the color be named or RGB. */
unsigned char to_term256_index() const;
/** Returns whether the color is bold */
bool is_bold() const
{
return !!(flags & flag_bold);
}
/** Set whether the color is bold */
void set_bold(bool x)
{
if (x) flags |= flag_bold;
else flags &= ~flag_bold;
}
/** Returns whether the color is underlined */
bool is_underline() const
{
return !!(flags & flag_underline);
}
/** Set whether the color is underlined */
void set_underline(bool x)
{
if (x) flags |= flag_underline;
else flags &= ~flag_underline;
}
/** Compare two colors for equality */
bool operator==(const rgb_color_t &other) const
{
return type == other.type && ! memcmp(&data, &other.data, sizeof data);
}
/** Compare two colors for inequality */
bool operator!=(const rgb_color_t &other) const
{
return !(*this == other);
}
/** Returns the names of all named colors */
static wcstring_list_t named_color_names(void);
};
#endif

1859
common.c

File diff suppressed because it is too large Load Diff

2302
common.cpp Normal file

File diff suppressed because it is too large Load Diff

531
common.h
View File

@@ -12,9 +12,28 @@
#include <stdio.h>
#include <wchar.h>
#include <termios.h>
#include <string>
#include <sstream>
#include <vector>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "util.h"
/**
Avoid writing the type name twice in a common "static_cast-initialization".
Caveat: This doesn't work with type names containing commas!
*/
#define CAST_INIT(type, dst, src) type dst = static_cast<type >(src)
class completion_t;
/* Common string type */
typedef std::wstring wcstring;
typedef std::vector<wcstring> wcstring_list_t;
/**
Maximum number of bytes used by a single utf-8 character
*/
@@ -50,15 +69,27 @@
*/
#define UNESCAPE_INCOMPLETE 2
/**
Escape all characters, including magic characters like the semicolon
*/
#define ESCAPE_ALL 1
/**
Do not try to use 'simplified' quoted escapes, and do not use empty quotes as the empty string
*/
#define ESCAPE_NO_QUOTED 2
/* Flags for the escape() and escape_string() functions */
enum
{
/** Escape all characters, including magic characters like the semicolon */
ESCAPE_ALL = 1 << 0,
/** Do not try to use 'simplified' quoted escapes, and do not use empty quotes as the empty string */
ESCAPE_NO_QUOTED = 1 << 1,
/** Do not escape tildes */
ESCAPE_NO_TILDE = 1 << 2
};
typedef unsigned int escape_flags_t;
/**
Helper macro for errors
*/
#define VOMIT_ON_FAILURE(a) do { if (0 != (a)) { int err = errno; fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", #a, __LINE__, __FILE__, err, strerror(err)); abort(); }} while (0)
/** Exits without invoking destructors (via _exit), useful for code after fork. */
void exit_without_destructors(int code) __attribute__((noreturn));
/**
Save the shell mode on startup so we can restore them on exit
@@ -71,6 +102,9 @@ extern struct termios shell_modes;
*/
extern wchar_t ellipsis_char;
/* Character representing an omitted newline at the end of text */
extern wchar_t omitted_newline_char;
/**
The verbosity level of fish. If a call to debug has a severity
level higher than \c debug_level, it will not be printed.
@@ -86,19 +120,19 @@ extern char *profile;
Name of the current program. Should be set at startup. Used by the
debug function.
*/
extern wchar_t *program_name;
extern const wchar_t *program_name;
/**
This macro is used to check that an input argument is not null. It
is a bit lika a non-fatal form of assert. Instead of exit-ing on
failiure, the current function is ended at once. The second
parameter is the return value of the current function on failiure.
failure, the current function is ended at once. The second
parameter is the return value of the current function on failure.
*/
#define CHECK( arg, retval ) \
if( !(arg) ) \
if (!(arg)) \
{ \
debug( 0, \
_( L"function %s called with null value for argument %s. " ), \
"function %s called with null value for argument %s. ", \
__func__, \
#arg ); \
bugreport(); \
@@ -111,12 +145,12 @@ extern wchar_t *program_name;
*/
#define FATAL_EXIT() \
{ \
int exit_read_count;char exit_read_buff; \
char exit_read_buff; \
show_stackframe(); \
exit_read_count=read( 0, &exit_read_buff, 1 ); \
exit( 1 ); \
read( 0, &exit_read_buff, 1 ); \
exit_without_destructors( 1 ); \
} \
/**
Exit program at once, leaving an error message about running out of memory.
@@ -124,8 +158,8 @@ extern wchar_t *program_name;
#define DIE_MEM() \
{ \
fwprintf( stderr, \
L"fish: Out of memory on line %d of file %s, shutting down fish\n", \
__LINE__, \
L"fish: Out of memory on line %ld of file %s, shutting down fish\n", \
(long)__LINE__, \
__FILE__ ); \
FATAL_EXIT(); \
}
@@ -134,11 +168,11 @@ extern wchar_t *program_name;
Check if signals are blocked. If so, print an error message and
return from the function performing this check.
*/
#define CHECK_BLOCK( retval ) \
if( signal_is_blocked() ) \
#define CHECK_BLOCK(retval) \
if (signal_is_blocked()) \
{ \
debug( 0, \
_( L"function %s called while blocking signals. " ), \
"function %s called while blocking signals. ", \
__func__); \
bugreport(); \
show_stackframe(); \
@@ -157,63 +191,38 @@ extern wchar_t *program_name;
#define N_(wstr) wstr
/**
Check if the specified stringelement is a part of the specified string list
Check if the specified string element 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 )
#define contains( str,... ) contains_internal( str, __VA_ARGS__, NULL )
/**
Print a stack trace to stderr
*/
void show_stackframe();
/**
Take an array_list_t containing wide strings and converts them to a
single null-terminated wchar_t **. The array is allocated using
malloc, and needs to be fred's by the caller.
*/
wchar_t **list_to_char_arr( array_list_t *l );
/**
Read a line from the stream f into the buffer buff of length len. If
buff is to small, it will be reallocated, and both buff and len will
be updated to reflect this. Returns the number of bytes read or -1
on failiure.
Read a line from the stream f into the string. Returns
the number of bytes read or -1 on failure.
If the carriage return character is encountered, it is
ignored. fgetws() considers the line to end if reading the file
results in either a newline (L'\n') character, the null (L'\\0')
character or the end of file (WEOF) character.
*/
int fgetws2( wchar_t **buff, int *len, FILE *f );
int fgetws2(wcstring *s, FILE *f);
/**
Sorts an array_list of wide strings according to the
wcsfilecmp-function from the util library
*/
void sort_list( array_list_t *comp );
Returns a wide character string equivalent of the
specified multibyte character string
/**
Returns a newly allocated wide character string equivalent of the
specified multibyte character string
This function encodes illegal character sequences in a reversible
way using the private use area.
*/
wchar_t *str2wcs( const char *in );
/**
Converts the narrow character string \c in into it's wide
equivalent, stored in \c out. \c out must have enough space to fit
the entire string.
This function encodes illegal character sequences in a reversible
way using the private use area.
*/
wchar_t *str2wcs_internal( const char *in, wchar_t *out );
This function encodes illegal character sequences in a reversible
way using the private use area.
*/
wcstring str2wcstring(const char *in);
wcstring str2wcstring(const char *in, size_t len);
wcstring str2wcstring(const std::string &in);
/**
Returns a newly allocated multibyte character string equivalent of
@@ -222,40 +231,291 @@ wchar_t *str2wcs_internal( const char *in, wchar_t *out );
This function decodes illegal character sequences in a reversible
way using the private use area.
*/
char *wcs2str( const wchar_t *in );
char *wcs2str(const wchar_t *in);
char *wcs2str(const wcstring &in);
std::string wcs2string(const wcstring &input);
/** Test if a string prefixes another. Returns true if a is a prefix of b */
bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value);
bool string_prefixes_string(const wchar_t *proposed_prefix, const wcstring &value);
/** Test if a string is a suffix of another */
bool string_suffixes_string(const wcstring &proposed_suffix, const wcstring &value);
bool string_suffixes_string(const wchar_t *proposed_suffix, const wcstring &value);
/** Test if a string prefixes another without regard to case. Returns true if a is a prefix of b */
bool string_prefixes_string_case_insensitive(const wcstring &proposed_prefix, const wcstring &value);
/** Test if a list contains a string using a linear search. */
bool list_contains_string(const wcstring_list_t &list, const wcstring &str);
void assert_is_main_thread(const char *who);
#define ASSERT_IS_MAIN_THREAD_TRAMPOLINE(x) assert_is_main_thread(x)
#define ASSERT_IS_MAIN_THREAD() ASSERT_IS_MAIN_THREAD_TRAMPOLINE(__FUNCTION__)
void assert_is_background_thread(const char *who);
#define ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(x) assert_is_background_thread(x)
#define ASSERT_IS_BACKGROUND_THREAD() ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(__FUNCTION__)
/* Useful macro for asserting that a lock is locked. This doesn't check whether this thread locked it, which it would be nice if it did, but here it is anyways. */
void assert_is_locked(void *mutex, const char *who, const char *caller);
#define ASSERT_IS_LOCKED(x) assert_is_locked((void *)(&x), #x, __FUNCTION__)
/** Format the specified size (in bytes, kilobytes, etc.) into the specified stringbuffer. */
wcstring format_size(long long sz);
/** Version of format_size that does not allocate memory. */
void format_size_safe(char buff[128], unsigned long long sz);
/** Our crappier versions of debug which is guaranteed to not allocate any memory, or do anything other than call write(). This is useful after a call to fork() with threads. */
void debug_safe(int level, const char *msg, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL, const char *param5 = NULL, const char *param6 = NULL, const char *param7 = NULL, const char *param8 = NULL, const char *param9 = NULL, const char *param10 = NULL, const char *param11 = NULL, const char *param12 = NULL);
/** Writes out a long safely */
void format_long_safe(char buff[128], long val);
void format_long_safe(wchar_t buff[128], long val);
template<typename T>
T from_string(const wcstring &x)
{
T result;
std::wstringstream stream(x);
stream >> result;
return result;
}
template<typename T>
T from_string(const std::string &x)
{
T result = T();
std::stringstream stream(x);
stream >> result;
return result;
}
template<typename T>
wcstring to_string(const T &x)
{
std::wstringstream stream;
stream << x;
return stream.str();
}
/* wstringstream is a huge memory pig. Let's provide some specializations where we can. */
template<>
inline wcstring to_string(const long &x)
{
wchar_t buff[128];
format_long_safe(buff, x);
return wcstring(buff);
}
template<>
inline bool from_string(const std::string &x)
{
return ! x.empty() && strchr("YTyt1", x.at(0));
}
template<>
inline bool from_string(const wcstring &x)
{
return ! x.empty() && wcschr(L"YTyt1", x.at(0));
}
template<>
inline wcstring to_string(const int &x)
{
return to_string(static_cast<long>(x));
}
wchar_t **make_null_terminated_array(const wcstring_list_t &lst);
char **make_null_terminated_array(const std::vector<std::string> &lst);
/* Helper class for managing a null-terminated array of null-terminated strings (of some char type) */
template <typename CharType_t>
class null_terminated_array_t
{
CharType_t **array;
/* No assignment or copying */
void operator=(null_terminated_array_t rhs);
null_terminated_array_t(const null_terminated_array_t &);
typedef std::vector<std::basic_string<CharType_t> > string_list_t;
size_t size() const
{
size_t len = 0;
if (array != NULL)
{
while (array[len] != NULL)
{
len++;
}
}
return len;
}
void free(void)
{
::free((void *)array);
array = NULL;
}
public:
null_terminated_array_t() : array(NULL) { }
null_terminated_array_t(const string_list_t &argv) : array(make_null_terminated_array(argv))
{
}
~null_terminated_array_t()
{
this->free();
}
void set(const string_list_t &argv)
{
this->free();
this->array = make_null_terminated_array(argv);
}
const CharType_t * const *get() const
{
return array;
}
void clear()
{
this->free();
}
};
/* Helper function to convert from a null_terminated_array_t<wchar_t> to a null_terminated_array_t<char_t> */
void convert_wide_array_to_narrow(const null_terminated_array_t<wchar_t> &arr, null_terminated_array_t<char> *output);
/* Helper class to cache a narrow version of a wcstring in a malloc'd buffer, so that we can read it after fork() */
class narrow_string_rep_t
{
private:
const char *str;
/* No copying */
narrow_string_rep_t &operator=(const narrow_string_rep_t &);
narrow_string_rep_t(const narrow_string_rep_t &x);
public:
~narrow_string_rep_t()
{
free((void *)str);
}
narrow_string_rep_t() : str(NULL) {}
void set(const wcstring &s)
{
free((void *)str);
str = wcs2str(s.c_str());
}
const char *get() const
{
return str;
}
};
bool is_forked_child();
/* Basic scoped lock class */
class scoped_lock
{
pthread_mutex_t *lock_obj;
bool locked;
/* No copying */
scoped_lock &operator=(const scoped_lock &);
scoped_lock(const scoped_lock &);
public:
void lock(void);
void unlock(void);
scoped_lock(pthread_mutex_t &mutex);
~scoped_lock();
};
/**
Converts the wide character string \c in into it's narrow
equivalent, stored in \c out. \c out must have enough space to fit
the entire string.
A scoped manager to save the current value of some variable, and optionally
set it to a new value. On destruction it restores the variable to its old
value.
This function decodes illegal character sequences in a reversible
way using the private use area.
This can be handy when there are multiple code paths to exit a block.
*/
char *wcs2str_internal( const wchar_t *in, char *out );
template <typename T>
class scoped_push
{
T * const ref;
T saved_value;
bool restored;
public:
scoped_push(T *r): ref(r), saved_value(*r), restored(false)
{
}
scoped_push(T *r, const T &new_value) : ref(r), saved_value(*r), restored(false)
{
*r = new_value;
}
~scoped_push()
{
restore();
}
void restore()
{
if (!restored)
{
std::swap(*ref, saved_value);
restored = true;
}
}
};
/* Wrapper around wcstok */
class wcstokenizer
{
wchar_t *buffer, *str, *state;
const wcstring sep;
/* No copying */
wcstokenizer &operator=(const wcstokenizer &);
wcstokenizer(const wcstokenizer &);
public:
wcstokenizer(const wcstring &s, const wcstring &separator);
bool next(wcstring &result);
~wcstokenizer();
};
/**
Appends a path component, with a / if necessary
*/
void append_path_component(wcstring &path, const wcstring &component);
wcstring format_string(const wchar_t *format, ...);
wcstring vformat_string(const wchar_t *format, va_list va_orig);
void append_format(wcstring &str, const wchar_t *format, ...);
void append_formatv(wcstring &str, const wchar_t *format, va_list ap);
/**
Returns a newly allocated wide character string array equivalent of
the specified multibyte character string array
*/
char **wcsv2strv( const wchar_t **in );
/**
Returns a newly allocated multibyte character string array equivalent of the specified wide character string array
*/
wchar_t **strv2wcsv( const char **in );
/**
Returns a newly allocated concatenation of the specified wide
character strings. The last argument must be a null pointer.
*/
__sentinel wchar_t *wcsdupcat_internal( const wchar_t *a, ... );
/**
Test if the given string is a valid variable name
*/
char **wcsv2strv(const wchar_t * const *in);
/**
Test if the given string is a valid variable name.
@@ -263,7 +523,7 @@ __sentinel wchar_t *wcsdupcat_internal( const wchar_t *a, ... );
\return null if this is a valid name, and a pointer to the first invalid character otherwise
*/
wchar_t *wcsvarname( const wchar_t *str );
wchar_t *wcsvarname(const wchar_t *str);
/**
@@ -272,7 +532,7 @@ wchar_t *wcsvarname( const wchar_t *str );
\return null if this is a valid name, and a pointer to the first invalid character otherwise
*/
wchar_t *wcsfuncname( const wchar_t *str );
const wchar_t *wcsfuncname(const wchar_t *str);
/**
Test if the given string is valid in a variable name
@@ -280,13 +540,13 @@ wchar_t *wcsfuncname( const wchar_t *str );
\return 1 if this is a valid name, 0 otherwise
*/
int wcsvarchr( wchar_t chr );
int wcsvarchr(wchar_t chr);
/**
A wcswidth workalike. Fish uses this since the regular wcswidth seems flaky.
*/
int my_wcswidth( const wchar_t *c );
int my_wcswidth(const wchar_t *c);
/**
This functions returns the end of the quoted substring beginning at
@@ -295,7 +555,7 @@ int my_wcswidth( const wchar_t *c );
\param in the position of the opening quote
*/
wchar_t *quote_end( const wchar_t *in );
wchar_t *quote_end(const wchar_t *in);
/**
A call to this function will reset the error counter. Some
@@ -313,7 +573,7 @@ void error_reset();
the user is using a Unicode character set, and if so, use the
unicode ellipsis character as ellipsis, instead of '$'.
*/
const wchar_t *wsetlocale( int category, const wchar_t *locale );
wcstring wsetlocale(int category, const wchar_t *locale);
/**
Checks if \c needle is included in the list of strings specified. A warning is printed if needle is zero.
@@ -322,20 +582,27 @@ const wchar_t *wsetlocale( int category, const wchar_t *locale );
\return zero if needle is not found, of if needle is null, non-zero otherwise
*/
__sentinel int contains_internal( const wchar_t *needle, ... );
__sentinel bool contains_internal(const wchar_t *needle, ...);
__sentinel bool contains_internal(const wcstring &needle, ...);
/**
Call read while blocking the SIGCHLD signal. Should only be called
if you _know_ there is data available for reading, or the program
will hang until there is data.
*/
int read_blocked(int fd, void *buf, size_t count);
long read_blocked(int fd, void *buf, size_t count);
/**
Loop a write request while failiure is non-critical. Return -1 and set errno
Loop a write request while failure is non-critical. Return -1 and set errno
in case of critical error.
*/
ssize_t write_loop(int fd, char *buff, size_t count);
ssize_t write_loop(int fd, const char *buff, size_t count);
/**
Loop a read request while failure is non-critical. Return -1 and set errno
in case of critical error.
*/
ssize_t read_loop(int fd, void *buff, size_t count);
/**
@@ -356,7 +623,8 @@ ssize_t write_loop(int fd, char *buff, size_t count);
will print the string 'fish: Pi = 3.141', given that debug_level is 1 or higher, and that program_name is 'fish'.
*/
void debug( int level, const wchar_t *msg, ... );
void debug(int level, const char *msg, ...);
void debug(int level, const wchar_t *msg, ...);
/**
Replace special characters with backslash escape sequences. Newline is
@@ -367,7 +635,8 @@ void debug( int level, const wchar_t *msg, ... );
\return The escaped string, or 0 if there is not enough memory
*/
wchar_t *escape( const wchar_t *in, int escape_all );
wchar_t *escape(const wchar_t *in, escape_flags_t flags);
wcstring escape_string(const wcstring &in, escape_flags_t flags);
/**
Expand backslashed escapes and substitute them with their unescaped
@@ -380,19 +649,12 @@ wchar_t *escape( const wchar_t *in, int escape_all );
an invalid sequence is specified, 0 is returned.
*/
wchar_t *unescape( const wchar_t * in,
int escape_special );
wchar_t *unescape(const wchar_t * in,
int escape_special);
bool unescape_string(wcstring &str,
int escape_special);
/**
Attempt to acquire a lock based on a lockfile, waiting LOCKPOLLINTERVAL
milliseconds between polls and timing out after timeout seconds,
thereafter forcibly attempting to obtain the lock if force is non-zero.
Returns 1 on success, 0 on failure.
To release the lock the lockfile must be unlinked.
A unique temporary file named by appending characters to the lockfile name
is used; any pre-existing file of the same name is subject to deletion.
*/
int acquire_lock_file( const char *lockfile, const int timeout, int force );
/**
Returns the width of the terminal window, so that not all
@@ -416,23 +678,20 @@ int common_get_height();
saving it in an internal variable used by common_get_wisth and
common_get_height().
*/
void common_handle_winch( int signal );
void common_handle_winch(int signal);
/**
Write paragraph of output to the specified stringbuffer, and redo
the linebreaks to fit the current screen.
*/
void write_screen( const wchar_t *msg, string_buffer_t *buff );
void write_screen(const wcstring &msg, wcstring &buff);
/**
Tokenize the specified string into the specified array_list_t.
Each new element is allocated using malloc and must be freed by the
caller.
Tokenize the specified string into the specified wcstring_list_t.
\param val the input string. The contents of this string is not changed.
\param out the list in which to place the elements.
*/
void tokenize_variable_array( const wchar_t *val, array_list_t *out );
void tokenize_variable_array(const wcstring &val, wcstring_list_t &out);
/**
Make sure the specified direcotry exists. If needed, try to create
@@ -440,19 +699,13 @@ void tokenize_variable_array( const wchar_t *val, array_list_t *out );
\return 0 if, at the time of function return the directory exists, -1 otherwise.
*/
int create_directory( wchar_t *d );
int create_directory(const wcstring &d);
/**
Print a short message about how to file a bug report to stderr
*/
void bugreport();
/**
Format the specified size (in bytes, kilobytes, etc.) into the specified stringbuffer.
*/
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
@@ -462,6 +715,34 @@ void sb_format_size( string_buffer_t *sb,
*/
double timef();
/**
Call the following function early in main to set the main thread.
This is our replacement for pthread_main_np().
*/
void set_main_thread();
bool is_main_thread();
/** Configures thread assertions for testing */
void configure_thread_assertions_for_testing();
/** Set up a guard to complain if we try to do certain things (like take a lock) after calling fork */
void setup_fork_guards(void);
/** Save the value of tcgetpgrp so we can restore it on exit */
void save_term_foreground_process_group(void);
void restore_term_foreground_process_group(void);
/** Return whether we are the child of a fork */
bool is_forked_child(void);
void assert_is_not_forked_child(const char *who);
#define ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(x) assert_is_not_forked_child(x)
#define ASSERT_IS_NOT_FORKED_CHILD() ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(__FUNCTION__)
extern "C" {
__attribute__((noinline)) void debug_thread_error(void);
}
/** Return the path of an appropriate runtime data directory */
std::string common_get_runtime_path();
#endif

2158
complete.c

File diff suppressed because it is too large Load Diff

2102
complete.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
/** \file complete.h
Prototypes for functions related to tab-completion.
Prototypes for 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.
*/
#ifndef FISH_COMPLETE_H
@@ -12,123 +12,153 @@
*/
#define FISH_COMPLETE_H
#include <wchar.h>
#include "util.h"
#include "common.h"
/**
Use all completions
*/
* Use all completions
*/
#define SHARED 0
/**
Do not use file completion
*/
* Do not use file completion
*/
#define NO_FILES 1
/**
Require a parameter after completion
*/
* Require a parameter after completion
*/
#define NO_COMMON 2
/**
Only use the argument list specifies with completion after
option. This is the same as (NO_FILES & NO_COMMON)
*/
* Only use the argument list specifies with completion after
* option. This is the same as (NO_FILES & NO_COMMON)
*/
#define EXCLUSIVE 3
/**
Command is a path
*/
* Command is a path
*/
#define PATH 1
/**
Command is not a path
*/
* Command is not a path
*/
#define COMMAND 0
/**
Separator between completion and description
*/
* Separator between completion and description
*/
#define COMPLETE_SEP L'\004'
/**
Separator between completion and description
*/
* Separator between completion and description
*/
#define COMPLETE_SEP_STR L"\004"
/**
Separator between completion items in fish_pager. This is used for
completion grouping, e.g. when putting completions with the same
descriptions on the same line.
*/
* Separator between completion items in fish_pager. This is used for
* completion grouping, e.g. when putting completions with the same
* descriptions on the same line.
*/
#define COMPLETE_ITEM_SEP L'\uf500'
/**
Character that separates the completion and description on
programmable completions
*/
* Character that separates the completion and description on
* programmable completions
*/
#define PROG_COMPLETE_SEP L'\t'
/**
Do not insert space afterwards if this is the only completion. (The
default is to try insert a space)
*/
#define COMPLETE_NO_SPACE 1
enum
{
/**
Do not insert space afterwards if this is the only completion. (The
default is to try insert a space)
*/
COMPLETE_NO_SPACE = 1 << 0,
/**
This compeltion is case insensitive.
/** This completion is case insensitive. */
COMPLETE_CASE_INSENSITIVE = 1 << 1,
Warning: The contents of the completion_t structure is actually
different if this flag is set! Specifically, the completion string
contains the _entire_ completion token, not only the current
*/
#define COMPLETE_NO_CASE 2
/** This is not the suffix of a token, but replaces it entirely */
COMPLETE_REPLACES_TOKEN = 1 << 2,
/**
This compeltion is the whole argument, not just the remainder. This
flag must never be set on completions returned from the complete()
function. It is strictly for internal use in the completion code.
*/
#define COMPLETE_WHOLE_ARGUMENT 4
/**
This completion may or may not want a space at the end - guess by
checking the last character of the completion.
*/
COMPLETE_AUTO_SPACE = 1 << 3,
/**
This completion may or may not want a space at the end - guess by
checking the last character of the completion.
*/
#define COMPLETE_AUTO_SPACE 8
/** This completion should be inserted as-is, without escaping. */
COMPLETE_DONT_ESCAPE = 1 << 4,
/**
This completion should be inserted as-is, without escaping.
*/
#define COMPLETE_DONT_ESCAPE 16
/** If you do escape, don't escape tildes */
COMPLETE_DONT_ESCAPE_TILDES = 1 << 5
};
typedef int complete_flags_t;
typedef struct
class completion_t
{
/**
The completion string
*/
const wchar_t *completion;
private:
/* No public default constructor */
completion_t();
public:
/**
The description for this completion
*/
const wchar_t *description;
/* Destructor. Not inlining it saves code size. */
~completion_t();
/**
Flags determining the completion behaviour.
/**
The completion string
*/
wcstring completion;
Determines whether a space should be inserted after this
compeltion if it is the only possible completion using the
COMPLETE_NO_SPACE flag.
/**
The description for this completion
*/
wcstring description;
The COMPLETE_NO_CASE can be used to signal that this completion
is case insensitive.
*/
int flags;
/**
Flags determining the completion behaviour.
}
completion_t;
Determines whether a space should be inserted after this
completion if it is the only possible completion using the
COMPLETE_NO_SPACE flag.
The COMPLETE_NO_CASE can be used to signal that this completion
is case insensitive.
*/
int flags;
bool is_case_insensitive() const
{
return !!(flags & COMPLETE_CASE_INSENSITIVE);
}
/* Construction. Note: defining these so that they are not inlined reduces the executable size. */
completion_t(const wcstring &comp, const wcstring &desc = L"", int flags_val = 0);
completion_t(const completion_t &);
completion_t &operator=(const completion_t &);
/* The following are needed for sorting and uniquing completions */
bool operator < (const completion_t& rhs) const;
bool operator == (const completion_t& rhs) const;
bool operator != (const completion_t& rhs) const;
};
enum
{
COMPLETION_REQUEST_DEFAULT = 0,
COMPLETION_REQUEST_AUTOSUGGESTION = 1 << 0, // indicates the completion is for an autosuggestion
COMPLETION_REQUEST_DESCRIPTIONS = 1 << 1, // indicates that we want descriptions
COMPLETION_REQUEST_FUZZY_MATCH = 1 << 2 // indicates that we don't require a prefix match
};
typedef uint32_t completion_request_flags_t;
/** Given a list of completions, returns a list of their completion fields */
wcstring_list_t completions_to_wcstring_list(const std::vector<completion_t> &completions);
/** Sorts a list of completions */
void sort_completions(std::vector<completion_t> &completions);
/**
@@ -155,83 +185,83 @@ typedef struct
\param cmd Command to complete.
\param cmd_type If cmd_type is PATH, cmd will be interpreted as the absolute
path of the program (optionally containing wildcards), otherwise it
will be interpreted as the command name.
\param short_opt The single character name of an option. (-a is a short option, --all and -funroll are long options)
\param long_opt The multi character name of an option. (-a is a short option, --all and -funroll are long options)
path of the program (optionally containing wildcards), otherwise it
will be interpreted as the command name.
\param short_opt The single character name of an option. (-a is a short option,
--all and -funroll are long options)
\param long_opt The multi character name of an option. (-a is a short option,
--all and -funroll are long options)
\param long_mode Whether to use old style, single dash long options.
\param result_mode Whether to search further completions when this
completion has been succesfully matched. If result_mode is SHARED,
any other completions may also be used. If result_mode is NO_FILES,
file completion should not be used, but other completions may be
used. If result_mode is NO_COMMON, on option may follow it - only a
parameter. If result_mode is EXCLUSIVE, no option may follow it, and
file completion is not performed.
completion has been succesfully matched. If result_mode is SHARED,
any other completions may also be used. If result_mode is NO_FILES,
file completion should not be used, but other completions may be
used. If result_mode is NO_COMMON, on option may follow it - only a
parameter. If result_mode is EXCLUSIVE, no option may follow it, and
file completion is not performed.
\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 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 );
void complete_add(const wchar_t *cmd,
bool cmd_is_path,
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 );
void complete_set_authoritative(const wchar_t *cmd, bool cmd_type, bool 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 );
void complete_remove(const wchar_t *cmd,
bool cmd_is_path,
wchar_t short_opt,
const wchar_t *long_opt);
/** Find all completions of the command cmd, insert them into out. If to_load is
* not NULL, append all commands that we would autoload, but did not (presumably
* because this is not the main thread)
*/
void complete(const wcstring &cmd,
std::vector<completion_t> &comp,
completion_request_flags_t flags,
wcstring_list_t *to_load = NULL);
/**
Find all completions of the command cmd, insert them into out. The
caller must free the variables returned in out. The results are
returned in the array_list_t 'out', in the format of wide character
strings, with each element consisting of a suggested completion and
a description of what kind of object this completion represents,
separated by a separator of type COMPLETE_SEP.
Print a list of all current completions into the string.
Values returned by this function should be freed by the caller.
\param out The string to write completions to
*/
void complete( const wchar_t *cmd, array_list_t *out );
/**
Print a list of all current completions into the string_buffer_t.
\param out The string_buffer_t to write completions to
*/
void complete_print( string_buffer_t *out );
void complete_print(wcstring &out);
/**
Tests if the specified option is defined for the specified command
*/
int complete_is_valid_option( const wchar_t *str,
const wchar_t *opt,
array_list_t *errors );
int complete_is_valid_option(const wcstring &str,
const wcstring &opt,
wcstring_list_t *inErrorsOrNull,
bool allow_autoload);
/**
Tests if the specified argument is valid for the specified option
and command
*/
int complete_is_valid_argument( const wchar_t *str,
const wchar_t *opt,
const wchar_t *arg );
bool complete_is_valid_argument(const wcstring &str,
const wcstring &opt,
const wcstring &arg);
/**
@@ -241,22 +271,24 @@ int complete_is_valid_argument( const wchar_t *str,
with internal dependencies.
\param cmd the command for which to load command-specific completions
\param reload should the commands completions be reloaded, even if they where previously loaded. (This is set to true on actual completions, so that changed completion are updated in running shells)
\param reload should the commands completions be reloaded, even if they where
previously loaded. (This is set to true on actual completions, so that
changed completion are updated in running shells)
*/
void complete_load( const wchar_t *cmd, int reload );
void complete_load(const wcstring &cmd, bool reload);
/**
Create a new completion entry
\param context The halloc context to use for allocating new memory
\param completions The array of completions to append to
\param comp The completion string
\param desc The description of the completion
\param flags completion flags
*/
void completion_allocate( array_list_t *context,
const wchar_t *comp,
const wchar_t *desc,
int flags );
*/
void append_completion(std::vector<completion_t> &completions, const wcstring &comp, const wcstring &desc = L"", int flags = 0);
/* Function used for testing */
void complete_set_variable_names(const wcstring_list_t *names);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -6,13 +6,29 @@ alias NAME=DEFINITION</pre>
\subsection alias-description Description
Alias is a shellscript wrapper around the function builtin.
\c alias is a simple wrapper for the \c function builtin.
It exists for backwards compatibility with Posix
shells. For other uses, it is recommended to define a <a
href='#function'>function</a>.
Alias does not keep track of which functions have been defined using
alias, nor does it allow erasing of aliases.
\c fish does not keep track of which functions have been defined using
\c alias. They must be erased using <code>functions -e</code>.
- NAME is the name of the alias
- DEFINITION is the actual command to execute. The string " $argv" will be appended.
You cannot create an alias to a function with the same name.
\subsection alias-example Example
The following code will create \c rmi, which runs \c rm with additional
arguments on every invocation.
<code>alias rmi "rm -i"</code>
This is equivalent to entering the following function:
<pre>function rmi
rm -i $argv
end</pre>
- NAME is the name of the function to define
- DEFINITION is the body of the function. The string " $argv" will be appended to the body.

View File

@@ -5,10 +5,10 @@
\subsection and-description Description
The \c and builtin is used to execute a command if the current exit
\c and is used to execute a command if the current exit
status (as set by the last previous command) is 0.
The and command does not change the current exit status.
\c and does not change the current exit status.
The exit status of the last foreground command to exit can always be
accessed using the <a href="index.html#variables-status">$status</a>
@@ -16,10 +16,10 @@ variable.
\subsection and-example Example
The following code runs the \c make command to build a program, if the
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
The following code runs the \c make command to build a program. If the
build succeeds, <code>make</code>'s exit status is 0, and the program is installed. If either step fails,
the exit status is 1, and <tt>make clean</tt> is run, which removes the files created by the.
build process.
<pre>
make; and make install; or make clean

View File

@@ -5,15 +5,18 @@
\subsection begin-description Description
The \c begin builtin is used to create a new block of code. The block
\c begin is used to create a new block of code.
The block
is unconditionally executed. <code>begin; ...; end</tt> is equivalent
to <tt>if true; ...; end</tt>. The begin command is used to group any
number of commands into a block. The reason for doing so is usually
either to introduce a new variable scope, to redirect the input or
to <tt>if true; ...; end</tt>.
\c begin is used to group a number of commands into a block.
This allows the introduction of a new variable scope, redirection of the input or
output of a set of commands as a group, or to specify precedence when
using the conditional commands like \c and.
The \c begin command does not change the current exit status.
\c begin does not change the current exit status.
\subsection begin-example Example

View File

@@ -1,16 +1,17 @@
\section bg bg - send to background
\section bg bg - send jobs to background
\subsection bg-synopsis Synopsis
<tt>bg [PID...]</tt>
\subsection bg-description Description
Sends the specified jobs to the background. A background job is
\c bg sends <a href="index.html#syntax-job-control">jobs</a> to the background, resuming them if they are stopped. A background job is
executed simultaneously with fish, and does not have access to the
keyboard. If no job is specified, the last job to be used is put in the background. If PID is specified, the jobs with the specified group ids are put in the background.
keyboard. If no job is specified, the last job to be used is put in the background. If PID is specified, the jobs with the specified process group IDs are put in the background.
The PID of the desired process is usually found by using <a href="index.html#expand-process">process expansion</a>.
\subsection bg-example Example
<tt>bg \%0</tt> will put the job with job id 0 in the background.
<tt>bg \%1</tt> will put the job with job ID 1 in the background.

View File

@@ -5,33 +5,34 @@
\subsection bind-description Description
The <tt>bind</tt> builtin causes fish to add a key binding from the specified sequence.
<tt>bind</tt> adds a binding for the specified key sequence to the
specified command.
SEQUENCE is the character sequence to bind to. Usually, one would use
fish escape sequences to express them. For example, because pressing
SEQUENCE is the character sequence to bind to. These should be written as
<a href="index.html#escapes">fish escape sequences</a>. 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>\\ew</tt>. The control character can be written in much the same way
using the \c \\c escape, for example Control-x (^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.
Control-based key bindings are not. This is a constraint of text-based
termainls, not \c fish.
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
The default key binding can be set by specifying a SEQUENCE of the empty
string (that is, <code>''</code>). It will be used whenever no
other binding matches. For most key bindings, it makes sense to use
the \c self-insert function (i.e. <tt>bind '' self-insert</tt> as the
default keybining. This will insert any keystrokes not specifically
default keybinding. This will insert any keystrokes not specifically
bound to into the editor. Non-printable characters are ignored by the
editor, so this will not result in e.g. control sequences being
editor, so this will not result in control sequences being
printable.
If the -k switch is used, the name of the key (such as down, up or
backspace) is used instead of a sequence. The names used are the same
as the corresponding curses variables, but without the 'key_'
prefix. (See man 5 terminfo for more information, or use <tt>bind
--key-names</tt> for a list of all available named keys)
prefix. (See \c terminfo(5) for more information, or use <tt>bind
--key-names</tt> for a list of all available named keys.)
COMMAND can be any fish command, but it can also be one of a set of
special input functions. These include functions for moving the
@@ -45,16 +46,19 @@ bind to the function name. This way it becomes significantly easier to
test the function while editing, and the result is usually more
readable as well.
- <tt>-a</tt> or <tt>--all</tt> If --key-names is specified, show all key names, not only the ones that actually are defined for the current terminal. If erase mode is specified, this switch will cause all current bindings to be erased.
- <tt>-e</tt> or <tt>--erase</tt> Erase mode. All non-switch arguments are interpreted as character sequences and any commands associated with those sequences are erased.
- <tt>-h</tt> or <tt>--help</tt> Display help and exit
Key bindings are not saved between sessions by default. To save custom
keybindings, edit the \c fish_user_key_bindings function and insert the
appropirate \c bind statements.
The following parameters are available:
- <tt>-k</tt> or <tt>--key</tt> Specify a key name, such as 'left' or 'backspace' instead of a character sequence
- <tt>-K</tt> or <tt>--key-names</tt> Display a list of available key names
- <tt>-f</tt> or <tt>--function-names</tt> Display a list of available input functions
\subsection bind-example Example
\subsection bind-example Examples
<tt>bind \\cd 'exit'</tt> causes fish to exit on Control-d
<tt>bind \\cd 'exit'</tt> causes \c fish to exit when Control-d is pressed.
<tt>bind -k ppage history-search-backward</tt> Causes fish to perform a history search when the page up key is pressed
<tt>bind -k ppage history-search-backward</tt> performs a history search when the Page Up key is pressed.

View File

@@ -5,15 +5,36 @@
\subsection block-description Description
- <tt>-l</tt> or <tt>--local</tt> Release the block at the end of the currently innermost block scope
\c block prevents events triggered by \c fish or the
<a href="commands.html#emit"><code>emit</code></a> command from
being delivered and acted upon while the block is in place.
In functions, \c block can be useful while performing work that
should not be interrupted by the shell.
The block can be removed. Any events which triggered while the
block was in place will then be delivered.
Event blocks should not be confused with code blocks, which are created
with <code>begin</code>, <code>if</code>, <code>while</code> or
<code>for</code>
The following parameters are available:
- <tt>-l</tt> or <tt>--local</tt> Release the block automatically at the end of the current innermost code block scope
- <tt>-g</tt> or <tt>--global</tt> Never automatically release the lock
- <tt>-e</tt> or <tt>--erase</tt> Release global block
\subsection block-example Example
<pre>
# Create a function that listens for events
function --on-event foo foo; echo 'foo fired'; end
# Block the delivery of events
block -g
\#Do something that should not be interrupted
emit foo
# No output will be produced
block -e
# 'foo fired' will now be printed
</pre>

View File

@@ -1,13 +1,16 @@
\section break break - stop the innermost currently evaluated loop
\section break break - stop the current inner loop
\subsection break-synopsis Synopsis
<tt>LOOP_CONSTRUCT; [COMMANDS...] break; [COMMANDS...] end</tt>
\subsection break-description Description
The \c break builtin is used to halt a currently running loop, such as a <a href="#for">for</a> loop or a <a href="#while">while</a> loop. It is usually added inside of a conditional block such as an <a href="#if">if</a> statement or a <a href="#switch">switch</a> statement.
\c break halts a currently running loop, such as a <a href="#for">for</a> loop or a <a href="#while">while</a> loop. It is usually added inside of a conditional block such as an <a href="#if">if</a> statement or a <a href="#switch">switch</a> statement.
There are no parameters for <code>break</code>.
\subsection break-example Example
The following code searches all .c files for smurfs, and halts at the first occurrence.
The following code searches all .c files for "smurf", and halts at the first occurrence.
<pre>
for i in *.c

View File

@@ -5,6 +5,10 @@
\subsection breakpoint-description Description
The \c breakpoint builtin is used to halt a running script and launch
an interactive debug prompt.
\c breakpoint is used to halt a running script and launch
an interactive debugging prompt.
For more details, see <a href="index.html#debugging">Debugging fish
scripts</a> in the \c fish manual.
There are no parameters for <code>breakpoint</code>.

View File

@@ -5,12 +5,12 @@
\subsection builtin-description Description
- <tt>-n</tt> or <tt>--names</tt> List the names of all defined builtins
\c builtin forces the shell to use a builtin command, rather than a function or program.
Prefixing a command with the word 'builtin' forces fish to ignore any functions with the same name.
The following parameters are available:
- <tt>-n</tt> or <tt>--names</tt> List the names of all defined builtins
\subsection builtin-example Example
<tt>builtin jobs</tt>
causes fish to execute the jobs builtin, even if a function named jobs exists.
<tt>builtin jobs</tt> executes the jobs builtin, even if a function named jobs exists.

View File

@@ -5,27 +5,24 @@
\subsection case-description Description
The \c switch statement is used to perform one of several blocks of
commands depending on whether a specified value equals one of several
wildcarded values. The \c case statement is used together with the \c
switch statement in order to determine which block should be
performed.
\c switch performs one of several blocks of commands, depending on whether
a specified value equals one of several wildcarded values. \c case is used
together with the \c switch statement in order to determine which block should
be executed.
Each \c case command is given one or more parameter. The first \c case
Each \c case command is given one or more parameters. The first \c case
command with a parameter that matches the string specified in the
switch command will be evaluated. \c case parameters may contain
wildcards. These need to be escaped or quoted in order to avoid
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 statements of traditional shells.
Note that fish does not fall through on case statements. Only the
first matching case is executed.
Also note that command substitutions in a case statement will be
evaluated even if it's body is not taken. This may seem
counterintuitive at first, but it is unavoidable, since it would be
impossible to know if a case command will evaluate to true before all
forms of parameter expansion have been performed for the case command.
Note that command substitutions in a case statement will be
evaluated even if its body is not taken. All substitutions, including
command substitutions, must be performed before the value can be compared
against the parameter.
\subsection case-example Example
@@ -42,6 +39,7 @@ switch $animal
echo bird
case shark trout stingray
echo fish
# Note that the next case has a wildcard which is quoted
case '*'
echo I have no idea what a $animal is
end

View File

@@ -3,9 +3,22 @@
\subsection cd-synopsis Synopsis
<tt>cd [DIRECTORY]</tt>
\subsection cd-description Description Changes the current
directory. If <tt>DIRECTORY</tt> is supplied it will become the new
directory. If \c DIRECTORY is a relative path, the paths found in the
CDPATH environment variable array will be tried as prefixes for the
specified path. If CDPATH is not set, it is assumed to be '.'. If \c
DIRECTORY is not specified, \$HOME will be the new directory.
\subsection cd-description Description
\c cd changes the current working directory.
If \c DIRECTORY is supplied, it will become the new directory. If no parameter
is given, the contents of the \c HOME environment variable will be used.
If \c DIRECTORY is a relative path, the paths found in the
\c CDPATH environment variable array will be tried as prefixes for the specified
path.
Note that the shell will attempt to change directory without requiring \c cd
if the name of a directory is provided (starting with '.', '/' or '~').
\subsection cd-example Examples
\c cd changes the working directory to your home directory.
<code>cd /usr/src/fish-shell</code> changes the working directory to
<code>/usr/src/fish-shell</code>.

View File

@@ -4,11 +4,9 @@
<tt>command COMMANDNAME [OPTIONS...]</tt>
\subsection command-description Description
prefixing a command with the word 'command' forces fish to ignore any functions or builtins with the same name.
\c command forces the shell to execute the program \c COMMANDNAME and ignore any functions or builtins with the same name.
\subsection command-example Example
<tt>command ls</tt>
causes fish to execute the ls program, even if there exists a 'ls' function.
<tt>command ls</tt> causes fish to execute the \c ls program, even if an 'ls' function exists.

View File

@@ -1,32 +1,34 @@
\section commandline commandline - set or get the current commandline buffer
\section commandline commandline - set or get the current command line buffer
\subsection commandline-synopsis Synopsis
<tt>commandline [OPTIONS] [CMD]</tt>
\subsection commandline-description Description
\c commandline can be used to set or get the current contents of the command
line buffer.
- \c CMD is the new value of the commandline. If unspecified, the
current value of the commandline is written to standard output. All
output from the commandline builtin is escaped, i.e. quotes are
removed, backslash escapes are expanded, etc..
With no parameters, \c commandline returns the current value of the command
line.
The following switches change what the commandline builtin does
With \c CMD specified, the command line buffer is erased and replaced with
the contents of \c CMD.
The following options are available:
- \c -C or \c --cursor set or get the current cursor position, not
the contents of the buffer. If no argument is given, the current
cursor position is printed, otherwise the argument is interpreted
as the new cursor position.
- \c -f or \c --function inject readline functions into the
reader. This option can not be combined with any other option. It
reader. This option cannot be combined with any other option. It
will cause any additional arguments to be interpreted as readline
functions, and these functions will be injected into the reader, so
that they will be returned to the reader before any additional
actual key presses are read.
The following switches change the way \c commandline updates the
commandline buffer
The following options change the way \c commandline updates the
command line buffer:
- \c -a or \c --append do not remove the current commandline, append
the specified string at the end of it
@@ -35,29 +37,27 @@ commandline buffer
- \c -r or \c --replace remove the current commandline and replace it
with the specified string (default)
The following switches change what part of the commandline is printed
or updated
The following options change what part of the commandline is printed
or updated:
- \c -b or \c --current-buffer select the entire buffer (default)
- \c -j or \c --current-job select the current job
- \c -p or \c --current-process select the current process
- \c -t or \c --current-token select the current token.
The following switch changes the way \c commandline prints the current
commandline buffer
The following options change the way \c commandline prints the current
commandline buffer:
- \c -c or \c --cut-at-cursor only print selection up until the
current cursor position
- \c -o or \c --tokenize tokenize the selection and print one string-type token per line
If commandline is called during a call to complete a given string
using <code>complete -C STRING</code>, commandline will consider the
specified string to be the current contents of the commandline.
If \c commandline is called during a call to complete a given string
using <code>complete -C STRING</code>, \c commandline will consider the
specified string to be the current contents of the command line.
\subsection commandline-example Example
<tt>commandline -j $history[3]</tt>
replaces the job under the cursor with the third item from the
commandline history.
<tt>commandline -j $history[3]</tt> replaces the job under the cursor with the
third item from the command line history.

View File

@@ -1,12 +1,12 @@
\section complete complete - edit command specific tab-completions.
\section complete complete - edit command specific tab-completions
\subsection complete-synopsis Synopsis
<tt>complete (-c|--command|-p|--path) COMMAND [(-s|--short-option) SHORT_OPTION] [(-l|--long-option|-o|--old-option) LONG_OPTION [(-a||--arguments) OPTION_ARGUMENTS] [(-d|--description) DESCRIPTION] </tt>
\subsection complete-description Description
For an introduction to how to specify completions, see the section <a
href='index.html#completion-own'>Writing your own completions</a> of
For an introduction to specifying completions, see <a
href='index.html#completion-own'>Writing your own completions</a> in
the fish manual.
- <tt>COMMAND</tt> is the name of the command for which to add a completion

View File

@@ -5,19 +5,22 @@
\subsection contains-description Description
\c contains tests whether the set \c VALUES contains the string
<code>KEY</code>. If so, \c contains exits with status 0; if not, it exits
with status 1.
The following options are available:
- \c -i or \c --index print the word index
- \c -h or \c --help display this message
Test if the set VALUES contains the string KEY. Return status is 0 if
yes, 1 otherwise
\subsection contains-example Example
<pre>
for i in ~/bin /usr/local/bin
if not contains \$i \$PATH
set PATH \$PATH i
set PATH \$PATH \$i
end
end
</pre>
The above code tests if ~/bin and /usr/local/bin are in the path and if they are not, they are added.
The above code tests if \c ~/bin and \c /usr/local/bin are in the path and adds them if not.

View File

@@ -1,13 +1,13 @@
\section continue continue - skip the rest of the current lap of the innermost currently evaluated loop
\section continue continue - skip the remainder of the current iteration of the current inner loop
\subsection continue-synopsis Synopsis
<tt>LOOP_CONSTRUCT; [COMMANDS...;] continue; [COMMANDS...;] end</tt>
\subsection continue-description Description
The \c continue builtin is used to skip the current lap of the innermost currently running loop, such as a <a href="#for">for</a> loop or a <a href="#while">while</a> loop. It is usually added inside of a conditional block such as an <a href="#if">if</a> statement or a <a href="#switch">switch</a> statement.
\c continue skips the remainder of the current iteration of the current inner loop, such as a <a href="#for">for</a> loop or a <a href="#while">while</a> loop. It is usually added inside of a conditional block such as an <a href="#if">if</a> statement or a <a href="#switch">switch</a> statement.
\subsection continue-example Example
The following code removes all tmp files without smurfs.
The following code removes all tmp files that do not contain the word smurf.
<pre>
for i in *.tmp

View File

@@ -5,21 +5,14 @@
\subsection count-description Description
The <tt>count</tt> builtin prints the number of arguments that were
<tt>count</tt> prints the number of arguments that were
passed to it. This is usually used to find out how many elements an
environment variable array contains, but this is not the only
potential usage for the count command.
environment variable array contains.
The count command does not accept any options, not even '-h'. This way
the user does not have to worry about an array containing elements
such as dashes. \c fish performs a special check when invoking the
count command, and if the user uses a help option, this help page is
displayed, but if a help option is contained inside of a variable or
is the result of expansion, it will simply be counted like any other
argument.
\c count does not accept any options, including '-h'.
Count exits with a non-zero exit status if no arguments where passed
to it, with zero otherwise.
\c count exits with a non-zero exit status if no arguments were passed
to it, and with zero if at least one argument was passed.
\subsection count-example Example

View File

@@ -13,7 +13,7 @@ Most tradeoffs between power and ease of use can be avoided with careful design.
-# Whenever possible without breaking the above goals, fish should
follow the Posix syntax.
To achive these high-level goals, the fish design relies on a number
To achieve these high-level goals, the fish design relies on a number
of more specific design principles. These are presented below,
together with a rationale and a few examples for each.
@@ -33,43 +33,22 @@ program harder to maintain and update.
Examples:
- Here documents are too similar to using echo inside of a pipeline.
- Subshells, command substitution and process substitution are strongly related. \c fish only supports command substitution, the others can be achived either using a block or the psub shellscript function.
- Subshells, command substitution and process substitution are strongly related. \c fish only supports command substitution, the others can be achieved either using a block or the psub shellscript function.
- Having both aliases and functions is confusing, especially since both of them have limitations and problems. \c fish functions have none of the drawbacks of either syntax.
- The many Posix quoting styles are silly, especially \$''.
\section sep The law of responsiveness
\section sep The law of minimalism
The shell should only contain features that cannot be implemented in
a reasonable way outside of the shell. A large performance decrease,
as well as some program complexity increase is acceptable in order to
improve separation.
The shell should attempt to remain responsive to the user at all times, even in the face of contended or unresponsive filesystems. It is only acceptable to block in response to a user initiated action, such as running a command.
Rationale:
A modular project is easier to maintain since smaller programs are far
easier to understand than larger ones. A modular project is also more
future proof since the modules can be individually
replaced. Modularity also decreases the severity of bugs, since there
is good hope that a bug, even a serious one, in one module, does not
take the whole system down.
Bad performance increases user-facing complexity, because it trains users to recognize and route around slow use cases. It is also incredibly frustrating.
Examples:
- Builtin commands should only be created when it cannot be
avoided. \c echo, \c kill, \c printf and \c time are among the commands
that fish does not implement internally since they can be provided as
external commands. Several other commands that are commonly implemented
as builtins and can not be implemented as external commands,
including \c type, \c vared, \c pushd and \c popd are implemented as shellscript
functions in fish.
- Mathematical calculations, regex matching, generating lists of numbers
and many other funtions can easily be done in external programs. They
should not be supported internally by the shell.
The law of minimalism does not imply that a large feature set is
bad. So long as a feature is not part of the shell itself, but a
separate command or at least a shellscript function, bloat is fine.
- Features like syntax highlighting and autosuggestions must perform all of their disk I/O asynchronously.
- Startup should minimize forks and disk I/O, so that fish can be started even if the system is under load.
\section conf Configurability is the root of all evil
@@ -98,7 +77,7 @@ A special note on the evils of configurability is the long list of
very useful features found in some shells, that are not turned on by
default. Both zsh and bash support command specific completions, but
no such completions are shipped with bash by default, and they are
turned of by default in zsh. Other features that zsh support that are
turned off by default in zsh. Other features that zsh support that are
disabled by default include tab-completion of strings containing
wildcards, a sane completion pager and a history file.

View File

@@ -4,5 +4,9 @@
<tt>dirh</tt>
\subsection dirh-description Description
<tt>dirh</tt> prints the current directory history. The current position in the
history is highlighted using <tt>$fish_color_history_current</tt>.
history is highlighted using the color defined in the
<tt>fish_color_history_current</tt> environment variable.
\c dirh does not accept any parameters.

View File

@@ -4,4 +4,7 @@
<tt>dirs</tt>
\subsection dirs-description Description
<tt>dirs</tt> prints the current directory stack.
<tt>dirs</tt> prints the current directory stack, as created by the
<code><a href="#pushd">pushd</a></code> command.
\c dirs does not accept any parameters.

39
doc_src/echo.txt Normal file
View File

@@ -0,0 +1,39 @@
\section echo echo - display a line of text
\subsection echo-synopsis Synopsis
<tt>echo [STRING]</tt>
\subsection echo-description Description
\c echo displays a string of text.
The following options are available:
- \c -n, \c Do not output a newline
- \c -s, \c Do not separate arguments with spaces
- \c -E, \c Disable interpretation of backslash escapes (default)
- \c -e, \c Enable interpretation of backslash escapes
- \c -h, \c --help Display this help
\subsection echo-escapes Escape Sequences
If \c -e is used, the following sequences are recognized:
- \c \\\\ \c backslash
- \\a alert (BEL)
- \\b backspace
- \\c produce no further output
- \\e escape
- \\f form feed
- \\n new line
- \\r carriage return
- \\t horizontal tab
- \\v vertical tab
- \\0NNN byte with octal value NNN (1 to 3 digits)
- \\xHH byte with hexadecimal value HH (1 to 2 digits)
\subsection echo-example Example
<tt>echo 'Hello World'</tt> Print hello world to stdout
<tt>echo -e 'Top\\nBottom'</tt> Print Top and Bottom on separate lines, using an escape sequence

View File

@@ -4,14 +4,18 @@
<tt>if CONDITION; COMMANDS_TRUE...; [else; COMMANDS_FALSE...;] end</tt>
\subsection else-description Description
<tt>if</tt> will execute the command CONDITION. If the condition's exit
status is 0, the commands COMMANDS_TRUE will execute. If it is not 0 and
<tt>else</tt> is given, COMMANDS_FALSE will be executed. Hint: use
<a href="#begin"><tt>begin; ...; end</tt></a> for complex conditions.
<tt>if</tt> will execute the command \c CONDITION. If the condition's exit
status is 0, the commands \c COMMANDS_TRUE will execute. If it is not 0 and
<tt>else</tt> is given, \c COMMANDS_FALSE will be executed.
\subsection else-example Example
The command <tt>if test -f foo.txt; echo foo.txt exists; else; echo foo.txt does not exist; end</tt>
will print <tt>foo.txt exists</tt> if the file foo.txt
exists and is a regular file, otherwise it will print
<tt>foo.txt does not exist</tt>.
The following code tests whether a file \c foo.txt exists as a regular file.
<pre>
if test -f foo.txt
echo foo.txt exists
else
echo foo.txt does not exist
end
</pre>

View File

@@ -1,11 +1,11 @@
\section emit emit - Emit a generic event
\subsection block-synopsis Synopsis
<tt>emit EVENT_NAME</tt>
<tt>emit EVENT_NAME [ARGUMENTS...]</tt>
\subsection emit-description Description
The emit builtin fires a generic fish event. Such events can be caught by special functions called event handlers.
\c emit emits, or fires, an event. Events are delivered to, or caught by, special functions called event handlers. The arguments are passed to the event handlers as function arguments.
\subsection emit-example Example
@@ -13,7 +13,8 @@ The following code first defines an event handler for the generic
event named 'test_event', and then emits an event of that type.
<pre>function event_test --on-event test_event
echo event test!!!
echo event test: $argv
end
emit test_event</pre>
emit test_event something
</pre>

View File

@@ -10,7 +10,9 @@ switch VALUE; [case [WILDCARD...]; [COMMANDS...]; ...] end
</pre>
\subsection end-description Description
<tt>end</tt> ends a block of commands. For more information, read the
<tt>end</tt> ends a block of commands.
For more information, read the
documentation for the block constructs, such as \c if, \c for and \c
while.

View File

@@ -4,13 +4,16 @@
<tt>eval [COMMANDS...]</tt>
\subsection eval-description Description
The <tt>eval</tt> function causes fish to evaluate the specified parameters as a command. If more than one parameter is specified, all parameters will be joined using a space character as a separator.
<tt>eval</tt> evaluates the specified parameters as a command. If more than one parameter is specified, all parameters will be joined using a space character as a separator.
\subsection eval-example Example
The folloing code will call the ls command. Note that \c fish does not
support the use of environment variables as direct commands; \c eval can
be used to work around this.
<pre>
set cmd ls
eval $cmd
</pre>
will call the ls command.

View File

@@ -5,11 +5,11 @@
\subsection exec-description Description
The \c exec builtin is used to replace the currently running shells
process image with a new command. On successful completion, exec never
returns. exec can not be used inside a pipeline.
\c exec replaces the currently running shell with a new command.
On successful completion, \c exec never returns. \c exec cannot be used
inside a pipeline.
\subsection exec-example Example
<tt>exec emacs</tt> starts up the emacs text editor. When emacs exits,
the session will terminate.
<tt>exec emacs</tt> starts up the emacs text editor, and exits \c fish.
When emacs exits, the session will terminate.

View File

@@ -1,13 +1,13 @@
\section exit exit - exit the shell.
\section exit exit - exit the shell
\subsection exit-synopsis Synopsis
<tt>exit [STATUS]</tt>
\subsection exit-description Description
The <tt>exit</tt> builtin causes fish to exit. If <tt>STATUS</tt> is
\c exit causes fish to exit. If <tt>STATUS</tt> is
supplied, it will be converted to an integer and used as the exit
code. Otherwise the exit code will be that of the last command executed.
code. Otherwise, the exit code will be that of the last command executed.
If exit is called while sourcing a file (using the <a
href="#source">.</a> builtin) the rest of the file will be skipped,

View File

@@ -1,13 +1,13 @@
/** \page faq Frequently asked questions
- <a href='#faq-cwd-symlink'>Why does cd, pwd and other fish commands always resolve symlinked directories to their canonical path?</a>
- <a href='#faq-cd-autocomplete'>Why does the cd command autocompletion list the subdirectories of my home directory as completions?</a>
- <a href='#faq-cd-implicit'>I accidentally entered a directory path and fish changed directory. What happened?</a>
- <a href='#faq-open'>The open command doesn't work.</a>
- <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>
- <a href='#faq-uninstalling'>How do I uninstall fish?</a>
<hr>
@@ -26,9 +26,9 @@ handled, and are varitations of the following example:
Writing <code>cd images; ls ..</code> given the above directory
structure would list the contents of ~/Documents, not of ~, even
though using <code>cd ..</code> changes the current direcotry to ~,
though using <code>cd ..</code> changes the current directory to ~,
and the prompt, the pwd builtin and many other directory information
sources suggest that the the current directory is ~/images and it's
sources suggest that the current directory is ~/images and its
parent is ~. This issue is not possible to fix without either making
every single command into a builtin, breaking Unix semantics or
implementing kludges in every single command.
@@ -42,19 +42,9 @@ silently fails in shells that don't resolve symlinked paths.
<hr>
\section faq-cd-autocomplete Why does the cd command autocompletion list the subdirectories of my home directory as completions?
Because they are completions. In fish, if you specify a relative
directory to the cd command, i.e. any path that does not start with
either './' or '/', the environment variable CDPATH will be examined, and any
directories in this path is used as a base direcotry. To disable this
feature, write <code>set CDPATH .</code> on the commandline.
<hr>
\section faq-cd-implicit I accidentally entered a directory path and fish changed directory. What happened?
If fish is unable to locate a command with a given name, fish will
If fish is unable to locate a command with a given name, and it starts with '.', '/' or '~', 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 press
@@ -64,13 +54,12 @@ fastest way to switch to your home directory is to simply press
\section faq-open The open command doesn't work.
The open command uses the mimetype database and the .desktop files
The \c open command uses the MIME type database and the <code>.desktop</code> files
used by Gnome and KDE to identify filetypes and default actions. If
at least one of these two desktops are installed, but the open command is
at least one of these environments is installed, but the open command is
not working, this probably means that the relevant files are installed
in a nonstandard location. Please contact the <a
href='mailto:fish-users@lists.sf.net'>fish mailing list</a>, and
hopefully this can be resolved.
in a non-standard location. Consider <a href="index.html#more-help">asking for
more help</a>.
<hr>
@@ -91,10 +80,10 @@ In order to change your default shell, type:
<code>chsh -s /usr/local/bin/fish</code>
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 may need to adjust the above path to e.g. \c /usr/bin/fish. Use the command <code>which fish</code> if you are unsure of where fish is installed.
Unfortunatly, there is no way to make the changes take effect at once,
you will need to log out and back in again.
Unfortunately, there is no way to make the changes take effect at once.
You will need to log out and back in again.
<hr>
@@ -114,7 +103,7 @@ The long answer:
Fish is trying to set the titlebar message of your terminal. While
screen itself supports this feature, your terminal does
not. Unfortuntaly, when the underlying terminal doesn't support
not. Unfortunately, when the underlying terminal doesn't support
setting the titlebar, screen simply passes through the escape codes
and text to the underlying terminal instead of ignoring them. It is
impossible detect and resolve this problem from inside fish since fish
@@ -158,4 +147,19 @@ Fish history recall is very simple yet effective:
See <a href='index.html#editor'>documentation</a> for more details about line editing in fish.
<hr>
\section faq-uninstalling Uninstalling fish
Should you wish to uninstall fish, first ensure fish is not set as your shell. Run <code>chsh -s /bin/bash</code> if you are not sure.
Next, do the following (assuming fish was installed to /usr/local):
<pre>
rm -Rf /usr/local/etc/fish /usr/local/share/fish ~/.config/fish
rm /usr/local/share/man/man1/fish*.1
cd /usr/local/bin
rm -f fish mimedb fish_pager fishd fish_indent
</pre>
*/

View File

@@ -1,14 +1,14 @@
\section fg fg - send job to foreground
\section fg fg - bring job to foreground
\subsection fg-synopsis Synopsis
<tt>fg [PID]</tt>
\subsection fg-description Description
Sends the specified job to the foreground. While a foreground job is
executed, fish is suspended. If no job is specified, the last job to be used is put in the foreground. If PID is specified, the job with the specified group id is put in the foreground.
\c fg brings the specified <a href="index.html#syntax-job-control">job</a> to the foreground, resuming it if it is stopped. While a foreground job is
executed, fish is suspended. If no job is specified, the last job to be used is put in the foreground. If PID is specified, the job with the specified group ID is put in the foreground.
The PID of the desired process is usually found by using <a href="index.html#expand-process">process expansion</a>.
\subsection fg-example Example
<tt>fg \%0</tt> will put the job with job id 0 in the foreground.
<tt>fg \%1</tt> will put the job with job ID 1 in the foreground.

View File

@@ -5,10 +5,12 @@ fish [-h] [-v] [-c command] [FILE [ARGUMENTS...]]
\subsection fish-description Description
A commandline shell written mainly with interactive use in mind. The
full manual is available <a href='index.html'>in html</a> by using the
\c fish is a command-line shell written mainly with interactive use in mind. The
full manual is available <a href='index.html'>in HTML</a> by using the
<a href='#help'>help</a> command from inside fish.
The following options are available:
- <code>-c</code> or <code>--command=COMMANDS</code> evaluate the specified commands instead of reading from the commandline
- <code>-d</code> or <code>--debug-level=DEBUG_LEVEL</code> specify the verbosity level of fish. A higher number means higher verbosity. The default level is 1.
- <code>-h</code> or <code>--help</code> display help and exit

22
doc_src/fish_config.txt Normal file
View File

@@ -0,0 +1,22 @@
\section fish_config fish_config - start the web-based configuration interface
\subsection fish_config-description Description
\c fish_config starts the web-based configuration interface.
The web interface allows you to view your functions, variables and history, and
to make changes to your prompt and color configuration.
\c fish_config starts a local web server and then opens a web browser window; when
you have finished, close the browser window and then press the Enter key to
terminate the configuration session.
There are no parameters for <code>fish_config</code>.
If the \c BROWSER environment variable is set, it will be used as the name
of the web browser to open instead of the system default.
\subsection fish_config-example Example
\c fish_config opens a new web browser window and allows you to configure certain
fish settings.

View File

@@ -5,11 +5,11 @@
\subsection fish_indent-description Description
\c fish_indent is used to indent or otherwise prettify a piece of fish
\c fish_indent is used to indent a piece of fish
code. \c fish_indent reads commands from standard input and outputs
them to standard output.
\c fish_indent understands the following options:
The following options are available:
- <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

@@ -2,7 +2,6 @@
\subsection fish_pager-description Description
This command is used internally by fish to display a list of
completions. It should not be used by other commands, as it's
interface is liable to change in the future.
\c fish_pager is used internally by fish. It should not be used by other
commands, as its interface is liable to change in the future.

View File

@@ -1,6 +1,6 @@
\section fish_prompt fish_prompt - define the apperance of the command line prompt
\section fish_prompt fish_prompt - define the appearance of the command line prompt
\subsection fish_promt-synopsis Synopsis
\subsection fish_prompt-synopsis Synopsis
<pre>function fish_prompt
...
end</pre>
@@ -11,6 +11,11 @@ By defining the \c fish_prompt function, the user can choose a custom
prompt. The \c fish_prompt function is executed when the prompt is to
be shown, and the output is used as a prompt.
The exit status of commands within \c fish_prompt will not modify the value of <a href="index.html#variables-status">$status</a> outside of the \c fish_prompt function.
\c fish ships with a number of example prompts that can be chosen with the
\c fish_config command.
\subsection fish_prompt-example Example
A simple prompt:

View File

@@ -0,0 +1,23 @@
\section fish_right_prompt fish_right_prompt - define the appearance of the right-side command line prompt
\subsection fish_right_prompt-synopsis Synopsis
<pre>function fish_right_prompt
...
end</pre>
\subsection fish_right_prompt-description Description
\c fish_right_prompt is similar to \c fish_prompt, except that it appears on the right side of the terminal window.
Multiple lines are not supported in \c fish_right_prompt.
\subsection fish_prompt-example Example
A simple right prompt:
<pre>
function fish_right_prompt -d "Write out the right prompt"
date "+%m/%d/%y"
end
</pre>

View File

@@ -0,0 +1,9 @@
\section fish_update_completions fish_update_completions - Update completions using manual pages
\subsection fish_update_completions-description Description
\c fish_update_completions parses manual pages installed on the system, and attempts to create completion files in the \c fish configuration directory.
This does not overwrite custom completions.
There are no parameters for <code>fish_update_completions</code>.

View File

@@ -6,26 +6,28 @@
\subsection fishd-description Description
The \c fishd daemon is used to load, save and distribute universal
variable information. fish automatically connects to fishd via a socket
on startup. If no instance of fishd is running, fish spawns a new
fishd instance. fishd will create a socket in /tmp, and wait for
incoming connections from universal variable clients, such as fish,
When no clients are connected, fishd will automatically shut down.
variable information. \c fish automatically connects to \c fishd via a socket
on startup.
\c fishd is started and stopped automatically.
The following options are available if starting \c fishd manually:
- <tt>-h</tt> or <tt>--help</tt> displays this help message and then exits
- <tt>-v</tt> or <tt>--version</tt> displays the current fish version and then exits
\subsection fishd-files Files
\c ~/.config/fish/fishd.HOSTNAME permanent storage location for universal
variable data. The data is stored as a set of \c set and \c set_export
commands such as would be parsed by fishd. The file must always be
stored in ASCII format. If an instance of fishd is running (which is
generally the case), manual modifications to ~/.fishd.HOSTNAME will be
lost. Do NOT edit this file manually!
- \c ~/.config/fish/fishd.MACHINE_ID - permanent storage location for universal
variable data. \c MACHINE_ID is generally based on the machine's MAC address.
\c /tmp/fishd.socket.USERNAME the socket which fishd uses to communicate
The data is stored as a set of \c set and \c set_export commands such as
would be parsed by fishd. The file must always be stored in YAML format.
If an instance of fishd is running (which is generally the case), manual
modifications to \c ~/.fishd.MACHINE_ID will be lost. Do NOT edit this file manually!
- \c /tmp/fishd.socket.USERNAME - the socket which fishd uses to communicate
with all clients.
/tmp/fishd.log.USERNAME the fishd log file
- /tmp/fishd.log.USERNAME - the fishd log file

View File

@@ -5,8 +5,8 @@
\subsection for-description Description
<tt>for</tt> is a loop construct. It will perform the commands specified by
COMMANDS multiple times. Each time the environment variable specified by
VARNAME is assigned a new value from VALUES. If VALUES is empty, COMMANDS will
\c COMMANDS multiple times. On each iteration, the environment variable specified by
\c VARNAME is assigned a new value from \c VALUES. If \c VALUES is empty, \c COMMANDS will
not be executed at all.
\subsection for-example Example

View File

@@ -1,9 +1,21 @@
\section funced funced - edit a function interactively
\subsection funced-synopsis Synopsis
<code>funced NAME</code>
<code>funced [OPTIONS] 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.
\c funced provides an interface to edit the definition of the function
<code>NAME</code>.
If the \c $EDITOR environment variable is set, it will be used as the program
to edit the function. Otherwise, a built-in editor will be used.
If there is no function called \c NAME a new function will be created with
the specified name
- <code>-e command</code> or <code>--editor command</code> Open the function
body inside the text editor given by the command (for example, "vi"). The
command 'fish' will use the built-in editor.
- <code>-i</code> or <code>--interactive</code> Open function body in the
built-in editor.

View File

@@ -1,12 +1,13 @@
\section funcsave funcsave - save the definition of a function to the users autoload directory
\section funcsave funcsave - save the definition of a function to the user's autoload directory
\subsection funcsave-synopsis Synopsis
<tt>funcsave FUNCTION_NAME</tt>
<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
\c funcsave saves the current definition of a function to
a file in the fish configuration directory. This function will be automatically
loaded 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

@@ -5,32 +5,28 @@
\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
\c function creates a new function \c NAME with the body <code>BODY</code>.
A function is a list of commands that will be executed when the name of the
function is given as a command.
The following options are available:
- <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)
- <code>-v</code> or <code>--on-variable VARIABLE_NAME</code> tells fish to run this function when the variable VARIABLE_NAME changes value
This builtin command is used to create a new function. A function is a
list of commands that will be executed when the name of the function
is entered. The function
<pre>
function hi
echo hello
end
</pre>
will write <code>hello</code> whenever the user enters \c hi.
- <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).
- <code>-v</code> or <code>--on-variable VARIABLE_NAME</code> tells fish to run this function when the variable VARIABLE_NAME changes value.
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.
are inserted into the environment <a href="index.html#variables-arrays">variable array</a>
<code>$argv</code>.
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:
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
- \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
@@ -44,7 +40,7 @@ will run the \c ls command, using the \c -l option, while passing on any additio
<pre>
function mkdir -d "Create a directory and set CWD"
mkdir $argv
command mkdir $argv
if test $status = 0
switch $argv[(count $argv)]
case '-*'

View File

@@ -1,31 +1,51 @@
\section functions functions - print or erase functions
\subsection function-synopsis Synopsis
<code>functions [-e] FUNCTIONS...</code>
<pre>functions [-n]
functions -c OLDNAME NEWNAME
functions -d DESCRIPTION FUNCTION
functions [-eq] FUNCTIONS...</pre>
\subsection functions-description Description
This builtin command is used to print or erase functions.
\c functions prints or erases functions.
- <code>-a</code> or <code>--all</code> list all functions, even those whose name start with an underscore.
The following options are available:
- <code>-a</code> or <code>--all</code> lists all functions, even those whose name start with an underscore.
- <code>-c OLDNAME NEWNAME</code> or <code>--copy OLDNAME NEWNAME</code> creates a new function named NEWNAME, using the definition of the OLDNAME function.
- <code>-d DESCRIPTION</code> or <code>--description=DESCRIPTION</code> change the description of this function
- <code>-d DESCRIPTION</code> or <code>--description=DESCRIPTION</code> changes the description of this function.
- <code>-e</code> or <code>--erase</code> causes the specified functions to be erased.
- <code>-h</code> or <code>--help</code> display a help message and exit
- <code>-n</code> or <code>--names</code> list only the names of all defined functions, not their definition
- <code>-q</code> or <code>--query</code> test if the specified functions exist. Does not output anything, but the builtins exit status is the number of functions specified that were not defined.
- <code>-h</code> or <code>--help</code> displays a help message and exits.
- <code>-n</code> or <code>--names</code> lists the names of all defined functions.
- <code>-q</code> or <code>--query</code> tests if the specified functions exist.
The default behavior of \c functions when called with no arguments,
is to print the names and definitions of all defined functions. If any
non-switch parameters are given, only the definition of the specified
The default behavior of <code>functions</code>, when called with no arguments,
is to print the names of all defined functions. Unless the \c -a option is
given, no functions starting with underscores are not included in the output.
If any non-option parameters are given, the definition of the specified
functions are printed.
Automatically loaded functions can not be removed using functions
-e. Either remove the definition file or change the
Automatically loaded functions cannot be removed using <code>functions
-e</code>. Either remove the definition file or change the
$fish_function_path variable to remove autoloaded functions.
Function copies, created with -c, will not have any event/signal/on-exit
notifications that the original may have had.
Copying a function using \c -c copies only the body of the function, and
does not attach any event notifications from the original function.
The exit status of the functions builtin is the number functions
specified in the argument list that do not exist.
Only one function's description can be changed in a single invocation
of <code>functions -d</code>.
The exit status of \c functions is the number of functions
specified in the argument list that do not exist, which can be used in
concert with the \c -q option.
\subsection functions-example Examples
<code>functions -n</code> displays a list of currently-defined functions.
<code>functions -c foo bar</code> copies the \c foo function to a new function called
<code>bar</code>.
<code>functions -e bar</code> erases the function <code>bar</code>.

View File

@@ -5,12 +5,14 @@
\subsection help-description Description
The \c help command is used to display a section of the fish help documentation.
\c help displays the fish help documentation.
If a \c SECTION is specified, the help for that command is shown.
If the BROWSER environment variable is set, it will be used to display the
documentation, otherwise fish will search for a suitable browser.
documentation. Otherwise, fish will search for a suitable browser.
Note also that most builtin commands display their help in the terminal when
Note that most builtin commands display their help in the terminal when
given the <tt>--help</tt> option.
\subsection help-example Example

44
doc_src/history.txt Normal file
View File

@@ -0,0 +1,44 @@
\section history history - Show and manipulate command history
\subsection history-synopsis Synopsis
<pre>
history (--save | --clear)
history (--search | --delete ) (--prefix "prefix string" | --contains "search string")
</pre>
\subsection history-description Description
\c history is used to list, search and delete the history of commands used.
The following options are available:
- \c --save saves all changes in the history file. The shell automatically
saves the history file; this option is provided for internal use.
- \c --clear clears the history file. A prompt is displayed before the history
is erased.
- \c --search returns history items in keeping with the \c --prefix or
\c --contains options.
- \c --delete deletes history items.
- \c --prefix searches or deletes items in the history that begin with the
specified text string.
- \c --contains searches or deletes items in the history that contain the
specified text string.
If \c --search is specified without \c --contains or <code>--prefix</code>,
\c --contains will be assumed.
If \c --delete is specified without \c --contains or <code>--prefix</code>,
only a history item which exactly matches the parameter will be erased. No
prompt will be given. If \c --delete is specified with either of these
parameters, an interactive prompt will be displayed before any items are
deleted.
\subsection history-examples Example
<code>history --clear</code> deletes all history items
<code>history --search --contains "foo"</code> outputs a list of all previous
commands containing the string "foo".
<code>history --delete --prefix "foo"</code> interactively deletes the record
of previous commands which start with "foo".

View File

@@ -1,19 +1,19 @@
\section if if - conditionally execute a command
\subsection if-synopsis Synopsis
<tt>if CONDITION; COMMANDS_TRUE...; [else; COMMANDS_FALSE...;] end</tt>
<tt>if CONDITION; COMMANDS_TRUE...; [else if CONDITION2; COMMANDS_TRUE2...;] [else; COMMANDS_FALSE...;] end</tt>
\subsection if-description Description
<tt>if</tt> will execute the command CONDITION. If the condition's
exit status is 0, the commands COMMANDS_TRUE will execute. If the
exit status is not 0 and <tt>else</tt> is given, COMMANDS_FALSE will
<tt>if</tt> will execute the command \c CONDITION. If the condition's
exit status is 0, the commands \c COMMANDS_TRUE will execute. If the
exit status is not 0 and <tt>else</tt> is given, \c COMMANDS_FALSE will
be executed.
In order to use the exit status of multiple commands as the condition
of an if block, use <a href="#begin"><tt>begin; ...; end</tt></a> and
the short circuit commands <a href="commands.html#and">and</a> and <a
href="commands.html#or">or</a>.
the short circuit commands <a href="commands.html#and"><tt>and</tt></a>
and <a href="commands.html#or"><tt>or</tt></a>.
The exit status of the last foreground command to exit can always be
accessed using the <a href="index.html#variables-status">$status</a>
@@ -24,10 +24,13 @@ variable.
<pre>
if test -f foo.txt
echo foo.txt exists
else if test -f bar.txt
echo bar.txt exists
else
echo foo.txt does not exist
echo foo.txt and bar.txt do not exist
end
</pre>
will print <tt>foo.txt exists</tt> if the file foo.txt
</pre>will print <tt>foo.txt exists</tt> if the file foo.txt
exists and is a regular file, otherwise it will print
<tt>foo.txt does not exist</tt>.
<tt>bar.txt exists</tt> if the file bar.txt exists
and is a regular file, otherwise it will print
<tt>foo.txt and bar.txt do not exist</tt>.

View File

@@ -11,7 +11,7 @@ This is the documentation for \c fish, the friendly interactive
shell. \c fish is a user friendly commandline shell intended
mostly for interactive use. A shell is a program used to execute other
programs. For the latest information on \c fish, please visit the <a
href="http://www.fishshell.org"><code>fish</code> homepage</a>.
href="http://fishshell.com/"><code>fish</code> homepage</a>.
\section syntax Syntax overview
@@ -48,7 +48,7 @@ Every program on your computer can be used as a command in \c fish. If
the program file is located in one of the directories in the <a
href="#variables-special">PATH</a>, it is sufficient to type the name
of the program to use it. Otherwise the whole filename, including the
directory (like \c /home/me/code/checkers/checkers or \c ../checkers)
directory (like \c /home/me/code/checkers/checkers or <code>../checkers</code>)
has to be used.
Here is a list of some useful commands:
@@ -80,7 +80,7 @@ while '-f' will turn it off.
\subsection quotes Quotes
Sometimes features such as <a href="#globbing">parameter expansion</a>
Sometimes features such as <a href="#expand">parameter expansion</a>
and <a href="#escapes">character escapes</a> get in the way. When that
happens, the user can write a parameter within quotes, either '
(single quote) or " (double quote). There is one important difference
@@ -92,8 +92,9 @@ only backslash escape accepted within single quotes is \\', which
escapes a single quote and \\\\, which escapes the backslash
symbol. The only backslash escapes accepted within double quotes are
\\", which escapes a double quote, \\$, which escapes a dollar
character, and \\\\, which escapes the backslash symbol. Single quotes
have no special meaning withing double quotes and vice versa.
character, \\ followed by a newline, which deletes the backslash
and the newline, and lastly \\\\, which escapes the backslash symbol.
Single quotes have no special meaning within double quotes and vice versa.
Example:
@@ -110,35 +111,35 @@ would remove the two files 'cumbersome' and 'filename.txt'.
Some characters can not be written directly on the command line. For
these characters, so called escape sequences are provided. These are:
- <code>'\\a'</code>, escapes the alert character
- <code>'\\b'</code>, escapes the backspace character
- <code>'\\e'</code>, escapes the escape character
- <code>'\\f'</code>, escapes the form feed character
- <code>'\\n'</code>, escapes a newline character
- <code>'\\r'</code>, escapes the carriage return character
- <code>'\\t'</code>, escapes the tab character
- <code>'\\v'</code>, escapes the vertical tab character
- <code>'\\ '</code>, escapes the space character
- <code>'\\$'</code>, escapes the dollar character
- <code>'\\\\'</code>, escapes the backslash character
- <code>'\\*'</code>, escapes the star character
- <code>'\\?'</code>, escapes the question mark character
- <code>'\\~'</code>, escapes the tilde character
- <code>'\\%'</code>, escapes the percent character
- <code>'\\#'</code>, escapes the hash character
- <code>'\\('</code>, escapes the left parenthesis character
- <code>'\\)'</code>, escapes the right parenthesis character
- <code>'\\{'</code>, escapes the left curly bracket character
- <code>'\\}'</code>, escapes the right curly bracket character
- <code>'\\['</code>, escapes the left bracket character
- <code>'\\]'</code>, escapes the right bracket character
- <code>'\\\<'</code>, escapes the less than character
- <code>'\\\>'</code>, escapes the more than character
- <code>'\\^'</code>, escapes the circumflex character
- <code>'\\&'</code>, escapes the ampersand character
- <code>'\\;'</code>, escapes the semicolon character
- <code>'\\"'</code>, escapes the quote character
- <code>'\\''</code>, escapes the apostrophe character
- <code>'\\a'</code> escapes the alert character
- <code>'\\b'</code> escapes the backspace character
- <code>'\\e'</code> escapes the escape character
- <code>'\\f'</code> escapes the form feed character
- <code>'\\n'</code> escapes a newline character
- <code>'\\r'</code> escapes the carriage return character
- <code>'\\t'</code> escapes the tab character
- <code>'\\v'</code> escapes the vertical tab character
- <code>'\\ '</code> escapes the space character
- <code>'\\$'</code> escapes the dollar character
- <code>'\\\\'</code> escapes the backslash character
- <code>'\\*'</code> escapes the star character
- <code>'\\?'</code> escapes the question mark character
- <code>'\\~'</code> escapes the tilde character
- <code>'\\%%'</code> escapes the percent character
- <code>'\\#'</code> escapes the hash character
- <code>'\\('</code> escapes the left parenthesis character
- <code>'\\)'</code> escapes the right parenthesis character
- <code>'\\{'</code> escapes the left curly bracket character
- <code>'\\}'</code> escapes the right curly bracket character
- <code>'\\['</code> escapes the left bracket character
- <code>'\\]'</code> escapes the right bracket character
- <code>'\\\<'</code> escapes the less than character
- <code>'\\\>'</code> escapes the more than character
- <code>'\\^'</code> escapes the circumflex character
- <code>'\\&'</code> escapes the ampersand character
- <code>'\\;'</code> escapes the semicolon character
- <code>'\\"'</code> escapes the quote character
- <code>'\\''</code> escapes the apostrophe character
- <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.
@@ -146,9 +147,9 @@ these characters, so called escape sequences are provided. These are:
- <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
\subsection redirects Input/Output (IO) redirection
Most program use three types of input/output (IO), each represented by
Most programs use three input/output (IO) streams, each represented by
a number called a file descriptor (FD). These are:
- Standard input, FD 0, for reading, defaults to reading from the keyboard.
@@ -162,7 +163,7 @@ Any file descriptor can be directed to a different output than its
default through a simple mechanism called a redirection.
An example of a file redirection is <code> echo hello \>output.txt</code>,
which directs the output of the echo command to the file error.txt.
which directs the output of the echo command to the file output.txt.
- To redirect standard input, write <code>\<SOURCE_FILE</code>
- To redirect standard output, write <code>\>DESTINATION</code>
@@ -225,7 +226,7 @@ using the less pager.
When you start a job in \c fish, \c fish itself will pause, and give
control of the terminal to the program just started. Sometimes, you
want to continue using the commandline, and have the job run in the
background. To create a background job, append a \& (ampersand) to
background. To create a background job, append an \& (ampersand) to
your command. This will tell fish to run the job in the
background. Background jobs are very useful when running programs that
have a graphical user interface.
@@ -238,12 +239,12 @@ will start the emacs text editor in the background.
\subsection syntax-job-control Job control
Most programs allow you to suspend the programs execution and return
control to \c fish by Pressing ^Z (Press and hold the Control key and
Most programs allow you to suspend the program's execution and return
control to \c fish by pressing ^Z (press and hold the Control key and
press 'z'). Once back at the \c fish commandline, you can start other
programs and do anything you want. If you then want to go back to the
suspended command by using the <a href="commands.html#fg">fg</a>
command.
programs and do anything you want. If you then want you can go back to
the suspended command by using the <a href="commands.html#fg">fg</a>
(foreground) command.
If you instead want to put a suspended job into the background, use
the <a href="commands.html#bg">bg</a> command.
@@ -251,12 +252,14 @@ the <a href="commands.html#bg">bg</a> command.
To get a listing of all currently started jobs, use the <a
href="commands.html#jobs">jobs</a> command.
\subsection syntax-function Shellscript functions
\subsection syntax-function Functions
Functions are used to group together commands and arguments using a
single name. It can also be used to start a specific command with
additional arguments. For example, the following is a function
definition that calls the command 'ls -l' to print a detailed listing
Functions are programs written in the fish syntax. They group together one
or more commands and their arguments using a single name. It can also be
used to start a specific command with additional arguments.
For example, the following is a function definition that calls the command
\c ls with the argument '-l' to print a detailed listing
of the contents of the current directory:
<pre>
@@ -265,7 +268,7 @@ function ll
end
</pre>
The first line tells fish that a function by the name of ll is to be
The first line tells fish that a function by the name of \c ll is to be
defined. To use it, simply write <code>ll</code> on the
commandline. The second line tells fish that the command <code>ls -l
$argv</code> should be called when ll is invoked. $argv is an array
@@ -274,42 +277,44 @@ the example above, these are simply passed on to the ls command. For
more information on functions, see the documentation for the <a
href='commands.html#function'>function</a> builtin.
\subsubsection syntax-function-wrappers Defining wrapper functions
\subsubsection syntax-function-wrappers Defining aliases
One of the most common used for functions is to slightly alter the
One of the most common uses for functions is to slightly alter the
behavior of an already existing command. For example, one might want
to redefine the \c ls command to display colors. The switch for
turning on colors on GNU systems is \c '--color=auto'. A wrapper
around \c ls might look like this:
turning on colors on GNU systems is \c '--color=auto'. An alias, or
wrapper, around \c ls might look like this:
<pre>function ls
ls --color=auto $argv
command ls --color=auto $argv
end
</pre>
There are a few important things that need to be noted about wrapper
functions:
There are a few important things that need to be noted about aliases:
- Wrappers should always take care to add the $argv variable to the list of parameters to the wrapped command. This makes sure that if the user specifies any additional parameters to the function, they are passed on to the underlying command.
- If the wrapped command is not the first command to be called by the wrapper, it is necessary to prefix the call to the command with the word 'command' in order to tell fish that the function should not call itself, but rather a command with the same name. Failing to do so will cause infinite recursion bugs.
- Always take care to add the \c $argv variable to the list of parameters to the wrapped command. This makes sure that if the user specifies any additional parameters to the function, they are passed on to the underlying command.
- If the alias has the same name as the aliased command, it is necessary to prefix the call to the program with \c command in order to tell fish that the function should not call itself, but rather a command with the same name. Failing to do so will cause infinite recursion bugs.
To easily create a function of this form, you can use the
<a href="commands.html#alias">alias</a> command.
\subsubsection syntax-function-autoloading Autoloading functions
Functions can be defined on the commandline or in a configuration
file, but they can also be automatically loaded. This method of
defining functions has several advantages. An autoloaded function
becomes available automatically to all running shells, if the function
becomes available automatically to all running shells. If the function
definition is changed, all running shells will automatically reload
the altered version, startup time and memory usage is improved, etc.
the altered version. Startup time and memory usage is improved, etc.
Fish automatically searches through any directories in the array
variable \$fish_function_path, and any functions defined are
variable \c $fish_function_path, and any functions defined are
automatically loaded when needed. A function definition file must have
a filename consisting of the name of the function plus the suffix
'.fish'.
The default value for \$fish_function_path is \c ~/.config/fish/functions
\c /etc/fish/functions \c /usr/share/fish/functions. The exact path
The default value for \c $fish_function_path is <code>~/.config/fish/functions
/etc/fish/functions /usr/share/fish/functions</code>. The exact path
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
@@ -320,11 +325,11 @@ administrator can override default fish functions, and the user can
override functions defined by the system administrator.
It is very important that function definition files only contain the
definition for the specified function and nothing else, otherwise it
definition for the specified function and nothing else. Otherwise, it
is possible that autoloading a function files requires that the
function already be loaded, i.e. a circular dependency.
function already be loaded, which creates a circular dependency.
\subsection syntax-conditional Conditional execution of code
\subsection syntax-conditional Conditional execution of code and flow control
There are four fish builtins that let you execute commands only if a
specific criterion is met. These builtins are
@@ -359,11 +364,14 @@ This is a short explanation of some of the commonly used words in fish.
\section help Help
\c fish has an extensive help system. Use the <a
href="commands.html#help"><code>help</code></a> command to obtain help on
href="commands.html#help">help</a> command to obtain help on
a specific subject or command. For instance, writing <code>help
syntax</code> displays the <a href="#syntax">syntax section</a> of this
documentation.
fish also has man pages for its commands. For example, <code>man set</code>
will show the documentation for \c set as a man page.
Help on a specific builtin can also be obtained with the <code>-h</code>
parameter. For instance, to obtain help on the \c fg builtin, either
type <code>fg -h</code> or <code>help fg</code>.
@@ -386,24 +394,24 @@ command line.
These are the general purpose tab completions that \c fish provides:
- Completion of commands, both builtins, functions and regular programs.
- Completion of commands (builtins, functions and regular programs).
- Completion of environment variable names.
- Completion of usernames for tilde expansion.
- Completion of filenames, even on strings with wildcards such as '*', '**' and '?'.
- Completion of job id, job name and process names for <a href="#expand-process">process expansion</a>.
- Completion of job ID, job name and process names for <a href="#expand-process">process expansion</a>.
\c fish provides a large number of program specific completions. Most
of these completions are simple options like the \c -l option for \c
ls, but some are more advanced. The latter include:
- The programs 'man' and 'whatis' show all installed
- The programs \c man and \c whatis show all installed
manual pages as completions.
- The 'make' program uses all targets in the Makefile in
- The \c make program uses all targets in the Makefile in
the current directory as completions.
- The 'mount' command uses all mount points specified in fstab as completions.
- The 'ssh' command uses all hosts that are stored
in the known_hosts file as completions. (see the ssh documentation for more information)
- The 'su' command uses all users on the system as completions.
- The \c mount command uses all mount points specified in fstab as completions.
- The \c ssh command uses all hosts that are stored
in the known_hosts file as completions. (See the ssh documentation for more information)
- The \c su command uses all users on the system as completions.
- The \c apt-get, \c rpm and \c yum commands use all installed packages as completions.
\subsection completion-own Writing your own completions
@@ -440,7 +448,7 @@ href="commands.html#complete">complete</a> builtin, or write 'complete
--help' inside the \c fish shell.
For examples of how to write your own complex completions, study the
completions in /usr/share/fish/completions. (The exact path depends on
completions in \c /usr/share/fish/completions. (The exact path depends on
your chosen installation prefix and may be slightly different)
\subsection completion-func Useful functions for writing completions
@@ -507,12 +515,12 @@ Debian, rpm and Gentoo packages.
Completions can be defined on the commandline or in a configuration
file, but they can also be automatically loaded. Fish automatically
searches through any directories in the array variable
\$fish_complete_path, and any completions defined are automatically
\c $fish_complete_path, and any completions defined are automatically
loaded when needed. A completion file must have a filename consisting
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
The default value for \c $fish_complete_path is <code>~/.config/fish/completions
/etc/fish/completions /usr/share/fish/completions</code>. The exact
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
@@ -522,16 +530,16 @@ user specific completions, the second one is for system-wide
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 mailing list</a>.
Unix command, please consider sharing your work by submitting it via
the instructions in <a href="#more-help">Further help and development</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 mechanisms that
allow you to expand the parameter in various ways, including
the command. Parameter expansion is a powerful mechanism that
allows 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
another command as a parameter list.
@@ -563,7 +571,7 @@ Examples:
<code>**</code> matches any files and directories in the current directory and all of its subdirectories.
If no matches are found for a specific wildcard, it will expand into
Note that if no matches are found for a specific wildcard, it will expand into
zero arguments, i.e. to nothing. If none of the wildcarded arguments
sent to a command result in any matches, the command will not be
executed. If this happens when using the shell interactively, a
@@ -571,24 +579,27 @@ warning will also be printed.
\subsection expand-command-substitution Command substitution
If a parameter contains a set of parenthesis, the text enclosed by the
The output of a series of commands can be used as the parameters to another
command. If a parameter contains a set of parenthesis, the text enclosed by the
parenthesis will be interpreted as a list of commands. On expansion,
this list is executed, and substituted by the output. If the output is
more than one line long, each line will be expanded to a new
parameter.
A command substitution will not change the value of the <a
href='#variables-status'>status</a> variable outside of the command
substitution.
The exit status of the last run command substitution is available in the <a
href='#variables-status'>status</a> variable.
Example:
Only part of the output can be used, see <a href='#expand-index-range'>index
range expansion</a> for details.
Examples:
The command <code>echo (basename image.jpg .jpg).png</code> will
output 'image.png'.
The command <code>for i in *.jpg; convert $i (basename $i .jpg).png;
end</code> will convert all Jpeg files in the current directory to the
PNG format.
end</code> will convert all JPEG files in the current directory to the
PNG format using the \c convert program.
\subsection expand-brace Brace expansion
@@ -608,35 +619,27 @@ The command <code>mv *.{c,h} src/</code> moves all files with the suffix
A dollar sign followed by a string of characters is expanded into the
value of the environment variable with the same name. For an
introduction to the concept of environment variables, read the <a
href="#variables"> Environment variables</a> section.
href="#variables">Environment variables</a> section.
Example:
Undefined and empty variables expand to nothing.
<code> echo \$HOME</code> prints the home directory of the current
To separate a variable name from text it should immediately be followed by,
encase the variable within braces.
Examples:
<code>echo $HOME</code> prints the home directory of the current
user.
If you wish to combine environment variables with text, you can
encase the variables within braces to embed a variable inside running
text like <code>echo Konnichiwa {$USER}san</code>, which will print a
personalized Japanese greeting.
<code>echo $nonexistentvariable</code> prints no output.
The {$USER}san syntax might need a bit of an elaboration. Posix
shells allow you to specify a variable name using '$VARNAME' or
'${VARNAME}'. Fish supports the former, and has no support whatsoever
for the latter or anything like it. So what is '{$VARNAME}' then?
Well, '{WHATEVER}' is <a href='#brace'>brace expansion</a>, e.g. 'a{b,c}d' -> 'abd acd'.
So '{$VARNAME}' is a bracket-expansion with
only a single element, i.e. it becomes expanded to '$VARNAME', which
will be variable expanded to the value of the variable 'VARNAME'. So
you might think that the brackets don't actually do anything, and that
is nearly the truth. The snag is that there once along the way was a
'}' in there somewhere, and } is not a valid character in a variable
name. So anything after the otherwise pointless bracket expansion
becomes explicitly NOT a part of the variable name, even if it happens
to be a legal variable name character. That's why '{$USER}san' looks
for the variable '$USER' and not for the variable '$USERsan'. It's
simply a case of one syntax lending itself nicely to solving an
unrelated problem in its spare time.
<code>echo The plural of $WORD is {$WORD}s</code> prints "The plural of
cat is cats" when \c $WORD is set to cat. Note that without the braces, fish
will try to expand a variable called <code>$WORDs</code>, which may not exist.
The latter syntax works by exploiting <a href="#expand-brace">brace
expansion</a>; care should be taken with array variables and undefined
variables, as these behave very differently to POSIX shells.
Variable expansion is the only type of expansion performed on double
quoted strings. There is, however, an important difference in how
@@ -648,7 +651,9 @@ array of five elements, the argument $foo will expand to five
elements. When quoted, like "$foo", a variable expansion will always
result in exactly one argument. Undefined variables will expand to the
empty string, and array variables will be concatenated using the space
character.
character. The dangers noted in the third example above can therefore be
avoided by wrapping the variable in double quotes
(<code>echo {"$WORD"}s</code>).
There is one further notable feature of fish variable
expansion. Consider the following code snippet:
@@ -667,12 +672,56 @@ end
The above code demonstrates how to use multiple '$' symbols to expand
the value of a variable as a variable name. One can think of
the $-symbol as a variable dereference operator. When using this
the $ symbol as a variable dereference operator. When using this
feature together with array brackets, the brackets will always match
the innermost $ dereference. Thus, $$foo[5] will always mean the fifth
element of the foo variable should be dereferenced and never that the fifth
element of the doubly dereferenced variable foo. The latter can
instead be expressed as $$foo[1][5].
the innermost $ dereference. Thus, <code>$$foo[5]</code> will always mean the fifth
element of the \c foo variable should be dereferenced, not the fifth
element of the doubly dereferenced variable \c foo. The latter can
instead be expressed as <code>$$foo[1][5]</code>.
\subsection expand-index-range Index range expansion
Both command substitution and environment variables support accessing only
specific items by providing a set of indices in square brackets. It's
often needed to access a sequence of elements. To do this, use the range
operator '..' for this. A range <code>'a..b'</code>, where range limits 'a'
and 'b' are integer numbers, is expanded into a sequence of indices
'a a+1 a+2 ... b' or 'a a-1 a-2 ... b' depending on which of 'a' or 'b'
is higher. The negative range limits are calculated from the end of the array
or command substitution.
Some examples:
<pre>
# Limit the command substitution output
echo (seq 10)[2..5] # will use elements from 2 to 5
# Output is:
# 2 3 4 5
# Use overlapping ranges:
echo (seq 10)[2..5 1..3] # will take elements from 2 to 5 and then elements from 1 to 3
# Output is:
# 2 3 4 5 1 2 3
# Reverse output
echo (seq 10)[-1..1] # will use elements from the last output line to the first one in reverse direction
# Output is:
# 10 9 8 7 6 5 4 3 2 1
</pre>
The same works when setting or expanding variables:
<pre>
# Reverse path variable
set PATH $PATH[-1..1]
# or
set PATH[-1..1] $PATH
# Use only n last items of the PATH
set n -3
echo $PATH[$n..-1]
</pre>
Note that variables can be used as indices for expansion of variables, but not
command substitution.
\subsection expand-home Home directory expansion
@@ -684,19 +733,20 @@ directory of the process owner.
\subsection expand-process Process expansion
The \% (percent) character at the beginning of a parameter followed by
a string is expanded into a process id. The following expansions are
a string is expanded into a process ID (PID). The following expansions are
performed:
- If the string is the entire word \c self, the shells pid is the result.
- Otherwise, if the string is the id of a job, the result is the process
group id of the job.
- If the string is the entire word \c self, the shell's PID is the result.
- Otherwise, if the string is the ID of a job, the result is the process
group ID of the job.
- Otherwise, if any child processes match the specified string, their
pids are the result of the expansion.
PIDs are the result of the expansion.
- Otherwise, if any processes owned by the user match the specified
string, their pids are the result of the expansion.
string, their PIDs are the result of the expansion.
- If none of these matches apply, an error is produced.
This form of expansion is useful for commands like kill and fg, which
take the process ids as an argument.
take process IDs as arguments.
Example:
@@ -705,7 +755,7 @@ with the letters 'ema', such as emacs, and if found, put it in the
foreground.
<code>kill -s SIGINT \%3</code> will send the SIGINT signal to the job
with job id 3.
with job ID 3.
\subsection combine Combining different expansions
@@ -733,11 +783,8 @@ will output 'abar1 abar2 abar3 afoo1 afoo2 afoo3'.
\section variables Environment variables
The concept of environment variables are central to any
shell. Environment variables are variables, whose values can be set
and used by the user. For information on how to use the current value
of a variable, see the section on <a href='#expand-variable'>variable
expansion</a>.
Environment variables are named pieces of data, which can be created, deleted
and their values changed and used by the user.
To set a variable value, use the <a href="commands.html#set"> \c set
command</a>.
@@ -759,7 +806,7 @@ usually blue'.
\subsection variables-scope Variable scope
There are three kinds of variables in fish, universal, global and
There are three kinds of variables in fish: universal, global and
local variables. Universal variables are shared between all fish
sessions a user is running on one computer. Global variables are
specific to the current fish session, but are not associated with any
@@ -768,9 +815,9 @@ explicitly requests it using <code>set -e</code>. Local variables are
specific to the current fish session, and associated with a specific
block of commands, and is automatically erased when a specific block
goes out of scope. A block of commands is a series of commands that
begins with one of the commands \c 'for, \c 'while' , \c 'if', \c
'function', \c 'begin' or \c 'switch', and ends with the command \c
'end'. The user can specify that a variable should have either global
begins with one of the commands \c for, \c while , \c if, \c
function, \c begin or \c switch, and ends with the command \c
end. The user can specify that a variable should have either global
or local scope using the \c -g/--global or \c -l/--local switches.
Variables can be explicitly set to be universal with the \c -U or \c
@@ -780,7 +827,7 @@ creating or updating a variable are:
-# If a variable is explicitly set to either universal, global or local, that setting will be honored. If a variable of the same name exists in a different scope, that variable will not be changed.
-# If a variable is not explicitly set to be either universal, global or local, but has been previously defined, the variable scope is not changed.
-# If a variable is not explicitly set to be either universal, global or local and has never before been defined, the variable will be local to the currently executing functions. If no function is executing, the variable will be global.
-# If a variable is not explicitly set to be either universal, global or local and has never before been defined, the variable will be local to the currently executing function. Note that this is different from using the \c -l or \c --local flag. If one of those flags is used, the variable will be local to the most inner currently executing block, while without these the variable will be local to the function. If no function is executing, the variable will be global.
There may be many variables with the same name, but different scopes.
When using a variable, the variable scope will be searched from the
@@ -818,7 +865,7 @@ prompt will instantly change to blue on both terminals.
\subsection variables-functions Variable scope for functions
When calling a function, all non-global variables temporarily
When calling a function, all current local variables temporarily
disappear. This shadowing of the local scope is needed since the
variable namespace would become cluttered, making it very easy to
accidentally overwrite variables from another function.
@@ -871,7 +918,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 \c seq
are more suited to such use.
If you do not use any brackets, all the elements of the array will be
@@ -909,44 +956,49 @@ If you specify a negative index when expanding or assigning to an
array variable, the index will be calculated from the end of the
array. For example, the index -1 means the last index of an array.
A range of indices can be specified, see <a href='#expand-index-range'>index
range expansion</a> for details.
All arrays are one-dimensional and cannot contain other arrays, although
it is possible to fake nested arrays using the dereferencing rules of
<a href="#expand-variable">variable expansion</a>.
\subsection variables-special Special variables
The user can change the settings of \c fish by changing the values of
certain environment variables.
- \c BROWSER, which is the users preferred web browser. If this variable is set, fish will use the specified browser instead of the system default browser to display the fish documentation.
- \c CDPATH, which is an array of directories in which to search for the new directory for the \c cd builtin. The fish init files defined CDPATH to be a universal variable with the values . and ~.
- \c BROWSER, the user's preferred web browser. If this variable is set, fish will use the specified browser instead of the system default browser to display the fish documentation.
- \c CDPATH, an array of directories in which to search for the new directory for the \c cd builtin. By default, the fish configuration defines \c CDPATH to be a universal variable with the values \c . and \c ~.
- A large number of variable starting with the prefixes \c fish_color and \c fish_pager_color. See <a href='#variables-color'>Variables for changing highlighting colors</a> for more information.
- \c fish_greeting, which is the greeting message printed on startup.
- \c fish_greeting, the greeting message printed on startup.
- \c LANG, \c LC_ALL, \c LC_COLLATE, \c LC_CTYPE, \c LC_MESSAGES, \c LC_MONETARY, \c LC_NUMERIC and \c LC_TIME set the language option for the shell and subprograms. See the section <a href='#variables-locale'>Locale variables</a> for more information.
- \c PATH, which is an array of directories in which to search for commands
- \c umask, which is the current file creation mask. The preferred way to change the umask variable is through the <a href="commands.html#umask">umask shellscript function</a>. An attempt to set umask to an invalid value will always fail.
- \c fish_user_paths, an array of directories that are appended to PATH. This can be a universal variable.
- \c PATH, an array of directories in which to search for commands
- \c umask, the current file creation mask. The preferred way to change the umask variable is through the <a href="commands.html#umask">umask function</a>. An attempt to set umask to an invalid value will always fail.
\c fish also sends additional information to the user through the
values of certain environment variables. The user can not change the
values of certain environment variables. The user cannot change the
values of most of these variables.
- \c _, which is the name of the currently running command.
- \c argv, which is an array of arguments to the shell or function. \c argv is only defined when inside a function call, or if fish was invoked with a list of arguments, like 'fish myscript.fish foo bar'. This variable can be changed by the user.
- \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. 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.
- \c _, the name of the currently running command.
- \c argv, an array of arguments to the shell or function. \c argv is only defined when inside a function call, or if fish was invoked with a list of arguments, like 'fish myscript.fish foo bar'. This variable can be changed by the user.
- \c history, an array containing the last commands that were entered.
- \c HOME, the user's home directory. This variable can only be changed by the root user.
- \c PWD, the current working directory.
- \c status, the <a href="#variables-status">exit status</a> 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, the current username. This variable can only be changed by the root user.
The names of these variables are mostly derived from the csh family of
shells and differ from the ones used by Bourne style shells such as
bash. The csh names where chosen because Bourne style names, such as
?, * and @ lead to significantly less readable code, and much larger
discoverability problems, and given the existence of tab completion,
the keystroke savings are minimal.
bash.
Variables whose name are in uppercase are exported to the commands
started by fish, those in lowercase are not exported. This rule is not
started by fish, while those in lowercase are not exported. This rule is not
enforced by fish, but it is good coding practice to use casing to
distinguish between exported and unexported variables. \c fish also
uses several variables internally. Such variables are prefixed with
the string __FISH or __fish. These should never be used by the
the string \c __FISH or \c __fish. These should never be used by the
user. Changing their value may break fish.
\subsection variables-status The status variable
@@ -961,10 +1013,10 @@ some form of problem.
Fish stores the exit status of the last process in the last job to
exit in the \c status variable.
If fish encounters a problem while executing a command, the status
If \c fish encounters a problem while executing a command, the status
variable may also be set to a specific value:
- 1 is the generally the exit status from fish builtins if they where supplied with invalid arguments
- 1 is the generally the exit status from fish builtin commands if they were supplied with invalid arguments
- 124 means that the command was not executed because none of the wildcards in the command produced any matches
- 125 means that while an executable with the specified name was located, the operating system could not actually execute the command
- 126 means that while a file with the specified name was located, it was not executable
@@ -1004,6 +1056,7 @@ highlighting in the completion pager:
- \c fish_pager_color_completion, the color of the completion itself
- \c fish_pager_color_description, the color of the completion description
- \c fish_pager_color_progress, the color of the progress bar at the bottom left corner
- \c fish_pager_color_secondary, the background color of the every second completion
Example:
@@ -1027,13 +1080,13 @@ variables set the specified aspect of the locale information. LANG
is a fallback value, it will be used if none of the LC_ variables are
specified.
\section builtin-overview Builtins
\section builtin-overview Builtin commands
Many other shells have a large library of builtin commands. Most of
these commands are also available as standalone commands, but have
been implemented in the shell anyway for whatever reason. To avoid
been implemented in the shell anyway. To avoid
code duplication, and to avoid the confusion of subtly differing
versions of the same command, \c fish only implements builtins for
versions of the same command, \c fish generally only implements builtins for
actions which cannot be performed by a regular command.
For a list of all builtins, functions and commands shipped with fish,
@@ -1041,31 +1094,32 @@ see the <a href="#toc-commands">table of contents</a>. The
documentation is also available by using the <code>--help</code>
switch of the command.
\section editor Command Line editor
\section editor Command line editor
The \c fish editor features copy and paste, a searchable history and
many editor functions that can be bound to special keyboard
shortcuts. The most important keybinding is probably the tab key, which is bound to the complete function.
shortcuts.
Here are some of the commands available in the editor:
- Tab completes the current token
- Home or Ctrl-a moves to the beginning of the line
- End or Ctrl-e moves to the end of line
- Left and right moves one character left or right
- Alt-left and Alt-right moves one word left or right, or moves forward/backward in the directory history if the commandline is empty
- Up and down search the command history for the previous/next command containing the string that was specified on the commandline before the search was started. If the commandline was empty when the search started, all commands match. See the <a href='#history'>history </a>section for more information on history searching.
- Alt-up and Alt-down search the command history for the previous/next token containing the token under the cursor before the search was started. If the commandline was not on a token when the search started, all tokens match. See the <a href='#history'>history </a>section for more information on history searching.
- Delete and backspace removes one character forwards or backwards 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>
- Ctrl-u move contents from the beginning of line to the cursor to the <a href="#killring">killring</a>
- Ctrl-l clear and repaint screen
- Ctrl-w move previous word to the <a href="#killring">killring</a>
- Alt-d move next word to the <a href="#killring">killring</a>
- Alt-w prints a short description of the command under the cursor
- Alt-l lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed
- Alt-p adds the string '| less;' to the end of the job under the cursor. The result is that the output of the command will be paged.
- Tab <a href="#completion">completes</a> the current token
- Home or Ctrl-A moves to the beginning of the line
- End or Ctrl-E moves to the end of line
- Left and Right moves one character left or right
- Alt-Left and Alt-Right moves one word left or right, or moves forward/backward in the directory history if the commandline is empty
- Up and Down search the command history for the previous/next command containing the string that was specified on the commandline before the search was started. If the commandline was empty when the search started, all commands match. See the <a href='#history'>history </a>section for more information on history searching.
- Alt-Up and Alt-Down search the command history for the previous/next token containing the token under the cursor before the search was started. If the commandline was not on a token when the search started, all tokens match. See the <a href='#history'>history </a>section for more information on history searching.
- Delete and Backspace removes one character forwards or backwards 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 moves contents from the cursor to the end of line to the <a href="#killring">killring</a>
- Ctrl-U moves contents from the beginning of line to the cursor to the <a href="#killring">killring</a>
- Ctrl-L clears and repaints the screen
- Ctrl-W moves the previous word to the <a href="#killring">killring</a>
- Alt-D moves the next word to the <a href="#killring">killring</a>
- Alt-W prints a short description of the command under the cursor
- Alt-L lists the contents of the current directory, unless the cursor is over a directory argument, in which case the contents of that directory will be listed
- Alt-P adds the string <code>'| less;'</code> to the end of the job under the cursor. The result is that the output of the command will be paged.
You can change these key bindings using the
<a href="commands.html#bind">bind</a> builtin command.
@@ -1108,8 +1162,8 @@ inserted into a linked list of kills, called the kill ring. To paste
the latest value from the kill ring use Ctrl-Y. After pasting, use
Meta-Y to rotate to the previous kill.
If the environment variable DISPLAY is set, \c fish will try to
connect to the X-windows server specified by this variable, and use
If the environment variable DISPLAY is set and the \c xsel program is installed, \c fish will try to
connect to the X Windows server specified by this variable, and use
the clipboard on the X server for copying and pasting.
\subsection history Searchable history
@@ -1121,31 +1175,36 @@ forwards and backwards in the history. If the current command line is
not empty when starting a history search, only the commands containing
the string entered into the command line are shown.
By pressing Alt-up and Alt-down, a history search is also performed,
By pressing Alt-Up and Alt-Down, a history search is also performed,
but instead of searching for a complete commandline, each commandline
is tokenized into separate elements just like it would be before
execution, and each such token is matched against the token under the
cursor when the search began.
is broken into separate elements just like it would be before
execution, and the history is searched for an element matching that under
the cursor.
History searches can be aborted by pressing the escape key.
The history is stored in the file '~/.config/fish/fish_history'. It is automatically
read on startup and merged on program exit.
Prefixing the commandline with a space will prevent the entire line
from being stored in the history.
Example:
The history is stored in the file <code>~/.config/fish/fish_history</code>.
To search for previous entries containing the word 'make', type 'make'
Examples:
To search for previous entries containing the word \c 'make', type \c 'make'
in the console and press the up key.
If the commandline reads '<code>cd m</code>', place the cursor over the \c m
character and press Alt-Up to search for previously typed words containing 'm'.
\subsection multiline Multiline editing
The fish commandline editor can be used to work on commands that are
several lines long. There are three ways to make a command span more
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 before pressing the enter key.
- Pressing the Enter key while a block of commands is unclosed, such as when one or more block commands such as \c 'for', \c 'begin' or \c 'if' do not have a corresponding \c 'end' command.
- Pressing Alt-Enter instead of pressing the Enter key.
- By inserting a backslash (\\) character before pressing the Enter key, escaping the newline.
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
@@ -1162,9 +1221,13 @@ continue using the shell. In such cases, there are several ways in
which the user can change <code>fish</code>'s behavior.
-# By ending a command with the \& (ampersand) symbol, the user tells \c fish to put the specified command into the background. A background process will be run simultaneous with \c fish. \c fish will retain control of the terminal, so the program will not be able to read from the keyboard.
-# By pressing ^Z, the user stops a currently running foreground program and returns control to \c fish. Some programs do not support this feature, or remap it to another key. Gnu emacs uses ^X z to stop running.
-# By pressing ^Z, the user stops a currently running foreground program and returns control to \c fish. Some programs do not support this feature, or remap it to another key. GNU Emacs uses ^X z to stop running.
-# By using the <a href="commands.html#fg">fg</a> and <a href="commands.html#bg">bg</a> builtin commands, the user can send any currently running job into the foreground or background.
Note that functions cannot be started in the background. Functions that
are stopped and then restarted in the background using the \c bg command
will not execute correctly.
\section initialization Initialization files
On startup, \c fish evaluates the files /usr/share/fish/config.fish
@@ -1198,9 +1261,9 @@ shell:
end</pre>
<a href="#variables-universal">Universal variables</a> are stored in
the file .config/fish/fishd.HOSTNAME, where HOSTNAME is the name of your
computer. Do not edit this file directly, edit them through fish
scripts or by using fish interactively instead.
the file .config/fish/fishd.MACHINE_ID, where MACHINE_ID is typically your
MAC address. Do not edit this file directly, as your edits may be overwritten.
Edit them through fish scripts or by using fish interactively instead.
\section other Other features
@@ -1227,8 +1290,8 @@ fish_color_substitution, \c fish_color_redirection, \c fish_color_end,
\c fish_color_error, \c fish_color_param, \c fish_color_comment, \c
fish_color_match, \c fish_color_search_match, \c fish_color_cwd, \c
fish_pager_color_prefix, \c fish_pager_color_completion, \c
fish_pager_color_description and \c
fish_pager_color_progress. Usually, the value of these variables will
fish_pager_color_description, \c fish_pager_color_progress
and \c fish_pager_color_secondary. Usually, the value of these variables will
be one of \c black, \c red, \c green, \c brown, \c yellow, \c blue, \c
magenta, \c purple, \c cyan, \c white or \c normal, but they can be an
array containing any color options for the set_color command.
@@ -1323,7 +1386,7 @@ translated, a future version of fish should also include translated
manuals.
To make a translation of fish, you will first need the source code,
available from the <a href='http://www.fishshell.org'>fish
available from the <a href='http://fishshell.com/'>fish
homepage</a>. Download the latest version, and then extract it using a
command like <code>tar -zxf fish-VERSION.tar.gz</code>.
@@ -1374,70 +1437,19 @@ are ways to avoid this, but they are too complicated for this short
introduction. See the full manual for the printf C function for more
information.)
Once you have provided a translation for fish, please send it to <a
href='fish-users@lists.sf.net'>fish-users@lists.sf.net</a>.
Once you have provided a translation for fish, please submit it via
the instructions in <a href="#more-help">Further help and development</a>.
\section todo Missing features and bugs
\section more-help Further help and development
\subsection todo-features Missing features
If you have a question not answered by this documentation, there are
several avenues for help:
- Complete vi-mode key bindings
- More completions (for example konsole, gnome-terminal,
rlogin, rsync, arch, finger, bibtex, aspell, xpdf,
compress, wine, dig, batch,
g++, javac, java, gcj, lpr, doxygen, whois)
- Undo support
- wait shellscript
- Support for the screen clipboard
- It should be possible to test in a script if a function is autoloaded or manually defined
- The validator should be better about error reporting unclosed quotes. They are usually reported as something else.
-# The official mailing list at <a href='fish-users@lists.sf.net'>fish-users@lists.sf.net</a>
-# The Internet Relay Chat channel, \c #fish on \c irc.oftc.net
-# The <a href="http://github.com/fish-shell/fish-shell/">project GitHub page</a>
\subsection todo-possible Possible features
- mouse support like zsh has with http://stchaz.free.fr/mouse.zsh
installed would be awesome
- suggest a completion on unique matches by writing it out in an understated color
- Highlight beginning/end of block when moving over a block command
- command specific wildcarding (use case * instead of case '*', etc.)
- Map variables. (export only the values. When expanding with no key specified, expand to all values.)
- Descriptions for variables using 'set -d'.
- Parse errors should when possible honor IO redirections
- Support for writing strings like /u/l/b/foo and have them expand to /usr/local/bin/foo - perhaps through tab expansion
- Right-side prompt
- 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-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.
- Try to remove more malloc calls to reduce memory usage. The time_t arrays used by the autoloader sound like a good candidate.
- The code validator should warn about unknown commands.
- Auto-newlines
- A fault injector could be written to increase robustness and testing of error recovery paths
- The parser/validator could be more clever in order to make things like writing 'function --help' work as expected
- Some event handler functions make much more sense as oneshots - maybe they should be automatically deleted after firing?
- exec_subshell should be either merged with eval or moved to parser.c
- 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
- Suspending and then resuming pipelines containing a builtin or a shellscript function is broken. Ideally, the exec function in exec.c should be able to resume execution of a partially executed job.
- 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 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>.
If you have an improvement for fish, you can submit it via the mailing list
or the GitHub page.
*/

View File

@@ -3,10 +3,12 @@
\subsection isatty-synopsis Synopsis
<tt>isatty [FILE DESCRIPTOR]</tt>
where FILE DESCRIPTOR may be either the number of a file descriptor, or one
of the strings stdin, stdout and stderr.
\subsection isatty-description Description
<tt>isatty</tt> tests if a file descriptor is a tty.
If the specified file descriptor is a tty, the exit status of the
command is zero, otherwise, it is non-zero.
<tt>FILE DESCRIPTOR</tt> may be either the number of a file descriptor, or one of the
strings <tt>stdin</tt>, \c stdout and <tt>stderr</tt>.
If the specified file descriptor is a tty, the exit status of the command is
zero. Otherwise, it is non-zero.

View File

@@ -1,21 +1,25 @@
\section jobs jobs - print currently running jobs
\subsection jobs-synopsis
\subsection jobs-synopsis Synopsis
<code>jobs [OPTIONS] [PID]</code>
\subsection jobs-description Description
The <code>jobs</code> builtin causes fish to print a list of the currently
running jobs and their status.
<code>jobs</code> prints a list of the currently
running <a href="index.html#syntax-job-control">jobs</a> and their status.
jobs accepts the following switches:
- <code>-c</code> or <code>--command</code> print the command name for each process in jobs
- <code>-g</code> or <code>--group</code> only print the group id of each job
- <code>-h</code> or <code>--help</code> display a help message and exit
- <code>-l</code> or <code>--last</code> only the last job to be started is printed
- <code>-p</code> or <code>--pid</code> print the process id for each process in all jobs
- <code>-c</code> or <code>--command</code> prints the command name for each process in jobs.
- <code>-g</code> or <code>--group</code> only prints the group ID of each job.
- <code>-h</code> or <code>--help</code> displays a help message and exits.
- <code>-l</code> or <code>--last</code> prints only the last job to be started.
- <code>-p</code> or <code>--pid</code> prints the process ID for each process in all jobs.
On systems that supports this feature, jobs will print the CPU usage
of each job since the last command was executed. The CPU usage is
expressed as a percentage of full CPU activity. Note that on
multiprocessor systems, the total activity may be more than 100\%.
\subsection jobs-example Example
<code>jobs</code> outputs a summary of the current jobs.

Some files were not shown because too many files have changed in this diff Show More