Filetype.lua: Autodetection of Ansible YAML files (filetype: yaml.ansible)

Hi all! To all to active contributors here, thanks for this great tool! I really like neovim.

I’ve been trying to autodetect ansible files based on the first key in a file. I’ve found some topics with the new filetype.lua detection, but none of them similar enough to comment under them.

I’ve tried the following so far:

vim.filetype.add({
  extension = {
    ....

    -- doesn't work yet, TODO
    yaml = function(path, bufnr)
      if vim.fn.search('---\n- name: [a-zA-z]+', "nw") == 1 then
        return "yaml.ansible"

      elseif vim.fn.search('---\n- hosts: [a-zA-z]+', "nw") == 1 then

      -- other approach also did not work
      -- elseif string.find('- hosts:', vim.api.nvim_buf_get_lines(bufnr, 0, 2, true)) then
        return "yaml.ansible"
      else
        return "yaml"
      end
    end,
    ....
  },
...

This very simple approach also did not give the correct results:

vim.filetype.add({
  .....

  filename = {
    ["**/tasks/*.yaml"] = "yaml.ansible",
  }
  .....
}

I am clearly doing something wrong, but cannot figure out what. Could someone help me out?

Aside from this my custom filetype detection works file (but it’s more straightforward and does not use functions)

EDIT:

Error executing lua callback: .../.config/nvim/filetype.lua:9: bad argument #2 to 'find' (string expected,
 got table)

I think you should use the pattern not filename

vim.filetype.add({
  pattern = {
    [".*/tasks/.*.yaml"] = "yaml.ansible"
  },
})

For the extension function, I’m not working with ansible, but what kind of pattern is used to detect an ansible file? Take a look into :h vim.filetype.match() especially with contents args

Thanks for the suggestions and bugfixing. Your solution works like charm. I’ll have a look at the match function.

If you’re interested the docs has a example layout of an Ansible setup: Sample Ansible setup — Ansible Documentation.