Compare commits

...

188 Commits

Author SHA1 Message Date
axel
6d0b6e5de5 Bump version number to 1.21.0
darcs-hash:20060225022220-ac50b-27a71eef149c0caa5336d425f24686ce152dcad1.gz
2006-02-25 12:22:20 +10:00
axel
fd6bf06f15 Various minor edits
darcs-hash:20060225022139-ac50b-9ef43f88e2266978e9b39038a6a5087ff1305509.gz
2006-02-25 12:21:39 +10:00
axel
d2e11ea61d Fix crash bug on invalid input to fish_pager
darcs-hash:20060224184050-ac50b-da122d893fa0e2aabbd48058c696e2815c4657ca.gz
2006-02-25 04:40:50 +10:00
axel
dad2b93d1e Add functiopn prototype completions for valgrind --alloc-fn
darcs-hash:20060224135618-ac50b-bcd2fa57593f6a5c9f41b9513ac25f859baf1659.gz
2006-02-24 23:56:18 +10:00
axel
1075ca69b0 Switch to standard syntax for octal escapes
darcs-hash:20060224121829-ac50b-8e19f27857378e6456ae08269721138bd60f3464.gz
2006-02-24 22:18:29 +10:00
axel
e29f5c5474 Add an FAQ section to the documentation, and remove a few seactions of the manual containing introductory material on fish which was no longer accurate
darcs-hash:20060224011446-ac50b-e9246e23dbf725a3e2488f7831b1c7420cdd42db.gz
2006-02-24 11:14:46 +10:00
axel
22bfa6638a Update of the makefile on how to handle the directory hierarchy transition
darcs-hash:20060223153556-ac50b-4af8c2376a37c28f056b7fef37db3fb371a3e899.gz
2006-02-24 01:35:56 +10:00
axel
1a48941f6b Protect against double-free of the process argument list
darcs-hash:20060222175107-ac50b-87c36439e2ec2f8be652db1595dad9a09e20f36c.gz
2006-02-23 03:51:07 +10:00
axel
68e0c94dbb Do not unescape strings from completion callouts. Why was this done before?
darcs-hash:20060222174716-ac50b-218c6896918e5cf8047ea6291a8cde44061d0b57.gz
2006-02-23 03:47:16 +10:00
axel
ca04fc745d Add some input validation code to various functions
darcs-hash:20060222154152-ac50b-608032284165f099beecd1cd4f7c6bb2b45df432.gz
2006-02-23 01:41:52 +10:00
axel
3afead1827 Documentation clarification for the cd builtin
darcs-hash:20060222142137-ac50b-cc9200ed23fa5796a56dc4ee3dde1ff7e8768fc3.gz
2006-02-23 00:21:37 +10:00
axel
0ea69dab7b Drop unuses error counter for string conversions
darcs-hash:20060222142042-ac50b-25f2e050c680071ccec6989e477f6db5904a2713.gz
2006-02-23 00:20:42 +10:00
axel
a4a025b786 Allow multiple slashes in a wildcard to be used as a single directory separator
darcs-hash:20060221154738-ac50b-e4b35d3604d8e39d3aff7b8da38617272bd6e89e.gz
2006-02-22 01:47:38 +10:00
axel
328c3a39a1 Move _ shellscript function to it's own file
darcs-hash:20060221153701-ac50b-05cecdac1221e0abc709d9e9c1799faa7986fa78.gz
2006-02-22 01:37:01 +10:00
axel
5aa019a0b5 Fix off-by-one error resulting in truncated output from wcsndup fallback and halloc_wcsndup
darcs-hash:20060221144642-ac50b-9dcd77238bc4bd740bbda6e15ded793fad44c363.gz
2006-02-22 00:46:42 +10:00
axel
92aa99104a Fix rare accidental ellipsisizing of strings that will actually fit in fish_pager
darcs-hash:20060221103435-ac50b-f46a08e29e7860886a357bc1c5d314b594793e68.gz
2006-02-21 20:34:35 +10:00
axel
6b544bc3c2 API documentation, code style cleanup, etc.
darcs-hash:20060220131146-ac50b-6ec3664e5e3eaefa2296a93d39014058df37fdf2.gz
2006-02-20 23:11:46 +10:00
axel
ea0005e16d Move code for setting ls and grep colors to function definition files
darcs-hash:20060220130203-ac50b-feb426f6450a0bbd17cb9dacdca94d4d5b72c113.gz
2006-02-20 23:02:03 +10:00
axel
6901ad361d Make fish continue parsing/executing a file if a command is not found
darcs-hash:20060220125524-ac50b-1f85e530cbbcb45988254c75cd45c11395c5cd27.gz
2006-02-20 22:55:24 +10:00
axel
b21cccf5f0 A flag got reversed, causing children to execute even if an IO redirection failed
darcs-hash:20060220014036-ac50b-43156940397e0535cfa9dd7e88d61e4ca4bab13b.gz
2006-02-20 11:40:36 +10:00
axel
7740035d14 Remove some ancient debug messages, drop two warnings, add some braces and other minor code tweaks
darcs-hash:20060219181932-ac50b-2d032e7a64257a6ca0db078ea9c81ae04a01120f.gz
2006-02-20 04:19:32 +10:00
axel
7dc3934997 Use variable name as index for tables when autoloading functions and completions in order to better handle changes on path variable values
darcs-hash:20060219170116-ac50b-8f617c6f8960660e6227827914dc910a78655c13.gz
2006-02-20 03:01:16 +10:00
axel
845e15876c Minor edits, additional comments, etc.
darcs-hash:20060219015438-ac50b-b6346876460912f3c27d1bb4287aeab962260ab6.gz
2006-02-19 11:54:38 +10:00
axel
c4e7a7992f Fix bug causing fish to occasionally reset line number for error reporting
darcs-hash:20060219011702-ac50b-c72b1f5ae56d3757c3fbfca002f1bc33c36a7660.gz
2006-02-19 11:17:02 +10:00
axel
43ab84397b Make sure that command specific completions can handle input strings with wildcards reasonably well
darcs-hash:20060219011432-ac50b-89a73a3d414f2dbd8a213b851fcb1c494e022eae.gz
2006-02-19 11:14:32 +10:00
axel
0840c9248f Give more detail in an error message
darcs-hash:20060218024346-ac50b-f26f6ef107fffa398b6ff61baff81914b998940a.gz
2006-02-18 12:43:46 +10:00
axel
dd79d75504 Move a few shellscript bits around
darcs-hash:20060218024145-ac50b-207ca782808ea8968cb38253c7bc2563350f38b2.gz
2006-02-18 12:41:45 +10:00
axel
7073f0b58b Change translation file offsets in swedish translation, needed to avoid darcs hang
darcs-hash:20060218023559-ac50b-bf6f5802b7ab810a3a8167f92358c085e3f02401.gz
2006-02-18 12:35:59 +10:00
axel
15916bfbdc Update build dependencies
darcs-hash:20060218023432-ac50b-9cfdc633f4b6834dea4324f429b1decca6d9e110.gz
2006-02-18 12:34:32 +10:00
axel
228fdbef5a Use the right sources for generating translation strings
darcs-hash:20060218023332-ac50b-5a2cec156ad5c49d052f17cf14fd14e72e0aa137.gz
2006-02-18 12:33:32 +10:00
axel
7f7f8fb156 Fix broken call to source /fish/fish on startup
darcs-hash:20060217223236-ac50b-384ea2549a2bbf445842700e693f5edc8bf72023.gz
2006-02-18 08:32:36 +10:00
axel
2ae9735858 Add the LGPL license to the license section of the documentation - xdgmime is released under this license. Also add a few rulers, and make some other minor edits to the license section.
darcs-hash:20060217222051-ac50b-8fc2e6d4e32d0f7f67cde8ff475ec0e16f72ffa1.gz
2006-02-18 08:20:51 +10:00
axel
8ac1688c89 Allow backslash-escaping of newlines
darcs-hash:20060217164119-ac50b-6efd2491fb7f504ad26ca35b2a7421d24c61ec63.gz
2006-02-18 02:41:19 +10:00
axel
9cd2dbc9e7 Remove note about problem with ancient fish version
darcs-hash:20060217125341-ac50b-8f4dc873c8b7146cfdae00b62a139c0643e4156e.gz
2006-02-17 22:53:41 +10:00
axel
a74055bc33 Proper ordering on paths for dynamic loading - user stuff should override sysadmin stuff should overrtide default stuff
darcs-hash:20060217125318-ac50b-f74103958cf01103b351227ae561703ac96ebe95.gz
2006-02-17 22:53:18 +10:00
axel
e1d0b9370e Minor edits in parse_util.c
darcs-hash:20060217125205-ac50b-f3cd1572eec966581730ee1983d06b64caac566f.gz
2006-02-17 22:52:05 +10:00
axel
5dfa28059e Remove dropped fish_function.fish from Makefile
darcs-hash:20060217103540-ac50b-5ea95b93bd93512100e652e2cd8146d4f2fdbf58.gz
2006-02-17 20:35:40 +10:00
axel
7ead45d899 More missing files
darcs-hash:20060217103214-ac50b-f0f65a28d574e6a7258148fd1162677be287e99c.gz
2006-02-17 20:32:14 +10:00
axel
5c9ac72c19 Add missing files
darcs-hash:20060217103018-ac50b-9097f60908d06d89f235d969719fe654117b423e.gz
2006-02-17 20:30:18 +10:00
axel
343cafef34 Redo installation file structure, move lots of things to $PREFIX/share/fish
darcs-hash:20060217101339-ac50b-d93d2c620a4b7f75f05ff461a6edbee001da7613.gz
2006-02-17 20:13:39 +10:00
axel
95a01f3c8f Use plgin support in output.c to make buffered pager output - noticably faster printing in many situations
darcs-hash:20060216142159-ac50b-2c31025be7d12fcc32f4ba352b59ea4cc3cc1387.gz
2006-02-17 00:21:59 +10:00
axel
cfa367f14c Finish support for plugging in a new output function for output.c
darcs-hash:20060216142100-ac50b-06db798debb56c7640f7ffec0bc32c8ca7b013e5.gz
2006-02-17 00:21:00 +10:00
axel
94cae410f3 Move the move_cursor and writeb functions to output.c, and make the output function used by output.c configurable
darcs-hash:20060216134025-ac50b-360d4816ee2c3f2ffdc8e5660502cb97b31d699e.gz
2006-02-16 23:40:25 +10:00
axel
cc69afc4fe Fix bug in fish causing occasionally incorrect signal handlers
darcs-hash:20060216133632-ac50b-f24c049830f9c6deca50aca640189ad3f87b630a.gz
2006-02-16 23:36:32 +10:00
axel
777a559e12 Use env to work around path issues on the shebang line for the seq fallback implementation
darcs-hash:20060216121617-ac50b-6c7e34329a5ca8f3cd6756f1860fa10693db21e4.gz
2006-02-16 22:16:17 +10:00
axel
0427ccbb55 Fix invalid destruction order on exit
darcs-hash:20060215222513-ac50b-f3b489568e4bad3532c36f9c66a3c0d61352cd5b.gz
2006-02-16 08:25:13 +10:00
axel
f9a4699147 Add swedish translation of function descriptions
darcs-hash:20060215180031-ac50b-f21e471c178610b7a2912f82b3d46b46f76d350c.gz
2006-02-16 04:00:31 +10:00
axel
e6e287ae1f Make function descriptions for dynamically loaded functions translatable
darcs-hash:20060215175925-ac50b-5dc52c615650779771a6c4a3c5d006b72dbca67d.gz
2006-02-16 03:59:25 +10:00
axel
143602e5f6 Minor edits
darcs-hash:20060215024900-ac50b-51863879c32660d9787db706c34fef10aa4c30c2.gz
2006-02-15 12:49:00 +10:00
axel
1c2d3583e7 Drop fuction from man completion file, already lives in it's own file
darcs-hash:20060215024822-ac50b-dbb1e3769f0b3101f634d4bf5f5e530aacc1dfda.gz
2006-02-15 12:48:22 +10:00
axel
e58110da2c Reset list of loaded completion files when running complete_destroy. Otherwise completions will not get propely loaded on language changes.
darcs-hash:20060215024644-ac50b-d259cdac14dccb55309a4702683f1b881636e9ac.gz
2006-02-15 12:46:44 +10:00
axel
0d1683edc8 Add missing function prototype in parse_util.h
darcs-hash:20060215022415-ac50b-a6510213a3559c7bd6b944bbe87c739faaef4792.gz
2006-02-15 12:24:15 +10:00
axel
c94b9e504d Remove the rather stupid -y option for complete, which loads another commands completions. Mostly the same results can be had with fewer bugs and corner cases vy using the new dynamically loaded functions.
darcs-hash:20060215022228-ac50b-85614ed684f73460d43543a579ff2c7e7914efeb.gz
2006-02-15 12:22:28 +10:00
axel
8be3bf3e5d Add support for checking current filename and current line nuber to status builtin
darcs-hash:20060214195747-ac50b-77b6aba42c99da4f79ea500c47cc00bba12ec663.gz
2006-02-15 05:57:47 +10:00
axel
3e165297ce Add support for sending arguments whenusing the source builtin
darcs-hash:20060214195636-ac50b-511c211368103df6923d63cef99ce20a88d31be3.gz
2006-02-15 05:56:36 +10:00
axel
7ac922def6 Fix timestap checking bug when autoloading scripts
darcs-hash:20060214195517-ac50b-3d084f351c5d1f4f11afb4fc1c706c843de98da1.gz
2006-02-15 05:55:17 +10:00
axel
f12127c775 Add missing translation string
darcs-hash:20060214114804-ac50b-1ce10e7613ebec38a283cd6f6f8ad08397cec529.gz
2006-02-14 21:48:04 +10:00
axel
73d84fe136 Escape semicolons and other chars that have syntactic meaning in various shell command situations
darcs-hash:20060214114739-ac50b-17616bf01a0504041c0d29ee9428abd8a9f9ad3a.gz
2006-02-14 21:47:39 +10:00
axel
c595448f9c Add missing #define, needed by new fish_pager code
darcs-hash:20060214114631-ac50b-39756b670fd0ab1f5a6bd067ba2ff3f9d6f82fc2.gz
2006-02-14 21:46:31 +10:00
axel
5a2aeb1511 Swedish translation checkin
darcs-hash:20060214113926-ac50b-86926878d127405be8a3acd8cf9ac36a56ea432e.gz
2006-02-14 21:39:26 +10:00
axel
5fb9d9aa38 Fix clash in usage of unicode private use area
darcs-hash:20060214113514-ac50b-5160e3b7ac9401a7ef198121d39e33225df4b766.gz
2006-02-14 21:35:14 +10:00
axel
8258961c29 Fix minor display bugs and a memory leak in fish_pager
darcs-hash:20060214113347-ac50b-302a7da47f9c07af3acc9a2dcc5c8007127fc3a2.gz
2006-02-14 21:33:47 +10:00
axel
0dab94a54c Group multiple switches with common description together when printing completions
darcs-hash:20060214000823-ac50b-2bde1ac964baf12a515d763a076434757ac9fd21.gz
2006-02-14 10:08:23 +10:00
axel
3097f71abd Initial checkin of german translation
darcs-hash:20060213215118-ac50b-7981b89adff210e5b53cc18cdc0ad6f1c865cd83.gz
2006-02-14 07:51:18 +10:00
axel
ea5e1b70db Fix memory leak and missing error check in dynamic function lookup
darcs-hash:20060213214416-ac50b-2bd8532aed600c06234e6fce500c737fcb415a5c.gz
2006-02-14 07:44:16 +10:00
axel
6b393d35a9 Spelling fixes from HJB
darcs-hash:20060213213659-ac50b-024e99d5c3a56d1c7308bf5cc291e032aa65bc0e.gz
2006-02-14 07:36:59 +10:00
axel
a5dde6021c Change a few chars to be long
darcs-hash:20060213111023-ac50b-5ad5ddf9beb72117fc1dc81c048a83e5480bc510.gz
2006-02-13 21:10:23 +10:00
axel
a015472739 Remova a few calls to free that are handled by halloc now
darcs-hash:20060213110929-ac50b-95bba1b70840ef16e45f3876c5d0521a51b90561.gz
2006-02-13 21:09:29 +10:00
axel
6affa4452b Check for translation strings in function files
darcs-hash:20060212222406-ac50b-10424c1daeb9e81054c87bbf8f7839da72cb05bb.gz
2006-02-13 08:24:06 +10:00
axel
7ebfa380dd Variable used for filenmae length was accidentally set to static
darcs-hash:20060212222313-ac50b-1893f4fbe52a8c72ebc8332b1e575c1b8a2b31d5.gz
2006-02-13 08:23:13 +10:00
axel
370336e7c7 Fix various minor misses in moving of shellscript functions
darcs-hash:20060212222205-ac50b-d7bccc4c1e1dd752ca40560e81309bb37bb4dca8.gz
2006-02-13 08:22:05 +10:00
axel
bad4269dc9 Remove trailing periods from descriptions
darcs-hash:20060212221918-ac50b-d2310f6a166b585b242a9b548b1d1f890cac2e03.gz
2006-02-13 08:19:18 +10:00
axel
effe6f47a3 Minor hallocifications
darcs-hash:20060212190301-ac50b-c15b9a8c6c2897189c4343946d9bd115eefb4972.gz
2006-02-13 05:03:01 +10:00
axel
7eb3a5a17d Allow backslash of quotes within quotes
darcs-hash:20060212161331-ac50b-c25affaa4b18e1654dab3d08debafa95017009ea.gz
2006-02-13 02:13:31 +10:00
axel
b6cd723eb7 Fix a few compiler warnings, add halloc debug output on exit if HALLOC_DEBUG is defined and other minor tweaks
darcs-hash:20060212131846-ac50b-128685d1c043697768be70631c736567544abf2c.gz
2006-02-12 23:18:46 +10:00
axel
a2cd8c8a8d Move a few more shellscript functions to their own files
darcs-hash:20060212131421-ac50b-861f8941af76cf9a1e6fb7da2ac7f33795fab272.gz
2006-02-12 23:14:21 +10:00
axel
3b03bd6a10 Check if curses-string 'flash_screen' is set before using it in fish_pager
darcs-hash:20060212131253-ac50b-39c03e4223e66230c9c76a59bc95eeadc38637c9.gz
2006-02-12 23:12:53 +10:00
Nicholas Pilon
6caff2d85d svn completions
Command-line completions for svn. This includes some tweaks to the cvs completions file, to move a common function out into fish_complete.fish.

darcs-hash:20060210004314-494f2-c12a77084499cbc4216e8c5603ae4fadfb6b384c.gz
2006-02-10 10:43:14 +10:00
axel
eeaa241be8 Optimizations of how variable expansion implementation
darcs-hash:20060212112930-ac50b-9b8bb640ef1a5bd14230ecd276167a80d6d986c9.gz
2006-02-12 21:29:30 +10:00
axel
8fdb4d2a17 Define fish_function_path at the top of the first init file to improve preformance (each non-existing variable causes a universal variable barrier)
darcs-hash:20060212112349-ac50b-51956f701d11ae897c560617e4b476fb51b576c7.gz
2006-02-12 21:23:49 +10:00
axel
7c7f744b4c Add %o, %x and %X formats to *wprintf fallback implemnentation
darcs-hash:20060212112030-ac50b-1e3153c25dca3d2e12a8eb0e65da29bf70fa0d2e.gz
2006-02-12 21:20:30 +10:00
axel
5718ea41df Add comment in manual about array base index
darcs-hash:20060211001546-ac50b-cebbcd5ca6709c8370433abf366c0aa318ec48ec.gz
2006-02-11 10:15:46 +10:00
axel
20c83ba605 Optimize the halloc implementation so that mutiple calls to halloc can be satisfied by a single malloc, also add wcsdup and wcsndup workalikes using halloc
darcs-hash:20060211001317-ac50b-c9cf234c334b4d697fe1251c21013c8ec7f7b0a1.gz
2006-02-11 10:13:17 +10:00
axel
e9e32f980b Re-add check for presense of ncurses.h header file
darcs-hash:20060211001050-ac50b-434f0d6ea015325f75f27aaebbc54d4b81f18a2c.gz
2006-02-11 10:10:50 +10:00
axel
4b2cc49aaa Registered wrong string with halloc in expand_one, causing potential crash.
darcs-hash:20060210003539-ac50b-523cbc848435b7f2b4239cc83da897cc65c00c1c.gz
2006-02-10 10:35:39 +10:00
axel
28f65c07b0 Use consistent quoting in wgetopt
darcs-hash:20060209215120-ac50b-4dda64a6791be33b6493899714485d55372ca8ea.gz
2006-02-10 07:51:20 +10:00
axel
18279c3867 make sure fish_tests is deleted on make clean
darcs-hash:20060209215101-ac50b-48d6e4ffa276e55e0ab896040a7070294061a4ce.gz
2006-02-10 07:51:01 +10:00
axel
d1c9bca2e9 Another halloc:ification of fish. Halloc has been extended to allow registering function calls, this has allowed the creation of halloc-handled arraylists, stringbuffers, etc. More job parsing halloc-ification has reduced the error handling code to only a shadow of it's former self
darcs-hash:20060209155020-ac50b-e119c5293ce2368e252cfc01b98ab7c629fdd678.gz
2006-02-10 01:50:20 +10:00
axel
49973b85da Add source documentation for functions in parse_util.h
darcs-hash:20060208184737-ac50b-e86de902a966621501eea1b706b181bcda91fb61.gz
2006-02-09 04:47:37 +10:00
axel
47373c4f68 Fix bug where recursive function loading crashed fish
darcs-hash:20060208184437-ac50b-c6b2001fbab07ac9561ba7aa941fbab0d93d7cd7.gz
2006-02-09 04:44:37 +10:00
axel
cbf1dbaa2e Add missing fish_tests file to make clean
darcs-hash:20060208180342-ac50b-a4cf2411534c8c1bd3db335152d4615f951529c8.gz
2006-02-09 04:03:42 +10:00
axel
fdaa79416a Make sure dynamically loaded functions are completable, even if they have not yet been loaded
darcs-hash:20060208173718-ac50b-40c93b82f3b8a717d220642e22c4b4005d8871d0.gz
2006-02-09 03:37:18 +10:00
axel
7c3700c190 Fix crash bug caused by trying to free halloc:ed memory
darcs-hash:20060208153904-ac50b-f8b3d2aadb12fa1e6aca0c4ca7a6046a09a0450d.gz
2006-02-09 01:39:04 +10:00
axel
a0e1f9113e Do not use CDPATH when completing arguments starting with a '.'
darcs-hash:20060208152909-ac50b-650092242a4d9454db6cf4d73858c137040db4c5.gz
2006-02-09 01:29:09 +10:00
axel
133b682793 New wreaddir function, wide character version of readdir
darcs-hash:20060208145847-ac50b-0e250edb67dd095e90054ed55f88a2638ba9b02a.gz
2006-02-09 00:58:47 +10:00
axel
824f4ee566 Make the __fish_describe_command function strip spaces and newlines
darcs-hash:20060208102236-ac50b-6df5b077a09eda9180a1405305e12fd15967eb31.gz
2006-02-08 20:22:36 +10:00
axel
1cb9b65744 Fis function signature for a few functions in parser.c
darcs-hash:20060208102203-ac50b-5e81c6580302ca3a1cee0d03f179b5d75ff61be3.gz
2006-02-08 20:22:03 +10:00
axel
35dde5de15 Move more functions to autoload
darcs-hash:20060208102043-ac50b-4e26615523a6b9528c2ea4768f41ad1b2e1c4a0f.gz
2006-02-08 20:20:43 +10:00
Nicholas Pilon
4d9bb19467 cvs completions
Better completions for cvs. Covers most flags in the manual, except for some for history that I couldn't write good descriptions for. Descriptions could probably use some tweaking, but the basic structure should be much better than what we had before.

darcs-hash:20060208023146-494f2-bea009421c161257f09c0f53c52ab1ee116fc3dc.gz
2006-02-08 12:31:46 +10:00
axel
2555353161 Make 'exit' work in even handlers
darcs-hash:20060208092429-ac50b-f88534a423dc194fdb6453d66b5d4cc7733e54fb.gz
2006-02-08 19:24:29 +10:00
axel
73a9c8bcb8 Autoloaded functions
darcs-hash:20060208092005-ac50b-8e784f79a4e158c8c15b553fad85002dccc7bd03.gz
2006-02-08 19:20:05 +10:00
Nicholas Pilon
47b652c76e Awk Indent Fix
Indented the awk script for command description.

darcs-hash:20060208004201-494f2-2f08b1b7999c690bd1815b6c1702529c932b364d.gz
2006-02-08 10:42:01 +10:00
axel
0b044b785a 1.20.2
darcs-hash:20060207115300-ac50b-036d087b1f3493d9ecd7fd1c31d31be5c77c26b6.gz
2006-02-07 21:53:00 +10:00
axel
ddff3561e3 Minor tweaks to expand_Variables, fixes rare memory leak
darcs-hash:20060207114857-ac50b-9b2ecf31106678ec35d888066162bf14605c6003.gz
2006-02-07 21:48:57 +10:00
axel
c4dfdfa849 Fix various uses of old set syntax
darcs-hash:20060206184145-ac50b-5140cacddec9da734d4ef9a38f053259ea1f479a.gz
2006-02-07 04:41:45 +10:00
axel
08251dcc98 Only hide /private directories under OS X
darcs-hash:20060206181717-ac50b-043020858020be5dc55c34240329916696f5892a.gz
2006-02-07 04:17:17 +10:00
axel
57d53c70e3 Further halloc:ification if fish
darcs-hash:20060206181101-ac50b-db0aac307a81e7f0677acd15a9f38ff8c7ff36d2.gz
2006-02-07 04:11:01 +10:00
axel
4e77ee4516 Fix bug that would accidentally disable interactive mode on OS X when writing the titlebar message on some systems. Found by Nick Pilon
darcs-hash:20060206152015-ac50b-63d86ca778c240012bbe1e0d28062591a10f3a54.gz
2006-02-07 01:20:15 +10:00
axel
6291be256b Second checkin of halloc changeover. Make the argv array, but not it's contents, be allocated using halloc. Also make list_to_char_arr use halloc
darcs-hash:20060206151817-ac50b-e8fd4cff831ee975c5bf3855d9ecfc15a3fb9215.gz
2006-02-07 01:18:17 +10:00
axel
e756f7d619 Minor code cleanup, don't use expand_escape and expand_unescape any more
darcs-hash:20060206151552-ac50b-e2229d096926461f643fdcdfc79ef1ff01344a35.gz
2006-02-07 01:15:52 +10:00
axel
cf3d30d4e4 Lazily load history file
darcs-hash:20060206150810-ac50b-f4e5fe9312aa898fa025d2874444c4fc5724c309.gz
2006-02-07 01:08:10 +10:00
axel
585191310b First checkin of transition to using a new hierarchical memory allocator, some of the memory associated with a job is covered
darcs-hash:20060206142502-ac50b-ba1c9a4f64ea0f44f65303a125f9ddae5bd31e2f.gz
2006-02-07 00:25:02 +10:00
axel
530bbfc9ac Make sure line counting doesn't move past end of string
darcs-hash:20060206134757-ac50b-2e80cf3ec104f7b40babef5260fb1d5435dbc74d.gz
2006-02-06 23:47:57 +10:00
axel
a521fa4165 Make execution of functions use wcsdup to make sure no memory errors happen if a function removes itself
darcs-hash:20060206134701-ac50b-27be7fe76512d6ac4313eea79b45a9c11083bccd.gz
2006-02-06 23:47:01 +10:00
axel
0f76f77173 Make sure interactive mode is of when firing events
darcs-hash:20060206134532-ac50b-93f8a7cf7be2a82a1222fb520541b08bef33baa4.gz
2006-02-06 23:45:32 +10:00
axel
c743ebf211 Add long style option support for prevd/pushd, also add a few missing translation strings
darcs-hash:20060206112453-ac50b-271b830b35176d1ff93d9d9fb6c30343b4f1b4df.gz
2006-02-06 21:24:53 +10:00
Nicholas Pilon
04ce9ecf16 Darwin Open
Tweak the open function to use /usr/bin/open on Darwin, and mimedb on everything else.

darcs-hash:20060206012623-494f2-e4626c03895065837f0c8981482d5b16313dfc08.gz
2006-02-06 11:26:23 +10:00
Nicholas Pilon
bde5921258 Describe Command awk-ification
Changed __fish_describe_command to use awk instead of sed, and handle 'alternative' names, as used by OS X. (And possibly some BSDs?)

darcs-hash:20060205221805-494f2-85a48edd8e6fbcfc1dcd28079e4adfa52a0466d0.gz
2006-02-06 08:18:05 +10:00
Nicholas Pilon
89ae02976f Completion: System Commands
Tiny tweak to sed expression to get descriptions for system commands too.

darcs-hash:20060205194830-494f2-1f1df9c2d4d1d2302e34df113c4919078388aa1a.gz
2006-02-06 05:48:30 +10:00
Nicholas Pilon
d8382acc74 PWD Tweaks
Tweaked prompt_pwd and pwd to omit the leading /private from some system directories on OS X.

darcs-hash:20060205194908-494f2-936d1346a4cd118f763bea24495edf9829b59748.gz
2006-02-06 05:49:08 +10:00
axel
749c44fe27 Minor edits of builtin.c, some reindentation and code comment improvement
darcs-hash:20060205212050-ac50b-70c1b34208b442b5670fde2c6655e09c4480c7e7.gz
2006-02-06 07:20:50 +10:00
axel
88ec924323 Another set of spelling corrections from HJB
darcs-hash:20060205211835-ac50b-d08f069c3307ec7785b038f157c919416c6bb8b7.gz
2006-02-06 07:18:35 +10:00
axel
7ff069a2e1 Make LS_COLORS non-univerasl, and contain many more filetypes
darcs-hash:20060205131422-ac50b-521f4764e463acab1fc0414f58e73af55bd62c5c.gz
2006-02-05 23:14:22 +10:00
axel
8e05c8bee8 Tiny performance tweaks
darcs-hash:20060205131335-ac50b-5b1895d50334dfe9e375ab60e723d1b62b712707.gz
2006-02-05 23:13:35 +10:00
axel
0fa3c15114 Tweaks to some source comments
darcs-hash:20060205131253-ac50b-c3ad91b280a73fc8ec318ca6c285de773ffecfc6.gz
2006-02-05 23:12:53 +10:00
axel
58667673d9 Remove duplicate line counting code. Make the remaining implementation have a two element cache.
darcs-hash:20060205131035-ac50b-885c6ba87a6d16aa48dfa7ee4608ae8891c71724.gz
2006-02-05 23:10:35 +10:00
axel
a53a9aa293 Clean up init code in builtin.c
darcs-hash:20060205130840-ac50b-1a2b29671b7d8c557ebd284513c535e082ee5cf3.gz
2006-02-05 23:08:40 +10:00
axel
09402223e8 Minor edits to the INSTALL file
darcs-hash:20060204131412-ac50b-3713bdae731b4853e598930c9823b950d3039a72.gz
2006-02-04 23:14:12 +10:00
axel
4f947015d2 Minor tweaks, including a few small performance improvements
darcs-hash:20060204130914-ac50b-331e83fd8fe472545fce60fc4b76bb8300526d64.gz
2006-02-04 23:09:14 +10:00
axel
9f3a7543aa Remove some unneeded debug messages
darcs-hash:20060204115812-ac50b-b756b9d1257be714fae52f713a48a360903437dd.gz
2006-02-04 21:58:12 +10:00
axel
7ae6805698 Minor optimization - only set locale if we actually want to output something in set_color
darcs-hash:20060204114256-ac50b-5ec72de2f15d359b8edb330ae6c5f05c4c54e4b5.gz
2006-02-04 21:42:56 +10:00
axel
1401c44a79 Don't print full stack trace for failiures in cd in interactive mode
darcs-hash:20060204113650-ac50b-465dd4b3fb27e8d90127231cccdae29ac7b8fd20.gz
2006-02-04 21:36:50 +10:00
axel
40ea5987b2 Add /opt and /opt/local to list of possibly interesting directories for PATH and library path
darcs-hash:20060204113619-ac50b-97b1e6b3c2cf32fa12bf42486f9249319f4a531b.gz
2006-02-04 21:36:19 +10:00
axel
6920f039eb Minor optimization to the prompt command
darcs-hash:20060204113512-ac50b-4604692cac17972b379a7f40599a30e0bbfc3f89.gz
2006-02-04 21:35:12 +10:00
axel
ff00354305 Make sure completions aren't run in interactive mode
darcs-hash:20060204113433-ac50b-454170ab12fbbcec9cfb6615910b611c680fcc3d.gz
2006-02-04 21:34:33 +10:00
axel
f9c63a142b Don't print errors if parent can't give child control of terminal during exec(), since child may have already exited
darcs-hash:20060204113320-ac50b-385b600789e7d1aee2a15a69658e9e0b4af838d0.gz
2006-02-04 21:33:20 +10:00
axel
3733fe3997 Make children set their own process group instead of waiting for their parent to do it for them
darcs-hash:20060203215031-ac50b-d00ce5c09b469edd968618a4bba4b5c1f7dc075c.gz
2006-02-04 07:50:31 +10:00
axel
7e3128f097 Minor comment edits in complete.c
darcs-hash:20060203213006-ac50b-86ccb93b4c984ab0d29423b8a63269bd1e161410.gz
2006-02-04 07:30:06 +10:00
axel
727472d5bd Correct broken test for gettext command
darcs-hash:20060203212939-ac50b-8a99c32124c6b643443bc7295df91d6f0c903247.gz
2006-02-04 07:29:39 +10:00
axel
3616a23bdd Add fink and pkgsrc /bin directories to PATH if they exist
darcs-hash:20060203212901-ac50b-94e02eea218c2f40542efd62060a74796cdbe363.gz
2006-02-04 07:29:01 +10:00
axel
f13262d87e Move parts of the command description lookup code to a shellscript function
darcs-hash:20060203172736-ac50b-95430eb4ca0d7ee2859237e8543a4e0883349fdb.gz
2006-02-04 03:27:36 +10:00
axel
f71cd494de prompt and terminal functions should not be run in interactive mode
darcs-hash:20060203093426-ac50b-5e6bf8382c6a5fb4b409439eddf612fffa9c752e.gz
2006-02-03 19:34:26 +10:00
axel
264c065006 Remove old unneeded code that makes fish_pager wait to become owner of the terminal
darcs-hash:20060203093314-ac50b-537c521093e85a110f822cde37b022d7706e8cb0.gz
2006-02-03 19:33:14 +10:00
axel
07c89c71d8 Fix broken test for realpath taking null as a second argument
darcs-hash:20060203004145-ac50b-5357d5f203fa66d5aaef9059e3f03866d2e7f67d.gz
2006-02-03 10:41:45 +10:00
axel
19c67db731 Make hostname completion code more robust
darcs-hash:20060203004114-ac50b-54fda8fe89649d404cd6981d7783e18f5092f217.gz
2006-02-03 10:41:14 +10:00
axel
294da72d11 Make string conversion in wutil.c handle special 'broken encoding' sequences
darcs-hash:20060203004028-ac50b-01fbe7b22aece08a7a4d1afe84affd80ce944d40.gz
2006-02-03 10:40:28 +10:00
axel
847b6daa34 Minor fix for completions for status builtin
darcs-hash:20060203003935-ac50b-fd3e5b642cdca5631f36942309b017ebbaa63cb2.gz
2006-02-03 10:39:35 +10:00
axel
807a0b8dbd Improved error checking in main()
darcs-hash:20060203003855-ac50b-d4f5c4e183dc1b38bbfe15bf44be746bb188ef10.gz
2006-02-03 10:38:55 +10:00
axel
c3a1473419 Add fish switch to enter login mode
darcs-hash:20060203003754-ac50b-99961eb6635beb0700fbd542fc7ff979ab1ceeb9.gz
2006-02-03 10:37:54 +10:00
axel
29707e66e6 Update INSTALL file to be less redundant and contain a bit of information about compilers
darcs-hash:20060202153401-ac50b-502136b1a0e1c5117a34cc1e105a718d6ea8884b.gz
2006-02-03 01:34:01 +10:00
axel
a97b652046 Minor source documentation edits
darcs-hash:20060202153330-ac50b-63ad1ac0f20b94f6015e472b52ac32040a942280.gz
2006-02-03 01:33:30 +10:00
axel
91b46b305d Make error message in contains function translatable
darcs-hash:20060202153304-ac50b-69fc557308b7ae7eb3a3d8d658e6f7c871aa68cd.gz
2006-02-03 01:33:04 +10:00
axel
fbe66f54aa Make completion of subsommands for time and sudo a bit better at differing between command and subcommand
darcs-hash:20060202153151-ac50b-d943052af165dc345366b49a5db413f635a2f28a.gz
2006-02-03 01:31:51 +10:00
axel
ff03fe7e41 Make autoconf detection for have__nl_msg_cat_cntr slightly more robust
darcs-hash:20060202152939-ac50b-9b38585f8c1d1855d08cc7fd1a75e51ff54a9b0e.gz
2006-02-03 01:29:39 +10:00
axel
06fd1aa9f8 Make stack traces print absolute filenames
darcs-hash:20060202152356-ac50b-9e6ab31c03d5f49824ccca7eee3b8e62d66b0009.gz
2006-02-03 01:23:56 +10:00
axel
5942a6d6c1 Don't reset history on cursor movement
darcs-hash:20060201155546-ac50b-975730e850775a9f47e15a65c9c5959a335edc93.gz
2006-02-02 01:55:46 +10:00
axel
a781736fb7 Swedish translation checkin
darcs-hash:20060201155516-ac50b-aeeebdc296c8684325a97edf92ad360f7675a981.gz
2006-02-02 01:55:16 +10:00
axel
feabc032f6 Generalize the stack tracing code, add support for showing events and command substitutions in stack traces
darcs-hash:20060201154911-ac50b-707358ea50231661c05a92b40ca109ec801081e6.gz
2006-02-02 01:49:11 +10:00
axel
9f9f7bf95a Minor edits to fish documentation
darcs-hash:20060201134029-ac50b-c80a9dadb4960dfbba255ca046682f2798621cf2.gz
2006-02-01 23:40:29 +10:00
axel
02f638ad2b Minor spelling fixes from Hermann J. Beckers
darcs-hash:20060201122912-ac50b-88d59b8c0e94e8a2db5b1a6f94b4fa7f25c7859e.gz
2006-02-01 22:29:12 +10:00
axel
e95effb043 Readd the terminal flag for jobs, as not all jobs under job control should be given the terminal.
darcs-hash:20060201122715-ac50b-7efc499e8905e9898c214816d0a3468e077c7005.gz
2006-02-01 22:27:15 +10:00
axel
7a1a5a6f01 Swedish translation checkin
darcs-hash:20060131220043-ac50b-f4885e4fb81bea7b84b0ea85669f813f751b9903.gz
2006-02-01 08:00:43 +10:00
axel
bfefe7f262 Add completions for the status builtin
darcs-hash:20060131215933-ac50b-330b6cb15406ee62006d0dcd3b9ae4cf70ee1e68.gz
2006-02-01 07:59:33 +10:00
axel
44e8dcd331 Add not on commandline behaviour when using complete -C to documentation
darcs-hash:20060131214646-ac50b-dc7b1510ceefc7645061d91bbe5022c09c209a34.gz
2006-02-01 07:46:46 +10:00
axel
3580811f8e Minor documentation correction regarding how to use io redirection to close a fd
darcs-hash:20060131214551-ac50b-0b687b3279d3a9c94338092bff1b0a8001e9566d.gz
2006-02-01 07:45:51 +10:00
axel
35cf20640f Add mention of the new -C switch for complete in the documentation
darcs-hash:20060131214426-ac50b-16a1b18cf8f5c05e59e1b338dde1c13089321bac.gz
2006-02-01 07:44:26 +10:00
axel
eff36003db Remove fallback version of the _nl_msg_cat_cntr symbol. We check for it at configure-time and only use it if it exists
darcs-hash:20060131214303-ac50b-c13a7addd8f35e0adce72213f5aa6dc2a35b7a73.gz
2006-02-01 07:43:03 +10:00
axel
0eab394c24 Fix for how fish parses the double quote character
darcs-hash:20060131214201-ac50b-d921c2c74fa40723ae064a90d445258aa41ec94f.gz
2006-02-01 07:42:01 +10:00
axel
028e1f36a1 Improve the status builtin
darcs-hash:20060130195310-ac50b-5da6881a847170242be56555646bbf037218d545.gz
2006-01-31 05:53:10 +10:00
axel
f59e9baab9 Rename the 'terminal' flag to 'job_control', make sure fg and bg only considers jobs under job control and make it configurable which jobs are put under job control using the status builtin. Also add an option to the status builtin to print a stack trace.
darcs-hash:20060130175426-ac50b-46fb79797284cb600c67cb19462b53761446f00a.gz
2006-01-31 03:54:26 +10:00
axel
1c6f685522 Minor code tweaks
darcs-hash:20060130165800-ac50b-8fa4a7ff78365497c5d03d6c7643d5206f41de37.gz
2006-01-31 02:58:00 +10:00
axel
c8a36c9889 Autoconf tweaks to make library detection more robust
darcs-hash:20060130165706-ac50b-e7685a85f07811815fb01ac3b79609ea7f0a7786.gz
2006-01-31 02:57:06 +10:00
axel
521d09b6d0 Add support for calculating completions for arbitrary commands through the 'complete' builtin
darcs-hash:20060130165150-ac50b-5e2ef3bb0298dd5e1a5d6fbdade314cc73ef36f3.gz
2006-01-31 02:51:50 +10:00
axel
3efb0bf5cf Fix bug that caused shellscript functions in pipelines that don't have any output to never be properly removed
darcs-hash:20060129220414-ac50b-8c26e83933a73ef146c28bed020a6a2dfeca425f.gz
2006-01-30 08:04:14 +10:00
axel
003c4d776f Display use of . (source) builtin in stack traces
darcs-hash:20060128113440-ac50b-6556097eb766cc7561a3d30ef994bc913181fe65.gz
2006-01-28 21:34:40 +10:00
axel
00dea8a082 Optimize the fish_prompt function
darcs-hash:20060128102551-ac50b-58580c29fd9537e502bacaad7949433010b5a04b.gz
2006-01-28 20:25:51 +10:00
axel
7f195b2f23 Swedish translation checkin (small)
darcs-hash:20060128022149-ac50b-e4089e5517b80ea05aa2d1e2597fc83fc346feb4.gz
2006-01-28 12:21:49 +10:00
axel
ecc2fbca98 Minor documentation tweaks
darcs-hash:20060128022118-ac50b-555ebb17d4f43692a5f363a085dcbcf57aa69111.gz
2006-01-28 12:21:18 +10:00
axel
631acd529d Fix typo in sudo completions
darcs-hash:20060128022054-ac50b-8d859c4481c34c5830e9b5fa9e436e165160547e.gz
2006-01-28 12:20:54 +10:00
axel
369f1709be Misc init-files cleanup, including making sure various variables are function-local
darcs-hash:20060128022022-ac50b-3a9fabe385f53559dd9e0bb5d8f9994d833ced1d.gz
2006-01-28 12:20:22 +10:00
axel
1505cc3d81 Add comment in documentation for set builtin about not allowing switches after non-switches
darcs-hash:20060128021933-ac50b-db340075e9a57b41a91d6b64d56d9b5579185254.gz
2006-01-28 12:19:33 +10:00
axel
78ae6d3bea Check for gettext in seq fallback implementation
darcs-hash:20060128021846-ac50b-7c11eea694e5c3b87e00508fbeaedc9dcd163726.gz
2006-01-28 12:18:46 +10:00
axel
ea81321ccb Add translation support to wgetopt library
darcs-hash:20060128021740-ac50b-f670531d3d79cb8070756669f83f4e8b25233a0a.gz
2006-01-28 12:17:40 +10:00
axel
1977d3beb3 Add support for correctly handling illegal character strings
darcs-hash:20060128020329-ac50b-d3499e6ff9108cef25bf7e00f39bbe1476896e07.gz
2006-01-28 12:03:29 +10:00
axel
285984196d More spelling fixes from Hermann J. Beckers
darcs-hash:20060128003459-ac50b-af346d3abc52bf1bb4de43cbbaa3d87b3b7264eb.gz
2006-01-28 10:34:59 +10:00
axel
5f8e6c85e4 Small fixes for emerge completions, sent by Mike Auty
darcs-hash:20060127082639-ac50b-881d00da4712a2d149618c07356c8d711bf55ac9.gz
2006-01-27 18:26:39 +10:00
axel
e01ccb14af shellscript functions should use the help command to display help
darcs-hash:20060126173437-ac50b-69c03761554180467f741a9597205fab6c823378.gz
2006-01-27 03:34:37 +10:00
axel
86b7ae6d21 1.20.1
darcs-hash:20060126163046-ac50b-483c77663467060a13015bcee755f708a86157e9.gz
2006-01-27 02:30:46 +10:00
287 changed files with 21966 additions and 9835 deletions

31
INSTALL
View File

@@ -2,39 +2,38 @@
Known issues
============
Older versions of Doxygen has bugs in the man-page generation which
cause the builtin help to render incorrectly. Version 1.2.14 is known
to have this problem.
Fish currently requires a semi-modern GCC version to
compile. Specifically, GCC 2.95.* won't compile fish, but GCC 3.23
should work. Fish has not been coded with an C99- or GNU-specific
features in mind, so it is hoped that it should be possible to make
fish work with other compilers. Patches are welcome.
In version 1.9.2, the installation prefix for fish rpms and debs has
changed from /usr/local to /usr. The package should automatically
change any instances of /usr/local/bin/fish in /etc/passwd to
/usr/bin/fish, but some programs, like screen, may need to be
restarted to notice the changes. You may also run into problems when
switching between using a package and personal builds.
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 packages to build:
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 and echo. Fish does not support cross-compilation, separate
build directories or any other fancy configure options. Use a recent
version of Doxygen, since older versions have bugs that make the
builtin help pages render incorrectly. Version 1.2.14 is known to be
broken.
whoami, bc and echo. Fish does not yet support cross-compilation,
separate build directories or any other fancy configure options.
Simple install procedure
========================
If you have downloaded the darcs repository of fish, you need to run
autoconf.
the autoconf command first. Then use the following commands to compile
fish:
% ./configure
% make # Compile fish

View File

@@ -16,6 +16,10 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# @configure_input@
#
#
# Makefile for the fish shell. Can build fish and associated
# applications, install them, recalculate dependencies and also create
@@ -33,9 +37,9 @@ CC := @CC@
INSTALL:=@INSTALL@
# Compiler flags
CFLAGS := @CFLAGS@ @INCLUDEDIR@ -Wall -std=gnu99 -fno-strict-aliasing
CFLAGS:=@CFLAGS@ -Wall -std=gnu99 -fno-strict-aliasing
CPPFLAGS=@CPPFLAGS@
LDFLAGS:= -l@CURSESLIB@ @LIBS@ @LDFLAGS@ @LIBDIR@
LDFLAGS:= @LIBS@ @LDFLAGS@
# Installation directories
prefix = @prefix@
@@ -44,24 +48,25 @@ datadir = @datadir@
bindir = @bindir@
mandir = @mandir@
sysconfdir = @sysconfdir@
fishdir = @fishdir@
fishfile = @fishfile@
fishinputfile = @fishinputfile@
docdir = @docdir@
#Init files to install
INIT_DIR_INSTALL = init/fish_interactive.fish init/fish_function.fish init/fish_complete.fish
#etc files to install
ETC_DIR_INSTALL = etc/fish_interactive.fish
# Set to 1 if we have gettext
HAVE_GETTEXT=@HAVE_GETTEXT@
CORE_OBJS := util.o common.o halloc.o halloc_util.o
# All objects used by fish, that are compiled from an ordinary .c file
# using an ordinary .h file.
COMMON_OBJS := function.o builtin.o common.o complete.o env.o exec.o \
COMMON_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 util.o wildcard.o wgetopt.o wutil.o input.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 translate.o
input_common.o event.o signal.o io.o translate.o parse_util.o \
$(CORE_OBJS)
# builtin_help.h exists, but builtin_help.c is autogenerated
COMMON_OBJS_WITH_HEADER := builtin_help.o
@@ -75,20 +80,20 @@ FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
$(COMMON_OBJS_WITH_HEADER) main.o
# All objects that the system needs to build fish_pager
FISH_PAGER_OBJS := fish_pager.o common.o output.o util.o wutil.o \
FISH_PAGER_OBJS := fish_pager.o output.o wutil.o \
tokenizer.o input_common.o env_universal.o env_universal_common.o \
translate.o
translate.o $(CORE_OBJS)
# All objects that the system needs to build fish_tests
FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
$(COMMON_OBJS_WITH_HEADER) fish_tests.o
# All objects that the system needs to build fishd
FISHD_OBJS := fishd.o env_universal_common.o common.o util.o wutil.o \
doc_src/fishd.o
FISHD_OBJS := fishd.o env_universal_common.o wutil.o \
doc_src/fishd.o $(CORE_OBJS)
# All objects needed to build mimedb
MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o
#
@@ -119,12 +124,13 @@ BUILTIN_DOC_HDR := $(BUILTIN_DOC_SRC:.txt=.doxygen)
# alphabetically, since this is the order in which they will be written
# in the help file.
#
CMD_DOC_SRC := doc_src/count.txt doc_src/dirh.txt doc_src/dirs.txt \
doc_src/fish_pager.txt doc_src/fishd.txt doc_src/help.txt \
doc_src/mimedb.txt doc_src/nextd.txt doc_src/open.txt \
doc_src/popd.txt doc_src/prevd.txt doc_src/psub.txt \
doc_src/pushd.txt doc_src/set_color.txt doc_src/trap.txt \
doc_src/type.txt doc_src/umask.txt doc_src/vared.txt
CMD_DOC_SRC := doc_src/contains.txt doc_src/count.txt doc_src/dirh.txt \
doc_src/dirs.txt doc_src/fish_pager.txt doc_src/fishd.txt \
doc_src/help.txt doc_src/mimedb.txt doc_src/nextd.txt \
doc_src/open.txt doc_src/popd.txt doc_src/prevd.txt \
doc_src/psub.txt doc_src/pushd.txt doc_src/set_color.txt \
doc_src/trap.txt doc_src/type.txt doc_src/umask.txt \
doc_src/vared.txt
#
# Files generated by running doxygen on the files in $(CMD_DOC_SRC)
@@ -154,16 +160,20 @@ MAIN_DIR_FILES := Doxyfile Doxyfile.user Makefile.in configure \
user_doc.head.html xsel-0.9.6.tar ChangeLog config.sub \
config.guess fish_tests.c main.c fish_pager.c fishd.c seq.in
# Files in ./init/
INIT_DIR_FILES :=init/fish.in init/fish_complete.fish.in \
init/fish_function.fish init/fish_inputrc \
init/fish_interactive.fish.in
# Files in ./etc/
ETC_DIR_FILES :=etc/fish.in etc/fish_inputrc \
etc/fish_interactive.fish.in
# Files in ./share/
SHARE_DIR_FILES :=share/fish
# Files in ./tests/
TESTS_DIR_FILES := $(TEST_IN) $(TEST_IN:.in=.out) $(TEST_IN:.in=.err) \
$(TEST_IN:.in=.status) tests/test.fish tests/gen_output.fish
COMPLETIONS_DIR_FILES := $(wildcard init/completions/*.fish)
COMPLETIONS_DIR_FILES := $(wildcard share/completions/*.fish)
FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish)
# Programs to build
PROGRAMS:=fish set_color @XSEL@ @SEQ_FALLBACK@ mimedb count fish_pager fishd
@@ -187,7 +197,7 @@ all: $(PROGRAMS) user_doc
.PHONY: all
debug:
make fish CFLAGS="-O0 -Wno-unused -Werror -g @INCLUDEDIR@ -Wall -std=gnu99 -fno-strict-aliasing"
make fish CFLAGS="-O0 -Wno-unused -Werror -g -Wall -std=gnu99 -fno-strict-aliasing"
.PHONY: debug
# User documentation, describing the features of the fish shell.
@@ -256,10 +266,10 @@ doc.h:$(BUILTIN_DOC_SRC) $(CMD_DOC_SRC) doc_src/doc.hdr
fi
# Create a template translation object
messages.pot: *.c *.h init/*.in init/*.fish init/completions/*.fish seq
messages.pot: *.c *.h etc/*.in share/fish share/completions/*.fish share/functions/*.fish seq
if test $(HAVE_GETTEXT) = 1;then \
xgettext -k_ -kN_ -kcomplete_desc *.c *.h -o messages.pot; \
if ! xgettext -j -k_ -LShell init/*.in init/*.fish init/completions/*.fish seq -o messages.pot; then \
if ! xgettext -j -k_ -LShell etc/*.in share/fish share/completions/*.fish share/functions/*.fish seq -o messages.pot; then \
echo "Your xgettext version is too old to build the messages.pot file"\
rm messages.pot\
false;\
@@ -330,24 +340,54 @@ builtin_help.c: $(BUILTIN_DOC_HDR) doc_src/count.doxygen gen_hdr2 gen_hdr.sh bui
#man -- doc_src/builtin_doc/man/man1/`basename $@ .c`.1 | cat -s | ./gen_hdr2 >>$@
#
# The build rules for installing/uninstalling
# The build rules for installing/uninstalling fish
#
install: all install-translations
# Check for an incompatible installed fish version, and fail with an
# error if found
check-uninstall:
if test -f $(DESTDIR)$(sysconfdir)/fish.d/fish_function.fish -o -f $(DESTDIR)$(sysconfdir)/fish.d/fish_complete.fish; then \
echo;\
echo ERROR;\
echo;\
echo An older fish installation using an incompatible filesystem hierarchy was detected;\
echo You must uninstall this fish version before installing proceeding;\
echo type \'make uninstall-legacy\' to uninstall these files,;\
echo or type \'make force-install\' to force installation.;\
echo The latter may result in a broken installation.;\
echo;\
false;\
fi;
.PHONY: check-uninstall
# Try to install after checking for incompatible installed versions
install: all check-uninstall install-force
.PHONY: install
# Force installation, even in presense of incompatible previous
# version
install-force: all install-translations
$(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
for i in $(PROGRAMS); do\
$(INSTALL) -m 755 $$i $(DESTDIR)$(bindir) ; \
done;
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)$(fishdir)
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)$(fishdir)/completions
$(INSTALL) -m 644 init/fish $(DESTDIR)$(sysconfdir)$(fishfile)
for i in $(INIT_DIR_INSTALL); do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)$(fishdir); \
$(INSTALL) -m 755 -d $(DESTDIR)$(sysconfdir)/fish.d
$(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 644 etc/fish $(DESTDIR)$(sysconfdir)/fish
$(INSTALL) -m 644 share/fish $(DESTDIR)$(datadir)/fish
for i in $(ETC_DIR_INSTALL); do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)/fish.d; \
done;
for i in $(COMPLETIONS_DIR_FILES); do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(sysconfdir)$(fishdir)/completions/; \
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/completions/; \
done;
$(INSTALL) -m 644 init/fish_inputrc $(DESTDIR)$(sysconfdir)$(fishinputfile);
for i in $(FUNCTIONS_DIR_FILES); do \
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/fish/functions/; \
done;
$(INSTALL) -m 644 etc/fish_inputrc $(DESTDIR)$(sysconfdir)/fish_inputrc;
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
for i in user_doc/html/* ChangeLog; do \
if test -f $$i; then \
@@ -366,22 +406,48 @@ install: all install-translations
@echo \* use the command \'chsh -s $(DESTDIR)$(bindir)/fish\'.
@echo
@echo Have fun!
.PHONY: install
.PHONY: force-install
# Uninstall this fish version
uninstall: uninstall-translations
for i in $(PROGRAMS); do \
rm -f $(DESTDIR)$(bindir)/$$i; \
done;
rm -f $(DESTDIR)$(bindir)/xsel
rm -f $(DESTDIR)$(sysconfdir)$(fishfile)
rm -f $(DESTDIR)$(sysconfdir)$(fishinputfile)
rm -r $(DESTDIR)$(sysconfdir)$(fishdir)
rm -r $(DESTDIR)$(docdir)
for i in fish.1* @XSEL_MAN@ mimedb.1* fishd.1* set_color.1* count.1*; do \
rm $(DESTDIR)$(mandir)/man1/$$i; \
rm -f $(DESTDIR)$(sysconfdir)/fish
rm -f $(DESTDIR)$(sysconfdir)/fish_inputrc
if test -d $(DESTDIR)$(datadir)/fish; then \
rm -r $(DESTDIR)$(datadir)/fish; \
fi
if test -d $(DESTDIR)$(docdir); then \
rm -r $(DESTDIR)$(docdir);\
fi
for i in fish.1 @XSEL_MAN@ mimedb.1 fishd.1 set_color.1 count.1; do \
rm -f $(DESTDIR)$(mandir)/man1/$$i*; \
done;
.PHONY: uninstall
# Uninstall older fish release. This is not the default uninstall
# since there is a slight chance that it removes a file put in place by
# the sysadmin.
uninstall-legacy: uninstall
rm -f $(DESTDIR)$(sysconfdir)/fish.d/fish_interactive.fish
rm -f $(DESTDIR)$(sysconfdir)/fish.d/fish_complete.fish
rm -f $(DESTDIR)$(sysconfdir)/fish.d/fish_function.fish
if test -d $(DESTDIR)$(sysconfdir)/fish.d/completions; then \
for i in $(COMPLETIONS_DIR_FILES); do \
basename=`basename $$i`; \
if test -f $(DESTDIR)$(sysconfdir)/fish.d/completions/$$basename; then \
rm $(DESTDIR)$(sysconfdir)/fish.d/completions/$$basename; \
fi; \
done; \
fi;
rmdir $(DESTDIR)$(sysconfdir)/fish.d/completions; true
rmdir $(DESTDIR)$(sysconfdir)/fish.d; true
install-translations: $(TRANSLATIONS)
if test $(HAVE_GETTEXT) = 1; then \
for i in $(TRANSLATIONS); do \
@@ -389,13 +455,13 @@ install-translations: $(TRANSLATIONS)
$(INSTALL) -m 644 $$i $(DESTDIR)$(datadir)/locale/`basename $$i .gmo`/LC_MESSAGES/fish.mo; \
echo $(DESTDIR)$(datadir)/locale/`basename $$i .gmo`/LC_MESSAGES/fish.mo;\
done; \
fi
fi;
.PHONY: install-translations
uninstall-translations:
if test $(HAVE_GETTEXT) = 1; then \
for i in $(TRANSLATIONS_SRC); do \
rm -f $(DESTDIR)$(datadir)/locale/`basename $$i .po`/LC_MESSAGES/fish.mo; \
rm -f $(DESTDIR)$(datadir)/locale/*/LC_MESSAGES/fish.mo; \
done; \
fi
.PHONY: uninstall-translations
@@ -444,18 +510,22 @@ depend:
#
# Uses install instead of mkdir so build won't fail if the directory
# exists
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(INIT_DIR_FILES) $(TEST_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog
fish-@PACKAGE_VERSION@.tar: $(DOC_SRC_DIR_FILES) $(MAIN_DIR_FILES) $(ETC_DIR_FILES) $(TEST_DIR_FILES) $(SHARE_DIR_FILES) $(FUNCTIONS_DIR_FILES) $(COMPLETIONS_DIR_FILES) ChangeLog
rm -rf fish-@PACKAGE_VERSION@
$(INSTALL) -d fish-@PACKAGE_VERSION@
$(INSTALL) -d fish-@PACKAGE_VERSION@/doc_src
$(INSTALL) -d fish-@PACKAGE_VERSION@/init
$(INSTALL) -d fish-@PACKAGE_VERSION@/init/completions
$(INSTALL) -d fish-@PACKAGE_VERSION@/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@/tests
$(INSTALL) -d fish-@PACKAGE_VERSION@/po
cp -f $(DOC_SRC_DIR_FILES) fish-@PACKAGE_VERSION@/doc_src
cp -f $(MAIN_DIR_FILES) fish-@PACKAGE_VERSION@/
cp -f $(INIT_DIR_FILES) fish-@PACKAGE_VERSION@/init/
cp -f $(COMPLETIONS_DIR_FILES) fish-@PACKAGE_VERSION@/init/completions/
cp -f $(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/
tar -c fish-@PACKAGE_VERSION@ >fish-@PACKAGE_VERSION@.tar
@@ -483,7 +553,7 @@ rpm: fish-@PACKAGE_VERSION@.tar.bz2
distclean: clean
rm -f fish.spec doc_src/fish.1 doc_src/Doxyfile
rm -f init/fish init/fish_interactive.fish init/fish_complete.fish
rm -f etc/fish etc/fish_interactive.fish share/fish
rm -f config.status config.log config.h Makefile
.PHONY: distclean
@@ -506,83 +576,101 @@ clean:
# DO NOT DELETE THIS LINE -- make depend depends on it.
builtin.o: config.h util.h wutil.h builtin.h function.h complete.h proc.h
builtin.o: io.h parser.h reader.h env.h expand.h common.h wgetopt.h sanity.h
builtin.o: io.h parser.h event.h reader.h env.h common.h wgetopt.h sanity.h
builtin.o: tokenizer.h builtin_help.h wildcard.h input_common.h input.h
builtin.o: intern.h event.h signal.h translate.h
builtin_commandline.o: signal.h config.h util.h builtin.h common.h wgetopt.h
builtin_commandline.o: reader.h proc.h io.h parser.h tokenizer.h
builtin_commandline.o: input_common.h input.h translate.h
builtin.o: intern.h signal.h translate.h halloc.h halloc_util.h parse_util.h
builtin.o: expand.h
builtin_commandline.o: signal.h config.h util.h wutil.h builtin.h common.h
builtin_commandline.o: wgetopt.h reader.h proc.h io.h parser.h event.h
builtin_commandline.o: tokenizer.h input_common.h input.h translate.h
builtin_commandline.o: parse_util.h
builtin_complete.o: signal.h config.h util.h wutil.h builtin.h common.h
builtin_complete.o: complete.h wgetopt.h parser.h proc.h io.h event.h
builtin_complete.o: reader.h translate.h
builtin_help.o: config.h util.h common.h builtin_help.h
builtin_set.o: signal.h config.h util.h builtin.h env.h expand.h common.h
builtin_set.o: wgetopt.h proc.h io.h parser.h translate.h
builtin_set.o: signal.h config.h util.h wutil.h builtin.h env.h expand.h
builtin_set.o: common.h wgetopt.h proc.h io.h parser.h event.h translate.h
builtin_ulimit.o: config.h util.h builtin.h common.h wgetopt.h translate.h
common.o: config.h signal.h util.h wutil.h common.h expand.h proc.h io.h
common.o: wildcard.h parser.h
common.o: config.h util.h wutil.h common.h expand.h proc.h io.h wildcard.h
common.o: parser.h event.h
complete.o: signal.h config.h util.h tokenizer.h wildcard.h proc.h io.h
complete.o: parser.h function.h complete.h builtin.h env.h exec.h expand.h
complete.o: common.h reader.h history.h intern.h translate.h wutil.h
complete.o: parser.h event.h function.h complete.h builtin.h env.h exec.h
complete.o: expand.h common.h reader.h history.h intern.h translate.h
complete.o: parse_util.h halloc_util.h wutil.h
env.o: config.h signal.h util.h wutil.h proc.h io.h common.h env.h sanity.h
env.o: expand.h history.h reader.h parser.h env_universal.h
env.o: env_universal_common.h input_common.h event.h translate.h
env.o: expand.h history.h reader.h parser.h event.h env_universal.h
env.o: env_universal_common.h input_common.h translate.h complete.h
env_universal.o: config.h signal.h util.h common.h wutil.h
env_universal.o: env_universal_common.h env_universal.h
env_universal_common.o: signal.h util.h common.h wutil.h
env_universal_common.o: config.h signal.h util.h common.h wutil.h
env_universal_common.o: env_universal_common.h
event.o: signal.h config.h util.h function.h proc.h io.h parser.h common.h
event.o: event.h translate.h
event.o: signal.h config.h util.h wutil.h function.h proc.h io.h parser.h
event.o: event.h common.h translate.h halloc_util.h
exec.o: signal.h config.h util.h common.h wutil.h proc.h io.h exec.h parser.h
exec.o: builtin.h function.h env.h wildcard.h sanity.h expand.h
exec.o: env_universal.h env_universal_common.h translate.h
exec.o: event.h builtin.h function.h env.h wildcard.h sanity.h expand.h
exec.o: env_universal.h env_universal_common.h translate.h halloc.h
exec.o: halloc_util.h parse_util.h
expand.o: signal.h config.h util.h common.h wutil.h env.h proc.h io.h
expand.o: parser.h expand.h wildcard.h exec.h tokenizer.h complete.h
fishd.o: signal.h util.h common.h wutil.h env_universal_common.h
expand.o: parser.h event.h expand.h wildcard.h exec.h tokenizer.h complete.h
expand.o: translate.h parse_util.h halloc_util.h
fishd.o: config.h signal.h util.h common.h wutil.h env_universal_common.h
fish_pager.o: config.h signal.h util.h wutil.h common.h complete.h output.h
fish_pager.o: input_common.h env_universal.h env_universal_common.h
fish_pager.o: input_common.h env_universal.h env_universal_common.h halloc.h
fish_pager.o: halloc_util.h
fish_tests.o: config.h signal.h util.h common.h proc.h io.h reader.h
fish_tests.o: builtin.h function.h complete.h wutil.h env.h expand.h parser.h
fish_tests.o: tokenizer.h output.h exec.h event.h
function.o: signal.h config.h util.h function.h proc.h io.h parser.h common.h
function.o: intern.h event.h
fish_tests.o: event.h tokenizer.h output.h exec.h halloc_util.h
function.o: signal.h config.h wutil.h util.h function.h proc.h io.h parser.h
function.o: event.h common.h intern.h reader.h parse_util.h env.h expand.h
halloc.o: config.h util.h common.h halloc.h
halloc_util.o: config.h util.h common.h halloc.h
highlight.o: signal.h config.h util.h wutil.h highlight.h tokenizer.h proc.h
highlight.o: io.h parser.h builtin.h function.h env.h expand.h sanity.h
highlight.o: common.h complete.h output.h
highlight.o: io.h parser.h event.h parse_util.h builtin.h function.h env.h
highlight.o: expand.h sanity.h common.h complete.h output.h
history.o: config.h util.h wutil.h history.h common.h reader.h env.h sanity.h
history.o: signal.h
input.o: config.h signal.h util.h wutil.h reader.h proc.h io.h common.h
input.o: sanity.h input_common.h input.h parser.h env.h expand.h event.h
input.o: translate.h
input.o: sanity.h input_common.h input.h parser.h event.h env.h expand.h
input.o: translate.h output.h
input_common.o: config.h util.h common.h wutil.h input_common.h
input_common.o: env_universal.h env_universal_common.h
intern.o: config.h util.h common.h intern.h
intern.o: config.h util.h wutil.h common.h intern.h
io.o: config.h util.h wutil.h exec.h proc.h io.h common.h translate.h
io.o: halloc.h
key_reader.o: input_common.h
kill.o: signal.h config.h util.h wutil.h kill.h proc.h io.h sanity.h common.h
kill.o: env.h expand.h exec.h parser.h
kill.o: env.h exec.h parser.h event.h
main.o: config.h signal.h util.h common.h reader.h builtin.h function.h
main.o: complete.h wutil.h env.h sanity.h proc.h io.h parser.h expand.h
main.o: intern.h exec.h event.h output.h translate.h
main.o: complete.h wutil.h env.h sanity.h proc.h io.h parser.h event.h
main.o: expand.h intern.h exec.h output.h translate.h halloc_util.h
mimedb.o: config.h xdgmime.h util.h
output.o: config.h signal.h util.h wutil.h expand.h common.h output.h
output.o: highlight.h
output.o: halloc_util.h highlight.h
parser.o: signal.h config.h util.h common.h wutil.h proc.h io.h parser.h
parser.o: tokenizer.h exec.h wildcard.h function.h builtin.h builtin_help.h
parser.o: env.h expand.h reader.h sanity.h env_universal.h
parser.o: env_universal_common.h event.h translate.h
parser.o: event.h tokenizer.h exec.h wildcard.h function.h builtin.h
parser.o: builtin_help.h env.h expand.h reader.h sanity.h env_universal.h
parser.o: env_universal_common.h translate.h intern.h parse_util.h halloc.h
parser.o: halloc_util.h
parse_util.o: config.h util.h wutil.h common.h tokenizer.h parse_util.h
parse_util.o: expand.h intern.h exec.h proc.h io.h env.h halloc_util.h
proc.o: config.h signal.h util.h wutil.h proc.h io.h common.h reader.h
proc.o: sanity.h env.h parser.h event.h translate.h
proc.o: sanity.h env.h parser.h event.h translate.h halloc.h halloc_util.h
proc.o: output.h
reader.o: config.h signal.h util.h wutil.h highlight.h reader.h proc.h io.h
reader.o: parser.h complete.h history.h common.h sanity.h env.h exec.h
reader.o: expand.h tokenizer.h kill.h input_common.h input.h function.h
reader.o: output.h translate.h
reader.o: parser.h event.h complete.h history.h common.h sanity.h env.h
reader.o: exec.h expand.h tokenizer.h kill.h input_common.h input.h
reader.o: function.h output.h translate.h parse_util.h
refcount.o: config.h util.h wutil.h common.h refcount.h
sanity.o: signal.h config.h util.h common.h sanity.h proc.h io.h history.h
sanity.o: reader.h kill.h wutil.h
sanity.o: reader.h kill.h wutil.h translate.h
set_color.o: config.h
signal.o: config.h signal.h common.h util.h wutil.h event.h reader.h proc.h
signal.o: io.h translate.h
tokenizer.o: config.h util.h wutil.h tokenizer.h common.h wildcard.h
tokenizer.o: translate.h
translate.o: config.h common.h util.h
translate.o: config.h common.h util.h halloc_util.h
util.o: config.h util.h common.h wutil.h
wgetopt.o: config.h wgetopt.h wutil.h
wgetopt.o: config.h wgetopt.h wutil.h translate.h
wildcard.o: config.h util.h wutil.h complete.h common.h wildcard.h reader.h
wildcard.o: expand.h translate.h
wutil.o: config.h util.h common.h wutil.h

1805
builtin.c

File diff suppressed because it is too large Load Diff

View File

@@ -159,6 +159,8 @@ int builtin_ulimit(wchar_t **argv);
*/
int builtin_complete(wchar_t **argv);
const wchar_t *builtin_complete_get_temporary_buffer();
/**
This function works like wperror, but it prints its result into
the sb_err string_buffer_t instead of to stderr. Used by the builtin

View File

@@ -24,6 +24,7 @@ Functions used for implementing the commandline builtin.
#include "input_common.h"
#include "input.h"
#include "translate.h"
#include "parse_util.h"
/**
Which part of the comandbuffer are we operating on
@@ -48,6 +49,26 @@ enum
}
;
/**
Returns the current commandline buffer.
*/
static const wchar_t *get_buffer()
{
const wchar_t *buff = builtin_complete_get_temporary_buffer();
if( !buff )
buff = reader_get_buffer();
return buff;
}
static int get_cursor_pos()
{
const wchar_t *buff = builtin_complete_get_temporary_buffer();
if( buff )
return wcslen( buff );
else
return reader_get_cursor_pos();
}
/**
Replace/append/insert the selection with/at/after the specified string.
@@ -57,14 +78,14 @@ enum
\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( wchar_t *begin,
wchar_t *end,
static void replace_part( const wchar_t *begin,
const wchar_t *end,
wchar_t *insert,
int append_mode )
{
wchar_t *buff = reader_get_buffer();
const wchar_t *buff = get_buffer();
string_buffer_t out;
int out_pos=reader_get_cursor_pos();
int out_pos=get_cursor_pos();
sb_init( &out );
@@ -88,7 +109,7 @@ static void replace_part( wchar_t *begin,
}
case INSERT_MODE:
{
int cursor = reader_get_cursor_pos() -(begin-buff);
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 );
@@ -109,8 +130,8 @@ static void replace_part( wchar_t *begin,
\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( wchar_t *begin,
wchar_t *end,
static void write_part( const wchar_t *begin,
const wchar_t *end,
int cut_at_cursor,
int tokenize )
{
@@ -119,7 +140,7 @@ static void write_part( wchar_t *begin,
wchar_t *buff;
int pos;
pos = reader_get_cursor_pos()-(begin-reader_get_buffer());
pos = get_cursor_pos()-(begin-get_buffer());
if( tokenize )
{
@@ -184,7 +205,7 @@ int builtin_commandline( wchar_t **argv )
int tokenize = 0;
if( !reader_get_buffer() )
if( !get_buffer() )
{
sb_append2( sb_err,
argv[0],
@@ -429,32 +450,42 @@ int builtin_commandline( wchar_t **argv )
buffer_part = STRING_MODE;
}
wchar_t *begin, *end;
const wchar_t *begin, *end;
switch( buffer_part )
{
case STRING_MODE:
{
begin = reader_get_buffer();
begin = get_buffer();
end = begin+wcslen(begin);
break;
}
case PROCESS_MODE:
{
reader_current_process_extent( &begin, &end );
parse_util_process_extent( get_buffer(),
get_cursor_pos(),
&begin,
&end );
break;
}
case JOB_MODE:
{
reader_current_job_extent( &begin, &end );
parse_util_job_extent( get_buffer(),
get_cursor_pos(),
&begin,
&end );
break;
}
case TOKEN_MODE:
{
reader_current_token_extent( &begin, &end, 0, 0 );
parse_util_token_extent( get_buffer(),
get_cursor_pos(),
&begin,
&end,
0, 0 );
break;
}

View File

@@ -19,12 +19,15 @@ Functions used for implementing the complete builtin.
#include "complete.h"
#include "wgetopt.h"
#include "parser.h"
#include "reader.h"
#include "translate.h"
const static 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.
complete_remove get called.
*/
static void builtin_complete_add2( const wchar_t *cmd,
@@ -235,6 +238,11 @@ static void builtin_complete_remove( array_list_t *cmd,
}
const wchar_t *builtin_complete_get_temporary_buffer()
{
return temporary_buffer;
}
int builtin_complete( wchar_t **argv )
{
int res=0;
@@ -245,11 +253,20 @@ int builtin_complete( wchar_t **argv )
string_buffer_t short_opt;
array_list_t gnu_opt, old_opt;
wchar_t *comp=L"", *desc=L"", *condition=L"", *load=0;
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;
if( !is_interactive_session )
{
debug( 1, _(L"%ls: Command only available in interactive sessions"), argv[0] );
}
al_init( &cmd );
al_init( &path );
sb_init( &short_opt );
@@ -290,7 +307,8 @@ int builtin_complete( wchar_t **argv )
}
,
{
L"long-option", required_argument, 0, 'l' }
L"long-option", required_argument, 0, 'l'
}
,
{
L"old-option", required_argument, 0, 'o'
@@ -317,7 +335,7 @@ int builtin_complete( wchar_t **argv )
}
,
{
L"load", required_argument, 0, 'y'
L"do-complete", required_argument, 0, 'C'
}
,
{
@@ -330,7 +348,7 @@ int builtin_complete( wchar_t **argv )
int opt = wgetopt_long( argc,
argv,
L"a:c:p:s:l:o:d:frxeun:y:",
L"a:c:p:s:l:o:d:frxeun:C:",
long_options,
&opt_index );
if( opt == -1 )
@@ -347,6 +365,7 @@ int builtin_complete( wchar_t **argv )
long_options[opt_index].name );
sb_append( sb_err,
parser_current_line() );
// builtin_print_help( argv[0], sb_err );
@@ -397,22 +416,21 @@ int builtin_complete( wchar_t **argv )
comp = woptarg;
break;
case 'e':
remove = 1;
break;
case 'n':
condition = woptarg;
break;
case 'y':
load = woptarg;
case 'C':
do_complete = woptarg?woptarg:reader_get_buffer();
break;
case '?':
sb_append( sb_err,
parser_current_line() );
// builtin_print_help( argv[0], sb_err );
res = 1;
@@ -422,56 +440,85 @@ int builtin_complete( wchar_t **argv )
}
if( res != 0 )
if( !res )
{
}
else if( woptind != argc )
{
sb_printf( sb_err,
_( L"%ls: Too many arguments\n" ),
argv[0] );
sb_append( sb_err,
parser_current_line() );
// builtin_print_help( argv[0], sb_err );
res = 1;
}
else if( load )
{
complete_load( load, 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 )
if( do_complete )
{
builtin_complete_remove( &cmd,
&path,
(wchar_t *)short_opt.buff,
&gnu_opt,
&old_opt );
array_list_t comp;
int i;
const wchar_t *prev_temporary_buffer = temporary_buffer;
temporary_buffer = do_complete;
if( recursion_level < 1 )
{
recursion_level++;
al_init( &comp );
complete( do_complete, &comp );
for( i=0; i<al_get_count( &comp ); i++ )
{
wchar_t *next = (wchar_t *)al_get( &comp, i );
wchar_t *sep = wcschr( next, COMPLETE_SEP );
if( sep )
*sep = L'\t';
sb_printf( sb_out, L"%ls\n", next );
}
al_foreach( &comp, (void (*)(const void *))&free );
al_destroy( &comp );
recursion_level--;
}
temporary_buffer = prev_temporary_buffer;
}
else if( woptind != argc )
{
sb_printf( sb_err,
_( L"%ls: Too many arguments\n" ),
argv[0] );
sb_append( sb_err,
parser_current_line() );
// 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
{
builtin_complete_add( &cmd,
&path,
(wchar_t *)short_opt.buff,
&gnu_opt,
&old_opt,
result_mode,
authorative,
condition,
comp,
desc );
}
}
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,
authorative,
condition,
comp,
desc );
}
}
}
al_foreach( &cmd, (void (*)(const void *))&free );
al_foreach( &path, (void (*)(const void *))&free );

View File

@@ -509,9 +509,6 @@ int builtin_set( wchar_t **argv )
!erase &&
!list )
{
/*
Only update the variable scope
*/
env_set( name, 0, scope );
finished = 1;
}

332
common.c
View File

@@ -20,7 +20,6 @@ parts of fish.
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <signal.h>
#include <locale.h>
#include <time.h>
#include <sys/time.h>
@@ -59,11 +58,6 @@ parts of fish.
#include "wildcard.h"
#include "parser.h"
/**
Error message to show on string convertion error
*/
#define STR2WCS_MSG "fish: Invalid multibyte sequence \'"
/**
The maximum number of minor errors to report. Further errors will be omitted.
*/
@@ -77,13 +71,6 @@ parts of fish.
struct termios shell_modes;
/**
Number of error encountered. This is reset after each command, and
used to limit the number of error messages on commands with many
string convertion problems.
*/
static int error_count=0;
int error_max=1;
wchar_t ellipsis_char;
@@ -99,20 +86,14 @@ int debug_level=1;
*/
static struct winsize termsize;
/**
Number of nested calls to the block function. Unblock when this reaches 0.
*/
static int block_count=0;
/**
String buffer used by the wsetlocale function
*/
static string_buffer_t *setlocale_buff=0;
void common_destroy()
{
if( setlocale_buff )
{
sb_destroy( setlocale_buff );
@@ -120,7 +101,9 @@ void common_destroy()
}
}
void common_init()
{
}
wchar_t **list_to_char_arr( array_list_t *l )
{
@@ -131,38 +114,13 @@ wchar_t **list_to_char_arr( array_list_t *l )
die_mem();
}
for( i=0; i<al_get_count( l ); i++ )
{
res[i] = (wchar_t *)al_get(l,i);
}
res[i]='\0';
return res;
}
void block()
{
block_count++;
if( block_count == 1 )
{
sigset_t chldset;
sigemptyset( &chldset );
sigaddset( &chldset, SIGCHLD );
sigprocmask(SIG_BLOCK, &chldset, 0);
}
}
void unblock()
{
block_count--;
if( block_count == 0 )
{
sigset_t chldset;
sigemptyset( &chldset );
sigaddset( &chldset, SIGCHLD );
sigprocmask(SIG_UNBLOCK, &chldset, 0);
}
}
int fgetws2( wchar_t **b, int *len, FILE *f )
{
int i=0;
@@ -176,8 +134,6 @@ int fgetws2( wchar_t **b, int *len, FILE *f )
watching for EINTR errors, bytes are lost.
*/
block();
while( 1 )
{
/* Reallocate the buffer if necessary */
@@ -216,8 +172,6 @@ int fgetws2( wchar_t **b, int *len, FILE *f )
case L'\n':
case L'\0':
buff[i]=L'\0';
unblock();
return i;
/* Ignore carriage returns */
case L'\r':
@@ -230,7 +184,6 @@ int fgetws2( wchar_t **b, int *len, FILE *f )
}
unblock();
}
@@ -255,61 +208,115 @@ void sort_list( array_list_t *comp )
wchar_t *str2wcs( const char *in )
{
wchar_t *res;
wchar_t *out;
size_t len = strlen(in);
res = malloc( sizeof(wchar_t)*(strlen(in)+1) );
if( !res )
out = malloc( sizeof(wchar_t)*(len+1) );
if( !out )
{
die_mem();
}
if( (size_t)-1 == mbstowcs( res, in, sizeof(wchar_t)*(strlen(in)) +1) )
{
error_count++;
if( error_count <=error_max )
{
fflush( stderr );
write( 2,
STR2WCS_MSG,
strlen(STR2WCS_MSG) );
write( 2,
in,
strlen(in ));
write( 2,
"\'\n",
2 );
}
free(res);
return 0;
}
return res;
return str2wcs_internal( in, out );
}
void error_reset()
wchar_t *str2wcs_internal( const char *in, wchar_t *out )
{
error_count=0;
size_t res=0;
int in_pos=0;
int out_pos = 0;
mbstate_t state;
size_t len = strlen(in);
memset( &state, 0, sizeof(state) );
while( in[in_pos] )
{
res = mbrtowc( &out[out_pos], &in[in_pos], len-in_pos, &state );
switch( res )
{
case (size_t)(-2):
case (size_t)(-1):
{
out[out_pos] = ENCODE_DIRECT_BASE + (unsigned char)in[in_pos];
in_pos++;
memset( &state, 0, sizeof(state) );
break;
}
case 0:
{
return out;
}
default:
{
in_pos += res;
break;
}
}
out_pos++;
}
out[out_pos] = 0;
return out;
}
char *wcs2str( const wchar_t *in )
{
char *res = malloc( MAX_UTF8_BYTES*wcslen(in)+1 );
char *out;
out = malloc( MAX_UTF8_BYTES*wcslen(in)+1 );
if( res == 0 )
if( !out )
{
die_mem();
}
wcstombs( res,
in,
MAX_UTF8_BYTES*wcslen(in)+1 );
return wcs2str_internal( in, out );
}
res = realloc( res, strlen( res )+1 );
return res;
char *wcs2str_internal( const wchar_t *in, char *out )
{
size_t res=0;
int in_pos=0;
int out_pos = 0;
mbstate_t state;
memset( &state, 0, sizeof(state) );
while( in[in_pos] )
{
if( ( in[in_pos] >= ENCODE_DIRECT_BASE) &&
( in[in_pos] < ENCODE_DIRECT_BASE+256) )
{
out[out_pos++] = in[in_pos]- ENCODE_DIRECT_BASE;
}
else
{
res = wcrtomb( &out[out_pos], in[in_pos], &state );
switch( res )
{
case (size_t)(-1):
{
debug( 1, L"Wide character has no narrow representation" );
memset( &state, 0, sizeof(state) );
break;
}
default:
{
out_pos += res;
break;
}
}
}
in_pos++;
}
out[out_pos] = 0;
return out;
}
char **wcsv2strv( const wchar_t **in )
@@ -508,8 +515,6 @@ int wcsvarname( wchar_t *str )
str++;
}
return 1;
}
@@ -532,30 +537,34 @@ int my_wcswidth( const wchar_t *c )
return res;
}
wchar_t *quote_end( const wchar_t *in )
const wchar_t *quote_end( const wchar_t *pos )
{
switch( *in )
wchar_t c = *pos;
while( 1 )
{
case '"':
pos++;
if( !*pos )
return 0;
if( *pos == L'\\')
{
while(1)
{
in = wcschr( in+1, L'"' );
if( !in )
return 0;
if( *(in-1) != L'\\' )
return (wchar_t *)in;
}
pos++;
}
case '\'':
else
{
return wcschr( in+1, L'\'' );
if( *pos == c )
{
return pos;
}
}
}
return 0;
}
const wchar_t *wsetlocale(int category, const wchar_t *locale)
{
@@ -618,12 +627,6 @@ int read_blocked(int fd, void *buf, size_t count)
return res;
}
int writeb( tputs_arg_t b )
{
write( 1, &b, 1 );
// putc( b, stdout );
return 0;
}
void die_mem()
{
@@ -752,6 +755,26 @@ wchar_t *escape( const wchar_t *in,
while( *in != 0 )
{
if( ( *in >= ENCODE_DIRECT_BASE) &&
( *in < ENCODE_DIRECT_BASE+256) )
{
int val = *in - ENCODE_DIRECT_BASE;
int tmp;
*(pos++) = L'\\';
*(pos++) = L'X';
tmp = val/16;
*pos++ = tmp > 9? L'a'+(tmp-10):L'0'+tmp;
tmp = val%16;
*pos++ = tmp > 9? L'a'+(tmp-10):L'0'+tmp;
}
else
{
switch( *in )
{
case L'\t':
@@ -820,6 +843,8 @@ wchar_t *escape( const wchar_t *in,
*pos++ = *in;
break;
}
}
in++;
}
*pos = 0;
@@ -895,60 +920,84 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
case L'u':
case L'U':
case L'x':
case L'o':
case L'X':
case L'0':
case L'1':
case L'2':
case L'3':
case L'4':
case L'5':
case L'6':
case L'7':
{
int i;
wchar_t res=0;
long long res=0;
int chars=2;
int base=16;
int byte = 0;
int max_val = 127;
switch( in[in_pos] )
{
case L'u':
{
base=16;
chars=4;
max_val = 35535;
break;
}
case L'U':
{
base=16;
chars=8;
max_val = WCHAR_MAX;
break;
}
case L'x':
{
base=16;
chars=2;
break;
}
case L'o':
case L'X':
{
byte=1;
max_val = 255;
break;
}
default:
{
base=8;
chars=3;
in_pos--;
break;
}
}
}
for( i=0; i<chars; i++ )
{
int d = convert_digit( in[++in_pos],base);
if( d < 0 )
{
in_pos--;
break;
}
res=(res*base)|d;
}
in[out_pos] = res;
if( (res > 0) && (res <= max_val) )
{
in[out_pos] = (byte?ENCODE_DIRECT_BASE:0)+res;
}
else
{
free(in);
return 0;
}
break;
}
@@ -1103,6 +1152,30 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
*/
case 1:
{
if( c == L'\\' )
{
switch( in[++in_pos] )
{
case L'\'':
{
in[out_pos]=in[in_pos];
break;
}
case 0:
{
free(in);
return 0;
}
default:
{
in[out_pos++] = L'\\';
in[out_pos]= in[in_pos];
}
}
}
if( c == L'\'' )
{
in[out_pos] = INTERNAL_SEPARATOR;
@@ -1141,11 +1214,12 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
}
case L'$':
case '"':
{
in[out_pos]=in[in_pos];
break;
}
default:
{
in[out_pos++] = L'\\';

View File

@@ -8,6 +8,8 @@
*/
#define FISH_COMMON_H
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <termios.h>
@@ -42,6 +44,11 @@ typedef char tputs_arg_t;
*/
#define FISH_COLOR_RESET -2
/**
This is in the unicode private use area.
*/
#define ENCODE_DIRECT_BASE 0xf100
/**
Save the shell mode on startup so we can restore them on exit
*/
@@ -76,7 +83,10 @@ extern wchar_t *program_name;
/**
Take an array_list_t containing wide strings and converts them to a
single null-terminated wchar_t **.
single null-terminated wchar_t **. The array is allocated using
halloc, and uses the \c context parameter as context. If \c context
is not noll, all elements of the \c array_list_t are also
registered to \c context using \c halloc_register().
*/
wchar_t **list_to_char_arr( array_list_t *l );
@@ -104,6 +114,7 @@ void sort_list( array_list_t *comp );
specified multibyte character string
*/
wchar_t *str2wcs( const char *in );
wchar_t *str2wcs_internal( const char *in, wchar_t *out );
/**
Returns a newly allocated multibyte character string equivalent of
@@ -111,6 +122,8 @@ wchar_t *str2wcs( const char *in );
*/
char *wcs2str( const wchar_t *in );
char *wcs2str_internal( const wchar_t *in, char *out );
/**
Returns a newly allocated wide character string array equivalent of
the specified multibyte character string array
@@ -172,12 +185,12 @@ int my_wcswidth( const wchar_t *c );
/**
This functions returns the end of the quoted substring beginning at
\c in. It can handle both single and double quotes. Returns 0 on
error.
\c in. The type of quoting character is detemrined by examining \c
in. Returns 0 on error.
\param in the position of the opening quote
*/
wchar_t *quote_end( const wchar_t *in );
const wchar_t *quote_end( const wchar_t *in );
/**
A call to this function will reset the error counter. Some
@@ -210,20 +223,18 @@ int contains_str( const wchar_t *needle, ... );
*/
int read_blocked(int fd, void *buf, size_t count);
/**
This is for writing process notification messages. Has to write to
stdout, so clr_eol and such functions will work correctly. Not an
issue since this function is only used in interactive mode anyway.
*/
int writeb( tputs_arg_t b );
/**
Exit program at once, leaving an error message about running out of memory
*/
void die_mem();
/**
Clean up
Create global_context using halloc
*/
void common_init();
/**
Free global_context using halloc_free
*/
void common_destroy();
@@ -252,8 +263,7 @@ 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, int escape_all );
/**
Expand backslashed escapes and substitute them with their unescaped
@@ -269,16 +279,6 @@ wchar_t *escape( const wchar_t *in,
wchar_t *unescape( const wchar_t * in,
int escape_special );
/**
Block SIGCHLD. Calls to block/unblock may be nested, and only once the nest count reaches zero wiull the block be removed.
*/
void block();
/**
undo call to block().
*/
void unblock();
/**
Attempt to acquire a lock based on a lockfile, waiting LOCKPOLLINTERVAL
milliseconds between polls and timing out after timeout seconds,

File diff suppressed because it is too large Load Diff

View File

@@ -33,6 +33,8 @@
/** Separateor between completion and description*/
#define COMPLETE_SEP_STR L"\004"
#define COMPLETE_ITEM_SEP L'\uf500'
/**
Character that separates the completion and description on programmable completions
*/
@@ -162,6 +164,6 @@ int complete_is_valid_argument( const wchar_t *str,
\param cmd the command for which to load command-specific completions
\param reload should the commands completions be reloaded, even if they where previously loaded. (This is set to true on actual completions, so that changed completion are updated in running shells)
*/
void complete_load( wchar_t *cmd, int reload );
void complete_load( const wchar_t *cmd, int reload );
#endif

View File

@@ -1,17 +1,50 @@
# Process this file with autoconf to produce a configure script.
AC_INIT(fish,1.20.0,fish-users@lists.sf.net)
AC_INIT(fish,1.21.0,fish-users@lists.sf.net)
for i in /usr/pkg /sw /opt /opt/local; do
AC_MSG_CHECKING([for $i/include include directory])
if test -d $i/include; then
AC_MSG_RESULT(yes)
CPPFLAGS="$CPPFLAGS -I$i/include/"
else
AC_MSG_RESULT(no)
fi
AC_MSG_CHECKING([for $i/lib library directory])
if test -d $i/lib; then
AC_MSG_RESULT(yes)
LDFLAGS="$LDFLAGS -L$i/lib/ -R$i/lib/"
else
AC_MSG_RESULT(no)
fi
AC_MSG_CHECKING([for $i/bin command directory])
if test -d $i/bin; then
AC_MSG_RESULT(yes)
optbindirs="$optbindirs $i/bin"
else
AC_MSG_RESULT(no)
fi
done
AC_SUBST( optbindirs, $optbindirs )
# If needed, run autoheader automatically
AC_MSG_CHECKING([if autoheader needs to be run])
if test ! -f ./config.h.in -o config.h.in -ot configure.ac; then
AC_MSG_RESULT([yes])
if which autoheader >/dev/null; then
echo running autoheader...
AC_MSG_NOTICE([running autoheader])
autoheader
else
echo Could not find the autoheader program in your path.
echo This program is needed because the configure.ac file has been modified.
echo Please install it and try again.
exit 1
AC_MSG_ERROR( [cannot find the autoheader program in your path.
This program is needed because the configure.ac file has been modified.
Please install it and try again.])
fi
else
AC_MSG_RESULT([no])
fi
# Tell autoconf to create config.h header
@@ -26,10 +59,9 @@ AC_PROG_INSTALL
AC_CHECK_PROG( has_doxygen, [doxygen], "true")
if ! test $has_doxygen = "true"; then
echo Could not find the Doxygen program in your path.
echo This program is needed to build fish.
echo Please install it and try again.
exit 1
AC_MSG_ERROR( [cannot find the Doxygen program in your path.
This program is needed to build fish.
Please install it and try again.])
fi
# Check for seq program. If missing, install fallback shellscript implementation
@@ -72,10 +104,6 @@ else
AC_SUBST( PREFIX, [$prefix])
fi
AC_SUBST(fishdir,[/fish.d])
AC_SUBST(fishfile,[/fish])
AC_SUBST(fishinputfile,[/fish_inputrc])
AC_ARG_VAR( [docdir], [Documentation direcotry] )
if test -z $docdir; then
@@ -84,7 +112,9 @@ fi
AC_DEFINE_UNQUOTED( DOCDIR, [L"$(eval echo $docdir)"], [Documentation directory] )
AC_DEFINE_UNQUOTED( SYSCONFDIR, [L"$(eval echo $sysconfdir)"], [System configuration directory] )
AC_DEFINE_UNQUOTED( DATADIR, [L"$(eval echo $datadir)"], [System configuration directory] )
AC_SUBST( SYSCONFDIR, ["$(eval echo $sysconfdir)"] )
AC_SUBST( DATADIR, ["$(eval echo $datadir)"] )
# Set up locale directory
AC_DEFINE_UNQUOTED( [LOCALEDIR], "$(eval echo $datadir)/locale", [Locale directory])
@@ -93,10 +123,6 @@ AC_SUBST( [LOCALEDIR], [$datadir/locale])
# See if Linux procfs is present
AC_CHECK_FILES([/proc/self/stat])
# See if NetBSD pkgsrc is installed
AC_CHECK_FILE([/usr/pkg/lib],[AC_SUBST(LIBDIR,[-L/usr/pkg/lib\ -R/usr/pkg/lib])])
AC_CHECK_FILE([/usr/pkg/include],[AC_SUBST(INCLUDEDIR,[-I/usr/pkg/include])])
# Check for RLIMIT_AS in sys/resource.h.
AC_MSG_CHECKING([for RLIMIT_AS in sys/resource.h])
AC_TRY_COMPILE([#include <sys/resource.h>],
@@ -146,6 +172,24 @@ else
AC_MSG_RESULT(no)
fi
# Check if realpath accepts null for its second argument
AC_MSG_CHECKING([if realpath accepts null for its second argument])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([#include <limits.h>
#include <errno.h>
#include <stdlib.h>],
[int status; char *res; res = realpath( "somefile", 0 ); status = !(res != 0 || errno == ENOENT); exit( status );])],
[have_realpath_null=yes],
[have_realpath_null=no] )
if test "$have_realpath_null" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_REALPATH_NULL], [1],
[Define to 1 if realpath accepts null for its second argument.])
else
AC_MSG_RESULT(no)
fi
# Check for libraries
AC_CHECK_LIB(socket, connect)
@@ -153,7 +197,7 @@ AC_CHECK_LIB(rt, nanosleep)
AC_CHECK_LIB(intl, gettext)
# Check for various header files
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h term.h ncurses/term.h libintl.h])
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h term.h ncurses/term.h libintl.h ncurses.h curses.h])
AC_CHECK_HEADER([regex.h],
[AC_DEFINE([HAVE_REGEX_H], [1], [Define to 1 if you have the <regex.h> header file.])],
@@ -165,6 +209,9 @@ AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp gettext fwprintf )
AC_CHECK_FUNCS( futimes wcwidth wcswidth getopt_long wcstok fputwc fgetwc )
AC_CHECK_FUNCS( wcstol dcgettext )
AC_DEFINE([HAVE_TRANSLATE_H], [1],
[Define to 1 if the wgettext function should be used for translating strings.])
# Check again for gettext library, and insert results into the Makefile
AC_CHECK_FUNC(gettext, AC_SUBST(HAVE_GETTEXT,1), AC_SUBST(HAVE_GETTEXT,0) )
@@ -174,7 +221,7 @@ AC_TRY_LINK([#if HAVE_LIBINTL_H]
[#include <libintl.h>]
[#endif],
[extern int _nl_msg_cat_cntr;]
[int tmp = _nl_msg_cat_cntr;], have__nl_msg_cat_cntr=yes, have__nl_msg_cat_cntr=no)
[int tmp = _nl_msg_cat_cntr; exit(tmp);], have__nl_msg_cat_cntr=yes, have__nl_msg_cat_cntr=no)
if test "$have__nl_msg_cat_cntr" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE__NL_MSG_CAT_CNTR], [1],
@@ -184,14 +231,9 @@ else
fi
# Check if we have ncurses, and use it rather than curses if possible.
AC_CHECK_HEADERS([ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURSES_H)],[AC_SUBST(CURSESLIB,[curses])])
AC_SEARCH_LIBS( setupterm, [ncurses curses], [ AC_MSG_NOTICE([Found curses implementation])], [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] )
# Force use of ncurses if it is avialable via NetBSD pkgsrc. This is an
# ugly kludge to force NetBSD to use ncurses, since NetBSDs own version
# does not properly support terminfo.
AC_CHECK_FILE([/usr/pkg/include/ncurses.h],[AC_SUBST(CURSESLIB,[ncurses]) AC_DEFINE(HAVE_NCURSES_H)])
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile init/fish init/fish_interactive.fish init/fish_complete.fish seq])
AC_CONFIG_FILES([Makefile fish.spec doc_src/fish.1 doc_src/Doxyfile etc/fish etc/fish_interactive.fish seq])
AC_OUTPUT
echo "Now run 'make' and 'make install' to built and install fish."

View File

@@ -3,10 +3,9 @@
\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
CDPATH environment variable will be separated using the : as
separator, and the resulting list will be searched for a suitable new
current directory. 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 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.

View File

@@ -43,6 +43,10 @@ Other switches
that they will be returned to the reader before any additional
actual keypresses are read.
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.
\subsection commandline-example Example
<tt>commandline -j $history[3]</tt>

View File

@@ -14,6 +14,7 @@ the fish manual.
- <tt>LONG_OPTION</tt> is a multi character option for the command
- <tt>OPTION_ARGUMENTS</tt> is parameter containing a space-separated list of possible option-arguments, which may contain subshells
- <tt>DESCRIPTION</tt> is a description of what the option and/or option arguments do
- <tt>-C STRING</tt> or <tt>--do-complete=STRING</tt> makes complete try to find all possible completions for the specified string
- <tt>-e</tt> or <tt>--erase</tt> implies that the specified completion should be deleted
- <tt>-f</tt> or <tt>--no-files</tt> specifies that the option specified by this completion may not be followed by a filename
- <tt>-n</tt> or <tt>--condition</tt> specifies a shell command that must return 0 if the completion is to be used. This makes it possible to specify completions that should only be used in some cases.
@@ -31,8 +32,8 @@ options, the same styles as the GNU version of the getopt
library. These styles are:
- Short options, like '-a'. Short options are a single character long, are preceded by a single hyphen and may be grouped together (like '-la', which is equivalent to '-l -a'). Option arguments may be specified in the following parameter ('-w 32') or by appending the option with the value ('-w32').
- Old style long options, like '-Wall'. Old style long options are more than one character long, are preceded by a single hyphen and may not be grouped together. Option arguments are specified in the following parameter ('-ao null').
- GNU style long options, like '--colors'. GNU style long options are more than one character long, are preceded by two hyphens, and may not be grouped together. Option arguments may be specified in the following parameter ('--quoting-style shell') or by appending the option with a '=' and the value ('--quoting-style=shell'). GNU style long options may be abbreviated so long as the abbreviation is unique ('--h' is equivalent to '--help' if help is the only long option beginning with an 'h').
- Old style long options, like '-Wall'. Old style long options can be more than one character long, are preceded by a single hyphen and may not be grouped together. Option arguments are specified in the following parameter ('-ao null').
- GNU style long options, like '--colors'. GNU style long options can be more than one character long, are preceded by two hyphens, and may not be grouped together. Option arguments may be specified in the following parameter ('--quoting-style shell') or by appending the option with a '=' and the value ('--quoting-style=shell'). GNU style long options may be abbreviated so long as the abbreviation is unique ('--h' is equivalent to '--help' if help is the only long option beginning with an 'h').
The options for specifying command name, command path, or command
switches may all be used multiple times to specify multiple commands

24
doc_src/contains.txt Normal file
View File

@@ -0,0 +1,24 @@
\section contains contains - Test if a word is present in a list
\subsection contains-synopsis Synopsis
<code>contains [OPTIONS] KEY [VALUES...]</code>
\subsection contains-description Description
- \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
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.

File diff suppressed because it is too large Load Diff

9
doc_src/fish_pager.txt Normal file
View File

@@ -0,0 +1,9 @@
\section fish_pager fish_pager - Internal command used by fish
\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.

View File

@@ -1,9 +1,10 @@
\section nextd nextd
\subsection nextd-synopsis Synopsis
<tt>nextd [-l] [pos]</tt>
<tt>nextd [-l | --list] [pos]</tt>
\subsection nextd-description Description
<tt>nextd</tt> moves forwards <tt>pos</tt> positions in the history of visited directories;
if the end of the history has been hit, a warning is printed. If the <tt>-l></tt> flag is
specified, the current history is also displayed.
\subsection nextd-description Description <tt>nextd</tt> moves
forwards <tt>pos</tt> positions in the history of visited directories;
if the end of the history has been hit, a warning is printed. If the
<code>-l></code> or <code>--list</code> flag is specified, the current
history is also displayed.

View File

@@ -1,9 +1,10 @@
\section prevd prevd
\subsection prevd-synopsis Synopsis
<tt>prevd [-l] [pos]</tt>
<tt>prevd [-l | --list] [pos]</tt>
\subsection prevd-description Description
<tt>prevd</tt> moves backwards <tt>pos</tt> positions in the history of visited directories;
if the beginning of the history has been hit, a warning is printed. If the <tt>-l</tt> flag
is specified, the current history is also displayed.
\subsection prevd-description Description <tt>prevd</tt> moves
backwards <tt>pos</tt> positions in the history of visited
directories; if the beginning of the history has been hit, a warning
is printed. If the <code>-l</code> or <code>--list</code> flag is
specified, the current history is also displayed.

View File

@@ -27,8 +27,14 @@ If a variable is set to more than one value, the variable will be an
array with the specified elements. If a variable is set to zero
elements, it will become an array with zero elements.
If the variable name is one or more array elements, such as <code>PATH[1
3 7]</code>, only those array elements specified will be changed.
If the variable name is one or more array elements, such as
<code>PATH[1 3 7]</code>, only those array elements specified will be
changed.
The set command requires all switch arguments to come before any
non-switch arguments. For example, <code>set flags -l</code> will have
the effect of setting the value of the variable <code>flags</code> to
'-l', not making the variable local.
\subsection set-example Example

2
env.c
View File

@@ -386,7 +386,7 @@ static void setup_path()
path = env_get( L"PATH" );
if( !path )
{
env_set( L"PATH", 0, ENV_EXPORT | ENV_GLOBAL | ENV_USER );
env_set( L"PATH", 0, ENV_EXPORT | ENV_GLOBAL );
path=0;
}

View File

@@ -214,7 +214,7 @@ void env_universal_init( wchar_t * p,
void (*sf)(),
void (*cb)( int type, const wchar_t *name, const wchar_t *val ))
{
debug( 2, L"env_universal_init()" );
debug( 3, L"env_universal_init()" );
path=p;
user=u;
start_fishd=sf;
@@ -233,7 +233,7 @@ void env_universal_init( wchar_t * p,
{
env_universal_barrier();
}
debug( 2, L"end env_universal_init()" );
debug( 3, L"end env_universal_init()" );
}
void env_universal_destroy()

View File

@@ -5,6 +5,8 @@
client library and by the daemon.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
@@ -103,7 +105,7 @@ static int get_names_show_unexported;
void env_universal_common_init( void (*cb)(int type, const wchar_t *key, const wchar_t *val ) )
{
debug( 2, L"Init env_universal_common" );
debug( 3, L"Init env_universal_common" );
callback = cb;
hash_init( &env_universal_var, &hash_wcs_func, &hash_wcs_cmp );
}
@@ -186,7 +188,7 @@ void read_message( connection_t *src )
}
else
{
sb_printf( &src->input, L"%lc", res );
sb_append_char( &src->input, res );
}
}
}
@@ -227,7 +229,7 @@ static int match( const wchar_t *msg, const wchar_t *cmd )
static void parse_message( wchar_t *msg,
connection_t *src )
{
debug( 2, L"parse_message( %ls );", msg );
debug( 3, L"parse_message( %ls );", msg );
if( msg[0] == L'#' )
return;

View File

@@ -1,7 +1,14 @@
#
# Init file for fish
#
# @configure_input@
#
# Set default search paths
#
set -g fish_function_path ~/.fish.d/functions @SYSCONFDIR@/fish.d/functions @DATADIR@/functions
set -g fish_complete_path ~/.fish.d/completions @SYSCONFDIR@/fish.d/completions @DATADIR@/completions
#
# Set default field separators
@@ -15,11 +22,10 @@ set -g IFS \ \t\n
# want this even for text-only terminals.
#
set -l path_list /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin
set -l path_list /bin /usr/bin /usr/X11R6/bin @PREFIX@/bin @optbindirs@
# Root should also have the sbin directories in the path
set -l uid (id -u 2>/dev/null)
if test "$uid" = 0
if test "$USER" = root
set path_list $path_list /sbin /usr/sbin /usr/local/sbin
end
@@ -32,28 +38,12 @@ for i in $path_list
end
#
# Set some value for LANG if nothing was set before, and this is a
# login shell. Also check for i18n information in /etc/sysconfig/i18n
#
if status --is-login
if not set -q LANG >/dev/null
set -gx LANG en_US.UTF-8
end
if test -f /etc/sysconfig/i18n
eval (cat /etc/sysconfig/i18n |sed -ne 's/^\([a-zA-Z]*\)=\(.*\)$/set -gx \1 \2;/p')
end
end
#
# Put linux console in unicode mode. Should this be done in any other
# situation as well?
#
if expr "$LANG" : ".*UTF" >/dev/null
if expr "$LANG" : ".*[Uu][Tt][Ff]" >/dev/null
if test linux = "$TERM"
unicode_start ^/dev/null
end
@@ -71,22 +61,6 @@ for i in DISPLAY
end
end
#
# Alias for gettext (or a fallback if gettext isn't installed) This
# needs to be defined here and not in fish_function.fish, since it is
# used by other init files.
#
if test 1 = "@HAVE_GETTEXT@"; and which gettext >/dev/null ^/dev/null
function _ -d "Alias for the gettext command"
gettext fish $argv
end
else
function _ -d "Alias for the gettext command"
printf "%s" $argv
end
end
#
# Load additional initialization files
#

View File

@@ -0,0 +1,97 @@
#
# Initializations that should only be performed when in interactive mode
#
# @configure_input@
if not status --is-interactive
exit
end
#
# Print a greeting
#
printf (_ 'Welcome to fish, the friendly interactive shell\n')
printf (_ 'Type %shelp%s for instructions on how to use fish\n') (set_color green) (set_color normal)
#
# Set exit message
#
function fish_on_exit -d (_ "Commands to execute when fish exits") --on-process %self
printf (_ "Good bye\n")
end
#
# Set INPUTRC to something nice
#
# We override INPUTRC if already set, since it may be set by a shell
# other than fish, which may use a different file. The new value should
# be exported, since the fish inputrc file plays nice with other files
# by including them when found.
# Give priority to the default file installed with fish in
# @SYSCONFDIR@/fish_inputrc.
#
for i in ~/.fish_inputrc @SYSCONFDIR@/fish_inputrc ~/.inputrc /etc/inputrc
if test -f $i
set -xg INPUTRC $i
break
end
end
#
# Set various color values
#
function set_default -d "Set an exported universal variable, unless it has already been set"
if not set -q $argv[1]
set -Ux -- $argv
end
end
function set_exported_default -d "Set an exported universal variable, unless it has already been set"
if not set -q $argv[1]
set -Ux -- $argv
end
end
# Regular syntax highlighting colors
set_default fish_color_normal normal
set_default fish_color_command green
set_default fish_color_redirection normal
set_default fish_color_comment brown
set_default fish_color_error red
set_default fish_color_cwd green
# Background color for matching quotes and parenthesis
set_default fish_color_match cyan
# Background color for search matches
set_default fish_color_search_match purple
# Pager colors
set_default fish_pager_color_prefix cyan
set_default fish_pager_color_completion normal
set_default fish_pager_color_description normal
set_default fish_pager_color_progress cyan
# Directory history colors
set_default fish_color_history_current cyan
#
# Setup the CDPATH variable
#
set_default CDPATH . ~
#
# Remove temporary functions
#
functions -e set_exported_default
functions -e set_default

83
event.c
View File

@@ -21,6 +21,7 @@
#include "event.h"
#include "signal.h"
#include "translate.h"
#include "halloc_util.h"
/**
Number of signals that can be queued before an overflow occurs
@@ -74,11 +75,15 @@ static array_list_t *killme;
*/
static array_list_t *blocked;
/**
String buffer used for formating event descriptions in event_get_desc()
*/
static string_buffer_t *get_desc_buff=0;
/**
Tests if one event instance matches the definition of a event
class. If the class defines a function name, that will also be a
match criterion.
class. If both the class and the instance name a function,
they must name the same function.
*/
static int event_match( event_t *class, event_t *instance )
@@ -186,6 +191,60 @@ static int event_is_blocked( event_t *e )
return 0;
}
const wchar_t *event_get_desc( event_t *e )
{
if( !get_desc_buff )
{
get_desc_buff=sb_halloc( global_context );
}
else
{
sb_clear( get_desc_buff );
}
switch( e->type )
{
case EVENT_SIGNAL:
sb_printf( get_desc_buff, _(L"signal handler for %ls (%ls)"), sig2wcs(e->param1.signal ), signal_get_desc( e->param1.signal ) );
break;
case EVENT_VARIABLE:
sb_printf( get_desc_buff, _(L"handler for variable '%ls'"), e->param1.variable );
break;
case EVENT_EXIT:
if( e->param1.pid > 0 )
{
sb_printf( get_desc_buff, _(L"exit handler for process %d"), e->param1.pid );
}
else
{
job_t *j = job_get_from_pid( -e->param1.pid );
if( j )
sb_printf( get_desc_buff, _(L"exit handler for job %d, '%ls'"), j->job_id, j->command );
else
sb_printf( get_desc_buff, _(L"exit handler for job with process group %d"), -e->param1.pid );
}
break;
case EVENT_JOB_ID:
{
job_t *j = job_get( e->param1.job_id );
if( j )
sb_printf( get_desc_buff, _(L"exit handler for job %d, '%ls'"), j->job_id, j->command );
else
sb_printf( get_desc_buff, _(L"exit handler for job with job id %d"), j->job_id );
break;
}
}
return (const wchar_t *)get_desc_buff->buff;
}
void event_add_handler( event_t *event )
{
@@ -194,7 +253,7 @@ void event_add_handler( event_t *event )
e = event_copy( event, 0 );
if( !events )
events = al_new();
events = al_new();
if( e->type == EVENT_SIGNAL )
{
@@ -326,8 +385,6 @@ static void event_fire_internal( event_t *event )
int i, j;
string_buffer_t *b=0;
array_list_t *fire=0;
int was_subshell = is_subshell;
/*
First we free all events that have been removed
@@ -391,7 +448,7 @@ static void event_fire_internal( event_t *event )
for( j=0; j<al_get_count(&event->arguments); j++ )
{
wchar_t *arg_esc = escape( (wchar_t *)al_get( &event->arguments, j), 0 );
wchar_t *arg_esc = escape( (wchar_t *)al_get( &event->arguments, j), 1 );
sb_append( b, L" " );
sb_append( b, arg_esc );
free( arg_esc );
@@ -403,16 +460,14 @@ static void event_fire_internal( event_t *event )
Event handlers are not part of the main flow of code, so
they are marked as non-interactive and as a subshell
*/
is_subshell=1;
proc_push_interactive(0);
parser_push_block( EVENT );
current_block->param1.event = event;
eval( (wchar_t *)b->buff, 0, TOP );
parser_pop_block();
proc_pop_interactive();
}
/*
Restore interactivity flags
*/
is_subshell = was_subshell;
if( b )
{
sb_destroy( b );
@@ -564,6 +619,7 @@ void event_init()
void event_destroy()
{
if( events )
{
al_foreach( events, (void (*)(const void *))&event_free );
@@ -571,6 +627,7 @@ void event_destroy()
free( events );
events=0;
}
if( killme )
{
al_foreach( killme, (void (*)(const void *))&event_free );

View File

@@ -130,4 +130,10 @@ void event_destroy();
*/
void event_free( event_t *e );
/**
Returns a string describing the specified event. The string should
not be freed.
*/
const wchar_t *event_get_desc( event_t *e );
#endif

220
exec.c
View File

@@ -37,6 +37,9 @@
#include "signal.h"
#include "env_universal.h"
#include "translate.h"
#include "halloc.h"
#include "halloc_util.h"
#include "parse_util.h"
/**
Prototype for the getpgid library function. The prototype for this
@@ -67,6 +70,8 @@ pid_t getpgid( pid_t pid );
*/
static array_list_t *open_fds=0;
static int set_child_group( job_t *j, process_t *p, int print_errors );
void exec_close( int fd )
{
@@ -238,7 +243,7 @@ void free_fd( io_data_t *io, int fd )
\param io the list of IO redirections for the child
\param exit_on_error whether to call exit() on errors
\return 1 on sucess, 0 on failiure
\return 0 on sucess, -1 on failiure
*/
static int handle_child_io( io_data_t *io, int exit_on_error )
{
@@ -257,7 +262,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
if( io->fd > 2 )
{
/*
Make sure the fd used by this redirection is not used by i.e. a pipe.
Make sure the fd used by this redirection is not used by e.g. a pipe.
*/
free_fd( io, io->fd );
}
@@ -283,7 +288,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
}
else
{
return 0;
return -1;
}
}
else if( tmp != io->fd)
@@ -302,7 +307,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
}
else
{
return 0;
return -1;
}
}
exec_close( tmp );
@@ -326,7 +331,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
}
else
{
return 0;
return -1;
}
}
break;
@@ -349,7 +354,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
}
else
{
return 0;
return -1;
}
}
@@ -373,7 +378,7 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
if( env_universal_server.fd >= 0 )
exec_close( env_universal_server.fd );
return 1;
return 0;
}
@@ -387,41 +392,24 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
\param j the job to set up the IO for
\param p the child process to set up
\return 1 on sucess, 0 on failiure
\return 0 on sucess, -1 on failiure
*/
static int setup_child_process( job_t *j, process_t *p )
{
int res;
if( j->terminal )
{
pid_t pid;
/*
Put the process into the process group and give the process
group the terminal, if appropriate. This has to be done
both by the shell and in the individual child processes
because of potential race conditions.
*/
pid = getpid ();
if (j->pgid == 0)
j->pgid = pid;
/* Wait till shell puts os in our own group */
while( getpgrp() != j->pgid )
sleep(0);
/* Wait till shell gives us stdin */
if ( j->fg )
{
while( tcgetpgrp( 0 ) != j->pgid )
sleep(0);
}
int res=0;
if( p )
{
res = set_child_group( j, p, 1 );
}
if( !res )
{
res = handle_child_io( j->io, (p!=0) );
}
res = handle_child_io( j->io, (p==0) );
/* Set the handling for job control signals back to the default. */
if( res )
if( !res )
{
signal_reset_handlers();
}
@@ -595,14 +583,22 @@ static void internal_exec_helper( const wchar_t *def,
}
/**
This function should be called by the parent process right after
fork() has been called. If job control is enabled, the child is put
in the jobs group.
This function should be called by both the parent process and the
child right after fork() has been called. If job control is
enabled, the child is put in the jobs group, and if the child is
also in the foreground, it is also given control of the
terminal. When called in the parent process, this function may
fail, since the child might have already finished and called
exit. The parent process may safely ignore the exit status of this
call.
Returns 0 on sucess, -1 on failiure.
*/
static int handle_new_child( job_t *j, process_t *p )
static int set_child_group( job_t *j, process_t *p, int print_errors )
{
int res = 0;
if( j->terminal )
if( j->job_control )
{
int new_pgid=0;
@@ -614,7 +610,7 @@ static int handle_new_child( job_t *j, process_t *p )
if( setpgid (p->pid, j->pgid) )
{
if( getpgid( p->pid) != j->pgid )
if( getpgid( p->pid) != j->pgid && print_errors )
{
debug( 1,
_( L"Could not send process %d from group %d to group %d" ),
@@ -622,38 +618,28 @@ static int handle_new_child( job_t *j, process_t *p )
getpgid( p->pid),
j->pgid );
wperror( L"setpgid" );
res = -1;
}
}
if( j->fg )
{
if( tcsetpgrp (0, j->pgid) )
{
debug( 1, _( L"Could not send job %d ('%ls') to foreground" ),
j->job_id,
j->command );
wperror( L"tcsetpgrp" );
return -1;
}
}
if( j->fg && new_pgid)
{
if( tcsetpgrp (0, j->pgid) )
{
debug( 1, _( L"Could not send job %d ('%ls') to foreground" ),
j->job_id,
j->command );
wperror( L"tcsetpgrp" );
return -1;
}
}
}
else
{
j->pgid = getpid();
}
return 0;
if( j->terminal && j->fg )
{
if( tcsetpgrp (0, j->pgid) && print_errors )
{
debug( 1, _( L"Could not send job %d ('%ls') to foreground" ),
j->job_id,
j->command );
wperror( L"tcsetpgrp" );
res = -1;
}
}
return res;
}
@@ -689,9 +675,10 @@ void exec( job_t *j )
signal_block();
/*
setup_child_process make sure signals are propelry set up
setup_child_process make sure signals are properly set
up. It will also call signal_unblock
*/
if( setup_child_process( j, 0 ) )
if( !setup_child_process( j, 0 ) )
{
/*
launch_process never returns
@@ -722,9 +709,9 @@ void exec( job_t *j )
if( block_io )
{
if( j->io )
j->io = io_add( io_duplicate(block_io), j->io );
j->io = io_add( io_duplicate( j, block_io), j->io );
else
j->io=io_duplicate(block_io);
j->io=io_duplicate( j, block_io);
}
j->io = io_add( j->io, &pipe_write );
@@ -803,53 +790,22 @@ void exec( job_t *j )
{
case INTERNAL_FUNCTION:
{
wchar_t **arg;
int i;
string_buffer_t sb;
const wchar_t * def = function_get_definition( p->argv[0] );
// fwprintf( stderr, L"run function %ls\n", argv[0] );
wchar_t * def = halloc_register( j, wcsdup( function_get_definition( p->argv[0] )));
//fwprintf( stderr, L"run function %ls\n", argv[0] );
if( def == 0 )
{
debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] );
break;
}
/*
These two lines must be called before the new block is pushed
*/
int lineno = parser_get_lineno();
wchar_t *file = parser_current_filename()?wcsdup(parser_current_filename()):0;
parser_push_block( FUNCTION_CALL );
al_init( &current_block->param2.function_vars );
current_block->param1.function_name = wcsdup( p->argv[0] );
current_block->param3.function_lineno = lineno;
current_block->param4.function_filename = file;
if( builtin_count_args(p->argv)>1 )
{
sb_init( &sb );
for( i=1, arg=p->argv+1; *arg; i++, arg++ )
{
al_push( &current_block->param2.function_vars,
escape(*arg, 1) );
if( i != 1 )
sb_append( &sb, ARRAY_SEP_STR );
sb_append( &sb, *arg );
}
env_set( L"argv", (wchar_t *)sb.buff, ENV_LOCAL );
sb_destroy( &sb );
}
else
{
env_set( L"argv", 0, ENV_LOCAL );
}
current_block->param2.function_call_process = p;
current_block->param1.function_name = halloc_register( current_block, wcsdup( p->argv[0] ) );
parse_util_set_argv( p->argv+1 );
parser_forbid_function( p->argv[0] );
if( p->next )
@@ -1016,7 +972,7 @@ void exec( job_t *j )
if( !io_buffer )
{
/*
No buffer, se we exit directly. This means we
No buffer, so we exit directly. This means we
have to manually set the exit status.
*/
if( p->next == 0 )
@@ -1062,12 +1018,19 @@ void exec( job_t *j )
it control over the terminal.
*/
p->pid = pid;
if( handle_new_child( j, p ) )
exit(1);
set_child_group( j, p, 0 );
}
}
else
{
if( p->next == 0 )
{
proc_set_last_status( j->negate?(status?0:1):status);
}
p->completed = 1;
}
io_buffer_destroy( io_buffer );
@@ -1154,9 +1117,8 @@ void exec( job_t *j )
*/
p->pid = pid;
if( handle_new_child( j, p ) )
exit( 1 );
set_child_group( j, p, 0 );
}
break;
@@ -1194,20 +1156,16 @@ void exec( job_t *j )
*/
p->pid = pid;
if( handle_new_child( j, p ) )
exit( 1 );
set_child_group( j, p, 0 );
}
break;
}
}
if( p->type == INTERNAL_BUILTIN )
builtin_pop_io();
builtin_pop_io();
/*
Close the pipe the current process uses to read from the previous process_t
@@ -1302,24 +1260,30 @@ int exec_subshell( const wchar_t *cmd,
{
wchar_t *el = str2wcs( begin );
if( el )
{
al_push( l, el );
}
else
{
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
}
}
io_buffer_destroy( io_buffer );
return status;
case '\n':
{
wchar_t *el;
*end=0;
el = str2wcs( begin );
if( !el )
el = str2wcs( begin );
if( el )
{
debug( 0, _( L"Subshell '%ls' returned illegal string, discarded one entry" ), cmd );
al_push( l, el );
}
else
{
al_push( l, el );
debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ );
}
begin = end+1;
break;

911
expand.c

File diff suppressed because it is too large Load Diff

View File

@@ -130,7 +130,7 @@ enum
\param out The list to which the result will be appended.
\return One of EXPAND_OK, EXPAND_ERROR, EXPAND_WILDCARD_MATCH and EXPAND_WILDCARD_NO_MATCH
*/
int expand_string( wchar_t *in, array_list_t *out, int flag );
int expand_string( void *context, wchar_t *in, array_list_t *out, int flag );
/**
expand_one is identical to expand_string, except it will fail if in
@@ -141,39 +141,13 @@ int expand_string( wchar_t *in, array_list_t *out, int flag );
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
\return The expanded parameter, or 0 on failiure
*/
wchar_t *expand_one( wchar_t *in, int flag );
/**
Expand backslashed escapes and substitute them with their unescaped
counterparts. Also optionally change the wildcards, the tilde
character and a few more into constants which are defined in a
private use area of Unicode. This assumes wchar_t is a unicode
character. character set.
The result must be free()d. The original string is not modified. If
an invalid sequence is specified, 0 is returned.
*/
wchar_t *expand_unescape( const wchar_t * in, int escape_special );
/**
Replace special characters with escape sequences. Newline is
replaced with \n, etc.
The result must be free()d. The original string is not modified.
\param in The string to be escaped
\param escape_all Whether all characters wich hold special meaning in fish (Pipe, semicolon, etc,) should be escaped, or only unprintable characters
\return The escaped string
*/
wchar_t *expand_escape( const wchar_t *in, int escape_all );
wchar_t *expand_one( void *context, wchar_t *in, int flag );
/**
Convert the variable value to a human readable form, i.e. escape things, handle arrays, etc. Suitable for pretty-printing.
*/
wchar_t *expand_escape_variable( const wchar_t *in );
/**
Perform tilde expansion and nothing else on the specified string.
@@ -182,20 +156,6 @@ wchar_t *expand_escape_variable( const wchar_t *in );
*/
wchar_t *expand_tilde(wchar_t *in);
/**
Locate the first subshell in the specified string.
\param in the string to search for subshells
\param begin the starting paranthesis of the subshell
\param end the ending paranthesis of the subshell
\param flags set this variable to ACCEPT_INCOMPLETE if in tab_completion mode
\return -1 on syntax error, 0 if no subshells exist and 1 on sucess
*/
int expand_locate_subshell( wchar_t *in,
wchar_t **begin,
wchar_t **end,
int flags );
/**
Tokenize the specified string into the specified array_list_t.

View File

@@ -13,40 +13,65 @@ Source0: http://roo.no-ip.org/%{name}/files/%{version}/%{name}-%{
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: doxygen ncurses-devel xorg-x11-devel
%description
fish is a shell geared towards interactive use. It's features are
focused on user friendlieness and discoverability. The language syntax
is simple but incompatible with other shell languages.
%prep
%setup -q
%build
%build
%configure docdir=%_datadir/doc/%{name}-%{version}
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR="$RPM_BUILD_ROOT"
%clean
rm -rf $RPM_BUILD_ROOT
%post
if ! grep %_bindir/fish %_sysconfdir/shells >/dev/null; then
echo %_bindir/fish >>%_sysconfdir/shells
fi
%postun
if [ "$1" = 0 ]; then
grep -v %_bindir/fish %_sysconfdir/shells >%_sysconfdir/fish.tmp
mv %_sysconfdir/fish.tmp %_sysconfdir/shells
fi
%files
%defattr(-,root,root,-)
%doc %_datadir/doc/%{name}-%{version}
%_mandir/man1/fish.1*
%_mandir/man1/xsel.1x*
%_mandir/man1/mimedb.1*
@@ -54,6 +79,7 @@ fi
%_mandir/man1/count.1*
%_mandir/man1/fishd.1*
%_mandir/man1/fish_pager.1*
%attr(0755,root,root) %_bindir/fish
%attr(0755,root,root) %_bindir/fishd
%attr(0755,root,root) %_bindir/fish_pager
@@ -61,14 +87,26 @@ fi
%attr(0755,root,root) %_bindir/set_color
%attr(0755,root,root) %_bindir/mimedb
%attr(0755,root,root) %_bindir/count
%config %_sysconfdir/fish
%config %_sysconfdir/fish_inputrc
%dir %_sysconfdir/fish.d
%config %_sysconfdir/fish.d/fish_*.fish
%dir %_sysconfdir/fish.d/completions
%config %_sysconfdir/fish.d/completions/*.fish
%dir %_datadir/fish
%_datadir/fish/fish
%dir %_datadir/fish/completions
%_datadir/fish/completions/*.fish
%dir %_datadir/fish/functions
%_datadir/fish/functions/*.fish
%_datadir/locale/*/LC_MESSAGES/fish.mo
%changelog
* Tue Nov 29 2005 Axel Liljencrantz <axel@liljencrantz.se> 1.17.0-0
- 1.17.0

View File

@@ -42,6 +42,8 @@
#include "output.h"
#include "input_common.h"
#include "env_universal.h"
#include "halloc.h"
#include "halloc_util.h"
enum
{
@@ -74,6 +76,7 @@ static struct termios pager_modes;
static int is_ca_mode = 0;
static buffer_t *pager_buffer;
/**
The environment variables used to specify the color of different
@@ -91,8 +94,18 @@ static wchar_t *hightlight_var[] =
static string_buffer_t out_buff;
static FILE *out_file;
typedef struct
{
array_list_t *comp;
wchar_t *desc;
int comp_width;
int desc_width;
int pref_width;
int min_width;
}
comp_t;
int get_color( int highlight )
static int get_color( int highlight )
{
if( highlight < 0 )
return FISH_COLOR_NORMAL;
@@ -101,9 +114,6 @@ int get_color( int highlight )
wchar_t *val = env_universal_get( hightlight_var[highlight]);
if( val == 0 )
return FISH_COLOR_NORMAL;
if( val == 0 )
{
return FISH_COLOR_NORMAL;
@@ -112,7 +122,20 @@ int get_color( int highlight )
return output_color_code( val );
}
int try_sequence( char *seq )
static void recalc_width( array_list_t *l, const wchar_t *prefix )
{
int i;
for( i=0; i<al_get_count( l ); i++ )
{
comp_t *c = (comp_t *)al_get( l, i );
c->min_width = mini( c->desc_width, maxi(0,termsize.ws_col/3 - 2)) +
mini( c->desc_width, maxi(0,termsize.ws_col/5 - 4)) +4;
}
}
static int try_sequence( char *seq )
{
int j, k;
wint_t c=0;
@@ -195,6 +218,110 @@ static wint_t readch()
}
static int pager_buffered_writer( char c)
{
b_append( pager_buffer, &c, 1 );
return 0;
}
static void pager_flush()
{
write( 1, pager_buffer->buff, pager_buffer->used );
pager_buffer->used = 0;
}
static int print_max( const wchar_t *str, int max, int has_more )
{
int i;
int written = 0;
for( i=0; str[i]; i++ )
{
if( written + wcwidth(str[i]) > max )
break;
if( ( written + wcwidth(str[i]) == max) && (has_more || str[i+1]) )
{
writech( ellipsis_char );
written += wcwidth(ellipsis_char );
break;
}
writech( str[i] );
written+= wcwidth( str[i] );
}
return written;
}
static void completion_print_item( const wchar_t *prefix, comp_t *c, int width )
{
int comp_width=0, desc_width=0;
int i;
int written=0;
if( c->pref_width <= width )
{
/*
The entry fits, we give it as much space as it wants
*/
comp_width = c->comp_width;
desc_width = c->desc_width;
}
else
{
/*
The completion and description won't fit on the
allocated space. Give a maximum of 2/3 of the
space to the completion, and whatever is left to
the description.
*/
int desc_all = c->desc_width?c->desc_width+4:0;
comp_width = maxi( mini( c->comp_width,
2*(width-4)/3 ),
width - desc_all );
if( c->desc_width )
desc_width = width-comp_width-4;
else
c->desc_width=0;
}
for( i=0; i<al_get_count( c->comp ); i++ )
{
const wchar_t *comp = (const wchar_t *)al_get( c->comp, i );
if( i != 0 )
written += print_max( L" ", comp_width - written, 2 );
set_color( get_color(HIGHLIGHT_PAGER_PREFIX),FISH_COLOR_NORMAL );
written += print_max( prefix, comp_width - written, comp[0]?1:0 );
set_color( get_color(HIGHLIGHT_PAGER_COMPLETION),FISH_COLOR_IGNORE );
written += print_max( comp, comp_width - written, i!=(al_get_count(c->comp)-1) );
}
if( desc_width )
{
while( written < (width-desc_width-2))
{
written++;
writech( L' ');
}
written += print_max( L"(", 1, 0 );
set_color( get_color( HIGHLIGHT_PAGER_DESCRIPTION ),
FISH_COLOR_IGNORE );
written += print_max( c->desc, desc_width, 0 );
written += print_max( L")", 1, 0 );
}
else
{
while( written < width )
{
written++;
writech( L' ');
}
}
}
/**
Print the specified part of the completion list, using the
specified column offsets and quoting style.
@@ -219,277 +346,29 @@ static void completion_print( int cols,
int rows = (al_get_count( l )-1)/cols+1;
int i, j;
int prefix_width= my_wcswidth(prefix);
for( i = row_start; i<row_stop; i++ )
{
for( j = 0; j < cols; j++ )
{
wchar_t *el, *el_end;
comp_t *el;
int is_last = (j==(cols-1));
if( al_get_count( l ) <= j*rows + i )
continue;
el = (wchar_t *)al_get( l, j*rows + i );
el_end= wcschr( el, COMPLETE_SEP );
set_color( get_color(HIGHLIGHT_PAGER_PREFIX),FISH_COLOR_NORMAL );
writestr( prefix );
set_color( get_color(HIGHLIGHT_PAGER_COMPLETION),FISH_COLOR_IGNORE );
if( el_end == 0 )
{
/* We do not have a description for this completion */
int written = 0;
int max_written = width[j] - prefix_width - (j==cols-1?0:2);
if( is_quoted )
{
for( i=0; i<max_written; i++ )
{
if( !el[i] )
break;
writech( el[i] );
written+= wcwidth( el[i] );
}
}
else
{
written = write_escaped_str( el, max_written );
}
set_color( get_color( HIGHLIGHT_PAGER_DESCRIPTION ),
FISH_COLOR_IGNORE );
writespace( width[j]-
written-
prefix_width );
}
else
{
int whole_desc_width = my_wcswidth(el_end+1);
int whole_comp_width;
/*
Temporarily drop the description so that wcswidth et
al only calculate the width of the completion.
*/
*el_end = L'\0';
/*
Calculate preferred completion width
*/
if( is_quoted )
{
whole_comp_width = my_wcswidth(el);
}
else
{
wchar_t *tmp = escape( el, 1 );
whole_comp_width = my_wcswidth( tmp );
free(tmp);
}
/*
Calculate how wide this entry 'wants' to be
*/
int pref_width = whole_desc_width + 4 + prefix_width + 2 -
(j==cols-1?2:0) + whole_comp_width;
int comp_width, desc_width;
if( pref_width <= width[j] )
{
/*
The entry fits, we give it as much space as it wants
*/
comp_width = whole_comp_width;
desc_width = whole_desc_width;
}
else
{
/*
The completion and description won't fit on the
allocated space. Give a maximum of 2/3 of the
space to the completion, and whatever is left to
the description.
*/
int sum = width[j] - prefix_width - 4 - 2 + (j==cols-1?2:0);
comp_width = maxi( mini( whole_comp_width,
2*sum/3 ),
sum - whole_desc_width );
desc_width = sum-comp_width;
}
/* First we must print the completion. */
if( is_quoted )
{
writestr_ellipsis( el, comp_width);
}
else
{
write_escaped_str( el, comp_width );
}
/* Put the description back */
*el_end = COMPLETE_SEP;
/* And print it */
set_color( get_color(HIGHLIGHT_PAGER_DESCRIPTION),
FISH_COLOR_IGNORE );
writespace( maxi( 2,
width[j]
- comp_width
- desc_width
- 4
- prefix_width
+ (j==cols-1?2:0) ) );
/* Print description */
writestr(L"(");
writestr_ellipsis( el_end+1, desc_width);
writestr(L")");
if( j != cols-1)
writestr( L" " );
}
el = (comp_t *)al_get( l, j*rows + i );
completion_print_item( prefix, el, width[j] - (is_last?0:2) );
if( !is_last)
writestr( L" " );
}
writech( L'\n' );
}
}
/**
Calculates how long the specified string would be when printed on the command line.
\param str The string to be printed.
\param is_quoted Whether the string would be printed quoted or unquoted
\param pref_width the preferred width for this item
\param min_width the minimum width for this item
*/
static void printed_length( wchar_t *str,
int is_quoted,
int *pref_width,
int *min_width )
{
if( is_quoted )
{
wchar_t *sep = wcschr(str,COMPLETE_SEP);
if( sep )
{
*sep=0;
int cw = my_wcswidth( str );
int dw = my_wcswidth(sep+1);
if( termsize.ws_col > 80 )
dw = mini( dw, termsize.ws_col/3 );
*pref_width = cw+dw+4;
if( dw > termsize.ws_col/3 )
{
dw = termsize.ws_col/3;
}
*min_width=cw+dw+4;
*sep= COMPLETE_SEP;
return;
}
else
{
*pref_width=*min_width= my_wcswidth( str );
return;
}
}
else
{
int comp_len=0, desc_len=0;
int has_description = 0;
while( *str != 0 )
{
switch( *str )
{
case L'\n':
case L'\b':
case L'\r':
case L'\e':
case L'\t':
case L'\\':
case L'&':
case L'$':
case L' ':
case L'#':
case L'^':
case L'<':
case L'>':
case L'(':
case L')':
case L'[':
case L']':
case L'{':
case L'}':
case L'?':
case L'*':
case L'|':
case L';':
case L':':
case L'\'':
case L'"':
case L'%':
case L'~':
if( has_description )
desc_len++;
else
comp_len+=2;
break;
case COMPLETE_SEP:
has_description = 1;
break;
default:
if( has_description )
desc_len+= wcwidth(*str);
else
comp_len+= wcwidth(*str);
break;
}
str++;
}
if( has_description )
{
/*
Mangle long descriptions to make formating look nicer
*/
debug( 3, L"Desc, width = %d %d\n", comp_len, desc_len );
// if( termsize.ws_col > 80 )
// desc_len = mini( desc_len, termsize.ws_col/3 );
*pref_width = comp_len+ desc_len+4;;
comp_len = mini( comp_len, maxi(0,termsize.ws_col/3 - 2));
desc_len = mini( desc_len, maxi(0,termsize.ws_col/5 - 4));
*min_width = comp_len+ desc_len+4;
return;
}
else
{
debug( 3, L"No desc, width = %d\n", comp_len );
*pref_width=*min_width= comp_len;
return;
}
}
}
/**
Try to print the list of completions l with the prefix prefix using
@@ -537,8 +416,6 @@ static int completion_try_print( int cols,
int pref_tot_width=0;
int min_tot_width = 0;
int prefix_width = my_wcswidth( prefix );
int res=0;
/*
Skip completions on tiny terminals
@@ -546,25 +423,24 @@ static int completion_try_print( int cols,
if( termsize.ws_col < 16 )
return 1;
memset( pref_width, 0, sizeof(pref_width) );
memset( min_width, 0, sizeof(min_width) );
/* Calculated how wide the list would be */
/* Calculate how wide the list would be */
for( j = 0; j < cols; j++ )
{
for( i = 0; i<rows; i++ )
{
int pref,min;
wchar_t *el;
comp_t *c;
if( al_get_count( l ) <= j*rows + i )
continue;
el = (wchar_t *)al_get( l, j*rows + i );
printed_length( el, is_quoted, &pref, &min );
pref += prefix_width;
min += prefix_width;
c = (comp_t *)al_get( l, j*rows + i );
pref = c->pref_width;
min = c->min_width;
if( j != cols-1 )
{
pref += 2;
@@ -646,6 +522,7 @@ static int completion_try_print( int cols,
}
completion_print( cols, width, 0, rows, prefix, is_quoted, l);
pager_flush();
}
else
{
@@ -678,6 +555,7 @@ static int completion_try_print( int cols,
percent );
writestr(msg);
set_color( FISH_COLOR_NORMAL, FISH_COLOR_NORMAL );
pager_flush();
int c = readch();
switch( c )
@@ -739,7 +617,8 @@ static int completion_try_print( int cols,
}
else
{
writembs( flash_screen );
if( flash_screen )
writembs( flash_screen );
}
break;
@@ -763,7 +642,8 @@ static int completion_try_print( int cols,
}
else
{
writembs( flash_screen );
if( flash_screen )
writembs( flash_screen );
}
break;
}
@@ -791,7 +671,9 @@ static int completion_try_print( int cols,
}
/**
Substitute any series of tabs, newlines, etc. with a single space character in completion description
Substitute any series of whitespace with a single space character
inside completion descriptions. Remove all whitespace from
beginning/end of completion descriptions.
*/
static void mangle_descriptions( array_list_t *l )
{
@@ -800,7 +682,7 @@ static void mangle_descriptions( array_list_t *l )
{
wchar_t *next = (wchar_t *)al_get(l, i);
wchar_t *in, *out;
skip=0;
skip=1;
while( *next != COMPLETE_SEP && *next )
next++;
@@ -829,6 +711,125 @@ static void mangle_descriptions( array_list_t *l )
}
}
/**
Merge multiple completions with the same description to the same line
*/
static void join_completions( array_list_t *l )
{
int i, in, out;
hash_table_t desc_table;
hash_init( &desc_table, &hash_wcs_func, &hash_wcs_cmp );
for( i=0; i<al_get_count(l); i++ )
{
wchar_t *item = (wchar_t *)al_get( l, i );
wchar_t *desc = wcschr( item, COMPLETE_SEP );
long prev_idx;
if( !desc )
continue;
desc++;
prev_idx = ((long)hash_get( &desc_table, desc) )-1;
if( prev_idx == -1 )
{
hash_put( &desc_table, halloc_wcsdup( global_context, desc), (void *)(i+1));
}
else
{
string_buffer_t foo;
wchar_t *old = (wchar_t *)al_get( l, prev_idx );
wchar_t *old_end = wcschr( old, COMPLETE_SEP );
if( old_end )
{
*old_end = 0;
sb_init( &foo );
sb_append( &foo, old );
sb_append_char( &foo, COMPLETE_ITEM_SEP );
sb_append( &foo, item );
free( (void *)al_get( l, prev_idx ) );
al_set( l, prev_idx, foo.buff );
free( (void *)al_get( l, i ) );
al_set( l, i, 0 );
}
// debug( 1, L"WOOT WOOT %ls är släkt med %ls", item, al_get( l, prev_idx ) );
}
}
hash_destroy( &desc_table );
out=0;
for( in=0; in < al_get_count(l); in++ )
{
const void * d = al_get( l, in );
if( d )
{
al_set( l, out++, d );
}
}
al_truncate( l, out );
}
/**
Replace completion strings with a comp_t structure
*/
static void mangle_completions( array_list_t *l, const wchar_t *prefix )
{
int i;
for( i=0; i<al_get_count( l ); i++ )
{
wchar_t *next = (wchar_t *)al_get( l, i );
wchar_t *start, *end;
comp_t *comp = halloc( global_context, sizeof( comp_t ) );
comp->comp = al_halloc( global_context );
for( start=end=next; 1; end++ )
{
wchar_t c = *end;
if( (c == COMPLETE_ITEM_SEP) || (c==COMPLETE_SEP) || !c)
{
*end = 0;
wchar_t * str = escape( start, 1 );
comp->comp_width += my_wcswidth( str );
halloc_register( global_context, str );
al_push( comp->comp, str );
start = end+1;
}
if( c == COMPLETE_SEP )
{
comp->desc = halloc_wcsdup( global_context, start );
break;
}
if( !c )
break;
}
comp->comp_width += my_wcswidth(prefix)*al_get_count(comp->comp) + 2*(al_get_count(comp->comp)-1);
comp->desc_width = comp->desc?my_wcswidth( comp->desc ):0;
comp->pref_width = comp->comp_width + comp->desc_width + (comp->desc_width?4:0);
free( next );
al_set( l, i, comp );
}
recalc_width( l, prefix );
}
/**
Respond to a winch signal by checking the terminal size
*/
@@ -851,7 +852,11 @@ static void init()
struct sigaction act;
program_name = L"fish_pager";
wsetlocale( LC_ALL, L"" );
/*
Make fd 1 output to screen, and use some other fd for writing
the resulting output back to the caller
*/
int out = dup( 1 );
close(1);
if( open( ttyname(0), O_WRONLY ) != 1 )
@@ -863,11 +868,18 @@ static void init()
}
}
out_file = fdopen( out, "w" );
/**
Init the stringbuffer used to keep any output in
*/
sb_init( &out_buff );
output_init();
halloc_util_init();
env_universal_init( 0, 0, 0, 0);
input_common_init( &interrupt_handler );
output_set_writer( &pager_buffered_writer );
pager_buffer = halloc( global_context, sizeof( buffer_t ) );
halloc_register_function( global_context, (void (*)(void *))&b_destroy, pager_buffer );
sigemptyset( & act.sa_mask );
act.sa_flags=0;
@@ -880,33 +892,6 @@ static void init()
exit(1);
}
/* Loop until we are in the foreground. */
while (tcgetpgrp( 0 ) != getpid())
{
kill (- getpid(), SIGTTIN);
}
/* Put ourselves in our own process group. */
if( getpgrp() != getpid() )
{
if (setpgid (getpid(), getpid()) < 0)
{
debug( 1,
L"Couldn't put the shell in its own process group");
wperror( L"setpgid" );
exit (1);
}
}
/* Grab control of the terminal. */
if( tcsetpgrp (STDIN_FILENO, getpid()) )
{
debug( 1,
L"Couldn't grab control of terminal" );
wperror( L"tcsetpgrp" );
exit(1);
}
handle_winch( 0 ); /* Set handler for window change events */
tcgetattr(0,&pager_modes); /* get the current terminal modes */
@@ -919,6 +904,9 @@ static void init()
pager_modes.c_cc[VMIN]=1;
pager_modes.c_cc[VTIME]=0;
/*
*/
if( tcsetattr(0,TCSANOW,&pager_modes)) /* set the new modes */
{
wperror(L"tcsetattr");
@@ -937,45 +925,51 @@ void destroy()
{
env_universal_destroy();
input_common_destroy();
output_destroy();
halloc_util_destroy();
del_curterm( cur_term );
sb_destroy( &out_buff );
fclose( out_file );
}
int main( int argc, char **argv )
{
int i;
int is_quoted=0;
array_list_t comp;
array_list_t *comp;
wchar_t *prefix;
init();
if( argc < 3 )
{
debug( 0, L"Insufficient arguments" );
}
else
{
comp = al_halloc( global_context );
prefix = str2wcs( argv[2] );
is_quoted = strcmp( "1", argv[1] )==0;
is_quoted = 0;
debug( 3, L"prefix is '%ls'", prefix );
al_init( &comp );
for( i=3; i<argc; i++ )
{
al_push( &comp, str2wcs( argv[i] ) );
wchar_t *wcs = str2wcs( argv[i] );
if( wcs )
{
al_push( comp, wcs );
}
}
mangle_descriptions( comp );
if( wcscmp( prefix, L"-" ) == 0 )
join_completions( comp );
mangle_completions( comp, prefix );
mangle_descriptions( &comp );
for( i = 6; i>0; i-- )
{
switch( completion_try_print( i, prefix, is_quoted, &comp ) )
switch( completion_try_print( i, prefix, is_quoted, comp ) )
{
case 0:
break;
@@ -989,8 +983,6 @@ int main( int argc, char **argv )
}
al_foreach( &comp, (void(*)(const void *))&free );
al_destroy( &comp );
free(prefix );
fwprintf( out_file, L"%ls", (wchar_t *)out_buff.buff );

View File

@@ -41,6 +41,7 @@
#include "output.h"
#include "exec.h"
#include "event.h"
#include "halloc_util.h"
/**
Number of laps to run performance testing loop
@@ -327,7 +328,7 @@ static void sb_test()
sb_init( &b );
if( res=sb_printf( &b, L"%ls%s", L"Testing ", "string_buffer_t " ) == -1 )
if( (res=sb_printf( &b, L"%ls%s", L"Testing ", "string_buffer_t " )) == -1 )
{
err( L"Error %d while testing stringbuffers", res );
}
@@ -336,7 +337,22 @@ static void sb_test()
{
err( L"Error %d while testing stringbuffers", res );
}
say( (wchar_t *)b.buff );
sb_clear( &b );
#define NUM_ANS L"-7 99999999 1234567 deadbeef DEADBEEFDEADBEEF"
sb_printf( &b, L"%d %u %o %x %llX", -7, 99999999, 01234567, 0xdeadbeef, 0xdeadbeefdeadbeefll );
if( wcscmp( (wchar_t *)b.buff, NUM_ANS) != 0 )
{
err( L"numerical formating is broken, '%ls' != '%ls'", (wchar_t *)b.buff, NUM_ANS );
}
else
say( L"numerical formating works" );
}
/**
@@ -533,7 +549,7 @@ static int expand_test( const wchar_t *in, int flags, ... )
wchar_t *arg;
al_init( &out );
expand_string( wcsdup(in), &out, flags);
expand_string( 0, wcsdup(in), &out, flags);
va_start( va, flags );
@@ -669,7 +685,7 @@ int main( int argc, char **argv )
say( L"Lines beginning with '(ignore):' are not errors, they are warning messages\ngenerated by the fish parser library when given broken input, and can be\nignored. All actual errors begin with 'Error:'." );
proc_init();
output_init();
halloc_util_init();
event_init();
exec_init();
parser_init();
@@ -701,7 +717,7 @@ int main( int argc, char **argv )
wutil_destroy();
exec_destroy();
event_destroy();
output_destroy();
proc_destroy();
halloc_util_destroy();
}

View File

@@ -18,6 +18,9 @@
#include "intern.h"
#include "event.h"
#include "reader.h"
#include "parse_util.h"
#include "env.h"
#include "expand.h"
/**
@@ -32,6 +35,7 @@ typedef struct
const wchar_t *definition_file;
int definition_offset;
int is_binding;
int is_autoload;
}
function_data_t;
@@ -39,6 +43,79 @@ typedef struct
Table containing all functions
*/
static hash_table_t function;
static int is_autoload = 0;
/**
Make sure that if the specified function is a dynamically loaded
function, it has been fully loaded.
*/
static int load( const wchar_t *name )
{
int was_autoload = is_autoload;
int res;
function_data_t *data;
data = (function_data_t *)hash_get( &function, name );
if( data && !data->is_autoload )
return 0;
is_autoload = 1;
res = parse_util_load( name,
L"fish_function_path",
&function_remove,
1 );
is_autoload = was_autoload;
return res;
}
/**
Insert a list of all dynamically loaded functions into the
specified list.
*/
static void autoload_names( array_list_t *out, int get_hidden )
{
int i;
array_list_t path_list;
const wchar_t *path_var = env_get( L"fish_function_path" );
if( ! path_var )
return;
al_init( &path_list );
expand_variable_array( path_var, &path_list );
for( i=0; i<al_get_count( &path_list ); i++ )
{
wchar_t *ndir = (wchar_t *)al_get( &path_list, i );
DIR *dir = wopendir( ndir );
if( !dir )
continue;
struct wdirent *next;
while( (next=wreaddir(dir))!=0 )
{
wchar_t *fn = next->d_name;
wchar_t *suffix;
if( !get_hidden && fn[0] == L'_' )
continue;
suffix = wcsrchr( fn, L'.' );
if( suffix && (wcscmp( suffix, L".fish" ) == 0 ) )
{
const wchar_t *dup;
*suffix = 0;
dup = intern( fn );
if( !dup )
die_mem();
al_push( out, dup );
}
}
closedir(dir);
}
al_foreach( &path_list, (void (*)(const void *))&free );
al_destroy( &path_list );
}
/**
Free all contents of an entry to the function hash table
@@ -65,18 +142,6 @@ void function_destroy()
hash_destroy( &function );
}
static int count_lineno( const wchar_t *str, int len )
{
int res = 0;
int i;
for( i=0; i<len; i++ )
{
if( str[i] == L'\n' )
res++;
}
return res;
}
void function_add( const wchar_t *name,
const wchar_t *val,
@@ -86,16 +151,14 @@ void function_add( const wchar_t *name,
{
int i;
wchar_t *cmd_end;
function_data_t *d;
if( function_exists( name ) )
function_remove( name );
function_remove( name );
function_data_t *d = malloc( sizeof( function_data_t ) );
d->definition_offset = count_lineno( parser_get_buffer(), current_block->tok_pos );
d = malloc( sizeof( function_data_t ) );
d->definition_offset = parse_util_lineno( parser_get_buffer(), current_block->tok_pos );
d->cmd = wcsdup( val );
cmd_end = d->cmd + wcslen(d->cmd)-1;
while( (cmd_end>d->cmd) && wcschr( L"\n\r\t ", *cmd_end ) )
{
@@ -104,7 +167,9 @@ void function_add( const wchar_t *name,
d->desc = desc?wcsdup( desc ):0;
d->is_binding = is_binding;
d->definition_file = reader_current_filename()?intern(reader_current_filename()):0;
d->definition_file = intern(reader_current_filename());
d->is_autoload = is_autoload;
hash_put( &function, intern(name), d );
for( i=0; i<al_get_count( events ); i++ )
@@ -116,6 +181,10 @@ void function_add( const wchar_t *name,
int function_exists( const wchar_t *cmd )
{
if( parser_is_reserved(cmd) )
return 0;
load( cmd );
return (hash_get(&function, cmd) != 0 );
}
@@ -123,27 +192,28 @@ void function_remove( const wchar_t *name )
{
void *key;
function_data_t *d;
event_t ev;
ev.type=EVENT_ANY;
ev.function_name=name;
event_remove( &ev );
hash_remove( &function,
name,
(const void **) &key,
(const void **)&d );
if( !d )
if( !key )
return;
ev.type=EVENT_ANY;
ev.function_name=name;
event_remove( &ev );
clear_function_entry( key, d );
}
const wchar_t *function_get_definition( const wchar_t *argv )
{
function_data_t *data =
(function_data_t *)hash_get( &function, argv );
function_data_t *data;
load( argv );
data = (function_data_t *)hash_get( &function, argv );
if( data == 0 )
return 0;
return data->cmd;
@@ -151,8 +221,9 @@ const wchar_t *function_get_definition( const wchar_t *argv )
const wchar_t *function_get_desc( const wchar_t *argv )
{
function_data_t *data =
(function_data_t *)hash_get( &function, argv );
function_data_t *data;
load( argv );
data = (function_data_t *)hash_get( &function, argv );
if( data == 0 )
return 0;
@@ -161,8 +232,9 @@ const wchar_t *function_get_desc( const wchar_t *argv )
void function_set_desc( const wchar_t *name, const wchar_t *desc )
{
function_data_t *data =
(function_data_t *)hash_get( &function, name );
function_data_t *data;
load( name );
data = (function_data_t *)hash_get( &function, name );
if( data == 0 )
return;
@@ -185,6 +257,8 @@ static void get_names_internal( const void *key,
void function_get_names( array_list_t *list, int get_hidden )
{
autoload_names( list, get_hidden );
if( get_hidden )
hash_get_keys( &function, list );
else
@@ -194,8 +268,9 @@ void function_get_names( array_list_t *list, int get_hidden )
const wchar_t *function_get_definition_file( const wchar_t *argv )
{
function_data_t *data =
(function_data_t *)hash_get( &function, argv );
function_data_t *data;
load( argv );
data = (function_data_t *)hash_get( &function, argv );
if( data == 0 )
return 0;
@@ -205,13 +280,12 @@ const wchar_t *function_get_definition_file( const wchar_t *argv )
int function_get_definition_offset( const wchar_t *argv )
{
function_data_t *data =
(function_data_t *)hash_get( &function, argv );
function_data_t *data;
load( argv );
data = (function_data_t *)hash_get( &function, argv );
if( data == 0 )
return -1;
return data->definition_offset;
}

View File

@@ -69,8 +69,15 @@ int function_exists( const wchar_t *name );
void function_get_names( array_list_t *list,
int get_hidden );
/**
Returns tha absolute path of the file where the specified function
was defined. Returns 0 if the file was defined on the commandline.
*/
const wchar_t *function_get_definition_file( const wchar_t *name );
/**
Returns the linenumber where the definition of the specified function started
*/
int function_get_definition_offset( const wchar_t *name );
#endif

170
halloc.c Normal file
View File

@@ -0,0 +1,170 @@
/** \file halloc.c
A hierarchical memory allocation system. Works just like talloc
used in Samba, except that an arbitrary block allocated with
malloc() can be registered to be freed by halloc_free.
*/
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include "util.h"
#include "common.h"
#include "halloc.h"
#define HALLOC_BLOCK_SIZE 128
#define HALLOC_SCRAP_SIZE 16
#ifdef HALLOC_DEBUG
static int child_count=0;
static int child_size=0;
static int alloc_count =0;
static int alloc_spill = 0;
static pid_t pid=0;
static int parent_count=0;
#endif
typedef struct halloc
{
array_list_t children;
void *scratch;
size_t scratch_free;
long long data[0];
}
halloc_t;
static halloc_t *halloc_from_data( void *data )
{
return (halloc_t *)(data - sizeof( halloc_t ) );
}
static void late_free( void *data)
{
}
#ifdef HALLOC_DEBUG
static void woot()
{
if( getpid() == pid )
{
debug( 1, L"%d parents, %d children with average child size of %.2f bytes caused %d allocs, average spill of %.2f bytes",
parent_count, child_count, (double)child_size/child_count,
parent_count+alloc_count, (double)alloc_spill/(parent_count+alloc_count) );
}
}
#endif
void *halloc( void *context, size_t size )
{
halloc_t *me, *parent;
if( context )
{
void *res;
#ifdef HALLOC_DEBUG
if( !child_count )
{
pid = getpid();
atexit( woot );
}
child_count++;
child_size += size;
#endif
parent = halloc_from_data( context );
if( size <= parent->scratch_free )
{
res = parent->scratch;
parent->scratch_free -= size;
parent->scratch += size;
}
else
{
#ifdef HALLOC_DEBUG
alloc_count++;
#endif
if( parent->scratch_free < HALLOC_SCRAP_SIZE )
{
#ifdef HALLOC_DEBUG
alloc_spill += parent->scratch_free;
#endif
res = calloc( 1, size + HALLOC_BLOCK_SIZE );
parent->scratch = res + size;
parent->scratch_free = HALLOC_BLOCK_SIZE;
}
else
{
res = calloc( 1, size );
}
al_push( &parent->children, &late_free );
al_push( &parent->children, res );
}
return res;
}
else
{
me = (halloc_t *)calloc( 1, sizeof(halloc_t) + size + HALLOC_BLOCK_SIZE );
if( !me )
return 0;
#ifdef HALLOC_DEBUG
parent_count++;
#endif
me->scratch = ((void *)me) + sizeof(halloc_t) + size;
me->scratch_free = HALLOC_BLOCK_SIZE;
al_init( &me->children );
return &me->data;
}
}
void halloc_register_function( void *context, void (*func)(void *), void *data )
{
halloc_t *me;
if( !context )
return;
me = halloc_from_data( context );
al_push( &me->children, func );
al_push( &me->children, data );
}
void halloc_free( void *context )
{
halloc_t *me;
int i;
if( !context )
return;
me = halloc_from_data( context );
#ifdef HALLOC_DEBUG
alloc_spill += me->scratch_free;
#endif
for( i=0; i<al_get_count(&me->children); i+=2 )
{
void (*func)(void *) = (void (*)(void *))al_get( &me->children, i );
void * data = (void *)al_get( &me->children, i+1 );
if( func != &late_free )
func( data );
}
for( i=0; i<al_get_count(&me->children); i+=2 )
{
void (*func)(void *) = (void (*)(void *))al_get( &me->children, i );
void * data = (void *)al_get( &me->children, i+1 );
if( func == &late_free )
free( data );
}
al_destroy( &me->children );
free(me);
}

48
halloc.h Normal file
View File

@@ -0,0 +1,48 @@
/** \file halloc.h
A hierarchical memory allocation system. Works mostly like talloc
used in Samba, except that an arbitrary block allocated with
malloc() can be registered to be freed by halloc_free.
*/
#ifndef FISH_HALLOC_H
#define FISH_HALLOC_H
/**
Allocate new memory using specified parent memory context. Context
_must_ be either 0 or the result of a previous call to halloc.
If \c context is null, the resulting block is a root block, and
must be freed with a call to halloc_free().
If \c context is not null, context must be a halloc root block. the
resulting memory block is a child context, and must never be
explicitly freed, it will be automatically freed whenever the
parent context is freed. Child blocks can also never be used as the
context in calls to halloc_register_function, halloc_free, etc.
*/
void *halloc( void *context, size_t size );
/**
Make the specified function run whenever context is free'd, using data as argument.
\c context a halloc root block
*/
void halloc_register_function( void *context, void (*func)(void *), void *data );
/**
Free memory context and all children contexts. Only root contexts
may be freed explicitly.
All functions registered with halloc_register_function are run in
the order they where added. Afterwards, all memory allocated using
halloc itself is free'd.
\c context a halloc root block
*/
void halloc_free( void *context );
#endif

94
halloc_util.c Normal file
View File

@@ -0,0 +1,94 @@
/** \file halloc.c
A hierarchical memory allocation system. Works just like talloc
used in Samba, except that an arbitrary block allocated with
malloc() can be registered to be freed by halloc_free.
*/
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "util.h"
#include "common.h"
#include "halloc.h"
void *global_context=0;
void halloc_util_init()
{
global_context = halloc( 0, 0 );
}
void halloc_util_destroy()
{
halloc_free( global_context );
}
array_list_t *al_halloc( void *context )
{
array_list_t *res = halloc( context, sizeof( array_list_t ) );
if( !res )
die_mem();
al_init( res );
halloc_register_function( context, (void (*)(void *)) &al_destroy, res );
return res;
}
string_buffer_t *sb_halloc( void *context )
{
string_buffer_t *res = halloc( context, sizeof( string_buffer_t ) );
if( !res )
die_mem();
sb_init( res );
halloc_register_function( context, (void (*)(void *)) &sb_destroy, res );
return res;
}
static void halloc_passthrough( void *f )
{
void (*func)() = (void (*)() )f;
func();
}
void halloc_register_function_void( void *context, void (*func)() )
{
halloc_register_function( context, &halloc_passthrough, (void *)func );
}
void *halloc_register( void *context, void *data )
{
if( !data )
return 0;
halloc_register_function( context, &free, data );
return data;
}
wchar_t *halloc_wcsdup( void *context, wchar_t *in )
{
size_t len=wcslen(in);
wchar_t *out = halloc( context, sizeof( wchar_t)*(len+1));
if( out == 0 )
{
die_mem();
}
memcpy( out, in, sizeof( wchar_t)*(len+1));
return out;
}
wchar_t *halloc_wcsndup( void * context, const wchar_t *in, int c )
{
wchar_t *res = halloc( context, sizeof(wchar_t)*(c+1) );
if( res == 0 )
{
die_mem();
}
wcslcpy( res, in, c+1 );
res[c] = L'\0';
return res;
}

66
halloc_util.h Normal file
View File

@@ -0,0 +1,66 @@
/**
\file halloc_util.h
Various halloc-related utility functions.
*/
#ifndef FISH_HALLOC_UTIL_H
#define FISH_HALLOC_UTIL_H
/**
This pointer is a valid halloc context that will be freed right
before program shutdown. It may be used to allocate memory that
should be freed when the program shuts down.
*/
extern void *global_context;
/**
Create the global_context halloc object
*/
void halloc_util_init();
/**
Free the global_context halloc object
*/
void halloc_util_destroy();
/**
Allocate a array_list_t that will be automatically disposed of when
the specified context is free'd
*/
array_list_t *al_halloc( void *context );
/**
Allocate a string_buffer_t that will be automatically disposed of
when the specified context is free'd
*/
string_buffer_t *sb_halloc( void *context );
/**
Register the specified function to run when the specified context
is free'd. This function is related to halloc_register_function,
but the specified function dowes not take an argument.
*/
void halloc_register_function_void( void *context, void (*func)() );
/**
Free the memory pointed to by \c data when the memory pointed to by
\c context is free:d. Note that this will _not_ turn the specified
memory area into a valid halloc context. Only memory areas created
using a call to halloc( 0, size ) can be used as a context.
*/
void *halloc_register( void *context, void *data );
/**
Make a copy of the specified string using memory allocated using
halloc and the specified context
*/
wchar_t *halloc_wcsdup( void *context, wchar_t *str );
/**
Make a copy of the specified substring using memory allocated using
halloc and the specified context
*/
wchar_t *halloc_wcsndup( void * context, const wchar_t *in, int c );
#endif

View File

@@ -18,6 +18,7 @@
#include "tokenizer.h"
#include "proc.h"
#include "parser.h"
#include "parse_util.h"
#include "builtin.h"
#include "function.h"
#include "env.h"
@@ -129,10 +130,10 @@ void highlight_shell( wchar_t * buff,
/*
Command. First check that the command actually exists.
*/
wchar_t *cmd =
(last_type == TOK_STRING) ?
expand_one(wcsdup(tok_last( &tok )),EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES) :
wcsdup(tok_last( &tok ));
wchar_t *cmd = expand_one( 0,
wcsdup(tok_last( &tok )),
EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES);
if( cmd == 0 )
{
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_ERROR;
@@ -144,7 +145,6 @@ void highlight_shell( wchar_t * buff,
int is_subcommand = 0;
int mark = tok_get_pos( &tok );
color[ tok_get_pos( &tok ) ] = HIGHLIGHT_COMMAND;
if( parser_is_subcommand( cmd ) )
{
@@ -247,7 +247,7 @@ void highlight_shell( wchar_t * buff,
{
case TOK_STRING:
{
target = expand_one( wcsdup( tok_last( &tok ) ), EXPAND_SKIP_SUBSHELL);
target = expand_one( 0, wcsdup( tok_last( &tok ) ), EXPAND_SKIP_SUBSHELL);
/*
Redirect filename may contain a subshell.
If so, it will be ignored/not flagged.
@@ -365,11 +365,11 @@ void highlight_shell( wchar_t * buff,
while( 1 )
{
wchar_t *begin, *end;
if( expand_locate_subshell( subpos,
&begin,
&end,
1) <= 0)
if( parse_util_locate_cmdsubst( subpos,
(const wchar_t **)&begin,
(const wchar_t **)&end,
1) <= 0)
{
break;
}

View File

@@ -19,6 +19,7 @@
#include "reader.h"
#include "env.h"
#include "sanity.h"
#include "signal.h"
/*
The history is implemented using a linked list. Searches are done
@@ -45,6 +46,8 @@ typedef struct
The last item loaded from file
*/
ll_node_t *last_loaded;
int is_loaded;
}
history_data;
@@ -82,25 +85,31 @@ static wchar_t *mode_name;
*/
static hash_table_t history_table;
/**
Flag, set to 1 once the history file has been loaded
*/
static int is_loaded;
/**
Load history from ~/.fish_history
Load history from file
*/
static void history_load( wchar_t *name )
static void history_load()
{
wchar_t *fn;
wchar_t *buff=0;
int buff_len=0;
FILE *in_stream;
hash_table_t used;
block();
is_loaded = 1;
signal_block();
hash_init2( &used,
&hash_wcs_func,
&hash_wcs_cmp,
4096 );
fn = wcsdupcat2( env_get(L"HOME"), L"/.", name, L"_history", 0 );
fn = wcsdupcat2( env_get(L"HOME"), L"/.", mode_name, L"_history", 0 );
in_stream = wfopen( fn, "r" );
@@ -111,12 +120,12 @@ static void history_load( wchar_t *name )
int buff_read = fgetws2( &buff, &buff_len, in_stream );
if( buff_read == -1 )
{
debug( 1, L"The following non-fatal error occurred while reading command history from \'%ls\':", name );
debug( 1, L"The following non-fatal error occurred while reading command history from \'%ls\':", mode_name );
wperror( L"fgetws2" );
fclose( in_stream );
free( fn );
free( buff );
unblock();
signal_unblock();
return;
}
@@ -161,7 +170,7 @@ static void history_load( wchar_t *name )
{
if( errno != ENOENT )
{
debug( 1, L"The following non-fatal error occurred while reading command history from \'%ls\':", name );
debug( 1, L"The following non-fatal error occurred while reading command history from \'%ls\':", mode_name );
wperror( L"fopen" );
}
@@ -173,7 +182,7 @@ static void history_load( wchar_t *name )
free( buff );
free( fn );
last_loaded = history_last;
unblock();
signal_unblock();
}
void history_init()
@@ -198,6 +207,7 @@ static void history_to_hash()
d->last=history_last;
d->last_loaded=last_loaded;
d->count=history_count;
d->is_loaded = is_loaded;
hash_put( &history_table,
mode_name,
@@ -223,13 +233,14 @@ void history_set_mode( wchar_t *name )
history_current = history_last = curr->last;
last_loaded = curr->last_loaded;
history_count = curr->count;
is_loaded = curr->is_loaded;
}
else
{
history_count=0;
history_last = history_current = last_loaded=0;
mode_name = wcsdup( name );
history_load( name );
is_loaded = 0;
}
past_end=1;
@@ -259,6 +270,9 @@ static void history_save()
/* First we save this sessions history in local variables */
ll_node_t *real_pos = history_last, *real_first = last_loaded;
if( !is_loaded )
return;
if( !real_first )
{
real_first = history_current;
@@ -390,6 +404,9 @@ void history_destroy()
*/
static ll_node_t *history_find( ll_node_t *n, const wchar_t *s )
{
if( !is_loaded )
history_load();
if( n == 0 )
return 0;
@@ -406,6 +423,9 @@ void history_add( const wchar_t *str )
{
ll_node_t *old_node;
if( !is_loaded )
history_load();
if( wcslen( str ) == 0 )
return;
@@ -460,6 +480,9 @@ static int history_test( const wchar_t *needle, const wchar_t *haystack )
const wchar_t *history_prev_match( const wchar_t *str )
{
if( !is_loaded )
history_load();
if( history_current == 0 )
return str;
@@ -481,6 +504,9 @@ const wchar_t *history_prev_match( const wchar_t *str )
const wchar_t *history_next_match( const wchar_t *str)
{
if( !is_loaded )
history_load();
if( history_current == 0 )
return str;
@@ -507,15 +533,21 @@ void history_reset()
*/
void history_first()
{
while( history_current->prev )
history_current = history_current->prev;
if( is_loaded )
while( history_current->prev )
history_current = history_current->prev;
}
wchar_t *history_get( int idx )
{
ll_node_t *n=history_last;
ll_node_t *n;
int i;
if( !is_loaded )
history_load();
n = history_last;
if( idx<0)
{
debug( 1, L"Tried to access negative history index %d", idx );

View File

@@ -8,7 +8,8 @@
#include <wchar.h>
/**
Load history from file.
Init history library. The history file won't actually be loaded
until the first time a history search is performed.
*/
void history_init();

View File

@@ -1,2 +0,0 @@
complete -y btdownloadheadless.py

View File

@@ -1,33 +0,0 @@
# Bittorrent commands
for i in btdownloadcurses.py btdownloadheadless.py;
complete -c $i -l max_uploads -x -d (_ "Maximum uploads at once")
complete -c $i -l keepalive_interval -x -d (_ "Number of seconds between keepalives")
complete -c $i -l download_slice_size -x -d (_ "Bytes per request")
complete -c $i -l request_backlog -x -d (_ "Requests per pipe")
complete -c $i -l max_message_length -x -d (_ "Maximum length prefix encoding")
complete -c $i -l ip -d (_ "IP to report to the tracker") -x -a "(__fish_print_addresses)"
complete -c $i -l minport -d (_ "Minimum port to listen to")
complete -c $i -l maxport -d (_ "Maximum port to listen to")
complete -c $i -l responsefile -r -d (_ "File for server response")
complete -c $i -l url -x -d (_ "URL to get file from")
complete -c $i -l saveas -r -d (_ "Local file target")
complete -c $i -l timeout -x -d (_ "Time to close inactive socket")
complete -c $i -l timeout_check_interval -x -d (_ "Time between checking timeouts")
complete -c $i -l max_slice_length -x -d (_ "Maximum outgoing slice length")
complete -c $i -l max_rate_period -x -d (_ "Maximum time to guess rate")
complete -c $i -l bind -x -d (_ "IP to bind to locally") -a "(__fish_print_addresses)"
complete -c $i -l display_interval -x -d (_ "Time between screen updates")
complete -c $i -l rerequest_interval -x -d (_ "Time to wait between requesting more peers")
complete -c $i -l min_peers -x -d (_ "Minimum number of peers to not do requesting")
complete -c $i -l http_timeout -x -d (_ "Number of seconds before assuming http timeout")
complete -c $i -l max_initiate -x -d (_ "Number of peers at which to stop initiating new connections")
complete -c $i -l max_allow_in -x -d (_ "Maximum number of connections to allow")
complete -c $i -l check_hashes -x -d (_ "Whether to check hashes on disk")
complete -c $i -l max_upload_rate -x -d (_ "Maximum kB/s to upload at")
complete -c $i -l snub_time -x -d (_ "Seconds to wait for data to come in before assuming choking")
complete -c $i -l spew -x -d (_ "Whether to display diagnostic info")
complete -c $i -l rarest_first_cutoff -x -d (_ "Number of downloads at which to switch from random to rarest first")
complete -c $i -l min_uploads -x -d (_ "Number of uploads to fill out to with optimistic unchokes")
complete -c $i -l report_hash_failiures -x -d (_ "Whether to inform the user that hash failures occur")
end;

View File

@@ -1,53 +0,0 @@
#
# I don't use CVS, so these completions are probably not all that good.
#
complete -c cvs -x -a 'add' -d (_ "Add a new file/directory to the repository")
complete -c cvs -x -a 'admin' -d (_ "Administration front end for rcs")
complete -c cvs -x -a 'annotate' -d (_ "Show last revision where each line was modified")
complete -c cvs -x -a 'checkout' -d (_ "Checkout sources for editing")
complete -c cvs -x -a 'commit' -d (_ "Check files into the repository")
complete -c cvs -x -a 'diff' -d (_ "Show differences between revisions")
complete -c cvs -x -a 'edit' -d (_ "Get ready to edit a watched file")
complete -c cvs -x -a 'editors' -d (_ "See who is editing a watched file")
complete -c cvs -x -a 'export' -d (_ "Export sources from CVS, similar to checkout")
complete -c cvs -x -a 'history' -d (_ "Show repository access history")
complete -c cvs -x -a 'import' -d (_ "Import sources into CVS, using vendor branches")
complete -c cvs -x -a 'init' -d (_ "Create a CVS repository if it doesnt exist")
complete -c cvs -x -a 'kserver' -d (_ "Kerberos server mode")
complete -c cvs -x -a 'log' -d (_ "Print out history information for files")
complete -c cvs -x -a 'login' -d (_ "Prompt for password for authenticating server")
complete -c cvs -x -a 'logout' -d (_ "Removes entry in .cvspass for remote repository")
complete -c cvs -x -a 'pserver' -d (_ "Password server mode")
complete -c cvs -x -a 'rannotate' -d (_ "Show last revision where each line of module was modified")
complete -c cvs -x -a 'rdiff' -d (_ "Create "patch" format diffs between releases")
complete -c cvs -x -a 'release' -d (_ "Indicate that a Module is no longer in use")
complete -c cvs -x -a 'remove' -d (_ "Remove an entry from the repository")
complete -c cvs -x -a 'rlog' -d (_ "Print out history information for a module")
complete -c cvs -x -a 'rtag' -d (_ "Add a symbolic tag to a module")
complete -c cvs -x -a 'server' -d (_ "Server mode")
complete -c cvs -x -a 'status' -d (_ "Display status information on checked out files")
complete -c cvs -x -a 'tag' -d (_ "Add a symbolic tag to checked out version of files")
complete -c cvs -x -a 'unedit' -d (_ "Undo an edit command")
complete -c cvs -x -a 'update' -d (_ "Bring work tree in sync with repository")
complete -c cvs -x -a 'version' -d (_ "Display version and exit")
complete -c cvs -x -a 'watch' -d (_ "Set watches")
complete -c cvs -x -a 'watchers' -d (_ "See who is watching a file")
complete -c cvs -x -s H -d (_ "Displays usage information for command")
complete -c cvs -x -s Q -d (_ "Cause CVS to be really quiet")
complete -c cvs -x -s q -d (_ "Cause CVS to be somewhat quiet")
complete -c cvs -x -s r -d (_ "Make checked-out files read-only")
complete -c cvs -x -s w -d (_ "Make checked-out files read-write (default)")
complete -c cvs -x -s n -d (_ "Do not execute anything that will change the disk")
complete -c cvs -x -s t -d (_ "Show trace of program execution -- try with -n")
complete -c cvs -x -s v -d (_ "Display version and exit")
complete -c cvs -x -s T -r -d (_ "Use "tmpdir" for temporary files")
complete -c cvs -x -s e -r -d (_ "Use "editor" for editing log information")
complete -c cvs -x -s d -r -d (_ "Overrides $CVSROOT as the root of the CVS tree")
complete -c cvs -x -s f -d (_ "Do not use the ~/.cvsrc file")
complete -c cvs -x -s z -d (_ "Compression level for net traffic") -x -a '1 2 3 4 5 6 7 8 9'
complete -c cvs -x -s x -d (_ "Encrypt all net traffic")
complete -c cvs -x -s a -d (_ "Authenticate all net traffic")
complete -c cvs -x -s s -d (_ "Set CVS user variable") -x

View File

@@ -1 +0,0 @@
complete -y tex

View File

@@ -1 +0,0 @@
complete -y tex

View File

@@ -1,2 +0,0 @@
complete -y ls

View File

@@ -1 +0,0 @@
complete -y tex

View File

@@ -1,2 +0,0 @@
complete -y ls

View File

@@ -1,105 +0,0 @@
#
# Completions for the ls command and its aliases
#
# Test if we are using GNU ls
set -l is_gnu
ls --version >/dev/null ^/dev/null; and set is_gnu --is-gnu
set -l cmds -c ls -c ll -c la
# Shared ls switches
__fish_gnu_complete $cmds -s a -l all -d (_ "Show hidden") $is_gnu
__fish_gnu_complete $cmds -s A -l almost-all -d (_ "Show hidden except . and ..") $is_gnu
__fish_gnu_complete $cmds -s F -l classify -d (_ "Append filetype indicator") $is_gnu
__fish_gnu_complete $cmds -s H -l dereference-command-line -d (_ "Follow symlinks") $is_gnu
__fish_gnu_complete $cmds -s L -l dereference -d (_ "Follow symlinks") $is_gnu
__fish_gnu_complete $cmds -s R -l recursive -d (_ "List subdirectory recursively") $is_gnu
__fish_gnu_complete $cmds -s b -l escape -d (_ "Octal escapes for non graphic characters") $is_gnu
__fish_gnu_complete $cmds -s d -l directory -d (_ "List directories, not their content") $is_gnu
__fish_gnu_complete $cmds -s h -l human-readable -d (_ "Human readable sizes") $is_gnu
__fish_gnu_complete $cmds -s i -l inode -d (_ "Print inode number of files") $is_gnu
__fish_gnu_complete $cmds -s n -l numeric-uid-gid -d (_ "Long format, numeric IDs") $is_gnu
__fish_gnu_complete $cmds -s p -l file-type -d (_ "Append filetype indicator") $is_gnu
__fish_gnu_complete $cmds -s q -l hide-control-chars -d (_ "Replace non-graphic characters with '?'") $is_gnu
__fish_gnu_complete $cmds -s r -l reverse -d (_ "Reverse sort order") $is_gnu
__fish_gnu_complete $cmds -s s -l size -d (_ "Print size of files") $is_gnu
complete $cmds -s C -d (_ "List by columns")
complete $cmds -s S -d (_ "Sort by size")
complete $cmds -s c -d (_ "Show and sort by ctime")
complete $cmds -s f -d (_ "Don't sort")
complete $cmds -s g -d (_ "Long format without owner")
complete $cmds -s k -d (_ "Set blocksize to 1kB")
complete $cmds -s l -d (_ "Long format")
complete $cmds -s m -d (_ "Comma separated format")
complete $cmds -s t -d (_ "Sort by modification time")
complete $cmds -s u -d (_ "Show access time")
complete $cmds -s x -d (_ "List entries by lines")
complete $cmds -s 1 -d (_ "List one file per line")
if test -n "$is_gnu"
# GNU specific features
complete $cmds -l author -d (_ "Print author")
complete $cmds -l blocksize -x -d (_ "Set block size")
complete $cmds -s B -l ignore-backups -d (_ "Ignore files ending with ~")
complete $cmds -l color -f -a "never always auto" -d (_ "Use colors")
complete $cmds -s D -l dired -d (_ "Generate dired output")
complete $cmds -l format -x -a "across commas horizontal long single-column verbose vertical" -d (_ "List format")
complete $cmds -l full-time -d (_ "Long format, full-iso time")
complete $cmds -s G -l no-group -d (_ "Don't print group information")
complete $cmds -l si -d (_ "Human readable sizes, powers of 1000")
complete $cmds -l dereference-command-line-symlink-to-dir #-d (_ "Follow directory symlinks from command line")
complete $cmds -l indicator-style -x -a "none classify file-type" -d (_ "Append filetype indicator")
complete $cmds -s I -l ignore -r -d (_ "Skip entries matching pattern")
complete $cmds -s N -l literal -d (_ "Print raw entry names")
complete $cmds -s o -d (_ "Long format without groups")
complete $cmds -l show-control-chars -d (_ "Non graphic as-is")
complete $cmds -s Q -l quote-name -d (_ "Enclose entry in quotes")
complete $cmds -l quoting-style -x -a "literal locale shell shell-always c escape" -d (_ "Select quoting style")
complete $cmds -l sort -x -d (_ "Sort criteria") -a "
extension\t'Sort by file extension'
none\tDon't\ sort
size\t'Sort by size'
time\t'Sort by modification time'
version\t'Sort by version'
status\t'Sort by file status modification time'
atime\t'Sort by access time'
access\t'Sort by access time'
use\t'Sort by access time'
"
complete $cmds -l time -x -d (_ "Show time type") -a "
time\t'Sort by modification time'
access\t'Sort by access time'
use\t'Sort by use time'
ctime\t'Sort by file status modification time'
status\t'Sort by status time'
"
complete $cmds -l time-style -x -a "full-iso long-iso iso locale" -d (_ "Select time style")
complete $cmds -s T -l tabsize -x -a "1 2 3 4 5 6 7 8 9 10 11 12" -d (_ "Assume tab stops at each COLS")
complete $cmds -s U -d (_ "Do not sort")
complete $cmds -s v -d (_ "Sort by version")
complete $cmds -s w -l width -x -d (_ "Assume screen width")
complete $cmds -s X -d (_ "Sort by extension")
complete $cmds -l help -d (_ "Display help and exit")
complete $cmds -l version -d (_ "Display version and exit")
else
# If not a GNU system, assume we have standard BSD ls features instead
complete $cmds -s B -d (_ "Octal escapes for non graphic characters")
complete $cmds -s G -d (_ "Use colors")
complete $cmds -s I -d (_ "Prevent -A from being automatically set for root")
complete $cmds -s P -d (_ "Don't follow symlinks")
complete $cmds -s T -d (_ "Show modification time")
complete $cmds -s W -d (_ "Show whiteouts when scanning directories")
complete $cmds -s Z -d (_ "Display each file's MAC label")
complete $cmds -s o -d (_ "Include the file flags in a long (-l) output")
complete $cmds -s w -d (_ "Print raw entry names")
end

View File

@@ -1 +0,0 @@
complete -y tex

View File

@@ -1 +0,0 @@
complete -y tex

View File

@@ -1 +0,0 @@
complete -y tex

View File

@@ -1 +0,0 @@
complete -y tex

View File

@@ -1 +0,0 @@
complete -y tex

View File

@@ -1,10 +0,0 @@
#
# Completion for sudo
#
# Generate a list of commands
#
complete -c sudo -d (_ "Command to run") -x -a "(__fish_complete_commands)"
complete -c sudo -s h -d (_ "Display help and exit")
complete -c sudo -s v -d (_ "Validate")

View File

@@ -1,7 +0,0 @@
set -l cmds -c etex -c tex -c elatex -c latex -c pdflatex -c pdfelatex -c pdftex -c pdfetex -c omega
complete $cmds -o help -d (_ "Display help and exit")
complete $cmds -o version -d (_ "Display version and exit")
complete $cmds -x -a "(
__fish_complete_suffix (commandline -ct) .tex '(La)TeX file'
)"

View File

@@ -1,11 +0,0 @@
complete -c time -a "(__fish_complete_command)" -d (_ "Command")
complete -c time -s f -l format -d (_ "Specify output format") -x
complete -c time -s p -l portable -d (_ "Use the portable output format")
complete -c time -s o -l output -d (_ "Do not send the results to stderr, but overwrite the specified file") -r
complete -c time -s a -l append -d (_ "(Used together with -o) Do not overwrite but append")
complete -c time -s v -l verbose -d (_ "Verbose mode")
complete -c time -l help -d (_ "Display help and exit")
complete -c time -s V -l version -d (_ "Display version and exit")

View File

@@ -1,306 +0,0 @@
# Main file for fish command completions. This file contains various
# common helper functions for the command completions. All actual
# completions are located in the completions subdirectory.
#
# Don't need completions in non-interactive mode
#
if not status --is-interactive
exit
end
set -g fish_complete_path @SYSCONFDIR@/fish.d/completions ~/.fish.d/completions
# Knowing the location of the whatis database speeds up command
# description lookup.
for i in /var/cache/man/{whatis,windex} /usr{,/local}{,/share}/man/{whatis,windex}
if test -f $i
set -g __fish_whatis_path $i
break
end
end
#
# Convenience functions
#
# The naming heuristic is that __fish_complete_* prints completions
# and descriptions, while __fish_print_* only prints the completion,
# without the description
#
#
# Find files that complete $argv[1], has the suffix $argv[2], and
# output them as completions with description $argv[3]
#
function __fish_complete_suffix -d "Complete using files"
set -- comp $argv[1]
set -- suff $argv[2]
set -- desc $argv[3]
set -- base (echo $comp |sed -e 's/\.[a-zA-Z0-9]*$//')
eval "set -- files $base*$suff"
if test $files[1]
printf "%s\t$desc\n" $files
end
#
# Also do directory completion, since there might be files
# with the correct suffix in a subdirectory
#
__fish_complete_directory $comp
end
#
# Find directories that complete $argv[1], output them as completions
# with description $argv[2] if defined, otherwise use 'Directory'
#
function __fish_complete_directory -d "Complete using directories"
set -- comp $argv[1]
set -- desc (_ Directory)
if test (count $argv) -gt 1
set desc $argv[2]
end
eval "set -- dirs "$comp"*/"
if test $dirs[1]
printf "%s\t$desc\n" $dirs
end
end
function __fish_complete_users -d "Print a list of local users, with the real user name as a description"
cat /etc/passwd | sed -e "s/^\([^:]*\):[^:]*:[^:]*:[^:]*:\([^:]*\):.*/\1\t\2/"
end
function __fish_complete_groups -d "Print a list of local groups, with group members as the description"
cat /etc/group | sed -e "s/^\([^:]*\):[^:]*:[^:]*:\(.*\)/\1\tMembers: \2/"
end
function __fish_complete_pids -d "Print a list of process identifiers along with brief descriptions"
# This may be a bit slower, but it's nice - having the tty displayed is really handy
ps --no-heading -o pid,comm,tty --ppid %self -N | sed -r 's/ *([0-9]+) +([^ ].*[^ ]|[^ ]) +([^ ]+)$/\1\t\2 [\3]/' ^/dev/null
# If the above is too slow, this is faster but a little less useful
# pgrep -l -v -P %self | sed 's/ /\t/'
end
function __fish_complete_command -d "Complete using all available commands"
for i in $PATH; command ls $i; end
end
function __fish_print_hostnames -d "Print a list of known hostnames"
# Print all hosts from /etc/hosts
cat /etc/hosts|sed -e 's/[0-9.]*\( \|\t\)*\(.*\)/\2/'|sed -e 's/\#.*//'|sed -e 'y/\t/\n/'|grep -v '^$'
# Print nfs servers from /etc/fstab
cat /etc/fstab| grep "^\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\|[a-zA-Z.]*\):"|cut -d : -f 1
# Print hosts with known ssh keys
cat ~/.ssh/known_hosts{,2} ^/dev/null|cut -d ' ' -f 1| cut -d , -f 1
end
function __fish_print_interfaces -d "Print a list of known network interfaces"
netstat -i -n -a | awk 'NR>2'|awk '{print $1}'
end
function __fish_print_addresses -d "Print a list of known network addresses"
/sbin/ifconfig |grep 'inet addr'|cut -d : -f 2|cut -d ' ' -f 1
end
function __fish_print_users -d "Print a list of local users"
cat /etc/passwd | cut -d : -f 1
end
function __fish_contains_opt -d "Checks if a specific option has been given in the current commandline"
set -l next_short
set -l short_opt
set -l long_opt
for i in $argv
if test $next_short
set next_short
set -- short_opt $short_opt $i
else
switch $i
case -s
set next_short 1
case '-*'
echo __fish_contains_opt: Unknown option $i
return 1
case '**'
set -- long_opt $long_opt $i
end
end
end
for i in $short_opt
if test -z $i
continue
end
if commandline -cpo | grep -- "^-"$i"\|^-[^-]*"$i >/dev/null
return 0
end
if commandline -ct | grep -- "^-"$i"\|^-[^-]*"$i >/dev/null
return 0
end
end
for i in $long_opt
if test -z $i
continue
end
if contains -- --$i (commandline -cpo)
return 0
end
end
return 1
end
#
# Completions for the shell and it's builtin commands and functions
#
set -l __fish_help_desc (_ "Display help and exit")
for i in (builtin -n|grep -vE '(while|for|if|function|switch)' )
complete -c $i -s h -l help -d $__fish_help_desc
end
function __fish_print_packages
# apt-cache is much, much faster than rpm, and can do this in real
# time. We use it if available.
switch (commandline -tc)
case '-**'
return
end
#Get the word 'Package' in the current language
set -l package (_ Package)
if which apt-cache >/dev/null ^/dev/null
# Apply the following filters to output of apt-cache:
# 1) Remove package names with parentesis in them, since these seem to not correspond to actual packages as reported by rpm
# 2) Remove package names that are .so files, since these seem to not correspond to actual packages as reported by rpm
# 3) Remove path information such as /usr/bin/, as rpm packages do not have paths
apt-cache --no-generate pkgnames (commandline -tc)|grep -v \( |grep -v '\.so\(\.[0-9]\)*$'|sed -e 's/\/.*\///'|sed -e 's/$/\t'$package'/'
return
end
# Rpm is too slow for this job, so we set it up to do completions
# as a background job and cache the results.
if which rpm >/dev/null ^/dev/null
# If the cache is less than five minutes old, we do not recalculate it
set cache_file /tmp/.rpm-cache.$USER
if test -f $cache_file
cat $cache_file
set age (echo (date +%s) - (stat -c '%Y' $cache_file) | bc)
set max_age 250
if test $age -lt $max_age
return
end
end
# Remove package version information from output and pipe into cache file
rpm -qa >$cache_file |sed -e 's/-[^-]*-[^-]*$//' | sed -e 's/$/\t'$package'/' &
end
# This completes the package name from the portage tree.
# True for installing new packages. Function for printing
# installed on the system packages is in completions/emerge.fish
if which emerge >/dev/null ^/dev/null
emerge -s \^(commandline -tc) |grep "^*" |cut -d\ -f3 |cut -d/ -f2
return
end
end
function __fish_append -d "Internal completion function for appending string to the commandline"
set separator $argv[1]
set -e argv[1]
set str (commandline -tc| sed -ne "s/\(.*$separator\)[^$separator]*/\1/p"|sed -e "s/--.*=//")
printf "%s\n" "$str"$argv "$str"(printf "%s\n" $argv|sed -e "s/\(\t\|\$\)/,\1/")
end
function __fish_gnu_complete -d "Wrapper for the complete builtin. Skips the long completions on non-GNU systems"
set is_gnu 0
# Check if we are using a gnu system
for i in (seq (count $argv))
switch $argv[$i]
case -g --is-gnu
set -e argv[$i]
set is_gnu 1
break
end
end
# Remove long option if not on a gnu system
if test $is_gnu = 0
for i in (seq (count $argv))
if test $argv[$i] = -l
set -e argv[$i]
set -e argv[$i]
break
end
end
end
complete $argv
end
function __fish_is_first_token -d 'Test if no non-switch argument has been specified yet'
set -- cmd (commandline -poc)
set -e -- cmd[1]
for i in $cmd
switch $i
case '-*'
case '*'
return 1;
end
end
return 0
end
#
# Completions for SysV startup scripts
#
complete -x -p "/etc/init.d/*" -a start\t(_ 'Start service')
complete -x -p "/etc/init.d/*" -a stop\t(_ 'Stop service')
complete -x -p "/etc/init.d/*" -a status\t(_ 'Print service status')
complete -x -p "/etc/init.d/*" -a restart\t(_ 'Stop and then start service')
complete -x -p "/etc/init.d/*" -a reload\t(_ 'Reload service configuration')

File diff suppressed because it is too large Load Diff

View File

@@ -1,127 +0,0 @@
#
# Initializations that should only be performed when in interactive mode
#
if not status --is-interactive
exit
end
#
# Print a greeting
#
printf (_ 'Welcome to fish, the friendly interactive shell\n')
printf (_ 'Type %shelp%s for instructions on how to use fish\n') (set_color green) (set_color normal)
#
# Set exit message
#
function fish_on_exit -d (_ "Commands to execute when fish exits") --on-process %self
printf (_ "Good bye\n")
end
# Set the default prompt command. Make sure that every terminal escape
# string has a newline before and after, so that fish will know how
# long it is.
function fish_prompt -d (_ "Write out the prompt")
printf '%s@%s %s%s%s> \n' (whoami) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
end
#
# Set INPUTRC to something nice
#
# We override INPUTRC if already set, since it may be set by a shell
# other than fish, which may use a different file. The new value should
# be exported, since the fish inputrc file plays nice with other files
# by including them when found.
# Give priority to the default file installed with fish in
# @SYSCONFDIR@/fish_inputrc.
#
for i in ~/.fish_inputrc @SYSCONFDIR@/fish_inputrc ~/.inputrc /etc/inputrc
if test -f $i
set -xg INPUTRC $i
break
end
end
#
# Set various color values
#
function set_default_color -d "Set an universal variable, unless it has already been set. If set, verify that it is a valid color name"
if not set -q $argv[1]
set -U -- $argv
return
end
if contains -- $$argv[1] (set_color -c)
return
end
set -U -- $argv
end
function set_exported_default -d "Set an exported universal variable, unless it has already been set"
if not set -q $argv[1]
set -Ux -- $argv
end
end
# Regular syntax highlighting colors
set_default_color fish_color_normal normal
set_default_color fish_color_command green
set_default_color fish_color_redirection normal
set_default_color fish_color_comment brown
set_default_color fish_color_error red
set_default_color fish_color_cwd green
# Background color for matching quotes and parenthesis
set_default_color fish_color_match cyan
# Background color for search matches
set_default_color fish_color_search_match purple
# Pager colors
set_default_color fish_pager_color_prefix cyan
set_default_color fish_pager_color_completion normal
set_default_color fish_pager_color_description normal
set_default_color fish_pager_color_progress cyan
# Directory history colors
set_default_color fish_color_history_current cyan
#
# Setup the CDPATH variable
#
set_exported_default CDPATH . ~
#
# Match colors for grep, if supported
#
if grep --color=auto --help 1>/dev/null 2>/dev/null
set_exported_default GREP_COLOR '97;45'
set_exported_default GREP_OPTIONS '--color=auto'
end
#
# Color definitions for ls, if supported
#
if command ls --color=auto --help 1>/dev/null 2>/dev/null
set_exported_default LS_COLORS $LS_COLORS '*.jar=01;31' '*.doc=35' '*.pdf=35' '*.ps=35' '*.xls=35' '*.swf=35' '*~=37'
end
#
# Remove temporary functions
#
functions -e set_default_color
functions -e set_exported_default

View File

@@ -55,7 +55,9 @@ implementation in fish is as of yet incomplete.
#include "env.h"
#include "expand.h"
#include "event.h"
#include "signal.h"
#include "translate.h"
#include "output.h"
static void input_read_inputrc( wchar_t *fn );
@@ -1085,7 +1087,7 @@ static void input_read_inputrc( wchar_t *fn )
int error=0;
// fwprintf( stderr, L"read %ls\n", fn );
block();
signal_block();
rc = wfopen( fn, "r" );
if( rc )
@@ -1120,7 +1122,7 @@ static void input_read_inputrc( wchar_t *fn )
free( buff );
fclose( rc );
}
unblock();
signal_unblock();
inputrc_skip_block_count=0;
inputrc_block_count=0;

View File

@@ -25,14 +25,6 @@ static hash_table_t *intern_table=0;
*/
static hash_table_t *intern_static_table=0;
/**
Load static strings that are universally common. Currently only loads the empty string.
*/
static void intern_load_common_static()
{
intern_static( L"" );
}
const wchar_t *intern( const wchar_t *in )
{
const wchar_t *res=0;
@@ -40,9 +32,6 @@ const wchar_t *intern( const wchar_t *in )
if( !in )
return 0;
intern_load_common_static();
if( !intern_table )
{
intern_table = malloc( sizeof( hash_table_t ) );

8
io.c
View File

@@ -37,7 +37,7 @@ Utilities for io redirection.
#include "common.h"
#include "io.h"
#include "translate.h"
#include "halloc.h"
void io_buffer_read( io_data_t *d )
@@ -175,14 +175,14 @@ io_data_t *io_remove( io_data_t *list, io_data_t *element )
return list;
}
io_data_t *io_duplicate( io_data_t *l )
io_data_t *io_duplicate( void *context, io_data_t *l )
{
io_data_t *res;
if( l == 0 )
return 0;
res = malloc( sizeof( io_data_t) );
res = halloc( context, sizeof( io_data_t) );
if( !res )
{
@@ -191,7 +191,7 @@ io_data_t *io_duplicate( io_data_t *l )
}
memcpy( res, l, sizeof(io_data_t ));
res->next=io_duplicate( l->next );
res->next=io_duplicate( context, l->next );
return res;
}

4
io.h
View File

@@ -62,9 +62,9 @@ io_data_t *io_add( io_data_t *first_chain, io_data_t *decond_chain );
io_data_t *io_remove( io_data_t *list, io_data_t *element );
/**
Make a copy of the specified chain of redirections
Make a copy of the specified chain of redirections. Uses halloc.
*/
io_data_t *io_duplicate( io_data_t *l );
io_data_t *io_duplicate( void *context, io_data_t *l );
/**
Return the last io redirection in ht e chain for the specified file descriptor.

5
kill.c
View File

@@ -25,7 +25,6 @@
#include "sanity.h"
#include "common.h"
#include "env.h"
#include "expand.h"
#include "exec.h"
#include "parser.h"
@@ -95,7 +94,7 @@ void kill_add( wchar_t *str )
wchar_t *disp;
if( (disp = env_get( L"DISPLAY" )) )
{
wchar_t *escaped_str = expand_escape( str, 1 );
wchar_t *escaped_str = escape( str, 1 );
wchar_t *cmd = wcsdupcat2(L"echo ", escaped_str, L"|xsel -b",0);
exec_subshell( cmd, 0 );
free( cut_buffer );
@@ -137,7 +136,7 @@ static void kill_check_x_buffer()
for( i=0; i<al_get_count( &list ); i++ )
{
wchar_t *next_line = expand_escape( (wchar_t *)al_get( &list, i ), 0);
wchar_t *next_line = escape( (wchar_t *)al_get( &list, i ), 0 );
if( i==0 )
{
new_cut_buffer = next_line;

79
main.c
View File

@@ -57,6 +57,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "event.h"
#include "output.h"
#include "translate.h"
#include "halloc_util.h"
/**
Parse init files
@@ -73,7 +74,8 @@ static int read_init()
}
env_set( L"__fish_help_dir", DOCDIR, 0);
eval( L"builtin cd " DATADIR L"/fish 2>/dev/null; . fish 2>/dev/null", 0, TOP );
eval( L"builtin cd " SYSCONFDIR L" 2>/dev/null; . fish 2>/dev/null", 0, TOP );
eval( L"builtin cd 2>/dev/null;. .fish 2>/dev/null", 0, TOP );
@@ -120,10 +122,18 @@ int main( int argc, char **argv )
"command", required_argument, 0, 'c'
}
,
{
"debug-level", required_argument, 0, 'd'
}
,
{
"interactive", no_argument, 0, 'i'
}
,
{
"login", no_argument, 0, 'l'
}
,
{
"profile", required_argument, 0, 'p'
}
@@ -146,14 +156,14 @@ int main( int argc, char **argv )
int opt = getopt_long( argc,
argv,
"hivc:p:",
"hilvc:p:d:",
long_options,
&opt_index );
#else
int opt = getopt( argc,
argv,
"hivc:p:" );
"hilvc:p:d:" );
#endif
if( opt == -1 )
break;
@@ -168,16 +178,34 @@ int main( int argc, char **argv )
is_interactive_session = 0;
break;
case 'd':
{
char *end;
int tmp = strtol(optarg, &end, 10);
if( tmp >= 0 && tmp <=10 && !*end )
{
debug_level=tmp;
}
else
{
debug( 0, _(L"Invalid value '%s' for debug level switch"), optarg );
exit(1);
}
break;
}
case 'h':
cmd = "help";
//interactive=0;
break;
case 'i':
force_interactive = 1;
break;
case 'l':
is_login=1;
break;
case 'p':
profile = optarg;
break;
@@ -197,21 +225,17 @@ int main( int argc, char **argv )
my_optind = optind;
is_login |= strcmp( argv[0], "-fish") == 0;
// fwprintf( stderr, L"%s\n", argv[0] );
is_login |= (strcmp( argv[0], "-fish") == 0);
is_interactive_session &= (cmd == 0);
is_interactive_session &= (my_optind == argc);
is_interactive_session &= isatty(STDIN_FILENO);
// fwprintf( stderr, L"%d %d %d\n", cmd==0, my_optind == argc, isatty(STDIN_FILENO) );
is_interactive_session |= force_interactive;
if( force_interactive )
is_interactive_session=1;
common_init();
halloc_util_init();
translate_init();
proc_init();
output_init();
event_init();
exec_init();
wutil_init();
@@ -229,7 +253,7 @@ int main( int argc, char **argv )
wchar_t *cmd_wcs = str2wcs( cmd );
res = eval( cmd_wcs, 0, TOP );
free(cmd_wcs);
reader_exit(0);
reader_exit(0);
}
else
{
@@ -244,7 +268,8 @@ int main( int argc, char **argv )
int i;
string_buffer_t sb;
int fd;
wchar_t *rel_filename, *abs_filename;
if( ( fd = open(file, O_RDONLY) ) == -1 )
{
wperror( L"open" );
@@ -267,8 +292,15 @@ int main( int argc, char **argv )
env_set( L"argv", (wchar_t *)sb.buff, 0 );
sb_destroy( &sb );
}
reader_push_current_filename( str2wcs( file ) );
rel_filename = str2wcs( file );
abs_filename = wrealpath( rel_filename, 0 );
if( !abs_filename )
abs_filename = wcsdup(rel_filename);
reader_push_current_filename( intern( abs_filename ) );
free( rel_filename );
free( abs_filename );
res = reader_read( fd );
if( res )
@@ -277,27 +309,26 @@ int main( int argc, char **argv )
_(L"Error while reading file %ls\n"),
reader_current_filename()?reader_current_filename(): _(L"Standard input") );
}
free(reader_pop_current_filename());
reader_pop_current_filename();
}
}
}
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
complete_destroy();
proc_destroy();
env_destroy();
builtin_destroy();
function_destroy();
complete_destroy();
reader_destroy();
parser_destroy();
wutil_destroy();
common_destroy();
exec_destroy();
event_destroy();
output_destroy();
translate_destroy();
common_destroy();
halloc_util_destroy();
intern_free_all();
return res;

145
output.c
View File

@@ -43,6 +43,7 @@
#include "expand.h"
#include "common.h"
#include "output.h"
#include "halloc_util.h"
#include "highlight.h"
/**
@@ -50,6 +51,8 @@
*/
#define COLORS (sizeof(col)/sizeof(wchar_t *))
static int writeb_internal( char c );
/**
Names of different colors.
*/
@@ -101,15 +104,22 @@ static size_t writestr_buff_sz=0;
*/
static char *writestr_buff = 0;
void output_init()
{
}
/**
The function used for output
*/
void output_destroy()
static int (*out)(char c) = &writeb_internal;
static void output_destroy()
{
free( writestr_buff );
}
void output_set_writer( int (*writer)(char) )
{
out = writer;
}
void set_color( int c, int c2 )
{
@@ -133,7 +143,9 @@ void set_color( int c, int c2 )
{
c = c2 = FISH_COLOR_NORMAL;
if( fg )
{
writembs( tparm( fg, 0 ) );
}
writembs( exit_attribute_mode );
return;
}
@@ -193,12 +205,14 @@ void set_color( int c, int c2 )
if( c==FISH_COLOR_NORMAL )
{
if( fg )
{
writembs( tparm( fg, 0 ) );
}
writembs( exit_attribute_mode );
last_color2 = FISH_COLOR_NORMAL;
}
else if( ( c >= 0) && ( c < FISH_COLOR_NORMAL ) )
else if( ( c >= 0 ) && ( c < FISH_COLOR_NORMAL ) )
{
if( fg )
{
@@ -218,15 +232,15 @@ void set_color( int c, int c2 )
writembs( tparm( bg, 0 ) );
}
writembs(exit_attribute_mode);
if(( last_color != FISH_COLOR_NORMAL ) && fg )
writembs( exit_attribute_mode );
if( ( last_color != FISH_COLOR_NORMAL ) && fg )
{
writembs(tparm( fg, last_color ));
writembs( tparm( fg, last_color ) );
}
last_color2 = c2;
}
else if ((c2 >= 0 ) &&(c2 < FISH_COLOR_NORMAL))
else if ( ( c2 >= 0 ) && ( c2 < FISH_COLOR_NORMAL ) )
{
if( bg )
{
@@ -237,40 +251,96 @@ void set_color( int c, int c2 )
}
}
/**
perm_left_cursor and parm_right_cursor don't seem to be properly
emulated by many terminal emulators, so we only use plain
curor_left, curor_right...
*/
void move_cursor( int steps )
{
int i;
if( !steps )
return;
if( steps < 0 ){
for( i=0; i>steps; i--)
{
writembs(cursor_left);
}
}
else
{
for( i=0; i<steps; i++)
{
writembs(cursor_right);
}
}
}
static int writeb_internal( char c )
{
write( 1, &c, 1 );
return 0;
}
int writeb( tputs_arg_t b )
{
out( b );
return 0;
}
int writembs( char *str )
{
#ifdef TPUTS_KLUDGE
write( 1, str, strlen(str));
while( *str )
{
out( *str );
}
#else
tputs(str,1,&writeb);
tputs(str,1,writeb);
#endif
return 0;
}
int writech( wint_t ch )
{
static mbstate_t out_state;
char buff[MB_CUR_MAX];
size_t bytes = wcrtomb( buff, ch, &out_state );
int err;
while( (err =write( 1, buff, bytes ) ) )
mbstate_t state;
int i;
char buff[MB_CUR_MAX+1];
size_t bytes;
if( ( ch >= ENCODE_DIRECT_BASE) &&
( ch < ENCODE_DIRECT_BASE+256) )
{
if( err >= 0 )
break;
buff[0] = ch - ENCODE_DIRECT_BASE;
bytes=1;
}
else
{
memset( &state, 0, sizeof(state) );
bytes= wcrtomb( buff, ch, &state );
if( errno == EINTR )
continue;
wperror( L"write" );
return 1;
switch( bytes )
{
case (size_t)(-1):
{
return 1;
}
}
}
for( i=0; i<bytes; i++ )
{
out( buff[i] );
}
return 0;
}
void writestr( const wchar_t *str )
{
char *pos;
// while( *str )
// writech( *str++ );
@@ -292,9 +362,16 @@ void writestr( const wchar_t *str )
*/
if( writestr_buff_sz < len )
{
if( !writestr_buff )
{
halloc_register_function_void( global_context, &output_destroy );
}
writestr_buff = realloc( writestr_buff, len );
if( !writestr_buff )
{
die_mem();
}
writestr_buff_sz = len;
}
@@ -308,8 +385,10 @@ void writestr( const wchar_t *str )
/*
Write
*/
write( 1, writestr_buff, strlen( writestr_buff ) );
for( pos = writestr_buff; *pos; pos++ )
{
out( *pos );
}
}
@@ -328,7 +407,9 @@ void writestr_ellipsis( const wchar_t *str, int max_width )
{
int w = wcwidth( *str );
if( written+w+wcwidth( ellipsis_char )>max_width )
{
break;
}
written+=w;
writech( *(str++) );
}
@@ -386,13 +467,13 @@ int writespace( int c )
}
else
{
write( 1, " ", mini(c,8) );
if( c>8)
int i;
for( i=0; i<c; i++ )
{
writespace( c-8);
out( ' ' );
}
}
return 0;
}
@@ -411,7 +492,11 @@ int output_color_code( const wchar_t *val )
}
if( color >= 0 )
{
return color;
}
else
{
return FISH_COLOR_NORMAL;
}
}

View File

@@ -80,7 +80,9 @@ void set_color( int c, int c2 );
/**
Write a char * narrow string to FD 1, needed for the terminfo
strings.
strings. This is usually just a wrapper aound tputs, using writeb
as the sending function. But a weird bug on PPC Linux means that on
this platform, write is instead used directly.
*/
int writembs( char *str );
@@ -117,13 +119,25 @@ int writespace( int c );
int output_color_code( const wchar_t *val );
/**
Initialize static data
perm_left_cursor and parm_right_cursor don't seem to be defined
very often so we use cursor_left and cursor_right as a fallback.
*/
void output_init();
void move_cursor( int steps );
/**
Destroy static data
This is for writing process notification messages. Has to write to
stdout, so clr_eol and such functions will work correctly. Not an
issue since this function is only used in interactive mode anyway.
*/
void output_destroy();
int writeb( tputs_arg_t b );
/**
Set the function used for writing in move_cursor, writespace and
set_color and all other output functions in this library. By
default, the write call is used to give completely unbuffered
output to stdout.
*/
void output_set_writer( int (*writer)(char) );
#endif

689
parse_util.c Normal file
View File

@@ -0,0 +1,689 @@
/** \file parse_util.c
Various mostly unrelated utility functions related to parsing,
loading and evaluating fish code.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <wctype.h>
#include <wchar.h>
#include <time.h>
#include <assert.h>
#include "util.h"
#include "wutil.h"
#include "common.h"
#include "tokenizer.h"
#include "parse_util.h"
#include "expand.h"
#include "intern.h"
#include "exec.h"
#include "env.h"
#include "wildcard.h"
#include "halloc_util.h"
/**
Set of files which have been autoloaded
*/
static hash_table_t *all_loaded=0;
int parse_util_lineno( const wchar_t *str, int len )
{
/**
First cached state
*/
static const wchar_t *prev_str = 0;
static int i=0;
static int res = 1;
/**
Second cached state
*/
static const wchar_t *prev_str2 = 0;
static int i2 = 0;
static int res2 = 1;
if( str != prev_str || i>len )
{
if( prev_str2 == str && i2 <= len )
{
const wchar_t *tmp_str = prev_str;
int tmp_i = i;
int tmp_res = res;
prev_str = prev_str2;
i=i2;
res=res2;
prev_str2 = tmp_str;
i2 = tmp_i;
res2 = tmp_res;
}
else
{
prev_str2 = prev_str;
i2 = i;
res2=res;
prev_str = str;
i=0;
res=1;
}
}
for( ; str[i] && i<len; i++ )
{
if( str[i] == L'\n' )
res++;
}
return res;
}
int parse_util_locate_cmdsubst( const wchar_t *in,
const wchar_t **begin,
const wchar_t **end,
int allow_incomplete )
{
const wchar_t *pos;
wchar_t prev=0;
int syntax_error=0;
int paran_count=0;
const wchar_t *paran_begin=0, *paran_end=0;
for( pos=in; *pos; pos++ )
{
if( prev != '\\' )
{
if( wcschr( L"\'\"", *pos ) )
{
const wchar_t *end = quote_end( pos );
if( end && *end)
{
pos=end;
}
else
break;
}
else
{
if( *pos == '(' )
{
if(( paran_count == 0)&&(paran_begin==0))
paran_begin = pos;
paran_count++;
}
else if( *pos == ')' )
{
paran_count--;
if( (paran_count == 0) && (paran_end == 0) )
{
paran_end = pos;
break;
}
if( paran_count < 0 )
{
syntax_error = 1;
break;
}
}
}
}
prev = *pos;
}
syntax_error |= (paran_count < 0 );
syntax_error |= ((paran_count>0)&&(!allow_incomplete));
if( syntax_error )
{
return -1;
}
if( paran_begin == 0 )
{
return 0;
}
if( begin )
*begin = paran_begin;
if( end )
*end = paran_count?in+wcslen(in):paran_end;
return 1;
}
void parse_util_cmdsubst_extent( const wchar_t *buff,
int cursor_pos,
const wchar_t **a,
const wchar_t **b )
{
const wchar_t *begin, *end;
const wchar_t *pos;
if( a )
*a=0;
if( b )
*b = 0;
if( !buff )
return;
pos = buff;
while( 1 )
{
int bc, ec;
if( parse_util_locate_cmdsubst( pos,
&begin,
&end,
1 ) <= 0)
{
begin=buff;
end = buff + wcslen(buff);
break;
}
if( !end )
{
end = buff + wcslen(buff);
}
bc = begin-buff;
ec = end-buff;
if(( bc < cursor_pos ) && (ec >= cursor_pos) )
{
begin++;
break;
}
pos = end+1;
}
if( a )
*a = begin;
if( b )
*b = end;
}
/**
Get the beginning and end of the job or process definition under the cursor
*/
static void job_or_process_extent( const wchar_t *buff,
int cursor_pos,
const wchar_t **a,
const wchar_t **b,
int process )
{
const wchar_t *begin, *end;
int pos;
wchar_t *buffcpy;
int finished=0;
tokenizer tok;
if( a )
*a=0;
if( b )
*b = 0;
parse_util_cmdsubst_extent( buff, cursor_pos, &begin, &end );
if( !end || !begin )
return;
pos = cursor_pos - (begin - buff);
if( a )
{
*a = begin;
}
if( b )
{
*b = end;
}
buffcpy = wcsndup( begin, end-begin );
if( !buffcpy )
{
die_mem();
}
for( tok_init( &tok, buffcpy, TOK_ACCEPT_UNFINISHED );
tok_has_next( &tok ) && !finished;
tok_next( &tok ) )
{
int tok_begin = tok_get_pos( &tok );
switch( tok_last_type( &tok ) )
{
case TOK_PIPE:
if( !process )
break;
case TOK_END:
case TOK_BACKGROUND:
{
if( tok_begin >= pos )
{
finished=1;
if( b )
*b = buff + tok_begin;
}
else
{
if( a )
*a = buff + tok_begin+1;
}
break;
}
}
}
free( buffcpy);
tok_destroy( &tok );
}
void parse_util_process_extent( const wchar_t *buff,
int pos,
const wchar_t **a,
const wchar_t **b )
{
job_or_process_extent( buff, pos, a, b, 1 );
}
void parse_util_job_extent( const wchar_t *buff,
int pos,
const wchar_t **a,
const wchar_t **b )
{
job_or_process_extent( buff,pos,a, b, 0 );
}
void parse_util_token_extent( const wchar_t *buff,
int cursor_pos,
const wchar_t **tok_begin,
const wchar_t **tok_end,
const wchar_t **prev_begin,
const wchar_t **prev_end )
{
const wchar_t *begin, *end;
int pos;
wchar_t *buffcpy;
tokenizer tok;
const wchar_t *a, *b, *pa, *pb;
a = b = pa = pb = 0;
parse_util_cmdsubst_extent( buff, cursor_pos, &begin, &end );
if( !end || !begin )
return;
pos = cursor_pos - (begin - buff);
a = buff + pos;
b = a;
pa = buff + pos;
pb = pa;
assert( begin >= buff );
assert( begin <= (buff+wcslen(buff) ) );
assert( end >= begin );
assert( end <= (buff+wcslen(buff) ) );
buffcpy = wcsndup( begin, end-begin );
if( !buffcpy )
{
die_mem();
}
for( tok_init( &tok, buffcpy, TOK_ACCEPT_UNFINISHED );
tok_has_next( &tok );
tok_next( &tok ) )
{
int tok_begin = tok_get_pos( &tok );
int tok_end=tok_begin;
/*
Calculate end of token
*/
if( tok_last_type( &tok ) == TOK_STRING )
tok_end +=wcslen(tok_last(&tok));
/*
Cursor was before beginning of this token, means that the
cursor is between two tokens, so we set it to a zero element
string and break
*/
if( tok_begin > pos )
{
a = b = buff + pos;
break;
}
/*
If cursor is inside the token, this is the token we are
looking for. If so, set a and b and break
*/
if( tok_end >= pos )
{
a = begin + tok_get_pos( &tok );
b = a + wcslen(tok_last(&tok));
// fwprintf( stderr, L"Whee %ls\n", *a );
break;
}
/*
Remember previous string token
*/
if( tok_last_type( &tok ) == TOK_STRING )
{
pa = begin + tok_get_pos( &tok );
pb = pa + wcslen(tok_last(&tok));
}
}
free( buffcpy);
tok_destroy( &tok );
if( tok_begin )
*tok_begin = a;
if( tok_end )
*tok_end = b;
if( prev_begin )
*prev_begin = pa;
if( prev_end )
*prev_end = pb;
assert( pa >= buff );
assert( pa <= (buff+wcslen(buff) ) );
assert( pb >= pa );
assert( pb <= (buff+wcslen(buff) ) );
}
/**
Free hash value, but not hash key
*/
static void clear_hash_value( const void *key, const void *data )
{
free( (void *)data );
}
/**
Part of the autoloader cleanup
*/
static void clear_loaded_entry( const void *key, const void *data )
{
hash_table_t *loaded = (hash_table_t *)data;
hash_foreach( loaded,
&clear_hash_value );
hash_destroy( loaded );
free( loaded );
free( (void *)key );
}
/**
The autoloader cleanup function. It is run on shutdown and frees
any memory used by the autoloader code to keep track of loaded
files.
*/
static void parse_util_destroy()
{
if( all_loaded )
{
hash_foreach( all_loaded,
&clear_loaded_entry );
hash_destroy( all_loaded );
free( all_loaded );
all_loaded = 0;
}
}
void parse_util_load_reset( const wchar_t *path_var )
{
if( all_loaded )
{
void *key, *data;
hash_remove( all_loaded, path_var, (const void **)&key, (const void **)&data );
if( key )
clear_loaded_entry( key, data );
}
}
int parse_util_load( const wchar_t *cmd,
const wchar_t *path_var_name,
void (*on_load)(const wchar_t *cmd),
int reload )
{
static array_list_t *path_list=0;
static string_buffer_t *path=0;
int i;
time_t *tm;
int reloaded = 0;
hash_table_t *loaded;
const wchar_t *path_var = env_get( path_var_name );
/*
Do we know where to look
*/
if( !path_var )
return 0;
if( !all_loaded )
{
all_loaded = malloc( sizeof( hash_table_t ) );
halloc_register_function_void( global_context, &parse_util_destroy );
if( !all_loaded )
{
die_mem();
}
hash_init( all_loaded, &hash_wcs_func, &hash_wcs_cmp );
}
loaded = (hash_table_t *)hash_get( all_loaded, path_var_name );
if( !loaded )
{
loaded = malloc( sizeof( hash_table_t ) );
if( !loaded )
{
die_mem();
}
hash_init( loaded, &hash_wcs_func, &hash_wcs_cmp );
hash_put( all_loaded, wcsdup(path_var_name), loaded );
}
/*
Get modification time of file
*/
tm = (time_t *)hash_get( loaded, cmd );
/*
Did we just check this?
*/
if( tm )
{
if(time(0)-tm[1]<=1)
{
return 0;
}
}
/*
Return if already loaded and we are skipping reloading
*/
if( !reload && tm )
return 0;
if( !path_list )
path_list = al_halloc( global_context);
if( !path )
path = sb_halloc( global_context );
else
sb_clear( path );
expand_variable_array( path_var, path_list );
/*
Iterate over path searching for suitable completion files
*/
for( i=0; i<al_get_count( path_list ); i++ )
{
struct stat buf;
wchar_t *next = (wchar_t *)al_get( path_list, i );
sb_clear( path );
sb_append2( path, next, L"/", cmd, L".fish", (void *)0 );
if( (wstat( (wchar_t *)path->buff, &buf )== 0) &&
(waccess( (wchar_t *)path->buff, R_OK ) == 0) )
{
if( !tm || (tm[0] != buf.st_mtime ) )
{
wchar_t *esc = escape( (wchar_t *)path->buff, 1 );
wchar_t *src_cmd = wcsdupcat( L". ", esc );
if( !tm )
{
tm = malloc(sizeof(time_t)*2);
if( !tm )
die_mem();
}
tm[0] = buf.st_mtime;
tm[1] = time(0);
hash_put( loaded,
intern( cmd ),
tm );
free( esc );
if( on_load )
on_load(cmd );
/*
Source the completion file for the specified completion
*/
exec_subshell( src_cmd, 0 );
free(src_cmd);
reloaded = 1;
break;
}
}
}
/*
If no file was found we insert the current time. Later we only
research if the current time is at least five seconds later.
This way, the files won't be searched over and over again.
*/
if( !tm )
{
tm = malloc(sizeof(time_t)*2);
if( !tm )
die_mem();
tm[0] = 0;
tm[1] = time(0);
hash_put( loaded, intern( cmd ), tm );
}
al_foreach( path_list, (void (*)(const void *))&free );
al_truncate( path_list, 0 );
return reloaded;
}
void parse_util_set_argv( wchar_t **argv )
{
if( *argv )
{
wchar_t **arg;
string_buffer_t sb;
sb_init( &sb );
for( arg=argv; *arg; arg++ )
{
if( arg != argv )
sb_append( &sb, ARRAY_SEP_STR );
sb_append( &sb, *arg );
}
env_set( L"argv", (wchar_t *)sb.buff, ENV_LOCAL );
sb_destroy( &sb );
}
else
{
env_set( L"argv", 0, ENV_LOCAL );
}
}
wchar_t *parse_util_unescape_wildcards( const wchar_t *str )
{
wchar_t *in, *out;
wchar_t *unescaped = wcsdup(str);
if( !unescaped )
die_mem();
for( in=out=unescaped; *in; in++ )
{
switch( *in )
{
case L'\\':
if( *(in+1) )
{
in++;
*(out++)=*in;
}
*(out++)=*in;
break;
case L'*':
*(out++)=ANY_STRING;
break;
case L'?':
*(out++)=ANY_CHAR;
break;
default:
*(out++)=*in;
break;
}
}
return unescaped;
}

119
parse_util.h Normal file
View File

@@ -0,0 +1,119 @@
/** \file parse_util.h
Various mostly unrelated utility functions related to parsing,
loading and evaluating fish code.
*/
#ifndef FISH_PARSE_UTIL_H
#define FISH_PARSE_UTIL_H
#include <wchar.h>
/**
Find the beginning and end of the first subshell in the specified string.
\param in the string to search for subshells
\param begin the starting paranthesis of the subshell
\param end the ending paranthesis of the subshell
\param flags set this variable to ACCEPT_INCOMPLETE if in tab_completion mode
\return -1 on syntax error, 0 if no subshells exist and 1 on sucess
*/
int parse_util_locate_cmdsubst( const wchar_t *in,
const wchar_t **begin,
const wchar_t **end,
int allow_incomplete );
/**
Find the beginning and end of the command substitution under the cursor
\param buff the string to search for subshells
\param cursor_pos the position of the cursor
\param a the start of the searched string
\param b the end of the searched string
*/
void parse_util_cmdsubst_extent( const wchar_t *buff,
int cursor_pos,
const wchar_t **a,
const wchar_t **b );
/**
Find the beginning and end of the process definition under the cursor
\param buff the string to search for subshells
\param cursor_pos the position of the cursor
\param a the start of the searched string
\param b the end of the searched string
*/
void parse_util_process_extent( const wchar_t *buff,
int cursor_pos,
const wchar_t **a,
const wchar_t **b );
/**
Find the beginning and end of the job definition under the cursor
\param buff the string to search for subshells
\param cursor_pos the position of the cursor
\param a the start of the searched string
\param b the end of the searched string
*/
void parse_util_job_extent( const wchar_t *buff,
int cursor_pos,
const wchar_t **a,
const wchar_t **b );
/**
Find the beginning and end of the token under the cursor
\param buff the string to search for subshells
\param cursor_pos the position of the cursor
\param a the start of the searched string
\param b the end of the searched string
*/
void parse_util_token_extent( const wchar_t *buff,
int cursor_pos,
const wchar_t **tok_begin,
const wchar_t **tok_end,
const wchar_t **prev_begin,
const wchar_t **prev_end );
/**
Get the linenumber at the specified character offset
*/
int parse_util_lineno( const wchar_t *str, int len );
/**
Autoload the specified file, if it exists in the specified path. Do
not load it multiple times unless it's timestamp changes.
\param cmd the filename to search for. The suffix '.fish' is always added to this name
\param path_var_name the name of an environment variable containing a search path
\param on_load a callback function to run if a suitable file is found, which has not already been run
\param reload wheter to recheck file timestamps on already loaded files
*/
int parse_util_load( const wchar_t *cmd,
const wchar_t *path_var_name,
void (*on_load)(const wchar_t *cmd),
int reload );
/**
Reset the loader for the specified path variable
*/
void parse_util_load_reset( const wchar_t *path_var );
/**
Set the argv environment variable to the specified null-terminated
array of strings.
*/
void parse_util_set_argv( wchar_t **argv );
/**
Make a duplicate of the specified string, unescape wildcard
characters but not performing any other character transformation.
*/
wchar_t *parse_util_unescape_wildcards( const wchar_t *in );
#endif

1102
parser.c

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@
#include "proc.h"
#include "util.h"
#include "parser.h"
#include "event.h"
/**
event_block_t represents a block on events of the specified type
@@ -64,6 +65,8 @@ typedef struct block
int if_state; /**< The state of the if block */
wchar_t *switch_value; /**< The value to test in a switch block */
wchar_t *function_name; /**< The name of the function to define or the function called*/
const wchar_t *source_dest; /**< The name of the file to source*/
event_t *event; /**<The event that triggered this block */
} param1;
/**
@@ -74,7 +77,7 @@ typedef struct block
array_list_t for_vars; /**< List of values for a for block */
int switch_taken; /**< Whether a switch match has already been found */
wchar_t *function_description; /**< The description of the function to define */
array_list_t function_vars; /**< List of arguments for a function call */
process_t *function_call_process; /**< The process representing this function call */
} param2;
/**
@@ -83,7 +86,6 @@ typedef struct block
union
{
int function_is_binding; /**< Whether a function is a keybinding */
int function_lineno; /**< Function invocation line number */
} param3;
/**
@@ -92,8 +94,17 @@ typedef struct block
union
{
array_list_t *function_events;
wchar_t *function_filename;
} param4;
/**
Name of file that created this block
*/
const wchar_t *src_filename;
/**
Line number where this block was created
*/
int src_lineno;
/**
Some naming confusion. This is a pointer to the first element in the list of all event blocks.
@@ -121,6 +132,8 @@ enum block_type
SUBST, /**< Command substitution scope */
TOP, /**< Outermost block */
BEGIN, /**< Unconditional block */
SOURCE, /**< Block created by the . (source) builtin */
EVENT, /**< Block created on event notifier invocation */
}
;
@@ -244,7 +257,7 @@ int parser_is_subcommand( const wchar_t *cmd );
\param word The command name to test
\return 1 of the command parameter is a command, 0 otherwise
*/
int parser_is_reserved( wchar_t *word );
int parser_is_reserved( const wchar_t *word );
/**
Returns a string describing the current parser pisition in the format 'FILENAME (line LINE_NUMBER): LINE'.
@@ -346,5 +359,10 @@ int parser_is_help( wchar_t *s, int min_match );
*/
const wchar_t *parser_current_filename();
/**
Write a stack trace starting at the specified block to the specified string_buffer_t
*/
void parser_stack_trace( block_t *b, string_buffer_t *buff);
#endif

8665
po/de.po Normal file

File diff suppressed because it is too large Load Diff

6644
po/sv.po

File diff suppressed because it is too large Load Diff

166
proc.c
View File

@@ -53,6 +53,9 @@ Some of the code in this file is based on code from the Glibc manual.
#include "signal.h"
#include "event.h"
#include "translate.h"
#include "halloc.h"
#include "halloc_util.h"
#include "output.h"
/**
Size of message buffer
@@ -75,7 +78,7 @@ static int last_status=0;
static sig_atomic_t got_signal=0;
job_t *first_job=0;
int is_interactive=0;
int is_interactive=-1;
int is_interactive_session=0;
int is_subshell=0;
int is_block=0;
@@ -83,6 +86,7 @@ int is_login=0;
int is_event=0;
int proc_had_barrier;
pid_t proc_last_bg_pid = 0;
int job_control_mode = JOB_CONTROL_INTERACTIVE;
/**
The event variable used to send all process event
@@ -99,43 +103,18 @@ static string_buffer_t event_pid;
*/
static string_buffer_t event_status;
static array_list_t *interactive_stack;
void proc_init()
{
interactive_stack = al_halloc( global_context );
proc_push_interactive( 0 );
al_init( &event.arguments );
sb_init( &event_pid );
sb_init( &event_status );
}
/**
Recursively free a process and those following it
*/
static void free_process( process_t *p )
{
wchar_t **arg;
if( p==0 )
return;
free_process( p->next );
debug( 3, L"Free process %ls", p->actual_cmd );
free( p->actual_cmd );
if( p->argv != 0 )
{
debug( 3, L"Process has argument vector" );
for( arg=p->argv; *arg; arg++ )
{
debug( 3, L"Free argument %ls", *arg );
free( *arg );
}
free(p->argv );
}
free( p );
}
/**
Remove job from list of jobs
*/
@@ -169,30 +148,8 @@ static int job_remove( job_t *j )
*/
void job_free( job_t * j )
{
io_data_t *io, *ionext;
// fwprintf( stderr, L"Remove job %d (%ls)\n", j->job_id, j->command );
job_remove( j );
/* Then free ourselves */
free_process( j->first_process);
if( j->command != 0 )
free( j->command );
for( io=j->io; io; io=ionext )
{
ionext = io->next;
// fwprintf( stderr, L"Kill redirect %d of type %d\n", ionext, io->io_mode );
if( io->io_mode == IO_FILE )
{
free( io->param1.filename );
}
free( io );
}
free( j );
halloc_free( j );
}
void proc_destroy()
@@ -225,10 +182,14 @@ job_t *job_create()
while( job_get( free_id ) != 0 )
free_id++;
res = calloc( 1, sizeof(job_t) );
res = halloc( 0, sizeof(job_t) );
res->next = first_job;
res->job_id = free_id;
first_job = res;
res->job_control = (job_control_mode==JOB_CONTROL_ALL) ||
((job_control_mode == JOB_CONTROL_INTERACTIVE) && (is_interactive));
// if( res->job_id > 2 )
// fwprintf( stderr, L"Create job %d\n", res->job_id );
return res;
@@ -388,7 +349,7 @@ static void handle_child_status( pid_t pid, int status )
"Process %d is %ls from job %ls\n",
(int) pid, p->actual_cmd, j->command );
write( 2, mess, strlen(mess ));
*/
*/
mark_process_status ( j, p, status);
if( p->completed && prev != 0 )
@@ -583,7 +544,7 @@ int job_reap( int interactive )
j->job_id,
j->command,
sig2wcs(WTERMSIG(p->status)),
sig_description( WTERMSIG(p->status) ) );
signal_get_desc( WTERMSIG(p->status) ) );
else
fwprintf( stdout,
_( L"%ls: Process %d, \'%ls\' from job %d, \'%ls\' terminated by signal %ls (%ls)" ),
@@ -593,7 +554,7 @@ int job_reap( int interactive )
j->job_id,
j->command,
sig2wcs(WTERMSIG(p->status)),
sig_description( WTERMSIG(p->status) ) );
signal_get_desc( WTERMSIG(p->status) ) );
tputs(clr_eol,1,&writeb);
fwprintf (stdout, L"\n" );
found=1;
@@ -875,37 +836,33 @@ void job_continue (job_t *j, int cont)
if( !job_is_completed( j ) )
{
if( j->terminal )
{
if( j->terminal && j->fg )
{
/* Put the job into the foreground. */
if( j->fg )
signal_block();
if( tcsetpgrp (0, j->pgid) )
{
signal_block();
if( tcsetpgrp (0, j->pgid) )
{
debug( 1,
_( L"Could not send job %d ('%ls') to foreground" ),
j->job_id,
j->command );
wperror( L"tcsetpgrp" );
return;
}
if( cont )
{
if( tcsetattr (0, TCSADRAIN, &j->tmodes))
{
debug( 1,
_( L"Could not send job %d ('%ls') to foreground" ),
j->job_id,
j->command );
wperror( L"tcsetattr" );
return;
}
}
signal_unblock();
debug( 1,
_( L"Could not send job %d ('%ls') to foreground" ),
j->job_id,
j->command );
wperror( L"tcsetpgrp" );
return;
}
if( cont )
{
if( tcsetattr (0, TCSADRAIN, &j->tmodes))
{
debug( 1,
_( L"Could not send job %d ('%ls') to foreground" ),
j->job_id,
j->command );
wperror( L"tcsetattr" );
return;
}
}
signal_unblock();
}
/*
@@ -914,15 +871,28 @@ void job_continue (job_t *j, int cont)
if( cont )
{
process_t *p;
for( p=j->first_process; p; p=p->next )
p->stopped=0;
for( p=j->first_process; p; p=p->next )
if( j->job_control )
{
if (kill ( p->pid, SIGCONT) < 0)
if( killpg( j->pgid, SIGCONT ) )
{
wperror (L"kill (SIGCONT)");
wperror( L"killpg (SIGCONT)" );
return;
}
}
}
else
{
for( p=j->first_process; p; p=p->next )
{
if (kill ( p->pid, SIGCONT) < 0)
{
wperror (L"kill (SIGCONT)");
return;
}
}
}
}
@@ -979,7 +949,7 @@ void job_continue (job_t *j, int cont)
}
}
}
if( j->fg )
{
@@ -1005,7 +975,7 @@ void job_continue (job_t *j, int cont)
/*
Put the shell back in the foreground.
*/
if( j->terminal )
if( j->terminal && j->fg )
{
signal_block();
if( tcsetpgrp (0, getpid()) )
@@ -1112,3 +1082,19 @@ void proc_sanity_check()
}
}
void proc_push_interactive( int value )
{
int old = is_interactive;
al_push( interactive_stack, (void *)(long)is_interactive );
is_interactive = value;
if( old != value )
signal_set_handlers();
}
void proc_pop_interactive()
{
int old = is_interactive;
is_interactive= (int)(long)al_pop(interactive_stack);
if( is_interactive != old )
signal_set_handlers();
}

36
proc.h
View File

@@ -48,6 +48,13 @@ enum
}
;
enum
{
JOB_CONTROL_ALL,
JOB_CONTROL_INTERACTIVE,
JOB_CONTROL_NONE,
}
;
/**
A structure representing a single fish process. Contains variables
@@ -156,9 +163,12 @@ typedef struct job
/** Skip executing this job. This flag is set by the short-circut builtins, i.e. and and or */
int skip;
/** Whether this job wants to have control of the terminal when it is in the foreground */
/** Whether the job is under job control */
int job_control;
/** Whether the job wants to own the terminal when in the foreground */
int terminal;
/** Pointer to the next job */
struct job *next;
}
@@ -216,6 +226,11 @@ extern int proc_had_barrier;
*/
extern pid_t proc_last_bg_pid;
/**
Can be one of JOB_CONTROL_ALL, JOB_CONTROL_INTERACTIVE and JOB_CONTROL_NONE
*/
extern int job_control_mode;
/**
Sets the status of the last process to exit
*/
@@ -232,7 +247,9 @@ int proc_get_last_status();
void job_free( job_t* j );
/**
Create a new job
Create a new job. Job struct is allocated using halloc, so anything
that should be freed with the job can uset it as a halloc context
when allocating.
*/
job_t *job_create();
@@ -281,7 +298,6 @@ int job_reap( int interactive );
*/
void job_handle_signal( int signal, siginfo_t *info, void *con );
#ifdef HAVE__PROC_SELF_STAT
/**
Use the procfs filesystem to look up how many jiffies of cpu time
@@ -320,4 +336,16 @@ void proc_init();
*/
void proc_destroy();
/**
Set new value for is_interactive flag, saving previous value. If
needed, update signal handlers.
*/
void proc_push_interactive( int value );
/**
Set is_interactive flag to the previous value. If needed, update
signal handlers.
*/
void proc_pop_interactive();
#endif

612
reader.c

File diff suppressed because it is too large Load Diff

View File

@@ -48,7 +48,7 @@ wchar_t *reader_current_filename();
\param fn The fileanme to push
*/
void reader_push_current_filename( wchar_t *fn );
void reader_push_current_filename( const wchar_t *fn );
/**
Pop the current filename from the stack of read files
*/
@@ -152,27 +152,6 @@ void reader_set_prompt( wchar_t *prompt );
*/
int exit_status();
/**
Find the beginning and the end of the current subshell
*/
void reader_current_subshell_extent( wchar_t **a, wchar_t **b );
/**
Find the beginning and the end of the job under the cursor
*/
void reader_current_job_extent( wchar_t **a, wchar_t **b );
/**
Find the beginning and the end of the process under the cursor
*/
void reader_current_process_extent( wchar_t **a, wchar_t **b );
/**
Find the beginning and the end of the token under the curor and the token before the cursor
*/
void reader_current_token_extent( wchar_t **a, wchar_t **b, wchar_t **pa, wchar_t **pb );
/**
Replace the current token with the specified string
*/

17
seq.in
View File

@@ -1,9 +1,24 @@
#!@prefix@/bin/fish
#!/usr/bin/env fish
#
# Fallback implementation of the seq command
#
# @configure_input@
set -l from 1
set -l step 1
set -l to 1
function _ -d "Alias for the gettext command"
printf "%s" $argv
end
if test 1 = "@HAVE_GETTEXT@"
if which gettext ^/dev/null >/dev/null
function _ -d "Alias for the gettext command"
gettext fish $argv
end
end
end
switch (count $argv)
case 1
set to $argv[1]

View File

@@ -125,8 +125,13 @@ void print_colors()
}
}
static void locale_init()
static void check_locale_init()
{
static int is_init = 0;
if( is_init )
return;
is_init = 1;
setlocale( LC_ALL, "" );
#if HAVE_GETTEXT
bindtextdomain( PACKAGE_NAME, LOCALEDIR );
@@ -142,7 +147,6 @@ int main( int argc, char **argv )
int fg, bg;
int bold=0;
locale_init();
while( 1 )
@@ -209,6 +213,7 @@ int main( int argc, char **argv )
break;
case 'v':
check_locale_init();
fprintf( stderr, _("%s, version %s\n"), SET_COLOR, PACKAGE_VERSION );
exit( 0 );
@@ -235,12 +240,14 @@ int main( int argc, char **argv )
break;
default:
check_locale_init();
printf( _("%s: Too many arguments\n"), SET_COLOR );
return 1;
}
if( !fgcolor && !bgcolor && !bold )
{
check_locale_init();
fprintf( stderr, _("%s: Expected an argument\n"), SET_COLOR );
print_help();
return 1;
@@ -249,6 +256,7 @@ int main( int argc, char **argv )
fg = translate_color(fgcolor);
if( fgcolor && (fg==-1))
{
check_locale_init();
fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, fgcolor );
return 1;
}
@@ -256,6 +264,7 @@ int main( int argc, char **argv )
bg = translate_color(bgcolor);
if( bgcolor && (bg==-1))
{
check_locale_init();
fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, bgcolor );
return 1;
}

View File

@@ -12,7 +12,7 @@ complete -c apropos -s h -l help -d (_ "Display help and exit")
complete -f -c apropos -s d -l debug -d (_ "Print debugging info")
complete -f -c apropos -s v -l verbose -d (_ "Verbose mode")
complete -f -c apropos -s r -l regex -d (_ "Keyword as regex")
complete -f -c apropos -s w -l wildcard -d (_ "Keyword as wildwards")
complete -f -c apropos -s w -l wildcard -d (_ "Keyword as wildcards")
complete -f -c apropos -s e -l exact -d (_ "Keyword as exactly match")
complete -x -c apropos -s m -l system -d (_ "Search for other system")
complete -x -c apropos -s M -l manpath -a '(echo $MANPATH)' -d (_ "Specify man path")

View File

@@ -2,7 +2,7 @@
complete -c apt-listchanges -l help -d (_ "Display help and exit")
complete -c apt-listchanges -l apt -d (_ "Read filenames from pipe")
complete -f -c apt-listchanges -s v -l verbose -d (_ "Verbose mode")
complete -f -c apt-listchanges -s f -l frontend -a "pager browser xterm-pager xterm-browser text mail none" -d (_ "Select fronend interface")
complete -f -c apt-listchanges -s f -l frontend -a "pager browser xterm-pager xterm-browser text mail none" -d (_ "Select frontend interface")
complete -r -f -c apt-listchanges -l email-address -d (_ "Specify email address")
complete -f -c apt-listchanges -s c -l confirm -d (_ "Ask confirmation")
complete -f -c apt-listchanges -s a -l all -d (_ "Display all changelogs")

View File

@@ -12,7 +12,7 @@ complete -f -c apt-move -a mirror -d (_ "Download package missing from mirror")
complete -f -c apt-move -a sync -d (_ "Sync packages installed")
complete -f -c apt-move -a exclude -d 'test $LOCALDIR/.exclude file'
complete -c apt-move -a movefile -d (_ "Move file specified on commandline")
complete -f -c apt-move -a listbin -d (_ "List packags that may serve as input to mirrorbin or mirrorsource" )
complete -f -c apt-move -a listbin -d (_ "List packages that may serve as input to mirrorbin or mirrorsource" )
complete -f -c apt-move -a mirrorbin -d (_ "Fetch package from STDIN")
complete -f -c apt-move -a mirrorsrc -d (_ "Fetch source package from STDIN")
complete -f -c apt-move -s a -d (_ "Process all packages")

View File

@@ -1,6 +1,6 @@
#apt-rdepends
complete -c apt-rdepends -l help -d (_ "Display help and exit")
complete -f -c apt-rdepends -s b -l build-depends -d (_ "Show bulid dependencies")
complete -f -c apt-rdepends -s b -l build-depends -d (_ "Show build dependencies")
complete -f -c apt-rdepends -s d -l dotty -d (_ "Generate a dotty graph")
complete -f -c apt-rdepends -s p -l print-state -d (_ "Show state of dependencies")
complete -f -c apt-rdepends -s r -l reverse -d (_ "List packages depending on")

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