-
Notifications
You must be signed in to change notification settings - Fork 5
/
clojure.el
110 lines (97 loc) · 4.51 KB
/
clojure.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
106
107
108
109
(require 'semantic/wisent)
(require ';; semantic/wisent/
clojure-wy)
(defcustom wisent-clojure-user-def-macros nil
"A list of names for the user's own Clojure macros that defines variables."
:type '(repeat string)
:group 'wisent-clojure)
(defvar wisent-clojure-def-regexp (regexp-opt (append
'("def" "def-" "defonce" "defonce-"
"defstruct-" "defunbound"
"defunbound-"
"defvar" "defvar-"
"defrecord"
"defstruct" "deftype" "defprotocol"
"defalias" "defhinted")
wisent-clojure-user-def-macros)))
(defcustom wisent-clojure-user-defn-macros nil
"A list of names for the user's own Clojure macros that defines functions."
:type '(repeat string)
:group 'wisent-clojure)
(defvar wisent-clojure-defn-regexp (regexp-opt (append
'("defn" "defn-"
"defmulti" "defmethod" "defmacro"
"deftest"
"defmacro-"
"defn-memo" "defnk")
wisent-clojure-user-defn-macros)))
(define-lex-simple-regex-analyzer wisent-clojure-lex-deffunc
"Detect functions and macros."
wisent-clojure-defn-regexp 'DEFN)
(define-lex-simple-regex-analyzer wisent-clojure-lex-defvar
"Detect variables."
wisent-clojure-def-regexp 'DEF)
(define-lex-simple-regex-analyzer wisent-clojure-lex-defproject
"Detect projects definition."
"defproject" 'DEFPROJECT)
(define-lex-regex-analyzer wisent-clojure-lex-reader
"Detect reader macros or metadata symbol."
"\\(#[^ ]\\|\\^\\|`\\|'\\|~@\\|~\\|\\\\.\\|@\\)"
(let* ((matched (match-string-no-properties 0))
(token-type (cond ((string= matched "^") 'METADATA)
((string= matched "`") 'BACKQUOTE)
((string= matched "'") 'QUOTE)
((string= (substring matched 0 1) "\\") 'CHARACTER)
((string= matched "~") 'UNQUOTE)
((string= matched "~@") 'UNQUOTE_SPLICING)
((string= matched "@") 'DEREF)
((string= matched "#^") 'META_READER)
((string= matched "#'") 'VAR_READER)
((string= matched "#{") 'SET_READER)
((string= matched "#(") 'FN_READER)
((string= matched "#=") 'EVAL_READER)
((string= matched "#!") 'COMMENT_READER)
((string= matched "#<") 'UNREADABLE_READER)
((string= matched "#_") 'DISCARD_READER)
(t 'UNKNOWN_READER))))
(semantic-lex-push-token
(semantic-lex-token
token-type
(match-beginning 0) (match-end 0)))))
(define-lex-regex-analyzer wisent-clojure-lex-clj-symbol
"Detect Clojure symbols."
"\\([^][(){}\"\n\t ]+\\)"
(let* ((matched (match-string-no-properties 0))
(token-type (cond ((string= matched "ns") 'NS)
(t 'SYMBOL))))
(semantic-lex-push-token
(semantic-lex-token
token-type
(match-beginning 0) (match-end 0)))))
;; Define the lexer for this grammar
(define-lex wisent-clojure-lexer
"Lexical analyzer that handles Clojure buffers.
It ignores whitespaces, newlines and comments."
semantic-lex-ignore-whitespace
semantic-lex-ignore-newline
semantic-lex-ignore-comments
;;; our own lexers:
wisent-clojure-lex-reader
wisent-clojure-lex-defproject
wisent-clojure-lex-deffunc
wisent-clojure-lex-defvar
wisent-clojure-lex-clj-symbol
;;;; Auto-generated analyzers.
wisent-clojure-wy--<number>-regexp-analyzer
wisent-clojure-wy--<string>-sexp-analyzer
wisent-clojure-wy--<block>-block-analyzer
semantic-lex-default-action)
(defun wisent-clojure-default-setup ()
"Hook run to setup Semantic in `clojure-mode'."
(wisent-clojure-wy--install-parser)
(setq
;; Lexical analysis
;; semantic-lex-depth nil
semantic-lex-analyzer 'wisent-clojure-lexer))
(add-to-list 'semantic-new-buffer-setup-functions
(cons 'clojure-mode 'wisent-clojure-default-setup))