Skip to content

Commit

Permalink
Extend syntax highlighting in emacs + Vim config (#1890)
Browse files Browse the repository at this point in the history
Changes include:
- Refactor `swarm-mode.el`
  - Everything doesn't need to be in one `let` binding inside a `setq` function. I've split
    into `defvar`s depending on the type. Eg: `swarm-mode-commands-regexp` defines
    all the commands in swarm game with `regex-opt` on them.
- Add syntax highlighting for operators like `->`, `=`, `+`, `:` etc. This is Haskell-ish.
- Make syntax highlighting respect case sensitivity.
- Add `autoload` macro to `define-derived-mode` since it defines the syntax table and syntax related variables.
- Add `commentary` section in top level comments as emacs convention.
- Update Vim config in order for syntax highlighting to be case sensitive for types.

Before:
![CleanShot 2024-06-02 at 20 55 47@2x](https://github.com/swarm-game/swarm/assets/15181803/251f85bb-e97e-4e9a-9157-34d2b8d0d4bf)

After:
![CleanShot 2024-06-02 at 20 52 12@2x](https://github.com/swarm-game/swarm/assets/15181803/7873847f-ebea-4143-8843-64a7cf8ebd09)


In order to test locally:
1. Open `swarm-mode.el` in emacs. Then `M-x eval-buffer`
2. Then open up any `.sw` file and `M-x swarm-mode`
  • Loading branch information
nitinprakash96 authored Jun 3, 2024
1 parent ca4a2b8 commit 4e7b2f4
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 132 deletions.
281 changes: 150 additions & 131 deletions editors/emacs/swarm-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -7,151 +7,170 @@
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;; This package provides major mode for the Swarm programming language.
;;
;;
;;; Code:

(require 'lsp-mode)

(defvar swarm-mode-syntax-table nil "Syntax table for `swarm-mode'.")
(defvar swarm-mode-syntax-table
(let ((synTable (make-syntax-table)))
;; C++ style comments ("// ..." and "/* ... */")
(modify-syntax-entry ?\/ ". 124b" synTable)
(modify-syntax-entry ?* ". 23" synTable)
(modify-syntax-entry ?\n "> b" synTable)
synTable)
"Syntax table for `swarm-mode'.")

(setq swarm-mode-syntax-table
(let ( (synTable (make-syntax-table)))
(defvar swarm-mode-operators-regexp
(regexp-opt '(":" "->" "=" "<-" "+" "*" "/" "-") t)
"Regexp that recognizes operators for swarm language.")

;; C++ style comments ("// ..." and "/* ... */")
(modify-syntax-entry ?\/ ". 124" synTable)
(modify-syntax-entry ?* ". 23b" synTable)
(modify-syntax-entry ?\n "> " synTable)
(defvar swarm-mode-commands-regexp
(concat
"\\b"
(regexp-opt
'(
"noop"
"wait"
"selfdestruct"
"move"
"backup"
"volume"
"path"
"push"
"stride"
"turn"
"grab"
"harvest"
"sow"
"ignite"
"place"
"ping"
"give"
"equip"
"unequip"
"make"
"has"
"equipped"
"count"
"drill"
"use"
"build"
"salvage"
"reprogram"
"say"
"listen"
"log"
"view"
"appear"
"create"
"halt"
"time"
"scout"
"whereami"
"waypoint"
"structure"
"floorplan"
"hastag"
"tagmembers"
"detect"
"resonate"
"density"
"sniff"
"chirp"
"watch"
"surveil"
"heading"
"blocked"
"scan"
"upload"
"ishere"
"isempty"
"meet"
"meetall"
"whoami"
"setname"
"random"
"run"
"return"
"try"
"swap"
"atomic"
"instant"
"installkeyhandler"
"teleport"
"as"
"robotnamed"
"robotnumbered"
"knows"
"east"
"north"
"west"
"south"
"down"
"forward"
"left"
"back"
"right"
)
t)
"\\b")
"Regexp that recognizes commands for swarm.")

synTable))
(defvar swarm-mode-builtins-regexp
(concat
"\\b"
(regexp-opt
'(
"self"
"parent"
"base"
"if"
"inl"
"inr"
"case"
"fst"
"snd"
"force"
"undefined"
"fail"
"not"
"format"
"chars"
"split"
"charat"
"tochar"
"key"
)
t)
"\\b" )
"Regexp that recognizes builtin for swarm language.")

(setq swarm-font-lock-keywords
(let* (
;; Generate the current keywords with:
;; cabal run swarm:swarm-docs -- editors --emacs
(x-keywords '("def" "tydef" "end" "let" "in" "require"))
(x-builtins '(
"self"
"parent"
"base"
"if"
"inl"
"inr"
"case"
"fst"
"snd"
"force"
"undefined"
"fail"
"not"
"format"
"chars"
"split"
"charat"
"tochar"
"key"
))
(x-commands '(
"noop"
"wait"
"selfdestruct"
"move"
"backup"
"volume"
"path"
"push"
"stride"
"turn"
"grab"
"harvest"
"sow"
"ignite"
"place"
"ping"
"give"
"equip"
"unequip"
"make"
"has"
"equipped"
"count"
"drill"
"use"
"build"
"salvage"
"reprogram"
"say"
"listen"
"log"
"view"
"appear"
"create"
"halt"
"time"
"scout"
"whereami"
"waypoint"
"structure"
"floorplan"
"hastag"
"tagmembers"
"detect"
"resonate"
"density"
"sniff"
"chirp"
"watch"
"surveil"
"heading"
"blocked"
"scan"
"upload"
"ishere"
"isempty"
"meet"
"meetall"
"whoami"
"setname"
"random"
"run"
"return"
"try"
"swap"
"atomic"
"instant"
"installkeyhandler"
"teleport"
"as"
"robotnamed"
"robotnumbered"
"knows"
"east"
"north"
"west"
"south"
"down"
"forward"
"left"
"back"
"right"
))
(x-types '("int" "text" "dir" "bool" "cmd" "void" "unit" "actor"))
(defvar swarm-mode-types-regexp
"\\b[A-Z][a-zA-Z_]*\\b"
"Regexp that recognizes types (all uppercase strings are supposed to be types) in swarm language.")

(x-keywords-regexp (regexp-opt x-keywords 'words))
(x-builtins-regexp (regexp-opt x-builtins 'words))
(x-commands-regexp (regexp-opt x-commands 'words))
(x-types-regexp (regexp-opt x-types 'words)))
(defvar swarm-mode-keywords-regexp
(concat "\\b" (regexp-opt '("def" "tydef" "end" "let" "in" "require") t) "\\b")
"Regexp that recognizes keywords in swarm language.")

`(
(,x-keywords-regexp . 'font-lock-keyword-face)
(,x-builtins-regexp . 'font-lock-builtin-face)
(,x-types-regexp . 'font-lock-type-face)
(,x-commands-regexp . 'font-lock-constant-face)
("[a-z_][a-z0-9_]*" . 'font-lock-function-name-face)
)))
(defvar swarm-font-lock-keywords
`((,swarm-mode-types-regexp . 'font-lock-type-face)
(,swarm-mode-keywords-regexp . 'font-lock-keyword-face)
(,swarm-mode-builtins-regexp . 'font-lock-builtin-face)
(,swarm-mode-commands-regexp . 'font-lock-constant-face)
(,swarm-mode-operators-regexp . 'font-lock-variable-name-face)))

;;;###autoload
(define-derived-mode swarm-mode prog-mode "Swarm Lang Mode"
(setq font-lock-defaults '((swarm-font-lock-keywords) nil t nil))
"Major mode for editing Swarm language files."
(setq font-lock-defaults '((swarm-font-lock-keywords)))
(set-syntax-table swarm-mode-syntax-table))

;;;###autoload
(add-to-list 'auto-mode-alist '("\\.sw\\'" . swarm-mode))

(with-eval-after-load 'lsp-mode
Expand Down
2 changes: 1 addition & 1 deletion editors/vim/swarm.vim
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ syn keyword Keyword def tydef end let in require
syn keyword Builtins self parent base if inl inr case fst snd force undefined fail not format chars split charat tochar key
syn keyword Command noop wait selfdestruct move backup volume path push stride turn grab harvest sow ignite place ping give equip unequip make has equipped count drill use build salvage reprogram say listen log view appear create halt time scout whereami waypoint structure floorplan hastag tagmembers detect resonate density sniff chirp watch surveil heading blocked scan upload ishere isempty meet meetall whoami setname random run return try swap atomic instant installkeyhandler teleport as robotnamed robotnumbered knows
syn keyword Direction east north west south down forward left back right
syn keyword Type int text dir bool cmd void unit actor
syn keyword Type "\<[A-Z][a-zA-Z_]*\>"


syn match Comment "//.*$"
Expand Down

0 comments on commit 4e7b2f4

Please sign in to comment.