Skip to content

Commit 6197af6

Browse files
author
Monte Goulding
committed
Adds LiveCode Builder linter
This commit adds support for source.lcb to be linted using lc-compile. It adds two new settings: * The path for lc-compile * The module paths delimited by ; Default settings assume a debug build of the livened repo in the home directory.
1 parent a92b4ed commit 6197af6

File tree

3 files changed

+157
-60
lines changed

3 files changed

+157
-60
lines changed

README.md

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,16 @@ for Atom.
4242

4343
## Script Error Checking
4444

45-
This package provides a linter for LiveCode Script and Server to highlight and describe
46-
script compilation errors on the fly.
45+
This package provides a linter for LiveCode Script, LiveCode Server and LiveCode
46+
Builder to highlight and describe script compilation errors on the fly.
4747

4848
![Linter In Action](http://ecove.on-rev.com/linter.gif)
4949

5050
Dependencies:
5151

5252
* The [linter package](https://atom.io/packages/linter) needs to be installed
53-
* LiveCode 7.1+ Server engine for the platform it is being run on must be accessible
53+
* LiveCode 7.1+ Server engine for the platform it is being run on must be
54+
accessible
5455

5556
The default setting assumes you have installed the LiveCode Server engine somewhere
5657
on the current `$PATH` with the name `livecode-server`. However, you can enter any
@@ -63,6 +64,27 @@ by the inclusion of another file that error won't be detected.
6364
The linter supports an optional explicit variables mode which can be turned on
6465
via the package settings.
6566

67+
### LiveCode Builder Linting
68+
69+
Linting of LiveCode Builder files should be considered experimental. This is
70+
particularly the case for projects that have complex interdependencies between
71+
files.
72+
73+
In order to lint LiveCode Builder files ensure the following:
74+
75+
* lc-compile can be found at the location specified in settings
76+
* You have appropriately set the module paths to a directory with the standard
77+
`*.lci` files provided by LiveCode. You may add further paths delimited by `;`
78+
79+
The default settings assume you have a clone of the LiveCode repo in
80+
your home directory named livecode and you have built a debug build.
81+
82+
In the process of linting the LiveCode Builder file a `*.lci` file is created in
83+
a directory named `.lci` next to the file being edited. In the case of files
84+
that have dependencies you may receive a dependency error if you edit a
85+
file with the dependency before those it depends on because it won't be able to
86+
fine the appropriate `*.lci` file in the `.lci` directory.
87+
6688
## Authors
6789

6890
* Ralf Bitter

lib/main.coffee

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,31 @@ module.exports =
1313
title: 'Explicit Variables'
1414
default: 'false'
1515
description: 'Get errors on undeclared variables'
16+
lcCompilePath:
17+
type: 'string'
18+
title: 'Compiler Path For LiveCode Builder'
19+
default: switch
20+
when process.platform == 'darwin'
21+
then '~/livecode/_build/mac/Debug/lc-compile'
22+
when process.platform == 'linux'
23+
then '~/livecode/build-linux-x86_64/livecode/out/Debug/lc-compile'
24+
when process.platform == 'win32'
25+
then '~/livecode/_build/Win32/Debug/lc-compile.exe'
26+
description: 'Where is your lc-compile installed? ' +
27+
'Default assumes it\'s on $PATH'
28+
modulePaths:
29+
type: 'string'
30+
title: 'Module Paths For LiveCode Builder'
31+
default: switch
32+
when process.platform == 'darwin'
33+
then '~/livecode/_build/mac/Debug/modules/lci/'
34+
when process.platform == 'linux'
35+
then '~/livecode/build-linux-x86_64/livecode/out/Debug/modules/lci/'
36+
when process.platform == 'win32'
37+
then '~/livecode/_build/Win32/Debug/modules/lci/'
38+
description: 'Where are the modules installed? ' +
39+
'Default is where they should be after building ' +
40+
'a debug build of LiveCode. Delimit paths with `;`.'
1641

1742
activate: ->
1843
@subscriptions = new CompositeDisposable
@@ -22,6 +47,12 @@ module.exports =
2247
@subscriptions.add atom.config.observe 'language-livecode.explicitVars',
2348
(explicitVars) =>
2449
@explicitVars = explicitVars
50+
@subscriptions.add atom.config.observe 'language-livecode.lcCompilePath',
51+
(lcCompilePath) =>
52+
@lcCompilePath = lcCompilePath
53+
@subscriptions.add atom.config.observe 'language-livecode.modulePaths',
54+
(modulePaths) =>
55+
@modulePaths = modulePaths
2556
path = require 'path'
2657
@linterPath = path.join(__dirname, '..', 'tools', 'Linter.lc')
2758

@@ -31,7 +62,7 @@ module.exports =
3162
provideLinter: ->
3263
helpers = require('atom-linter')
3364
provider =
34-
grammarScopes: ['source.livecodescript', 'source.iRev']
65+
grammarScopes: ['source.livecodescript', 'source.iRev', 'source.lcb']
3566
scope: 'file'
3667
lintOnFly: true
3768
lint: (textEditor) =>
@@ -44,6 +75,12 @@ module.exports =
4475
parameters.push(scope)
4576
explicitVariables = '-explicitVariables=' + @explicitVars
4677
parameters.push(explicitVariables)
78+
lcCompile = '-lcCompile=' + @lcCompilePath
79+
parameters.push(lcCompile)
80+
lcCompileModulePaths = '-modulePaths=' + @modulePaths
81+
parameters.push(lcCompileModulePaths)
82+
editorFilePath = '-filepath=' + filePath
83+
parameters.push(editorFilePath)
4784
text = textEditor.getText()
4885
return helpers.exec(command, parameters, {stdin: text}).then (output) ->
4986
regex = /(\d+),(\d+),(.*)/g

tools/Linter.lc

Lines changed: 94 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,43 @@
22

33
local sErrorsList
44
local sLastLine
5+
local sTempFile
6+
57

68
Lint
79

810
command Lint
9-
local tScope, theArgument
11+
local tScope, tLCCompile, tModulePaths, theArgument, tFilename, tLCIDirectory
12+
13+
local tIndex
1014
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-
else if theArgument begins with "-explicitVariables" then
15-
split theArgument with "="
16-
set the explicitVariables to theArgument[2]
17-
end if
15+
split theArgument with "="
16+
switch theArgument[1]
17+
case "-scope"
18+
put theArgument[2] into tScope
19+
break
20+
case "-explicitVariables"
21+
set the explicitVariables to theArgument[2]
22+
break
23+
case "-modulePaths"
24+
split theArgument[2] with ";"
25+
repeat with tIndex = 1 to the number of elements in theArgument[2]
26+
if there is a folder theArgument[2][tIndex] then
27+
put " --modulepath " & theArgument[2][tIndex] after tModulePaths
28+
end if
29+
end repeat
30+
break
31+
case "-lcCompile"
32+
put theArgument[2] into tLCCompile
33+
break
34+
case "-filepath"
35+
set the itemDelimiter to slash
36+
put item -1 of theArgument[2] into tFilename
37+
put item 1 to -2 of theArgument[2] & "/.lci" into tLCIDirectory
38+
put " --modulepath " & tLCIDirectory before tModulePaths
39+
set the itemDelimiter to comma
40+
break
41+
end switch
1842
end repeat
1943

2044
read from stdin until empty
@@ -26,54 +50,76 @@ command Lint
2650

2751
create script only stack "TestScript"
2852

29-
if tScope is empty or tScope is ".source.livecodescript" then
30-
local tLineOffset = 0
53+
local tErrors
54+
switch tScope
55+
case ".source.livecodescript"
56+
local tLineOffset = 0
3157

32-
-- check for script only
33-
if word 1 of tScript is "script" then
34-
put 1 into tLineOffset
35-
end if
58+
-- check for script only
59+
if word 1 of tScript is "script" then
60+
put 1 into tLineOffset
61+
end if
3662

37-
if tLineOffset is 1 then
38-
delete line 1 of tScript
39-
end if
63+
if tLineOffset is 1 then
64+
delete line 1 of tScript
65+
end if
4066

41-
set the script of stack "TestScript" to tScript
42-
43-
local theErrors
44-
put the result into theErrors
45-
split theErrors with return
46-
local tIndex
47-
repeat with tIndex = 1 to the number of elements in theErrors
48-
if theErrors[tIndex] is not empty then
49-
local tMessage
50-
put sErrorsList[item 1 of theErrors[tIndex]] into tMessage
51-
if tMessage is not empty then
52-
if item 4 of theErrors[tIndex] is not empty then
53-
put " (" & item 4 of theErrors[tIndex] & ")" after tMessage
67+
set the script of stack "TestScript" to tScript
68+
69+
put the result into tErrors
70+
split tErrors with return
71+
repeat with tIndex = 1 to the number of elements in tErrors
72+
if tErrors[tIndex] is not empty then
73+
split tErrors with ","
74+
local tMessage
75+
put sErrorsList[tErrors[tIndex][1]] into tMessage
76+
if tMessage is not empty then
77+
if tErrors[tIndex][4] is not empty then
78+
put " (" & item 4 of tErrors[tIndex][4] & ")" after tMessage
79+
end if
80+
write tErrors[tIndex][2] + tLineOffset, tErrors[tIndex][3], tMessage & linefeed to stdout
5481
end if
55-
write item 2 of theErrors[tIndex] + tLineOffset, item 3 of theErrors[tIndex], tMessage & linefeed to stdout
5682
end if
83+
end repeat
84+
break
85+
case ".source.iRev"
86+
-- can't lint a whole web app...
87+
replace "include" with "# include" in tScript
88+
replace "require" with "# require" in tScript
89+
-- ensure it throws an error so it's not exectuted
90+
put return & quote after tScript
91+
put the number of lines of tScript into sLastLine
92+
SaveToTempFile tScript
93+
include sTempFile
94+
break
95+
case ".source.lcb"
96+
if there is not a folder tLCIDirectory then
97+
create folder tLCIDirectory
5798
end if
58-
end repeat
59-
else if tScope is ".source.iRev" then
60-
-- write out to a temporary file and include
61-
local tFile
62-
put the temporary folder & slash & uuid() into tFile
63-
-- can't lint a whole web app...
64-
replace "include" with "# include" in tScript
65-
replace "require" with "# require" in tScript
66-
-- ensure it throws an error so it's not exectuted
67-
put return & quote after tScript
68-
put the number of lines of tScript into sLastLine
69-
put tScript into url ("binfile:" & tFile)
70-
include tFile
71-
end if
72-
73-
write linefeed to stdout
99+
SaveToTempFile tScript
100+
put shell(tLCCompile & tModulePaths & " -- " & sTempFile) into tErrors
101+
split tErrors with return
102+
repeat with tIndex = 1 to the number of elements of tErrors
103+
split tErrors[tIndex] with ":"
104+
write tErrors[tIndex][2], tErrors[tIndex][3], tErrors[tIndex][4] & linefeed to stdout
105+
end repeat
106+
DeleteTempFile
107+
break
108+
end switch
109+
110+
write linefeed to stdout
74111

75112
end Lint
76113

114+
command SaveToTempFile pScript
115+
put the temporary folder & slash & uuid() into sTempFile
116+
put pScript into url ("binfile:" & sTempFile)
117+
end SaveToTempFile
118+
119+
command DeleteTempFile
120+
delete file sTempFile
121+
end DeleteTempFile
122+
77123
command scriptExecutionError pStack, pFiles
78124
split pStack with return
79125
local tIndex
@@ -93,15 +139,7 @@ command scriptExecutionError pStack, pFiles
93139
end if
94140
end repeat
95141

96-
-- cleanup
97-
local tFile
98-
set the itemDelimiter to slash
99-
repeat for each line tFile in pFiles
100-
if item -1 of tFile is "Linter.lc" then
101-
next repeat
102-
end if
103-
delete file tFile
104-
end repeat
142+
DeleteTempFile
105143

106144
write linefeed to stdout
107145
end scriptExecutionError

0 commit comments

Comments
 (0)