Nothing Special   »   [go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a hook to detect LSP project root #2241

Merged
merged 2 commits into from
Jan 26, 2019

Conversation

bk2204
Copy link
Contributor
@bk2204 bk2204 commented Jan 24, 2019

Currently, we detect the linter root based on a variety of techniques. However, these techniques are not foolproof. For example, clangd works fine for many things without a compile_commands.json file, and Go projects may be built outside of the GOPATH to take advantage of Go 1.11's automatic module support.

Add a variable for the user to customize which points to a hook that detects the project root if the linter-specific configuration fails. Note that we allow only strings, since Vim requires that funcrefs are stored in variables that begin with an uppercase letter, and ALE's variables do not.

I fully expect discussion and revision of this PR, so comments are welcome.

Copy link
Member
@w0rp w0rp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what would be better would be support for a dictionary for project paths, and then any dynamic logic for that can be written into either ftplugin files or vimrc. For example...

" Just setting a string for a specific linter.
let b:ale_lsp_root = {'pyls': '/home/johndoe/project'}

" Maybe support this alternative format too, used for all linters run for this buffer.
let b:ale_lsp_root = '/home/johndoe/project'

" You can also use whatever logic you want, as you're writing VimL.
let b:ale_lsp_root = {'pyls': MyProjectDetectionFunction()}

g:ale_lsp_root would also work, but I'd encourage the use of the buffer-specific variables in ftplugin files over that.

One advantage with this design is that you'd also be able to define project paths from inside of sandboxed scripts too, including something like a plugin which runs a local .vim file for a project with :sandbox. (Though very recent versions of Vim do now let you define functions in the sandbox which are also sandboxed now.)

I think the general idea here is very good. I've been considering doing something similar myself.

@w0rp
Copy link
Member
w0rp commented Jan 24, 2019

Another advantage is that later on when #2132 is done, we could support functions as values if we wanted to, which could themselves execute asynchronous code. I wouldn't worry about that right away.

@w0rp
Copy link
Member
w0rp commented Jan 24, 2019

I also recommend making it so the user's specified project path is always preferred over whatever ALE is trying to figure out. That way you can override what ALE is trying to do by default, including skipping any potentially complex processing ALE might be doing, when you already know what the path should be.

@bk2204
Copy link
Contributor Author
bk2204 commented Jan 24, 2019

Part of my goal here is to allow for global settings, such as always picking the top level of the Git repo as the project root. While there are merits to the design you've proposed, I think it lacks the ability to handle that case without specifically enumerating every possible LSP tool to use, which I would like to avoid.

Do you have any suggestions about a design that incorporates both the flexibility of your proposal with the ability to honor global settings of my original design? Would a default key be sufficient here in the dictionary, along with reading both b:ale_lsp_root and g:ale_lsp_root?

I'm fine with overriding the autodetection here, and I was considering that behavior myself.

@w0rp
Copy link
Member
w0rp commented Jan 25, 2019

Have a look at the existing code for variables like g:ale_linters and b:ale_linters. These new variables would work in the same way. We would try to get the project path with the following methods, in order of precedence.

  1. Try to use b:ale_lsp_root as a string.
  2. Try to get a project path from b:ale_lsp_root as a Dictionary.
  3. Try to get a project path from g:ale_lsp_root as a Dictionary.
  4. Automatically determine the project path from the linter's function.

@w0rp
Copy link
Member
w0rp commented Jan 25, 2019

Note that you can set a path for all LSP servers across all filetypes by setting b:ale_lsp_root as a String in all buffers.

All linters should have a name variable set in their dictionary, and
code should be able to rely on that. Fix this test such that its example
linter contains a name entry.
Currently, we detect the linter root based on a variety of techniques.
However, these techniques are not foolproof. For example, clangd works
fine for many things without a compile_commands.json file, and Go
projects may be built outside of the GOPATH to take advantage of Go
1.11's automatic module support.

Add global and buffer-specific variables to allow the user to specify
the root, either as a string or a funcref. Make the funcrefs accept the
buffer number as an argument to make sure that they can function easily
in an asynchronous environment.

We define the global variable in the main plugin, since the LSP linter
code is not loaded unless required, and we want the variable to be able
to be read correctly by :ALEInfo regardless.
@bk2204
Copy link
Contributor Author
bk2204 commented Jan 26, 2019

Okay, I've updated the series to fit with that design. I additionally fixed a test that was missing a name entry in its linter dictionary, since we now rely on the fact that all linters have such an entry.

@w0rp
Copy link
Member
w0rp commented Jan 26, 2019

This is a very nice addition. Nice work!

Cheers! 🍻

@w0rp w0rp merged commit 452460b into dense-analysis:master Jan 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants