-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclean-mode.el
105 lines (84 loc) · 4.22 KB
/
clean-mode.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
;;; clean-mode.el --- Major mode for editing clean language files. -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2017, by Mrinal Purohit
;; Author: Mrinal Purohit ([email protected])
;; Version: 0.0.6
;; Created: 27 Apr 2017
;; Keywords: languages, clean
;; Homepage: https://github.com/cleanlang/clean-mode
;; This file is not part of GNU Emacs.
;;; License:
;; You can redistribute this program and/or modify it under the terms of the GNU General Public License version 3.
;;; Commentary:
;;
;; This mode adds basic support to Emacs for writing software using
;; the Clean programming language, available at:
;;
;; https://github.com/cleanlang/clean
;;
;;
;;; Code:
(require 'cl-lib)
(require 'company)
(defconst clean-mode-version-number "0.0.6"
"Clean Mode version number.")
;; define several category of keywords
(defvar clean-keywords '("if" "then" "else" "return" "in" "let" "do"))
(defvar clean-constants '("false" "true" "null" "node-core" "browser-core"))
(defvar clean-builtins '("getLine" "putLine" "defineProp" "delete" "maybeTrue" "maybeFalse" "maybeNull" "maybeUndefined" "maybeErr" "require" "IO" "print"))
(defvar clean-preprocessors '("include"))
;; generate regex string for each category of keywords
(defvar clean-keywords-regexp (regexp-opt clean-keywords 'words))
(defvar clean-constants-regexp (regexp-opt clean-constants 'words))
(defvar clean-builtins-regexp (regexp-opt clean-builtins 'words))
(defvar clean-preprocessors-regexp (regexp-opt clean-preprocessors 'words))
;; create the list for font-lock.
;; each category of keyword is given a particular face
(defvar clean-font-lock-keywords
`(
(,"^\\(\/\/\\)\\(.*\\)\\(\n\\|\\)$" . font-lock-comment-face) ;; For single line comments of the form // text
(,"\\('[^\\\n']*\\(?:\\.[^\\\n']*\\)*'\\)" . font-lock-string-face) ;; For strings of the form 'val'
(,clean-keywords-regexp . font-lock-keyword-face)
(,clean-constants-regexp . font-lock-constant-face)
(,clean-builtins-regexp . font-lock-builtin-face)
(,clean-preprocessors-regexp . font-lock-preprocessor-face)
(,"\\([a-z]+[a-zA-z]*\\)\\(\\(\s\\(\\([a-z]+\\|[0-9]+\\)[a-zA-Z0-9]*\\)\\)+\\)\\(\s=\\)" (1 font-lock-function-name-face) (2 font-lock-variable-name-face)) ;; For function names of the form `func a b ='
(,"\\([a-z]+[a-zA-Z0-9]*\\)\\(\s=\\)" . (1 font-lock-variable-name-face)) ;; For variables of the form `a ='
(,"\\(\\([a-z]+[a-zA-Z0-9]*\s\\)+\\)\\(<-\\)" . (1 font-lock-variable-name-face)) ;; For variables in reverse bind of the form `req res <-'
;; (,"\\(\\([0-9]+.?[0-9]*\\)\\|\\([0-9]+\\)\\)\\(\\(E\\|e\\)\\(+\\|-\\)?[0-9]+\\)?" . font-lock-warning-face)
;; note: order above matters, because once colored, that part won't change.
;; in general, longer words first
))
(defvar clean-mode-syntax-table nil "Syntax table for `clean-mode'.")
(setq clean-mode-syntax-table
(let ( (synTable (make-syntax-table)))
;; comment style “/* … */”
(modify-syntax-entry ?\/ ". 14" synTable)
(modify-syntax-entry ?* ". 23" synTable)
synTable))
(defun clean-company-backend (command &optional arg &rest ignored)
"Interactive completion insertion where COMMAND is command received.
When ARG is non-nil, compare with keywords for completion.
IGNORED is ignored."
(interactive (list 'interactive))
(cl-case command
(interactive (company-begin-backend 'clean-company-backend))
(prefix (and (eq major-mode 'clean-mode)
(company-grab-symbol)))
(candidates
(cl-remove-if-not
(lambda (c) (string-prefix-p arg c))
(append clean-keywords clean-builtins clean-constants clean-preprocessors)))))
;;;###autoload
(define-derived-mode clean-mode prog-mode "clean"
"clean-mode is a major mode for editing clean language files."
(setq font-lock-defaults '((clean-font-lock-keywords)))
(set-syntax-table clean-mode-syntax-table)
(setq-local comment-start "/*")
(setq-local comment-start-skip "/\\*+[ \t]*")
(setq-local comment-end "*\/")
(setq-local comment-end-skip "[ \t]*\\*+/")
(add-to-list 'company-backends 'clean-company-backend)
(company-mode))
;; add the mode to the `features' list
(provide 'clean)
;;; clean-mode.el ends here