1- import { IContributeType , IExtension , components } from '@dtinsight/molecule' ;
1+ import {
2+ IContributeType ,
3+ IEditorTab ,
4+ IExtension ,
5+ IMoleculeContext ,
6+ TabGroup ,
7+ UniqueId
8+ } from '@dtinsight/molecule' ;
9+ import lips from '@jcubic/lips' ;
10+
11+ import * as monaco from 'monaco-editor' ;
212
313import Welcome from '@/workbench/welcome' ;
414import {
@@ -14,6 +24,15 @@ import QuickGithub from '@/workbench/quickGithub';
1424import SourceSpace from '@/workbench/sourceSpace' ;
1525import UnitTest from '@/workbench/unitTest' ;
1626import ApiDocPage from '@/workbench/apiDocPage' ;
27+ import { debounce } from '@/utils/tool' ;
28+ import { LanguageService } from '../../../../esm/languageService' ;
29+ import { ParseError } from 'dt-sql-parser' ;
30+ import { ProblemsPaneView } from '@/workbench/problems' ;
31+ import ProblemStore from '@/workbench/problems/clients/problemStore' ;
32+ import { ProblemsService } from '@/workbench/problems/services' ;
33+ import { ProblemsController } from '@/workbench/problems/controllers' ;
34+
35+ const problemsService = new ProblemsService ( ) ;
1736
1837export const mainExt : IExtension = {
1938 id : 'mainExt' ,
@@ -22,8 +41,15 @@ export const mainExt: IExtension = {
2241 [ IContributeType . Modules ] : {
2342 menuBar : null
2443 }
44+ // [IContributeType.Grammar]: grammars
2545 } ,
2646 activate ( molecule ) {
47+ const languageService = new LanguageService ( ) ;
48+ problemsService . onSelect ( ( item ) => {
49+ // 写入展开的数组内; 当展开的时候 root 的icon 进行变换
50+ problemsService . toggleRoot ( item ) ;
51+ } ) ;
52+
2753 molecule . colorTheme . update ( 'Default Dark+' , ( data ) => ( {
2854 colors : {
2955 ...data . colors ,
@@ -170,7 +196,17 @@ export const mainExt: IExtension = {
170196 id : 'problem' ,
171197 name : '问题' ,
172198 sortIndex : 2 ,
173- render : ( ) => < div style = { { padding : 20 } } > Test</ div >
199+ render : ( ) => {
200+ return (
201+ < ProblemStore
202+ value = { {
203+ onselect : new ProblemsController ( ) . onSelect
204+ } }
205+ >
206+ < ProblemsPaneView problemsService = { problemsService } />
207+ </ ProblemStore >
208+ ) ;
209+ }
174210 } ) ;
175211
176212 molecule . statusBar . add ( {
@@ -195,5 +231,152 @@ export const mainExt: IExtension = {
195231
196232 molecule . activityBar . setCurrent ( ACTIVITY_FOLDER ) ;
197233 molecule . sidebar . setCurrent ( ACTIVITY_FOLDER ) ;
234+
235+ molecule . editor . onCurrentChange ( ( tab ) => {
236+ const language = ( tab . tabId as string ) ?. split ( '_' ) ?. [ 0 ] ;
237+ const groups = molecule . editor . getGroups ( ) ;
238+ const fileData = groups [ 0 ] ?. data ?. find ( ( item ) => item . id === tab . tabId ) ;
239+ molecule . output . setState ( { value : '' } ) ;
240+
241+ if ( fileData ?. model ) {
242+ monaco . editor . setModelLanguage ( fileData . model , language ) ;
243+ analyzeProblems ( { fileData, molecule, tab } ) ;
244+ }
245+ activeExplore ( tab , molecule ) ;
246+ } ) ;
247+
248+ molecule . editor . onContextMenu ( ( pos , tabId , groupId ) => {
249+ molecule . editor . setCurrent ( tabId , groupId ) ;
250+ molecule . contextMenu . open (
251+ [
252+ {
253+ id : 'parse' ,
254+ name : 'parse'
255+ }
256+ ] ,
257+ pos ,
258+ {
259+ name : molecule . builtin . getConstants ( ) . CONTEXTMENU_ITEM_EDITOR ,
260+ item : { tabId, groupId }
261+ }
262+ ) ;
263+ } ) ;
264+
265+ molecule . editor . onContextMenuClick ( ( item , tabId , groupId ) => {
266+ switch ( item . id ) {
267+ case 'parse' : {
268+ parseToAST ( molecule , languageService ) ;
269+ break ;
270+ }
271+ default :
272+ break ;
273+ }
274+ } ) ;
275+
276+ molecule . editor . onFocus ( ( item ) => {
277+ const groupId = ( molecule . editor . getCurrentGroup ( ) || - 1 ) as UniqueId ;
278+ const tab = molecule . editor . getCurrentTab ( ) ;
279+ if ( tab ?. id && tab . language ) {
280+ molecule . editor . setCurrent ( tab ?. id , groupId ) ;
281+ }
282+ } ) ;
283+
284+ molecule . editor . onUpdateState ( ( item ) => {
285+ const tab = molecule . editor . getCurrentTab ( ) ;
286+ const groups = molecule . editor . getGroups ( ) ;
287+ const fileData = groups [ 0 ] ?. data ?. find ( ( item ) => item . id === tab ?. id ) ;
288+ analyzeProblems ( { fileData, molecule, tab } ) ;
289+ } ) ;
290+ }
291+ } ;
292+
293+ const analyzeProblems = debounce ( ( info : any ) => {
294+ const { fileData, molecule, tab } = info || { } ;
295+ const { value : sql , language } = fileData || { } ;
296+ // todo: 一定要 active Tab 才能获取到 language
297+ if ( ! language ) return ;
298+ const languageService = new LanguageService ( ) ;
299+ languageService . valid ( language . toLocaleLowerCase ( ) , fileData . model ) . then ( ( res ) => {
300+ const problems = convertMsgToProblemItem ( tab , sql , res ) ;
301+
302+ molecule . panel . update ( {
303+ id : 'problem' ,
304+ data : problems . value
305+ } ) ;
306+ problems . icon = 'chevron-right' ;
307+ problemsService . update ( problems ) ;
308+ } ) ;
309+ } , 200 ) ;
310+
311+ const convertMsgToProblemItem = ( tab : IEditorTab < any > , code : string , msgs : ParseError [ ] = [ ] ) => {
312+ const rootId = tab ?. id ;
313+ const rootName = `${ tab . name || '' } ` ;
314+ const languageProblems = {
315+ id : rootId ,
316+ name : rootName ,
317+ isLeaf : false ,
318+ value : {
319+ code : rootName ,
320+ message : '' ,
321+ startLineNumber : 0 ,
322+ startColumn : 1 ,
323+ endLineNumber : 0 ,
324+ endColumn : 1 ,
325+ status : monaco . MarkerSeverity . Hint
326+ } ,
327+ children : [ ]
328+ } as any ;
329+
330+ languageProblems . children = msgs . map ( ( msg : any , index : number ) => {
331+ return {
332+ id : `${ rootId } -${ index } ` ,
333+ name : msg . code || '' ,
334+ isLeaf : true ,
335+ value : {
336+ code : msg . code ,
337+ message : msg . message ,
338+ startLineNumber : Number ( msg . startLine ) ,
339+ startColumn : Number ( msg . startCol ) ,
340+ endLineNumber : Number ( msg . endLine ) ,
341+ endColumn : Number ( msg . endCol ) ,
342+ status : monaco . MarkerSeverity . Error
343+ } ,
344+ children : [ ]
345+ } ;
346+ } ) ;
347+
348+ return languageProblems ;
349+ } ;
350+
351+ const activeExplore = ( tab : Partial < TabGroup > , molecule : IMoleculeContext ) => {
352+ const language = ( tab . tabId as string ) ?. split ( '_' ) ?. [ 0 ] ;
353+ const curActiveExplore = molecule . explorer . getActive ( ) || [ ] ;
354+ const isExist = curActiveExplore
355+ . map ( ( item ) => ( item as string ) . toLocaleLowerCase ( ) )
356+ . includes ( language ?. toLocaleLowerCase ( ) ) ;
357+ if ( ! isExist && language ) {
358+ const activeExploreId = SQL_LANGUAGES . find (
359+ ( item ) => item . toLocaleLowerCase ( ) === language . toLocaleLowerCase ( )
360+ ) as string ;
361+ molecule . explorer . setActive ( [ ...curActiveExplore , activeExploreId ] ?. filter ( Boolean ) ) ;
362+ }
363+ } ;
364+
365+ const parseToAST = ( molecule : IMoleculeContext , languageService : LanguageService ) => {
366+ const sql = molecule . editor . getCurrentGroup ( ) ?. editorInstance ?. getValue ( ) ;
367+
368+ const curActiveTab = molecule . editor . getCurrentTab ( ) ;
369+ const lang = curActiveTab ?. language ?. toLocaleLowerCase ( ) ;
370+ if ( lang && sql ) {
371+ languageService . parserTreeToString ( lang , sql ) . then ( ( res ) => {
372+ const pre = res ?. replace ( / ( \( | \) ) / g, '$1\n' ) ;
373+ const format = new lips . Formatter ( pre ) ;
374+ const formatted = format . format ( {
375+ indent : 2 ,
376+ offset : 2
377+ } ) ;
378+ molecule . panel . setCurrent ( molecule . builtin . getConstants ( ) . PANEL_ITEM_OUTPUT ) ;
379+ molecule . output . setState ( { value : formatted } ) ;
380+ } ) ;
198381 }
199382} ;
0 commit comments