~gagbo/rhai-mode

c089a33d05e79e5da8ac941b87a1a7c574ab4382 — Gerry Agbobada 1 year, 5 months ago 4706126 trunk
First version
4 files changed, 175 insertions(+), 0 deletions(-)

A .gitignore
A LICENSES/BSD-3-Clause-Clear.txt
A README.md
A rhai-mode.el
A .gitignore => .gitignore +2 -0
@@ 0,0 1,2 @@
# Test files
*.rhai

A LICENSES/BSD-3-Clause-Clear.txt => LICENSES/BSD-3-Clause-Clear.txt +14 -0
@@ 0,0 1,14 @@
The Clear BSD License

Copyright (c) [xxxx]-[xxxx] [Owner Organization]
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met:

     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

     * Neither the name of [Owner Organization] nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

A README.md => README.md +3 -0
@@ 0,0 1,3 @@
# Rhai-mode: a major mode for Rhai scripts

[Rhai](https://rhai.rs/) is an embedded scripting language and engine for Rust

A rhai-mode.el => rhai-mode.el +156 -0
@@ 0,0 1,156 @@
;;; rhai-mode.el --- A major-mode for editing Rhai scripts -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2022 Gerry Agbobada <git@gagbo.net>
;; SPDX-License-Identifier: BSD-3-Clause-Clear
;;
;; Author: Gerry Agbobada <git@gagbo.net>
;; Maintainer: Gerry Agbobada <git@gagbo.net>
;; Created: September 03, 2022
;; Modified: September 03, 2022
;; Version: 0.0.1
;; Keywords: languages
;; Homepage: https://git.sr.ht/~gagbo/rhai-mode
;; Package-Requires: ((emacs "27.2") (rust-mode "1.0.5"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;; Rhai is a small, fast, easy-to-use scripting language and evaluation engine
;; that integrates tightly with Rust. Builds for most common targets including
;; no-std and WASM.
;;
;; More information at https://rhai.rs
;;
;;
;;; Code:

(require 'prog-mode)
(require 'rust-mode)
(eval-when-compile (require 'rx))

;; Source: https://rhai.rs/book/language/keywords.html
(defconst rhai-mode-bool-keywords
  '("true" "false"                                            ; constants
    ))
(defconst rhai-mode-var-decl-keywords
  '("let" "const"                       ; variables
    "fn"                                ; functions
    ))
(defconst rhai-mode-builtin-func-keywords
  '("is_shared"                                               ; shared values
    "is_def_fn"                         ; functions
    "type_of" "print" "debug" "eval" "is_def_var"             ; special functions
    "Fn" "call" "curry"                                       ; function pointers
    ))
(defconst rhai-mode-builtin-vars-keywords
  '("this"                         ; functions
    "global"                                                  ; automatic global module
    ))
(defconst rhai-mode-cond-keywords
  '("if" "else"                                               ; control flow
    "switch"                                                  ; switching and matching
    ))
(defconst rhai-mode-loop-keywords
  '("do" "while" "loop" "until" "for" "in" ; looping
    ))
(defconst rhai-mode-statement-keywords
  '("continue" "break"  ; looping
    "return"                                                  ; return values
    ))
(defconst rhai-mode-exception-keywords
  '("throw" "try" "catch"                                     ; throw/catch exceptions
    ))
(defconst rhai-mode-access-qual-keywords
  '("private"                         ; functions
    ))
(defconst rhai-mode-module-keywords
  '("import" "export" "as"                                    ; modules
    ))
(defconst rhai-mode-reserved-keywords
  '("var" "static"                                       ; variables
    "is"                                                 ; type checking
    "goto" "exit"                                        ; control flow
    "match" "case"                                       ; switching and matching
    "public" "protected" "new"                           ; functions
    "use" "with" "module" "package" "super"              ; modules
    "spawn" "thread" "go" "sync" "async" "await" "yield" ; threading/async
    "default" "void" "null" "nil"                        ; special values
    ))

;; indent-line-function

;; Faces
(defface rhai-mode-number-face '((t :inherit  font-lock-constant-face))
  "Face for numbers in Rhai scripts."
  :group 'rhai-mode)
(defface rhai-mode-boolean-face '((t :inherit  font-lock-constant-face))
  "Face for booleans in Rhai scripts."
  :group 'rhai-mode)
(defface rhai-mode-string-face '((t :inherit  font-lock-string-face))
  "Face for strings in Rhai scripts."
  :group 'rhai-mode)
(defface rhai-mode-keyword-face '((t :inherit  font-lock-keyword-face))
  "Face for keywords in Rhai scripts."
  :group 'rhai-mode)
(defface rhai-mode-module-face '((t :inherit  font-lock-preprocessor-face))
  "Face for modules in Rhai scripts."
  :group 'rhai-mode)
(defface rhai-mode-decl-face '((t :inherit  font-lock-builtin-face))
  "Face for variable declarations in Rhai scripts."
  :group 'rhai-mode)
(defface rhai-mode-access-face '((t :inherit  font-lock-warning-face))
  "Face for access qualifiers in Rhai scripts."
  :group 'rhai-mode)
(defface rhai-mode-reserved-face '((t :inherit  font-lock-warning-face))
  "Face for reserved qualifiers in Rhai scripts."
  :group 'rhai-mode)
(defface rhai-mode-builtin-face '((t :inherit  font-lock-builtin-face))
  "Face for builtin functions in Rhai scripts."
  :group 'rhai-mode)
(defface rhai-mode-function-face '((t :inherit  font-lock-function-name-face))
  "Face for function names in Rhai scripts."
  :group 'rhai-mode)

(defvar rhai-font-lock-keywords
  (append
   `(
     ;; Special types
     (,(regexp-opt rust-special-types 'symbols) . font-lock-type-face)

     (,(regexp-opt rhai-mode-bool-keywords 'symbols) . 'rhai-mode-boolean-face)
     (,(regexp-opt rhai-mode-var-decl-keywords 'symbols) . 'rhai-mode-decl-face)
     (,(regexp-opt rhai-mode-builtin-func-keywords 'symbols) . 'rhai-mode-builtin-face)
     (,(regexp-opt rhai-mode-builtin-vars-keywords 'symbols) . 'rhai-mode-builtin-face)
     (,(regexp-opt rhai-mode-cond-keywords 'symbols) . 'rhai-mode-keyword-face)
     (,(regexp-opt rhai-mode-loop-keywords 'symbols) . 'rhai-mode-keyword-face)
     (,(regexp-opt rhai-mode-statement-keywords 'symbols) . 'rhai-mode-builtin-face)
     (,(regexp-opt rhai-mode-exception-keywords 'symbols) . 'rhai-mode-keyword-face)
     (,(regexp-opt rhai-mode-access-qual-keywords 'symbols) . 'rhai-mode-access-face)
     (,(regexp-opt rhai-mode-module-keywords 'symbols) . 'rhai-mode-module-face)
     (,(regexp-opt rhai-mode-reserved-keywords 'symbols) . 'rhai-mode-reserved-face)))
  "First element to use for `font-lock-defaults'.")

(defvar rhai-mode-syntax-table
  (let ((st (make-syntax-table)))
    ;; Rust style comment
    (modify-syntax-entry ?\/ ". 12b" st)
    (modify-syntax-entry ?\n "> b" st)
    st))

;; User facing API
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.rhai\\'" . rhai-mode))

;;;###autoload
(define-derived-mode rhai-mode prog-mode "Rhai"
  "Major mode for Rhai scripts."
  :group 'rhai-mode
  ;; Faces
  (setq-local font-lock-defaults '(rhai-font-lock-keywords))
  ;; Misc
  (setq-local comment-start "// ")
  (setq-local comment-end   ""))

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