1" Vim Plugin: Edit the file with an existing Vim if possible 2" Maintainer: Bram Moolenaar 3" Last Change: 2016 Mar 28 4 5" To use add ":packadd! editexisting" in your vimrc file. 6 7" This plugin serves two purposes: 8" 1. On startup, if we were invoked with one file name argument and the file 9" is not modified then try to find another Vim instance that is editing 10" this file. If there is one then bring it to the foreground and exit. 11" 2. When a file is edited and a swap file exists for it, try finding that 12" other Vim and bring it to the foreground. Requires Vim 7, because it 13" uses the SwapExists autocommand event. 14 15" Function that finds the Vim instance that is editing "filename" and brings 16" it to the foreground. 17func s:EditElsewhere(filename) 18 let fname_esc = substitute(a:filename, "'", "''", "g") 19 20 let servers = serverlist() 21 while servers != '' 22 " Get next server name in "servername"; remove it from "servers". 23 let i = match(servers, "\n") 24 if i == -1 25 let servername = servers 26 let servers = '' 27 else 28 let servername = strpart(servers, 0, i) 29 let servers = strpart(servers, i + 1) 30 endif 31 32 " Skip ourselves. 33 if servername ==? v:servername 34 continue 35 endif 36 37 " Check if this server is editing our file. 38 if remote_expr(servername, "bufloaded('" . fname_esc . "')") 39 " Yes, bring it to the foreground. 40 if has("win32") 41 call remote_foreground(servername) 42 endif 43 call remote_expr(servername, "foreground()") 44 45 if remote_expr(servername, "exists('*EditExisting')") 46 " Make sure the file is visible in a window (not hidden). 47 " If v:swapcommand exists and is set, send it to the server. 48 if exists("v:swapcommand") 49 let c = substitute(v:swapcommand, "'", "''", "g") 50 call remote_expr(servername, "EditExisting('" . fname_esc . "', '" . c . "')") 51 else 52 call remote_expr(servername, "EditExisting('" . fname_esc . "', '')") 53 endif 54 endif 55 56 if !(has('vim_starting') && has('gui_running') && has('gui_win32')) 57 " Tell the user what is happening. Not when the GUI is starting 58 " though, it would result in a message box. 59 echomsg "File is being edited by " . servername 60 sleep 2 61 endif 62 return 'q' 63 endif 64 endwhile 65 return '' 66endfunc 67 68" When the plugin is loaded and there is one file name argument: Find another 69" Vim server that is editing this file right now. 70if argc() == 1 && !&modified 71 if s:EditElsewhere(expand("%:p")) == 'q' 72 quit 73 endif 74endif 75 76" Setup for handling the situation that an existing swap file is found. 77try 78 au! SwapExists * let v:swapchoice = s:EditElsewhere(expand("<afile>:p")) 79catch 80 " Without SwapExists we don't do anything for ":edit" commands 81endtry 82 83" Function used on the server to make the file visible and possibly execute a 84" command. 85func! EditExisting(fname, command) 86 " Get the window number of the file in the current tab page. 87 let winnr = bufwinnr(a:fname) 88 if winnr <= 0 89 " Not found, look in other tab pages. 90 let bufnr = bufnr(a:fname) 91 for i in range(tabpagenr('$')) 92 if index(tabpagebuflist(i + 1), bufnr) >= 0 93 " Make this tab page the current one and find the window number. 94 exe 'tabnext ' . (i + 1) 95 let winnr = bufwinnr(a:fname) 96 break 97 endif 98 endfor 99 endif 100 101 if winnr > 0 102 exe winnr . "wincmd w" 103 elseif exists('*fnameescape') 104 exe "split " . fnameescape(a:fname) 105 else 106 exe "split " . escape(a:fname, " \t\n*?[{`$\\%#'\"|!<") 107 endif 108 109 if a:command != '' 110 exe "normal! " . a:command 111 endif 112 113 redraw 114endfunc 115