@@ -3,20 +3,37 @@ import { commands, ExtensionContext, window, workspace } from "vscode";
33import { OxcCommands } from "./commands" ;
44import { ConfigService } from "./ConfigService" ;
55import StatusBarItemHandler from "./StatusBarItemHandler" ;
6+ import Formatter from "./tools/formatter" ;
67import Linter from "./tools/linter" ;
8+ import ToolInterface from "./tools/ToolInterface" ;
79
810const outputChannelName = "Oxc" ;
9- const linter = new Linter ( ) ;
11+ const tools : ToolInterface [ ] = [ ] ;
12+
13+ if ( process . env . SKIP_LINTER_TEST !== "true" ) {
14+ tools . push ( new Linter ( ) ) ;
15+ }
16+ if ( process . env . SKIP_FORMATTER_TEST !== "true" ) {
17+ tools . push ( new Formatter ( ) ) ;
18+ }
1019
1120export async function activate ( context : ExtensionContext ) {
1221 const configService = new ConfigService ( ) ;
1322
14- const outputChannel = window . createOutputChannel ( outputChannelName , {
23+ const outputChannelLint = window . createOutputChannel ( outputChannelName + " (Lint)" , {
24+ log : true ,
25+ } ) ;
26+
27+ const outputChannelFormat = window . createOutputChannel ( outputChannelName + " (Fmt)" , {
1528 log : true ,
1629 } ) ;
1730
18- const showOutputCommand = commands . registerCommand ( OxcCommands . ShowOutputChannel , ( ) => {
19- outputChannel . show ( ) ;
31+ const showOutputLintCommand = commands . registerCommand ( OxcCommands . ShowOutputChannelLint , ( ) => {
32+ outputChannelLint . show ( ) ;
33+ } ) ;
34+
35+ const showOutputFmtCommand = commands . registerCommand ( OxcCommands . ShowOutputChannelFmt , ( ) => {
36+ outputChannelFormat . show ( ) ;
2037 } ) ;
2138
2239 const onDidChangeWorkspaceFoldersDispose = workspace . onDidChangeWorkspaceFolders (
@@ -33,35 +50,87 @@ export async function activate(context: ExtensionContext) {
3350 const statusBarItemHandler = new StatusBarItemHandler ( context . extension . packageJSON ?. version ) ;
3451
3552 context . subscriptions . push (
36- showOutputCommand ,
53+ showOutputLintCommand ,
54+ showOutputFmtCommand ,
3755 configService ,
38- outputChannel ,
56+ outputChannelLint ,
57+ outputChannelFormat ,
3958 onDidChangeWorkspaceFoldersDispose ,
4059 statusBarItemHandler ,
4160 ) ;
4261
4362 configService . onConfigChange = async function onConfigChange ( event ) {
44- await linter . onConfigChange ( event , configService , statusBarItemHandler ) ;
45- } ;
46- const binaryPath = await linter . getBinary ( context , outputChannel , configService ) ;
47-
48- // For the linter this should never happen, but just in case.
49- if ( ! binaryPath ) {
50- statusBarItemHandler . setColorAndIcon ( "statusBarItem.errorBackground" , "error" ) ;
51- statusBarItemHandler . updateToolTooltip (
52- "linter" ,
53- "Error: No valid oxc language server binary found." ,
63+ await Promise . all (
64+ tools . map ( ( tool ) => tool . onConfigChange ( event , configService , statusBarItemHandler ) ) ,
5465 ) ;
55- statusBarItemHandler . show ( ) ;
56- outputChannel . error ( "No valid oxc language server binary found." ) ;
57- return ;
58- }
66+ } ;
67+
68+ const foundBinaries : string [ ] = [ ] ;
69+
70+ await Promise . all (
71+ tools . map ( async ( tool ) => {
72+ const outputChannel = tool instanceof Linter ? outputChannelLint : outputChannelFormat ;
73+ const binaryPath = await tool . getBinary ( context , outputChannel , configService ) ;
74+
75+ // For the linter this should never happen, but just in case.
76+ if ( ! binaryPath && tool instanceof Linter ) {
77+ statusBarItemHandler . setColorAndIcon ( "statusBarItem.errorBackground" , "error" ) ;
78+ statusBarItemHandler . updateToolTooltip (
79+ "linter" ,
80+ "Error: No valid oxc language server binary found." ,
81+ ) ;
82+ }
83+
84+ if ( tool instanceof Formatter ) {
85+ if ( foundBinaries . some ( ( path ) => path . includes ( "oxc_language_server" ) ) ) {
86+ // The formatter is already handled by the linter tool in this case.
87+ statusBarItemHandler . updateToolTooltip (
88+ "formatter" ,
89+ "oxc_language_server is used for formatting." ,
90+ ) ;
91+ outputChannelFormat . appendLine ( "oxc_language_server is used for formatting." ) ;
92+ return ;
93+ } else if ( ! binaryPath ) {
94+ // No valid binary found for the formatter.
95+ statusBarItemHandler . updateToolTooltip (
96+ "formatter" ,
97+ "No valid oxfmt binary found. Formatter will not be activated." ,
98+ ) ;
99+ outputChannelFormat . appendLine (
100+ "No valid oxfmt binary found. Formatter will not be activated." ,
101+ ) ;
102+ return ;
103+ }
104+ }
105+
106+ // binaryPath is guaranteed to be defined here.
107+ const binaryPathResolved = binaryPath ! ;
108+
109+ // do not activate the same binary multiple times.
110+ // This only happens when the `oxc_language_server` is used, which support both linting and formatting.
111+ //
112+ // The `linter` tool is prioritized here, so the formatter will not be activated if the linter already uses the same binary.
113+ // Because the linter source code also handles formatting in that case. (for now)
114+ if ( foundBinaries . includes ( binaryPathResolved ) ) {
115+ return ;
116+ }
117+
118+ foundBinaries . push ( binaryPathResolved ) ;
119+
120+ return tool . activate (
121+ context ,
122+ binaryPathResolved ,
123+ outputChannel ,
124+ configService ,
125+ statusBarItemHandler ,
126+ ) ;
127+ } ) ,
128+ ) ;
59129
60- await linter . activate ( context , binaryPath , outputChannel , configService , statusBarItemHandler ) ;
61- // Show status bar item after activation
130+ // Finally show the status bar item.
62131 statusBarItemHandler . show ( ) ;
63132}
64133
65134export async function deactivate ( ) : Promise < void > {
66- await linter . deactivate ( ) ;
135+ await Promise . all ( tools . map ( ( tool ) => tool . deactivate ( ) ) ) ;
67136}
0 commit comments