diff --git a/doc_src/psub.txt b/doc_src/psub.txt index e6347d851..42fb7257e 100644 --- a/doc_src/psub.txt +++ b/doc_src/psub.txt @@ -2,7 +2,7 @@ \subsection psub-synopsis Synopsis \fish{synopsis} -COMMAND1 ( COMMAND2 | psub [-f] ) +COMMAND1 ( COMMAND2 | psub [-f] [-s SUFFIX]) \endfish \subsection psub-description Description @@ -11,10 +11,15 @@ Posix shells feature a syntax that is a mix between command substitution and pip If the `-f` or `--file` switch is given to `psub`, `psub` will use a regular file instead of a named pipe to communicate with the calling process. This will cause `psub` to be significantly slower when large amounts of data are involved, but has the advantage that the reading process can seek in the stream. +If the `-s` or `---suffix` switch is given, `psub` will append SUFFIX to the filename. + \subsection psub-example Example \fish diff (sort a.txt | psub) (sort b.txt | psub) # shows the difference between the sorted versions of files `a.txt` and `b.txt`. -\endfish \ No newline at end of file + +source-highlight -f esc (cpp main.c | psub -s .c) +# highlights `main.c` after preprocessing as a C source. +\endfish diff --git a/share/functions/psub.fish b/share/functions/psub.fish index d19404493..221045312 100644 --- a/share/functions/psub.fish +++ b/share/functions/psub.fish @@ -1,42 +1,49 @@ function psub --description "Read from stdin into a file and output the filename. Remove the file when the command that called psub exits." + set -l dirname set -l filename set -l funcname + set -l suffix set -l use_fifo 1 - set -l shortopt -o hf - set -l longopt -l help,file - if getopt -T >/dev/null - set longopt - end + while count $argv >/dev/null - if not getopt -n psub -Q $shortopt $longopt -- $argv >/dev/null - return 1 - end - - set -l tmp (getopt $shortopt $longopt -- $argv) - - eval set opt $tmp - - while count $opt >/dev/null - - switch $opt[1] + switch $argv[1] case -h --help __fish_print_help psub return 0 case -f --file set use_fifo 0 + set -e argv[1] + + case -s --suffix + if not set -q argv[2] + printf "psub: missing operand\n" + return 1 + end + set suffix $argv[2] + set -e argv[1..2] case -- - set -e opt[1] + set -e argv[1] break + case "-?" "--*" + printf "psub: invalid option: '%s'\n" $argv[1] + return 1 + + case "-*" + # Ungroup short options: -hfs => -h -f -s + set opts "-"(string sub -s 2 -- $argv[1] | string split "") + set -e argv[1] + set argv $opts $argv + + case "*" + printf "psub: extra operand: '%s'\n" $argv[1] + return 1 end - - set -e opt[1] - end if not status --is-command-substitution @@ -53,13 +60,17 @@ function psub --description "Read from stdin into a file and output the filename # Write output to pipe. This needs to be done in the background so # that the command substitution exits without needing to wait for # all the commands to exit - set dir (mktemp -d "$TMPDIR[1]"/.psub.XXXXXXXXXX); or return - set filename $dir/psub.fifo + set dirname (mktemp -d "$TMPDIR[1]"/.psub.XXXXXXXXXX); or return + set filename $dirname/psub.fifo"$suffix" mkfifo $filename cat >$filename & - else + else if test -z $suffix set filename (mktemp "$TMPDIR[1]"/.psub.XXXXXXXXXX) cat >$filename + else + set dirname (mktemp -d "$TMPDIR[1]"/.psub.XXXXXXXXXX) + set filename $dirname/psub"$suffix" + cat >$filename end # Write filename to stdout @@ -74,8 +85,11 @@ function psub --description "Read from stdin into a file and output the filename end # Make sure we erase file when caller exits - function $funcname --on-job-exit caller --inherit-variable filename --inherit-variable funcname + function $funcname --on-job-exit caller --inherit-variable filename --inherit-variable dirname --inherit-variable funcname command rm $filename + if count $dirname >/dev/null + command rmdir $dirname + end functions -e $funcname end diff --git a/tests/test9.in b/tests/test9.in index 962fae8c9..1199609bf 100644 --- a/tests/test9.in +++ b/tests/test9.in @@ -97,6 +97,27 @@ else echo 'psub file was deleted' end +if count (echo foo | psub -s .cc | grep -o '\.cc$') >/dev/null + echo 'psub filename ends with .cc' +else + echo 'psub filename does not end with .cc' +end + +if count (echo foo | psub -f -s .cc | grep -o '\.cc$') >/dev/null + echo 'psub filename ends with .cc' +else + echo 'psub filename does not end with .cc' +end + +set -l filename (echo foo | psub -s .fish) +if test -e (dirname $filename) + echo 'psub directory was not deleted' +else + echo 'psub directory was deleted' +end + +diff -q (__fish_print_help psub | psub) (psub -hs banana | psub) + # Test support for unbalanced blocks function try_unbalanced_block ../fish -c "echo $argv | source " 2>&1 | grep "Missing end" 1>&2 diff --git a/tests/test9.out b/tests/test9.out index f33c85ace..8419e6975 100644 --- a/tests/test9.out +++ b/tests/test9.out @@ -17,6 +17,9 @@ foo bar baz psub file was deleted +psub filename ends with .cc +psub filename ends with .cc +psub directory was deleted bom_test not#a#comment is