@@ -17,6 +17,109 @@ require 'vm'
1717
1818local export = {}
1919
20+ local colors
21+
22+ if not os.getenv (' NO_COLOR' ) then
23+ colors = {
24+ red = ' \27 [31m' ,
25+ green = ' \27 [32m' ,
26+ yellow = ' \27 [33m' ,
27+ blue = ' \27 [34m' ,
28+ magenta = ' \27 [35m' ,
29+ white = ' \27 [37m' ,
30+ grey = ' \27 [90m' ,
31+ reset = ' \27 [0m'
32+ }
33+ else
34+ colors = {
35+ red = ' ' ,
36+ green = ' ' ,
37+ yellow = ' ' ,
38+ blue = ' ' ,
39+ magenta = ' ' ,
40+ white = ' ' ,
41+ grey = ' ' ,
42+ reset = ' '
43+ }
44+ end
45+
46+ --- @type table<DiagnosticSeverity , string>
47+ local severity_colors = {
48+ Error = colors .red ,
49+ Warning = colors .yellow ,
50+ Information = colors .white ,
51+ Hint = colors .white ,
52+ }
53+
54+ local severity_str = {} --- @type table<integer,DiagnosticSeverity>
55+ for k , v in pairs (define .DiagnosticSeverity ) do
56+ severity_str [v ] = k
57+ end
58+
59+ local pwd
60+
61+ --- @param path string
62+ --- @return string
63+ local function relpath (path )
64+ if not pwd then
65+ pwd = furi .decode (furi .encode (fs .current_path ():string ()))
66+ end
67+ if pwd and path :sub (1 , # pwd ) == pwd then
68+ path = path :sub (# pwd + 2 )
69+ end
70+ return path
71+ end
72+
73+ local function report_pretty (uri , diags )
74+ local path = relpath (furi .decode (uri ))
75+
76+ local lines = {} --- @type string[]
77+ pcall (function ()
78+ for line in io.lines (path ) do
79+ table.insert (lines , line )
80+ end
81+ end )
82+
83+ for _ , d in ipairs (diags ) do
84+ local rstart = d .range .start
85+ local rend = d .range [' end' ]
86+ local severity = severity_str [d .severity ]
87+ print (
88+ (' %s%s:%s:%s%s [%s%s%s] %s %s(%s)%s' ):format (
89+ colors .blue ,
90+ path ,
91+ rstart .line + 1 , -- Use 1-based indexing
92+ rstart .character + 1 , -- Use 1-based indexing
93+ colors .reset ,
94+ severity_colors [severity ],
95+ severity ,
96+ colors .reset ,
97+ d .message ,
98+ colors .magenta ,
99+ d .code ,
100+ colors .reset
101+ )
102+ )
103+ if # lines > 0 then
104+ io.write (' ' , lines [rstart .line + 1 ], ' \n ' )
105+ io.write (' ' , colors .grey , (' ' ):rep (rstart .character ), ' ^' )
106+ if rstart .line == rend .line then
107+ io.write ((' ^' ):rep (rend .character - rstart .character - 1 ))
108+ end
109+ io.write (colors .reset , ' \n ' )
110+ end
111+ end
112+ end
113+
114+ local function clear_line ()
115+ -- Write out empty space to ensure that the previous lien is cleared.
116+ io.write (' \x0D ' , (' ' ):rep (80 ), ' \x0D ' )
117+ end
118+
119+ local function quiet ()
120+ return QUIET or QUIET_WORKER
121+ end
122+
20123function export .runCLI ()
21124 lang (LOCALE )
22125
@@ -65,9 +168,13 @@ function export.runCLI()
65168
66169 client :register (' textDocument/publishDiagnostics' , function (params )
67170 results [params .uri ] = params .diagnostics
171+ if not QUIET and (CHECK_FORMAT == nil or CHECK_FORMAT == ' pretty' ) then
172+ clear_line ()
173+ report_pretty (params .uri , params .diagnostics )
174+ end
68175 end )
69176
70- if not QUIET then
177+ if not quiet () then
71178 io.write (lang .script (' CLI_CHECK_INITING' ))
72179 end
73180
@@ -89,14 +196,14 @@ function export.runCLI()
89196
90197 -- Downgrade file opened status to Opened for everything to avoid reporting during compilation on files that do not belong to this thread
91198 local diagStatus = config .get (rootUri , ' Lua.diagnostics.neededFileStatus' )
92- for diag , status in pairs (diagStatus ) do
199+ for d , status in pairs (diagStatus ) do
93200 if status == ' Any' or status == ' Any!' then
94- diagStatus [diag ] = ' Opened!'
201+ diagStatus [d ] = ' Opened!'
95202 end
96203 end
97- for diag , status in pairs (protoDiag .getDefaultStatus ()) do
204+ for d , status in pairs (protoDiag .getDefaultStatus ()) do
98205 if status == ' Any' or status == ' Any!' then
99- diagStatus [diag ] = ' Opened!'
206+ diagStatus [d ] = ' Opened!'
100207 end
101208 end
102209 config .set (rootUri , ' Lua.diagnostics.neededFileStatus' , diagStatus )
@@ -109,7 +216,7 @@ function export.runCLI()
109216 files .open (uri )
110217 diag .doDiagnostic (uri , true )
111218 -- Print regularly but always print the last entry to ensure that logs written to files don't look incomplete.
112- if ( os.clock () - lastClock > 0.2 or i == # uris ) and not QUIET then
219+ if not quiet () and ( os.clock () - lastClock > 0.2 or i == # uris ) then
113220 lastClock = os.clock ()
114221 client :update ()
115222 local output = ' \x0D '
@@ -133,8 +240,8 @@ function export.runCLI()
133240 end
134241 end
135242 end
136- if not QUIET then
137- io.write ( ' \x0D ' )
243+ if not quiet () then
244+ clear_line ( )
138245 end
139246 end )
140247
@@ -146,18 +253,21 @@ function export.runCLI()
146253 end
147254 end
148255
149- local outpath = CHECK_OUT_PATH
150- if outpath == nil then
151- outpath = LOGPATH .. ' /check.json'
256+ local outpath = nil
257+
258+ if CHECK_FORMAT == ' json' or CHECK_OUT_PATH then
259+ outpath = CHECK_OUT_PATH or LOGPATH .. ' /check.json'
260+ -- Always write result, even if it's empty to make sure no one accidentally looks at an old output after a successful run.
261+ util .saveFile (outpath , jsonb .beautify (results ))
152262 end
153- -- Always write result, even if it's empty to make sure no one accidentally looks at an old output after a successful run.
154- util .saveFile (outpath , jsonb .beautify (results ))
155263
156- if not QUIET then
264+ if not quiet () then
157265 if count == 0 then
158266 print (lang .script (' CLI_CHECK_SUCCESS' ))
267+ elseif outpath then
268+ print (lang .script (' CLI_CHECK_RESULTS_OUTPATH' , count , outpath ))
159269 else
160- print (lang .script (' CLI_CHECK_RESULTS ' , count , outpath ))
270+ print (lang .script (' CLI_CHECK_RESULTS_PRETTY ' , count ))
161271 end
162272 end
163273 return count == 0 and 0 or 1
0 commit comments