<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Simplify - Articles tagged with Go</title>
  <subtitle>Personal website of Saša Jovanić</subtitle>
  <id>https://www.simplify.ba/articles/tags/go/</id>
  <link href="https://www.simplify.ba/articles/tags/go/"/>
  <link href="https://www.simplify.ba/articles/tags/go/feed.xml" rel="self"/>
  <updated>2021-12-17T19:12:00+01:00</updated>
  <author>
    <name>Saša Jovanić</name>
  </author>
  <entry>
    <title>Go development using GNU Emacs</title>
    <link rel="alternate" href="https://www.simplify.ba/articles/2016/03/04/go-development-with-gnu-emacs/"/>
    <id>https://www.simplify.ba/articles/2016/03/04/go-development-with-gnu-emacs/</id>
    <published>2016-03-04T15:17:00+01:00</published>
    <updated>2016-03-15T11:15:45+01:00</updated>
    <author>
      <name>Saša Jovanić</name>
    </author>
    <content type="html">&lt;p&gt;In this post I'll describe how I use GNU Emacs in Go development. I past year and a half I changed my configuration several times and I'm sure that more changes are coming as tools get better. I'm not going into details about any of Emacs packages used in this article. Please check their documentation for available commands. I'll try to keep this article up to date as time goes by.&lt;/p&gt;

&lt;h2 id="go-mode"&gt;go-mode&lt;/h2&gt;

&lt;p&gt;First, we need syntax highlighting, formatting and other functionality provided by mayor programming modes in Emacs. In the case of Go programming language, that is &lt;a href="https://github.com/dominikh/go-mode.el"&gt;go-mode&lt;/a&gt;. &lt;code&gt;go-mode&lt;/code&gt; adds even more functionality, but I'll not cover those in this article. It's available on &lt;a href="http://melpa.org/"&gt;Melpa&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="go-projectile"&gt;go-projectile&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="http://batsov.com/projectile/"&gt;projectile&lt;/a&gt; for project management in GNU Emacs and &lt;a href="https://github.com/dougm/go-projectile"&gt;go-projectile&lt;/a&gt; was natural choice for me. You can install it using Melpa.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go-projectile&lt;/code&gt; can manage &lt;code&gt;$GOPATH&lt;/code&gt; for you. Before using &lt;code&gt;go-projectile&lt;/code&gt; I was setting &lt;code&gt;$GOPATH&lt;/code&gt; using &lt;code&gt;.dir-locals.el&lt;/code&gt; per project, similar as described in &lt;a href="/articles/2016/02/14/node-modules-bin-in-path/"&gt;my other article&lt;/a&gt; about &lt;code&gt;node_modules/.bin&lt;/code&gt;. Unfortunately, this doesn't work all the times, only after &lt;code&gt;projectile&lt;/code&gt; changes project using &lt;code&gt;projectile-switch-project&lt;/code&gt;. We can fix that.&lt;/p&gt;

&lt;p&gt;Second thing that &lt;code&gt;go-projectile&lt;/code&gt; does is installing different Go development tools needed for other GNU Emacs packages into one single location. For example for code completion we need &lt;code&gt;gocode&lt;/code&gt;, for code analysis we need &lt;code&gt;oracle&lt;/code&gt;, etc. In order to install those packages just run &lt;kbd&gt;M-x go-projectile-install-tools&lt;/kbd&gt;. There is also &lt;code&gt;go-projectile-update-tools&lt;/code&gt; when you need to update installed tools. All tools will be installed in your &lt;code&gt;~/.emacs.d/gotools&lt;/code&gt;. You can change that directory by changing &lt;code&gt;go-projectile-tools-path&lt;/code&gt; in your Emacs configuration. You can see all installed tools in the &lt;a href="https://github.com/dougm/go-projectile/blob/master/go-projectile.el"&gt;source&lt;/a&gt; of &lt;code&gt;go-projectile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, &lt;code&gt;go-projectile&lt;/code&gt; doesn't change your &lt;code&gt;$PATH&lt;/code&gt; and those tools are not available outside &lt;code&gt;go-projectile&lt;/code&gt;. We can change that too.&lt;/p&gt;

&lt;p&gt;Whole setup part looks like this:&lt;/p&gt;

&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;'go-projectile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;eval-after-load&lt;/span&gt; &lt;span class="ss"&gt;'go-mode&lt;/span&gt;
  &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;progn&lt;/span&gt;
    &lt;span class="c1"&gt;;; Set $GOPATH&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-projectile-set-gopath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;;; Set $PATH to $PATH:~/.emacs.d/gotools/bin&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-projectile-tools-add-path&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="error-checking"&gt;Error checking&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="https://github.com/flycheck/flycheck"&gt;flycheck&lt;/a&gt; and it comes with build-in support for &lt;code&gt;go vet&lt;/code&gt;, &lt;code&gt;golint&lt;/code&gt;, &lt;code&gt;go fmt&lt;/code&gt;, &lt;code&gt;go build&lt;/code&gt; and &lt;code&gt;errcheck&lt;/code&gt;. Three of those tools come together with go, other two you get after installing go tools with &lt;code&gt;go-projectile&lt;/code&gt;. Flycheck will run all of those one after another. That may be too much and in that case you can disable specific checker using &lt;code&gt;flycheck-disable-checker&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="code-completion"&gt;Code completion&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="http://company-mode.github.io/"&gt;company-mode&lt;/a&gt; for code completion in GNU Emacs. The is extension for &lt;code&gt;company-mode&lt;/code&gt; for Go programming language called &lt;a href="https://github.com/nsf/gocode/tree/master/emacs-company"&gt;company-go&lt;/a&gt;.&lt;/p&gt;

&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'go-mode-hook&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-local-variable&lt;/span&gt; &lt;span class="ss"&gt;'company-backends&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;company-go&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;company-mode&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="snippets"&gt;Snippets&lt;/h2&gt;

&lt;p&gt;If you are using &lt;code&gt;yas-snippet&lt;/code&gt; package, there is also &lt;a href="https://github.com/dominikh/yasnippet-go"&gt;yasnippet-go&lt;/a&gt; (manual install) or &lt;a href="https://github.com/toumorokoshi/go-snippets"&gt;go-snippets&lt;/a&gt; (also on &lt;a href="https://melpa.org/#/go-snippets"&gt;Melpa&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id="eldoc"&gt;ELDoc&lt;/h2&gt;

&lt;p&gt;When installing &lt;code&gt;go-projectile&lt;/code&gt; using Melpa, you will also get &lt;code&gt;go-eldoc&lt;/code&gt; package that provides go documentation. We can initialize like this:&lt;/p&gt;

&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'go-mode-hook&lt;/span&gt; &lt;span class="ss"&gt;'go-eldoc-setup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="oracleel"&gt;oracle.el&lt;/h2&gt;

&lt;p&gt;One of the installed tools is &lt;code&gt;oracle&lt;/code&gt; analysis tool and includes &lt;a href="https://github.com/golang/tools/blob/master/cmd/oracle/oracle.el"&gt;oracle.el&lt;/a&gt; that integrate &lt;code&gt;oracle&lt;/code&gt; into GNU Emacs. We can load it (if &lt;code&gt;oracle&lt;/code&gt; is installed):&lt;/p&gt;

&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defvar&lt;/span&gt; &lt;span class="nv"&gt;oracle-file&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt; &lt;span class="nv"&gt;go-projectile-tools-path&lt;/span&gt; &lt;span class="s"&gt;"/src/"&lt;/span&gt;
                            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cdr&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;assq&lt;/span&gt; &lt;span class="ss"&gt;'oracle&lt;/span&gt; &lt;span class="nv"&gt;go-projectile-tools&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                            &lt;span class="s"&gt;"/oracle.el"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-exists-p&lt;/span&gt; &lt;span class="nv"&gt;oracle-file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
		&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;load-file&lt;/span&gt; &lt;span class="nv"&gt;oracle-file&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</content>
  </entry>
</feed>
