From 3c794e59c871927c0e84254a35c0e49ff1e9d287 Mon Sep 17 00:00:00 2001 From: Jakub Date: Sat, 1 Nov 2025 20:19:23 +0800 Subject: [PATCH] Initial commit --- README.org | 5 +++ jomini-mode.el | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 README.org create mode 100644 jomini-mode.el diff --git a/README.org b/README.org new file mode 100644 index 0000000..a2c647c --- /dev/null +++ b/README.org @@ -0,0 +1,5 @@ +#+title: jomini-mode.el + +Extremely basic major mode for editing Jomini script files. Needs work, but it handles all the basics like indentation properly which is all I really care about currently. + +It won't automatically detect what files it should start in currently. That is left as an exercise for the reader. diff --git a/jomini-mode.el b/jomini-mode.el new file mode 100644 index 0000000..a350dab --- /dev/null +++ b/jomini-mode.el @@ -0,0 +1,83 @@ +;;; 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