golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.74k stars 17.5k forks source link

x/tools/gopls: update editor instructions for go.work #50955

Open findleyr opened 2 years ago

findleyr commented 2 years ago

Some language-agnostic LSP clients need to be configured with root patterns (e.g. open the workspace to the folder containing go.mod).

We should update those to account for using go.work as the workspace root.

EDIT: the main things to look for are:

  1. LSP clients should choose the workspace root correctly. Ideally, they should set the workspace root to the first parent directory (or current directory) containing a go.work file (i.e. find nearest go.work file up the directory hierarchy). If no such directory exists, they should repeat with go.mod. Unfortunately, not all LSP clients support this multi-phase search, so an alternate heuristic is to take the farthest directory up the directory hierarchy that contains either a go.work file or go.mod file.
/A/go.work <- acceptable workspace folder
/A/B/go.mod <- avoid
/A/B/C/go.work  <- ideal workspace folder 
/A/B/C/D/go.mod <- avoid
/A/B/C/D/E <- opened directory
  1. If possible, LSP clients should activate gopls for go.work files and send the "go.work" language identifier. This is much less critical than (1) -- clients could also do this for go.mod files and AFAIK none of them do, except VS Code.
gopherbot commented 2 years ago

Change https://golang.org/cl/382242 mentions this issue: gopls: update coc.nvim documentation for using go.work

findleyr commented 2 years ago

gopls now supports go.work files at master. @muirdm or @bcmills, would you be able to update our emacs documentation at some point in the next few weeks? No worries if not -- I can figure it out -- but I know you have contributed to that documentation before.

See the edit in the top comment and the associated CL for coc.nvim for more information.

findleyr commented 2 years ago

@myitcv and @leitzler I believe govim should implement these heuristics for its users. Would you be able to verify its functionality with go.work files?

findleyr commented 2 years ago

@dr2chase do you know if sublime has heuristics for deriving the workspace folder? If so, could you help update the sublime documentation?

dr2chase commented 2 years ago

I have not yet learned about Go workspaces, so I am a bit in the dark here. Seems like I should look at this.

bcmills commented 2 years ago

I haven't updated my own .emacs for workspace mode yet, but when I do I'll send a CL.

(I suspect that it will involve another parallel implementation of the project hook, but I expect to need a little bit of work to get it to prioritize the go.work project root over the go.mod one when both are present.)

gopherbot commented 2 years ago

Change https://go.dev/cl/388576 mentions this issue: gopls: update neovim documentation for using go.work

dr2chase commented 2 years ago

Follow-up -- for the case of the Go source tree, with go.work =

go 1.18

use (
    .
    cmd
)

and Sublime/LSP tweaked to use gopls@latest (and the sublime editor instructions for gopls include that) it all seems to "just work". Is that what we want, or were we looking for something more?

findleyr commented 2 years ago

@dr2chase "Just works" is good enough for me! Thanks for trying it out.

findleyr commented 2 years ago

Some (but not all) editor instructions have been updated. Moving this to the next milestone.

jguenther commented 2 years ago

FWIW, using emacs+gopls with projectile and lsp-mode this Just Worked™️ for me after cleaning up my lsp-mode workspace folders with lsp-workspace-folders-remove so that the only entry in my workspace folders was the $BASE dir containing the root module and the new go.work file (details below)

(prior to this, I was using vendored deps so I couldn't use the experimentalWorkspaceModule feature (#50214))


Project structure

Modules

# previously each of these module dirs were added to my workspace folders (lsp-workspace-folders-add)
go.mod
path/to/other/module/go.mod
another/one/go.mod

Setting up workspaces with go work

  1. upgrade go to 1.18
  2. reinstall gopls using go 1.18
  3. cd $BASE
  4. go work init
  5. go work use ./path/to/other/module ./another/one .

Setting up lsp-mode to use workspaces

  1. lsp-workspace-folders-remove, select $BASE/path/to/other/module
  2. lsp-workspace-folders-remove, select $BASE/another/one

Now, the only dir in lsp-mode workspace folders for this project is $BASE.

Restart gopls

  1. lsp-workspace-restart

At this point everything Just Worked™️. I can navigate refs between these modules, jump to definition goes to the file in the source module instead of the file vendored in my vendor dir, etc.

NOTE I'm not sure if eglot or the builtin project.el package would require any other setup as I don't use them.


cc @findleyr @bcmills

findleyr commented 2 years ago

@jguenther thanks for that, we can include this in our editor instructions. Do you know if using projectile is strictly required for this to work?

CC @adonovan (another eglot user)

findleyr commented 2 years ago

Keeping this open to track additional documentation for other editors, but it is a lower priority now.