changeset 0:ba03cac1b1c6

Initial commit.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 24 Sep 2020 23:04:57 -0700
parents
children 43d0e448edce
files autoload/unreal.vim compiler/ubuild.vim compiler/uclean.vim compiler/ugenprojfiles.vim compiler/urebuild.vim plugin/unreal.vim syntax/unrealcpp.vim
diffstat 7 files changed, 436 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/autoload/unreal.vim	Thu Sep 24 23:04:57 2020 -0700
@@ -0,0 +1,270 @@
+" unreal.vim - Work with the Unreal Engine in Vim
+
+" Utilities {{{
+
+function! unreal#throw(message)
+    throw "unreal: ".a:message
+endfunction
+
+function! unreal#error(message)
+    let v:errmsg = "unreal: ".a:message
+    echoerr v:errmsg
+endfunction
+
+function! unreal#warning(message)
+    echohl WarningMsg
+    echom "unreal: ".a:message
+    echohl None
+endfunction
+
+function! unreal#info(message)
+    echom "unreal: ".a:message
+endfunction
+
+function! unreal#trace(message)
+    if g:unreal_trace
+        echom "unreal: ".a:message
+    endif
+endfunction
+
+if has('win32') || has('win64')
+    let s:iswin = 1
+    let s:dirsep = "\\"
+    let s:scriptext = ".bat"
+else
+    let s:iswin = 0
+    let s:dirsep = "/"
+    let s:scriptext = ".sh"
+endif
+
+" }}}
+
+" Modules {{{
+
+function! unreal#call_modules(funcname, ...) abort
+    for module in g:unreal_modules
+        let l:fullfuncname = module.'#'.a:funcname
+        if exists('*'.l:fullfuncname)
+            call unreal#trace("Calling module function: ".l:fullfuncname)
+            call call(l:fullfuncname, a:000)
+        else
+            call unreal#trace("Skipping ".l:fullfuncname.": doesn't exist.")
+        endif
+    endfor
+endfunction
+
+" }}}
+
+" Project Management {{{
+
+function! unreal#find_project_dir() abort
+    if !empty(g:unreal_project_dir_finder)
+        return call(g:unreal_project_dir_finder)
+    endif
+
+    let l:path = getcwd()
+    try
+        let l:proj_dir = unreal#default_project_dir_finder(l:path)
+    catch /^unreal:/
+        let l:proj_dir = ''
+    endtry
+    call unreal#set_project_dir(l:proj_dir)
+endfunction
+
+function! unreal#default_project_dir_finder(path) abort
+    let l:cur = a:path
+    let l:prev = ""
+    while l:cur != l:prev
+        let l:markers = globpath(l:cur, g:unreal_project_dir_marker, 0, 1)
+        if !empty(l:markers)
+            call unreal#trace("Found marker file: ".l:markers[0])
+            return l:cur
+        endif
+        let l:prev = l:cur
+        let l:cur = fnamemodify(l:cur, ':h')
+    endwhile
+    call unreal#throw("No UE project markers found.")
+endfunction
+
+function! unreal#set_project_dir(project_dir, ...) abort
+    " Strip any end slashes on the directory path.
+    let g:unreal_project_dir = fnamemodify(a:project_dir, ':s?[/\\]$??')
+
+    let l:proj_was_set = !empty(g:unreal_project_dir)
+
+    if exists(":VimcrosoftSetSln")
+        if l:proj_was_set
+            let l:sln_files = glob(g:unreal_project_dir.s:dirsep."*.sln", 0, 1)
+            if !empty(l:sln_files)
+                execute "VimcrosoftSetSln ".fnameescape(l:sln_files[0])
+
+				call unreal#generate_vimcrosoft_extra_args(l:sln_files[0])
+            endif
+        else
+            execute "VimcrosoftUnsetSln"
+        endif
+    endif
+
+    if l:proj_was_set
+        call unreal#call_modules('on_project_changed', g:unreal_project_dir)
+    else
+        call unreal#call_modules('on_project_cleared')
+    endif
+
+    let l:silent = a:0 && a:1
+    if !l:silent
+        if l:proj_was_set
+            echom "UE Project set to: ".g:unreal_project_dir
+        else
+            echom "UE Project cleared"
+        endif
+    endif
+endfunction
+
+let s:extra_args_version = 1
+
+function! unreal#generate_vimcrosoft_extra_args(solution) abort
+	let l:argfile = 
+				\fnamemodify(a:solution, ':p:h').s:dirsep.
+				\'.vimcrosoft'.s:dirsep.
+				\fnamemodify(a:solution, ':t').'.flags'
+
+	let l:do_regen = 0
+	let l:version_line = "# version ".string(s:extra_args_version)
+	try
+		call unreal#trace("Checking for extra clang args file: ".l:argfile)
+		let l:lines = readfile(l:argfile)
+		if len(l:lines) < 1
+			call unreal#trace("Extra clang args file is empty... regenerating")
+			let l:do_regen = 1
+		elseif trim(l:lines[0]) != l:version_line
+			call unreal#trace("Extra clang args file is outdated... regenerating")
+			let l:do_regen = 1
+		endif
+	catch
+		call unreal#trace("Extra clang args file doesn't exist... regenerating")
+		let l:do_regen = 1
+	endtry
+	if l:do_regen
+		let l:arglines = [
+					\l:version_line,
+					\"-DUNREAL_CODE_ANALYZER"
+					\]
+		call writefile(l:arglines, l:argfile)
+	endif
+endfunction
+
+" }}}
+
+" Commands {{{
+
+function! unreal#generate_project_files() abort
+    call unreal#run_make("ugenprojfiles")
+endfunction
+
+function! unreal#set_platform(platform) abort
+    if index(g:unreal_platforms, a:platform) < 0
+        call unreal#throw("Invalid Unreal platform: ".a:platform)
+    endif
+    let g:unreal_project_platform = a:platform
+endfunction
+
+function! unreal#build(...) abort
+    let l:opts = copy(g:unreal_auto_build_options)
+    if a:0
+        let l:opts = a:000 + l:opts
+    endif
+    let g:unreal_temp_makeprg_args__ = l:opts
+    call unreal#run_make("ubuild")
+endfunction
+
+" }}}
+
+" Completion Functions {{{
+
+function! s:add_unique_suggestion_trailing_space(suggestions)
+    " If there's only one answer, add a space so we can start typing the
+    " next argument right away.
+    if len(a:suggestions) == 1
+        let a:suggestions[0] = a:suggestions[0] . ' '
+    endif
+    return a:suggestions
+endfunction
+
+function! s:filter_suggestions(arglead, suggestions)
+    let l:argpat = tolower(a:arglead)
+    let l:suggestions = filter(a:suggestions,
+                \{idx, val -> val =~? l:argpat})
+    return s:add_unique_suggestion_trailing_space(l:suggestions)
+endfunction
+
+function! unreal#complete_platforms(ArgLead, CmdLine, CursorPos)
+    return s:filter_suggestions(a:ArgLead, copy(g:unreal_platforms))
+endfunction
+
+function! unreal#complete_configs(ArgLead, CmdLine, CursorPos)
+    return s:filter_suggestions(a:ArgLead, copy(g:unreal_configurations))
+endfunction
+
+function! unreal#complete_build_targets(ArgLead, CmdLine, CursorPos)
+    let l:bits = split(a:CmdLine.'_', ' ')
+    let l:bits = l:bits[1:]  " Remove the `UnrealBuild` command from the line
+    if len(l:bits) <= 1
+        let l:suggestions = vimcrosoft#get_sln_project_names()
+    elseif len(l:bits) == 2
+        let l:suggestions = copy(g:unreal_platforms)
+    elseif len(l:bits) == 3
+        let l:suggestions = copy(g:unreal_configurations)
+    elseif len(l:bits) >= 4
+        let l:suggestions = copy(g:unreal_build_options)
+    endif
+    return s:filter_suggestions(a:ArgLead, l:suggestions)
+endfunction
+
+" }}}
+
+" Build System {{{
+
+function! unreal#run_make(compilername) abort
+    execute "compiler ".a:compilername
+    if exists(':Make')  " Support for vim-dispatch
+        Make
+    else
+        make
+    endif
+endfunction
+
+" }}}
+
+" Unreal Scripts {{{
+
+let s:builds_in_progress = []
+
+function! unreal#get_script_path(scriptname, ...) abort
+    return g:unreal_project_dir.s:dirsep.a:scriptname.s:scriptext
+endfunction
+
+" }}}
+
+" Initialization {{{
+
+function! unreal#init() abort
+    if g:unreal_auto_find_project
+        call unreal#find_project_dir()
+    endif
+endfunction
+
+" }}}
+
+" Statusline Functions {{{
+
+function! unreal#statusline(...) abort
+    if empty(g:unreal_project_dir)
+        return ''
+    endif
+
+    let l:line = 'UE:'.g:unreal_project_dir
+    return l:line
+endfunction
+
+" }}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/ubuild.vim	Thu Sep 24 23:04:57 2020 -0700
@@ -0,0 +1,24 @@
+" Compiler file for building Unreal Engine projects
+" Compiler: Unreal Build
+" Maintainer: Ludovic Chabant <https://ludovic.chabant.com>
+
+if exists("current_compiler")
+    finish
+endif
+let current_compiler = "ubuild"
+
+let s:keepcpo = &cpo
+
+let s:prgpath = unreal#get_script_path("Engine/Build/BatchFiles/Build")
+let s:prgargs = get(g:, "unreal_temp_makeprg_args__", "")
+if !empty(s:prgargs)
+    let s:prgargs = '\ '.join(s:prgargs, '\ ')
+endif
+call unreal#trace("Setting makeprg to: ".s:prgpath.s:prgargs)
+execute "CompilerSet makeprg=".fnameescape(s:prgpath).s:prgargs
+
+CompilerSet errorformat&
+
+let &cpo = s:keepcpo
+unlet s:keepcpo
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/uclean.vim	Thu Sep 24 23:04:57 2020 -0700
@@ -0,0 +1,20 @@
+" Compiler file for building Unreal Engine projects
+" Compiler: Unreal Build
+" Maintainer: Ludovic Chabant <https://ludovic.chabant.com>
+
+if exists("current_compiler")
+    finish
+endif
+let current_compiler = "ubuild"
+
+let s:keepcpo = &cpo
+
+let s:prgpath = unreal#get_script_path("Engine/Build/BatchFiles/Clean")
+call unreal#trace("Setting makeprg to: ".s:prgpath)
+execute "CompilerSet makeprg=".fnameescape(s:prgpath)
+
+CompilerSet errorformat&
+
+let &cpo = s:keepcpo
+unlet s:keepcpo
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/ugenprojfiles.vim	Thu Sep 24 23:04:57 2020 -0700
@@ -0,0 +1,19 @@
+" Compiler file for generating Unreal Engine project files
+" Compiler: Unreal Generate Project Files
+" Maintainer: Ludovic Chabant <https://ludovic.chabant.com>
+
+if exists("current_compiler")
+    finish
+endif
+let current_compiler = "ugenprojfiles"
+
+let s:keepcpo = &cpo
+
+let s:prgpath = unreal#get_script_path("Engine/Build/BatchFiles/GenerateProjectFiles")
+call unreal#trace("Setting makeprg to: ".s:prgpath)
+execute "CompilerSet makeprg=".fnameescape(s:prgpath)
+
+CompilerSet errorformat&
+
+let &cpo = s:keepcpo
+unlet s:keepcpo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/urebuild.vim	Thu Sep 24 23:04:57 2020 -0700
@@ -0,0 +1,20 @@
+" Compiler file for building Unreal Engine projects
+" Compiler: Unreal Build
+" Maintainer: Ludovic Chabant <https://ludovic.chabant.com>
+
+if exists("current_compiler")
+    finish
+endif
+let current_compiler = "ubuild"
+
+let s:keepcpo = &cpo
+
+let s:prgpath = unreal#get_script_path("Engine/Build/BatchFiles/Rebuild")
+call unreal#trace("Setting makeprg to: ".s:prgpath)
+execute "CompilerSet makeprg=".fnameescape(s:prgpath)
+
+CompilerSet errorformat&
+
+let &cpo = s:keepcpo
+unlet s:keepcpo
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/unreal.vim	Thu Sep 24 23:04:57 2020 -0700
@@ -0,0 +1,61 @@
+" unreal.vim - Work with the Unreal Engine in Vim
+" Maintainer:    Ludovic Chabant <https://ludovic.chabant.com>
+
+" Globals {{{
+
+if !(has('job') || (has('nvim') && exists('*jobwait')))
+    echoerr "unreal: this plugin requires the job API from Vim8 or Neovim."
+    finish
+endif
+
+let g:unreal_trace = 0
+
+let g:unreal_project_dir_marker = get(g:, 'unreal_project_dir_marker', '*.uprojectdirs')
+let g:unreal_project_dir_finder = get(g:, 'unreal_project_dir_finder', '')
+let g:unreal_auto_find_project = get(g:, 'unreal_auto_find_project', 0)
+
+let g:unreal_project_dir = get(g:, 'unreal_project_dir', '')
+let g:unreal_project_platform = get(g:, 'unreal_project_platform', '')
+let g:unreal_project_config = get(g:, 'unreal_project_config', '')
+
+let g:unreal_modules = get(g:, 'unreal_modules', [])
+
+let g:unreal_platforms = get(g:, 'unreal_platforms', [
+            \"Win32", "Win64", "HoloLens", "Mac", "XboxOne", "PS4", "IOS", "Android",
+            \"HTML5", "Linux", "AllDesktop", "TVOS", "Switch"
+            \])
+let g:unreal_configurations = get(g:, 'unreal_configurations', [
+            \"Debug", "DebugGame", "Development", "Shipping", "Test"
+            \])
+let g:unreal_build_options = get(g:, 'unreal_build_options', [
+            \"-DisableUnity", "-ForceUnity"
+            \])
+let g:unreal_auto_build_options = get(g:, 'unreal_auto_build_options', [
+            \"-WaitMutex"
+            \])
+
+" }}}
+
+" Commands {{{
+
+command! UnrealFindProject :call unreal#find_project_dir()
+command! -nargs=1 -complete=dir UnrealSetProject :call unreal#set_project_dir(<f-args>)
+command! -nargs=1 -complete=customlist,unreal#complete_platforms 
+            \UnrealSetPlatform :call unreal#set_platform(<f-args>)
+command! -nargs=1 -complete=customlist,unreal#complete_config 
+            \UnrealSetConfig :call unreal#set_config(<f-args>)
+
+command! UnrealGenerateProjectFiles :call unreal#generate_project_files()
+
+command! -nargs=+ -complete=customlist,unreal#complete_build_targets 
+            \UnrealBuild :call unreal#build(<f-args>)
+command! -nargs=+ -complete=customlist,unreal#complete_build_targets 
+            \UnrealBuildEditor :call unreal#build_editor(<f-args>)
+
+" }}}
+
+" Initialization {{{
+
+call unreal#init()
+
+" }}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/syntax/unrealcpp.vim	Thu Sep 24 23:04:57 2020 -0700
@@ -0,0 +1,22 @@
+" Vim syntax file
+" Language:	C++ with Unreal extensions
+" Maintainer:	Ludovic Chabant <https://ludovic.chabant.com>
+
+if exists("b:current_syntax")
+  finish
+endif
+
+" Read the C++ syntax to start with
+runtime! syntax/cpp.vim
+unlet b:current_syntax
+
+
+" Highlight Class and Function names
+syn match    cCustomParen    "(" contains=cParen,cCppParen
+syn match    cCustomFunc     "\w\+\s*(" contains=cCustomParen
+syn match    cCustomScope    "::"
+syn match    cCustomClass    "\w\+\s*::" contains=cCustomScope
+
+hi def link cCustomFunc  Function
+hi def link cCustomClass Function
+