null-ls.nvim
null-ls.nvim copied to clipboard
Null-ls prefer_local and only_local are not resolving prettier executable
FAQ
- [X] I have checked the FAQ and it didn't resolve my problem.
Issues
- [X] I have checked existing issues and there are no issues with the same problem.
Neovim Version
v0.8.0
Dev Version?
- [X] I am using a stable Neovim release version, or if I am using a dev version of Neovim I have confirmed that my issue is reproducible on a stable version.
Operating System
macOS 12.5.1
Minimal Config
-- this template is borrowed from nvim-lspconfig
local on_windows = vim.loop.os_uname().version:match "Windows"
local function join_paths(...)
local path_sep = on_windows and "\\" or "/"
local result = table.concat({ ... }, path_sep)
return result
end
vim.g.loaded_remote_plugins = ""
vim.cmd [[set runtimepath=$VIMRUNTIME]]
local temp_dir = vim.loop.os_getenv "TEMP" or "/tmp"
vim.cmd("set packpath=" .. join_paths(temp_dir, "nvim", "site"))
local package_root = join_paths(temp_dir, "nvim", "site", "pack")
local install_path = join_paths(package_root, "packer", "start", "packer.nvim")
local compile_path = join_paths(install_path, "plugin", "packer_compiled.lua")
local null_ls_config = function()
local null_ls = require "null-ls"
local formatting = null_ls.builtins.formatting
-- add only what you need to reproduce your issue
null_ls.setup {
sources = {
formatting.prettier.with {
only_local = "node_modules/.bin",
},
},
debug = true,
}
end
local function load_plugins()
-- only add other plugins if they are necessary to reproduce the issue
require("packer").startup {
{
"wbthomason/packer.nvim",
{
"jose-elias-alvarez/null-ls.nvim",
requires = { "nvim-lua/plenary.nvim" },
config = null_ls_config,
},
},
config = {
package_root = package_root,
compile_path = compile_path,
profile = {
enable = true,
threshold = 0, -- the amount in ms that a plugins load time must be over for it to be included in the profile
},
},
}
end
if vim.fn.isdirectory(install_path) == 0 then
vim.fn.system { "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path }
load_plugins()
require("packer").sync()
else
load_plugins()
require("packer").sync()
end
Steps to Reproduce
- open project with
nvim --clean -u minimal_init.lua - open ts file
- run command
lua vim.lsp.buf.format({ async = true })
Reproducibility Check
- [X] I confirm that my minimal config is based on the
minimal_init.luatemplate and that my issue is reproducible by runningnvim --clean -u minimal_init.luaand following the steps above.
Expected Behavior
Format the document with prettier from node_modules
Actual Behavior
no format at all
Debug Log
[TRACE Fri Oct 7 13:16:54 2022] ...te/pack/packer/start/null-ls.nvim/lua/null-ls/client.lua:110: starting null-ls client
[TRACE Fri Oct 7 13:16:54 2022] .../site/pack/packer/start/null-ls.nvim/lua/null-ls/rpc.lua:123: received LSP request for method initialize
[TRACE Fri Oct 7 13:16:54 2022] .../site/pack/packer/start/null-ls.nvim/lua/null-ls/rpc.lua:148: received LSP notification for method initialized
[TRACE Fri Oct 7 13:16:54 2022] .../site/pack/packer/start/null-ls.nvim/lua/null-ls/rpc.lua:148: received LSP notification for method textDocument/didOpen
[TRACE Fri Oct 7 13:16:54 2022] ...ack/packer/start/null-ls.nvim/lua/null-ls/generators.lua:21: running generators for method NULL_LS_DIAGNOSTICS_ON_OPEN
[DEBUG Fri Oct 7 13:16:54 2022] ...ack/packer/start/null-ls.nvim/lua/null-ls/generators.lua:24: no generators available
[TRACE Fri Oct 7 13:17:13 2022] .../site/pack/packer/start/null-ls.nvim/lua/null-ls/rpc.lua:123: received LSP request for method textDocument/formatting
[TRACE Fri Oct 7 13:17:13 2022] ...ack/packer/start/null-ls.nvim/lua/null-ls/generators.lua:21: running generators for method NULL_LS_FORMATTING
[DEBUG Fri Oct 7 13:17:13 2022] ...t/null-ls.nvim/lua/null-ls/helpers/generator_factory.lua:284: unable to resolve command prettier; aborting
[TRACE Fri Oct 7 13:17:40 2022] .../site/pack/packer/start/null-ls.nvim/lua/null-ls/rpc.lua:123: received LSP request for method shutdown
[TRACE Fri Oct 7 13:17:40 2022] .../site/pack/packer/start/null-ls.nvim/lua/null-ls/rpc.lua:148: received LSP notification for method exit
Help
Maybe
Implementation Help
Requirements
- [x] I have read and followed the instructions above and understand that my issue will be closed if I did not provide the required information.
What is your project structure like? Are you able to run ./node_modules/.bin/prettier from the command line without issues?
@jose-elias-alvarez the project structure is a regular monorepo with prettier installed at the root project, I can run the command from ./node_modules/.bin/prettier, the structure is quite big but it was working before.
after more testing, this is happening when I open a project with nvim command, but when I open with nvim . it is working as expected.
Also, it seems to be happening as described above only in one of my monorepos, this is the structure:
.
├── Dockerfile
├── Jenkinsfile
├── Makefile
├── README.md
├── descriptor.yml
├── graphql.config.json
├── lerna-debug.log
├── lerna.json
├── nx.json
├── package.json
├── packages
│ ├── package-one
│ ├── package-two
│ ├── package-three
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── tsconfig.json
├── turbo.json
└── yarn.lock
It sounds like this may be an issue with root directory resolution. Does :lua print(require("null-ls.client").get_client().config.root_dir) show what you expect? If not you may need to change your config.
I run into the exact same behavior using eslint in a pnpm monorepo.
I think the problem is that pnpm doesn't hoist out but only symlinks to dependencies (https://pnpm.io/motivation) and null-ls thus not being able to resolve them.
:lua print(require("null-ls.client").get_client().config.root_dir) returned the expected working directory for me
I run into the exact same behavior using eslint in a pnpm monorepo. I think the problem is that pnpm doesn't hoist out but only symlinks to dependencies (https://pnpm.io/motivation) and null-ls thus not being able to resolve them.
I am currently using null-ls in a pnpm project and have no issues, since (at least with this project's setup) the executables are shell script wrappers. This may be different for other versions, but I have no way of verifying that.
If anyone having this issue could put together a minimal sample project that I can use to reproduce the issue, I can investigate. Otherwise, there are too many factors involved in real-world projects to isolate this.
I had the same issue, in my case it was because one of the directories contained a Makefile:
root_dir = u.root_pattern(".null-ls-root", "Makefile", ".git"),
IMO this shouldn't be used as a heuristic, as nested Makefiles are fairly common - even if some would argue it isn't proper.
To fix it in your config you can change the root_dir property, as suggested above:
null_ls.setup({
root_dir = require("null-ls.utils").root_pattern(".git", "package.json"),
...
})
IMO this shouldn't be used as a heuristic, as nested Makefiles are fairly common - even if some would argue it isn't proper.
I agree - if the practice is common enough that there are articles describing why it's wrong, then I don't think it's a good idea to rely on it. It would be a breaking change, but if multiple users are running into the issue, then I think it makes sense. Happy to review a quick PR if I haven't yet gotten around to it.
I'm not sure if this is the exact issue that I am having (seems similar) but I am experiencing an issue with use_local and prefer_local finding the executable in the wrong location.
.
├── vendor
│ └── bin
│ └── phpcs
├── phpcs.xml
└── web
└── app
└── themes
└── my-wp-theme
├── app
│ └── my-file.php
├── phpcs.xml
└── vendor
└── bin
└── phpcs
I am editing my-file.php yet null-ls is using the root vendor/bin/phpcs even though my config has prefer_local = './vendor/bin. This causes the wrong config file phpcs.xml to be used (phpcs uses the file relative to where it is executed).
Bit out of my depth here but does null-ls use npx or npm to execute Prettier 'under the hood'? I only ask as I have noticed with an exact version of Prettier in my package.json (2.5.0) from that project root, prettier -v gives me 2.7.0 whereas npx prettier -v returns the correct 2.5.0.
Could this have any bearing or is this likely unrelated?
Bit out of my depth here but does null-ls use npx or npm to execute Prettier 'under the hood'? I only ask as I have noticed with an exact version of Prettier in my package.json (2.5.0) from that project root,
prettier -vgives me2.7.0whereasnpx prettier -vreturns the correct2.5.0.Could this have any bearing or is this likely unrelated?
null-ls doesn't use npx or npm so this is likely unrelated.
@jose-elias-alvarez I have been running into this too. The local resolver does work for me mostly, but there is something to say for also letting npx deal with it. Especially for monorepos and stuff, npx prettier will take care of finding prettier. Unfortunately, setting the command to npx prettier doesn't work (only allows a single command). I could set the command to npx and add prettier to the args, but that would break the dynamic args from the plugin. Would it be useful to have an option to use npx instead of the node_modules resolver?
Ah, I have a work around to run prettier through npx
local null_ls = require("null-ls")
local null_ls_h = require("null-ls.helpers")
null_ls.setup({
sources = {
null_ls.builtins.formatting.prettier.with({
command = "npx",
args = null_ls_h.range_formatting_args_factory({
"prettier",
"--stdin-filepath",
"$FILENAME",
}, "--range-start", "--range-end", { row_offset = -3, col_offset = -1 }),
}),
},
})
Yep, your workaround makes sense but is definitely not ideal, since as you noted it requires copying the default dynamic arguments. Happy to review a PR adding an npx command resolver.