11import { Provider , Injectable , Autowired } from '@ali/common-di' ;
2+ import debounce from 'lodash.debounce' ;
23import {
34 BrowserModule ,
45 ClientAppContribution ,
@@ -9,8 +10,10 @@ import {
910 CommandService ,
1011 PreferenceProvider ,
1112 PreferenceScope ,
12- IDisposable ,
1313 Emitter ,
14+ CommandContribution ,
15+ CommandRegistry ,
16+ Disposable ,
1417} from '@ali/ide-core-browser' ;
1518import { Sequence } from '@ali/ide-core-common/lib/sequence' ;
1619import { BreadCrumbServiceImpl } from '@ali/ide-editor/lib/browser/breadcrumb' ;
@@ -28,6 +31,8 @@ import {
2831 WorkbenchEditorService ,
2932 BrowserEditorContribution ,
3033 EditorPreferences ,
34+ IEditorFeatureRegistry ,
35+ IEditor ,
3136} from '@ali/ide-editor/lib/browser' ;
3237import { IEditorDocumentModelService } from '@ali/ide-editor/lib/browser/doc-model/types' ;
3338import { FileSchemeDocumentProvider } from '@ali/ide-file-scheme/lib/browser/file-doc' ;
@@ -74,6 +79,31 @@ class FileSchemeDocumentProviderOverride extends FileSchemeDocumentProvider {
7479 */
7580@Injectable ( )
7681class WorkspacePreferenceProvider extends PreferenceProvider {
82+ constructor ( ) {
83+ super ( ) ;
84+ this . _ready . resolve ( ) ;
85+ }
86+
87+ getPreferences ( ) {
88+ return undefined ;
89+ }
90+
91+ getLanguagePreferences ( ) {
92+ return undefined ;
93+ }
94+
95+ doSetPreference ( ) {
96+ return Promise . resolve ( false ) ;
97+ }
98+ }
99+
100+ @Injectable ( )
101+ class FoldersPreferenceProvider extends PreferenceProvider {
102+ constructor ( ) {
103+ super ( ) ;
104+ this . _ready . resolve ( ) ;
105+ }
106+
77107 getPreferences ( ) {
78108 return undefined ;
79109 }
@@ -88,22 +118,36 @@ class WorkspacePreferenceProvider extends PreferenceProvider {
88118}
89119
90120@Domain ( ClientAppContribution )
91- class ThemeContribution implements ClientAppContribution {
121+ class ThemeContribution extends Disposable implements ClientAppContribution {
92122 @Autowired ( IThemeService )
93123 private readonly themeService : IThemeService ;
94124
125+ @Autowired ( PreferenceProvider , { tag : PreferenceScope . Default } )
126+ protected readonly defaultPreferenceProvider : PreferenceProvider ;
127+
95128 async initialize ( ) {
96129 this . themeService . registerThemes (
97130 IDETheme . packageJSON . contributes ! . themes ,
98131 URI . parse ( getExtensionPath ( IDETheme . extension ) )
99132 ) ;
100- await this . themeService . applyTheme ( getPreferenceThemeId ( ) ) ;
133+ // 强制用集成设置的默认主题
134+ await this . themeService . applyTheme ( this . defaultPreferenceProvider . get ( 'general.theme' ) ) ;
101135 }
102136}
103137
104- @Domain ( FileSystemContribution , BrowserEditorContribution , ClientAppContribution )
138+ @Domain (
139+ FileSystemContribution ,
140+ BrowserEditorContribution ,
141+ ClientAppContribution ,
142+ CommandContribution
143+ )
105144class EditorSpecialContribution
106- implements FileSystemContribution , BrowserEditorContribution , ClientAppContribution {
145+ extends Disposable
146+ implements
147+ FileSystemContribution ,
148+ BrowserEditorContribution ,
149+ ClientAppContribution ,
150+ CommandContribution {
107151 @Autowired ( WorkbenchEditorService )
108152 editorService : WorkbenchEditorService ;
109153
@@ -125,8 +169,6 @@ class EditorSpecialContribution
125169 @Autowired ( SCMService )
126170 scmService : SCMService ;
127171
128- private readonly disposables : IDisposable [ ] = [ ] ;
129-
130172 async mountFileSystem ( rootFS : FileSystemInstance < 'MountableFileSystem' > ) {
131173 // TODO: 提供配置选择存储在内存中还是 indexedDB 中
132174 const {
@@ -161,7 +203,7 @@ class EditorSpecialContribution
161203 } ) ;
162204 rootFS . mount ( this . appConfig . workspaceDir , overlayFileSystem ) ;
163205 rootFS . mount ( SCM_ROOT , editorSystem ) ;
164- this . disposables . push ( {
206+ this . addDispose ( {
165207 dispose : ( ) => {
166208 rootFS . umount ( this . appConfig . workspaceDir ) ;
167209 rootFS . umount ( SCM_ROOT ) ;
@@ -194,31 +236,37 @@ class EditorSpecialContribution
194236 if ( isCodeDocumentModel ( documentModel ) ) {
195237 this . openCodeEditor ( documentModel . ref , documentModel . filepath ) ;
196238 // 监听 props 变化
197- onSelect (
198- ( props ) => props . documentModel ,
199- ( newModel : CodeDocumentModel , oldModel : CodeDocumentModel ) =>
200- newModel . filepath === oldModel . filepath && newModel . ref === oldModel . ref
201- ) ( ( newModel : CodeDocumentModel ) => {
202- this . openCodeEditor ( newModel . ref , newModel . filepath ) ;
203- } ) ;
239+ this . addDispose (
240+ onSelect (
241+ ( props ) => props . documentModel ,
242+ ( newModel : CodeDocumentModel , oldModel : CodeDocumentModel ) =>
243+ newModel . filepath === oldModel . filepath && newModel . ref === oldModel . ref
244+ ) ( ( newModel : CodeDocumentModel ) => {
245+ this . openCodeEditor ( newModel . ref , newModel . filepath ) ;
246+ } )
247+ ) ;
204248 } else {
205249 this . openEditor ( documentModel . filepath ) ;
206250 // 监听 props 变化
207- onSelect ( ( props ) => props . documentModel . filepath ) ( ( newFilepath ) => {
208- this . openEditor ( newFilepath ) ;
209- } ) ;
251+ this . addDispose (
252+ onSelect ( ( props ) => props . documentModel . filepath ) ( ( newFilepath ) => {
253+ this . openEditor ( newFilepath ) ;
254+ } )
255+ ) ;
210256 }
211257
212- onSelect ( ( props ) => props . documentModel . encoding ) ( ( encoding ) => {
213- if ( encoding ) {
214- const resource = this . editorService . currentResource ;
215- if ( resource ) {
216- this . editorDocumentModelService . changeModelOptions ( resource . uri , {
217- encoding,
218- } ) ;
258+ this . addDispose (
259+ onSelect ( ( props ) => props . documentModel . encoding ) ( ( encoding ) => {
260+ if ( encoding ) {
261+ const resource = this . editorService . currentResource ;
262+ if ( resource ) {
263+ this . editorDocumentModelService . changeModelOptions ( resource . uri , {
264+ encoding,
265+ } ) ;
266+ }
219267 }
220- }
221- } ) ;
268+ } )
269+ ) ;
222270 }
223271
224272 private openEditor ( relativePath : string ) {
@@ -234,8 +282,95 @@ class EditorSpecialContribution
234282 return this . openEditor ( `${ encodeURIComponent ( ref ) } /${ filepath } ` ) ;
235283 }
236284
237- dispose ( ) {
238- this . disposables . forEach ( ( disposer ) => disposer . dispose ( ) ) ;
285+ registerCommands ( registry : CommandRegistry ) {
286+ registry . registerCommand (
287+ { id : 'alex.codeServiceProject' } ,
288+ {
289+ execute : ( ) => {
290+ const documentModel = select ( ( props ) => props . documentModel ) ;
291+ if ( ! isCodeDocumentModel ( documentModel ) ) return ;
292+ return {
293+ platform : 'antcode' ,
294+ project : `${ documentModel . owner } /${ documentModel . name } ` ,
295+ commit : documentModel . ref ,
296+ rootUri : URI . file ( this . appConfig . workspaceDir ) . resolve ( documentModel . ref ) . codeUri ,
297+ } ;
298+ } ,
299+ }
300+ ) ;
301+ }
302+
303+ registerEditorFeature ( registry : IEditorFeatureRegistry ) {
304+ registry . registerEditorFeatureContribution ( {
305+ contribute : ( editor : IEditor ) => {
306+ const disposer = new Disposable ( ) ;
307+ let oldHoverDecorations : string [ ] = [ ] ;
308+ disposer . addDispose (
309+ editor . monacoEditor . onMouseMove (
310+ debounce ( ( event ) => {
311+ const type = event ?. target ?. type ;
312+ if (
313+ type === monaco . editor . MouseTargetType . GUTTER_LINE_NUMBERS ||
314+ type === monaco . editor . MouseTargetType . GUTTER_GLYPH_MARGIN
315+ ) {
316+ const lineNumber = event . target . position ! . lineNumber ;
317+ oldHoverDecorations = editor . monacoEditor . deltaDecorations ( oldHoverDecorations , [
318+ {
319+ range : new monaco . Range ( lineNumber , 1 , lineNumber , 1 ) ,
320+ options : {
321+ className : 'alex-line-content' ,
322+ glyphMarginClassName : `alex-line-glyph-margin}` ,
323+ } ,
324+ } ,
325+ ] ) ;
326+ } else {
327+ oldHoverDecorations = editor . monacoEditor . deltaDecorations ( oldHoverDecorations , [ ] ) ;
328+ }
329+ } , 10 )
330+ )
331+ ) ;
332+ let oldClickDecorations : string [ ] = [ ] ;
333+ const highlightLine = ( lineNumber : number ) => {
334+ oldClickDecorations = editor . monacoEditor . deltaDecorations ( oldClickDecorations , [
335+ {
336+ range : new monaco . Range ( lineNumber , 1 , lineNumber , 1 ) ,
337+ options : {
338+ isWholeLine : true ,
339+ className : 'alex-line-content' ,
340+ } ,
341+ } ,
342+ ] ) ;
343+ } ;
344+ disposer . addDispose (
345+ editor . monacoEditor . onMouseDown ( ( event ) => {
346+ const type = event ?. target ?. type ;
347+ if (
348+ type === monaco . editor . MouseTargetType . GUTTER_LINE_NUMBERS ||
349+ type === monaco . editor . MouseTargetType . GUTTER_GLYPH_MARGIN
350+ ) {
351+ const lineNumber = event . target . position ! . lineNumber ;
352+ // 非受控
353+ if ( ! ( 'lineNumber' in select ( ( props ) => props . documentModel ) ) ) {
354+ highlightLine ( lineNumber ) ;
355+ }
356+ select ( ( props ) => props . documentModel . onLineNumberChange ) ?.( lineNumber ) ;
357+ }
358+ } )
359+ ) ;
360+ const initialLineNumber = select ( ( props ) => props . documentModel . lineNumber ) ;
361+ if ( initialLineNumber ) {
362+ highlightLine ( initialLineNumber ) ;
363+ }
364+ disposer . addDispose (
365+ onSelect ( ( props ) => props . documentModel . lineNumber ) ( ( newLineNumber ) => {
366+ if ( newLineNumber ) {
367+ highlightLine ( newLineNumber ) ;
368+ }
369+ } )
370+ ) ;
371+ return disposer ;
372+ } ,
373+ } ) ;
239374 }
240375}
241376
@@ -258,6 +393,12 @@ export class EditorSpecialModule extends BrowserModule {
258393 tag : PreferenceScope . Workspace ,
259394 override : true ,
260395 } ,
396+ {
397+ token : PreferenceProvider ,
398+ useClass : FoldersPreferenceProvider ,
399+ tag : PreferenceScope . Folder ,
400+ override : true ,
401+ } ,
261402 ThemeContribution ,
262403 EditorSpecialContribution ,
263404 ] ;
0 commit comments