How to configure File Associations for Intelephense LS

I was not able to find how to configure lspconfig to set the file.associations structure for php files that drupal uses.

In here: nvim-lspconfig/server_configurations.md at master · neovim/nvim-lspconfig · GitHub

There is an example of setting filetypes.

filetypes = { "php" }

In here: GitHub - bmewburn/vscode-intelephense: PHP intellisense for Visual Studio Code They mention what the structure might look like:

"files.associations": { "*.module": "php" }

So for drupal development, inside my nvim-lspconfig.lua I think I would want something like this

local files_associations = {}
files_associations["*.install"] = "php"
files_associations["*.theme"] = "php"
files_associations["*.module"] = "php"
files_associations["*.inc"] = "php"

for _, lsp in ipairs(servers) do
  nvim_lsp[lsp].setup {
    on_attach = on_attach,
    capabilities = capabilities,
    files.associations = files_associations,
    ts_settings = ts_settings,
    flags = {
      debounce_text_changes = 150,
    }
  }
end

But that does not work.

I also see this structure proposed for Coc ( Configuring coc-phpls and intelephense for Drupal 7 · webschneider.org )

{
  "intelephense.environment.documentRoot": "/home/user/git/drupal",
  "intelephense.environment.includePaths": ["/home/user/git/drupal/includes"],
  "intelephense.files.associations": ["*.php", "*.phtml", "*.module", "*.inc"]
}

I see that for the ts_server there is a function delared that sets internal settings so I tried this:

-- Set settings for language servers below
--
-- tsserver settings
local ts_settings = function(client)
  client.resolved_capabilities.document_formatting = false
  ts_settings(client)
end

local file_settings = function(client)
  files.associations = { '*.install', '*.theme', '*.module', '*.inc' }
  file_settings(client)
end

-- local files_associations = { '*.install', '*.theme', '*.module', '*.inc' }

for _, lsp in ipairs(servers) do
  nvim_lsp[lsp].setup {
    on_attach = on_attach,
    capabilities = capabilities,
    files_settings = file_settings,
    ts_settings = ts_settings,
    flags = {
      debounce_text_changes = 150,
    }
  }
end

But that did not work either.

Has anyone gotten file.associations to work with Intelephense LS?

Were you able to get anywhere with this?

I too am moving from coc to lsp for Drupal dev and haven’t been able to figure out how to get intelephense setup.

A couple things:

  nvim_lsp[lsp].setup {
    on_attach = on_attach,
    capabilities = capabilities,
    files.associations = files_associations,
    ts_settings = ts_settings,
    flags = {
      debounce_text_changes = 150,
    }

ts_settings and files.associations are not valid keys read by the setup function. I would suggest re-reading :help lspconfig-setup for the list of valid keys.

If you want to pass a setting (generally any option that begins with the server name in the server documentation, which is passed via workspace/didChangeConfiguration notification from client to server):

require('lspconfig').intelephense.setup {
  on_attach=on_attach,
  capabilities=capabilities,
  settings = { intelephense =  { files = { associations = {"*.php", "*.phtml", "*.module", "*.inc"}}}}
}

I don’t use intelephense, so I can’t test this.

caschbre I did end up with a solution that works. I took this setup ( nv-ide/init.lua at master · crivotz/nv-ide · GitHub ) and added these lines to the very end:

require'lspconfig'.intelephense.setup{
  filetypes = {"php"},
  capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities())
}

Thanks @mjlbach and @danshumaker.

I too was able to get intelephense loading, however I’m still having a bit of trouble with the documentRoot and includePaths options.

I used to have the following in my coc-settings.json that I’m having trouble converting.

{
  "intelephense.environment.documentRoot": "../drupal",
  "intelephense.environment.includePaths": [
    "../src/modules",
    "../src/themes",
    "../drupal/sites/all/modules/dna"
  ],
}

I had a specific coc-settings.json file for the project so using the relative directories worked. How would I go about doing this?

@danshumaker Do you use intelephense for linting / formatting php… specifically Drupal? In my old setup I was using the diagnostics-languageserver with phpcs for linting and phpcbf for formatting with the Drupal, DrupalPractice standards.

i would suggest to use nvim-lsp-installer along with null-ls.
have a look at my config:

nvim-lspconfig
nvim-lsp-installer
null-ls

Thanks @shaeinst… I based a lot of my new setup on GitHub - ChristianChiarulli/nvim: My neovim config. I’ll dig into null-ls to see how to set both of those up.

Hey @caschbre , I kinda figured this would be the next question because as good as intelephense is, it still doesn’t adhere to the Drupal standards like phpcs and phpcbf do. And unfortunately the integration of intelephense and phpcs is not automatic or straightforward. Currently I use intelephense for main php syntax error fixing and finding (within telescope), but have had to install and use praem90/nvim-phpcsf to use the phpcs rulesets provided (and installed) by ( PHP_CodeSniffer/phpcs.xml.dist at master · squizlabs/PHP_CodeSniffer · GitHub ) and ( GitHub - PHPCSStandards/composer-installer: Composer installer for PHP_CodeSniffer coding standards)

Then I install custom hotkeys / keymaps like this:

vim.api.nvim_set_keymap('n', '<C-k>k', ":lua require'phpcs'.cs()<CR>", {noremap = true, silent = true})
vim.api.nvim_set_keymap('n', '<C-k>b', ":lua require'phpcs'.cbf()<CR>", {noremap = true, silent = true})

But nvim has to have the project root dir as it’s base dir in order for the phpcs.xml and phpcs.xml.dist file to be picked up.

@danshumaker Not sure if you’re using null-ls or not… however I was already configured to use nvim-lspconfig, nvim-lsp-installer, and null-ls. I did find that null-ls does support PHP_CodeSniffer. It was rather easy to configure null-ls to run phpcs for diagnostics and phpcbf for formatting. I’m also using intelephense in there as well.

I’m still wrapping my head around what all handles everything, especially after moving to neovim + lua, but getting PHP_CodeSniffer setup using the Drupal standards was my biggest hurdle.

1 Like

I’m using astronvim which has its own weird-o config schema. Took me so many attempts to guess this, but in my user/init.lua file I have the following:

config = {
  -- ...
  lsp =
    ["server-settings"] = {
      intelephense = {
        root_dir = (require 'lspconfig.util').root_pattern{".thisIsDocRoot"},
        settings = {
          intelephense = { files = { associations = { "*.php", "*.module", "*.inc" }}},
        }
      },
     -- ....

Note that this also makes it scan up the dirs for a file called .thisIsDocRoot to find the ‘workspace’ to index.

The never ending php{cs+cbf} saga. Current setup uses null-ls with null-ls.lua like this:

local null_ls = require("null-ls")
local utils = require("null-ls.utils")
-- https://marioyepes.com/neovim-ide-with-lua-for-web-development/#linting-with-null-ls

null_ls.setup({
  root_dir = utils.root_pattern("composer.json", "package.json", "Makefile", ".git"), -- Add composer
  diagnostics_format = "#{m} (#{c}) [#{s}]", -- Makes PHPCS errors more readeable
  sources = {
    null_ls.builtins.completion.spell, -- You still need to execute `:set spell`
    null_ls.builtins.diagnostics.eslint, -- Add eslint to js projects
    null_ls.builtins.diagnostics.phpcs.with({ -- Change how the php linting will work
      prefer_local = "vendor/bin",
    }),
    null_ls.builtins.formatting.stylua, -- You need to install stylua first: `brew install stylua`
    null_ls.builtins.formatting.phpcbf.with({ -- Use the local installation first
      prefer_local = "vendor/bin",
      args = {
        '-',
        "-q",
        '--standard="Drupal,DrupalPractice"',
        '--extensions="php,module,inc,install,test,profile,theme"',
      },
    }),
  },
})

Diagnostics is running, and formatting config still needs adjusting (works for lua but not php).

I recently switched to using LazyVim. Here’s what I have for phpcs, phpcbf, and intelephense. I also have a phpcs.xml.dist file sitting just above my src to control phpcs rules, etc. So far this seems to work well.

lua/plugins/null-ls.lua

return {
  "jose-elias-alvarez/null-ls.nvim",
  opts = function()
    local nls = require("null-ls")
    return {
      -- debug = true,
      diagnostics_format = "#{m} (#{c}) [#{s}]",
      sources = {
        nls.builtins.diagnostics.phpcs,
        nls.builtins.formatting.phpcbf.with({
          args = {
            '-',
            "-q",
            '--standard="Drupal,DrupalPractice"',
            '--extensions="php,module,inc,install,test,profile,theme"',
          },
        }),
      },
    }
  end,
}

lua/plugins/nvim-lspconfig.lua

return {
  "neovim/nvim-lspconfig",
  opts = {
    servers = {
      intelephense = {
        settings = {
          intelephense = {
            diagnostics = { enable = false },
            environment = {
              documentRoot = "/path/to/src",
              includePaths = {
                "/path/to/drupal/root"
              },
              phpVersion = "8.1.22",
            },
            files = {
              associations = { "*.php", "*.module", "*.inc", "*.install" },
              exclude = {
                "/path/to/symlinked/src/under/drupal/root/**"
              }
            },
            format = { enable = false },
            licenseKey = "~/.intelephense",
            telemetry = { enabled = false },
          }
        }
      },
    },
  },
}