Vim adventures III
This post is part III for the Vim adventures series, it starts here.
Vim’s role
When I first learnt Vim, I was disappointed to find that it is not very good at replacing the more modern features of IDEs:
- I haven’t seen any great IDE plugin solution for iOS development.
- Completion plugins can make vim sluggish
- Even simple and fast navigation solutions (like ctags) are not as good as IDE navigation
Vim emulations inside IDEs are not a perfect solution either, they deter me from using Vim but they don’t emulate using Vim’s the most advanced features.
That is why I decided to use each tool for their strongest purpose:
- Vim is amazing for general text/code editing and refactoring
- My IDE (xcode in that case) is good enough for debugging and project browsing/tinkering.
Working with Vim alongside XCode can be painful if you do not have a way to go quickly from one editor to the other. That’s what the next section is all about.
Workflow integration with XCode
First of all, I want to be able to load project-specific settings.
Because sourcing local configuration files in insecure, I call it by manually, add this to your .vimrc:
command! -nargs=0 Loc so .vimlocal
You can then source your .vimlocal
with :Loc
.vimlocal: (place it at the root of each project)
set errorformat=%f:%l:%c:%.%#\ error:\ %m,%f:%l:%c:%.%#\ warning:\ %m,%-G%.%#
set makeprg=xcodebuild\ -quiet\ -project\ Sands.xcodeproj\ -scheme\ Sands\ -configuration\ Debug
nnoremap <silent> <leader>r :wa <bar> silent exec "!xcoderun.sh ".getcwd()."/ Sands.xcodeproj &" <bar> redraw!<CR>
nnoremap <silent> <leader>i :wa <bar> silent exec "!xcodeopen.sh ".getcwd()."/ Sands.xcodeproj ".line('.')." ".@%." &" <bar> redraw!<CR>
Line 1 and 2 allows me to use :make
Line 3 allows me to run the project in xcode, if the compilation fails, xcode opens, otherwise, it stays in the background.
Line 4 allows me to open the currently visited file/line in xcode.
Place these two files (with execution rights) somewhere in your $PATH (if you want to use these with macvim, don’t forget to set your path in .profile
).
Usage is as follows:
xcoderun.sh $PathToXcodeFolder $xcodeproj
xcodeopen.sh $PathToXcodeFolder $xcodeproj $linenr $PathToFile
xcoderun.sh:
#!/bin/bash
osascript -e "
if application \"XCode\" is running then
-- check if the application is running but not visible in the dock
tell application \"System Events\"
if visible of process \"Xcode\" is false then
-- activate xcode and reactivate the previous app
tell application \"System Events\"
set activeApp to name of first application process whose frontmost is true
end tell
tell application \"Xcode\" to activate
activate application activeApp
end if
end tell
end if
tell application \"Xcode\"
open \"$1$2\"
set workspaceDocument to workspace document \"$2\"
-- Wait for the workspace document to load with a 60 second timeout
repeat 120 times
if loaded of workspaceDocument is true then
exit repeat
end if
delay 0.5
end repeat
if loaded of workspaceDocument is true then
set actionResult to build workspaceDocument
repeat
if completed of actionResult is true then
if status of actionResult is succeeded then
set actionResult to run workspaceDocument
else
activate
end if
exit repeat
end if
delay 0.5
end repeat
end if
end tell
" > /dev/null
xcodeopen.sh:
#!/bin/bash
osascript -e "
tell application \"Xcode\"
activate
open \"$1$2\"
set workspaceDocument to workspace document \"$2\"
-- Wait for the workspace document to load with a 60 second timeout
repeat 120 times
if loaded of workspaceDocument is true then
exit repeat
end if
delay 0.5
end repeat
if loaded of workspaceDocument is false then
return
end if
end tell
" > /dev/null
#xed -l $3 doesn't seem to scroll
xed $4
osascript -e "
tell application \"System Events\"
tell process \"Xcode\"
-- got to line
keystroke \"l\" using command down
keystroke \"$3\"
keystroke return
end tell
end tell
" > /dev/null
For a quick edit, I can open a file in MacVim using xcode’s ‘Open with external editor’ mapped to Alt-E (it requires MacVim to be associated with the current file’s type).
Using these methods, I spend as much time as possible in vim and I quickly switch to XCode whenever I need to use some of the more modern features.
To autocomplete or not to autocomplete
At first, I missed Intellisense while coding in Vim. Intellisense is great - just like syntax checking on the fly, it saves time.
But my desire to use Vim outweighed its shortcomings and over time I got used to coding without these modern features. I suspect that being able to do without it will make me a better programmer in the long run.
This post is part III of the Vim Adventures series. Here is part IV. Feel free to shout me a good oul Tweet @PierreAclement…