;;; terraform-ts-mode.el --- Major mode for Terraform files using tree-sitter -*- lexical-binding: t; -*-

;; Copyright (C) 2026 Pavel Popov

;; Author: Pavel Popov (https://github.com/velppa)
;; Maintainer: Pavel Popov (https://github.com/velppa)
;; Created: 2026-05-05
;; Version: 0.1.0
;; Keywords: terraform, tree-sitter

;; Licensed under the same terms as Emacs.
;;
;; This file is not part of GNU Emacs.

;;; Commentary:

;; Works with https://github.com/tree-sitter-grammars/tree-sitter-hcl grammar.
;; (add-to-list 'treesit-language-source-alist
;;  '(hcl "https://github.com/tree-sitter-grammars/tree-sitter-hcl"))

;; History:
;; 0.1.0 - 2026-05-05 - initial release

;;; Code:

(require 'treesit)

(defvar terraform-ts-mode--indent-rules
  `((hcl
     ((node-is "}") parent-bol 0)
     ((parent-is "block") parent-bol 2)
     ((parent-is "object") parent-bol 2)
     ((parent-is "attribute") parent-bol 2))))

(defvar terraform-ts-mode--font-lock-settings
  (treesit-font-lock-rules
   :language 'hcl
   :feature 'keyword
   '([(block_start) (block_end)] @font-lock-keyword-face)

   :language 'hcl
   :feature 'string
   '((string_lit) @font-lock-string-face)

   :language 'hcl
   :feature 'number
   '((numeric_lit) @font-lock-number-face)

   :language 'hcl
   :feature 'comment
   '((comment) @font-lock-comment-face)

   :language 'hcl
   :feature 'function
   '((function_call (identifier) @font-lock-function-name-face))

   :language 'hcl
   :feature 'variable
   '((identifier) @font-lock-variable-name-face)))

;;;###autoload
(define-derived-mode terraform-ts-mode prog-mode "Terraform"
  "Major mode for editing Terraform files using tree-sitter."
  :syntax-table nil

  (when (treesit-ready-p 'hcl)
    (treesit-parser-create 'hcl)

    ;; Indentation
    (setq-local treesit-simple-indent-rules terraform-ts-mode--indent-rules)

    ;; Font-lock
    (setq-local treesit-font-lock-settings terraform-ts-mode--font-lock-settings)
    (setq-local treesit-font-lock-feature-list
                '((comment)
                  (keyword string)
                  (number function variable)))

    ;; Navigation
    (setq-local treesit-defun-type-regexp "block")

    (treesit-major-mode-setup)))

;;;###autoload
(add-to-list 'auto-mode-alist '("\\.tf\\'" . terraform-ts-mode))


;;; Code:
(provide 'terraform-ts-mode)
;;; terraform-ts-mode.el ends here
