---@module 'lazy'
---@type LazySpec
return { {
	'nvim-treesitter/nvim-treesitter', -- highlight, edit, and navigate code
	event = 'BufReadPre',
	build = ':TSUpdate',
	main = 'nvim-treesitter.configs', -- set main module to use for opts
	opts = {
		ensure_installed = {
			'bash', 'c', 'make', 'rust', 'diff',
			'markdown', 'markdown_inline', 'latex',
			'vim', 'vimdoc', 'lua', 'luadoc', 'regex',
		},
		auto_install = true, -- auto-install languages that are not installed
		highlight = {
			enable = true,
			additional_vim_regex_highlighting = { 'ruby' }, -- some languages depend on vim's regex highlighting system for indent rules
		},
		indent = { enable = true, disable = { 'ruby' } },
	},
	config = function(_, opts)
		require('nvim-treesitter.configs').setup(opts)

		-- set the keybind for appending in front of a comment, rather than behind.
		Map('n', 'A', function()
			local ts = vim.treesitter          -- get reference to treesitter
			local buf = vim.api.nvim_get_current_buf() -- get the current buffer id
			local row, col = unpack(vim.api.nvim_win_get_cursor(0)) -- get cursor position

			-- ensure the parser exists
			local res = nil
			repeat
				-- get the parser
				if not ts.language.get_lang(vim.bo[buf].filetype) then break end
				local parser = ts.get_parser(buf, nil, { error = false })
				if not parser then break end

				-- query the buffer using the parser
				local root = parser:parse()[1]:root()
				local ok, dat = pcall(ts.query.parse, parser:lang(), [[(comment) @comment]])
				if not ok or not dat then break end

				-- set the result
				res = { query = dat, root = root }
			until true

			-- check if we successfully made a query
			if res then
				-- loop through the captures from the query
				for _, node in res.query:iter_captures(res.root, buf, row - 1, row) do
					-- ensure the comment is on the same row as the cursor and after the cursor's column
					local srow, scol, _, _ = node:range() -- extract the starting row and starting column
					if srow ~= row - 1 or col >= scol then goto continue end

					-- get the line text and remove trailing whitespace
					local txt = vim.api.nvim_buf_get_lines(buf, srow, srow + 1, true)[1]:sub(0, scol)
					txt = txt:gsub("%s*$", "")
					local len = txt:len()

					-- check if we found a match
					if len > 0 then
						vim.api.nvim_win_set_cursor(0, { row, len })
						vim.cmd [[startinsert]]
						return
					end
					::continue:: -- lua is stupid
				end
			end

			-- no comment start was found, behave like normal (moves cursor to the end of the line)
			vim.cmd [[startinsert!]]
		end, { desc = 'append end of line' })
	end,
} }
