Screen: Grouping all vim invokation under one window

1

In screen, would it possible to open up all instances of vim in one window? (e.g. window 2) Initially, the window will switch to the designated window and open up the file in the buffer. And consequent invocation of vim (from other windows) will open the file in new tab of vim in that window. I am running cygwin.

Forethinker

Posted 2013-03-09T20:59:22.260

Reputation: 640

Answers

1

This is a great question and an awesome idea! I can't wait to incorporate it into my workflow.

Anyway, in my opinion, the best way to pull this off is to use vim's server functionality, which allows you to control your running vim instance using the vim command.

The idea is that the first time you run vim, you'll run it as:

vim --servername $VIM_SERVER_NAME

and then everytime you want to open a new tab in this instance, you'll run:

vim --servername $VIM_SERVER_NAME --remote-tab $PATH_TO_FILE_TO_OPEN

Apart from this, the only thing you'll need to add is the logic for identifying and switching to the vim window (which can be done using the window title).

I've put all of this together in the following shell function:

v() {
  if [ $STY ]; then
    # screen
    VIM_SERVER_NAME="VIM-SCREEN-$STY"

    if [ "`vim --serverlist | grep -i $VIM_SERVER_NAME`" = "" ]; then
      # No vim server, become the server
      screen -X title vim
      vim --servername $VIM_SERVER_NAME "$@"
      screen -X title `basename $SHELL`
    else
      # A vim server exists, use it, then switch to it.
      vim --servername $VIM_SERVER_NAME --remote-tab "$@"
      screen -X select vim
    fi
  else
    vim $@
  fi
}

If you add this function definition in ~/.profile (or ~/.bash_profile if you use bash), then whenever you want to use vim, just use v instead. It will check if you're currently in a screen session, and if so, it will use the designated vim window and switch to it (or make the current window the designated vim window if none exist), otherwise it will fallback to using vim normally. It should also work even if you're using several screen sessions at the same time and you're using v in all of them.

Notice that I also reset the window title to the shell name if/when you exit the vim server, this is to avoid having two or more windows with the title "vim" if you use v in a different window after closing it in one.

Because I'm more of a tmux guy, this is the shell function I'm actually planning to use:

v() {
  if [ $STY ]; then
    # screen
    VIM_SERVER_NAME="VIM-SCREEN-$STY"

    if [ "`vim --serverlist | grep -i $VIM_SERVER_NAME`" = "" ]; then
      # No vim server, become the server
      screen -X title vim
      vim --servername $VIM_SERVER_NAME "$@"
      screen -X title `basename $SHELL`
    else
      # A vim server exists, use it, then switch to it.
      vim --servername $VIM_SERVER_NAME --remote-tab "$@"
      screen -X select vim
    fi
  elif [ $TMUX ]; then
    # tmux
    VIM_SERVER_NAME="VIM-TMUX-`tmux list-windows -F '#{session_name}' | head -1`"

    if [ "`vim --serverlist | grep -i $VIM_SERVER_NAME`" = "" ]; then
      # No vim server, become the server
      tmux rename-window vim
      vim --servername $VIM_SERVER_NAME "$@"
      tmux rename-window `basename $SHELL`
    else
      # A vim server exists, use it, then switch to it.
      vim --servername $VIM_SERVER_NAME --remote-tab "$@"
      tmux select-window -t vim
    fi
  else
    vim "$@"
  fi
}

This version of the function will work for both tmux and screen (as many different sessions as you like), and fallback to normal vim if not within either.

maljub01

Posted 2013-03-09T20:59:22.260

Reputation: 161

If anyone's interested, Here's a link to the github gist: https://gist.github.com/maljub01/5130023

– maljub01 – 2013-03-10T19:34:17.657

1sorry for my late response. I was exploring the possibility of running this script in cygwin environment. I found this to be impossible with current XWin dependency for gVim and such. But I found you answer to be the best one so far and it gave me the idea to run everything in gVim via remote-silent-tab flag. This is not through screen, but still groups all instances of vim together. – Forethinker – 2013-04-21T00:54:01.380

0

You can't run two instances of vim in different screen windows that will allow you to edit one file simultaneously from both instances. If you try to open a second instance of vim to edit the same file, you will get a message warning you that the file is already being edited.

That said, you can open a second instance of vim in a new screen window to view the current file by executing this command within vim:

:!screen screen vim -R %

The -R option starts vim in read-only mode.

garyjohn

Posted 2013-03-09T20:59:22.260

Reputation: 29 085

This is a good work around to know. But I revised my question again for clarity. – Forethinker – 2013-03-09T22:29:50.960