-- replace the vimscript filetype machinery with pure lua. -- -- what neovim does by default: -- filetype on -> detection ( lua, vim.filetype ) -- filetype plugin on -> sources $VIMRUNTIME/ftplugin/.vim ( vimscript ) -- filetype indent on -> sources $VIMRUNTIME/indent/.vim ( vimscript ) -- -- we keep detection ( lua ) and kill the two vimscript loaders. -- this also stops our own after/ftplugin/*.lua from loading, because they -- ride the same builtin autocmd. so we reimplement that loader below. -- keep detection, drop the vimscript plugin + indent sourcing. vim.cmd 'filetype plugin indent off' -- indentation: delegate to treesitter ( pure lua ). -- nvim-treesitter main ships an experimental indent module + indents.scm queries. -- get_indent returns -1 when no parser is available, which makes neovim fall -- back to 'autoindent'. wrapped in pcall so a not-yet-loaded treesitter or a -- query error never spams indentexpr errors. function _G.BugabingaIndent() local ok, indent = pcall( function() return require( 'nvim-treesitter.indent' ).get_indent( vim.v.lnum ) end ) return ok and indent or -1 end vim.o.indentexpr = 'v:lua.BugabingaIndent()' -- our own filetype loader, replacing the builtin vimscript one. -- sets commentstring from a lua table ( native gc reads vim.bo.commentstring ) -- and sources our after/ftplugin/.lua files. mirrors neovim by splitting -- compound filetypes like 'markdown.mdx' into their dotted components. local commentstring = require 'std.commentstring' local ftoptions = require 'std.ftoptions' local config_dir = vim.fn.stdpath 'config' local group = vim.api.nvim_create_augroup( 'bugabinga_ftplugin', { clear = true } ) vim.api.nvim_create_autocmd( 'FileType', { group = group, desc = 'pure-lua ftplugin: commentstring + user after/ftplugin', callback = function ( args ) for ft in vim.gsplit( args.match, '.', { plain = true } ) do if ft ~= '' then local cs = commentstring[ft] if cs then vim.bo[args.buf].commentstring = cs end -- pure-data per-ft options ( comments, define, include, path, … ) -- that the killed vimscript ftplugins used to set. local opts = ftoptions[ft] if opts then for name, value in pairs( opts ) do vim.bo[args.buf][name] = value end end local file = config_dir .. '/after/ftplugin/' .. ft .. '.lua' if vim.uv.fs_stat( file ) then local chunk = loadfile( file ) if chunk then chunk() end end end end end, } )