Skip to content

denols and ts_ls conflict, neither activate in many typical scenarios #4300

@isaacs

Description

@isaacs

Description

Out of the box, it is impossible to attach the LSP client to most deno projects.

The denols configuration will not attach if there is a package.json file at a parent path equal to or greater than the nearest deno.lock file.

The ts_ls configuration will not attach if there is a deno.lock file at a parent path equal to or greater than the nearest package-lock.json file. (It does not respect package.json, though it ought to.)

This means that if you have a package.json and deno.lock file in the same directory, neither lsp client will attach.

Consider the following fairly typical case case:

my-project-workspace
+-- package-lock.json
+-- deno.lock
+-- packages
    +-- deno-package
    |    +-- deno.json
    |    +-- package.json
    |    +-- src
    |        +-- index.ts
    +-- node-package
        +-- package.json
        +-- src
            +-- index.ts

The file at packages/deno-package/src/index.ts will not
attach the denols client, because there is a package.json
file present closer than the nearest deno.lock file.

The file at packages/node-package/src/index.ts will not attach
the ts_ls client, because there is a deno.lock file present
parallel to the nearest package-lock.json file.

There is no LSP attachment for any typescript files anywhere in the project!

Proposed solution

If both lsps are enabled, then at least one should apply for any given TS file, no matter what.

denols behavior

  • Look for a deno.lock, deno.json, or deno.jsonc file.
  • Attach as long as the deno root is at least as close as the
    non-deno lockfile or project marker
local deno_markers = { 'deno.lock', 'deno.json', 'deno.jsonc' }
local project_markers = {
  'package-lock.json',
  'yarn.lock',
  'pnpm-lock.yaml',
  'bun.lockb',
  'bun.lock',
  'package.json',
  'node_modules',
}
local deno_root = vim.fs.root(bufnr, deno_markers)
local project_root = vim.fs.root(bufnr, project_markers)

if project_root and (not deno_root or #project_root > #deno_root) then
    return
end
on_dir(deno_root or vim.fn.getcwd())

ts_ls behavior

This should be the exact inverse of the denols attachment
behavior.

  • Look for a deno.lock, deno.json, or deno.jsonc file.
  • Attach as long as the deno root is further away than any
    non-deno project root.
local deno_markers = { 'deno.lock', 'deno.json', 'deno.jsonc' }
local project_markers = {
  'package-lock.json',
  'yarn.lock',
  'pnpm-lock.yaml',
  'bun.lockb',
  'bun.lock',
  'package.json',
  'node_modules',
}
local deno_root = vim.fs.root(bufnr, deno_markers)
local project_root = vim.fs.root(bufnr, project_markers)

if deno_root and (not project_root or #deno_root >= #project_root) then
    return
end
on_dir(project_root or vim.fn.getcwd())

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions