Skip to content

Instantly share code, notes, and snippets.

@interstateone
Last active September 16, 2015 02:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save interstateone/1a8c0f4bc0d3cf932b87 to your computer and use it in GitHub Desktop.
Save interstateone/1a8c0f4bc0d3cf932b87 to your computer and use it in GitHub Desktop.
A hacked-together xcodebuild vim plugin
" autoload/ctrlp/iossim.vim
"
" @file ios-sim.vim
" @author Colin Drake
" Special thanks to: github.com/kien/ctrlp.vim/blob/extensions/autoload/ctrlp/sample.vim.
" Load guard.
if ( exists('g:loaded_ctrlp_ios_sim') && g:loaded_ctrlp_ios_sim )
\ || v:version < 700 || &cp
finish
endif
let g:loaded_ctrlp_ios_sim = 1
" Ensure that ios-sim binary was found.
if (!executable('ios-sim'))
echoerr 'ctrlp-iossim.vim: ios-sim binary not found!'
finish
endif
" Initialize extension with ctrlp.
call add(g:ctrlp_ext_vars, {
\ 'init': 'ctrlp#iossim#init()',
\ 'accept': 'ctrlp#iossim#accept',
\ 'lname': 'iOS Simulator',
\ 'sname': 'iOSSim',
\ 'type': 'line',
\ 'enter': 0,
\ 'exit': 0,
\ 'opts': 0,
\ 'sort': 0,
\ 'specinput': 0,
\ })
" Initialization function.
" Return the list of possible selections.
function! ctrlp#iossim#init()
let cmd_output = system("ios-sim showdevicetypes | sort")
let choices = split(cmd_output, "\n")
return choices
endfunction
" Accept function.
" Perform an action on the given selection.
function! ctrlp#iossim#accept(mode, str)
call ctrlp#exit()
let g:XCB_iOSSimDeviceTypeId = a:str
let cmd_output = system("ios-sim start --devicetypeid \"" . a:str . "\" &")
endfunction
" Give the extension an ID.
let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
" Allow it to be called later.
function! ctrlp#iossim#id()
return s:id
endfunction
" Create commands to execute.
command! IOSSim call ctrlp#init(ctrlp#iossim#id())
" plugin/xcodebuild.vim
"
" Description: An easy way to use xcodebuild with Vim
" Author: Jerry Marino <@jerrymarino>
" License: Vim license
" Version .45
" Run
nn <leader>r :call g:XCB_Run()<cr>
" Test
nn <leader>u :call g:XCB_Test()<cr>
" Build current target
nn <leader>b :call g:XCB_Build()<cr>
" Clean current target
nn <leader>K :call g:XCB_Clean()<cr>
" Debug
" TODO integrate debugging
" Show Build Info
nn <leader>pi :call g:XCB_BuildInfo()<cr>
" Show Build Command
nn <leader>bi :call g:XCB_BuildCommandInfo()<cr>
let g:XCB_iOSSimDeviceTypeId = 'iPhone-5s'
let s:projectName = ''
let s:isWorkspace = 0
let s:targets = []
let s:schemes = []
let s:buildConfigs = []
let s:sdk = ''
let s:buildConfiguration = ''
let s:target = ''
let s:testTarget = ''
let s:scheme = ''
let s:noProjectError = ''
fun s:init()
let s:noProjectError = "Missing .xcodeproj, "
\ . "run vim from your project\'s root directory."
call g:XCB_LoadBuildInfo()
if s:projectIsValid()
call s:defaultInit()
endif
endf
fun s:projectIsValid()
if !empty(s:projectName)
return 1
endif
return 0
endf
fun s:defaultInit()
let s:sdk = "iphonesimulator"
let s:buildConfiguration = "Debug"
let s:testTarget = "'". substitute(s:projectName, "\.\/", "", "") . "Tests'"
let s:target = "'". substitute(s:projectName, "\.\/", "", "") ."'"
let s:scheme = "'". substitute(s:projectName, "\.\/", "", "") ."'"
endf
fun g:XCB_SetTarget(target)
if !s:targetIsValid(a:target)
echoerr "Invalid target, "
\ . " use XCB_BuildInfo() to get project info"
return
endif
let s:target = a:target
echo a:target
endf
fun s:targetIsValid(target)
if index(s:targets, a:target) < 0
return 0
endif
return 1
endf
fun g:XCB_SetTestTarget(target)
if !s:targetIsValid(a:target)
echoerr "Invalid target, "
\ . " use XCB_BuildInfo() to get project info"
return
endif
let s:testTarget = a:target
endf
fun g:XCB_SetScheme(scheme)
if !s:schemeIsValid(a:scheme)
echoerr "Invalid scheme, "
\ . " use XCB_BuildInfo() to get project info"
return
endif
let s:scheme = a:scheme
echo a:scheme
endf
fun s:schemeIsValid(scheme)
if index(s:schemes, a:scheme) < 0
return 0
endif
return 1
endf
" TODO allow setting of s:sdk and validate input
fun g:XCB_Test()
if !s:projectIsValid()
echoerr s:noProjectError
return
endif
call g:XCB_RunCommandAsync(s:buildCommandWithTarget(s:testTarget, "test"))
endf
fun g:XCB_Run()
call g:XCB_RunCommand(s:buildCommandWithTarget(s:target, "build"))
call g:XCB_LaunchWithSimulator("build/Build/Products/" . s:buildConfiguration . "-" . s:sdk . "/" . substitute(s:projectName, "^\.\/", "", "") . ".app")
endf
fun g:XCB_LaunchWithSimulator(path)
call dispatch#start_command(1, "ios-sim launch \"" . fnamemodify(a:path, ":p") ."\" --devicetypeid " . g:XCB_iOSSimDeviceTypeId)
endf
fun s:buildCommandWithTarget(target, command)
let cmd = "xcodebuild "
\ . " -derivedDataPath build"
if(!empty(s:sdk))
let cmd .= " -sdk " . s:sdk
endif
if(!empty(s:buildConfiguration))
let cmd .= " -configuration " . s:buildConfiguration
endif
if(!empty(s:scheme))
let cmd .= " -scheme " . a:target
endif
if(!empty(s:projectName))
if s:isWorkspace
let cmd .= " -workspace " . s:projectName . ".xcworkspace"
else
let cmd .= " -project " . s:projectName . ".xcodeproj"
endif
endif
let cmd .= " " . a:command
if executable("xcpretty")
let cmd .= " | xcpretty"
endif
return cmd
endf
fun g:XCB_Build()
if !s:projectIsValid()
echoerr s:noProjectError
return
endif
call g:XCB_RunCommandAsync(s:buildCommandWithTarget(s:target, "build"))
endf
fun g:XCB_Clean()
if !s:projectIsValid()
echoerr s:noProjectError
return
endif
let cmd = "xcodebuild "
\ . " clean "
\ . " -target " . s:target
call g:XCB_RunCommand(cmd)
endf
fun g:XCB_BuildCommandInfo()
if !s:projectIsValid()
echoerr s:noProjectError
return
endif
echo s:buildCommandWithTarget(s:target, "build")
endf
fun g:XCB_BuildInfo()
if empty(s:projectName)
echoerr s:noProjectError
return
endif
echo "Targets:" . join(s:targets, ' ')
\ . "\tBuild Configurations:" . join(s:buildConfigs, ' ')
\ . "\tSchemes:" . join(s:schemes, ' ')
endf
fun g:XCB_LoadBuildInfo()
let s:projectName = s:findWorkspaceFileName()
if empty(s:projectName)
let s:projectName = s:findProjectFileName()
if empty(s:projectName)
return
endif
endif
let outputList = split(system("xcodebuild -list"), '\n')
let configTypeEx = '\([^ :0-9"]\([a-zA-Z ]*\)\(:\)\)'
let typeSettingEx = '\([^ ]\w\w\+$\)'
let configVarToTitleDict = {'Build Configurations:' : s:buildConfigs, 'Targets:' : s:targets, 'Schemes:' : s:schemes}
let configVar = []
for line in outputList
if match(line, configTypeEx) > 1
let typeTitle = matchstr(line, configTypeEx)
if has_key(configVarToTitleDict, typeTitle)
let configVar = get(configVarToTitleDict, typeTitle, 'default')
endif
elseif match(line, typeSettingEx) > 1
let typeSetting = matchstr(line, typeSettingEx)
if strlen(typeSetting) > 1
call add(configVar, typeSetting)
endif
endif
endfor
endf
fun s:findProjectFileName()
let s:projectFile = globpath(expand('.'), '*.xcodeproj')
return matchstr(s:projectFile, '.*\ze.xcodeproj')
endf
fun s:findWorkspaceFileName()
let s:isWorkspace = 1
let s:projectFile = globpath(expand('.'), '*.xcworkspace')
return matchstr(s:projectFile, '.*\ze.xcworkspace')
endf
fun s:isWorkspace()
return matchstr(s:projectFile, '.*\ze.xcworkspace')
endf
fun g:XCB_RunCommand(cmd)
let &makeprg=a:cmd
exec "make | cw"
redraw!
endf
fun g:XCB_RunCommandAsync(cmd)
call dispatch#compile_command(0, a:cmd, 11)
endf
call s:init()
" compiler/xcodebuild.vim
if exists("current_compiler")
finish
endif
let current_compiler = "xcodebuild"
if exists(":CompilerSet") != 2
command -nargs=* CompilerSet setlocal <args>
endif
let s:save_cpo = &cpo
set cpo-=C
CompilerSet makeprg=xcodebuild
CompilerSet errorformat=
\%f:%l:%c:{%*[^}]}:\ error:\ %m,
\%f:%l:%c:{%*[^}]}:\ fatal\ error:\ %m,
\%f:%l:%c:{%*[^}]}:\ warning:\ %m,
\%f:%l:%c:\ error:\ %m,
\%f:%l:%c:\ fatal\ error:\ %m,
\%f:%l:%c:\ warning:\ %m,
\%f:%l:\ Error:\ %m,
\%f:%l:\ error:\ %m,
\%f:%l:\ fatal\ error:\ %m,
\%f:%l:\ warning:\ %m
let &cpo = s:save_cpo
unlet s:save_cpo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment