Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot distinguish between semantic token types and modifiers with the same name #4659

Closed
oxalica opened this issue May 31, 2023 · 19 comments
Closed

Comments

@oxalica
Copy link
Contributor

oxalica commented May 31, 2023

Result from CocInfo

## versions

vim version: NVIM v0.9.0
node version: v18.16.0
coc.nvim version: 0.0.82-b7375d5f 2023-01-30 05:09:03 +0800
coc.nvim directory: /nix/store/maqb95048mnnn5kl13wl3r01c9bgwk9c-vimplugin-coc.nvim-2023-01-29
term: tmux
platform: linux

Describe the bug

See: rust-lang/rust-analyzer#14795 (comment)

rust-analyzer recently added a macro modifier to all tokens inside macro invocations, which cause them to be all displayed as the same color of the macro itself, because CocSemMacro is defined by default. But this name is originally for token type macro, not modifier macro.

Reproduce the bug

  • Install coc-rust-analyzer and a recent rust-analyzer like 2023-05-22 or later

  • Create a rust library project with the following content in lib.rs

macro_rules! foo {
    ($item:item) => {
        $item
    };
}

foo! {
    pub struct Foo;
}
  • All tokens inside the macro invocation (line 8) are displayed as CocSemMacro highlighting. But should be colored as CocSemKeyword and CocSemStruct.

Output of CocCommand semanticTokens.inspect on the pub token inside macro invocation.

Type: keyword
Modifiers: macro
Highlight group: CocSemMacro

image

@fannheyward
Copy link
Member

fannheyward commented Jun 1, 2023

Reproduced and got your point. I got some questions about semanticToken highlighting, and I'd like to see your option as you're language server author :D.

From LSP, a token is composed with one token type and n token modifiers, n can be zero.

By default, coc.nvim defined some hi group like CocSemKeyword, here Keyword is token type, coc.nvim didn't handles modifier in default hi groups.

After language server responses tokens, coc.nvim parsed and converted to vim's hi group, in following rules:

  1. CocSem + modifier + type
  2. CocSem + modifier (I think this is incorrect because a token should must have type
  3. CocSem + type

For line-8 pub keyword

  1. first goes to CocSemMacroKeyword, no such hi group found in default groups, fail
  2. in early version of RA, no modifiers returns, no hi group, in newer release, goes to CocSemMacro
  3. in early version, goes to CocSemKeyword, with latest release, we finally got CocSemMacro, this is the issue.

Solutions:

  1. defines more hi groups by default. Cause a token can has n modifiers, I think this is hard to define all hi groups
  2. with a limit count hi groups defined by default, and change the rules to CocSem + modifier + type for all modifiers, fallback to CocSem + type if no modifiers found, didn't check found or not in default hi groups, leave them for user to define.

In this case, line-8 Foo goes to CocSemDeclarationStruct, CocSemMacroStruct and CocSemPublicStruct, you can define want as you like.

截屏2023-06-01 19 35 24

What do you think?

@oxalica
Copy link
Contributor Author

oxalica commented Jun 1, 2023

2. with a limit count hi groups defined by default, and change the rules to CocSem + modifier + type for all modifiers, fallback to CocSem + type if no modifiers found, didn't check found or not in default hi groups, leave them for user to define.

So that's basically removing the rule 2 CocSem + modifier, yes? So this will no longer work:

hi link CocSemDefaultLibrary TSOtherDefaultLibrary

To me, removing this support and always requiring a token type in hlgroups sound reasonable, since token type is more primary while modifiers are secondary and kinda optional. But not sure how many ones are relying on this feature.

@fannheyward
Copy link
Member

removing the rule 2 CocSem + modifier

We should keep this, CocSem + modifier is still useful. We can keep our 3-rules, key point is: don't limit default groups must have the highlight exist, and allow multiple highlight for same token.

  • CocSem + type
  • CocSem + modifier
  • CocSem + modifier + type

@oxalica
Copy link
Contributor Author

oxalica commented Jun 4, 2023

We should keep this, CocSem + modifier is still useful. We can keep our 3-rules, key point is: don't limit default groups must have the highlight exist.

Sorry I don't get it. What do you mean by "don't limit default groups must have the highlight exist"? Making default groups non-existent?

, and allow multiple highlight for same token

If there are multiple highlights, we still need to define priorities yeah? We cannot apply all colors to a single token.

My basic expectation is:

  • Tokens with type=Keyword and modifier=[macro], that are macro arguments, should apply CocSemKeyword. Don't use CocSemMacro -- this is coc.nvim currently using.
  • Tokens with type=Macro and modifiers=[whatever], that is the macro itself, should apply CocSemMacro.

Thus my suggestion is to either remove rule 2, or swap the priority of rule 2&3.

@fannheyward
Copy link
Member

fannheyward commented Jun 5, 2023

What do you mean by "don't limit default groups must have the highlight exist"?

In current implementation, coc.nvim defined default groups in vim file as you see (CocSemKeyword/CocSemFunction etc). After LS returns tokens, coc.nvim creates hi group with rules 1/2/3, then checks the group exists in highlightGroups or not, only use it as found in default groups, otherwise, no hi group returns for the token.

Removing this limit, a hi group can be created even if not defined, user can define the missing group.

nvim-lsp's rule:

@lsp.type.<type>.<ft> for the type
@lsp.mod.<mod>.<ft> for each modifier
@lsp.typemod.<type>.<mod>.<ft> for each modifier

suggestion is to either remove rule 2, or swap the priority of rule 2&3.

New rules:

  • CocSem + type
  • CocSem + modifier
  • CocSem + modifier + type

fannheyward added a commit that referenced this issue Jun 5, 2023
CocSem + type
CocSem + modifier
CocSem + modifier + type

The highlight group didn't need to be defined first

related #4659
@oxalica
Copy link
Contributor Author

oxalica commented Jun 6, 2023

Removing this limit, a hi group can be created even if not defined, user can define the missing group.

My issue is not about user customization. Sending all groups instead of one does NOT help here. It's only causing more unnecessary computation and updates.

New rules:

* `CocSem + type`

* `CocSem + modifier`

* `CocSem + modifier + type`

This sill collides then type==modifier. I only want to define for type=macro, NOT modifier=macro. What should I write? highlight CocSemMacro ... defines both type=macro and modifier=macro, which is wrong.

@fannheyward
Copy link
Member

@oxalica sorry but I was completely forcing my attention on the default hi groups limitation, and totally ignored the priority issue you already pointed out.

I checked nvim-lsp's rules, how about this?

  • CocSemType + type
  • CocSemMod + modifier
  • CocSemTypeMod + type + modifier

The CocSemTypeMacro is what you want.

My preview fix removed the limitation to allow to create hi groups, one or multiple signs for one token. Yes, this may bring more updating.

fannheyward added a commit that referenced this issue Jun 7, 2023
CocSem + Type + type
CocSem + Mod + modifier
CocSem + TypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
@oxalica
Copy link
Contributor Author

oxalica commented Jun 7, 2023

I checked nvim-lsp's rules, how about this?

* `CocSemType + type`

* `CocSemMod + modifier`

* `CocSemTypeMod + type + modifier`

The CocSemTypeMacro is what you want.

This should work. 👍 Just that it breaks users' current configurations. If coc.nvim allows such a breaking change, it's okay to me.

fannheyward added a commit that referenced this issue Jun 8, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Jun 28, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
@fannheyward
Copy link
Member

one or multiple signs for one token

This bring some flicking on CursorMoved:

  1. applies multiple signs to one token
  2. onCursorMoved, coc will highlight visible range/regions
  3. requests range or full tokens from LS
  4. diffHighlights with current visible start/end
  5. applies diff highlights

step 4 is the issue: there will still be new added highlights even the document is not modified, this makes the flicking.

Checking on the diffHighlights logic.

fannheyward added a commit that referenced this issue Aug 24, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
@oxalica
Copy link
Contributor Author

oxalica commented Nov 2, 2023

What's the status of this issue? I saw 9ae8651 is in dev branch but still not reach master.

fannheyward added a commit that referenced this issue Nov 3, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
@fannheyward
Copy link
Member

@oxalica dev branch is just rebase master and some unmerged PRs, for unable to merge to master usage.

#4667 brought flicking issue #4659 (comment), maybe this is not a good solution or needs more improvement.

sorry for the slow response.

@oxalica
Copy link
Contributor Author

oxalica commented Nov 3, 2023

#4667 brought flicking issue #4659 (comment), maybe this is not a good solution or needs more improvement.

I don't really think it's blocking hlgroup renaming. For this particular issue, I just want CocSemType*, CocSemMod*, CocSemTypeMod* hlgroups so that I can highlight them differently.

I guess the flicking issue is about 0cb6074#diff-610be46d48af22f1bc73dff66ee66e288671c57f1130353bc88d3fc65379eadbR241 which add multiple highlights on the same token. Will it work if we keep the old code (if + for find the first one) to only push one highlight, just rename the hlgroup names?

@fannheyward
Copy link
Member

@oxalica thank you for your help, will check #4667 later this week, a little busy recently.

@fannheyward
Copy link
Member

fannheyward commented Nov 10, 2023

Will it work if we keep the old code (if + for find the first one) to only push one highlight

I have a new thought:

  1. has tokenModifiers => CocSemTypeMod*, for multiple modifiers, only use first one to avoid flicking
  2. if not modifiers => CocSemType*, as the fallback one
  3. no more CocSemMod*

back to your code, struct goes to CocSemTypeModKeywordMacro. What do you think?

#4667 has updated, in my tests, no more flicking.

I'm digging vscode source to find how vscode handle this...

fannheyward added a commit that referenced this issue Nov 10, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
@fannheyward

This comment was marked as outdated.

@oxalica
Copy link
Contributor Author

oxalica commented Nov 10, 2023

Thanks for the update.

I have a new thought:

1. has `tokenModifiers` => `CocSemTypeMod*`, for multiple modifiers, only use first one to avoid flicking

2. if not modifiers => `CocSemType*`, as the fallback one

3. no more `CocSemMod*`

I personally think CocSemMod* is still useful in some situations, but mostly can be replaced with TypeMod* by listing all types using that modifier. I do use builtins modifier in nil LSP and want to highlight all token types with that modifier with the same color. I don't have a strong opinion on this.

back to your code, struct goes to CocSemTypeModKeywordMacro. What do you think?

What I want is CocSemTypeMacro, which is already included in the PR. It works for me.

@fannheyward
Copy link
Member

What I want is CocSemTypeMacro

struct won't go to this, RA returns this:

tokenType: keyword
tokenModifiers: [ 'macro' ]

@oxalica
Copy link
Contributor Author

oxalica commented Nov 10, 2023

What I want is CocSemTypeMacro

struct won't go to this, RA returns this:

tokenType: keyword
tokenModifiers: [ 'macro' ]

No. I DO NOT want the struct in screenshot to be highlighted as macro, it should be CocSemTypeKeyword. I only expect the foo! (type="macro") to be highlighted CocSemTypeMacro.

@fannheyward
Copy link
Member

@oxalica fixed

fannheyward added a commit that referenced this issue Nov 10, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Nov 14, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Nov 14, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Nov 17, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Nov 27, 2023
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Jan 3, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Jan 18, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Jan 18, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Jan 22, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Feb 19, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Feb 21, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Feb 21, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Feb 22, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Feb 22, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Feb 22, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Feb 27, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Mar 20, 2024
CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659
fannheyward added a commit that referenced this issue Mar 20, 2024
* feat(semanticTokens)!: token highlight groups

CocSemType + type
CocSemMod + modifier
CocSemTypeMod + type + modifier

The highlight group didn't need to be defined first

related #4659

* feat(semanticTokens)!: token highlight groups

CocSemType + type
CocSemTypeMod + type + modifier

* fix(highlight): check hlexists for vim

* feat(semanticTokens): rm modifiers in checkCurrent

modifiers are added to one token type, we can't list them directly

* feat(semanticTokens): follow tree-sitter's hi name

nvim-treesitter/nvim-treesitter#5895
nvim-treesitter/nvim-treesitter@1ae9b0e

* feat(highlight): coc_highlight_maximum_count 200
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants