Initial commit

This commit is contained in:
Jakub 2025-11-01 20:19:23 +08:00
commit 3c794e59c8
2 changed files with 88 additions and 0 deletions

5
README.org Normal file
View file

@ -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.

83
jomini-mode.el Normal file
View file

@ -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 <https://www.gnu.org/licenses/>.
;;; 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