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:

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:

Image alt

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.

Image alt

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