vuejs / language-tools

⚡ High-performance Vue language tooling based-on Volar.js
https://marketplace.visualstudio.com/items?itemName=Vue.volar
MIT License
5.79k stars 390 forks source link

highlight loss and elment miss end tag #4593

Open wlonghaha opened 2 months ago

wlonghaha commented 2 months ago

Vue - Official extension or vue-tsc version

v2.0.26

VSCode version

1.91.1

Vue version

3.4.31

TypeScript version

5.5.2

System Info

System:
    OS: Windows 10 10.0.19044
    CPU: (12) x64 AMD Ryzen 5 5600 6-Core Processor
    Memory: 18.51 GB / 23.92 GB
  Binaries:
    Node: 20.15.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.7.0 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.5.0 - ~\AppData\Roaming\npm\pnpm.CMD
  Browsers:
    Internet Explorer: 11.0.19041.1566

Steps to reproduce

1.创建项目: pnpm create vite --template vue-ts my-project 2.在App.vue中声明变量: const count = ref(0); 3.折叠style块,会出现行<HelloWorld msg="Vite + Vue" />高亮丢失 4.在<HelloWorld msg="Vite + Vue" />下面再写同样的声明(不复制),写完<HelloWorld />后,紧贴着/左边填写msg字母并根据提示回车后,会出现/丢失(不是百分百出现,建议多尝试,复现概率较高)

QQ_1721224797132

QQ_1721225037884

QQ_1721225375683

What is expected?

HelloWorld组件高亮显示,组件自闭合标签/不丢失

What is actually happening?

HelloWorld组件高亮丢失,组件自闭合标签/在属性补充时缺失

Link to minimal reproduction

No response

Any additional comments?

thanks for you job❤

Shyam-Chen commented 2 months ago

4295

KermanX commented 2 months ago

The highlight lost problem is reproducible, and the completion problem is tracked in #4295.

The strange thing is that the highlight loss only happens when:

Also, the inspector shows that the color is correct:

KermanX commented 1 month ago

I think this is related to #4464.

nieyuyao commented 1 month ago

I find that using setTimeout to wrap the relevant code will increase the probability of completion problem.

server.connection.onCompletion(async (params, token) => {
                const uri = vscode_uri_1.URI.parse(params.textDocument.uri);
                return new Promise(resolve => {  
                    setTimeout(() => {   // -> using setTimout to wrap code
                        worker(uri, token, async (languageService) => {
                            lastCompleteUri = params.textDocument.uri;
                            lastCompleteLs = languageService;
                            const list = await languageService.getCompletionItems(uri, params.position, params.context, token);
                            for (const item of list.items) {
                                fixTextEdit(initializeParams, item);
                            }
                            return list;
                        }).then(result => resolve(result))
                    }, 1000)
                })
            });

I debugged the code and found that the complete problem seems to be related to the execution order of server.connection.onCompletion and server.connection.onDidOpenTextDocument. For example, the completion option is msg="", the steps when the problem occurs are as follows,

  1. type m, server.connection.onDidOpenTextDocument is executed.
  2. server.connection.onCompletion is triggered, but execution is delayed(setTimeout).

https://github.com/volarjs/volar.js/blob/3215b596837e439fb3b8d80bf7ea32c90d417948/packages/language-server/lib/features/languageFeatures.ts#L766-L782

  1. type s, server.connection.onDidOpenTextDocument is executed again.
  2. the callback of server.connection.onCompletion is executed.

It seems to be no problem if step 4 is before step 3.

johnsoncodehk commented 1 month ago
  • type m, server.connection.onDidOpenTextDocument is executed.
    1. type s, server.connection.onDidOpenTextDocument is executed again.

@nieyuyao what do type m, type s mean here?

nieyuyao commented 4 weeks ago

@nieyuyao what do type m, type s mean here?

what I mean is that when we entered msg, we actually received m first, and then we received s. onDidOpenTextDocument will be triggered in sequence.