Last active
November 1, 2024 13:35
-
-
Save allenh1/5dd4476943b24f3bdc3b4979f123082a to your computer and use it in GitHub Desktop.
sl major mode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;;; sl-mode.el --- major mode for sl -*- lexical-binding: t; -*- | |
| ;; inspired by https://www.omarpolo.com/post/writing-a-major-mode.html | |
| (eval-when-compile | |
| (require 'rx)) | |
| (defconst sl--font-lock-defaults | |
| (let ((fn-keywords '("defun" "extern")) | |
| (keywords '("defun" "for" "in" "set" "lambda" "let" "cons" "car" "cdr" "and" "or" "xor" "not" "extern" "if")) | |
| (types '("string" "int" "bool" "float" "list"))) | |
| `( | |
| ((,(rx-to-string `(: (or ,@keywords))) 0 font-lock-keyword-face) | |
| (,(rx-to-string `(: (or ,@types))) 0 font-lock-type-face)) | |
| ) | |
| )) | |
| (defvar sl-mode-syntax-table | |
| (let ((st (make-syntax-table))) | |
| (modify-syntax-entry ?\{ "(}" st) | |
| (modify-syntax-entry ?\} "){" st) | |
| (modify-syntax-entry ?\( "()" st) | |
| ;; - and _ are word constituents | |
| (modify-syntax-entry ?_ "w" st) | |
| (modify-syntax-entry ?- "w" st) | |
| (modify-syntax-entry ?\" "\"" st) | |
| ;; add comments. lua-mode does something similar, so it shouldn't | |
| ;; bee *too* wrong. | |
| (modify-syntax-entry ?\; "<" st) | |
| (modify-syntax-entry ?\n ">" st) | |
| ;; '==' as punctuation | |
| (modify-syntax-entry ?= ".") | |
| st)) | |
| (defun sl-indent-line () | |
| "Indent current line." | |
| (let (indent | |
| boi-p ;begin of indent | |
| move-eol-p | |
| (point (point))) ;lisps-2 are truly wonderful | |
| (save-excursion | |
| (back-to-indentation) | |
| (setq indent (car (syntax-ppss)) | |
| boi-p (= point (point))) | |
| ;; don't indent empty lines if they don't have the in it | |
| (when (and (eq (char-after) ?\n) | |
| (not boi-p)) | |
| (setq indent 0)) | |
| ;; check whether we want to move to the end of line | |
| (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) ?\})) | |
| (setq indent (1- indent))) | |
| ;; indent the line | |
| (delete-region (line-beginning-position) | |
| (point)) | |
| (indent-to (* 2 indent))) | |
| (when move-eol-p | |
| (move-end-of-line nil)))) | |
| (defvar sl-mode-abbrev-table nil | |
| "Abbreviation table used in `sl-mode' buffers.") | |
| (define-abbrev-table 'sl-mode-abbrev-table | |
| '()) | |
| (define-derived-mode sl-mode prog-mode "sl" | |
| "Major mode for sl files." | |
| :abbrev-table sl-mode-abbrev-table | |
| (setq font-lock-defaults sl--font-lock-defaults) | |
| (setq-local comment-start ";;") | |
| (setq-local comment-start-skip ";;+[\t ]*") | |
| (setq-local indent-line-function #'sl-indent-line) | |
| (setq-local indent-tabs-mode nil)) | |
| (provide 'sl-mode) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment