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 6e2f0534 2021-08-07 op (let ((keywords '("assert" "const" "dir" "include" "proc" "should-fail"
30 7d1b6186 2021-08-07 op "testing" "vargs"))
31 85a1cbdd 2021-08-05 op (types '("str" "u8" "u16" "u32")))
32 85a1cbdd 2021-08-05 op `(((,(rx-to-string `(: (or ,@keywords))) 0 font-lock-keyword-face)
33 85a1cbdd 2021-08-05 op ("\\([[:word:]]+\\)\s*(" 1 font-lock-function-name-face)
34 85a1cbdd 2021-08-05 op (,(rx-to-string `(: (or ,@types))) 0 font-lock-type-face)))))
35 56250a8f 2021-08-05 op
36 56250a8f 2021-08-05 op (defvar 9ps-mode-syntax-table
37 56250a8f 2021-08-05 op (let ((st (make-syntax-table)))
38 56250a8f 2021-08-05 op (modify-syntax-entry ?\{ "(}" st)
39 56250a8f 2021-08-05 op (modify-syntax-entry ?\} "){" st)
40 56250a8f 2021-08-05 op (modify-syntax-entry ?\( "()" st)
41 a1ccf514 2021-08-05 op
42 56250a8f 2021-08-05 op ;; - and _ are word constituent
43 56250a8f 2021-08-05 op (modify-syntax-entry ?_ "w" st)
44 56250a8f 2021-08-05 op (modify-syntax-entry ?- "w" st)
45 a1ccf514 2021-08-05 op
46 56250a8f 2021-08-05 op ;; both single and double quotes makes strings
47 56250a8f 2021-08-05 op (modify-syntax-entry ?\" "\"" st)
48 56250a8f 2021-08-05 op (modify-syntax-entry ?' "'" st)
49 a1ccf514 2021-08-05 op
50 56250a8f 2021-08-05 op ;; one day we'll have escaping (maybe)
51 56250a8f 2021-08-05 op (modify-syntax-entry ?\\ "\\" st)
52 a1ccf514 2021-08-05 op
53 a1ccf514 2021-08-05 op ;; add comments. lua-mode does something similar, so it shouldn't
54 a1ccf514 2021-08-05 op ;; bee *too* wrong.
55 56250a8f 2021-08-05 op (modify-syntax-entry ?# "<" st)
56 56250a8f 2021-08-05 op (modify-syntax-entry ?\n ">" st)
57 a1ccf514 2021-08-05 op
58 a1ccf514 2021-08-05 op ;; '==' as punctuation
59 a1ccf514 2021-08-05 op (modify-syntax-entry ?= ".")
60 56250a8f 2021-08-05 op st))
61 56250a8f 2021-08-05 op
62 56250a8f 2021-08-05 op (defun 9ps-indent-line ()
63 56250a8f 2021-08-05 op "Indent current line."
64 56250a8f 2021-08-05 op (let (indent
65 56250a8f 2021-08-05 op boi-p ;begin of indent
66 56250a8f 2021-08-05 op move-eol-p
67 56250a8f 2021-08-05 op (point (point)))
68 56250a8f 2021-08-05 op (save-excursion
69 56250a8f 2021-08-05 op (back-to-indentation)
70 56250a8f 2021-08-05 op (setq indent (car (syntax-ppss))
71 56250a8f 2021-08-05 op boi-p (= point (point)))
72 27b5fcdd 2021-08-06 op ;; don't indent empty lines if they don't have the in it
73 56250a8f 2021-08-05 op (when (and (eq (char-after) ?\n)
74 56250a8f 2021-08-05 op (not boi-p))
75 56250a8f 2021-08-05 op (setq indent 0))
76 56250a8f 2021-08-05 op ;; check whether we want to move to the end of line
77 27b5fcdd 2021-08-06 op (when boi-p
78 56250a8f 2021-08-05 op (setq move-eol-p t))
79 56250a8f 2021-08-05 op ;; decrement the indent if the first character on the line is a
80 56250a8f 2021-08-05 op ;; closer.
81 56250a8f 2021-08-05 op (when (or (eq (char-after) ?\))
82 56250a8f 2021-08-05 op (eq (char-after) ?\}))
83 56250a8f 2021-08-05 op (setq indent (1- indent)))
84 56250a8f 2021-08-05 op ;; indent the line
85 56250a8f 2021-08-05 op (delete-region (line-beginning-position)
86 56250a8f 2021-08-05 op (point))
87 56250a8f 2021-08-05 op (indent-to (* tab-width indent)))
88 56250a8f 2021-08-05 op (when move-eol-p
89 56250a8f 2021-08-05 op (move-end-of-line nil))))
90 56250a8f 2021-08-05 op
91 7add5f7b 2021-08-05 op (defvar 9ps-mode-abbrev-table nil
92 7add5f7b 2021-08-05 op "Abbreviation table used in `9ps-mode' buffers.")
93 7add5f7b 2021-08-05 op
94 7add5f7b 2021-08-05 op (define-abbrev-table '9ps-mode-abbrev-table
95 7add5f7b 2021-08-05 op '())
96 7add5f7b 2021-08-05 op
97 56250a8f 2021-08-05 op ;;;###autoload
98 56250a8f 2021-08-05 op (define-derived-mode 9ps-mode prog-mode "9ps"
99 56250a8f 2021-08-05 op "Major mode for ninepscript files."
100 7add5f7b 2021-08-05 op :abbrev-table 9ps-mode-abbrev-table
101 c96779fc 2021-08-05 op (setq font-lock-defaults 9ps--font-lock-defaults)
102 56250a8f 2021-08-05 op (setq-local comment-start "#")
103 56250a8f 2021-08-05 op (setq-local comment-start-skip "#+[\t ]*")
104 f1617022 2021-08-05 op (setq-local indent-line-function #'9ps-indent-line)
105 f1617022 2021-08-05 op (setq-local indent-tabs-mode t))
106 56250a8f 2021-08-05 op
107 56250a8f 2021-08-05 op ;;;###autoload
108 56250a8f 2021-08-05 op (add-to-list 'auto-mode-alist '("\\.9ps" . 9ps-mode))
109 56250a8f 2021-08-05 op
110 56250a8f 2021-08-05 op (provide '9ps-mode)
111 56250a8f 2021-08-05 op ;;; 9ps-mode.el ends here