language-tools icon indicating copy to clipboard operation
language-tools copied to clipboard

highlight loss and elment miss end tag

Open wlonghaha opened this issue 1 year ago • 6 comments

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❤

wlonghaha avatar Jul 17 '24 14:07 wlonghaha

#4295

Shyam-Chen avatar Jul 18 '24 02:07 Shyam-Chen

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:

  • There is code inside <script> or <script setup>. And the code mustn't have certain TS error. (e.g. alert or alert+1 can cause the problem while aler cannot)
  • There is a folded SFC-level block after the template block.

Also, the inspector shows that the color is correct:

kermanx avatar Jul 23 '24 15:07 kermanx

I think this is related to #4464.

kermanx avatar Aug 14 '24 16:08 kermanx

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 3. type s, server.connection.onDidOpenTextDocument is executed again. 4. the callback of server.connection.onCompletion is executed.

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

nieyuyao avatar Aug 22 '24 09:08 nieyuyao

  • 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?

johnsoncodehk avatar Aug 28 '24 06:08 johnsoncodehk

@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.

nieyuyao avatar Sep 01 '24 08:09 nieyuyao

@wlonghaha does the miss end tag problem still reproduce in the latest version?

nieyuyao avatar Oct 28 '24 11:10 nieyuyao

@wlonghaha does the miss end tag problem still reproduce in the latest version?

QQ20241029-184135

版本2.1.8 出现概率极小了,typescript版本5.5之前出现概率大点,之后版本没有问题了,不排除ts server压力大可能会复现,这问题应该无伤大雅了

ghost avatar Oct 29 '24 11:10 ghost

The issue still exists in the latest version, but it does not reproduce stably

nieyuyao avatar Dec 21 '24 07:12 nieyuyao

I debugged the code. Here is an example of a style attribute that might help. I noticed that when I quickly pressed the s and t. The server receives the didChange, completion and didChange messages. image

image

Ideally, the server should process all three messages one by one. But the completion function is asynchronous, so both didChange have already executed when the completion item is actually generated. So the length of final edit range is 2.

Before image

After image

I don't know how VSCode works. It seems to apply completions to an older version of the document (the content of the document were <div class="virus-decrypt" s> after the first didChange), so > is overwritten.

nieyuyao avatar Dec 23 '24 12:12 nieyuyao

Save the doc when server receives the completion message. Use this doc to generate completion items instead of latest. That seems to solve the problem. However, this solution is difficult to implement and may need modify lots of code.


I found that vscode-languageserver-protocol supports async message handler in the latest version. This allows the second didChange to be processed exactly after completion.

nieyuyao avatar Dec 25 '24 04:12 nieyuyao

Highlight issue has been fixed by https://github.com/volarjs/volar.js/pull/271.

If you still have problems with completion overwriting subsequent characters in v3, please open a new issue with steps to reproduce.

KazariEX avatar Jul 07 '25 14:07 KazariEX