Skip to content

Instantly share code, notes, and snippets.

@allenh1
Last active November 1, 2024 13:35
Show Gist options
  • Select an option

  • Save allenh1/5dd4476943b24f3bdc3b4979f123082a to your computer and use it in GitHub Desktop.

Select an option

Save allenh1/5dd4476943b24f3bdc3b4979f123082a to your computer and use it in GitHub Desktop.
sl major mode
;;; 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