4

Recently, the project has implemented a prompt function, input a certain symbol, display the matching content, similar to the code prompt function. Finally, I chose monaco-editor , a js library developed by Microsoft, and vscode was also developed based on this library.

During the development process, I encountered some problems. Because the documentation was not very friendly, it took a long time to solve the problem. The following mainly records the problems and solutions, and hope that children's shoes who encounter these problems in the future can quickly avoid the pit.

Problems encountered and solutions

problem:

Use monaco-editor in Antd Modal. After displaying Modal, close Modal and open Modal again. The prompt content of monaco-editor will be repeated. If Modal is displayed several times, the corresponding content will be repeated several times, as shown in the figure below:

demo

Solution

Idea 1:
After debugging, it was found that the registerCompletionItemProvider method was executed multiple times. The first guess was that the plug-in was created multiple times without being destroyed. After consulting the corresponding document, it was found that a plug-in provided a method of destruction:

monaco.editor.dispose()

So, try to call the above method before the component is destroyed, but after running it is found that it does not take effect, the above problem still exists, this method does not work~

Idea 2:
Since registerCompletionItemProvider executed multiple times, add a global counter count to the component. After the component is registered once, count+1 is executed once. Only when count===0, the corresponding plug-in registration logic is taken, otherwise the cached data is directly taken . Some code snippets are as follows:

 let count = 0;
      monaco.languages.registerCompletionItemProvider(languageName, {
        triggerCharacters: ['['],
        provideCompletionItems: function (model, position, context) {
          count=count+1;
          if(count===1){
            let suggestions = [];
            if (context.triggerCharacter === '[') {
              [...dimensions, ...modules].forEach((item, index) => {
                suggestions.push({
                  label: item.customName,
                  insertText: `${item.customName}]`,
                  kind: 12,
                });
              });
            }
            return { suggestions };
          }
        },
      });

This method is simple and rude. If the content prompted by the plug-in is fixed, the problem can be solved by directly using the cached data. but! ! ! The demand I encountered is that the content of the prompt is dynamically fetched according to the interface. Therefore, this method still doesn't work~

Idea 3:
Since neither Google nor Baidu found a satisfactory answer, so I went to the monaco-editor of GitHub of issues to find the answer. At first, I searched according to the registerCompletionItemProvider , but there was no similar problem. Then I tried to search for the provideCompletionItems , and finally it was in issues. Found 2 similar problems, the links are as follows:

https://github.com/microsoft/monaco-editor/issues/2217

https://github.com/microsoft/monaco-editor/issues/2084

The final solution:
When registerCompletionItemProvider , store the created objects as follows:

 monacoProviderRef.current = monaco.languages.registerCompletionItemProvider(languageName, {

When the component is destroyed, the objects generated by editor and registerCompletionItemProvider code show as below:

useEffect(() => {
      // todo
      // xxxxxx
      return () => {
        // 销毁
        monacoProviderRef.current?.dispose();
        monacoRef.current?.dispose();
        
      };
    }, []);

In the final test, the bug is solved perfectly!

problem:

sets the default theme of the editor, but when Modal is displayed for the first time, the default theme does not take effect. The theme will take effect after the first time, as shown in the following figure:

The code for setting the default theme is as follows:

monaco.editor.defineTheme('myCoolTheme', {
        base: 'vs',
        inherit: false,
        colors: { token: 'value', foreground: '#00c1de' },
        rules: [{ token: 'value', foreground: '#00c1de' }],
      });

Solution

Go to the official document to find the API for setting the theme, and find that the above code is a definition operation for the theme. If you want to run it for the first time, you also need to manually set the theme defined above.

monaco.editor.setTheme('myCoolTheme');

In the end, the problem is solved, and the effect is as follows:

May there be no unsolvable bugs in the world! Happy Mid-autumn Festival! ! !

卖女孩的小火柴
2k 声望260 粉丝

while(1){