Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/lua/bugabinga/options/ftplugin.lua

Raw
-- 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/<ft>.vim  ( vimscript )
--   filetype indent on   -> sources $VIMRUNTIME/indent/<ft>.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/<ft>.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,
} )