惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
爱范儿
爱范儿
P
Proofpoint News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
Latest news
Latest news
The Hacker News
The Hacker News
Cyberwarzone
Cyberwarzone
博客园 - 【当耐特】
Project Zero
Project Zero
小众软件
小众软件
T
Tailwind CSS Blog
量子位
博客园 - 聂微东
I
Intezer
美团技术团队
S
SegmentFault 最新的问题
T
Tor Project blog
Spread Privacy
Spread Privacy
V
Vulnerabilities – Threatpost
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Jina AI
Jina AI
罗磊的独立博客
B
Blog RSS Feed
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
有赞技术团队
有赞技术团队
Google DeepMind News
Google DeepMind News
宝玉的分享
宝玉的分享
C
Cisco Blogs
L
LINUX DO - 热门话题
Last Week in AI
Last Week in AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AI
AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Azure Blog
Microsoft Azure Blog
L
LINUX DO - 最新话题
Know Your Adversary
Know Your Adversary
GbyAI
GbyAI
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
Lohrmann on Cybersecurity
The Register - Security
The Register - Security
L
LangChain Blog
博客园 - 叶小钗
T
Tenable Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

Emacs

Emacs 内好用漂亮的 YouTube Music 客户端 - V2EX 好用的 Emacs 数据库客户端 给 org-zettel-ref-mode 添加 AI 总结功能 - V2EX Emacs 30 新特性预览 - V2EX 『Made with Emacs』 博客收集 - V2EX 新手向问下,调试程序 - V2EX 求助, org 文件使用 emacs –script 执行 org-publish-all 的时候代码块没有高亮? - V2EX Emacs 在 Windows 下体验如何 - V2EX GPG in Emacs - V2EX Emacs 28 新特性介绍 - V2EX [Emacs Tips] 使用 Dired 快速移动文件 - V2EX spacemacs 如何让当前 buffer 中的内容水平居中? - V2EX 公众号里怎么直接实现 Latex 写出来的科学文章 PDF 之类的效果? - V2EX macOS 10.14.4 状态栏电池百分比选项回归(不好意思 以前一直都有😂) - V2EX emacs 自动安装 package 包 - V2EX emacs 怎么控制光标 - V2EX 怎么知道 emacs 启用了那几个安装包? - V2EX 源更新后不能保存吗? - V2EX 为什么在 Emacs 下打开 Python 文件就是显示 Tab 时 8 个字符 - V2EX Compare Doom-emacs, Spacemacs, and vanilla Emacs - V2EX Emacs 补全头文件的那个 company-c-header 有人用过吗? - V2EX elpy 把 importmagic 给 remove 了😂 - V2EX Emacs 在 window 10 下面运行好慢呀,有没有人和我一样? - V2EX emacs 的 org mode 好强大啊 - V2EX HHKB Pro2 接上 U 盘后电脑提示“USB 集线器没有足够的电源” - V2EX 不谈 Spacemacs,只谈 Centaur Emacs - V2EX 在用 brew 重新安装 Emacs 时遇到的问题,如下图所示。 - V2EX emacs 的 dired 模式有快速切换目录的方案或插件么? - V2EX 用 emacs 的,小指伤不起啊 - V2EX emacs25.1 发布了 - V2EX 用 Emacs 做 PostgreSQL 解释器一事不明 - V2EX 有没有办法在用 Emacs 的时候自动切换成英文输入法? - V2EX melpa down - V2EX v2ex-mode,在 emacs 下访问 V 站 - V2EX 在 emacs 中有没有能直接使用 imap 协议的同时下载邮件到本地或者使用 pop3 但是不删除服务器邮件的邮件客户端? - V2EX GNU Emacs 的新网站 - V2EX Emacs 配合使用 ibus 输入法的一个问题 - V2EX Ubuntu 下使用了 GNU 的 nnimap 设置了邮箱服务器,我想知道的是接收到邮件的默认保存位置在何处,尝试寻找了一下表示根本找不到,在 home 目录下的 Mail 和 News 目录下均未找到 - V2EX 关于 org-mode 8 导出 html 的一个问题 - V2EX 在 emacsclient 中应用中文字体设置 - V2EX emacs 显示出 tab 键 - V2EX Emacs 25.1 即将支持内嵌 webkit 浏览器 - V2EX Emacs 分别设置中英文字体及 org-mode 表格对齐 - V2EX 终于搞定了新帆新闻组 - V2EX 遇到 symbol's value as variable is void - V2EX 将 Emacs 打造成阅读源代码的神器 - V2EX Spacemacs Rocks 视频系列 - V2EX Emacs 自己已经包括了那么多按键组合,新写的函数只能绑定到 C-x 上了吗? - V2EX 在 Mac 上使用 Emacs 的 Prelude 配置,启动报错,求教 - V2EX Emacs 24.5 不兼容任何中文输入法 - V2EX Emacs 注释的时候代码着色有明显卡顿
Emacs Golang 开发环境配置 - V2EX
darksword21 · 2021-08-16 · via Emacs

原文

ps: 请大家不要引发编辑器的战争,我觉得只要用的顺手,可以完成工作,大家可以自己想用什么就用什么,没有绝对的好坏之分。 第一次尝试写东西,如果有哪里有错误欢迎指出,包括病句(不要嘲讽我,rua )

Table of Contents

  1. 开启 Emacs 自带的括号匹配
  2. 安装 straight.el
  3. 设置 major-mode
  4. 代码补全、跳转
  5. 总结

使用 Emacs 开发 Golang 一段时间时间了,今天将相关配置和踩过的坑总结分享出来,本文主要介绍的并不是从零开始的配置,主要都是与 Golang 开发功能相关的配置,默认认为你已经了解如何在 Emacs 查看一些内置的函数文档,绑定快捷键等基本操作,一些基础的 Emacs 功能可以参考梦梦的 Emacs builtin modes 功能介绍

在使用任何 编辑器 /IDE 开发时,最核心的需求无非以下几点:

  • 括号的自动匹配
  • 代码的自动补全
  • 查找定义、引用
  • 静态检查
  • 在项目中模糊查找(文件 /字符串)

Emacs 自带的 electric-pair-mode 已经足够好用,只不过默认没有开启。

(setq electric-pair-inhibit-predicate 'electric-pair-conservative-inhibit)
(add-hook 'prog-mode-hook #'electric-pair-mode)

安装 straight.el

在进行下一步配置之前,我们需要先安装 straight.el ,因为我们要用它来安装其他的第三方包。

(setq straight-check-for-modifications '(check-on-save find-when-checking))
(setq straight-vc-git-default-clone-depth 1)

(setq straight-disable-native-compile
      (when (fboundp 'native-comp-available-p)
    (not (native-comp-available-p))))

(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

straight.el 在安装其他包时需要访问 github,如果你的网络不够 绿色 咳咳…

可以将安装时的 github.com 替换为 github.com.cnpmjs.org

(defun +set-github-mirror (oldfunc &rest args)
  (let ((url (apply oldfunc args)))
    (replace-regexp-in-string (rx (group "github.com"))
                              "github.com.cnpmjs.org" url nil nil 1)))
(advice-add 'straight-vc-git--encode-url :around #'+set-github-mirror)

设置 major-mode

安装 go-mode.el ,其为我们在进行 Golang 开发时提供了相当多的常用功能。

(straight-use-package 'go-mode)

设置缩进。

(setq-default tab-width 4
              indent-tabs-mode nil)

使用 goimports 代替 gofmt 在文件保存后自动格式化我们的代码

(setq gofmt-command "goimports")
(add-hook 'before-save-hook #'gofmt-before-save)

如果你使用的是 MacOS 系统,那么需要使用 exec-path-from-shell 让 Emacs 读取系统的环境变量,不然 Emacs 可能找不到你安装的 go

(when (eq system-type 'darwin)
  (straight-use-package 'exec-path-from-shell)
  (setq exec-path-from-shell-arguments '("-l"))
  (add-hook 'after-init-hook #'exec-path-from-shell-initialize)
  (with-eval-after-load "go-mode"
    (with-eval-after-load "exec-path-from-shell"
      (exec-path-from-shell-copy-envs '("GOPATH" "GO111MODULE" "GOPROXY")))))

go-mode 在格式化代码时如果发现错误会弹出一个 buffer,这会打乱我们的窗口布局,其实我们只需要简单的设置下自带的 flymake-mode 就可以方便的在错误之间跳转而不是通过一个单独的 buffer 查看。

(add-hook 'prog-mode-hook #'flymake-mode)
(with-eval-after-load "flymake"
  (define-key flymake-mode-map (kbd "C-c C-b") 'flymake-show-diagnostics-buffer)
  (define-key flymake-mode-map (kbd "M-n") 'flymake-goto-next-error)
  (define-key flymake-mode-map (kbd "M-p") 'flymake-goto-prev-error))

这样就可以使用 M-nM-p 在错误之间移动,然后把 go-mode 自动弹出的这个 buffer 关掉。

(setq gofmt-show-errors nil)

代码补全、跳转

安装 company-mode ,在补全时可以使用 C-p C-n 或者 TAB 进行选择,回车完成补全。

(straight-use-package 'company)
(add-hook 'prog-mode-hook #'company-mode)
(setq company-tooltip-limit 10
      company-tooltip-align-annotations t
      company-tooltip-width-grow-only t
      company-abort-manual-when-too-short t
      company-require-match nil
      company-backends '(company-capf)
      company-tooltip-margin 0)
(with-eval-after-load "company"
  (define-key company-active-map [tab] 'company-complete-common-or-cycle)
  (define-key company-active-map (kbd "TAB") 'company-complete-common-or-cycle)
  (define-key company-active-map (kbd "C-p") #'company-select-previous)
  (define-key company-active-map (kbd "C-n") #'company-select-next))

安装 eglot ,一个 Emacs 中轻量级的 LSP 客户端,在 go-mode 中启用。

(straight-use-package 'eglot)
(add-hook 'go-mode-hook #'eglot-ensure)
(setq eglot-ignored-server-capabilites '(:documentHighlightProvider)
      read-process-output-max (* 1024 1024))

eglot 使用 Emacs 内置的 project.el 管理项目,以 .git 目录作为项目的根目录,如果你的项目包含一些子项目,例如:

├── .git
├── project1
│   ├── go.mod
│   └── main.go
├── project2
│   ├── go.mod
│   └── main.go
└── project3
    ├── go.mod
    └── main.go

如果你不想让 project1 中的代码出现在 project2 的补全中,或者在 project2 中查找定义时不想要 project1 中的定义出现在你的选择列表中时,则推荐使用 go.mod 所在的目录为项目的根目录,解决不同项目间的代码补全与跳转影响。

(with-eval-after-load "go-mode"
  (with-eval-after-load "project"
    (defun project-find-go-module (dir)
      (when-let ((root (locate-dominating-file dir "go.mod")))
        (cons 'go-module root)))
    (cl-defmethod project-root ((project (head go-module)))
      (cdr project))
    (add-hook 'project-find-functions #'project-find-go-module)))

eglot 默认会使用 eldoc 显示函数等文档,但是很多时候我们不是想立即查看,为了防止文档扰乱视线,给 eldoc 设置个 delay 时间。

(setq eldoc-idle-dealy 2)

如果你想在补全函数时带有占位符,可以对项目进行单独的配置,只需要在项目根目录的 .dir-locals.el 中添加如下代码,eglot 就会在初始化 gopls 之后修改 gopls 的配置,当然这个功能依赖 yasnippet ,所以我们也需要安装它。

(straight-use-package 'yasnippet)
(add-hook 'prog-mode-hook #'yas-minor-mode)

在项目根目录中创建 .dir-locals.el

((go-mode
  . ((eglot-workspace-configuration
      . ((:gopls . (:usePlaceholders t)))))))

当然也可以在你的配置文件中默认开启,这样就不需要对项目单独设置。

(setq-default eglot-workspace-configuration
              '((gopls
                 (usePlaceholders . t))))

另一个非常有用的 tip 是如果你的项目使用了 Build Constraints ,也可以针对项目单独修改 gopls 的配置使代码的补全与跳转完美的工作。

((go-mode
  . ((eglot-workspace-configuration
      . ((:gopls . (:buildFlags ["-tags=debug"])))))))

这里就不写出全局开启的示例了,而且这个功能一般不需要全局开启。

总结

Emacs 内置的 electric-pair-mode 帮我们实现了括号匹配,project.el 可以在项目中查找文件、字符串等( project-find-file project-search project-switch-to-buffer )。

在安装了 eglot 、company-mode 后实现了代码的补全、跳转等功能( xref-find-definitions xref-find-references ),同时 eglot 配合内置的 flymake 也为我们提供了静态检查。

当然这些插件的功能远不只这些,例如 eglot 可以帮你重命名函数或变量(同时修改其引用处的名字),company-mode 不仅可以补全代码也可以补全文件路径、代码片段,在编写 Golang 时需要用到的一些工具链是不是也可以通过 elisp 管理从而达到一个命令进行安装 /更新等。

在 Emacs 中能限制你的只有你的想象力与行动力,种种强大或实用的功能不可能在一篇文章中全部介绍,剩下的就需要你自己发现或者根据自身特定需求进行扩展了。