Skip to content

Instantly share code, notes, and snippets.

@amiralies
Created October 8, 2022 02:48
Show Gist options
  • Save amiralies/958278cc181c84acb22fa064222717f5 to your computer and use it in GitHub Desktop.
Save amiralies/958278cc181c84acb22fa064222717f5 to your computer and use it in GitHub Desktop.
Ensime TNG nvim lspconfig
local configs = require 'lspconfig.configs'
local lspconfig = require 'lspconfig'
-- Check if the config is already defined (useful when reloading this file)
if not configs.ensime then
configs.ensime = {
default_config = {
cmd = {
'java', '-jar', os.getenv("HOME") .. '/.cache/ensime/lib/ensime-lsp.jar'
},
filetypes = {'scala'},
root_dir = function(fname)
return lspconfig.util.find_git_ancestor(fname)
end,
settings = {}
}
}
end
-- call `setup()` to enable the FileType autocmd
require'lspconfig'.ensime.setup {}
@ckipp01
Copy link

ckipp01 commented Oct 8, 2022

If anyone is looking to use this and has a workspace that isn't a git workspace, you can replace root_dir with something like I use in nvim-metals which will look for given patterns. Although it requires plenary.

local Path = require("plenary.path")

--- Checks to see if the default or passed in patterns for a root file are
--- found or not for the given target level.
local has_pattern = function(patterns, target)
  for _, pattern in ipairs(patterns) do
    local what_we_are_looking_for = Path:new(target, pattern)
    if what_we_are_looking_for:exists() then
      return pattern
    end
  end
end

--- NOTE: This only searches 2 levels deep to find nested build files.
--- Given a situation like the below one where you have a root build.sbt
--- and one in your module a, you want to ensure the root is correctly set as
--- the root one, not the a one. This checks the parent dir to ensure this.
--- build.sbt  <-- this is the root
--- a/
---  - build.sbt <- this is not
---  - src/main/scala/Main.scala
local find_root_dir = function(patterns, startpath)
  local path = Path:new(startpath)
  -- TODO if we don't find it do we really want to search / probably not... add a check for this
  for _, parent in ipairs(path:parents()) do
    local pattern = has_pattern(patterns, parent)
    if pattern then
      local grandparent = Path:new(parent):parent()
      -- If the pattern is found, we don't check for all patterns anymore,
      -- instead only the one that was found. This will ensure that we don't
      -- find a buid.sc is src/build.sc and also a .git in ./ causing it to
      -- default to that instead of src for the root.
      if has_pattern({ pattern }, grandparent) then
        return grandparent.filename
      else
        return parent
      end
    end
  end
end

return {
  find_root_dir = find_root_dir,
}

@fommil
Copy link

fommil commented Oct 18, 2022

since ensime-tng is project agnostic, I think it's safe to set the project root to / or any other wildcard that neovim supports.

@ckipp01
Copy link

ckipp01 commented Oct 18, 2022

since ensime-tng is project agnostic

Could you explain a bit more about what you mean by this? If it's project agnostic how does it know what sources for example "belong" to a project?

@fommil
Copy link

fommil commented Oct 18, 2022

@ckipp01 check out the README for details. The compiler plugin extracts the build information, and it can reconcile all the open files that belong to the same compilation module. The build tool's definition of the project is irrelevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment