From 2744208ab3eab1741157e01484d08095bd8ef528 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 3 Feb 2024 20:10:52 -0800 Subject: [PATCH] unposted: elaboration on Roman's "slurp" implementation from zsh-users --- ChangeLog | 3 +++ Functions/Misc/zslurp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 Functions/Misc/zslurp diff --git a/ChangeLog b/ChangeLog index 386ef3ab9..238c12c16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-03 Bart Schaefer + * unposted: cf. Roman in users/29472: Functions/Misc/zslurp: + Efficient lossless read of stdin into $REPLY + * unposted: Src/Zle/zle_tricky.c, Src/parse.c, Src/pattern.c: Record as comments some notes about namespace usage exceptions. diff --git a/Functions/Misc/zslurp b/Functions/Misc/zslurp new file mode 100644 index 000000000..84df0c948 --- /dev/null +++ b/Functions/Misc/zslurp @@ -0,0 +1,31 @@ +#!/bin/zsh -f + +# Read stdin verbatim and as efficiently as possible into $REPLY, +# stopping without any change to $REPLY in the event of any error. +# Benchmarked by Roman Perepelitsa in zsh-users/29472 + +# Although this function faithfully records the input stream, later +# references to $REPLY with the multibyte option back in effect will +# (re-)interpret the content as multibyte characters. This may not be +# what is desired. + +emulate -L zsh -o no_multibyte + +### Alternate formulation, faster on bigger files +# # /dev/fd/0 is treated specially by -f so also check /dev/fd +# if [[ -d /dev/fd && -f /dev/fd/0 ]] && zmodload zsh/mapfile +# then +# local +h -Ar mapfile +# typeset -g REPLY="${mapfile[/dev/fd/0]}" && return +# fi +# # else fall through to read from pipe/socket + +zmodload zsh/system || return +local -a content +local -i i=0 +while true; do + sysread 'content[++i]' && continue + (( $? == 5 )) || return + break +done +typeset -g REPLY=${(j::)content}