├── .gitignore ├── bin ├── open_project.sh ├── list_available_simulators.sh ├── run_mac_app ├── project_platform.sh ├── run_ios_app └── list_schemes.sh ├── LICENSE ├── README.md ├── plugin └── xcode.vim └── doc └── xcode.txt /.gitignore: -------------------------------------------------------------------------------- 1 | doc/tags 2 | -------------------------------------------------------------------------------- /bin/open_project.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | xcode=$(xcode-select -p | sed 's|/Contents/Developer||') 4 | open -a "$xcode" "$1" 5 | -------------------------------------------------------------------------------- /bin/list_available_simulators.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -o pipefail 4 | 5 | xcrun simctl list devicetypes \ 6 | | tail -n +2 \ 7 | | sed -E "s/[[:space:]]\(.*$//" 8 | -------------------------------------------------------------------------------- /bin/run_mac_app: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | build_path=$(xcodebuild -showBuildSettings "$@" 2>/dev/null | egrep "\bBUILD_DIR\b" | sed -E "s/[[:space:]]+BUILD_DIR = //") 4 | app_path=$(find "$build_path" -iname "*.app" | head -n1) 5 | 6 | open "$app_path" 7 | -------------------------------------------------------------------------------- /bin/project_platform.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sim_info=$(xcrun xcodebuild -showBuildSettings "$@" 2>/dev/null \ 4 | | grep CORRESPONDING_SIMULATOR_SDK_NAME) 5 | 6 | if [[ "$sim_info" == *"appletv"* ]]; then 7 | platform="tvos" 8 | elif [[ "$sim_info" == *"watch"* ]]; then 9 | platform="watchos" 10 | elif [[ "$sim_info" == *"iphone"* ]]; then 11 | platform="ios" 12 | else 13 | platform="macos" 14 | fi 15 | 16 | printf "$platform" 17 | -------------------------------------------------------------------------------- /bin/run_ios_app: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | build_path=$(xcodebuild -showBuildSettings "$@" 2>/dev/null | grep -m 1 -E "\bBUILD_DIR\b" | sed -E "s/[[:space:]]+BUILD_DIR = //") 4 | app_path=$(find "$build_path" -iname "*.app" | grep -m 1 "simulator") 5 | app_id=$(defaults read "$app_path/Info" "CFBundleIdentifier") 6 | uuid=$(xcrun simctl list devices | grep "$SIMULATOR" | head -n1 | grep -E "[0-9A-F-]{8,}" -o) 7 | 8 | xcrun instruments -w "$uuid" 2>/dev/null 9 | 10 | xcrun simctl install booted "$app_path" 11 | xcrun simctl launch booted "$app_id" 12 | -------------------------------------------------------------------------------- /bin/list_schemes.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -o pipefail 4 | 5 | while getopts "f:t:i:" opt; do 6 | case $opt in 7 | f) target_type_flag="$OPTARG";; 8 | t) target="$OPTARG";; 9 | i) ignore_pattern="$OPTARG";; 10 | \?) 11 | echo "Invalid option: -$OPTARG" >&2 12 | exit 1 13 | ;; 14 | :) 15 | echo "Option -$OPTARG requires an argument" >&2 16 | exit 1 17 | ;; 18 | esac 19 | done 20 | 21 | schemes="$( 22 | xcrun xcodebuild -list "$target_type_flag" "$target" 2>/dev/null \ 23 | | awk '/Schemes:/,0' \ 24 | | tail -n +2 \ 25 | | sed -e "s/^[[:space:]]*//" 26 | )" 27 | 28 | if [ -z "$ignore_pattern" ]; then 29 | echo "$schemes" 30 | else 31 | echo "$schemes" | sed -E "$ignore_pattern" 32 | fi 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2015 Gordon Fontenot 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!WARNING] 2 | > This project is fully dead, and no further work will be done on it. There are lots of really nice modern replacements out there, from simple things like using Sourcekit-LSP directly to more complex solutions such as [xcodebuild.nvim](https://github.com/wojciech-kulik/xcodebuild.nvim). I'd encourage you to start there if you really want to use (neo)vim for your Apple ecosystem development. 3 | 4 | # xcode.vim 5 | 6 | Plugin for building and testing Xcode projects from within Vim 7 | 8 | 9 | ## Installation 10 | 11 | If you don't have a preferred installation method check out 12 | [vim-plug](https://github.com/junegunn/vim-plug): 13 | 14 | ```vim 15 | Plug 'gfontenot/vim-xcode' 16 | ``` 17 | 18 | ## Usage 19 | 20 | `xcode.vim` is a thin wrapper around `xcodebuild`, with some helper methods of 21 | its own. It dynamically finds the project in the current working directory 22 | (with support for workspaces as well) and builds the first scheme it finds. 23 | 24 | - `:Xbuild` will build the project 25 | - `:Xrun` will run the app in the iOS Simulator or locally on your Mac 26 | - `:Xtest` will test the project 27 | - `:Xclean` will clean the project's build directory 28 | - `:Xopen` will open the project or a specified file in Xcode 29 | - `:Xswitch` will switch the selected version of Xcode (requires sudo) 30 | - `:Xworkspace` will let you manually specify the workspace 31 | - `:Xproject` will let you manually specify the project 32 | - `:Xscheme` will let you manually specify the scheme 33 | - `:Xsimulator` will let you manually specify the simulator 34 | 35 | ### Default Configuration 36 | 37 | If `xcode.vim` is having trouble determining the workspace/project/scheme to 38 | use, you can set local variables to manually specify the configuration you 39 | expect: 40 | 41 | ``` 42 | let g:xcode_workspace_file = 'path/to/workspace.xcworkspace' 43 | let g:xcode_project_file = 'path/to/project.xcodeproj' 44 | let g:xcode_default_scheme = 'MyScheme' 45 | ``` 46 | 47 | If setting a scheme for each project doesn't work for you, 48 | you can set an ignore pattern to filter out schemes you don't 49 | want to be selected by default. 50 | ``` 51 | let g:xcode_scheme_ignore_pattern = "/Demo|Example/d" 52 | ``` 53 | 54 | You can also specify a custom default simulator to use: 55 | 56 | ``` 57 | let g:xcode_default_simulator = 'iPhone 5' 58 | ``` 59 | 60 | Note that manually specifying a different value with any of the setter 61 | commands listed above will override these values until you restart Vim. 62 | 63 | This is most useful when placed inside a project-specific vimrc ([See the Argo 64 | vimrc as an example][argo-vimrc]). You can make sure Vim loads these local 65 | vimrc files by default by setting the following in your main vimrc: 66 | 67 | [argo-vimrc]: https://github.com/thoughtbot/Argo/blob/master/.vimrc 68 | 69 | ``` 70 | set secure " Don't let external configs do scary shit 71 | set exrc " Load local vimrc if found 72 | ``` 73 | 74 | ### `xcpretty` support 75 | 76 | [`xcpretty`] is a gem for improving the output of xcodebuild. By default, if 77 | you have it installed, `xcode.vim` will pipe all `xcodebuild` output through 78 | `xcpretty` with the `--color` flag. 79 | 80 | [`xcpretty`]: https://github.com/supermarin/xcpretty 81 | 82 | For customization options, see the [included help doc][help] (`:help xcode` 83 | from within Vim). 84 | 85 | [help]: https://github.com/gfontenot/vim-xcode/blob/master/doc/xcode.txt 86 | 87 | ### Async builds 88 | 89 | By default, `xcode.vim` will take over the current terminal session to build 90 | and display the build/test log. However, with long build times, this might not 91 | be ideal. To help with this, `xcode.vim` allows you to customize the runner by 92 | setting `g:xcode_runner_command`. This variable should be a template string, 93 | where `{cmd}` will be replaced by the `xcodebuild` command. 94 | 95 | ```vim 96 | let g:xcode_runner_command = 'VtrSendCommandToRunner! {cmd}' 97 | ``` 98 | 99 | This is useful for using `xcode.vim` with other plugins such as 100 | [`vim-tmux-runner`] and [`vim-dispatch`]. 101 | 102 | [`vim-tmux-runner`]: https://github.com/christoomey/vim-tmux-runner 103 | [`vim-dispatch`]: https://github.com/tpope/vim-dispatch 104 | 105 | For more info, see the [included help doc][help] (`:help xcode` from within 106 | Vim). 107 | 108 | ## License 109 | 110 | xcode.vim is copyright © 2015 Gordon Fontenot. It is free software, and may be 111 | redistributed under the terms specified in the `LICENSE` file. 112 | -------------------------------------------------------------------------------- /plugin/xcode.vim: -------------------------------------------------------------------------------- 1 | command! -nargs=? -complete=customlist,s:build_actions 2 | \ Xbuild call build("") 3 | 4 | command! -nargs=? -complete=customlist,s:list_simulators 5 | \ Xrun call run("") 6 | 7 | command! Xtest call test() 8 | command! Xclean call clean() 9 | command! -nargs=? -complete=file Xopen call open("") 10 | command! -nargs=1 -complete=file Xswitch call switch("") 11 | 12 | command! -nargs=1 -complete=customlist,s:list_schemes 13 | \ Xscheme call set_scheme("") 14 | 15 | command! -nargs=1 -complete=custom,s:list_projects 16 | \ Xproject call set_project("") 17 | 18 | command! -nargs=1 -complete=custom,s:list_workspaces 19 | \ Xworkspace call set_workspace("") 20 | 21 | command! -nargs=1 -complete=customlist,s:list_simulators 22 | \ Xsimulator call set_simulator("") 23 | 24 | function! s:system_runner() 25 | if has('nvim') 26 | return 'terminal' 27 | else 28 | return '!' 29 | endif 30 | endfunction 31 | 32 | let s:default_runner_command = s:system_runner() . ' {cmd}' 33 | 34 | let s:default_xcpretty_flags = '--color' 35 | let s:default_xcpretty_testing_flags = '' 36 | let s:default_simulator = 'iPhone 6s' 37 | 38 | let s:plugin_path = expand(':p:h:h') 39 | 40 | function! s:bin_script(name) 41 | return s:plugin_path . '/bin/' . a:name 42 | endfunction 43 | 44 | function! s:cli_args(...) 45 | return ' ' . join(map(copy(a:000), 'shellescape(v:val)')) 46 | endfunction 47 | 48 | function! s:build(actions) 49 | if s:assert_project() 50 | if empty(a:actions) 51 | let actions = 'build' 52 | else 53 | let actions = a:actions 54 | endif 55 | 56 | let cmd = s:base_command(actions, s:simulator()) . s:xcpretty() 57 | call s:execute_command(cmd) 58 | endif 59 | endfunction 60 | 61 | function! s:build_actions(a, l, f) 62 | return ['build', 'analyze', 'archive', 'test', 'installsrc', 'install', 'clean'] 63 | endfunction 64 | 65 | function! s:run(simulator) 66 | if s:assert_project() 67 | if empty(a:simulator) 68 | let simulator = s:simulator() 69 | else 70 | let simulator = a:simulator 71 | endif 72 | 73 | let build_cmd = s:base_command('build', simulator) . s:xcpretty() 74 | let run_cmd = s:run_command(simulator) 75 | let cmd = build_cmd . ' \&\& ' . run_cmd 76 | call s:execute_command(cmd) 77 | endif 78 | endfunction 79 | 80 | function! s:test() 81 | if s:assert_project() 82 | let cmd = s:base_command('test', s:simulator()) . s:xcpretty_test() 83 | call s:execute_command(cmd) 84 | endif 85 | endfunction 86 | 87 | function! s:clean() 88 | if s:assert_project() 89 | let cmd = s:base_command('clean', s:simulator()) . s:xcpretty() 90 | call s:execute_command(cmd) 91 | endif 92 | endfunction 93 | 94 | function! s:open(path) 95 | if s:assert_project() 96 | if empty(a:path) 97 | if s:workspace_exists() 98 | let file_path = s:workspace_file() 99 | else 100 | let file_path = s:project_file() 101 | endif 102 | else 103 | let file_path = a:path 104 | endif 105 | call system('source ' . s:bin_script('open_project.sh') . s:cli_args(file_path)) 106 | endif 107 | endfunction 108 | 109 | function! s:switch(target) 110 | execute s:system_runner() . ' sudo xcode-select -s' . s:cli_args(a:target) 111 | endfunction 112 | 113 | function! s:set_workspace(workspace) 114 | let s:chosen_workspace = a:workspace 115 | unlet! s:available_schemes 116 | unlet! s:chosen_scheme 117 | unlet! s:use_simulator 118 | endfunction 119 | 120 | function! s:set_project(project) 121 | let s:chosen_project = a:project 122 | unlet! s:available_schemes 123 | unlet! s:chosen_scheme 124 | unlet! s:use_simulator 125 | endfunction 126 | 127 | function! s:set_scheme(scheme) 128 | let s:chosen_scheme = a:scheme 129 | unlet! s:use_simulator 130 | endfunction 131 | 132 | function! s:set_simulator(simulator) 133 | let s:chosen_simulator = a:simulator 134 | endfunction 135 | 136 | function! s:execute_command(cmd) 137 | let run_cmd = substitute(s:runner_template(), '{cmd}', a:cmd, 'g') 138 | execute run_cmd 139 | endfunction 140 | 141 | function! s:assert_project() 142 | if s:project_exists() || s:workspace_exists() 143 | return 1 144 | else 145 | echohl ErrorMsg | echo 'No Xcode project file found!' | echohl None 146 | return 0 147 | endif 148 | endfunction 149 | 150 | function! s:project_exists() 151 | if empty(s:project_files()) && !exists('g:xcode_project_file') 152 | return 0 153 | else 154 | return 1 155 | endif 156 | endfunction 157 | 158 | function! s:workspace_exists() 159 | if empty(s:workspace_files()) && !exists('g:xcode_workspace_file') 160 | return 0 161 | else 162 | return 1 163 | endif 164 | endfunction 165 | 166 | function! s:base_command(actions, simulator) 167 | return 'set -o pipefail; ' 168 | \ . 'NSUnbufferedIO=YES xcrun xcodebuild ' 169 | \ . a:actions 170 | \ . ' ' 171 | \ . s:build_target_with_scheme() 172 | \ . ' ' 173 | \ . s:destination(a:simulator) 174 | endfunction 175 | 176 | function! s:run_command(simulator) 177 | if s:use_simulator() 178 | return s:iphone_simulator_run_command(a:simulator) 179 | else 180 | return s:mac_run_command() 181 | endif 182 | endfunction 183 | 184 | function! s:iphone_simulator_run_command(simulator) 185 | return 'SIMULATOR="' . a:simulator . '" ' 186 | \ . s:bin_script('run_ios_app') 187 | \ . ' ' 188 | \ . s:build_target_with_scheme() 189 | endfunction 190 | 191 | function! s:mac_run_command() 192 | return s:bin_script('run_mac_app') . ' ' . s:build_target_with_scheme() 193 | endfunction 194 | 195 | function! s:build_target_with_scheme() 196 | return s:build_target() . ' ' . s:scheme() 197 | endfunction 198 | 199 | function! s:build_target() 200 | return s:build_target_flag() . ' ' . s:build_target_argument() 201 | endfunction 202 | 203 | function! s:build_target_flag() 204 | if s:workspace_exists() 205 | return s:cli_args('-workspace') 206 | else 207 | return s:cli_args('-project') 208 | endif 209 | endfunction 210 | 211 | function! s:build_target_argument() 212 | if s:workspace_exists() 213 | return s:cli_args(s:workspace_file()) 214 | else 215 | return s:cli_args(s:project_file()) 216 | endif 217 | endfunction 218 | 219 | function! s:workspace_file() 220 | if !exists('s:chosen_workspace') 221 | if exists('g:xcode_workspace_file') 222 | let s:chosen_workspace = g:xcode_workspace_file 223 | else 224 | let s:chosen_workspace = s:workspace_files()[0] 225 | endif 226 | endif 227 | 228 | return s:chosen_workspace 229 | endfunction 230 | 231 | function! s:list_workspaces(a, l, f) 232 | return s:workspace_files() 233 | endfunction 234 | 235 | function! s:workspace_files() 236 | return globpath(expand('.'), '*.xcworkspace', 0, 1) 237 | endfunction 238 | 239 | function! s:project_file() 240 | if !exists('s:chosen_project') 241 | if exists('g:xcode_project_file') 242 | let s:chosen_project = g:xcode_project_file 243 | else 244 | let s:chosen_project = s:project_files()[0] 245 | endif 246 | endif 247 | 248 | return s:chosen_project 249 | endfunction 250 | 251 | function! s:list_projects(a, l, f) 252 | return s:project_files() 253 | endfunction 254 | 255 | function! s:project_files() 256 | return globpath(expand('.'), '*.xcodeproj', 0, 1) 257 | endfunction 258 | 259 | function! s:scheme() 260 | return '-scheme'. s:cli_args(s:scheme_name()) 261 | endfunction 262 | 263 | function! s:scheme_name() 264 | if !exists('s:chosen_scheme') 265 | if exists('g:xcode_default_scheme') 266 | let s:chosen_scheme = g:xcode_default_scheme 267 | else 268 | let s:chosen_scheme = s:schemes()[0] 269 | endif 270 | endif 271 | 272 | return s:chosen_scheme 273 | endfunction 274 | 275 | function! s:list_schemes(a, l, f) 276 | return s:schemes() 277 | endfunction 278 | 279 | function! s:schemes() 280 | if !exists('s:available_schemes') 281 | call s:get_available_schemes() 282 | endif 283 | return s:available_schemes 284 | endfunction 285 | 286 | function! s:get_available_schemes() 287 | let scheme_command = 'source ' 288 | \ . s:bin_script('list_schemes.sh') 289 | \ . ' ' 290 | \ . '-f' 291 | \ . s:build_target_flag() 292 | \ . ' ' 293 | \ . '-t' 294 | \ . s:build_target_argument() 295 | 296 | if exists('g:xcode_scheme_ignore_pattern') 297 | let scheme_command .= ' ' . '-i' . s:cli_args(g:xcode_scheme_ignore_pattern) 298 | endif 299 | 300 | let s:available_schemes = systemlist(scheme_command) 301 | endfunction 302 | 303 | function! s:simulator() 304 | if !exists('s:chosen_simulator') 305 | if exists('g:xcode_default_simulator') 306 | let s:chosen_simulator = g:xcode_default_simulator 307 | else 308 | let s:chosen_simulator = s:default_simulator 309 | endif 310 | endif 311 | 312 | return s:chosen_simulator 313 | endfunction 314 | 315 | function! s:list_simulators(a, l, f) 316 | return s:available_simulators() 317 | endfunction 318 | 319 | function! s:available_simulators() 320 | if !exists('s:simulators') 321 | let s:simulators = systemlist('source ' . s:bin_script('list_available_simulators.sh')) 322 | endif 323 | 324 | return s:simulators 325 | endfunction 326 | 327 | function! s:use_simulator() 328 | if !exists('s:use_simulator') 329 | let platform = system('source ' . s:bin_script('project_platform.sh') . ' ' . s:build_target_with_scheme()) 330 | let s:use_simulator = platform ==# "ios" 331 | endif 332 | 333 | return s:use_simulator 334 | endfunction 335 | 336 | function! s:destination(simulator) 337 | if s:use_simulator() 338 | return s:iphone_simulator_destination(a:simulator) 339 | else 340 | return s:osx_destination() 341 | endif 342 | endfunction 343 | 344 | function! s:iphone_simulator_destination(simulator) 345 | return '-destination "platform=iOS Simulator,name=' . a:simulator . '"' 346 | endfunction 347 | 348 | function! s:osx_destination() 349 | return '-destination "platform=OS X"' 350 | endfunction 351 | 352 | function! s:runner_template() 353 | if exists('g:xcode_runner_command') 354 | return g:xcode_runner_command 355 | else 356 | return s:default_runner_command 357 | endif 358 | endfunction 359 | 360 | function! s:xcpretty() 361 | if executable('xcpretty') 362 | return ' | xcpretty ' . s:xcpretty_flags() 363 | else 364 | return '' 365 | endif 366 | endfunction 367 | 368 | function! s:xcpretty_test() 369 | let xcpretty = s:xcpretty() 370 | if empty(xcpretty) 371 | return '' 372 | else 373 | return xcpretty . ' ' . s:xcpretty_testing_flags() 374 | endif 375 | endfunction 376 | 377 | function! s:xcpretty_flags() 378 | if exists('g:xcode_xcpretty_flags') 379 | return g:xcode_xcpretty_flags 380 | else 381 | return s:default_xcpretty_flags 382 | endif 383 | endfunction 384 | 385 | function! s:xcpretty_testing_flags() 386 | if exists('g:xcode_xcpretty_testing_flags') 387 | return g:xcode_xcpretty_testing_flags 388 | else 389 | return s:default_xcpretty_testing_flags 390 | endif 391 | endfunction 392 | -------------------------------------------------------------------------------- /doc/xcode.txt: -------------------------------------------------------------------------------- 1 | *xcode.txt* 2 | 3 | xcode.vim 4 | Build and test Xcode projects from Vim 5 | 6 | ============================================================================== 7 | CONTENTS *xcode-Contents* 8 | 9 | 1. About.......................... |xcode-About| 10 | 2. Usage ......................... |xcode-Usage| 11 | 2.1 ............................. |xcode-:Xbuild| 12 | 2.2 ............................. |xcode-:Xrun| 13 | 2.3 ............................. |xcode-:Xtest| 14 | 2.4 ............................. |xcode-:Xclean| 15 | 2.5 ............................. |xcode-:Xopen| 16 | 2.6 ............................. |xcode-:Xswitch| 17 | 2.7 ............................. |xcode-:Xworkspace| 18 | 2.8 ............................. |xcode-:Xproject| 19 | 2.9 ............................. |xcode-:Xscheme| 20 | 2.10 ............................. |xcode-:Xsimulator| 21 | 2.11 ............................. |xcode-xcpretty| 22 | 3. Configuration ................. |xcode-Configuration| 23 | 3.1 .............................. |xcode_runner_command| 24 | 3.2 .............................. |xcode_xcpretty_flags| 25 | 3.3 .............................. |xcode_xcpretty_testing_flags| 26 | 3.4 .............................. |xcode_workspace_file| 27 | 3.5 .............................. |xcode_project_file| 28 | 3.6 .............................. |xcode_default_scheme| 29 | 3.7 .............................. |xcode_scheme_ignore_pattern| 30 | 3.8 .............................. |xcode_default_simulator| 31 | 32 | ============================================================================== 33 | ABOUT (1) *xcode-About* 34 | 35 | `xcode.vim` is primarily a thin wrapper around Apple's `xcodebuild` command 36 | line application that lets you build and test your Xcode projects from within 37 | Vim. It dynamically figures out your project information and passes the proper 38 | flags to `xcodebuild`. 39 | 40 | If you have `xcpretty`[1] installed, `xcode.vim` will use it to reformat 41 | the output from `xcodebuild`. 42 | 43 | This plugin was written by Gordon Fontenot[2]. Bugs and feature requests are 44 | welcomed, and can be posted on the GitHub repo[3]. 45 | 46 | [1]: https://github.com/supermarin/xcpretty 47 | [2]: http://gordonfontenot.com 48 | [3]: https://github.com/gfontenot/vim-xcode 49 | 50 | ============================================================================== 51 | USAGE (2) *xcode-Usage* 52 | 53 | `xcode.vim` provides two main commands, one for building the project, and one 54 | for testing the project. It dynamically looks at your project configuration 55 | and determines which flags to pass to `xcodebuild`. 56 | 57 | Currently, `xcode.vim` only looks at the first scheme that it finds in the 58 | Xcode project file in the working directory. It uses the build settings in 59 | that scheme to determine which SDK to test against. If you have an Xcode 60 | workspace file that contains your project (as is common with projects using 61 | CocoaPods[4]), it will build the scheme through the workspace. 62 | 63 | [4]: https://cocoapods.org/ 64 | 65 | ------------------------------------------------------------------------------ 66 | *xcode-:Xbuild* 67 | 2.1 :Xbuild~ 68 | 69 | Build the project with `xcodebuild`. 70 | 71 | The first time this command is run, there will be a small delay as the plugin 72 | parses the scheme information from the project. This scheme info is cached 73 | with your Vim session, so subsequent runs will execute faster. 74 | 75 | You can also optionally pass build actions to |:Xbuild| if you'd like to 76 | override the default of `build`. This could be used, for example, to run 77 | `xcodebuild clean build` if you wanted to clean before building. 78 | 79 | ------------------------------------------------------------------------------ 80 | *xcode-:Xrun* 81 | 2.2 :Xrun 82 | 83 | Build and run the app in the iOS simulator or locally on your Mac. 84 | 85 | You can also optionally pass a simulator name to |:Xrun| if you'd like to 86 | override the default for this specific session. 87 | 88 | ------------------------------------------------------------------------------ 89 | *xcode-:Xtest* 90 | 2.3 :Xtest~ 91 | 92 | Run the project tests through `xcodebuild`. 93 | 94 | The first time this command is run, there will be a small delay as the plugin 95 | parses the SDK information for the scheme, and might be a delay while it 96 | parses the scheme information as well (if |:Xbuild| hasn't been run 97 | previously). This information is cached with the Vim session, so subsequent 98 | runs will execute faster. 99 | 100 | ------------------------------------------------------------------------------ 101 | *xcode-:Xclean* 102 | 2.4 :Xclean~ 103 | 104 | Clean the project's build directory with `xcodebuild` 105 | 106 | This is useful for debugging build errors. Sometimes Xcode doesn't behave, and 107 | grabs stale build objects. Cleaning the project's build directory can 108 | occasionally solve these issues. 109 | 110 | ------------------------------------------------------------------------------ 111 | *xcode-:Xopen* 112 | 2.5 :Xopen~ 113 | 114 | Open the project or a specified file in Xcode 115 | 116 | There are still some things that aren't able to be done in Vim. Things like 117 | modifying the project index, changing build settings, and working with 118 | Interface Builder are better done in Xcode. This command provides an easy way 119 | to open the project quickly. 120 | 121 | You can also pass an optional file path to this command in order to open that 122 | file in Xcode. This can be useful for doing things like debugging a tricky 123 | class with the help of Xcode's faster feedback loop, or modifying an interface 124 | file. 125 | 126 | Xcode itself is fairly smart about this, too. If you open a specific file 127 | while you have the project itself open, Xcode will actually just open the 128 | specified file inside the already-open project. 129 | 130 | ------------------------------------------------------------------------------ 131 | *xcode-:Xswitch* 132 | 2.6 :Xswitch~ 133 | 134 | Switch the selected version of Xcode with `xcode-select`. 135 | 136 | Different versions of Xcode contain different versions of Swift and different 137 | versions of the compiler. Switching the version of Xcode can easily be done 138 | outside of Vim with `xcode-select`, but it's useful to have a quick shortcut 139 | for accessing that functionality quickly. 140 | 141 | ------------------------------------------------------------------------------ 142 | *xcode-:Xworkspace* 143 | 2.7 :Xworkspace~ 144 | 145 | Set the workspace to build or test through `xcodebuild`. 146 | 147 | Specify the workspace to build or test. Calling this command resets the 148 | currently set SDK to build with, as well as the selected scheme. If you set a 149 | workspace that doesn't exist, `xcodebuild` will throw an error. 150 | 151 | ------------------------------------------------------------------------------ 152 | *xcode-:Xproject* 153 | 2.8 :Xproject~ 154 | 155 | Set the project to build or test through `xcodebuild`. 156 | 157 | Specify the project to build or test. Calling this command resets the 158 | currently set SDK to build with, as well as the selected scheme. If you set a 159 | project that doesn't exist, `xcodebuild` will throw an error. 160 | 161 | ------------------------------------------------------------------------------ 162 | *xcode-:Xscheme* 163 | 2.9 :Xscheme~ 164 | 165 | Set the scheme to build or test through `xcodebuild`. 166 | 167 | Specify the scheme to build or test. Calling this command resets the currently 168 | set SDK to build with. If you set a scheme that doesn't exist, `xcodebuild` 169 | will throw an error. 170 | 171 | ------------------------------------------------------------------------------ 172 | *xcode-:Xsimulator* 173 | 2.10 :Xsimulator~ 174 | 175 | Set the simulator to use for building/testing/running. 176 | 177 | This will set the simulator to use for all commands while Xcode is running. It 178 | will be reset to the default value (`"iPhone 6s"`) when Vim restarts. 179 | 180 | ------------------------------------------------------------------------------ 181 | *xcode-xcpretty* 182 | 2.11 xcpretty~ 183 | 184 | If `xcpretty`[1] is installed and is available in your `$PATH`, `xcode.vim` 185 | will pipe all output through it to improve `xcodebuild`'s output. See 186 | |xcode-Configuration| for info on how to customize the appearance of the 187 | output. 188 | 189 | ============================================================================== 190 | CONFIGURATION (3) *xcode-Configuration* 191 | 192 | You can configure `xcode.vim` with the following settings: 193 | 194 | ------------------------------------------------------------------------------ 195 | *xcode_runner_command* 196 | 3.1 g:xcode_runner_command~ 197 | 198 | The command to use when executing `xcodebuild` commands. 199 | 200 | This is a template string used to execute the actual command. The string 201 | "{cmd}" will be replaced with the actual `xcodebuild` command that has been 202 | generated. 203 | 204 | You can customize this if you want to pass the command through a custom script 205 | in your `$PATH`, or use something like `vim-tmux-runner`[4] or 206 | `vim-dispatch`[5] to make builds asynchronous 207 | 208 | let g:xcode_runner_command = 'VtrSendCommandToRunner! {cmd}' 209 | 210 | Default: '! {cmd}` 211 | 212 | [4]: https://github.com/christoomey/vim-tmux-runner 213 | [5]: https://github.com/tpope/vim-dispatch 214 | 215 | ------------------------------------------------------------------------------ 216 | *xcode_xcpretty_flags* 217 | 3.2 g:xcode_xcpretty_flags~ 218 | 219 | The flags to pass to `xcpretty`[1] for all actions, including tests. 220 | 221 | See the `xcpretty` documentation[6] for available options. 222 | 223 | let g:xcode_xcpretty_flags = '--no-utf --color' 224 | 225 | Default: '--color' 226 | 227 | [6]: https://github.com/supermarin/xcpretty#formats 228 | 229 | ------------------------------------------------------------------------------ 230 | *xcode_xcpretty_testing_flags* 231 | 3.3 g:xcode_xcpretty_testing_flags~ 232 | 233 | The flags to pass to `xcpretty`[1] for test actions only. 234 | 235 | These will be combined with the flags from |xcode_xcpretty_flags| and 236 | passed only to test actions. These are set separately because some flags, such 237 | as '--test', hide the build output, which is probably undesirable during 238 | normal build actions. 239 | 240 | See the `xcpretty` documentation[6] for available options. 241 | 242 | let g:xcode_xcpretty_testing_flags = '--test' 243 | 244 | Default: '' 245 | 246 | [6]: https://github.com/supermarin/xcpretty#formats 247 | 248 | ------------------------------------------------------------------------------ 249 | *xcode_workspace_file* 250 | 3.4 g:xcode_workspace_file~ 251 | 252 | The main workspace to use for building and testing. 253 | 254 | If `xcode.vim` routinely selects the wrong workspace, you can set this local 255 | variable to tell it which to use. This is useful if you have multiple 256 | workspaces at the root of your project directory and the one you would like to 257 | default to isn't the first alphabetically. 258 | 259 | If not set, `xcode.vim` will default to the first workspace file it finds 260 | alphabetically. 261 | 262 | ------------------------------------------------------------------------------ 263 | *xcode_project_file* 264 | 3.5 g:xcode_project_file~ 265 | 266 | The main project to use for building and testing. 267 | 268 | If `xcode.vim` routinely selects the wrong project, you can set this local 269 | variable to tell it which to use. This is useful if you have multiple projects 270 | at the root of your project directory and the one you would like to default to 271 | isn't the first alphabetically. 272 | 273 | If not set, `xcode.vim` will default to the first project file it finds 274 | alphabetically. 275 | 276 | ------------------------------------------------------------------------------ 277 | *xcode_default_scheme* 278 | 3.6 g:xcode_default_scheme~ 279 | 280 | The default scheme to use for building and testing. 281 | 282 | If `xcode.vim` routinely selects the wrong scheme, you can set this local 283 | variable to tell it which to use. This is useful if you have multiple schemes 284 | in your project, and they are occasionally reordered. 285 | 286 | If not set, `xcode.vim` will default to the first scheme listed as a result of 287 | `xcodebuild -list` 288 | 289 | ------------------------------------------------------------------------------ 290 | *xcode_scheme_ignore_pattern* 291 | 3.7 g:xcode_scheme_ignore_pattern~ 292 | 293 | The optional ignore pattern when listing/building Xcode schemes. 294 | 295 | Patterns can be any entended regular expression. This setting is useful if you 296 | have multiple schemes in your project/workspace, and you wish to always 297 | ignore demo apps for example. Also, setting this scheme can help you avoid 298 | having to set an xcode_default_scheme for each project. 299 | 300 | If not set, `xcode.vim` will default to the first scheme listed as a result of 301 | `xcodebuild -list` or the scheme set as the `xcode_default_scheme`. 302 | 303 | ------------------------------------------------------------------------------ 304 | *xcode_default_simulator* 305 | 3.8 g:xcode_default_simulator~ 306 | 307 | The default simulator to use for building/testing/running. 308 | 309 | If you'd like to make sure that you use a specific device by default every 310 | time you build/run/test your iOS app, you can set this variable to do so. 311 | 312 | If not set, `xcode.vim` will default to `"iPhone 6s"` 313 | 314 | ============================================================================== 315 | vim:tw=78:ts=8:ft=help:norl: 316 | --------------------------------------------------------------------------------