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