Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose filetype matching from filetype.lua #18241

Closed
clason opened this issue Apr 24, 2022 · 9 comments
Closed

Expose filetype matching from filetype.lua #18241

clason opened this issue Apr 24, 2022 · 9 comments
Labels
enhancement feature request filetype filetype detection, filetype.lua lua stdlib

Comments

@clason
Copy link
Member

clason commented Apr 24, 2022

Currently, filetype.lua reproduces the behavior of filetype.vim in that the vim.filetype.match() function directly sets the filetype of a buffer as soon as a match for the file is found. However, there are situations when it is useful to just know the filetype without setting it (e.g., for getting the right treesitter parser, or for previewing a file with syntax highlighting without firing all ftplugins for it).

Ideally, vim.filetype.match() should be refactored to return the found filetype as a string (which is then used in the BufRead autocommand to set the filetype). The difficulty here is that filetype.lua still relies on the legacy dist#ft functions for more complicated content checks -- which set the filetype directly. (And similarly for runtime/scripts.vim.)

The simplest (in terms of complexity, not amount of work) approach would be to rewrite these in Lua as well and have them return the filetype instead. This would make porting new filetypes from Vim a bit harder, but a) upstream has already rewritten that file in Vim9script anyway and b) the same type of manual intervention is already done for the simpler (but otherwise similar) inlined functions in filetype.lua -- which could then be moved to a common submodule to remove this somewhat arbitrary distinction.

@clason clason added enhancement feature request good-first-issue lua stdlib filetype filetype detection, filetype.lua labels Apr 24, 2022
@afsharalex
Copy link

Hi,

Has anyone started on this already?

@gpanders
Copy link
Member

gpanders commented Apr 24, 2022

I propose a new file runtime/lua/vim/filetype/detect.lua where we translate all of the dist#ft functions and make them return a string for the matched filetype. In filetype.lua we then replace calls to dist#ft#whatever with vim.filetype.detect.whatever.

To expand further, I agree that vim.filetype.match should be refactored to simply return a string. This is a breaking change but since filetype.lua has been gated behind an opt-in flag I'm okay with that. The BufRead,BufNewFile autocommand in runtime/filetype.lua would then simply be changed to:

callback = function(args)
  vim.api.nvim_buf_set_option(args.buf, "filetype", vim.filetype.match(args.buf))
end

@clason
Copy link
Member Author

clason commented Apr 24, 2022

Has anyone started on this already?

Not yet -- go for it! As @gpanders wrote, create a new file and translate the functions one-by-one; you can call them from filetype.lua via

foo = function(path, bufnr)
  return require'filetype.detect'.foo()
end

(which is the Lua version of "autoloading"). Best start with the simplest ones; one commit per function. There are already some simple functions in filetype.lua that check contents; you can use those as a guide. (And you don't need to do all of them; getting a chunk out of the way is already helpful!)

@afsharalex
Copy link

Awesome, thanks for the guidance!

dundargoc added a commit to dundargoc/neovim that referenced this issue Apr 24, 2022
dundargoc added a commit to dundargoc/neovim that referenced this issue Apr 25, 2022
dundargoc added a commit to dundargoc/neovim that referenced this issue Apr 25, 2022
Also write a lua version of dist#ft#FTtf and use it in filetype.lua

Work on neovim#18241
@afsharalex
Copy link

Hi, I could use a hand with the FThtml, not that familiar with Lua patterns. Translating this:

getline(n) =~ '{%\s*\(extends\|block\|load\)\>\|{#\s\+'

regex has proven a bit tricky, so I'm wondering if I should use another pattern or just do:

local re = vim.regex("{%\\s*\\(extends\\|block\\|load\\)\\>\\|{#\\s\\+")

and use re:match_str or if there is a better way? Thanks

@gpanders
Copy link
Member

This almost works:

local line = getline(n)
if line:find("{%%%s*extends") or line:find("{%%%s*block") or line:find("{%%%s*load") or line:find("{#%s+") then

But AFAIK Lua patterns don't have any equivalent to Vim's \> in regex patterns. So it's possible there could be mismatches.

I'll have to think about whether or not we want to use vim.regex.

dundargoc added a commit to dundargoc/neovim that referenced this issue Apr 25, 2022
Also write a lua version of dist#ft#FTtf and use it in filetype.lua

Work on neovim#18241
dundargoc added a commit to dundargoc/neovim that referenced this issue Apr 25, 2022
Also write a lua version of dist#ft#FTtf and use it in filetype.lua

Work on neovim#18241
@clason
Copy link
Member Author

clason commented Apr 26, 2022

Hi,

Has anyone started on this already?

Looks like someone did beat you to it (sorry!): #18247

That PR is still missing the html check, though, so when you're done, you can contribute it to that PR (via a comment, or a different PR branched from that PR) -- it's best if you coordinate with @smjonas on the effort.

As an alternative, you could focus your attention on scripts.vim, which similarly requires porting and hasn't been touched yet (as far as I'm aware).

@afsharalex
Copy link

No worries! Thanks, I'll try again on the weekend so I don't get swept away by work, cheers!

@clason
Copy link
Member Author

clason commented May 17, 2022

Superseded by #18604

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement feature request filetype filetype detection, filetype.lua lua stdlib
Projects
None yet
Development

No branches or pull requests

3 participants