;;; jomini-mode.el --- Major mode for jomini script editing an Clausewitz paradox modding. -*- lexical-binding: t -*- ;; This file is not part of GNU Emacs ;; This program 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 of the License, or ;; (at your option) any later version. ;; This program 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 this program. If not, see . ;;; Commentary: ;; Mostly copied from https://www.omarpolo.com/post/writing-a-major-mode.html ;;; Code: (require 'rx) (defconst jomini/font-lock-defaults (let ((keywords '("root" "prev" "this" "limit" "trigger" "count")) (logops '("AND" "OR" "NOT" "NOR" "NAND")) (statements '("if" "else_if" "else" "switch" "while" "trigger_if" "trigger_else_if" "trigger_else"))) `(((,(rx-to-string `(: (or ,@keywords))) 0 font-lock-keyword-face) (,(rx-to-string '(: (one-or-more word) ":")) 0 font-lock-type-face) (,(rx-to-string '(: "#" (zero-or-more not-newline) "\n"))) (,(rx-to-string `(or (: "$" (one-or-more word) "$") (: (or ,@logops)))) 0 font-lock-variable-name-face) (,(rx-to-string `(: (or ,@statements))) 0 font-lock-function-call-face))))) (defvar jomini-mode-syntax-table (let ((st (make-syntax-table))) ;; Paren joining (modify-syntax-entry ?\{ "(}" st) (modify-syntax-entry ?\} "){" st) ;; Underscores can make up words (modify-syntax-entry ?_ "w" st) ;; Comments (modify-syntax-entry ?\# "<" st) (modify-syntax-entry ?\n ">" st) st)) (defun jomini-indent-line () "Indent the current line." (let (indent boi-p move-eol-p (point (point))) (save-excursion (back-to-indentation) (setq indent (car (syntax-ppss)) boi-p (= point (point))) (when boi-p (setq move-eol-p t)) (when (eq (char-after) ?\}) (setq indent (1- indent))) (delete-region (line-beginning-position) (point)) (indent-to (* tab-width indent))) (when move-eol-p (move-end-of-line nil)))) (define-derived-mode jomini-mode prog-mode "jmni" "Major mode for Jomini modding." :syntax-table jomini-mode-syntax-table (setq font-lock-defaults jomini/font-lock-defaults) (setq-local comment-start "#") (setq-local comment-start-skip "#+[\t ]*") (setq-local indent-line-function #'jomini-indent-line) (setq-local indent-tabs-mode t)) (provide 'jomini-mode) ;;; jomini-mode.el ends here