mason.nvim
mason.nvim copied to clipboard
Detect preinstalled packages in environment
I've searched open issues for similar requests
Yes
Is your feature request related to a problem? Please describe.
It seems that preinstalled packages are not recognized by Mason.
For example, I am using conda
to manage my virtual environments, and Mason's pylint
does not recognized the installed package. I found a solution by installing pylint
in my own virtual environment and change Mason's config PATH
to append
instead of prepend
. However, I noticed that in this case, if I remove Mason's pylint
but keep the one in conda
, Mason does not recognize the latter.
Describe the solution you'd like
It would be quite convenient to have Mason auto detect the preinstalled package, so that extensions such as mason-null-ls
knows not to reinstall them.
Describe potential alternatives you've considered
No response
Additional context
No response
Hello!
[...] and Mason's pylint does not recognized the installed package.
However, I noticed that in this case, if I remove Mason's pylint but keep the one in conda, Mason does not recognize the latter.
I'm not sure I'm following this part. What do you mean by "recognize" here?
It would be quite convenient to have Mason auto detect the preinstalled package, so that extensions such as mason-null-ls knows not to reinstall them.
This sounds more like a feature request to mason-null-ls, as Mason itself doesn't auto-install packages (yet).
Hi! For example, I have an environment with mypy
installed
$ conda list | grep mypy
mypy 0.981 py310h06a4308_0
mypy_extensions 0.4.3 py310h06a4308_0
but in the :Mason
dialogue, it does not recognize this as installed.
✗ mypy
I just think that it would be more convenient to be able to detect this, perhaps by checking that the binary exists in PATH
.
This is my temporary solution, this is more related to null-ls.nvim
than to mason.nvim
:
require("null-ls").setup({
sources = {
null_ls.builtins.diagnostics.pylint.with({
-- command has to be the path of the pylint executable you installed in the virtual environment
command = vim.fn.system({ "which", "pylint" }):gsub("[\n]", ""),
}),
},
})
I had to remove pylint
from mason.nvim
because the command which pylint
would return that first, second it returns the pylint path from the virtual environment and last it returns the pylint path installed globally, now pylint
won't give me warnings like "unable to import".
I am using linux and venv for the virtual environment.
but in the
:Mason
dialogue, it does not recognize this as installed.✗ mypy
I just think that it would be more convenient to be able to detect this, perhaps by checking that the binary exists in
PATH
.
Ah now I understand. So yeah Mason won't detect installations outside of Mason. It's also something it will never do, for various reasons. However, detecting existing installations of a package and present these in the :Mason
UI might be an interesting feature, if it helps people. Perhaps something like this:

Although to be honest, this would be pretty far down the backlog (and currently not entirely feasible).
I had to remove
pylint
frommason.nvim
because the commandwhich pylint
would return that first, second it returns the pylint path from the virtual environment and last it returns the pylint path installed globally, nowpylint
won't give me warnings like "unable to import".
You can change the PATH
setting of mason to be append:
require("mason").setup {
PATH = "append"
}
This will put executables installed by Mason last in PATH, giving precedence to your "normal PATH".
By the way you should not have to shell out to locate the executable via which pylint
. libuv (which null-ls uses for spawning commands) traverses PATH to find the command, yielding the exact same result.
Ah now I understand. So yeah Mason won't detect installations outside of Mason. It's also something it will never do, for various reasons. However, detecting existing installations of a package and present these in the
:Mason
UI might be an interesting feature, if it helps people. Perhaps something like this:![]()
Although to be honest, this would be pretty far down the backlog (and currently not entirely feasible).
Yes, indeed, that is what I meant. Being able to detect installations outside of Mason would be quite useful, especially for linting tools like mypy
or pylint
, which often need to be installed inside the working environment. Giving the path to that installation could also be useful in debugging the lsp.
I could try and have a look into implementing the feature then send a PR, if you find the feature suitable.
I could try and have a look into implementing the feature then send a PR, if you find the feature suitable.
I'm afraid this would be pretty difficult to achieve currently. It's practically impossible to programmatically introspect which executables a package is associated with as this information is not stored in an accessible way atm. Take rust-analyzer for example - you'd have to actually execute the installation to know which executable it ends up linking without keeping a manual record somewhere else (not an option). The same applies to all packages, although some would make this possible with little intervention (npm-based ones for example).
I am working on transforming package definitions to a serializable format (yaml), this format will in turn expose associated executables which would enable a feature like this.
Ah I see. We could implement it later once that is done then
Hi there!
I really consider this a must-have feature in the future, because lack of it makes Mason undesirable for me, unfortunately.
For example, installing clang
package on Arch Linux provides you with:
-
clang
- C++ compiler -
clangd
- C++ LSP server -
clang-tidy
- C++ linter -
clang-format
- C++ formatter
Of course, when I'm working on C++ files, I want clangd
LSP server to be installed.
At the moment, if I set
require("mason-lspconfig").setup({ ensure_installed = { "clangd" } })
it will download and install another copy in Mason's directory. This is very undesirable for following reasons:
- Unnecessary copies of the same thing on the system.
- Versions of
clangd
might actually not be the same and it may behave differently if ran from nvim vs system. (Adjusting global PATH to get consistent behavior also seems unsafe and error-prone)
If I exclude it with
require("mason-lspconfig").setup({ automatic_installation = { exclude = { "clangd" } } })
then Mason will never install it, neither on my current system (where I have it installed through system package), nor on another system where I might not have it, thus it defeats the purpose of me using Mason altogether.
Proposed Issue title rename (I find current one less intuitive)
Make Mason aware of packages installed on the system
Describe the solution you'd like
To tell which executable is installed and will be used, Mason needs to know two things:
- Map of all of packages that Mason offers with the executables that they bring when installed.
- Full
PATH
value in order to check for system installed executables.
After user sets up the Mason configuration, i.e. install_root_dir
and PATH
options, full PATH
variable can be computed.
With that, :Mason
can report all executables by calling/simulating which -a [executable]
in the order in which they are found.
At first glance, this will immediately tell the user:
- If there are multiple versions of the executable installed on the system
- Which executable is being used, one from the system or Mason
This general Mason behavior should also extend to its ecosystem. For example:
-
should either (further discussion on this might be needed):require("mason-lspconfig").setup({ ensure_installed = { "clangd" } })
- Not install anything if:
-
PATH
== "append" AND -
clangd
is installed on the system
-
- Install
clangd
for Mason, if:- No
clangd
executable was found OR-
PATH
== "prepend" AND - There is no Mason's installation of
clangd
-
- No
- Not install anything if:
-
should also include LSP servers installed on the system, not just by Mason.require("mason-lspconfig").get_installed_servers() -- or some new function
This is my temporary solution, this is more related to
null-ls.nvim
than tomason.nvim
:require("null-ls").setup({ sources = { null_ls.builtins.diagnostics.pylint.with({ -- command has to be the path of the pylint executable you installed in the virtual environment command = vim.fn.system({ "which", "pylint" }):gsub("[\n]", ""), }), }, })
I had to remove
pylint
frommason.nvim
because the commandwhich pylint
would return that first, second it returns the pylint path from the virtual environment and last it returns the pylint path installed globally, nowpylint
won't give me warnings like "unable to import".I am using linux and venv for the virtual environment.
even that is not working
I had to remove
pylint
frommason.nvim
because the commandwhich pylint
would return that first, second it returns the pylint path from the virtual environment and last it returns the pylint path installed globally, nowpylint
won't give me warnings like "unable to import".You can change the
PATH
setting of mason to be append:require("mason").setup { PATH = "append" }
This will put executables installed by Mason last in PATH, giving precedence to your "normal PATH".
By the way you should not have to shell out to locate the executable via
which pylint
. libuv (which null-ls uses for spawning commands) traverses PATH to find the command, yielding the exact same result.
even that is not doing any thing so u cant use pylint its always giving import error
You need to be more specific on how it doesn't work for you. These are workarounds that are not optimal, but at least it seems to work for the previous people. So perhaps a more detailed description than "even that did not work" would be helpful to see what went wrong.
My suggestion to troubleshoot is to open a shell inside neovim, then run which -a pylint
to detect which installation of pylint
is visible and is used by null-ls (the first output). If you do not see the installation, then it's some problem with your PATH
(for virtual environments, you need to install pylint
yourself inside those environments to be able to detect the packages). The PATH = append
only makes installations by Mason not preceed the pre-installed ones.
You need to be more specific on how it doesn't work for you. These are workarounds that are not optimal, but at least it seems to work for the previous people. So perhaps a more detailed description than "even that did not work" would be helpful to see what went wrong.
My suggestion to troubleshoot is to open a shell inside neovim, then run
which -a pylint
to detect which installation ofpylint
is visible and is used by null-ls (the first output). If you do not see the installation, then it's some problem with yourPATH
(for virtual environments, you need to installpylint
yourself inside those environments to be able to detect the packages). ThePATH = append
only makes installations by Mason not preceed the pre-installed ones. thanks for support path is working well its like as follows Γ¥» which -a pylint /home/amit/py_test/.venv/bin/pylint /home/amit/.local/bin/pylint /home/amit/.local/share/nvim/mason/bin/pylint /home/amit/py_test/.venv/bin/pylint /home/amit/.local/bin/pylint /home/amit/.local/bin/pylint /home/amit/anaconda3/bin/pylint but its not working i dont what is going wrong
So "managing" or in any way integrating externally installed packages is out of scope for mason.nvim. If you don't want to install a package if it's already installed on your system you can for example utilize vim.fn.executable()
in order to conditionally populate the ensure_installed
or automatic_installation = { exclude = {} }
lists.
So "managing" or in any way integrating externally installed packages is out of scope for mason.nvim. If you don't want to install a package if it's already installed on your system you can for example utilize
vim.fn.executable()
in order to conditionally populate theensure_installed
orautomatic_installation = { exclude = {} }
lists.
thanks very thing working fine except import error highlighted by plyint as its unable to find site packages , beside this when ever i use path option pylint doesnt work at all ( all three option )