about summary refs log tree commit diff
path: root/src/etc/vim/autoload/rust.vim
diff options
context:
space:
mode:
authorKevin Ballard <kevin@sb.org>2014-05-27 15:00:22 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-06-18 17:01:21 -0700
commit303cadfbb3addd30dafdc2bcb5db994ab3bb30ab (patch)
tree9c11606b7234e5f57f7e12fc3e853c6da0c60b88 /src/etc/vim/autoload/rust.vim
parent6ca454f12c13cd34ca41741d372485e34f79706a (diff)
downloadrust-303cadfbb3addd30dafdc2bcb5db994ab3bb30ab.tar.gz
rust-303cadfbb3addd30dafdc2bcb5db994ab3bb30ab.zip
vim: Add :Run and :Expand commands
Define a command :Run to compile and run the current file. This supports
unnamed buffers (by writing to a temporary file). See the comment above
the command definition for notes on usage.

Define <D-r> and <D-R> mappings for :Run to make it easier to invoke in
MacVim.

Define a command :Expand to display the --pretty expanded output for the
current file. This can be configured to use different pretty types. See
the comment above the command definition for notes on usage.

Create an autoload file and put function definitions there to speed up
load time.
Diffstat (limited to 'src/etc/vim/autoload/rust.vim')
-rw-r--r--src/etc/vim/autoload/rust.vim192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/etc/vim/autoload/rust.vim b/src/etc/vim/autoload/rust.vim
new file mode 100644
index 00000000000..688c1f690eb
--- /dev/null
+++ b/src/etc/vim/autoload/rust.vim
@@ -0,0 +1,192 @@
+" Author: Kevin Ballard
+" Description: Helper functions for Rust commands/mappings
+" Last Modified: May 27, 2014
+
+" Jump {{{1
+
+function! rust#Jump(mode, function) range
+	let cnt = v:count1
+	normal! m'
+	if a:mode ==# 'v'
+		norm! gv
+	endif
+	let foldenable = &foldenable
+	set nofoldenable
+	while cnt > 0
+		execute "call <SID>Jump_" . a:function . "()"
+		let cnt = cnt - 1
+	endwhile
+	let &foldenable = foldenable
+endfunction
+
+function! s:Jump_Back()
+	call search('{', 'b')
+	keepjumps normal! w99[{
+endfunction
+
+function! s:Jump_Forward()
+	normal! j0
+	call search('{', 'b')
+	keepjumps normal! w99[{%
+	call search('{')
+endfunction
+
+" Run {{{1
+
+function! rust#Run(bang, args)
+	if a:bang
+		let idx = index(a:args, '--')
+		if idx != -1
+			let rustc_args = idx == 0 ? [] : a:args[:idx-1]
+			let args = a:args[idx+1:]
+		else
+			let rustc_args = a:args
+			let args = []
+		endif
+	else
+		let rustc_args = []
+		let args = a:args
+	endif
+
+	let b:rust_last_rustc_args = rustc_args
+	let b:rust_last_args = args
+
+	call s:WithPath(function("s:Run"), rustc_args, args)
+endfunction
+
+function! s:Run(path, rustc_args, args)
+	try
+		let exepath = tempname()
+		if has('win32')
+			let exepath .= '.exe'
+		endif
+
+		let rustc_args = [a:path, '-o', exepath] + a:rustc_args
+
+		let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
+
+		let output = system(shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)')))
+		if output != ''
+			echohl WarningMsg
+			echo output
+			echohl None
+		endif
+		if !v:shell_error
+			exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)'))
+		endif
+	finally
+		if exists("exepath")
+			silent! call delete(exepath)
+		endif
+	endtry
+endfunction
+
+" Expand {{{1
+
+function! rust#Expand(bang, args)
+	if a:bang && !empty(a:args)
+		let pretty = a:args[0]
+		let args = a:args[1:]
+	else
+		let pretty = "expanded"
+		let args = a:args
+	endif
+	call s:WithPath(function("s:Expand"), pretty, args)
+endfunction
+
+function! s:Expand(path, pretty, args)
+	try
+		let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
+
+		let args = [a:path, '--pretty', a:pretty] + a:args
+		let output = system(shellescape(rustc) . " " . join(map(args, "shellescape(v:val)")))
+		if v:shell_error
+			echohl WarningMsg
+			echo output
+			echohl None
+		else
+			new
+			silent put =output
+			1
+			d
+			setl filetype=rust
+			setl buftype=nofile
+			setl bufhidden=hide
+			setl noswapfile
+		endif
+	endtry
+endfunction
+
+function! rust#CompleteExpand(lead, line, pos)
+	if a:line[: a:pos-1] =~ '^Expand!\s*\S*$'
+		" first argument and it has a !
+		let list = ["normal", "expanded", "typed", "expanded,identified", "flowgraph="]
+		if !empty(a:lead)
+			call filter(list, "v:val[:len(a:lead)-1] == a:lead")
+		endif
+		return list
+	endif
+
+	return glob(escape(a:lead, "*?[") . '*', 0, 1)
+endfunction
+
+" Utility functions {{{1
+
+function! s:WithPath(func, ...)
+	try
+		let save_write = &write
+		set write
+		let path = expand('%')
+		let pathisempty = empty(path)
+		if pathisempty || !save_write
+			" use a temporary file named 'unnamed.rs' inside a temporary
+			" directory. This produces better error messages
+			let tmpdir = tempname()
+			call mkdir(tmpdir)
+
+			let save_cwd = getcwd()
+			silent exe 'lcd' tmpdir
+
+			let path = 'unnamed.rs'
+
+			let save_mod = &mod
+			set nomod
+
+			silent exe 'keepalt write! ' . path
+			if pathisempty
+				silent keepalt 0file
+			endif
+		else
+			update
+		endif
+
+		call call(a:func, [path] + a:000)
+	finally
+		if exists("save_mod")   | let &mod = save_mod          | endif
+		if exists("save_write") | let &write = save_write      | endif
+		if exists("save_cwd")   | silent exe 'lcd' save_cwd    | endif
+		if exists("tmpdir")     | silent call s:RmDir(tmpdir)  | endif
+	endtry
+endfunction
+
+function! rust#AppendCmdLine(text)
+	call setcmdpos(getcmdpos())
+	let cmd = getcmdline() . a:text
+	return cmd
+endfunction
+
+function! s:RmDir(path)
+	" sanity check; make sure it's not empty, /, or $HOME
+	if empty(a:path)
+		echoerr 'Attempted to delete empty path'
+		return 0
+	elseif a:path == '/' || a:path == $HOME
+		echoerr 'Attempted to delete protected path: ' . a:path
+		return 0
+	endif
+	silent exe "!rm -rf " . shellescape(a:path)
+endfunction
+
+" }}}1
+
+" vim: set noet sw=4 ts=4: