xkick brings Golang support to Xcode 11
October 8, 2019
- Syntax Highlighting
- Jump to type/method/function definitions
- Automatic Go code formatting
- Automatic completion of Go imports
- How does it work?
- Installation Instructions
- Uninstall xkick
Hands down, Xcode is possibly the best IDE (integrated development environment) for macOS. It's got a clean user interface, it feels snappy, and it's easy to organize and navigate through large coding projects. There are many IDEs available for the macOS, but perhaps not as performant as Xcode.
Since Xcode happens to be Apple's flagship IDE, it makes sense that it comes with first-class support to develop Apple-specific technologies (iOS, macOS, tvOS, watchOS, etc). But what if you wanted lightweight support for the Go programming language (Golang) on Xcode? Well, unfortunately, there's been no recent efforts to provide Golang support for Xcode. Until now.
We created our newest tool, xkick, to bring limited Golang support to the latest version of Xcode, Xcode 11.
xkick comes with basic syntax highlighting support, the ability to jump to type/method/function definitions, automatic Go code formatting, and automatic Go imports completion.
xkick provides basic syntax highlighting for Golang by adding "Golang" as an option to the "Syntax Coloring" sub-menu found in Xcode's "Editor" menu.
Jump to type/method/function definitions
xkick provides the capability to jump to type/method/function definitions.
Automatic Go code formatting
Go code is automatically formatted upon saving the file.
Automatic completion of Go imports
Go imports are automatically completed upon saving the file.
How does it work?
The xkick product consists of two items: The xkick installer package and the xkick command line interface (CLI) tool.
The xkick installer package is responsible for installing the required files to make Xcode aware of Golang, and it also installs the xkick CLI tool at /usr/local/bin.
The xkick CLI tool watches a set of Go source files for changes in a Go project folder (and its subfolders). When a change is detected to a Go source file, xkick ensures that the changed Go source file is automatically formatted and that it's Go imports are automatically updated as well.
Use Workspaces for organizing and navigating through large Go codebases.
To get started, in the Xcode menu, choose File -> New -> Workspace. Give your workspace a name, and select a folder to save it in.
Open a Finder window and navigate to your Go project. Drag your Go project's folder into the Xcode Workspace's files pane.
When Xcode prompts you to choose options for adding the files, select the option "Create folder references for any added folders". Make sure that the "Copy items into destination's group folder" option is not checked. Click the Finish button when done.
Some benefits of Xcode
Searching through the codebase
With Xcode, searching through your Go codebase is super fast. You can search through multiple files using the following key combination: ⌘ + Shift + F
Opening a source file in a new window.
Double-clicking the source file will open it up in a new window.
Xcode remembers your windows
When you turn your Mac off, and then when you turn it back on again, you get to start off in Xcode from where you left off. All your open source file windows are remembered by Xcode.
Because of it's tight integration with macOS, Xcode provides excellent support for full-screen mode.
Quick Workspace Access
Xcode provies quick access to your workspace. Just right click on the Xcode icon in the dock, and you can easily open recent workspaces.
xkick CLI tool
The xkick CLI tool is responsible for watching a Go project folder and ensuring that the Go source file gets automatic formatting and automatic imports completion applied anytime the source file is updated.
To use the xkick CLI tool, open the terminal app and enter the directory containing your Go project, for example:
$ cd $GOPATH/src/MyGoProject $ xkick
In this example, we didn't specify a directory for xkick to watch so xkick will watch the current working directory.
Specify a directory to watch
If you want to watch some other directory, you can specify a directory for xkick to watch using the -directory flag:
$ xkick -directory=$GOPATH/src/github.com/EngineerKamesh/gofullstack/volume2/section7/gopherfaceq
Skipping vendor directories
By default, vendor directories are skipped over (you should have a pretty good reason for editing code in vendored packages). If you really want xkick to watch for changes in Go source files that live in vendor directories, set the -skip-vendor flag to false (it's true by default):
$ xkick -skip-vendor=false
By default, verbose mode is turned off. When verbose mode is turned on, xkick will print out the name of the Go source file when a change is detected to the file. You can turn on verbose mode like so:
$ xkick -verbose=true
Syntax errors show up in the xkick output:
If there are syntax errors in your Go code, they'll show up in the xkick output, upon saving the file. The auto formatting and auto imports completion steps will fail and will display the error that was encountered. The errors you see here, will be the errors that are reported directly from the gofmt and goimports commands:
gofmt error: exit status 2 /Users/kamesh/go/src/github.com/EngineerKamesh/gofullstack/volume2/section7/gopherfaceq/common/asyncq/asyncq.go:6:1: expected declaration, found foobar goimports error: exit status 2 /Users/kamesh/go/src/github.com/EngineerKamesh/gofullstack/volume2/section7/gopherfaceq/common/asyncq/asyncq.go:6:1: expected declaration, found 'IDENT' foobar
Limitations and Known Issues
With the introduction of System Integrity Protection in 2016, Xcode no longer supports writing custom plugins. That means, at the current time, plugins are not possible (e.g for Go code completion and building/running/debugging Go projects within Xcode).
Known Issue: "The file has been changed by another application" Dialog
Remedy 1: Hit the "Save Anyway" button, and the Go source file will undergo the automatic formatting and automatic imports completion steps in one or more subsequent cycles.
Remedy 2: Specify a higher writes delay value. The writes delay value specifies the delay (in milliseconds) of how long each source code formatting operation should take. The default writes delay value is 999 milliseconds. You can change this value by including the -writes-delay flag when running xkick:
$ xkick -writes-delay=1800
- macOS Catalina or Mojave
- Xcode (v11.0)
- Go (v1.12+)
- gofmt (included with Go)
- High maxfiles limit
Prior to running the xkick installer package, the following prerequisites must be met:
We recommend running xkick on macOS Catalina or Mojave. Both the xkick installer package and the xkick CLI tool have been codesigned and notarized.
We recommend running xkick on Xcode 11. xkick isn't designed to work for older versions of Xcode.
Go, gofmt, and goimports
You can grab the latest version of Go for macOS from the Go website's Downloads page. The Go distribution includes the gofmt tool.
You can install goimports by issuing the following command:
$ go get golang.org/x/tools/cmd/goimports
Using the Terminal app, you should now be able to issue the goimports --help command.
If the command was not found, make sure that you've set the GOPATH environment variable, and that you've added the /bin subdirectory to your PATH, as described in the GOPATH environment variable section of the How to Write Go Code document.
High maxfiles limit
You need to increase the system's default max open files limit. You can see what your current limit is by issuing the folowing command:
$ launchctl limit maxfiles
We recommend setting the max open files limit to 262144. Note: If your Go project has more files than this, you will need to set this to a higher value accordingly.
Create a file called limit.maxfiles.plist, located at /Library/LaunchDaemons. Enter the following contents in the limit.maxfiles.plist file:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>limit.maxfiles</string> <key>ProgramArguments</key> <array> <string>launchctl</string> <string>limit</string> <string>maxfiles</string> <string>262144</string> <string>524288</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>
Once you've saved the limit.maxfiles.plist file, issue the following command, to change the file's ownership:
$ sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
Issue the following command, to reload the Launch Daemon with the updated maxfiles limits:
$ sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
Confirm that the new max files limit have been set, by issuing the following command:
$ launchctl limit maxfiles
Note: Make sure you've exited the Xcode app prior to running the xkick installer package
Once you've downloaded xkick from 2Checkout (our payment processor), double-click the xkick installer package file (with extension .pkg), click the "Continue" button and follow the on screen prompts.
Once the installer has finished installing xkick, run the following command:
$ defaults write ~/Library/Developer/Xcode/Plug-ins/Golang.ideplugin/Contents/Info DVTPlugInCompatibilityUUIDs -array-add $(defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID)
Note: Anytime you update Xcode, you will need to run the defaults write command.
Launch Xcode. You will get an "Unexpected code bundle - Golang.ideplugin" dialog. Select "Load Bundle".
You should now be able to see "Golang" in the "Syntax Coloring" sub-menu of Xcode's "Editor" menu.
See the Usage section to learn how to use xkick.
To uninstall xkick, issue the following command:
$ /Library/Application\ Support/xkick/uninstall.sh