golang 官方的包管理從 1.11 版本就開始支持了, 以前嘗試了幾回, 效果都不理想, 就一直用 dep 來管理 package.git
最近 1.13 版本發佈了, 使用 go module 的官方管理方式愈來愈多, dep 也早就不在繼續開發了. 鑑於此, 是時候把 golang 的包管理方式遷移到 go module 上來了.github
我一直是用 spacemacs 來開發各類應用, 因此本文也是介紹如何在 spacemacs 中配置 golang module 的開發環境.golang
go module 其實自己是不須要什麼配置, 這裏的配置其實爲了更方便的編碼而作的 spacemacs 配置. 可以讓它支持自動補全, 代碼調轉等等開發時經常使用的操做.docker
使用 go module, golang 的工程不用在放在 GOPATH 下, 全部傳統的 gocode 不能再用來作代碼補全這些了. 咱們這裏採用 gopls 來代替 gocode.frontend
出來 golang 1.13, 額外須要的軟件就是 goplside
安裝好 golang 1.13, 安裝 gopls 很是簡單:函數
$ GO111MODULE=on go get golang.org/x/tools/gopls@latest
spacemacs 的 develop 分支默認繼承了 lsp 的功能. LSP 是什麼 因此配置起來很簡單, 在 dotspacemacs-configuration-layers 下配置:ui
dotspacemacs-configuration-layers '( ... ... lsp ;; ---------------------------------------------------------------- ;; Example of useful layers you may want to use right away. ;; Uncomment some layer names and press `SPC f e R' (Vim style) or ;; `M-m f e R' (Emacs style) to install them. ;; ---------------------------------------------------------------- (go :variables go-backend 'lsp go-tab-width 8 godoc-at-point-function 'godoc-gogetdoc) ... ... )
lsp-mode 是 emacs 對 lsp 的封裝, 參考其中 golang 的部分, 在 dotspacemacs/user-config 中配置:this
;; lsp (use-package lsp-mode :hook (go-mode . lsp-deferred) :commands (lsp lsp-deferred)) (setq lsp-auto-guess-root nil) (setq lsp-ui-doc-enable nil) (setq lsp-ui-sideline-enable nil) (setq lsp-prefer-flymake :none)
使用 go module 以後, golang 項目的目錄不必定在 GOPATH 下, 因此定義了個配置 project root 的函數. 固然, 若是不設置, 默認值是 emacs 的 projectile-project-root編碼
;; project path settings (setq current-project-path (projectile-project-root)) (defun set-project-path (relative-path) (interactive (list (read-string "relative path: " "." nil nil nil))) (setq current-project-path (file-truename relative-path))) (defun get-project-path () (interactive) (message current-project-path))
增長 2 個快捷鍵, 用來執行 go build 和 go install
;; go build/install (setq default-go-package "") (defun go-build (&optional pkg) (interactive (list (read-string (format "Package Name[%s]: " default-go-package) nil nil ""))) (if (not (string= pkg "")) (setq default-go-package pkg)) (if (string= current-project-path "") (message "You MUST set current-project-path FIRST!") (projectile-with-default-dir current-project-path (projectile-run-compilation (concat "go build " default-go-package)))) ) (defun go-install (&optional pkg) (interactive (list (read-string (format "Package Name[%s]: " default-go-package) nil nil ""))) (if (not (string= pkg "")) (setq default-go-package pkg)) (if (string= current-project-path "") (message "You MUST set current-project-path FIRST!") (projectile-with-default-dir current-project-path (projectile-run-compilation (concat "go install " default-go-package)))) ) ;; set shortcuts (spacemacs/set-leader-keys-for-major-mode 'go-mode "xi" 'go-install) (spacemacs/set-leader-keys-for-major-mode 'go-mode "xb" 'go-build)
go build 和 go install 的快捷鍵分別是: SPC m x b 和 SPC m x i
在嘗試使用的過程當中, 遇到 2 個坑, 耗費了大半天的時間… :(
在 spacemacs 的 Message buffer 中, 提示 LSP : main.go not in project or it is blacklisted 幾近波折, 才發現不知道何時, 當前的項目被加入到 blacklist 中了…
解決方法:
若是項目自己就是 golang 工程的話, 通常不會出現這個問題, 我有個項目, golang 工程是其中的一部分, 工程結構大體以下:
. ├── backend │ └── this-is-golang-project-root ├── deploy │ ├── builder │ └── docker-compose.yml ├── frontend │ └── ui └── README.md
golang 工程不在項目的根目錄, 使用時在 spacemacs 的 Message buffer 中, 提示: no AST for file:///..../foo.go
解決方式: