go-mode 默认不自动格式化,需手动添加 go-format-before-save 到 before-save-hook;GOPATH 和 GO111MODULE 必须在 init.el 中显式设置;补全应改用 lsp-mode + gopls;dlv 调试前需确保环境变量、工作目录和构建路径一致。

go-mode 插件装了但 go fmt 不自动运行?检查 before-save-hook 是否生效
很多人装完 go-mode 后发现保存文件时没格式化,不是插件坏了,而是默认不开启自动格式化。Go 官方推荐用 gofmt 或 goimports,但 go-mode 默认只提供语法高亮和基础导航,不绑定保存动作。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 确认已启用
go-format-before-save:在配置里加(add-hook 'before-save-hook 'go-format-before-save) - 如果用
goimports替代gofmt,得先go install golang.org/x/tools/cmd/goimports@latest,再设置(setq gofmt-command "goimports") - 注意 Emacs 版本差异:27+ 默认启用
electric-indent-mode,可能和go-mode的缩进逻辑冲突,可临时关掉测试:(electric-indent-local-mode -1)
import 提示 “not found” 或跳转失败?go-mode 没读对 GOPATH 和 GO111MODULE
Emacs 里的 go-mode 依赖 shell 环境启动时的 Go 配置,不是读你终端里 source ~/.zshrc 后的环境,尤其在 macOS GUI 启动 Emacs(比如从 Dock 点开)时,$PATH、GOPATH、GOROOT 全是空的。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 在
.emacs.d/init.el里显式设置:(setenv "GOPATH" "/Users/you/go"),并确保(setenv "PATH" (concat "/Users/you/go/bin:" (getenv "PATH"))) - 模块项目必须设
GO111MODULE=on,否则go-mode查 import 会退回到 GOPATH 模式,找不到github.com/xxx下的包 - 验证方式:在 Emacs 中执行
M-: (getenv "GOPATH"),看输出是否和终端里一致
补全卡顿或根本不出提示?别用 go-autocomplete,改用 lsp-mode + gopls
go-autocomplete 基于 gocode,早已被官方弃用;它无法处理 module、泛型、嵌入接口等现代 Go 特性,且在大项目里响应慢甚至崩溃。现在标准做法是 lsp-mode 配 gopls —— Go 官方维护的语言服务器。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 先装
gopls:go install golang.org/x/tools/gopls@latest - 在 init.el 加载顺序很重要:先
(require 'lsp-mode),再(add-hook 'go-mode-hook 'lsp-deferred) - 避免和旧插件冲突:禁用
go-autocomplete、go-guru、go-refactor等,它们和gopls抢端口或覆盖命令 - 首次打开项目会触发缓存构建,等几秒再试补全;如果一直卡住,检查
gopls日志:M-x lsp-describe-session
调试时 delve 启动失败或断点无效?路径、工作目录、dlv 版本三者必须对齐
Emacs 调试 Go 通常靠 realgud 或 lsp-mode 内置的 dlv 支持,但常见报错如 "could not launch process: fork/exec /path/to/main: no such file or directory",根本原因不是 dlv 没装,而是 Emacs 当前 buffer 对应的编译路径、dlv 工作目录、以及 go build 输出路径不一致。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 确保
dlv是最新版:go install github.com/go-delve/delve/cmd/dlv@latest,旧版不支持 Go 1.21+ 的 embed 和泛型 - 调试前用
C-c C-f(go-build)手动构建一次,保证当前目录下有可执行文件;不要依赖dlv debug自动 build,它容易忽略-ldflags等参数 - Emacs 启动
dlv时默认用 buffer 所在目录为工作目录,如果项目含go.work或多 module,需先M-x cd切到对应 module 根目录再调试
最常被忽略的是:Emacs GUI 启动时拿不到 shell 的完整环境变量,哪怕你 .zshrc 里写了一百遍 export GOPATH,它也看不见。这不是配置写得不够多,是加载时机问题 —— 必须在 Emacs 配置里显式 setenv,不能指望它自动继承。










