diff .zfun/zsh-autosuggestions/src/async.zsh @ 467:e1ce8897030d

zsh: import df6f6f9ff41 of zsh-autosuggestions
author Augie Fackler <raf@durin42.com>
date Mon, 03 Dec 2018 22:37:29 -0500
parents
children
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/.zfun/zsh-autosuggestions/src/async.zsh
@@ -0,0 +1,109 @@
+
+#--------------------------------------------------------------------#
+# Async                                                              #
+#--------------------------------------------------------------------#
+
+# Zpty process is spawned running this function
+_zsh_autosuggest_async_server() {
+	emulate -R zsh
+
+	# There is a bug in zpty module (fixed in zsh/master) by which a
+	# zpty that exits will kill all zpty processes that were forked
+	# before it. Here we set up a zsh exit hook to SIGKILL the zpty
+	# process immediately, before it has a chance to kill any other
+	# zpty processes.
+	zshexit() {
+		kill -KILL $$
+		sleep 1 # Block for long enough for the signal to come through
+	}
+
+	# Don't add any extra carriage returns
+	stty -onlcr
+
+	# Don't translate carriage returns to newlines
+	stty -icrnl
+
+	# Silence any error messages
+	exec 2>/dev/null
+
+	local last_pid
+
+	while IFS='' read -r -d $'\0' query; do
+		# Kill last bg process
+		kill -KILL $last_pid &>/dev/null
+
+		# Run suggestion search in the background
+		(
+			local suggestion
+			_zsh_autosuggest_fetch_suggestion "$query"
+			echo -n -E "$suggestion"$'\0'
+		) &
+
+		last_pid=$!
+	done
+}
+
+_zsh_autosuggest_async_request() {
+	# Write the query to the zpty process to fetch a suggestion
+	zpty -w -n $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME "${1}"$'\0'
+}
+
+# Called when new data is ready to be read from the pty
+# First arg will be fd ready for reading
+# Second arg will be passed in case of error
+_zsh_autosuggest_async_response() {
+	setopt LOCAL_OPTIONS EXTENDED_GLOB
+
+	local suggestion
+
+	zpty -rt $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME suggestion '*'$'\0' 2>/dev/null
+	zle autosuggest-suggest -- "${suggestion%%$'\0'##}"
+}
+
+_zsh_autosuggest_async_pty_create() {
+	# With newer versions of zsh, REPLY stores the fd to read from
+	typeset -h REPLY
+
+	# If we won't get a fd back from zpty, try to guess it
+	if (( ! $_ZSH_AUTOSUGGEST_ZPTY_RETURNS_FD )); then
+		integer -l zptyfd
+		exec {zptyfd}>&1  # Open a new file descriptor (above 10).
+		exec {zptyfd}>&-  # Close it so it's free to be used by zpty.
+	fi
+
+	# Fork a zpty process running the server function
+	zpty -b $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME _zsh_autosuggest_async_server
+
+	# Store the fd so we can remove the handler later
+	if (( REPLY )); then
+		_ZSH_AUTOSUGGEST_PTY_FD=$REPLY
+	else
+		_ZSH_AUTOSUGGEST_PTY_FD=$zptyfd
+	fi
+
+	# Set up input handler from the zpty
+	zle -F $_ZSH_AUTOSUGGEST_PTY_FD _zsh_autosuggest_async_response
+}
+
+_zsh_autosuggest_async_pty_destroy() {
+	# Remove the input handler
+	zle -F $_ZSH_AUTOSUGGEST_PTY_FD &>/dev/null
+
+	# Destroy the zpty
+	zpty -d $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME &>/dev/null
+}
+
+_zsh_autosuggest_async_pty_recreate() {
+	_zsh_autosuggest_async_pty_destroy
+	_zsh_autosuggest_async_pty_create
+}
+
+_zsh_autosuggest_async_start() {
+	typeset -g _ZSH_AUTOSUGGEST_PTY_FD
+
+	_zsh_autosuggest_feature_detect_zpty_returns_fd
+	_zsh_autosuggest_async_pty_recreate
+
+	# We recreate the pty to get a fresh list of history events
+	add-zsh-hook precmd _zsh_autosuggest_async_pty_recreate
+}