4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
6
import * as dom from 'vs/base/browser/dom' ;
7
- import { dispose , IDisposable } from 'vs/base/common/lifecycle' ;
7
+ import { DisposableStore , dispose , IDisposable } from 'vs/base/common/lifecycle' ;
8
8
import { ContentWidgetPositionPreference , ICodeEditor , IContentWidget , IContentWidgetPosition } from 'vs/editor/browser/editorBrowser' ;
9
9
import { localize } from 'vs/nls' ;
10
10
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService' ;
@@ -17,9 +17,10 @@ import { Schemas } from 'vs/base/common/network';
17
17
import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
18
18
import { ConfigurationChangedEvent , EditorOption } from 'vs/editor/common/config/editorOptions' ;
19
19
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions' ;
20
- import { EventType as GestureEventType , Gesture } from 'vs/base/browser/touch' ;
21
20
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding' ;
22
21
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService' ;
22
+ import { IContentActionHandler , renderFormattedText } from 'vs/base/browser/formattedTextRenderer' ;
23
+ import { SelectSnippetForEmptyFile } from 'vs/workbench/contrib/snippets/browser/commands/emptyFileSnippets' ;
23
24
24
25
const $ = dom . $ ;
25
26
@@ -70,7 +71,7 @@ class UntitledTextEditorHintContentWidget implements IContentWidget {
70
71
private static readonly ID = 'editor.widget.untitledHint' ;
71
72
72
73
private domNode : HTMLElement | undefined ;
73
- private toDispose : IDisposable [ ] ;
74
+ private toDispose : DisposableStore ;
74
75
75
76
constructor (
76
77
private readonly editor : ICodeEditor ,
@@ -79,9 +80,9 @@ class UntitledTextEditorHintContentWidget implements IContentWidget {
79
80
private readonly configurationService : IConfigurationService ,
80
81
private readonly keybindingService : IKeybindingService ,
81
82
) {
82
- this . toDispose = [ ] ;
83
- this . toDispose . push ( editor . onDidChangeModelContent ( ( ) => this . onDidChangeModelContent ( ) ) ) ;
84
- this . toDispose . push ( this . editor . onDidChangeConfiguration ( ( e : ConfigurationChangedEvent ) => {
83
+ this . toDispose = new DisposableStore ( ) ;
84
+ this . toDispose . add ( editor . onDidChangeModelContent ( ( ) => this . onDidChangeModelContent ( ) ) ) ;
85
+ this . toDispose . add ( this . editor . onDidChangeConfiguration ( ( e : ConfigurationChangedEvent ) => {
85
86
if ( this . domNode && e . hasChanged ( EditorOption . fontInfo ) ) {
86
87
this . editor . applyFontInfo ( this . domNode ) ;
87
88
}
@@ -107,59 +108,56 @@ class UntitledTextEditorHintContentWidget implements IContentWidget {
107
108
this . domNode = $ ( '.untitled-hint' ) ;
108
109
this . domNode . style . width = 'max-content' ;
109
110
110
- const language = $ ( 'a.language-mode' ) ;
111
- language . style . cursor = 'pointer' ;
112
- language . innerText = localize ( 'selectAlanguage2' , "Select a language" ) ;
113
- const languageKeyBinding = this . keybindingService . lookupKeybinding ( ChangeLanguageAction . ID ) ;
114
- const languageKeybindingLabel = languageKeyBinding ?. getLabel ( ) ;
115
- if ( languageKeybindingLabel ) {
116
- language . title = localize ( 'keyboardBindingTooltip' , "{0}" , languageKeybindingLabel ) ;
117
- }
118
- this . domNode . appendChild ( language ) ;
119
-
120
- const or = $ ( 'span' ) ;
121
- or . innerText = localize ( 'or' , " or " , ) ;
122
- this . domNode . appendChild ( or ) ;
123
-
124
- const editorType = $ ( 'a.editor-type' ) ;
125
- editorType . style . cursor = 'pointer' ;
126
- editorType . innerText = localize ( 'openADifferentEditor' , "open a different editor" ) ;
127
- const selectEditorTypeKeyBinding = this . keybindingService . lookupKeybinding ( 'welcome.showNewFileEntries' ) ;
128
- const selectEditorTypeKeybindingLabel = selectEditorTypeKeyBinding ?. getLabel ( ) ;
129
- if ( selectEditorTypeKeybindingLabel ) {
130
- editorType . title = localize ( 'keyboardBindingTooltip' , "{0}" , selectEditorTypeKeybindingLabel ) ;
131
- }
132
- this . domNode . appendChild ( editorType ) ;
133
-
134
- const toGetStarted = $ ( 'span' ) ;
135
- toGetStarted . innerText = localize ( 'toGetStarted' , " to get started." ) ;
136
- this . domNode . appendChild ( toGetStarted ) ;
137
-
138
- this . domNode . appendChild ( $ ( 'br' ) ) ;
139
-
140
- const startTyping = $ ( 'span' ) ;
141
- startTyping . innerText = localize ( 'startTyping' , "Start typing to dismiss or " ) ;
142
- this . domNode . appendChild ( startTyping ) ;
111
+ const hintMsg = localize ( { key : 'message' , comment : [ 'Presereve double-square brackets and their order' ] } , '[[Select a language]], [[start with a snippet]], or [[open a different editor]] to get started.\nStart typing to dismiss or [[don\'t show]] this again.' ) ;
112
+ const hintHandler : IContentActionHandler = {
113
+ disposables : this . toDispose ,
114
+ callback : ( index , event ) => {
115
+ switch ( index ) {
116
+ case '0' :
117
+ languageOnClickOrTap ( event . browserEvent ) ;
118
+ break ;
119
+ case '1' :
120
+ snippetOnClickOrTab ( event . browserEvent ) ;
121
+ break ;
122
+ case '2' :
123
+ chooseEditorOnClickOrTap ( event . browserEvent ) ;
124
+ break ;
125
+ case '3' :
126
+ dontShowOnClickOrTap ( ) ;
127
+ break ;
128
+ }
129
+ }
130
+ } ;
143
131
144
- const dontShow = $ ( 'a' ) ;
145
- dontShow . style . cursor = 'pointer' ;
146
- dontShow . innerText = localize ( 'dontshow' , "don't show" ) ;
147
- this . domNode . appendChild ( dontShow ) ;
132
+ const hintElement = renderFormattedText ( hintMsg , {
133
+ actionHandler : hintHandler ,
134
+ renderCodeSegments : false ,
135
+ } ) ;
136
+ this . domNode . append ( hintElement ) ;
137
+
138
+ // ugly way to associate keybindings...
139
+ const keybindingsLookup = [ ChangeLanguageAction . ID , SelectSnippetForEmptyFile . Id , 'welcome.showNewFileEntries' ] ;
140
+ for ( const anchor of hintElement . querySelectorAll ( 'A' ) ) {
141
+ ( < HTMLAnchorElement > anchor ) . style . cursor = 'pointer' ;
142
+ const id = keybindingsLookup . shift ( ) ;
143
+ const title = id && this . keybindingService . lookupKeybinding ( id ) ?. getLabel ( ) ;
144
+ ( < HTMLAnchorElement > anchor ) . title = title ?? '' ;
145
+ }
148
146
149
- const thisAgain = $ ( 'span' ) ;
150
- thisAgain . innerText = localize ( 'thisAgain' , " this again." ) ;
151
- this . domNode . appendChild ( thisAgain ) ;
152
- this . toDispose . push ( Gesture . addTarget ( this . domNode ) ) ;
147
+ // the actual command handlers...
153
148
const languageOnClickOrTap = async ( e : MouseEvent ) => {
154
149
e . stopPropagation ( ) ;
155
150
// Need to focus editor before so current editor becomes active and the command is properly executed
156
151
this . editor . focus ( ) ;
157
152
await this . commandService . executeCommand ( ChangeLanguageAction . ID , { from : 'hint' } ) ;
158
153
this . editor . focus ( ) ;
159
154
} ;
160
- this . toDispose . push ( dom . addDisposableListener ( language , 'click' , languageOnClickOrTap ) ) ;
161
- this . toDispose . push ( dom . addDisposableListener ( language , GestureEventType . Tap , languageOnClickOrTap ) ) ;
162
- this . toDispose . push ( Gesture . addTarget ( language ) ) ;
155
+
156
+ const snippetOnClickOrTab = async ( e : MouseEvent ) => {
157
+ e . stopPropagation ( ) ;
158
+ this . editor . focus ( ) ;
159
+ this . commandService . executeCommand ( SelectSnippetForEmptyFile . Id , { from : 'hint' } ) ;
160
+ } ;
163
161
164
162
const chooseEditorOnClickOrTap = async ( e : MouseEvent ) => {
165
163
e . stopPropagation ( ) ;
@@ -172,20 +170,14 @@ class UntitledTextEditorHintContentWidget implements IContentWidget {
172
170
this . editorGroupsService . activeGroup . closeEditor ( activeEditorInput , { preserveFocus : true } ) ;
173
171
}
174
172
} ;
175
- this . toDispose . push ( dom . addDisposableListener ( editorType , 'click' , chooseEditorOnClickOrTap ) ) ;
176
- this . toDispose . push ( dom . addDisposableListener ( editorType , GestureEventType . Tap , chooseEditorOnClickOrTap ) ) ;
177
- this . toDispose . push ( Gesture . addTarget ( editorType ) ) ;
178
173
179
174
const dontShowOnClickOrTap = ( ) => {
180
175
this . configurationService . updateValue ( untitledTextEditorHintSetting , 'hidden' ) ;
181
176
this . dispose ( ) ;
182
177
this . editor . focus ( ) ;
183
178
} ;
184
- this . toDispose . push ( dom . addDisposableListener ( dontShow , 'click' , dontShowOnClickOrTap ) ) ;
185
- this . toDispose . push ( dom . addDisposableListener ( dontShow , GestureEventType . Tap , dontShowOnClickOrTap ) ) ;
186
- this . toDispose . push ( Gesture . addTarget ( dontShow ) ) ;
187
179
188
- this . toDispose . push ( dom . addDisposableListener ( this . domNode , 'click' , ( ) => {
180
+ this . toDispose . add ( dom . addDisposableListener ( this . domNode , 'click' , ( ) => {
189
181
this . editor . focus ( ) ;
190
182
} ) ) ;
191
183
0 commit comments