Skip to content

Commit ef3be05

Browse files
committed
more generic highlighting for templates and components
1 parent 974a3bf commit ef3be05

File tree

3 files changed

+193
-2
lines changed

3 files changed

+193
-2
lines changed

Syntaxes/boxlang-template.tmLanguage

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,45 @@
10231023
</dict>
10241024
</dict>
10251025
</dict>
1026+
<dict>
1027+
<key>name</key>
1028+
<string>meta.tag.self-closing.generic.boxlang</string>
1029+
<key>match</key>
1030+
<string>(&lt;)(bx:([a-zA-Z_][a-zA-Z0-9_\-]*))(\s[^&gt;]*)?+(/?&gt;)</string>
1031+
<key>captures</key>
1032+
<dict>
1033+
<key>1</key>
1034+
<dict>
1035+
<key>name</key>
1036+
<string>punctuation.definition.tag.begin.boxlang</string>
1037+
</dict>
1038+
<key>2</key>
1039+
<dict>
1040+
<key>name</key>
1041+
<string>entity.name.tag.boxlang</string>
1042+
</dict>
1043+
<key>3</key>
1044+
<dict>
1045+
<key>name</key>
1046+
<string>entity.name.tag.boxlang</string>
1047+
</dict>
1048+
<key>4</key>
1049+
<dict>
1050+
<key>patterns</key>
1051+
<array>
1052+
<dict>
1053+
<key>include</key>
1054+
<string>#tag-attributes</string>
1055+
</dict>
1056+
</array>
1057+
</dict>
1058+
<key>5</key>
1059+
<dict>
1060+
<key>name</key>
1061+
<string>punctuation.definition.tag.end.boxlang</string>
1062+
</dict>
1063+
</dict>
1064+
</dict>
10261065
</array>
10271066
</dict>
10281067
<key>bx-generic</key>
@@ -1068,7 +1107,7 @@
10681107
</dict>
10691108
</dict>
10701109
<key>end</key>
1071-
<string>(&lt;/)\s*(bx:\3)\s*(&gt;)</string>
1110+
<string>(&lt;/)\s*(bx:[a-zA-Z_][a-zA-Z0-9_\-]*)\s*(&gt;)</string>
10721111
<key>endCaptures</key>
10731112
<dict>
10741113
<key>1</key>

Syntaxes/boxlang-template.tmLanguage.json

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,31 @@
651651
"name": "punctuation.definition.tag.end.boxlang"
652652
}
653653
}
654+
},
655+
{
656+
"name": "meta.tag.self-closing.generic.boxlang",
657+
"match": "(<)(bx:([a-zA-Z_][a-zA-Z0-9_\\-]*))(\\s[^>]*)?+(/?>)",
658+
"captures": {
659+
"1": {
660+
"name": "punctuation.definition.tag.begin.boxlang"
661+
},
662+
"2": {
663+
"name": "entity.name.tag.boxlang"
664+
},
665+
"3": {
666+
"name": "entity.name.tag.boxlang"
667+
},
668+
"4": {
669+
"patterns": [
670+
{
671+
"include": "#tag-attributes"
672+
}
673+
]
674+
},
675+
"5": {
676+
"name": "punctuation.definition.tag.end.boxlang"
677+
}
678+
}
654679
}
655680
]
656681
},
@@ -680,7 +705,7 @@
680705
"name": "punctuation.definition.tag.end.boxlang"
681706
}
682707
},
683-
"end": "(</)\\s*(bx:\\3)\\s*(>)",
708+
"end": "(</)\\s*(bx:[a-zA-Z_][a-zA-Z0-9_\\-]*)\\s*(>)",
684709
"endCaptures": {
685710
"1": {
686711
"name": "punctuation.definition.tag.begin.boxlang"

test-syntax.bxm

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<bx:try>
2+
<bx:script>
3+
// Global BIFs in embedded script - should be highlighted properly
4+
var config = DeserializeJSON(configData);
5+
var timestamp = Now();
6+
var formattedTime = TimeFormat(timestamp, "HH:mm:ss");
7+
var randomNum = RandRange(1, 100);
8+
9+
WriteOutput("Config loaded at: " & formattedTime);
10+
WriteOutput("Random number: " & randomNum);
11+
12+
// Array operations
13+
var items = ArrayNew(1);
14+
ArrayAppend(items, "Item 1");
15+
ArrayAppend(items, "Item 2");
16+
ArrayAppend(items, "Item 3");
17+
18+
var itemCount = ArrayLen(items);
19+
var lastItem = ArrayLast(items);
20+
21+
// String operations
22+
var message = "Hello World";
23+
var upperMessage = UCase(message);
24+
var messageLength = Len(message);
25+
var foundPos = Find("World", message);
26+
</bx:script>
27+
28+
<bx:catch type="any" name="e">
29+
<div class="error">
30+
Error loading config: #e.message#
31+
</div>
32+
</bx:catch>
33+
</bx:try>
34+
35+
<!-- Custom components - should be highlighted as entity.name.tag.boxlang -->
36+
<bx:userProfile userId="#users.id#" showDetails="true">
37+
38+
<bx:customWidget
39+
title="Dynamic Widget"
40+
data="#SerializeJSON(config)#"
41+
timestamp="#GetTickCount()#">
42+
</bx:customWidget>
43+
44+
<bx:output>
45+
<h1>BoxLang Template Demo</h1>
46+
47+
<!-- Global Components - should be highlighted as support.class.component.boxlang -->
48+
<bx:query name="users" datasource="mydb">
49+
SELECT id, name, email, created_date
50+
FROM users
51+
WHERE active = 1
52+
ORDER BY name
53+
</bx:query>
54+
55+
<bx:cache action="get" id="userCount" variable="cachedCount">
56+
<bx:query name="countQuery" datasource="mydb">
57+
SELECT COUNT(*) as total FROM users WHERE active = 1
58+
</bx:query>
59+
<bx:cache action="put" id="userCount" value="#countQuery.total#">
60+
</bx:cache>
61+
62+
<h2>User List (#cachedCount# total users)</h2>
63+
64+
<bx:loop query="users">
65+
<div class="user-card">
66+
<h3>#users.name#</h3>
67+
<p>Email: #users.email#</p>
68+
69+
<!-- Using global BIFs in template context -->
70+
<p>Member since: #DateFormat(users.created_date, 'mmmm d, yyyy')#</p>
71+
<p>Name length: #Len(users.name)# characters</p>
72+
<p>Uppercase name: #UCase(users.name)#</p>
73+
74+
<bx:if condition="Find('g', users.email) GT 0">
75+
<span class="verified">✓ Valid email format</span>
76+
</bx:if>
77+
</div>
78+
</bx:loop>
79+
80+
<!-- HTTP component for API calls -->
81+
<bx:http url="https://api.example.com/stats" method="GET" result="apiResponse">
82+
<bx:httpparam type="header" name="Authorization" value="Bearer #session.token#">
83+
<bx:httpparam type="header" name="Content-Type" value="application/json">
84+
</bx:http>
85+
86+
<bx:if condition="apiResponse.statusCode EQ '200 OK'">
87+
<div class="api-stats">
88+
<h3>API Statistics</h3>
89+
<pre>#HTMLCodeFormat(apiResponse.fileContent)#</pre>
90+
</div>
91+
</bx:if>
92+
93+
<!-- File operations -->
94+
<bx:file action="read" file="#ExpandPath('./data/config.json')#" variable="configFile">
95+
96+
<bx:try>
97+
<bx:script>
98+
var parsedConfig = DeserializeJSON(configFile);
99+
var appName = parsedConfig.application.name;
100+
var version = parsedConfig.application.version;
101+
</bx:script>
102+
103+
<div class="config-info">
104+
<h3>Application: #appName# v#version#</h3>
105+
</div>
106+
107+
<bx:catch type="any" name="configError">
108+
<div class="error">
109+
Error parsing config: #configError.message#
110+
</div>
111+
</bx:catch>
112+
</bx:try>
113+
114+
<!-- More custom components -->
115+
<bx:navigation items="#navigationItems#" activeItem="#currentPage#">
116+
117+
<bx:sidebar>
118+
<bx:widget type="calendar" data="#calendarData#">
119+
<bx:widget type="recent-posts" count="5">
120+
<bx:widget type="user-stats" userId="#session.userId#">
121+
</bx:sidebar>
122+
123+
<bx:footer>
124+
<bx:set name="currentYear" value="#Year(Now())#">
125+
<p>&copy; #currentYear# My Application. All rights reserved.</p>
126+
</bx:footer>
127+
</bx:output>

0 commit comments

Comments
 (0)