DEV Community

Cover image for Setting Up Emacs for Go Development on macOS
Yaseen
Yaseen

Posted on

Setting Up Emacs for Go Development on macOS

#go

Introduction

Emacs is a highly customizable text editor with powerful features for programming. In this guide, we’ll walk through installing Emacs on macOS, setting it up for Go development, and using it effectively.

Step 1: Install Emacs
First, ensure you have Emacs installed on your system. You can download it from GNU Emacs or use a package manager.

Step 2: Install Go
Make sure you have Go installed. You can download it from the official Go website.

Step 3: Install go-mode
go-mode is an Emacs major mode for editing Go code. You can install it via MELPA (Milkypostman’s Emacs Lisp Package Archive).

Enable MELPA in Emacs:
Add the following to your Emacs configuration file (usually ~/.emacs or ~/.emacs.d/init.el):

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
Enter fullscreen mode Exit fullscreen mode

Install go-mode:
Open Emacs and run the following commands:

M-x package-refresh-contents
M-x package-install RET go-mode RET

Step 4: Configure go-mode
Add the following configurations to your Emacs configuration file to enable go-mode and some useful Go tools:

(require 'go-mode)

;; Set up Go-specific key bindings
(add-hook 'go-mode-hook
          (lambda ()
            (setq tab-width 4)
            (setq indent-tabs-mode 1)))

;; Enable auto-completion
(add-hook 'go-mode-hook 'company-mode)

;; Enable Flycheck for real-time syntax checking
(add-hook 'go-mode-hook 'flycheck-mode)

;; Enable automatic formatting on save
(add-hook 'before-save-hook 'gofmt-before-save)

;; Optional: set $GOPATH and $GOROOT if not set globally
(setenv "GOPATH" "/path/to/your/gopath")
(setenv "GOROOT" "/path/to/your/goroot")
Enter fullscreen mode Exit fullscreen mode

Step 5: Install company-mode for Auto-completion
company-mode is a text completion framework for Emacs.

Install company-mode:

M-x package-install RET company RET

Step 6: Install flycheck for Syntax Checking
flycheck provides real-time syntax checking.

Install flycheck:

M-x package-install RET flycheck RET

Step 7: Install and Configure gopls (Go Language Server)
gopls is the official Go language server, providing IDE features.

Install gopls:

Open terminal tehn,

go install golang.org/x/tools/gopls@latest
Enter fullscreen mode Exit fullscreen mode

Configure Emacs to use gopls:
Add the following to your Emacs configuration file:

(use-package lsp-mode
  :ensure t
  :commands (lsp lsp-deferred)
  :hook ((go-mode . lsp-deferred))
  :config
  (setq lsp-prefer-flymake nil))  ;; Use flycheck instead of flymake

(use-package lsp-ui
  :ensure t
  :commands lsp-ui-mode)

(use-package company-lsp
  :ensure t
  :commands company-lsp)
Enter fullscreen mode Exit fullscreen mode

Step 8: Additional Tools

To further enhance your Go development experience in Emacs, you might want to install additional tools:

magit for Git integration:

M-x package-install RET magit RET

projectile for project management:

M-x package-install RET projectile RET

Example Configuration
Here's an example of a complete Emacs configuration for Go development:

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

;; Install and configure go-mode
(use-package go-mode
  :ensure t
  :hook ((go-mode . lsp-deferred)
         (before-save . gofmt-before-save))
  :config
  (setq tab-width 4)
  (setq indent-tabs-mode 1))

;; Enable company-mode for auto-completion
(use-package company
  :ensure t
  :hook (go-mode . company-mode))

;; Enable flycheck for real-time syntax checking
(use-package flycheck
  :ensure t
  :hook (go-mode . flycheck-mode))

;; Configure lsp-mode and lsp-ui for Go
(use-package lsp-mode
  :ensure t
  :commands (lsp lsp-deferred)
  :config
  (setq lsp-prefer-flymake nil))

(use-package lsp-ui
  :ensure t
  :commands lsp-ui-mode)

(use-package company-lsp
  :ensure t
  :commands company-lsp)

;; Optional: projectile for project management
(use-package projectile
  :ensure t
  :config
  (projectile-mode +1))

;; Optional: magit for git integration
(use-package magit
  :ensure t)
Enter fullscreen mode Exit fullscreen mode

Combined code for all packages:

;; Initialize package sources
(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

;; Ensure use-package is installed
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

;; Install and configure go-mode
(use-package go-mode
  :ensure t
  :hook ((go-mode . lsp-deferred)
         (before-save . gofmt-before-save))
  :config
  (setq tab-width 4)
  (setq indent-tabs-mode 1))

;; Enable company-mode for auto-completion
(use-package company
  :ensure t
  :hook (go-mode . company-mode))

;; Enable flycheck for real-time syntax checking
(use-package flycheck
  :ensure t
  :hook (go-mode . flycheck-mode))

;; Configure lsp-mode and lsp-ui for Go
(use-package lsp-mode
  :ensure t
  :commands (lsp lsp-deferred)
  :config
  (setq lsp-prefer-flymake nil))

(use-package lsp-ui
  :ensure t
  :commands lsp-ui-mode)

(use-package company-lsp
  :ensure t
  :commands company-lsp)

;; Optional: projectile for project management
(use-package projectile
  :ensure t
  :config
  (projectile-mode +1))

;; Optional: magit for git integration
(use-package magit
  :ensure t)

;; Function to run the current Go file
(defun my-go-run ()
  "Run the current Go file."
  (interactive)
  (let ((compile-command (concat "go run " buffer-file-name)))
    (compile compile-command)))

;; Function to build the current Go project
(defun my-go-build ()
  "Build the current Go project."
  (interactive)
  (compile "go build"))

;; Function to test the current Go project
(defun my-go-test ()
  "Test the current Go project."
  (interactive)
  (compile "go test ./..."))

;; Add key bindings for Go commands
(add-hook 'go-mode-hook
          (lambda ()
            (local-set-key (kbd "C-c C-r") 'my-go-run)
            (local-set-key (kbd "C-c C-b") 'my-go-build)
            (local-set-key (kbd "C-c C-t") 'my-go-test)))

;; End of configuration
Enter fullscreen mode Exit fullscreen mode

This setup should give you a powerful and efficient Go development environment in Emacs.

Step 9: Using Emacs for Go Development

Creating a Simple Go Program

Open Emacs

Create a New Go File:

Command:

C-x C-f ~/go/src/hello/hello.go RET
Add Go Code:

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
Enter fullscreen mode Exit fullscreen mode

Save the File:

Command:

C-x C-s

Running the Go Program
You can run your Go program directly from Emacs using the key bindings set up in your configuration.

Run the Current Go File:

Command:
C-c C-r

Build the Current Go Project:

Command:
C-c C-b

Test the Current Go Project:

Command:
C-c C-t

Extra: Clearing an Entire File in Emacs

Clearing File Content

Open File:

Command:
C-x C-f /path/to/yourfile RET

Select All Text:

Command:
C-x h

Delete Selected Text:

Command:
C-w
Save the File:

Command:
C-x C-s

Using erase-buffer Command

Open File

Run erase-buffer:

Command:
M-x erase-buffer RET

Save the File:

Command:
C-x C-s

Split window:

C-x 2 (horizontal split)
C-x 3 (vertical split)

Conclusion
By following this guide, you have set up Emacs on macOS for Go development, including installing necessary packages, configuring Emacs, and using it to write, run, build, and test Go programs. Happy coding!

Top comments (2)

Collapse
 
veer66 profile image
Vee Satayamas

Would you mind explaining the rationale for not using eglot?

Collapse
 
yas8say profile image
Yaseen

i am using lsp-mode , but'll surely try eglot
thanks brother