Skip to content

Commit bd57d38

Browse files
author
Monte Goulding
committed
Documented the linter and LiveCode Script grammar. Moved to using the server engine and added support to the linter for tagged server files (iRev). Added myself as an author
1 parent 32ffb7b commit bd57d38

File tree

7 files changed

+160
-645
lines changed

7 files changed

+160
-645
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,19 @@ Currently, this package supports editing:
1919

2020
* LiveCode Builder source code in `.lcb` files
2121
* LiveCode server source code in `.lc` and `.irev` files
22+
* LiveCode Script source code in `.livecodescript` files, where the shebang line
23+
contains `livecode` or the first line contains an Emacs mode comment
24+
`# -*- mode:livecodescript -*-`
2225

2326
The package provides syntax highlighting, highlighting and indentation support
2427
for all the supported languages.
2528

2629
It also provides snippets to enhance LiveCode server script and revIgniter
2730
script development.
2831

32+
For LiveCode Script there are quite a number of autocomplete snippets generated
33+
from the LiveCode documentation.
34+
2935
## Installation
3036

3137
Install the `language-livecode` package from the "Install Packages and Themes"
@@ -34,11 +40,30 @@ view in Atom's "Settings" window.
3440
You may also wish to install the [revIgniter theme](https://atom.io/themes/revigniter-syntax)
3541
for Atom.
3642

43+
## Script Error Checking
44+
45+
This package provides a linter for LiveCode Script and Server to highlight and describe
46+
script compilation errors on the fly.
47+
48+
Dependencies:
49+
50+
* The [linter package](https://atom.io/packages/linter) needs to be installed
51+
* LiveCode Server engine for the platform it is being run on must be accessible
52+
53+
The default setting assumes you have installed the LiveCode Server engine somewhere
54+
on the current `$PATH` with the name `livecode-server`. However, you can enter any
55+
path or name you choose via the package settings.
56+
57+
For LiveCode Server the linter will only check for errors within the scope of
58+
the file being edited. If for example a variable re-declarition error is caused
59+
by the inclusion of another file that error won't be detected.
60+
3761
## Authors
3862

3963
* Ralf Bitter
4064
* Peter Brett
4165
* Adam Robertson
66+
* Monte Goulding
4267

4368
## Reporting bugs and contributing
4469

grammars/livecodescript.cson

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
'fileTypes': [
77
'livecodescript'
88
]
9-
'firstLineMatch': '^#!.*\\b(livecode|/usr/bin/env livecode)|^#\\s*-\\*-[^*]*mode:\\s*livecodescript[^*]*-\\*-'
9+
'firstLineMatch': '^#!.*\\b(livecode)|^#\\s*-\\*-[^*]*mode:\\s*livecodescript[^*]*-\\*-'
1010
'patterns': [
1111
{
1212
include: "#language"

lib/main.coffee

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ module.exports =
44
config:
55
executablePath:
66
type: 'string'
7-
title: 'LiveCode Standalone Engine Path'
8-
default: 'livecode' # Let OS's $PATH handle the rest
7+
title: 'LiveCode Server Engine Path'
8+
default: 'livecode-server' # Let OS's $PATH handle the rest
99

1010
activate: ->
1111
@subscriptions = new CompositeDisposable
1212
@subscriptions.add atom.config.observe 'language-livecode.executablePath',
1313
(executablePath) =>
1414
@executablePath = executablePath
1515
path = require 'path'
16-
@linterPath = path.join(__dirname, '..', 'tools', 'Linter.livecodescript')
16+
@linterPath = path.join(__dirname, '..', 'tools', 'Linter.lc')
1717

1818
deactivate: ->
1919
@subscriptions.dispose()
@@ -28,7 +28,6 @@ module.exports =
2828
filePath = textEditor.getPath()
2929
command = @executablePath
3030
parameters = []
31-
parameters.push('-ui')
3231
stackfile = @linterPath
3332
parameters.push(stackfile)
3433
scope = '-scope=' + textEditor.getRootScopeDescriptor()

tools/GenerateSnippets.livecodescript

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on mouseUp
99
if the short name of the target is "Generate Snippets" then
1010
put "# GENERATED SNIPPETS START" & cr & \
1111
"'.source.livecodescript':" & cr & \
12-
tab & "autocomplete:" & cr & \
12+
tab & "autocomplete:" & cr & \
1313
tab & tab & "symbols:" & cr & \
1414
tab & tab & tab & "builtins:" & cr & \
1515
tab & tab & tab & tab & "suggestions: [" into theSnippets
@@ -24,21 +24,21 @@ on mouseUp
2424
delete word 1 of theSyntax
2525
replace "[" with empty in theSyntax
2626
replace "]" with empty in theSyntax
27-
27+
2828
-- parameters
2929
put empty into theFunctionName
3030
put empty into theParameters
3131
if theSyntax contains "(" then
3232
get MatchText(theSyntax,"(?i)^(.*)\((.*)\)",theFunctionName,theParameters)
33-
33+
3434
if theParameters is empty then
3535
next repeat
3636
end if
37-
37+
3838
put theFunctionName into thePrefix
39-
39+
4040
put theFunctionName&"(" into theBody
41-
41+
4242
if theParameters is not empty then
4343
replace "<" with "" in theParameters
4444
replace ">" with "" in theParameters
@@ -52,11 +52,11 @@ on mouseUp
5252
else
5353
put ")" after theBody
5454
end if
55-
55+
5656
AddSnippet theSnippets, theFunctionName, theBody, "function", theDescription, theFile
57-
57+
5858
else
59-
59+
6060
if theSyntax contains "of" then
6161
put word 2 to -4 of theSyntax into theOptions
6262
put word -3 of theSyntax into theFunctionName
@@ -69,7 +69,7 @@ on mouseUp
6969
put word 2 to -2 of theSyntax into theOptions
7070
put word -1 of theSyntax into theFunctionName
7171
end if
72-
72+
7373
if theOptions contains "|" then
7474
split theOptions with "|"
7575
repeat with theIndex = 1 to the number of elements of theOptions
@@ -88,7 +88,7 @@ on mouseUp
8888
end if
8989
end repeat
9090
end repeat
91-
91+
9292
# messages
9393
set the folder to specialFolderPath("home") & "/livecode/docs/dictionary/message"
9494
repeat for each line theFile in the files
@@ -117,12 +117,12 @@ on mouseUp
117117
if the last char of theSyntax is comma then
118118
delete the last char of theSyntax
119119
end if
120-
120+
121121
put theSyntax & cr & tab & "${1:/* code */ }" & cr & "end" && theMessageName into theBody
122122
AddSnippet theSnippets, theMessageName & " ... end " & theMessageName, theBody, "message", theDescription, theFile
123123
end repeat
124124
end repeat
125-
125+
126126
# properties
127127
set the folder to specialFolderPath("home") & "/livecode/docs/dictionary/property"
128128
repeat for each line theFile in the files
@@ -143,12 +143,12 @@ on mouseUp
143143
repeat with theIndex = 2 to the number of items of theSnippet
144144
put theIndex-1&":" before item theIndex of theSnippet
145145
end repeat
146-
147-
146+
147+
148148
AddSnippet theSnippets, theSyntax, theSnippet, "property", theDescription, theFile
149149
end repeat
150150
end repeat
151-
151+
152152
# keywords
153153
set the folder to specialFolderPath("home") & "/livecode/docs/dictionary/keyword"
154154
repeat for each line theFile in the files
@@ -163,7 +163,7 @@ on mouseUp
163163
AddSnippet theSnippets, theSyntax, theSyntax, "keyword", theDescription, theFile
164164
end repeat
165165
end repeat
166-
166+
167167
# constants
168168
set the folder to specialFolderPath("home") & "/livecode/docs/dictionary/constant"
169169
repeat for each line theFile in the files
@@ -176,7 +176,7 @@ on mouseUp
176176
AddSnippet theSnippets, theSyntax, theSyntax, "constant", theDescription, theFile
177177
end repeat
178178
end repeat
179-
179+
180180
# objects
181181
set the folder to specialFolderPath("home") & "/livecode/docs/dictionary/object"
182182
repeat for each line theFile in the files
@@ -189,7 +189,7 @@ on mouseUp
189189
AddSnippet theSnippets, theSyntax, theSyntax, "object", theDescription, theFile
190190
end repeat
191191
end repeat
192-
192+
193193
# operators
194194
set the folder to specialFolderPath("home") & "/livecode/docs/dictionary/operator"
195195
repeat for each line theFile in the files
@@ -229,7 +229,7 @@ on mouseUp
229229
end repeat
230230
end repeat
231231
end repeat
232-
232+
233233
# commands
234234
set the folder to specialFolderPath("home") & "/livecode/docs/dictionary/command"
235235
repeat for each line theFile in the files
@@ -248,7 +248,7 @@ on mouseUp
248248
replace ">" with "" in theSyntax
249249
put word 1 to 3 of theSyntax into thePrefix
250250
replace space with empty in thePrefix
251-
251+
252252
split theParameters with "<"
253253
repeat with theIndex = 1 to the number of elements of theParameters
254254
if theIndex is 1 then
@@ -262,10 +262,10 @@ on mouseUp
262262
end repeat
263263
end repeat
264264
end repeat
265-
265+
266266
put cr & tab & tab & tab & tab & "]" & cr & \
267267
"# GENERATED SNIPPETS END" & cr after theSnippets
268-
268+
269269
put url ("binfile:"&specialFolderPath("home")&"/atom-language-livecode/settings/language-livecode.cson") into theCSON
270270
put offset("# GENERATED SNIPPETS START",theCSON) into theStart
271271
put offset("# GENERATED SNIPPETS END",theCSON) into theEnd
@@ -389,35 +389,35 @@ command AddSnippet @pSnippets, pName, pBody, pType, pDescription, pFile
389389
if pName ends with space then
390390
delete the last char of pName
391391
end if
392-
392+
393393
put tab & tab & tab & tab & tab into tTabLevel
394-
394+
395395
put tTabLevel&"{" & cr into theSnippet
396-
396+
397397
replace quote with "\"&quote in pBody
398-
398+
399399
if the number of lines of pBody > 1 then
400400
put "'''" & cr before pBody
401401
put cr & "'''" after pBody
402-
402+
403403
repeat with theIndex = 2 to the number of lines of pBody
404404
put tTabLevel & tab before line theIndex of pBody
405405
end repeat
406406
else
407407
put "'" & pBody & "'" into pBody
408408
end if
409-
409+
410410
# I assume this is based on the lcdoc filename... hope so
411411
set the itemDelimiter to "."
412412
put "https://livecode.com/resources/api/#livecode_script/"&item 1 of pFile into theMoreURL
413-
413+
414414
put tTabLevel & tab & "type: '" & pType & "'" & cr after theSnippet
415415
put tTabLevel & tab & "snippet: " & pBody & cr after theSnippet
416416
put tTabLevel & tab & "description: '" & pDescription & "'" & cr after theSnippet
417417
put tTabLevel & tab & "descriptionMoreURL: '" & theMoreURL & "'" & cr after theSnippet
418-
418+
419419
put tTabLevel&"}" after theSnippet
420-
420+
421421
put cr & theSnippet after pSnippets
422-
422+
423423
end AddSnippet

tools/Linter.lc

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?livecode
2+
3+
local sErrorsList
4+
local sLastLine
5+
6+
Lint
7+
8+
command Lint
9+
local tScope
10+
repeat for each element theArgument in the commandArguments
11+
if theArgument begins with "-scope" then
12+
split theArgument with "="
13+
put theArgument[2] into tScope
14+
end if
15+
end repeat
16+
17+
read from stdin until empty
18+
put it into tScript
19+
20+
put the scriptParsingErrors into sErrorsList
21+
split sErrorsList with return
22+
23+
create script only stack "TestScript"
24+
25+
if tScope is empty or tScope is ".source.livecodescript" then
26+
local tLineOffset = 0
27+
28+
-- check for script only
29+
if word 1 of tScript is "script" then
30+
put 1 into tLineOffset
31+
end if
32+
33+
if tLineOffset is 1 then
34+
delete line 1 of tScript
35+
end if
36+
37+
set the script of stack "TestScript" to tScript
38+
39+
put the result into theErrors
40+
split theErrors with return
41+
repeat with tIndex = 1 to the number of elements in theErrors
42+
if theErrors[tIndex] is not empty then
43+
put sErrorsList[item 1 of theErrors[tIndex]] into tMessage
44+
if tMessage is not empty then
45+
if item 4 of theErrors[tIndex] is not empty then
46+
put " (" & item 4 of theErrors[tIndex] & ")" after tMessage
47+
end if
48+
write item 2 of theErrors[tIndex] + tLineOffset, item 3 of theErrors[tIndex], tMessage & linefeed to stdout
49+
end if
50+
end if
51+
end repeat
52+
else if tScope is ".source.iRev" then
53+
-- write out to a temporary file and include
54+
put the temporary folder & slash & uuid() into tFile
55+
-- can't lint a whole web app...
56+
replace "include" with "# include" in tScript
57+
replace "require" with "# require" in tScript
58+
-- ensure it throws an error so it's not exectuted
59+
put return & quote after tScript
60+
put the number of lines of tScript into sLastLine
61+
put tScript into url ("binfile:" & tFile)
62+
include tFile
63+
end if
64+
65+
write linefeed to stdout
66+
67+
end Lint
68+
69+
command scriptExecutionError pStack, pFiles
70+
local tHint, tFile
71+
--write 1,1,line 2 of pStack & linefeed to stdout
72+
split pStack with return
73+
repeat with tIndex = 2 to the number of elements in pStack
74+
if item 1 of pStack[tIndex] is 730 then
75+
exit repeat
76+
end if
77+
if item 2 of pStack[tIndex] is not 0 and item 2 of pStack[tIndex] is not sLastLine then
78+
put sErrorsList[item 1 of pStack[tIndex]] into tMessage
79+
if tMessage is not empty then
80+
if item 4 of pStack[tIndex] is not empty then
81+
put " (" & item 4 of pStack[tIndex] & ")" after tMessage
82+
end if
83+
write item 2 of pStack[tIndex], item 3 of pStack[tIndex], tMessage & linefeed to stdout
84+
end if
85+
end if
86+
end repeat
87+
88+
-- cleanup
89+
set the itemDelimiter to slash
90+
repeat for each line tFile in pFiles
91+
if item -1 of tFile is "Linter.lc" then
92+
next repeat
93+
end if
94+
delete file tFile
95+
end repeat
96+
97+
write linefeed to stdout
98+
end scriptExecutionError

0 commit comments

Comments
 (0)