diff --git a/autosuggestions.zsh b/autosuggestions.zsh index 7b62de9..fb5ffe6 100644 --- a/autosuggestions.zsh +++ b/autosuggestions.zsh @@ -6,8 +6,32 @@ # } # 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=( vi-cmd-mode vi-backward-char backward-char backward-word beginning-of-line @@ -146,9 +170,15 @@ paused-autosuggest-self-insert() { } autosuggest-first-completion() { - local cursor=$CURSOR - zle .complete-word || return 1 - CURSOR=$cursor + zsocket $ZLE_AUTOSUGGEST_SOCKET &>/dev/null || return 1 + local connection=$REPLY + local completion + print -u $connection $LBUFFER + while read -u $connection completion; do + RBUFFER=" $completion" + break + done + exec {connection}>&- } show-suggestion() { diff --git a/completion-client.zsh b/completion-client.zsh new file mode 100755 index 0000000..9439bd9 --- /dev/null +++ b/completion-client.zsh @@ -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}>&- diff --git a/completion-service-init.zsh b/completion-server-init.zsh similarity index 99% rename from completion-service-init.zsh rename to completion-server-init.zsh index 6b997f7..f5c59da 100644 --- a/completion-service-init.zsh +++ b/completion-server-init.zsh @@ -96,6 +96,7 @@ compadd () { # this is the point where we have all matches in $__hits and all # descriptions in $__dscr! + __hits=(${(O)__hits}) # display all matches local dsuf dscr for i in {1..$#__hits}; do diff --git a/completion-server.zsh b/completion-server.zsh new file mode 100755 index 0000000..cb1a4fb --- /dev/null +++ b/completion-server.zsh @@ -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 diff --git a/completion-service.zsh b/completion-service.zsh deleted file mode 100755 index 8092e09..0000000 --- a/completion-service.zsh +++ /dev/null @@ -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