diff --git a/CHANGELOG.md b/CHANGELOG.md index 88afd31011c5..65e94ed38a5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Add syntax highlight file for KSyntaxHighlighting. (@vanillajonathan, #5177) - Add syntax highlight file for Vim. (@vanillajonathan, #5185) +- Add syntax highlight file for GNU Emacs. (@vanillajonathan, #5189) **Internal changes**: diff --git a/grammars/README.md b/grammars/README.md index e7c929f593ad..564a642ff44a 100644 --- a/grammars/README.md +++ b/grammars/README.md @@ -23,6 +23,9 @@ an index. file is at [`grammars/prql-lezer/README.md`](https://github.com/PRQL/prql/tree/main/grammars/prql-lezer/README.md). +- emacs — used by terminal-based text editor GNU Emacs. File is at + [`grammars/emacs/`](https://github.com/PRQL/prql/tree/main/grammars/emacs/). + - GtkSourceView — used by GNOME Text Editor, GNOME Builder and other GTK applications. File is at [`grammars/GtkSourceView/`](https://github.com/PRQL/prql/tree/main/grammars/GtkSourceView/). diff --git a/grammars/emacs/README.md b/grammars/emacs/README.md new file mode 100644 index 000000000000..bf68b5b9d08c --- /dev/null +++ b/grammars/emacs/README.md @@ -0,0 +1,18 @@ +# Syntax highlighting for GNU Emacs + +This is a syntax highlighting file for GNU Emacs. + +## Installation + +Copy the `prql-mode.el` file to: + + ~/.emacs.d/custom-modes/ + +Then, edit your `~/emacs.d/init.el` file and add the following: + +```emacs +(add-to-list 'load-path "~/.emacs.d/custom-modes/") +(require 'prql-mode) + +(add-to-list 'auto-mode-alist '("\\.prql\\'" . prql-mode)) +``` diff --git a/grammars/emacs/prql-mode.el b/grammars/emacs/prql-mode.el new file mode 100644 index 000000000000..da70674946b9 --- /dev/null +++ b/grammars/emacs/prql-mode.el @@ -0,0 +1,64 @@ +;; prql-mode.el -- Major mode for PRQL language + +(defvar prql-mode-syntax-table + (let ((table (make-syntax-table))) + ;; Define comment syntax + (modify-syntax-entry ?# "<" table) + (modify-syntax-entry ?\n ">" table) + table) + "Syntax table for `prql-mode'.") + +(defconst prql-constants + '("true" "false" "this" "that" "null") + "List of PRQL constants.") + +(defconst prql-data-types + '("bool" "float" "int" "int8" "int16" "int32" "int64" "int128" "text" "date" "time" "timestamp") + "List of PRQL data types.") + +(defconst prql-builtin-functions + '("aggregate" "derive" "filter" "from" "group" "join" "select" "sort" "take" "window") + "List of PRQL built-in function.") + +(defconst prql-operators + '("!" "=" "&&" "||" + "+" "-" "*" "/" "%" + "<" ">" "~=") + "List of PRQL operators.") + +(defconst prql-numbers + '("0o[0-7]+" + "0x[0-9a-fA-F]+" + "0b[01]+" + "[0-9]+*") + "Regex for matching PRQL numbers.") + +(defconst prql-other-keywords + '("prql" "case" "let" "type" "alias" "in" "loop" "module") + "List of other PRQL keywords.") + +(defvar prql-font-lock-keywords + ;; Define keywords and patterns for highlighting + `( + ,(cons (regexp-opt prql-constants 'words) 'font-lock-constant-face) + ,(cons (regexp-opt prql-other-keywords 'words) 'font-lock-keyword-face) + ,(cons (regexp-opt prql-builtin-functions 'words) 'font-lock-builtin-face) + ,(cons (regexp-opt prql-data-types 'words) 'font-lock-type-face) + ,@(mapcar (lambda (kw) (cons kw 'font-lock-builtin-face)) prql-operators) + ,@(mapcar (lambda (kw) (cons kw 'font-lock-constant-face)) prql-numbers) + )) + +(define-derived-mode prql-mode prog-mode "PRQL" + "Major mode for editing PRQL code." + ;; Set the syntax table + (set-syntax-table prql-mode-syntax-table) + ;; Set font lock keywords + (setq font-lock-defaults '((prql-font-lock-keywords))) + ;; Enable automatic indentation + (setq indent-tabs-mode nil) + (setq tab-width 2)) + +;; Add the mode to the auto-mode-alist for .prql files +(add-to-list 'auto-mode-alist '("\\.prql\\'" . prql-mode)) + +(provide 'prql-mode)