;;; vegalite-mode.el --- Major mode for Vega-Lite specs -*- lexical-binding: t -*-

;; Copyright © 2024 Volker Edelmann <vedelmann@gmx.de>
;;
;; Author:  Volker Edelmann <vedelmann@gmx.de>

;; Version: 1.0
;; Keywords: languages, plotting, javascript
;; Package-Requires:

;; vegalite-mode is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; vegalite-mode is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with vegalite-mode.  If not, see <http://www.gnu.org/licenses/>.

;; This file is not part of GNU Emacs.

;;; Commentary:

;;; Code:
(require 'json-ts-mode)
(require 'treesit)

;;;###autoload
(add-to-list 'auto-mode-alist '("\\.vl\\.json$" . vegalite-mode))

(define-abbrev-table 'vegalite-mode-abbrev-table
  '(("d" "\"data\" :" nil nil t)
    ("sp" "\"spec\" :" nil nil t)
    ("m" "\"mark\" :" nil nil t)
    ("col" "\"color\" :" nil nil t)
    )
  "Abbrev table used in `vegalite-mode.")

(defconst vl-keywords
  (list "\"\$schema\""
	"\"data\""
	)
  )

(defvar vl-mode--font-lock-settings
  (treesit-font-lock-rules
   :language 'json
   :feature 'bracket
   '((["[" "]" "{" "}"]) @font-lock-bracket-face)
   :language 'json
   :feature 'constant
   '([(null) (true) (false)] @font-lock-constant-face)
   :language 'json
   :feature 'delimiter
   '((["," ":"]) @font-lock-delimiter-face)
   :language 'json
   :feature 'number
   '((number) @font-lock-number-face)
   :language 'json
   :feature 'string
   '((string) @font-lock-string-face)
   :language 'json
   :feature 'escape-sequence
   :override t
   '((escape_sequence) @font-lock-escape-face)
   :language 'json
   :feature 'pair
   :override t ; Needed for overriding string face on keys.
   '((pair key: (_) @font-lock-keyword-face))
   :language 'json
   :feature 'keyword
   `([,@vl-keywords] @font-lock-string-face)
   :override t
   :language 'json
   :feature 'error
   :override t
   '((ERROR) @font-lock-warning-face))
  "Font-lock settings for Vega Lite.")



;;;###autoload
(define-derived-mode vegalite-mode json-ts-mode "VL"
  "Major mode for editing Vega-Lite files."
  :abbrev-table vegalite-mode-abbrev-table
  
  (setq-local treesit-font-lock-settings vl-mode--font-lock-settings)
  (setq-local treesit-font-lock-feature-list
	      '((string pair keyword)
		(constant number)
		(escape-sequence)
		(bracket delimiter error)))
  
  (setq-local comment-start nil)
  )

(provide 'vegalite-mode)
;;; vegalite-mode.el ends here