Loading ...
Sorry, an error occurred while loading the content.

12166Re: mvim: bring forward window/tab of already open window instead of Alert

Expand Messages
  • Eric Wing
    Mar 12, 2011
      I thought I would share what I have so far. I wasn't able to figure
      out how to pass parameters like line numbers for already open files,
      but for my usage, it's not that important to me. The avoidance of the
      alert/lock and bringing forward the already open window/tab was key
      for me.

      Maybe others are interested in this or can improve it. And maybe it is
      reasonable enough for inclusion into mainline?

      Script pasted below.

      Thanks,
      Eric
      --
      Beginning iPhone Games Development
      http://playcontrol.net/iphonegamebook/



      #!/bin/sh
      #
      # This shell script passes all its arguments to the binary inside the
      # MacVim.app application bundle. If you make links to this script as view,
      # gvim, etc., then it will peek at the name used to call it and set options
      # appropriately.
      #
      # Based on a script by Wout Mertens and suggestions from Laurent Bihanic. This
      # version is the fault of Benji Fisher, 16 May 2005 (with modifications by Nico
      # Weber and Bjorn Winckler, Aug 13 2007).
      # First, check "All the Usual Suspects" for the location of the Vim.app bundle.
      # You can short-circuit this by setting the VIM_APP_DIR environment variable
      # or by un-commenting and editing the following line:
      # VIM_APP_DIR=/Applications

      if [ -z "$VIM_APP_DIR" ]
      then
      myDir="`dirname "$0"`"
      myAppDir="$myDir/../Applications"
      for i in ~/Applications ~/Applications/vim $myDir $myDir/vim
      $myAppDir $myAppDir/vim /Applications /Applications/vim
      /Applications/Utilities /Applications/Utilities/vim; do
      if [ -x "$i/MacVim.app" ]; then
      VIM_APP_DIR="$i"
      break
      fi
      done
      fi
      if [ -z "$VIM_APP_DIR" ]
      then
      echo "Sorry, cannot find MacVim.app. Try setting the VIM_APP_DIR
      environment variable to the directory containing MacVim.app."
      exit 1
      fi
      binary="$VIM_APP_DIR/MacVim.app/Contents/MacOS/Vim"

      # Next, peek at the name used to invoke this script, and set options
      # accordingly.

      name="`basename "$0"`"
      gui=
      opts=

      # GUI mode, implies forking
      case "$name" in m*|g*|rg*) gui=true ;; esac

      # Restricted mode
      case "$name" in r*) opts="$opts -Z";; esac

      # vimdiff and view
      case "$name" in
      *vimdiff)
      opts="$opts -dO"
      ;;
      *view)
      opts="$opts -R"
      ;;
      esac

      # Last step: fire up vim.
      # The program should fork by default when started in GUI mode, but it does
      # not; we work around this when this script is invoked as "gvim" or "rgview"
      # etc., but not when it is invoked as "vim -g".
      if [ "$gui" ]; then
      # Note: this isn't perfect, because any error output goes to the
      # terminal instead of the console log.
      # But if you use open instead, you will need to fully qualify the
      # path names for any filenames you specify, which is hard.
      did_find_file=0
      declare -a found_file_list


      # The following code tries to handle the case where a file is already
      # open in a window/tab. Instead of alerting the user the file is
      # already open, we should just bring the window/tab forward.

      # Get the list of VIM servers so we can query each one to find if it
      # contains the file we are looking for
      serverlist=`"$binary" --serverlist`
      for server in $serverlist; do
      # echo "server is $server"

      # Lookup each file in this server to see if it contains the an already
      # open window/tab we are looking for.
      for a_file in "${1:+"$@"}"; do
      # echo "a_file $a_file"

      # This remote expression found in MMAppController.m,
      # (see evaluateVimExpression) will return the number of
      # buffers matching our request. If we get more than 0 back,
      # the server already has the file we are looking for open.
      # We request one file here, so the max we get back should be 1.
      ret_num=`"$binary" --servername $server --remote-expr
      "map([\"$a_file\"],\"bufloaded(v:val)\")"`
      # echo "ret_num $ret_num"

      if [ "$ret_num" != "" ] && [ "$ret_num" -gt 0 ]; then
      # The server has the window/tab we are looking for.
      # This remote-send command will send some commands to
      # make the window/tab come forward.
      `"$binary" -g $opts --servername $server --remote-send
      "<C-\\><C-N>:let oldswb=&swb|let &swb=\"useopen,usetab\" | tab sb
      $a_file |let &swb=oldswb|unl oldswb|cal foreground()<CR><CR>"`

      did_find_file=1
      # echo "found file: $a_file, adding to found_file_list"
      # Because multiple files could be passed as arguments,
      # we need to keep track of which files we found so we
      # can later distinguish which files we need to create/open.
      found_file_list[${#found_file_list[*]}]=$a_file
      #found_file_list=( "${found_file_list[@]}" "$a_file" )
      fi
      done

      done

      # If multiple files were listed as arguments, there is a possibility
      # there is a mixture of both types.
      # So we need to determine the list of files we didn't find already open
      # and open those up.

      if [ "$did_find_file" == 0 ]; then
      # If we found no files at all, we have a trivial case and can just
      # do the standard behavior.
      exec "$binary" -g $opts ${1:+"$@"}
      else
      declare -a new_file_list

      # We will loop through all files and compare to all files we found
      # to be open. If the file was not opened, we add this to our
      # new_file_list so we can act on it later.
      for a_file in "${1:+"$@"}"; do
      # echo "a_file2 $a_file"
      # Initialize flag...assume we need to open new file until we find it
      need_to_create_file=1

      # for-in syntax doesn't seem to work with arrays
      # ...can only get first value.
      # Using numeric for instead
      for ((i=0; i<${#found_file_list[*]}; i++)); do
      found_file=${found_file_list[$i]}
      # echo "found_file2 $found_file"
      if [ "$found_file" == "$a_file" ]; then
      # echo "$found_file == $a_file"
      # We can skip this file
      need_to_create_file=0
      break
      fi
      done
      if [ $need_to_create_file == 1 ]; then
      # Append the file to the list
      new_file_list[${#new_file_list[*]}]=$a_file
      fi
      done

      # If there are remaining files, pass the list to open new windows
      if (( ${#new_file_list[@]} > 0 )); then
      exec "$binary" -g $opts "${new_file_list[@]}"
      fi
      fi
      else
      exec "$binary" $opts ${1:+"$@"}
      fi

      --
      You received this message from the "vim_mac" maillist.
      Do not top-post! Type your reply below the text you are replying to.
      For more information, visit http://www.vim.org/maillist.php
    • Show all 8 messages in this topic