blob: 3530e29dc44a002723ab63b40ecd54bf55bea269 [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 Moolenaared32d942014-12-06 23:33:00 +01003" Last Change: 2014 Dec 06
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.
Bram Moolenaar3577c6f2008-06-24 21:16:56 +000016if v:version < 700
17 finish
18endif
Bram Moolenaar292ad192005-12-11 21:29:51 +000019
20" Function that finds the Vim instance that is editing "filename" and brings
21" it to the foreground.
22func s:EditElsewhere(filename)
23 let fname_esc = substitute(a:filename, "'", "''", "g")
24
25 let servers = serverlist()
26 while servers != ''
27 " Get next server name in "servername"; remove it from "servers".
28 let i = match(servers, "\n")
29 if i == -1
30 let servername = servers
31 let servers = ''
32 else
33 let servername = strpart(servers, 0, i)
34 let servers = strpart(servers, i + 1)
35 endif
36
37 " Skip ourselves.
38 if servername ==? v:servername
39 continue
40 endif
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000041
Bram Moolenaar292ad192005-12-11 21:29:51 +000042 " Check if this server is editing our file.
43 if remote_expr(servername, "bufloaded('" . fname_esc . "')")
44 " Yes, bring it to the foreground.
45 if has("win32")
46 call remote_foreground(servername)
47 endif
48 call remote_expr(servername, "foreground()")
49
Bram Moolenaar12033fb2005-12-16 21:49:31 +000050 if remote_expr(servername, "exists('*EditExisting')")
51 " Make sure the file is visible in a window (not hidden).
52 " If v:swapcommand exists and is set, send it to the server.
53 if exists("v:swapcommand")
54 let c = substitute(v:swapcommand, "'", "''", "g")
55 call remote_expr(servername, "EditExisting('" . fname_esc . "', '" . c . "')")
56 else
57 call remote_expr(servername, "EditExisting('" . fname_esc . "', '')")
58 endif
Bram Moolenaar292ad192005-12-11 21:29:51 +000059 endif
60
61 if !(has('vim_starting') && has('gui_running') && has('gui_win32'))
62 " Tell the user what is happening. Not when the GUI is starting
63 " though, it would result in a message box.
64 echomsg "File is being edited by " . servername
65 sleep 2
66 endif
67 return 'q'
68 endif
69 endwhile
70 return ''
71endfunc
72
73" When the plugin is loaded and there is one file name argument: Find another
74" Vim server that is editing this file right now.
75if argc() == 1 && !&modified
76 if s:EditElsewhere(expand("%:p")) == 'q'
77 quit
78 endif
79endif
80
81" Setup for handling the situation that an existing swap file is found.
82try
83 au! SwapExists * let v:swapchoice = s:EditElsewhere(expand("<afile>:p"))
84catch
85 " Without SwapExists we don't do anything for ":edit" commands
86endtry
87
88" Function used on the server to make the file visible and possibly execute a
89" command.
90func! EditExisting(fname, command)
Bram Moolenaar867a4b72007-03-18 20:51:46 +000091 " Get the window number of the file in the current tab page.
92 let winnr = bufwinnr(a:fname)
93 if winnr <= 0
94 " Not found, look in other tab pages.
95 let bufnr = bufnr(a:fname)
96 for i in range(tabpagenr('$'))
97 if index(tabpagebuflist(i + 1), bufnr) >= 0
98 " Make this tab page the current one and find the window number.
99 exe 'tabnext ' . (i + 1)
100 let winnr = bufwinnr(a:fname)
Bram Moolenaar34700a62013-03-07 13:20:54 +0100101 break
Bram Moolenaar867a4b72007-03-18 20:51:46 +0000102 endif
103 endfor
104 endif
105
106 if winnr > 0
107 exe winnr . "wincmd w"
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000108 elseif exists('*fnameescape')
109 exe "split " . fnameescape(a:fname)
Bram Moolenaar292ad192005-12-11 21:29:51 +0000110 else
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000111 exe "split " . escape(a:fname, " \t\n*?[{`$\\%#'\"|!<")
Bram Moolenaar292ad192005-12-11 21:29:51 +0000112 endif
113
114 if a:command != ''
Bram Moolenaared32d942014-12-06 23:33:00 +0100115 exe "normal! " . a:command
Bram Moolenaar292ad192005-12-11 21:29:51 +0000116 endif
117
118 redraw
119endfunc