Initial version of able-script-mode

This commit is contained in:
Alex Bethel 2021-08-09 13:24:44 -06:00
parent 3596e7b663
commit a00866251f
3 changed files with 103 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*~

10
README.md Normal file
View file

@ -0,0 +1,10 @@
# AbleScript Mode
![Discord](https://img.shields.io/discord/831368967385120810)
[Able Script Book](https://ablecorp.us/able-script-the-book/)
Emacs major mode for editing AbleScript files.
## Features
- Syntax highlighting of keywords, variables and base52 numbers
- Automatic indentation

92
able-script-mode.el Normal file
View file

@ -0,0 +1,92 @@
;;; able-script-mode -- Able script mode
;;; Commentary:
;; Major mode for able-script code, by Alex Bethel. See
;; https://github.com/AbleCorp/able-script.
;;; Code:
(defgroup able-script-mode nil
"Support for AbleScript code."
:link '(url-link "https://github.com/AbleCorp/able-script")
:group 'languages)
(defcustom able-script-indent-offset 4
"Indent AbleScript code by this number of spaces per level."
:type 'integer
:group 'able-script-mode)
;; Adapted from
;; gemini://gemini.omarpolo.com/post/writing-a-major-mode.gmi
;;
;; TODO: this behaves strangely sometimes when point is at the
;; beginning of the line; re-write this to work like other major
;; modes.
(defun able-script-indent-line ()
"Indent current line."
(let (indent
boi-p ;begin of indent
move-eol-p
(point (point)))
(save-excursion
(back-to-indentation)
(setq indent (car (syntax-ppss))
boi-p (= point (point)))
;; don't indent empty lines
(when (and (eq (char-after) ?\n)
(not boi-p))
(setq indent 0))
;; check whether we want to move
(when boi-p
(setq move-eol-p t))
;; decrement the indent if the first character on the line is a
;; closer.
(when (or (eq (char-after) ?\))
(eq (char-after) ?\})
(eq (char-after) ?\]))
(setq indent (1- indent)))
;; indent the line.
(delete-region (line-beginning-position)
(point))
(indent-to (* able-script-indent-offset indent)))
(when move-eol-p
(back-to-indentation))))
;; Using generic-mode for now because I'm lazy.
(define-generic-mode
able-script-mode
'("owo")
'("aint"
"functio"
"bff"
"var"
"print"
"read"
"melo"
"T-Dark"
"if"
"loop"
"break"
"rlyeh"
"rickroll"
"true"
"false"
"always"
"sometimes"
"never")
'(
;; Draw base-52 numbers in the `warning' face, because if you're
;; anything like me you usually don't mean to use them.
("\\b[[:alpha:]]\\b" 0 font-lock-warning-face)
("\\bvar \\([[:alnum:]_]*\\)" 1 font-lock-variable-name-face)
("\\bfunctio \\([[:alnum:]_]*\\)" 1 font-lock-function-name-face))
'(".*\\.able")
(list
(function
(lambda ()
(setq-local indent-line-function #'able-script-indent-line))))
"Able-script mode")
(provide 'able-script-mode)
;;; able-script-mode.el ends here