Search code examples
vimcygwin

translating a linux vimrc function to one that will work in cygwin


I use screen and vim a lot. Therefore, when I go to open a file that I already have open in another vim session, in another screen window, I hate playing "where's waldo" and trying to figure out just which of my 22 screen windows that file happens to be opened in.
Therefore, I wrote the following .vimrc functions, that have worked well for me over the years in both redhat, debian, ubuntu, and centos. However, it isn't working in cygwin, because "lsof" is not found. From time to time I have had to slightly modify the functions, just to get the paths to work, but in general, these little guys have done well for me. When I go to open a file that is already opened in another window in vim, vim will actually tell me WHICH window (by number) it is opened in, so that I can go there, and close it, or edit it from there.

Could someone please help me adjust this so that it would work in cygwin on Windows10?

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" for screen use
" opened in another screen? lets not play where's waldo anymore!
" this will politely tell me which screen's window it is open in so that I may
" go close it if I want, but still provide me the normal options
"
augroup NoSimultaneousEdits
    autocmd!
    autocmd SwapExists * :call PrintScreenWindow()
augroup END

function! PrintScreenWindow ()
  let fname = expand("%:p")
  " fix fname here, remove the path and leave only the filename/basename
  let fname =  fnamemodify(fname, ':t')
  " I just added the 'fpath', and 'all' variables,
  " The below my_command USED to use fname, but I found that if you have the
  " file open somewhere else (in a different screen window) AND also, have the
  " same filename, with a different path open, in a different window, it
  " causes an error, I.E.:
  " /root/abc/test.txt -- open in window 0
  " /root/abc/def/test.text -- open in window 1
  " now, in window 2, try to open /root/abc/test.txt, the below my_command
  " USED to have the variable 'fname', where it now has the variable 'all'
  " and this caused an error.
  " Adding this 'fpath', and 'all', fixes this issue.
  let fpath = expand("%:p:h")
  let all = fpath . "/." . fname
  " you might have to fix your path to lsof
  let my_command = "lsof | grep '" . fname . ".swp' | grep " . $USER . " | sed -n 's/^vim\\? \\+\\([0-9]\\+\\).*$/\\1/p' "
  " let my_command = "lsof | grep '" . all . ".swp' | /bin/grep " . $USER . " | sed -n 's/^vim\\? \\+\\([0-9]\\+\\).*$/\\1/p' "
  let result = substitute(system(my_command), '\n','','')
  if result
    let my_cmd2 = "cat /proc/" . result . "/environ | xargs -0 echo | sed -n 's/.*WINDOW=\\([0-9]*\\).*/\\1/p' "
    let res2 = substitute(system(my_cmd2), '\n','','')
    if res2 || res2 == '0'
      echo 'This file is already opened in window: ' . res2
    else
      echo "command failed: " . my_cmd2
    endif
  else
    echo my_command . " : cmd failed"
  endif
endfunction

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Solution

  • Okay, for CYGWIN, you do NEED to install "busybox"

    Then, in my .vimrc file, change:

    let my_command = "lsof | grep '" . fname . ".swp' | grep " . $USER . " | sed -n 's/^vim\\? \\+\\([0-9]\\+\\).*$/\\1/p' "
    

    to:

    let my_command = "busybox lsof | grep '" . fname . ".swp' | cut -f1 "
    

    As there are no users listed, and the PID comes first, not after the process name.

    Secondly, change:

    let my_cmd2 = "cat /proc/" . result . "/environ | xargs -0 echo | sed -n 's/.*WINDOW=\\([0-9]*\\).*/\\1/p' "
    

    to:

    let my_cmd2 = "cat /proc/" . result . "/environ | xargs -0 echo | busybox sed -n 's/.*WINDOW=\\([0-9]*\\).*/\\1/p' "