Mercurial > vim-unreal
annotate autoload/unreal.vim @ 1:43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 25 Sep 2020 09:44:49 -0700 |
parents | ba03cac1b1c6 |
children | 9235d8341a18 |
rev | line source |
---|---|
0 | 1 " unreal.vim - Work with the Unreal Engine in Vim |
2 | |
3 " Utilities {{{ | |
4 | |
5 function! unreal#throw(message) | |
6 throw "unreal: ".a:message | |
7 endfunction | |
8 | |
9 function! unreal#error(message) | |
10 let v:errmsg = "unreal: ".a:message | |
11 echoerr v:errmsg | |
12 endfunction | |
13 | |
14 function! unreal#warning(message) | |
15 echohl WarningMsg | |
16 echom "unreal: ".a:message | |
17 echohl None | |
18 endfunction | |
19 | |
20 function! unreal#info(message) | |
21 echom "unreal: ".a:message | |
22 endfunction | |
23 | |
24 function! unreal#trace(message) | |
25 if g:unreal_trace | |
26 echom "unreal: ".a:message | |
27 endif | |
28 endfunction | |
29 | |
30 if has('win32') || has('win64') | |
31 let s:iswin = 1 | |
32 let s:dirsep = "\\" | |
33 let s:scriptext = ".bat" | |
34 else | |
35 let s:iswin = 0 | |
36 let s:dirsep = "/" | |
37 let s:scriptext = ".sh" | |
38 endif | |
39 | |
40 " }}} | |
41 | |
42 " Modules {{{ | |
43 | |
44 function! unreal#call_modules(funcname, ...) abort | |
45 for module in g:unreal_modules | |
46 let l:fullfuncname = module.'#'.a:funcname | |
47 if exists('*'.l:fullfuncname) | |
48 call unreal#trace("Calling module function: ".l:fullfuncname) | |
49 call call(l:fullfuncname, a:000) | |
50 else | |
51 call unreal#trace("Skipping ".l:fullfuncname.": doesn't exist.") | |
52 endif | |
53 endfor | |
54 endfunction | |
55 | |
56 " }}} | |
57 | |
58 " Project Management {{{ | |
59 | |
60 function! unreal#find_project_dir() abort | |
61 if !empty(g:unreal_project_dir_finder) | |
62 return call(g:unreal_project_dir_finder) | |
63 endif | |
64 | |
65 let l:path = getcwd() | |
66 try | |
67 let l:proj_dir = unreal#default_project_dir_finder(l:path) | |
68 catch /^unreal:/ | |
69 let l:proj_dir = '' | |
70 endtry | |
71 call unreal#set_project_dir(l:proj_dir) | |
72 endfunction | |
73 | |
74 function! unreal#default_project_dir_finder(path) abort | |
75 let l:cur = a:path | |
76 let l:prev = "" | |
77 while l:cur != l:prev | |
78 let l:markers = globpath(l:cur, g:unreal_project_dir_marker, 0, 1) | |
79 if !empty(l:markers) | |
80 call unreal#trace("Found marker file: ".l:markers[0]) | |
81 return l:cur | |
82 endif | |
83 let l:prev = l:cur | |
84 let l:cur = fnamemodify(l:cur, ':h') | |
85 endwhile | |
86 call unreal#throw("No UE project markers found.") | |
87 endfunction | |
88 | |
89 function! unreal#set_project_dir(project_dir, ...) abort | |
90 " Strip any end slashes on the directory path. | |
91 let g:unreal_project_dir = fnamemodify(a:project_dir, ':s?[/\\]$??') | |
92 | |
93 let l:proj_was_set = !empty(g:unreal_project_dir) | |
94 | |
95 if exists(":VimcrosoftSetSln") | |
96 if l:proj_was_set | |
97 let l:sln_files = glob(g:unreal_project_dir.s:dirsep."*.sln", 0, 1) | |
98 if !empty(l:sln_files) | |
1
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
99 " Vimcrosoft might have auto-found the same solution, already, |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
100 " in which case we don't have to set it. |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
101 if g:vimcrosoft_current_sln != l:sln_files[0] |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
102 execute "VimcrosoftSetSln ".fnameescape(l:sln_files[0]) |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
103 endif |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
104 " Make sure we have our extra compiler args ready. |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
105 call unreal#generate_vimcrosoft_extra_args(l:sln_files[0]) |
0 | 106 endif |
107 else | |
108 execute "VimcrosoftUnsetSln" | |
109 endif | |
110 endif | |
111 | |
112 if l:proj_was_set | |
113 call unreal#call_modules('on_project_changed', g:unreal_project_dir) | |
114 else | |
115 call unreal#call_modules('on_project_cleared') | |
116 endif | |
117 | |
118 let l:silent = a:0 && a:1 | |
119 if !l:silent | |
120 if l:proj_was_set | |
121 echom "UE Project set to: ".g:unreal_project_dir | |
122 else | |
123 echom "UE Project cleared" | |
124 endif | |
125 endif | |
126 endfunction | |
127 | |
128 let s:extra_args_version = 1 | |
129 | |
130 function! unreal#generate_vimcrosoft_extra_args(solution) abort | |
1
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
131 let l:argfile = |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
132 \fnamemodify(a:solution, ':p:h').s:dirsep. |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
133 \'.vimcrosoft'.s:dirsep. |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
134 \fnamemodify(a:solution, ':t').'.flags' |
0 | 135 |
1
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
136 let l:do_regen = 0 |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
137 let l:version_line = "# version ".string(s:extra_args_version) |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
138 try |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
139 call unreal#trace("Checking for extra clang args file: ".l:argfile) |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
140 let l:lines = readfile(l:argfile) |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
141 if len(l:lines) < 1 |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
142 call unreal#trace("Extra clang args file is empty... regenerating") |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
143 let l:do_regen = 1 |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
144 elseif trim(l:lines[0]) != l:version_line |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
145 call unreal#trace("Extra clang args file is outdated... regenerating") |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
146 let l:do_regen = 1 |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
147 endif |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
148 catch |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
149 call unreal#trace("Extra clang args file doesn't exist... regenerating") |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
150 let l:do_regen = 1 |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
151 endtry |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
152 if l:do_regen |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
153 let l:arglines = [ |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
154 \l:version_line, |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
155 \"-DUNREAL_CODE_ANALYZER" |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
156 \] |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
157 call writefile(l:arglines, l:argfile) |
43d0e448edce
Don't change the vimcrosoft solution if it's not needed. Fix indenting.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
158 endif |
0 | 159 endfunction |
160 | |
161 " }}} | |
162 | |
163 " Commands {{{ | |
164 | |
165 function! unreal#generate_project_files() abort | |
166 call unreal#run_make("ugenprojfiles") | |
167 endfunction | |
168 | |
169 function! unreal#set_platform(platform) abort | |
170 if index(g:unreal_platforms, a:platform) < 0 | |
171 call unreal#throw("Invalid Unreal platform: ".a:platform) | |
172 endif | |
173 let g:unreal_project_platform = a:platform | |
174 endfunction | |
175 | |
176 function! unreal#build(...) abort | |
177 let l:opts = copy(g:unreal_auto_build_options) | |
178 if a:0 | |
179 let l:opts = a:000 + l:opts | |
180 endif | |
181 let g:unreal_temp_makeprg_args__ = l:opts | |
182 call unreal#run_make("ubuild") | |
183 endfunction | |
184 | |
185 " }}} | |
186 | |
187 " Completion Functions {{{ | |
188 | |
189 function! s:add_unique_suggestion_trailing_space(suggestions) | |
190 " If there's only one answer, add a space so we can start typing the | |
191 " next argument right away. | |
192 if len(a:suggestions) == 1 | |
193 let a:suggestions[0] = a:suggestions[0] . ' ' | |
194 endif | |
195 return a:suggestions | |
196 endfunction | |
197 | |
198 function! s:filter_suggestions(arglead, suggestions) | |
199 let l:argpat = tolower(a:arglead) | |
200 let l:suggestions = filter(a:suggestions, | |
201 \{idx, val -> val =~? l:argpat}) | |
202 return s:add_unique_suggestion_trailing_space(l:suggestions) | |
203 endfunction | |
204 | |
205 function! unreal#complete_platforms(ArgLead, CmdLine, CursorPos) | |
206 return s:filter_suggestions(a:ArgLead, copy(g:unreal_platforms)) | |
207 endfunction | |
208 | |
209 function! unreal#complete_configs(ArgLead, CmdLine, CursorPos) | |
210 return s:filter_suggestions(a:ArgLead, copy(g:unreal_configurations)) | |
211 endfunction | |
212 | |
213 function! unreal#complete_build_targets(ArgLead, CmdLine, CursorPos) | |
214 let l:bits = split(a:CmdLine.'_', ' ') | |
215 let l:bits = l:bits[1:] " Remove the `UnrealBuild` command from the line | |
216 if len(l:bits) <= 1 | |
217 let l:suggestions = vimcrosoft#get_sln_project_names() | |
218 elseif len(l:bits) == 2 | |
219 let l:suggestions = copy(g:unreal_platforms) | |
220 elseif len(l:bits) == 3 | |
221 let l:suggestions = copy(g:unreal_configurations) | |
222 elseif len(l:bits) >= 4 | |
223 let l:suggestions = copy(g:unreal_build_options) | |
224 endif | |
225 return s:filter_suggestions(a:ArgLead, l:suggestions) | |
226 endfunction | |
227 | |
228 " }}} | |
229 | |
230 " Build System {{{ | |
231 | |
232 function! unreal#run_make(compilername) abort | |
233 execute "compiler ".a:compilername | |
234 if exists(':Make') " Support for vim-dispatch | |
235 Make | |
236 else | |
237 make | |
238 endif | |
239 endfunction | |
240 | |
241 " }}} | |
242 | |
243 " Unreal Scripts {{{ | |
244 | |
245 let s:builds_in_progress = [] | |
246 | |
247 function! unreal#get_script_path(scriptname, ...) abort | |
248 return g:unreal_project_dir.s:dirsep.a:scriptname.s:scriptext | |
249 endfunction | |
250 | |
251 " }}} | |
252 | |
253 " Initialization {{{ | |
254 | |
255 function! unreal#init() abort | |
256 if g:unreal_auto_find_project | |
257 call unreal#find_project_dir() | |
258 endif | |
259 endfunction | |
260 | |
261 " }}} | |
262 | |
263 " Statusline Functions {{{ | |
264 | |
265 function! unreal#statusline(...) abort | |
266 if empty(g:unreal_project_dir) | |
267 return '' | |
268 endif | |
269 | |
270 let l:line = 'UE:'.g:unreal_project_dir | |
271 return l:line | |
272 endfunction | |
273 | |
274 " }}} |