zsh-autosuggestions/completion-server.zsh
Thiago de Arruda 4ca0501c25 Add magic prefix to distinguish completion lines
from possible garbage output generated by the completion function
2013-10-29 08:26:59 -03:00

81 lines
1.8 KiB
Bash
Executable file

#!/usr/bin/env zsh
# Based on:
# https://github.com/Valodim/zsh-capture-completion/blob/master/capture.zsh
# close stdio
exec &> /dev/null
exec < /dev/null
zmodload zsh/zpty
zmodload zsh/net/socket
setopt noglob
# Start an interactive zsh connected to a zpty
zpty z ZLE_DISABLE_AUTOSUGGEST=1 zsh -i
# Source the init script
zpty -w z "source '${0:a:h}/completion-server-init.zsh'"
# read all completions and return the longest match
read-to-null() {
while zpty -r z chunk; do
[[ $chunk == *$'\0'* ]] && break
[[ $chunk != $'\1'* ]] && continue # ignore what doesnt start with '1'
print -n - ${chunk:1}
done
}
# wait for ok from shell
read-to-null &> /dev/null
# listen on a socket for completion requests
server_dir=$1
pid_file=$2
socket_path=$3
cleanup() {
rm -f $socket_path $pid_file
}
trap cleanup TERM INT HUP EXIT
mkdir -m 700 $server_dir &> /dev/null
while ! zsocket -l $socket_path; do
if [[ ! -r $pid_file ]] || ! kill -0 $(<$pid_file) &> /dev/null; then
rm -f $socket_path
else
exit 1
fi
done
print $$ > $pid_file
server=$REPLY
while zsocket -a $server &> /dev/null; do
connection=$REPLY
# connection accepted, read the request and send response
while read -u $connection prefix &> /dev/null; do
# send the prefix to be completed followed by a TAB to force
# completion
zpty -w -n z $prefix$'\t'
zpty -r z chunk &> /dev/null # read empty line before completions
local current=''
# read completions one by one, storing the longest match
read-to-null | while read line; do
(( $#line > $#current )) && current=$line
done
# send the longest completion back to the client, strip the last
# non-printable character
if (( $#current )); then
print -u $connection - ${current:0:-1}
else
print -u $connection ''
fi
# close fd
exec {connection}>&-
# clear input buffer
zpty -w z $'\n'
done
done