1
+ // Declare global variables to avoid warnings in JSHint
2
+ /* global CodeMirror, define */
3
+
4
+ ( function ( mod ) {
5
+ if ( typeof exports === "object" && typeof module === "object" ) // CommonJS
6
+ mod ( require ( "codemirror/lib/codemirror" ) ) ;
7
+ else if ( typeof define === "function" && define . amd ) // AMD
8
+ define ( [ "codemirror/lib/codemirror" ] , mod ) ;
9
+ else // Plain browser env
10
+ mod ( CodeMirror ) ;
11
+ } ) ( function ( CodeMirror ) {
12
+ "use strict" ;
13
+
14
+ CodeMirror . defineMode ( "aql" , function ( config ) {
15
+ var indentUnit = config . indentUnit ;
16
+ var curPunc ;
17
+
18
+ // ops and keywords taken from ArangoDB UI code:
19
+ // https://github.com/arangodb/arangodb/blob/devel/js/apps/system/_admin/aardvark/APP/react/public/assets/src/mode-aql.js
20
+ function wordRegexp ( words ) {
21
+ return new RegExp ( "^(?:" + words + ")$" , "i" ) ;
22
+ }
23
+ var ops = wordRegexp (
24
+ "to_bool|to_number|to_string|to_array|to_list|is_null|is_bool|is_number|is_string|is_array|is_list|is_object|is_document|is_datestring|" +
25
+ "typename|json_stringify|json_parse|concat|concat_separator|char_length|lower|upper|substring|left|right|trim|reverse|contains|" +
26
+ "log|log2|log10|exp|exp2|sin|cos|tan|asin|acos|atan|atan2|radians|degrees|pi|regex_test|regex_replace|" +
27
+ "like|floor|ceil|round|abs|rand|sqrt|pow|length|count|min|max|average|avg|sum|product|median|variance_population|variance_sample|variance|" +
28
+ "bit_and|bit_or|bit_xor|bit_negate|bit_test|bit_popcount|bit_shift_left|bit_shift_right|bit_construct|bit_deconstruct|bit_to_string|bit_from_string|" +
29
+ "first|last|unique|outersection|interleave|in_range|jaccard|matches|merge|merge_recursive|has|attributes|values|unset|unset_recursive|keep|" +
30
+ "near|within|within_rectangle|is_in_polygon|distance|fulltext|stddev_sample|stddev_population|stddev|" +
31
+ "slice|nth|position|contains_array|translate|zip|call|apply|push|append|pop|shift|unshift|remove_value|remove_values|" +
32
+ "remove_nth|replace_nth|date_now|date_timestamp|date_iso8601|date_dayofweek|date_year|date_month|date_day|date_hour|" +
33
+ "date_minute|date_second|date_millisecond|date_dayofyear|date_isoweek|date_leapyear|date_quarter|date_days_in_month|date_trunc|date_round|" +
34
+ "date_add|date_subtract|date_diff|date_compare|date_format|date_utctolocal|date_localtoutc|date_timezone|date_timezones|" +
35
+ "fail|passthru|v8|sleep|schema_get|schema_validate|call_greenspun|version|noopt|noeval|not_null|" +
36
+ "first_list|first_document|parse_identifier|current_user|current_database|collection_count|pregel_result|" +
37
+ "collections|document|decode_rev|range|union|union_distinct|minus|intersection|flatten|is_same_collection|check_document|" +
38
+ "ltrim|rtrim|find_first|find_last|split|substitute|ipv4_to_number|ipv4_from_number|is_ipv4|md5|sha1|sha512|crc32|fnv64|hash|random_token|to_base64|" +
39
+ "to_hex|encode_uri_component|soundex|assert|warn|is_key|sorted|sorted_unique|count_distinct|count_unique|" +
40
+ "levenshtein_distance|levenshtein_match|regex_matches|regex_split|ngram_match|ngram_similarity|ngram_positional_similarity|uuid|" +
41
+ "tokens|exists|starts_with|phrase|min_match|boost|analyzer|" +
42
+ "geo_point|geo_multipoint|geo_polygon|geo_multipolygon|geo_linestring|geo_multilinestring|geo_contains|geo_intersects|" +
43
+ "geo_equals|geo_distance|geo_area|geo_in_range"
44
+ ) ;
45
+
46
+ var keywords = wordRegexp (
47
+ "for|return|filter|search|sort|limit|let|collect|asc|desc|in|into|insert|update|remove|replace|upsert|options|with|and|or|not|distinct|graph|shortest_path|outbound|inbound|any|all|none|aggregate|like|k_shortest_paths|k_paths|prune|window" +
48
+ "|" +
49
+ "search|keep|to|prune|options"
50
+ ) ;
51
+ var operatorChars = / [ * + \- < > = & | \^ \/ ! \? ] / ;
52
+ var PN_CHARS = "[A-Za-z_\\-0-9]" ;
53
+ var PREFIX_START = new RegExp ( "[A-Za-z]" ) ;
54
+ var PREFIX_REMAINDER = new RegExp ( "((" + PN_CHARS + "|\\.)*(" + PN_CHARS + "))?:" ) ;
55
+
56
+ function tokenComment ( stream , state ) {
57
+ var maybeEnd = false , ch ;
58
+ while ( ch = stream . next ( ) ) {
59
+ if ( ch == "/" && maybeEnd ) {
60
+ state . tokenize = null ;
61
+ break ;
62
+ }
63
+ maybeEnd = ( ch == "*" ) ;
64
+ }
65
+ return "comment" ;
66
+ }
67
+
68
+ function tokenBase ( stream , state ) {
69
+ var ch = stream . next ( ) ;
70
+ curPunc = null ;
71
+ if ( ch == "<" && ! stream . match ( / ^ [ \s \u00a0 = ] / , false ) ) {
72
+ stream . match ( / ^ [ ^ \s \u00a0 > ] * > ? / ) ;
73
+ return "atom" ;
74
+ }
75
+ else if ( ch == "\"" || ch == "'" || ch == "`" || ch == "´" ) {
76
+ state . tokenize = tokenLiteral ( ch ) ;
77
+ return state . tokenize ( stream , state ) ;
78
+ }
79
+ else if ( / [ { } \( \) , \. ; \[ \] ] / . test ( ch ) ) {
80
+ curPunc = ch ;
81
+ return "bracket" ;
82
+ }
83
+ else if ( ch == "/" ) {
84
+ if ( stream . eat ( "*" ) ) {
85
+ state . tokenize = tokenComment ;
86
+ return state . tokenize ( stream , state ) ;
87
+ }
88
+ if ( stream . eat ( "/" ) ) {
89
+ stream . skipToEnd ( ) ;
90
+ return "comment" ;
91
+ }
92
+ }
93
+ else if ( operatorChars . test ( ch ) ) {
94
+ return "operator" ;
95
+ }
96
+ else if ( ch == ":" ) {
97
+ eatPnLocal ( stream ) ;
98
+ return "atom" ;
99
+ }
100
+ else if ( ch == "@" ) {
101
+ stream . eatWhile ( / [ a - z \d \- ] / i) ;
102
+ return "meta" ;
103
+ }
104
+ else if ( PREFIX_START . test ( ch ) && stream . match ( PREFIX_REMAINDER ) ) {
105
+ eatPnLocal ( stream ) ;
106
+ return "atom" ;
107
+ }
108
+ stream . eatWhile ( / [ _ \w \d ] / ) ;
109
+ var word = stream . current ( ) ;
110
+ if ( ops . test ( word ) )
111
+ return "builtin" ;
112
+ else if ( keywords . test ( word ) )
113
+ return "keyword" ;
114
+ else
115
+ return "variable" ;
116
+ }
117
+
118
+ function eatPnLocal ( stream ) {
119
+ stream . match ( / ( \. (? = [ \w _ \- \\ % ] ) | [: \w _ - ] | \\ [ - \\ _ ~ . ! $ & ' ( ) * + , ; = / ? # @ % ] | % [ a - f \d ] [ a - f \d ] ) + / i) ;
120
+ }
121
+
122
+ function tokenLiteral ( quote ) {
123
+ return function ( stream , state ) {
124
+ var escaped = false , ch ;
125
+ while ( ( ch = stream . next ( ) ) != null ) {
126
+ if ( ch == quote && ! escaped ) {
127
+ state . tokenize = tokenBase ;
128
+ break ;
129
+ }
130
+ escaped = ! escaped && ch == "\\" ;
131
+ }
132
+ return "string" ;
133
+ } ;
134
+ }
135
+
136
+ function pushContext ( state , type , col ) {
137
+ state . context = { prev : state . context , indent : state . indent , col : col , type : type } ;
138
+ }
139
+ function popContext ( state ) {
140
+ state . indent = state . context . indent ;
141
+ state . context = state . context . prev ;
142
+ }
143
+
144
+ return {
145
+ startState : function ( ) {
146
+ return { tokenize : tokenBase ,
147
+ context : null ,
148
+ indent : 0 ,
149
+ col : 0 } ;
150
+ } ,
151
+
152
+ token : function ( stream , state ) {
153
+ if ( stream . sol ( ) ) {
154
+ if ( state . context && state . context . align == null ) state . context . align = false ;
155
+ state . indent = stream . indentation ( ) ;
156
+ }
157
+ if ( stream . eatSpace ( ) ) return null ;
158
+ var style = ( state . tokenize || tokenBase ) ( stream , state ) ;
159
+
160
+ if ( style != "comment" && state . context && state . context . align == null && state . context . type != "pattern" ) {
161
+ state . context . align = true ;
162
+ }
163
+
164
+ if ( curPunc == "(" ) pushContext ( state , ")" , stream . column ( ) ) ;
165
+ else if ( curPunc == "[" ) pushContext ( state , "]" , stream . column ( ) ) ;
166
+ else if ( curPunc == "{" ) pushContext ( state , "}" , stream . column ( ) ) ;
167
+ else if ( / [ \] \} \) ] / . test ( curPunc ) ) {
168
+ while ( state . context && state . context . type == "pattern" ) popContext ( state ) ;
169
+ if ( state . context && curPunc == state . context . type ) {
170
+ popContext ( state ) ;
171
+ if ( curPunc == "}" && state . context && state . context . type == "pattern" )
172
+ popContext ( state ) ;
173
+ }
174
+ }
175
+ else if ( curPunc == "." && state . context && state . context . type == "pattern" ) popContext ( state ) ;
176
+ else if ( / a t o m | s t r i n g | v a r i a b l e / . test ( style ) && state . context ) {
177
+ if ( / [ \} \] ] / . test ( state . context . type ) )
178
+ pushContext ( state , "pattern" , stream . column ( ) ) ;
179
+ else if ( state . context . type == "pattern" && ! state . context . align ) {
180
+ state . context . align = true ;
181
+ state . context . col = stream . column ( ) ;
182
+ }
183
+ }
184
+
185
+ return style ;
186
+ } ,
187
+
188
+ indent : function ( state , textAfter ) {
189
+ var firstChar = textAfter && textAfter . charAt ( 0 ) ;
190
+ var context = state . context ;
191
+ if ( / [ \] \} ] / . test ( firstChar ) )
192
+ while ( context && context . type == "pattern" ) context = context . prev ;
193
+
194
+ var closing = context && firstChar == context . type ;
195
+ if ( ! context )
196
+ return 0 ;
197
+ else if ( context . type == "pattern" )
198
+ return context . col ;
199
+ else if ( context . align )
200
+ return context . col + ( closing ? 0 : 1 ) ;
201
+ else
202
+ return context . indent + ( closing ? 0 : indentUnit ) ;
203
+ } ,
204
+
205
+ blockCommentStart : "/*" ,
206
+ blockCommentEnd : "*/" ,
207
+ lineComment : "//"
208
+ } ;
209
+ } ) ;
210
+
211
+ CodeMirror . defineMIME ( "text/x-aql" , "aql" ) ;
212
+
213
+
214
+ } ) ;
0 commit comments