Refactored completion server to use zsocket

This commit is contained in:
Thiago de Arruda 2013-10-28 19:51:04 -03:00
parent c183ca22de
commit 1e6e900abf
5 changed files with 131 additions and 33 deletions

View file

@ -6,8 +6,32 @@
# } # }
# zle -N zle-line-init # zle -N zle-line-init
# ``` # ```
# zmodload zsh/zpty zmodload zsh/net/socket
#
AUTOSUGGEST_SERVER_SCRIPT="${0:a:h}/completion-server.zsh"
# function {
# [[ -n $ZLE_DISABLE_AUTOSUGGEST ]] && return
# setopt local_options no_hup
# local server_dir="/tmp/zsh-autosuggest-$USER"
# local pid_file="$server_dir/pid"
# local socket_path="$server_dir/socket"
# if ! [[ -S $socket_path && -r $pid_file ]] || ! kill -0 $(<$pid_file) &>/dev/null; then
# # start server
# zsh $AUTOSUGGEST_SERVER_SCRIPT $server_dir $pid_file $socket_path &!
# fi
# integer remaining_tries=10
# # wait until the process is listening
# while ! [[ -d $server_dir && -r $pid_file ]] || ! kill -0 $(<$pid_file) &> /dev/null; do
# (( --remaining_tries )) || break
# sleep 0.3
# done
# ZLE_AUTOSUGGEST_SOCKET=$socket_path
# }
ZLE_AUTOSUGGEST_PAUSE_WIDGETS=( ZLE_AUTOSUGGEST_PAUSE_WIDGETS=(
vi-cmd-mode vi-backward-char backward-char backward-word beginning-of-line vi-cmd-mode vi-backward-char backward-char backward-word beginning-of-line
@ -146,9 +170,15 @@ paused-autosuggest-self-insert() {
} }
autosuggest-first-completion() { autosuggest-first-completion() {
local cursor=$CURSOR zsocket $ZLE_AUTOSUGGEST_SOCKET &>/dev/null || return 1
zle .complete-word || return 1 local connection=$REPLY
CURSOR=$cursor local completion
print -u $connection $LBUFFER
while read -u $connection completion; do
RBUFFER=" $completion"
break
done
exec {connection}>&-
} }
show-suggestion() { show-suggestion() {

25
completion-client.zsh Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/env zsh
# Helper script for debugging the completion server
zmodload zsh/net/socket
setopt no_hup
AUTOSUGGEST_SERVER_SCRIPT="${0:a:h}/completion-server.zsh"
server_dir="/tmp/zsh-autosuggest-$USER"
pid_file="$server_dir/pid"
socket_path="$server_dir/socket"
[[ -S $socket_path && -r $pid_file ]] && kill -0 $(<$pid_file) &> /dev/null ||\
zsh $AUTOSUGGEST_SERVER_SCRIPT $server_dir $pid_file $socket_path &!
# wait until the process is listening
while ! [[ -d $server_dir && -r $pid_file ]] || ! kill -0 $(<$pid_file) &> /dev/null; do
sleep 0.3
done
zsocket $socket_path
connection=$REPLY
print -u $connection vi
while read -u $connection completion; do
print $completion
done
exec {connection}>&-

View file

@ -96,6 +96,7 @@ compadd () {
# this is the point where we have all matches in $__hits and all # this is the point where we have all matches in $__hits and all
# descriptions in $__dscr! # descriptions in $__dscr!
__hits=(${(O)__hits})
# display all matches # display all matches
local dsuf dscr local dsuf dscr
for i in {1..$#__hits}; do for i in {1..$#__hits}; do

70
completion-server.zsh Executable file
View file

@ -0,0 +1,70 @@
#!/usr/bin/env zsh
# Based on:
# https://github.com/Valodim/zsh-capture-completion/blob/master/capture.zsh
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-to-null() {
connection=$1
integer consumed=0
while zpty -r z chunk; do
[[ $chunk == *$'\0'* ]] && break
(( consumed++ )) && continue
if [[ -n $connection ]]; then
print -n -u $connection $chunk
else
print -n $chunk &> /dev/null
fi
done
}
# wait for ok from shell
read-to-null
# listen on an unix domain socket
server_dir=$1
pid_file=$2
socket_path=$3
cleanup() {
rm -f $socket_path
rm -f $pid_file
}
trap cleanup TERM INT HUP EXIT
mkdir $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
zpty -w -n z $prefix$'\t'
zpty -r z chunk &> /dev/null # read empty line before completions
read-to-null $connection
exec {connection}>&-
zpty -w z $'\n'
done
done

View file

@ -1,28 +0,0 @@
#!/bin/zsh
# Based on:
# https://github.com/Valodim/zsh-capture-completion/blob/master/capture.zsh
zmodload zsh/zpty
setopt noglob
zpty z ZLE_DISABLE_AUTOSUGGEST=1 zsh -i
# Source the init script
zpty -w z "source '${0:a:h}/completion-service-init.zsh'"
read-to-null() {
while zpty -r z chunk; do
[[ $chunk == *$'\0'* ]] && break
print -n $chunk
done
}
# wait for ok from shell
read-to-null &> /dev/null
while read prefix &> /dev/null; do
zpty -w -n z $prefix$'\t'
zpty -r z chunk &> /dev/null # read empty line before completions
read-to-null
zpty -w z $'\n'
done