12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 | (defvar tomo-mode-hook nil)
(defvar tomo-keywords
'("if" "else" "for" "in" "while" "return" "skip" "stop" "break" "continue" "repeat"
"struct" "enum" "lang" "when" "is" "func" "pass" "assert"))
(defvar tomo-types
'("Int" "Int64" "Int32" "Int16" "Int8" "Byte" "Num" "Num32" "Bool" "Text" "Void" "Abort"))
(defvar tomo-constants
'("yes" "no" "none"))
(defvar tomo-operators
'("+" "-" "*" "/" "%" "==" "!=" "<" ">" "<=" ">=" "!" ":=" ":" "=" "+=" "-=" "*=" "/="))
(defvar tomo-font-lock
`((,(regexp-opt tomo-keywords 'words) . font-lock-keyword-face)
(,(regexp-opt tomo-types 'words) . font-lock-type-face)
(,(regexp-opt tomo-constants 'words) . font-lock-constant-face)
(,(regexp-opt '("and" "or" "xor" "_min_" "_max_" "mod" "mod1") 'words) . font-lock-builtin-face)
(,(regexp-opt tomo-operators 'words) . font-lock-builtin-face)
("\\<[0-9]+\\(\\.[0-9]+\\)?\\([eE][+-]?[0-9]+\\)?\\>" . font-lock-constant-face) ; numbers
("\\<0x[0-9A-Fa-f]+\\>" . font-lock-constant-face) ; hex
("\\<0b[01]+\\>" . font-lock-constant-face) ; binary
("\\<0o[0-7]+\\>" . font-lock-constant-face) ; octal
("\\<[a-zA-Z_][a-zA-Z0-9_]*\\s-*(" . font-lock-function-name-face) ; function calls
("\"" ; text with interpolation
(0 font-lock-string-face)
("\\(\\$[a-zA-Z_][a-zA-Z0-9_]*\\)" ; Simple var interpolation
(string-match-p "[^\\]\"" (match-string 0)) nil ; Only within strings
(1 font-lock-variable-name-face t))
("\\(\\$([^)]*)\\)" ; Expression interpolation
(string-match-p "[^\\]\"" (match-string 0)) nil ; Only within strings
(1 font-lock-preprocessor-face t)))
)) ; function calls
(defun should-indent-tomo ()
(let ((tomo-indent-keywords '("if" "else" "repeat" "when" "is" "convert" "lang" "struct" "enum" "while" "for" "func")))
(seq-some (lambda (kw) (looking-at (concat "^[ \t]*" kw))) tomo-indent-keywords)))
(defun tomo-newline-and-indent ()
"Insert a newline and indent the next line if it's a block-starting line."
(interactive)
(let ((cur-indent (current-indentation)))
(let ((next-line-indent
(save-excursion
(beginning-of-line)
(if (should-indent-tomo) (+ cur-indent 4) cur-indent))))
(newline)
(indent-line-to next-line-indent))))
(defvar tomo-mode-syntax-table
(let ((st (make-syntax-table)))
;; Define '#' as comment start character
(modify-syntax-entry ?# "<" st)
;; Define newline as comment end character
(modify-syntax-entry ?\n ">" st)
;; Other syntax entries...
st)
"Syntax table for tomo-mode.")
;;;###autoload
(define-derived-mode tomo-mode prog-mode "Tomo"
"Major mode for editing Tomo source files."
:syntax-table tomo-mode-syntax-table
(setq font-lock-defaults '((tomo-font-lock)))
(setq comment-start "#")
(setq comment-end "")
(local-set-key (kbd "RET") 'tomo-newline-and-indent)
(setq-local indent-tabs-mode nil)
(setq-local tab-width 4))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.tm\\'" . tomo-mode))
(provide 'tomo-mode)
|