xref: /vim-8.2.3635/runtime/autoload/rust.vim (revision 3c2881dc)
1*3c2881dcSBram Moolenaar" Author: Kevin Ballard
2*3c2881dcSBram Moolenaar" Description: Helper functions for Rust commands/mappings
3*3c2881dcSBram Moolenaar" Last Modified: May 27, 2014
4*3c2881dcSBram Moolenaar" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
5*3c2881dcSBram Moolenaar
6*3c2881dcSBram Moolenaar" Jump {{{1
7*3c2881dcSBram Moolenaar
8*3c2881dcSBram Moolenaarfunction! rust#Jump(mode, function) range
9*3c2881dcSBram Moolenaar	let cnt = v:count1
10*3c2881dcSBram Moolenaar	normal! m'
11*3c2881dcSBram Moolenaar	if a:mode ==# 'v'
12*3c2881dcSBram Moolenaar		norm! gv
13*3c2881dcSBram Moolenaar	endif
14*3c2881dcSBram Moolenaar	let foldenable = &foldenable
15*3c2881dcSBram Moolenaar	set nofoldenable
16*3c2881dcSBram Moolenaar	while cnt > 0
17*3c2881dcSBram Moolenaar		execute "call <SID>Jump_" . a:function . "()"
18*3c2881dcSBram Moolenaar		let cnt = cnt - 1
19*3c2881dcSBram Moolenaar	endwhile
20*3c2881dcSBram Moolenaar	let &foldenable = foldenable
21*3c2881dcSBram Moolenaarendfunction
22*3c2881dcSBram Moolenaar
23*3c2881dcSBram Moolenaarfunction! s:Jump_Back()
24*3c2881dcSBram Moolenaar	call search('{', 'b')
25*3c2881dcSBram Moolenaar	keepjumps normal! w99[{
26*3c2881dcSBram Moolenaarendfunction
27*3c2881dcSBram Moolenaar
28*3c2881dcSBram Moolenaarfunction! s:Jump_Forward()
29*3c2881dcSBram Moolenaar	normal! j0
30*3c2881dcSBram Moolenaar	call search('{', 'b')
31*3c2881dcSBram Moolenaar	keepjumps normal! w99[{%
32*3c2881dcSBram Moolenaar	call search('{')
33*3c2881dcSBram Moolenaarendfunction
34*3c2881dcSBram Moolenaar
35*3c2881dcSBram Moolenaar" Run {{{1
36*3c2881dcSBram Moolenaar
37*3c2881dcSBram Moolenaarfunction! rust#Run(bang, args)
38*3c2881dcSBram Moolenaar	let args = s:ShellTokenize(a:args)
39*3c2881dcSBram Moolenaar	if a:bang
40*3c2881dcSBram Moolenaar		let idx = index(l:args, '--')
41*3c2881dcSBram Moolenaar		if idx != -1
42*3c2881dcSBram Moolenaar			let rustc_args = idx == 0 ? [] : l:args[:idx-1]
43*3c2881dcSBram Moolenaar			let args = l:args[idx+1:]
44*3c2881dcSBram Moolenaar		else
45*3c2881dcSBram Moolenaar			let rustc_args = l:args
46*3c2881dcSBram Moolenaar			let args = []
47*3c2881dcSBram Moolenaar		endif
48*3c2881dcSBram Moolenaar	else
49*3c2881dcSBram Moolenaar		let rustc_args = []
50*3c2881dcSBram Moolenaar	endif
51*3c2881dcSBram Moolenaar
52*3c2881dcSBram Moolenaar	let b:rust_last_rustc_args = l:rustc_args
53*3c2881dcSBram Moolenaar	let b:rust_last_args = l:args
54*3c2881dcSBram Moolenaar
55*3c2881dcSBram Moolenaar	call s:WithPath(function("s:Run"), rustc_args, args)
56*3c2881dcSBram Moolenaarendfunction
57*3c2881dcSBram Moolenaar
58*3c2881dcSBram Moolenaarfunction! s:Run(dict, rustc_args, args)
59*3c2881dcSBram Moolenaar	let exepath = a:dict.tmpdir.'/'.fnamemodify(a:dict.path, ':t:r')
60*3c2881dcSBram Moolenaar	if has('win32')
61*3c2881dcSBram Moolenaar		let exepath .= '.exe'
62*3c2881dcSBram Moolenaar	endif
63*3c2881dcSBram Moolenaar
64*3c2881dcSBram Moolenaar	let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
65*3c2881dcSBram Moolenaar	let rustc_args = [relpath, '-o', exepath] + a:rustc_args
66*3c2881dcSBram Moolenaar
67*3c2881dcSBram Moolenaar	let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
68*3c2881dcSBram Moolenaar
69*3c2881dcSBram Moolenaar	let pwd = a:dict.istemp ? a:dict.tmpdir : ''
70*3c2881dcSBram Moolenaar	let output = s:system(pwd, shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)')))
71*3c2881dcSBram Moolenaar	if output != ''
72*3c2881dcSBram Moolenaar		echohl WarningMsg
73*3c2881dcSBram Moolenaar		echo output
74*3c2881dcSBram Moolenaar		echohl None
75*3c2881dcSBram Moolenaar	endif
76*3c2881dcSBram Moolenaar	if !v:shell_error
77*3c2881dcSBram Moolenaar		exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)'))
78*3c2881dcSBram Moolenaar	endif
79*3c2881dcSBram Moolenaarendfunction
80*3c2881dcSBram Moolenaar
81*3c2881dcSBram Moolenaar" Expand {{{1
82*3c2881dcSBram Moolenaar
83*3c2881dcSBram Moolenaarfunction! rust#Expand(bang, args)
84*3c2881dcSBram Moolenaar	let args = s:ShellTokenize(a:args)
85*3c2881dcSBram Moolenaar	if a:bang && !empty(l:args)
86*3c2881dcSBram Moolenaar		let pretty = remove(l:args, 0)
87*3c2881dcSBram Moolenaar	else
88*3c2881dcSBram Moolenaar		let pretty = "expanded"
89*3c2881dcSBram Moolenaar	endif
90*3c2881dcSBram Moolenaar	call s:WithPath(function("s:Expand"), pretty, args)
91*3c2881dcSBram Moolenaarendfunction
92*3c2881dcSBram Moolenaar
93*3c2881dcSBram Moolenaarfunction! s:Expand(dict, pretty, args)
94*3c2881dcSBram Moolenaar	try
95*3c2881dcSBram Moolenaar		let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
96*3c2881dcSBram Moolenaar
97*3c2881dcSBram Moolenaar		if a:pretty =~? '^\%(everybody_loops$\|flowgraph=\)'
98*3c2881dcSBram Moolenaar			let flag = '--xpretty'
99*3c2881dcSBram Moolenaar		else
100*3c2881dcSBram Moolenaar			let flag = '--pretty'
101*3c2881dcSBram Moolenaar		endif
102*3c2881dcSBram Moolenaar		let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
103*3c2881dcSBram Moolenaar		let args = [relpath, '-Z', 'unstable-options', l:flag, a:pretty] + a:args
104*3c2881dcSBram Moolenaar		let pwd = a:dict.istemp ? a:dict.tmpdir : ''
105*3c2881dcSBram Moolenaar		let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)')))
106*3c2881dcSBram Moolenaar		if v:shell_error
107*3c2881dcSBram Moolenaar			echohl WarningMsg
108*3c2881dcSBram Moolenaar			echo output
109*3c2881dcSBram Moolenaar			echohl None
110*3c2881dcSBram Moolenaar		else
111*3c2881dcSBram Moolenaar			new
112*3c2881dcSBram Moolenaar			silent put =output
113*3c2881dcSBram Moolenaar			1
114*3c2881dcSBram Moolenaar			d
115*3c2881dcSBram Moolenaar			setl filetype=rust
116*3c2881dcSBram Moolenaar			setl buftype=nofile
117*3c2881dcSBram Moolenaar			setl bufhidden=hide
118*3c2881dcSBram Moolenaar			setl noswapfile
119*3c2881dcSBram Moolenaar			" give the buffer a nice name
120*3c2881dcSBram Moolenaar			let suffix = 1
121*3c2881dcSBram Moolenaar			let basename = fnamemodify(a:dict.path, ':t:r')
122*3c2881dcSBram Moolenaar			while 1
123*3c2881dcSBram Moolenaar				let bufname = basename
124*3c2881dcSBram Moolenaar				if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
125*3c2881dcSBram Moolenaar				let bufname .= '.pretty.rs'
126*3c2881dcSBram Moolenaar				if bufexists(bufname)
127*3c2881dcSBram Moolenaar					let suffix += 1
128*3c2881dcSBram Moolenaar					continue
129*3c2881dcSBram Moolenaar				endif
130*3c2881dcSBram Moolenaar				exe 'silent noautocmd keepalt file' fnameescape(bufname)
131*3c2881dcSBram Moolenaar				break
132*3c2881dcSBram Moolenaar			endwhile
133*3c2881dcSBram Moolenaar		endif
134*3c2881dcSBram Moolenaar	endtry
135*3c2881dcSBram Moolenaarendfunction
136*3c2881dcSBram Moolenaar
137*3c2881dcSBram Moolenaarfunction! rust#CompleteExpand(lead, line, pos)
138*3c2881dcSBram Moolenaar	if a:line[: a:pos-1] =~ '^RustExpand!\s*\S*$'
139*3c2881dcSBram Moolenaar		" first argument and it has a !
140*3c2881dcSBram Moolenaar		let list = ["normal", "expanded", "typed", "expanded,identified", "flowgraph=", "everybody_loops"]
141*3c2881dcSBram Moolenaar		if !empty(a:lead)
142*3c2881dcSBram Moolenaar			call filter(list, "v:val[:len(a:lead)-1] == a:lead")
143*3c2881dcSBram Moolenaar		endif
144*3c2881dcSBram Moolenaar		return list
145*3c2881dcSBram Moolenaar	endif
146*3c2881dcSBram Moolenaar
147*3c2881dcSBram Moolenaar	return glob(escape(a:lead, "*?[") . '*', 0, 1)
148*3c2881dcSBram Moolenaarendfunction
149*3c2881dcSBram Moolenaar
150*3c2881dcSBram Moolenaar" Emit {{{1
151*3c2881dcSBram Moolenaar
152*3c2881dcSBram Moolenaarfunction! rust#Emit(type, args)
153*3c2881dcSBram Moolenaar	let args = s:ShellTokenize(a:args)
154*3c2881dcSBram Moolenaar	call s:WithPath(function("s:Emit"), a:type, args)
155*3c2881dcSBram Moolenaarendfunction
156*3c2881dcSBram Moolenaar
157*3c2881dcSBram Moolenaarfunction! s:Emit(dict, type, args)
158*3c2881dcSBram Moolenaar	try
159*3c2881dcSBram Moolenaar		let output_path = a:dict.tmpdir.'/output'
160*3c2881dcSBram Moolenaar
161*3c2881dcSBram Moolenaar		let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
162*3c2881dcSBram Moolenaar
163*3c2881dcSBram Moolenaar		let relpath = get(a:dict, 'tmpdir_relpath', a:dict.path)
164*3c2881dcSBram Moolenaar		let args = [relpath, '--emit', a:type, '-o', output_path] + a:args
165*3c2881dcSBram Moolenaar		let pwd = a:dict.istemp ? a:dict.tmpdir : ''
166*3c2881dcSBram Moolenaar		let output = s:system(pwd, shellescape(rustc) . " " . join(map(args, 'shellescape(v:val)')))
167*3c2881dcSBram Moolenaar		if output != ''
168*3c2881dcSBram Moolenaar			echohl WarningMsg
169*3c2881dcSBram Moolenaar			echo output
170*3c2881dcSBram Moolenaar			echohl None
171*3c2881dcSBram Moolenaar		endif
172*3c2881dcSBram Moolenaar		if !v:shell_error
173*3c2881dcSBram Moolenaar			new
174*3c2881dcSBram Moolenaar			exe 'silent keepalt read' fnameescape(output_path)
175*3c2881dcSBram Moolenaar			1
176*3c2881dcSBram Moolenaar			d
177*3c2881dcSBram Moolenaar			if a:type == "llvm-ir"
178*3c2881dcSBram Moolenaar				setl filetype=llvm
179*3c2881dcSBram Moolenaar				let extension = 'll'
180*3c2881dcSBram Moolenaar			elseif a:type == "asm"
181*3c2881dcSBram Moolenaar				setl filetype=asm
182*3c2881dcSBram Moolenaar				let extension = 's'
183*3c2881dcSBram Moolenaar			endif
184*3c2881dcSBram Moolenaar			setl buftype=nofile
185*3c2881dcSBram Moolenaar			setl bufhidden=hide
186*3c2881dcSBram Moolenaar			setl noswapfile
187*3c2881dcSBram Moolenaar			if exists('l:extension')
188*3c2881dcSBram Moolenaar				" give the buffer a nice name
189*3c2881dcSBram Moolenaar				let suffix = 1
190*3c2881dcSBram Moolenaar				let basename = fnamemodify(a:dict.path, ':t:r')
191*3c2881dcSBram Moolenaar				while 1
192*3c2881dcSBram Moolenaar					let bufname = basename
193*3c2881dcSBram Moolenaar					if suffix > 1 | let bufname .= ' ('.suffix.')' | endif
194*3c2881dcSBram Moolenaar					let bufname .= '.'.extension
195*3c2881dcSBram Moolenaar					if bufexists(bufname)
196*3c2881dcSBram Moolenaar						let suffix += 1
197*3c2881dcSBram Moolenaar						continue
198*3c2881dcSBram Moolenaar					endif
199*3c2881dcSBram Moolenaar					exe 'silent noautocmd keepalt file' fnameescape(bufname)
200*3c2881dcSBram Moolenaar					break
201*3c2881dcSBram Moolenaar				endwhile
202*3c2881dcSBram Moolenaar			endif
203*3c2881dcSBram Moolenaar		endif
204*3c2881dcSBram Moolenaar	endtry
205*3c2881dcSBram Moolenaarendfunction
206*3c2881dcSBram Moolenaar
207*3c2881dcSBram Moolenaar" Utility functions {{{1
208*3c2881dcSBram Moolenaar
209*3c2881dcSBram Moolenaar" Invokes func(dict, ...)
210*3c2881dcSBram Moolenaar" Where {dict} is a dictionary with the following keys:
211*3c2881dcSBram Moolenaar"   'path' - The path to the file
212*3c2881dcSBram Moolenaar"   'tmpdir' - The path to a temporary directory that will be deleted when the
213*3c2881dcSBram Moolenaar"              function returns.
214*3c2881dcSBram Moolenaar"   'istemp' - 1 if the path is a file inside of {dict.tmpdir} or 0 otherwise.
215*3c2881dcSBram Moolenaar" If {istemp} is 1 then an additional key is provided:
216*3c2881dcSBram Moolenaar"   'tmpdir_relpath' - The {path} relative to the {tmpdir}.
217*3c2881dcSBram Moolenaar"
218*3c2881dcSBram Moolenaar" {dict.path} may be a path to a file inside of {dict.tmpdir} or it may be the
219*3c2881dcSBram Moolenaar" existing path of the current buffer. If the path is inside of {dict.tmpdir}
220*3c2881dcSBram Moolenaar" then it is guaranteed to have a '.rs' extension.
221*3c2881dcSBram Moolenaarfunction! s:WithPath(func, ...)
222*3c2881dcSBram Moolenaar	let buf = bufnr('')
223*3c2881dcSBram Moolenaar	let saved = {}
224*3c2881dcSBram Moolenaar	let dict = {}
225*3c2881dcSBram Moolenaar	try
226*3c2881dcSBram Moolenaar		let saved.write = &write
227*3c2881dcSBram Moolenaar		set write
228*3c2881dcSBram Moolenaar		let dict.path = expand('%')
229*3c2881dcSBram Moolenaar		let pathisempty = empty(dict.path)
230*3c2881dcSBram Moolenaar
231*3c2881dcSBram Moolenaar		" Always create a tmpdir in case the wrapped command wants it
232*3c2881dcSBram Moolenaar		let dict.tmpdir = tempname()
233*3c2881dcSBram Moolenaar		call mkdir(dict.tmpdir)
234*3c2881dcSBram Moolenaar
235*3c2881dcSBram Moolenaar		if pathisempty || !saved.write
236*3c2881dcSBram Moolenaar			let dict.istemp = 1
237*3c2881dcSBram Moolenaar			" if we're doing this because of nowrite, preserve the filename
238*3c2881dcSBram Moolenaar			if !pathisempty
239*3c2881dcSBram Moolenaar				let filename = expand('%:t:r').".rs"
240*3c2881dcSBram Moolenaar			else
241*3c2881dcSBram Moolenaar				let filename = 'unnamed.rs'
242*3c2881dcSBram Moolenaar			endif
243*3c2881dcSBram Moolenaar			let dict.tmpdir_relpath = filename
244*3c2881dcSBram Moolenaar			let dict.path = dict.tmpdir.'/'.filename
245*3c2881dcSBram Moolenaar
246*3c2881dcSBram Moolenaar			let saved.mod = &mod
247*3c2881dcSBram Moolenaar			set nomod
248*3c2881dcSBram Moolenaar
249*3c2881dcSBram Moolenaar			silent exe 'keepalt write! ' . fnameescape(dict.path)
250*3c2881dcSBram Moolenaar			if pathisempty
251*3c2881dcSBram Moolenaar				silent keepalt 0file
252*3c2881dcSBram Moolenaar			endif
253*3c2881dcSBram Moolenaar		else
254*3c2881dcSBram Moolenaar			let dict.istemp = 0
255*3c2881dcSBram Moolenaar			update
256*3c2881dcSBram Moolenaar		endif
257*3c2881dcSBram Moolenaar
258*3c2881dcSBram Moolenaar		call call(a:func, [dict] + a:000)
259*3c2881dcSBram Moolenaar	finally
260*3c2881dcSBram Moolenaar		if bufexists(buf)
261*3c2881dcSBram Moolenaar			for [opt, value] in items(saved)
262*3c2881dcSBram Moolenaar				silent call setbufvar(buf, '&'.opt, value)
263*3c2881dcSBram Moolenaar				unlet value " avoid variable type mismatches
264*3c2881dcSBram Moolenaar			endfor
265*3c2881dcSBram Moolenaar		endif
266*3c2881dcSBram Moolenaar		if has_key(dict, 'tmpdir') | silent call s:RmDir(dict.tmpdir) | endif
267*3c2881dcSBram Moolenaar	endtry
268*3c2881dcSBram Moolenaarendfunction
269*3c2881dcSBram Moolenaar
270*3c2881dcSBram Moolenaarfunction! rust#AppendCmdLine(text)
271*3c2881dcSBram Moolenaar	call setcmdpos(getcmdpos())
272*3c2881dcSBram Moolenaar	let cmd = getcmdline() . a:text
273*3c2881dcSBram Moolenaar	return cmd
274*3c2881dcSBram Moolenaarendfunction
275*3c2881dcSBram Moolenaar
276*3c2881dcSBram Moolenaar" Tokenize the string according to sh parsing rules
277*3c2881dcSBram Moolenaarfunction! s:ShellTokenize(text)
278*3c2881dcSBram Moolenaar	" states:
279*3c2881dcSBram Moolenaar	" 0: start of word
280*3c2881dcSBram Moolenaar	" 1: unquoted
281*3c2881dcSBram Moolenaar	" 2: unquoted backslash
282*3c2881dcSBram Moolenaar	" 3: double-quote
283*3c2881dcSBram Moolenaar	" 4: double-quoted backslash
284*3c2881dcSBram Moolenaar	" 5: single-quote
285*3c2881dcSBram Moolenaar	let l:state = 0
286*3c2881dcSBram Moolenaar	let l:current = ''
287*3c2881dcSBram Moolenaar	let l:args = []
288*3c2881dcSBram Moolenaar	for c in split(a:text, '\zs')
289*3c2881dcSBram Moolenaar		if l:state == 0 || l:state == 1 " unquoted
290*3c2881dcSBram Moolenaar			if l:c ==# ' '
291*3c2881dcSBram Moolenaar				if l:state == 0 | continue | endif
292*3c2881dcSBram Moolenaar				call add(l:args, l:current)
293*3c2881dcSBram Moolenaar				let l:current = ''
294*3c2881dcSBram Moolenaar				let l:state = 0
295*3c2881dcSBram Moolenaar			elseif l:c ==# '\'
296*3c2881dcSBram Moolenaar				let l:state = 2
297*3c2881dcSBram Moolenaar			elseif l:c ==# '"'
298*3c2881dcSBram Moolenaar				let l:state = 3
299*3c2881dcSBram Moolenaar			elseif l:c ==# "'"
300*3c2881dcSBram Moolenaar				let l:state = 5
301*3c2881dcSBram Moolenaar			else
302*3c2881dcSBram Moolenaar				let l:current .= l:c
303*3c2881dcSBram Moolenaar				let l:state = 1
304*3c2881dcSBram Moolenaar			endif
305*3c2881dcSBram Moolenaar		elseif l:state == 2 " unquoted backslash
306*3c2881dcSBram Moolenaar			if l:c !=# "\n" " can it even be \n?
307*3c2881dcSBram Moolenaar				let l:current .= l:c
308*3c2881dcSBram Moolenaar			endif
309*3c2881dcSBram Moolenaar			let l:state = 1
310*3c2881dcSBram Moolenaar		elseif l:state == 3 " double-quote
311*3c2881dcSBram Moolenaar			if l:c ==# '\'
312*3c2881dcSBram Moolenaar				let l:state = 4
313*3c2881dcSBram Moolenaar			elseif l:c ==# '"'
314*3c2881dcSBram Moolenaar				let l:state = 1
315*3c2881dcSBram Moolenaar			else
316*3c2881dcSBram Moolenaar				let l:current .= l:c
317*3c2881dcSBram Moolenaar			endif
318*3c2881dcSBram Moolenaar		elseif l:state == 4 " double-quoted backslash
319*3c2881dcSBram Moolenaar			if stridx('$`"\', l:c) >= 0
320*3c2881dcSBram Moolenaar				let l:current .= l:c
321*3c2881dcSBram Moolenaar			elseif l:c ==# "\n" " is this even possible?
322*3c2881dcSBram Moolenaar				" skip it
323*3c2881dcSBram Moolenaar			else
324*3c2881dcSBram Moolenaar				let l:current .= '\'.l:c
325*3c2881dcSBram Moolenaar			endif
326*3c2881dcSBram Moolenaar			let l:state = 3
327*3c2881dcSBram Moolenaar		elseif l:state == 5 " single-quoted
328*3c2881dcSBram Moolenaar			if l:c == "'"
329*3c2881dcSBram Moolenaar				let l:state = 1
330*3c2881dcSBram Moolenaar			else
331*3c2881dcSBram Moolenaar				let l:current .= l:c
332*3c2881dcSBram Moolenaar			endif
333*3c2881dcSBram Moolenaar		endif
334*3c2881dcSBram Moolenaar	endfor
335*3c2881dcSBram Moolenaar	if l:state != 0
336*3c2881dcSBram Moolenaar		call add(l:args, l:current)
337*3c2881dcSBram Moolenaar	endif
338*3c2881dcSBram Moolenaar	return l:args
339*3c2881dcSBram Moolenaarendfunction
340*3c2881dcSBram Moolenaar
341*3c2881dcSBram Moolenaarfunction! s:RmDir(path)
342*3c2881dcSBram Moolenaar	" sanity check; make sure it's not empty, /, or $HOME
343*3c2881dcSBram Moolenaar	if empty(a:path)
344*3c2881dcSBram Moolenaar		echoerr 'Attempted to delete empty path'
345*3c2881dcSBram Moolenaar		return 0
346*3c2881dcSBram Moolenaar	elseif a:path == '/' || a:path == $HOME
347*3c2881dcSBram Moolenaar		echoerr 'Attempted to delete protected path: ' . a:path
348*3c2881dcSBram Moolenaar		return 0
349*3c2881dcSBram Moolenaar	endif
350*3c2881dcSBram Moolenaar	return system("rm -rf " . shellescape(a:path))
351*3c2881dcSBram Moolenaarendfunction
352*3c2881dcSBram Moolenaar
353*3c2881dcSBram Moolenaar" Executes {cmd} with the cwd set to {pwd}, without changing Vim's cwd.
354*3c2881dcSBram Moolenaar" If {pwd} is the empty string then it doesn't change the cwd.
355*3c2881dcSBram Moolenaarfunction! s:system(pwd, cmd)
356*3c2881dcSBram Moolenaar	let cmd = a:cmd
357*3c2881dcSBram Moolenaar	if !empty(a:pwd)
358*3c2881dcSBram Moolenaar		let cmd = 'cd ' . shellescape(a:pwd) . ' && ' . cmd
359*3c2881dcSBram Moolenaar	endif
360*3c2881dcSBram Moolenaar	return system(cmd)
361*3c2881dcSBram Moolenaarendfunction
362*3c2881dcSBram Moolenaar
363*3c2881dcSBram Moolenaar" Playpen Support {{{1
364*3c2881dcSBram Moolenaar" Parts of gist.vim by Yasuhiro Matsumoto <[email protected]> reused
365*3c2881dcSBram Moolenaar" gist.vim available under the BSD license, available at
366*3c2881dcSBram Moolenaar" http://github.com/mattn/gist-vim
367*3c2881dcSBram Moolenaarfunction! s:has_webapi()
368*3c2881dcSBram Moolenaar    if !exists("*webapi#http#post")
369*3c2881dcSBram Moolenaar	try
370*3c2881dcSBram Moolenaar	    call webapi#http#post()
371*3c2881dcSBram Moolenaar	catch
372*3c2881dcSBram Moolenaar	endtry
373*3c2881dcSBram Moolenaar    endif
374*3c2881dcSBram Moolenaar    return exists("*webapi#http#post")
375*3c2881dcSBram Moolenaarendfunction
376*3c2881dcSBram Moolenaar
377*3c2881dcSBram Moolenaarfunction! rust#Play(count, line1, line2, ...) abort
378*3c2881dcSBram Moolenaar    redraw
379*3c2881dcSBram Moolenaar
380*3c2881dcSBram Moolenaar    let l:rust_playpen_url = get(g:, 'rust_playpen_url', 'https://play.rust-lang.org/')
381*3c2881dcSBram Moolenaar    let l:rust_shortener_url = get(g:, 'rust_shortener_url', 'https://is.gd/')
382*3c2881dcSBram Moolenaar
383*3c2881dcSBram Moolenaar    if !s:has_webapi()
384*3c2881dcSBram Moolenaar	echohl ErrorMsg | echomsg ':RustPlay depends on webapi.vim (https://github.com/mattn/webapi-vim)' | echohl None
385*3c2881dcSBram Moolenaar	return
386*3c2881dcSBram Moolenaar    endif
387*3c2881dcSBram Moolenaar
388*3c2881dcSBram Moolenaar    let bufname = bufname('%')
389*3c2881dcSBram Moolenaar    if a:count < 1
390*3c2881dcSBram Moolenaar	let content = join(getline(a:line1, a:line2), "\n")
391*3c2881dcSBram Moolenaar    else
392*3c2881dcSBram Moolenaar	let save_regcont = @"
393*3c2881dcSBram Moolenaar	let save_regtype = getregtype('"')
394*3c2881dcSBram Moolenaar	silent! normal! gvy
395*3c2881dcSBram Moolenaar	let content = @"
396*3c2881dcSBram Moolenaar	call setreg('"', save_regcont, save_regtype)
397*3c2881dcSBram Moolenaar    endif
398*3c2881dcSBram Moolenaar
399*3c2881dcSBram Moolenaar    let body = l:rust_playpen_url."?code=".webapi#http#encodeURI(content)
400*3c2881dcSBram Moolenaar
401*3c2881dcSBram Moolenaar    if strlen(body) > 5000
402*3c2881dcSBram Moolenaar	echohl ErrorMsg | echomsg 'Buffer too large, max 5000 encoded characters ('.strlen(body).')' | echohl None
403*3c2881dcSBram Moolenaar	return
404*3c2881dcSBram Moolenaar    endif
405*3c2881dcSBram Moolenaar
406*3c2881dcSBram Moolenaar    let payload = "format=simple&url=".webapi#http#encodeURI(body)
407*3c2881dcSBram Moolenaar    let res = webapi#http#post(l:rust_shortener_url.'create.php', payload, {})
408*3c2881dcSBram Moolenaar    let url = res.content
409*3c2881dcSBram Moolenaar
410*3c2881dcSBram Moolenaar    redraw | echomsg 'Done: '.url
411*3c2881dcSBram Moolenaarendfunction
412*3c2881dcSBram Moolenaar
413*3c2881dcSBram Moolenaar" }}}1
414*3c2881dcSBram Moolenaar
415*3c2881dcSBram Moolenaar" vim: set noet sw=8 ts=8:
416