Blame


1 56250a8f 2021-08-05 op ;;; 9ps-mode.el --- major mode for editing ninepscripts -*- lexical-binding: t; -*-
2 56250a8f 2021-08-05 op
3 56250a8f 2021-08-05 op ;; Copyright (C) 2021 Omar Polo
4 56250a8f 2021-08-05 op
5 56250a8f 2021-08-05 op ;; Author: Omar Polo <op@omarpolo.com>
6 56250a8f 2021-08-05 op ;; Keywords: languages
7 56250a8f 2021-08-05 op
8 72bd97a1 2021-08-05 op ;; Permission to use, copy, modify, and distribute this software for any
9 72bd97a1 2021-08-05 op ;; purpose with or without fee is hereby granted, provided that the above
10 72bd97a1 2021-08-05 op ;; copyright notice and this permission notice appear in all copies.
11 56250a8f 2021-08-05 op
12 72bd97a1 2021-08-05 op ;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 72bd97a1 2021-08-05 op ;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 72bd97a1 2021-08-05 op ;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 72bd97a1 2021-08-05 op ;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 72bd97a1 2021-08-05 op ;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 72bd97a1 2021-08-05 op ;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 72bd97a1 2021-08-05 op ;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 56250a8f 2021-08-05 op
20 56250a8f 2021-08-05 op ;;; Commentary:
21 56250a8f 2021-08-05 op
22 56250a8f 2021-08-05 op ;; Major mode for editing ninepscripts, the kamid regression tests.
23 56250a8f 2021-08-05 op
24 56250a8f 2021-08-05 op ;;; Code:
25 56250a8f 2021-08-05 op (eval-when-compile
26 56250a8f 2021-08-05 op (require 'rx))
27 56250a8f 2021-08-05 op
28 c96779fc 2021-08-05 op (defconst 9ps--font-lock-defaults
29 85a1cbdd 2021-08-05 op (let ((keywords '("assert" "const" "dir" "include" "proc" "testing"))
30 85a1cbdd 2021-08-05 op (types '("str" "u8" "u16" "u32")))
31 85a1cbdd 2021-08-05 op `(((,(rx-to-string `(: (or ,@keywords))) 0 font-lock-keyword-face)
32 85a1cbdd 2021-08-05 op ("\\([[:word:]]+\\)\s*(" 1 font-lock-function-name-face)
33 85a1cbdd 2021-08-05 op (,(rx-to-string `(: (or ,@types))) 0 font-lock-type-face)))))
34 56250a8f 2021-08-05 op
35 56250a8f 2021-08-05 op (defvar 9ps-mode-syntax-table
36 56250a8f 2021-08-05 op (let ((st (make-syntax-table)))
37 56250a8f 2021-08-05 op (modify-syntax-entry ?\{ "(}" st)
38 56250a8f 2021-08-05 op (modify-syntax-entry ?\} "){" st)
39 56250a8f 2021-08-05 op (modify-syntax-entry ?\( "()" st)
40 a1ccf514 2021-08-05 op
41 56250a8f 2021-08-05 op ;; - and _ are word constituent
42 56250a8f 2021-08-05 op (modify-syntax-entry ?_ "w" st)
43 56250a8f 2021-08-05 op (modify-syntax-entry ?- "w" st)
44 a1ccf514 2021-08-05 op
45 56250a8f 2021-08-05 op ;; both single and double quotes makes strings
46 56250a8f 2021-08-05 op (modify-syntax-entry ?\" "\"" st)
47 56250a8f 2021-08-05 op (modify-syntax-entry ?' "'" st)
48 a1ccf514 2021-08-05 op
49 56250a8f 2021-08-05 op ;; one day we'll have escaping (maybe)
50 56250a8f 2021-08-05 op (modify-syntax-entry ?\\ "\\" st)
51 a1ccf514 2021-08-05 op
52 a1ccf514 2021-08-05 op ;; add comments. lua-mode does something similar, so it shouldn't
53 a1ccf514 2021-08-05 op ;; bee *too* wrong.
54 56250a8f 2021-08-05 op (modify-syntax-entry ?# "<" st)
55 56250a8f 2021-08-05 op (modify-syntax-entry ?\n ">" st)
56 a1ccf514 2021-08-05 op
57 a1ccf514 2021-08-05 op ;; '==' as punctuation
58 a1ccf514 2021-08-05 op (modify-syntax-entry ?= ".")
59 56250a8f 2021-08-05 op st))
60 56250a8f 2021-08-05 op
61 56250a8f 2021-08-05 op (defun 9ps-indent-line ()
62 56250a8f 2021-08-05 op "Indent current line."
63 56250a8f 2021-08-05 op (let (indent
64 56250a8f 2021-08-05 op boi-p ;begin of indent
65 56250a8f 2021-08-05 op move-eol-p
66 56250a8f 2021-08-05 op (point (point)))
67 56250a8f 2021-08-05 op (save-excursion
68 56250a8f 2021-08-05 op (back-to-indentation)
69 56250a8f 2021-08-05 op (setq indent (car (syntax-ppss))
70 56250a8f 2021-08-05 op boi-p (= point (point)))
71 27b5fcdd 2021-08-06 op ;; don't indent empty lines if they don't have the in it
72 56250a8f 2021-08-05 op (when (and (eq (char-after) ?\n)
73 56250a8f 2021-08-05 op (not boi-p))
74 56250a8f 2021-08-05 op (setq indent 0))
75 56250a8f 2021-08-05 op ;; check whether we want to move to the end of line
76 27b5fcdd 2021-08-06 op (when boi-p
77 56250a8f 2021-08-05 op (setq move-eol-p t))
78 56250a8f 2021-08-05 op ;; decrement the indent if the first character on the line is a
79 56250a8f 2021-08-05 op ;; closer.
80 56250a8f 2021-08-05 op (when (or (eq (char-after) ?\))
81 56250a8f 2021-08-05 op (eq (char-after) ?\}))
82 56250a8f 2021-08-05 op (setq indent (1- indent)))
83 56250a8f 2021-08-05 op ;; indent the line
84 56250a8f 2021-08-05 op (delete-region (line-beginning-position)
85 56250a8f 2021-08-05 op (point))
86 56250a8f 2021-08-05 op (indent-to (* tab-width indent)))
87 56250a8f 2021-08-05 op (when move-eol-p
88 56250a8f 2021-08-05 op (move-end-of-line nil))))
89 56250a8f 2021-08-05 op
90 7add5f7b 2021-08-05 op (defvar 9ps-mode-abbrev-table nil
91 7add5f7b 2021-08-05 op "Abbreviation table used in `9ps-mode' buffers.")
92 7add5f7b 2021-08-05 op
93 7add5f7b 2021-08-05 op (define-abbrev-table '9ps-mode-abbrev-table
94 7add5f7b 2021-08-05 op '())
95 7add5f7b 2021-08-05 op
96 56250a8f 2021-08-05 op ;;;###autoload
97 56250a8f 2021-08-05 op (define-derived-mode 9ps-mode prog-mode "9ps"
98 56250a8f 2021-08-05 op "Major mode for ninepscript files."
99 7add5f7b 2021-08-05 op :abbrev-table 9ps-mode-abbrev-table
100 c96779fc 2021-08-05 op (setq font-lock-defaults 9ps--font-lock-defaults)
101 56250a8f 2021-08-05 op (setq-local comment-start "#")
102 56250a8f 2021-08-05 op (setq-local comment-start-skip "#+[\t ]*")
103 f1617022 2021-08-05 op (setq-local indent-line-function #'9ps-indent-line)
104 f1617022 2021-08-05 op (setq-local indent-tabs-mode t))
105 56250a8f 2021-08-05 op
106 56250a8f 2021-08-05 op ;;;###autoload
107 56250a8f 2021-08-05 op (add-to-list 'auto-mode-alist '("\\.9ps" . 9ps-mode))
108 56250a8f 2021-08-05 op
109 56250a8f 2021-08-05 op (provide '9ps-mode)
110 56250a8f 2021-08-05 op ;;; 9ps-mode.el ends here