diff --git a/src/strategies/completion.zsh b/src/strategies/completion.zsh
index aa87673..e8aac6c 100644
--- a/src/strategies/completion.zsh
+++ b/src/strategies/completion.zsh
@@ -3,90 +3,104 @@
 # Completion Suggestion Strategy                                     #
 #--------------------------------------------------------------------#
 # Fetches suggestions from zsh's completion engine
+# Based on https://github.com/Valodim/zsh-capture-completion
 #
 
-# Big thanks to https://github.com/Valodim/zsh-capture-completion
-_zsh_autosuggest_capture_completion() {
-	zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME zsh -f -i
-
-	local line
-
-	setopt rcquotes
-	() {
-		# Initialize the pty env, blocking until null byte is seen
-		zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "source $1"
-		zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0'
-	} =( <<< '
-	exec 2>/dev/null # Silence any error messages
-
-	autoload compinit
-	compinit -d ~/.zcompdump_autosuggestions
-
-	# Exit as soon as completion is finished
-	comppostfuncs=( exit )
+_zsh_autosuggest_capture_setup() {
+	zmodload zsh/zutil # For `zparseopts`
 
 	# Never group stuff!
-	zstyle '':completion:*'' list-grouped false
+	zstyle ':completion:*' list-grouped false
 
-	# no list separator, this saves some stripping later on
-	zstyle '':completion:*'' list-separator ''''
+	# No list separator, this saves some stripping later on
+	zstyle ':completion:*' list-separator ''
 
-	# we use zparseopts
-	zmodload zsh/zutil
-
-	# override compadd (this our hook)
+	# Override compadd (this is our hook)
 	compadd () {
+		setopt localoptions norcexpandparam
+
 		# Just delegate and leave if any of -O, -A or -D are given
 		if [[ ${@[1,(i)(-|--)]} == *-(O|A|D)\ * ]]; then
 			builtin compadd "$@"
 			return $?
 		fi
 
-		setopt localoptions norcexpandparam extendedglob
-
-		typeset -a __hits
-
 		# Capture completions by injecting -A parameter into the compadd call.
 		# This takes care of matching for us.
+		typeset -a __hits
 		builtin compadd -A __hits "$@"
 
 		# Exit if no completion results
 		[[ -n $__hits ]] || return
 
-		# Extract prefixes and suffixes from compadd call. we can''t do zsh''s cool
-		# -r remove-func magic, but it''s better than nothing.
+		# Extract prefixes and suffixes from compadd call. we can't do zsh's cool
+		# -r remove-func magic, but it's better than nothing.
 		typeset -A apre hpre hsuf asuf
 		zparseopts -E P:=apre p:=hpre S:=asuf s:=hsuf
 
 		# Print the first match
-		echo -nE - $''\0''$IPREFIX$apre$hpre$__hits[1]$dsuf$hsuf$asuf$''\0''
+		echo -nE - $'\0'$IPREFIX$apre$hpre$__hits[1]$dsuf$hsuf$asuf$'\0'
+	}
+}
+
+_zsh_autosuggest_capture_widget() {
+	_zsh_autosuggest_capture_setup
+
+	zle complete-word
+}
+
+zle -N autosuggest-capture-completion _zsh_autosuggest_capture_widget
+
+_zsh_autosuggest_capture_buffer() {
+	local BUFFERCONTENT="$1"
+
+	_zsh_autosuggest_capture_setup
+
+	zmodload zsh/parameter # For `$functions`
+
+	# Make vared completion work as if for a normal command line
+	# https://stackoverflow.com/a/7057118/154703
+	autoload +X _complete
+	functions[_original_complete]=$functions[_complete]
+	_complete () {
+		unset 'compstate[vared]'
+		_original_complete "$@"
 	}
 
-	# Signal setup completion by sending null byte
-	echo $''\0''
-	')
+	# Open zle with buffer set so we can capture completions for it
+	vared BUFFERCONTENT
+}
 
-	# Send the string and a tab to trigger completion
-	zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "$*"$'\t'
+_zsh_autosuggest_capture_completion() {
+	typeset -g completion
+	local line
 
-	# Read up to the start of the first result
+	# Zle will be inactive if we are in async mode
+	if zle; then
+		zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME zle autosuggest-capture-completion
+	else
+		zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "_zsh_autosuggest_capture_buffer '$1'"
+		zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME $'\t'
+	fi
+
+	# The completion result is surrounded by null bytes, so read the
+	# content between the first two null bytes.
 	zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0'
-
-	# Read the first result
 	zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0'
+	completion="${line%$'\0'}"
 
-	# Print it, removing the trailing null byte
-	echo -E - ${line%$'\0'}
+	# Destroy the pty
+	zpty -d $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME
 }
 
 _zsh_autosuggest_strategy_completion() {
-	typeset -g suggestion=$(_zsh_autosuggest_capture_completion "$1" | head -n 1)
+	typeset -g suggestion completion
 
-	# Strip the trailing carriage return
-	suggestion="${suggestion%$'\r'}"
+	# Fetch the first completion result
+	_zsh_autosuggest_capture_completion "$1"
 
 	# Add the completion string to the buffer to build the full suggestion
 	local -i i=1
-	while [[ "$suggestion" != "${1[$i,-1]}"* ]]; do ((i++)); done
-	suggestion="${1[1,$i-1]}$suggestion"
+	while [[ "$completion" != "${1[$i,-1]}"* ]]; do ((i++)); done
+	suggestion="${1[1,$i-1]}$completion"
 }
diff --git a/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh
index c29eb9e..40f6f66 100644
--- a/zsh-autosuggestions.zsh
+++ b/zsh-autosuggestions.zsh
@@ -500,92 +500,106 @@ zle -N autosuggest-toggle _zsh_autosuggest_widget_toggle
 # Completion Suggestion Strategy                                     #
 #--------------------------------------------------------------------#
 # Fetches suggestions from zsh's completion engine
+# Based on https://github.com/Valodim/zsh-capture-completion
 #
 
-# Big thanks to https://github.com/Valodim/zsh-capture-completion
-_zsh_autosuggest_capture_completion() {
-	zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME zsh -f -i
-
-	local line
-
-	setopt rcquotes
-	() {
-		# Initialize the pty env, blocking until null byte is seen
-		zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "source $1"
-		zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0'
-	} =( <<< '
-	exec 2>/dev/null # Silence any error messages
-
-	autoload compinit
-	compinit -d ~/.zcompdump_autosuggestions
-
-	# Exit as soon as completion is finished
-	comppostfuncs=( exit )
+_zsh_autosuggest_capture_setup() {
+	zmodload zsh/zutil # For `zparseopts`
 
 	# Never group stuff!
-	zstyle '':completion:*'' list-grouped false
+	zstyle ':completion:*' list-grouped false
 
-	# no list separator, this saves some stripping later on
-	zstyle '':completion:*'' list-separator ''''
+	# No list separator, this saves some stripping later on
+	zstyle ':completion:*' list-separator ''
 
-	# we use zparseopts
-	zmodload zsh/zutil
-
-	# override compadd (this our hook)
+	# Override compadd (this is our hook)
 	compadd () {
+		setopt localoptions norcexpandparam
+
 		# Just delegate and leave if any of -O, -A or -D are given
 		if [[ ${@[1,(i)(-|--)]} == *-(O|A|D)\ * ]]; then
 			builtin compadd "$@"
 			return $?
 		fi
 
-		setopt localoptions norcexpandparam extendedglob
-
-		typeset -a __hits
-
 		# Capture completions by injecting -A parameter into the compadd call.
 		# This takes care of matching for us.
+		typeset -a __hits
 		builtin compadd -A __hits "$@"
 
 		# Exit if no completion results
 		[[ -n $__hits ]] || return
 
-		# Extract prefixes and suffixes from compadd call. we can''t do zsh''s cool
-		# -r remove-func magic, but it''s better than nothing.
+		# Extract prefixes and suffixes from compadd call. we can't do zsh's cool
+		# -r remove-func magic, but it's better than nothing.
 		typeset -A apre hpre hsuf asuf
 		zparseopts -E P:=apre p:=hpre S:=asuf s:=hsuf
 
 		# Print the first match
-		echo -nE - $''\0''$IPREFIX$apre$hpre$__hits[1]$dsuf$hsuf$asuf$''\0''
+		echo -nE - $'\0'$IPREFIX$apre$hpre$__hits[1]$dsuf$hsuf$asuf$'\0'
+	}
+}
+
+_zsh_autosuggest_capture_widget() {
+	_zsh_autosuggest_capture_setup
+
+	zle complete-word
+}
+
+zle -N autosuggest-capture-completion _zsh_autosuggest_capture_widget
+
+_zsh_autosuggest_capture_buffer() {
+	local BUFFERCONTENT="$1"
+
+	_zsh_autosuggest_capture_setup
+
+	zmodload zsh/parameter # For `$functions`
+
+	# Make vared completion work as if for a normal command line
+	# https://stackoverflow.com/a/7057118/154703
+	autoload +X _complete
+	functions[_original_complete]=$functions[_complete]
+	_complete () {
+		unset 'compstate[vared]'
+		_original_complete "$@"
 	}
 
-	# Signal setup completion by sending null byte
-	echo $''\0''
-	')
+	# Open zle with buffer set so we can capture completions for it
+	vared BUFFERCONTENT
+}
 
-	# Send the string and a tab to trigger completion
-	zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "$*"$'\t'
+_zsh_autosuggest_capture_completion() {
+	typeset -g completion
+	local line
 
-	# Read up to the start of the first result
+	# Zle will be inactive if we are in async mode
+	if zle; then
+		zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME zle autosuggest-capture-completion
+	else
+		zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "_zsh_autosuggest_capture_buffer '$1'"
+		zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME $'\t'
+	fi
+
+	# The completion result is surrounded by null bytes, so read the
+	# content between the first two null bytes.
 	zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0'
-
-	# Read the first result
 	zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0'
+	completion="${line%$'\0'}"
 
-	# Print it, removing the trailing null byte
-	echo -E - ${line%$'\0'}
+	# Destroy the pty
+	zpty -d $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME
 }
 
 _zsh_autosuggest_strategy_completion() {
-	typeset -g suggestion=$(_zsh_autosuggest_capture_completion "$1" | head -n 1)
+	typeset -g suggestion completion
 
-	# Strip the trailing carriage return
-	suggestion="${suggestion%$'\r'}"
+	# Fetch the first completion result
+	_zsh_autosuggest_capture_completion "$1"
 
 	# Add the completion string to the buffer to build the full suggestion
 	local -i i=1
-	while [[ "$suggestion" != "${1[$i,-1]}"* ]]; do ((i++)); done
-	suggestion="${1[1,$i-1]}$suggestion"
+	while [[ "$completion" != "${1[$i,-1]}"* ]]; do ((i++)); done
+	suggestion="${1[1,$i-1]}$completion"
 }
 
 #--------------------------------------------------------------------#