1 ;;; 9ps-mode.el --- major mode for editing ninepscripts -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2021 Omar Polo
5 ;; Author: Omar Polo <op@omarpolo.com>
8 ;; Permission to use, copy, modify, and distribute this software for any
9 ;; purpose with or without fee is hereby granted, provided that the above
10 ;; copyright notice and this permission notice appear in all copies.
12 ;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 ;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 ;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 ;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 ;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 ;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 ;; Major mode for editing ninepscripts, the kamid regression tests.
28 (defconst 9ps-keywords
29 '("assert" "const" "dir" "include" "proc" "str" "testing"
32 (defconst 9ps--font-lock-keywords
35 `(: (or ,@9ps-keywords))))
36 "`9ps-mode' constant keywords.")
38 (defvar 9ps-mode-syntax-table
39 (let ((st (make-syntax-table)))
40 (modify-syntax-entry ?\{ "(}" st)
41 (modify-syntax-entry ?\} "){" st)
42 (modify-syntax-entry ?\( "()" st)
43 ;; - and _ are word constituent
44 (modify-syntax-entry ?_ "w" st)
45 (modify-syntax-entry ?- "w" st)
46 ;; both single and double quotes makes strings
47 (modify-syntax-entry ?\" "\"" st)
48 (modify-syntax-entry ?' "'" st)
49 ;; one day we'll have escaping (maybe)
50 (modify-syntax-entry ?\\ "\\" st)
51 ;; add comments. is this the correct way?
52 (modify-syntax-entry ?# "<" st)
53 (modify-syntax-entry ?\n ">" st)
56 (defun 9ps-indent-line ()
57 "Indent current line."
59 boi-p ;begin of indent
64 (setq indent (car (syntax-ppss))
65 boi-p (= point (point)))
66 ;; don't indent empty lines, but only when they don't have the
68 (when (and (eq (char-after) ?\n)
71 ;; check whether we want to move to the end of line
72 (when (and (eq (char-after) ?\n)
75 ;; decrement the indent if the first character on the line is a
77 (when (or (eq (char-after) ?\))
78 (eq (char-after) ?\}))
79 (setq indent (1- indent)))
81 (delete-region (line-beginning-position)
83 (indent-to (* tab-width indent)))
85 (move-end-of-line nil))))
88 (define-derived-mode 9ps-mode prog-mode "9ps"
89 "Major mode for ninepscript files."
90 (setq font-lock-defaults '((9ps--font-lock-keywords)))
91 (setq-local comment-start "#")
92 (setq-local comment-start-skip "#+[\t ]*")
93 (setq-local indent-line-function #'9ps-indent-line))
96 (add-to-list 'auto-mode-alist '("\\.9ps" . 9ps-mode))
99 ;;; 9ps-mode.el ends here