]> git.lizzy.rs Git - rust.git/blob - src/etc/vim/autoload/rust.vim
vim: Add :Run and :Expand commands
[rust.git] / src / etc / vim / autoload / rust.vim
1 " Author: Kevin Ballard
2 " Description: Helper functions for Rust commands/mappings
3 " Last Modified: May 27, 2014
4
5 " Jump {{{1
6
7 function! rust#Jump(mode, function) range
8         let cnt = v:count1
9         normal! m'
10         if a:mode ==# 'v'
11                 norm! gv
12         endif
13         let foldenable = &foldenable
14         set nofoldenable
15         while cnt > 0
16                 execute "call <SID>Jump_" . a:function . "()"
17                 let cnt = cnt - 1
18         endwhile
19         let &foldenable = foldenable
20 endfunction
21
22 function! s:Jump_Back()
23         call search('{', 'b')
24         keepjumps normal! w99[{
25 endfunction
26
27 function! s:Jump_Forward()
28         normal! j0
29         call search('{', 'b')
30         keepjumps normal! w99[{%
31         call search('{')
32 endfunction
33
34 " Run {{{1
35
36 function! rust#Run(bang, args)
37         if a:bang
38                 let idx = index(a:args, '--')
39                 if idx != -1
40                         let rustc_args = idx == 0 ? [] : a:args[:idx-1]
41                         let args = a:args[idx+1:]
42                 else
43                         let rustc_args = a:args
44                         let args = []
45                 endif
46         else
47                 let rustc_args = []
48                 let args = a:args
49         endif
50
51         let b:rust_last_rustc_args = rustc_args
52         let b:rust_last_args = args
53
54         call s:WithPath(function("s:Run"), rustc_args, args)
55 endfunction
56
57 function! s:Run(path, rustc_args, args)
58         try
59                 let exepath = tempname()
60                 if has('win32')
61                         let exepath .= '.exe'
62                 endif
63
64                 let rustc_args = [a:path, '-o', exepath] + a:rustc_args
65
66                 let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
67
68                 let output = system(shellescape(rustc) . " " . join(map(rustc_args, 'shellescape(v:val)')))
69                 if output != ''
70                         echohl WarningMsg
71                         echo output
72                         echohl None
73                 endif
74                 if !v:shell_error
75                         exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)'))
76                 endif
77         finally
78                 if exists("exepath")
79                         silent! call delete(exepath)
80                 endif
81         endtry
82 endfunction
83
84 " Expand {{{1
85
86 function! rust#Expand(bang, args)
87         if a:bang && !empty(a:args)
88                 let pretty = a:args[0]
89                 let args = a:args[1:]
90         else
91                 let pretty = "expanded"
92                 let args = a:args
93         endif
94         call s:WithPath(function("s:Expand"), pretty, args)
95 endfunction
96
97 function! s:Expand(path, pretty, args)
98         try
99                 let rustc = exists("g:rustc_path") ? g:rustc_path : "rustc"
100
101                 let args = [a:path, '--pretty', a:pretty] + a:args
102                 let output = system(shellescape(rustc) . " " . join(map(args, "shellescape(v:val)")))
103                 if v:shell_error
104                         echohl WarningMsg
105                         echo output
106                         echohl None
107                 else
108                         new
109                         silent put =output
110                         1
111                         d
112                         setl filetype=rust
113                         setl buftype=nofile
114                         setl bufhidden=hide
115                         setl noswapfile
116                 endif
117         endtry
118 endfunction
119
120 function! rust#CompleteExpand(lead, line, pos)
121         if a:line[: a:pos-1] =~ '^Expand!\s*\S*$'
122                 " first argument and it has a !
123                 let list = ["normal", "expanded", "typed", "expanded,identified", "flowgraph="]
124                 if !empty(a:lead)
125                         call filter(list, "v:val[:len(a:lead)-1] == a:lead")
126                 endif
127                 return list
128         endif
129
130         return glob(escape(a:lead, "*?[") . '*', 0, 1)
131 endfunction
132
133 " Utility functions {{{1
134
135 function! s:WithPath(func, ...)
136         try
137                 let save_write = &write
138                 set write
139                 let path = expand('%')
140                 let pathisempty = empty(path)
141                 if pathisempty || !save_write
142                         " use a temporary file named 'unnamed.rs' inside a temporary
143                         " directory. This produces better error messages
144                         let tmpdir = tempname()
145                         call mkdir(tmpdir)
146
147                         let save_cwd = getcwd()
148                         silent exe 'lcd' tmpdir
149
150                         let path = 'unnamed.rs'
151
152                         let save_mod = &mod
153                         set nomod
154
155                         silent exe 'keepalt write! ' . path
156                         if pathisempty
157                                 silent keepalt 0file
158                         endif
159                 else
160                         update
161                 endif
162
163                 call call(a:func, [path] + a:000)
164         finally
165                 if exists("save_mod")   | let &mod = save_mod          | endif
166                 if exists("save_write") | let &write = save_write      | endif
167                 if exists("save_cwd")   | silent exe 'lcd' save_cwd    | endif
168                 if exists("tmpdir")     | silent call s:RmDir(tmpdir)  | endif
169         endtry
170 endfunction
171
172 function! rust#AppendCmdLine(text)
173         call setcmdpos(getcmdpos())
174         let cmd = getcmdline() . a:text
175         return cmd
176 endfunction
177
178 function! s:RmDir(path)
179         " sanity check; make sure it's not empty, /, or $HOME
180         if empty(a:path)
181                 echoerr 'Attempted to delete empty path'
182                 return 0
183         elseif a:path == '/' || a:path == $HOME
184                 echoerr 'Attempted to delete protected path: ' . a:path
185                 return 0
186         endif
187         silent exe "!rm -rf " . shellescape(a:path)
188 endfunction
189
190 " }}}1
191
192 " vim: set noet sw=4 ts=4: