From d87f29f564286c4a233e454d8208b83b97b1366d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc=20Cornell=C3=A0?= <marc.cornella@live.com>
Date: Thu, 23 Sep 2021 12:33:37 +0200
Subject: [PATCH] refactor(vim-interaction): clean up code and open gvim
 instance if none open (#10209)

Co-authored-by: Kevin Bader <keb@visotech.at>
---
 .../vim-interaction.plugin.zsh                | 48 +++++++++++--------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/plugins/vim-interaction/vim-interaction.plugin.zsh b/plugins/vim-interaction/vim-interaction.plugin.zsh
index 53ec453e8..b73f9b4da 100644
--- a/plugins/vim-interaction/vim-interaction.plugin.zsh
+++ b/plugins/vim-interaction/vim-interaction.plugin.zsh
@@ -4,8 +4,7 @@
 # Derek Wyatt (derek@{myfirstnamemylastname}.org
 # 
 
-function callvim
-{
+function callvim {
   if [[ $# == 0 ]]; then
     cat <<EOH
 usage: callvim [-b cmd] [-a cmd] [-n name] [file ... fileN]
@@ -19,11 +18,20 @@ EOH
     return 0
   fi
 
-  local cmd=""
-  local before="<esc>"
-  local after=""
-  # Look up the newest instance
+  # Look up the newest instance or start one
   local name="$(gvim --serverlist | tail -n 1)"
+  [[ -n "$name" ]] || {
+    # run gvim or exit if it fails
+    gvim || return $?
+
+    # wait for gvim instance to fully load
+    while name=$(gvim --serverlist) && [[ -z "$name" ]]; do
+      sleep 0.1
+    done
+  }
+
+  local before="<esc>" files after cmd
+
   while getopts ":b:a:n:" option
   do
     case $option in
@@ -36,22 +44,20 @@ EOH
     esac
   done
   shift $((OPTIND-1))
-  if [[ ${after#:} != $after && ${after%<cr>} == $after ]]; then
-    after="$after<cr>"
-  fi
-  if [[ ${before#:} != $before && ${before%<cr>} == $before ]]; then
-    before="$before<cr>"
-  fi
-  local files
-  if [[ $# -gt 0 ]]; then
-    # absolute path of files resolving symlinks (:A) and quoting special chars (:q)
-    files=':args! '"${@:A:q}<cr>"
-  fi
+
+  # If before or after commands begin with : and don't end with <cr>, append it
+  [[ ${after}  = :* && ${after}  != *\<cr\> ]] && after+="<cr>"
+  [[ ${before} = :* && ${before} != *\<cr\> ]] && before+="<cr>"
+  # Open files passed (:A means abs path resolving symlinks, :q means quoting special chars)
+  [[ $# -gt 0 ]] && files=':args! '"${@:A:q}<cr>"
+  # Pass the built vim command to gvim
   cmd="$before$files$after"
-  gvim --servername "$name" --remote-send "$cmd"
-  if typeset -f postCallVim > /dev/null; then
-    postCallVim
-  fi
+
+  # Run the gvim command
+  gvim --servername "$name" --remote-send "$cmd" || return $?
+
+  # Run postCallVim if defined (maybe to bring focus to gvim, see README)
+  (( ! $+functions[postCallVim] )) || postCallVim
 }
 
 alias v=callvim