Emacs Golang 开发环境配置 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
darksword21
0D
V2EX    Emacs

Emacs Golang 开发环境配置

  •  
  •   darksword21
    PRO
    2021-08-16 01:02:27 +08:00 3141 次点击
    这是一个创建于 1531 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原文

    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 自带的括号匹配

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

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     885 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 162ms UTC 21:36 PVG 05:36 LAX 14:36 JFK 17:36
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86