@@ -73,6 +73,7 @@ const MonacoEditorCore: React.FC<CommonEditorProps> = (props) => {
7373 fontFamily : nodeStyle . fontFamily ,
7474 automaticLayout : true ,
7575 'semanticHighlighting.enabled' : true ,
76+ autoClosingOvertype : 'always' ,
7677 } ) ;
7778 setEditor ( editor ) ;
7879
@@ -81,93 +82,122 @@ const MonacoEditorCore: React.FC<CommonEditorProps> = (props) => {
8182 editor . focus ( ) ;
8283 } , [ ] ) ;
8384
84- useEditorProp ( editor , props . onEditCode , ( _editor , model , onEditCode ) => {
85- model . onDidChangeContent ( ( ) => {
86- onEditCode ( model . getValue ( ) ) ;
87- } ) ;
88- } ) ;
89-
90- useEditorProp ( editor , props . execute , ( editor , _model , execute ) => {
91- editor . addCommand ( monaco . KeyMod . CtrlCmd | monaco . KeyCode . Enter , ( ) => {
92- execute ( ) ;
93- } ) ;
94- // Ace's Vim mode runs code with :w, so let's do the same
95- editor . addCommand ( monaco . KeyMod . CtrlCmd | monaco . KeyCode . KeyS , ( ) => {
96- execute ( ) ;
97- } ) ;
98- } ) ;
85+ useEditorProp (
86+ editor ,
87+ props . onEditCode ,
88+ useCallback ( ( _editor , model , onEditCode ) => {
89+ model . onDidChangeContent ( ( ) => {
90+ onEditCode ( model . getValue ( ) ) ;
91+ } ) ;
92+ } , [ ] ) ,
93+ ) ;
9994
100- useEditorProp ( editor , props . code , ( editor , model , code ) => {
101- // Short-circuit if nothing interesting to change.
102- if ( code === model . getValue ( ) ) {
103- return ;
104- }
95+ useEditorProp (
96+ editor ,
97+ props . execute ,
98+ useCallback ( ( editor , _model , execute ) => {
99+ editor . addCommand ( monaco . KeyMod . CtrlCmd | monaco . KeyCode . Enter , ( ) => {
100+ execute ( ) ;
101+ } ) ;
102+ // Ace's Vim mode runs code with :w, so let's do the same
103+ editor . addCommand ( monaco . KeyMod . CtrlCmd | monaco . KeyCode . KeyS , ( ) => {
104+ execute ( ) ;
105+ } ) ;
106+ } , [ ] ) ,
107+ ) ;
105108
106- editor . executeEdits ( 'redux' , [
107- {
108- text : code ,
109- range : model . getFullModelRange ( ) ,
110- } ,
111- ] ) ;
112- } ) ;
109+ useEditorProp (
110+ editor ,
111+ props . code ,
112+ useCallback ( ( editor , model , code ) => {
113+ // Short-circuit if nothing interesting to change.
114+ if ( code === model . getValue ( ) ) {
115+ return ;
116+ }
117+
118+ editor . executeEdits ( 'redux' , [
119+ {
120+ text : code ,
121+ range : model . getFullModelRange ( ) ,
122+ } ,
123+ ] ) ;
124+ } , [ ] ) ,
125+ ) ;
113126
114- useEditorProp ( editor , theme , ( editor , _model , theme ) => {
115- editor . updateOptions ( { theme } ) ;
116- } ) ;
127+ useEditorProp (
128+ editor ,
129+ theme ,
130+ useCallback ( ( editor , _model , theme ) => {
131+ editor . updateOptions ( { theme } ) ;
132+ } , [ ] ) ,
133+ ) ;
117134
118135 const autocompleteProps = useMemo (
119136 ( ) => ( { autocompleteOnUse, crates : props . crates } ) ,
120137 [ autocompleteOnUse , props . crates ] ,
121138 ) ;
122139
123- useEditorProp ( editor , autocompleteProps , ( _editor , _model , { autocompleteOnUse, crates } ) => {
124- completionProvider . current = monaco . languages . registerCompletionItemProvider ( 'rust' , {
125- triggerCharacters : [ ' ' ] ,
126-
127- provideCompletionItems ( model , position , _context , _token ) {
128- const word = model . getWordUntilPosition ( position ) ;
129-
130- function wordBefore (
131- word : monaco . editor . IWordAtPosition ,
132- ) : monaco . editor . IWordAtPosition | null {
133- const prevPos = { lineNumber : position . lineNumber , column : word . startColumn - 1 } ;
134- return model . getWordAtPosition ( prevPos ) ;
135- }
136-
137- const preWord = wordBefore ( word ) ;
138- const prePreWord = preWord && wordBefore ( preWord ) ;
139-
140- const oldStyle = prePreWord ?. word === 'extern' && preWord ?. word === 'crate' ;
141- const newStyle = autocompleteOnUse && preWord ?. word === 'use' ;
142-
143- const triggerPrefix = oldStyle || newStyle ;
144-
145- if ( ! triggerPrefix ) {
146- return { suggestions : [ ] } ;
147- }
148-
149- const range = {
150- startLineNumber : position . lineNumber ,
151- endLineNumber : position . lineNumber ,
152- startColumn : word . startColumn ,
153- endColumn : word . endColumn ,
154- } ;
155-
156- const suggestions = crates . map ( ( { name, version, id } ) => ( {
157- kind : monaco . languages . CompletionItemKind . Module ,
158- label : `${ name } (${ version } )` ,
159- insertText : `${ id } ; // ${ version } ` ,
160- range,
161- } ) ) ;
162-
163- return { suggestions } ;
164- } ,
165- } ) ;
140+ useEditorProp (
141+ editor ,
142+ autocompleteProps ,
143+ useCallback ( ( _editor , _model , { autocompleteOnUse, crates } ) => {
144+ completionProvider . current = monaco . languages . registerCompletionItemProvider ( 'rust' , {
145+ triggerCharacters : [ ' ' ] ,
146+
147+ provideCompletionItems ( model , position , _context , _token ) {
148+ const word = model . getWordUntilPosition ( position ) ;
149+
150+ function wordBefore (
151+ word : monaco . editor . IWordAtPosition ,
152+ ) : monaco . editor . IWordAtPosition | null {
153+ const prevPos = { lineNumber : position . lineNumber , column : word . startColumn - 1 } ;
154+ return model . getWordAtPosition ( prevPos ) ;
155+ }
156+
157+ const preWord = wordBefore ( word ) ;
158+ const prePreWord = preWord && wordBefore ( preWord ) ;
159+
160+ const oldStyle = prePreWord ?. word === 'extern' && preWord ?. word === 'crate' ;
161+ const newStyle = autocompleteOnUse && preWord ?. word === 'use' ;
162+
163+ const triggerPrefix = oldStyle || newStyle ;
164+
165+ if ( ! triggerPrefix ) {
166+ return { suggestions : [ ] } ;
167+ }
168+
169+ const range = {
170+ startLineNumber : position . lineNumber ,
171+ endLineNumber : position . lineNumber ,
172+ startColumn : word . startColumn ,
173+ endColumn : word . endColumn ,
174+ } ;
175+
176+ const suggestions = crates . map ( ( { name, version, id } ) => ( {
177+ kind : monaco . languages . CompletionItemKind . Module ,
178+ label : `${ name } (${ version } )` ,
179+ insertText : `${ id } ; // ${ version } ` ,
180+ range,
181+ } ) ) ;
182+
183+ return { suggestions } ;
184+ } ,
185+ } ) ;
186+
187+ return ( ) => {
188+ completionProvider . current ?. dispose ( ) ;
189+ } ;
190+ } , [ ] ) ,
191+ ) ;
166192
167- return ( ) => {
168- completionProvider . current ?. dispose ( ) ;
169- } ;
170- } ) ;
193+ useEditorProp (
194+ editor ,
195+ props . position ,
196+ useCallback ( ( editor , _model , { line, column } ) => {
197+ editor . setPosition ( { lineNumber : line , column } ) ;
198+ editor . focus ( ) ;
199+ } , [ ] ) ,
200+ ) ;
171201
172202 return < div className = { styles . monaco } ref = { child } /> ;
173203} ;
0 commit comments