Skip to content

Conversation

folke
Copy link
Member

@folke folke commented Dec 12, 2022

This PR adds vim.inspect_pos(), vim.show_pos() and :Inspect to get/show the items at a given buffer position.

This PR includes 2e328ba vim.semantic_tokens.get_at_pos

Right now, the function uses nvim_echo, but I can change it to use a floating window if that would be better suited.

Todo

  • add special handling for semantic token types and modifiers. Would be great if feat(lsp): utility functions for getting and showing tokens #21373 could be re-opened and merged to implement this
  • put the nvim_create_user_command somewhere. What would be the best place for this? _editor.lua? plugin/inspector.lua?
  • improve the docs on the return values
  • add something to news.txt

Included Items

  • Treesitter captures
  • Semantic Tokens
  • Syntax Highlight Groups
  • Extmarks

Implementation details

  • The implementation resides in runtime/lua/vim/_inspector.lua
  • The submodule is lazy-loaded inside _init_packages.lua, so there's no impact on performance
  • If you want to test, make sure to build Neovim so the lazy-loading is included
  • any parameter can be nil, meaning the position under the cursor

User Commands

  • :Inspect is the same as vim.show_pos()
  • :Inspect! is the same as vim.pretty_print(vim.inspect_pos())

vim.show_pos(bufnr, row, col, filter)

image

image

vim.inspect_pos(bufnr, row, col, filter)

{
  extmarks = { {
      col = 6,
      id = 190,
      ns = "illuminate.highlight",
      ns_id = 30,
      opts = {
        end_col = 7,
        end_right_gravity = false,
        end_row = 4,
        hl_eol = false,
        hl_group = "IlluminatedWordWrite",
        hl_group_link = "IlluminatedWordWrite",
        priority = 1000,
        right_gravity = true
      },
      row = 4
    } },
  semantic_tokens = { {
      client_id = 1,
      end_col = 7,
      extmark_added = true,
      hl_groups = {
        modifiers = { {
            hl_group = "@declaration",
            hl_group_link = "@variable"
          } },
        type = {
          hl_group = "@variable",
          hl_group_link = "@variable"
        }
      },
      line = 4,
      modifiers = { "declaration" },
      start_col = 6,
      type = "variable"
    } },
  syntax = {},
  treesitter = { {
      capture = "variable",
      hl_group = "@variable",
      hl_group_link = "@variable",
      lang = "lua",
      metadata = {}
    }, {
      capture = "constant",
      hl_group = "@constant",
      hl_group_link = "Constant",
      lang = "lua",
      metadata = {}
    } }
}

@github-actions github-actions bot added the lua stdlib label Dec 12, 2022
@folke folke changed the title feat: added vim.highlight.show feat: vim.highlight.show shows the highlights under the cursor Dec 12, 2022
@jdrouhard
Copy link
Contributor

Could it display them in ascending order of priority? That would be pretty neat! Could easily visualize which highlights override others.

Copy link
Member

@justinmk justinmk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very useful! However I'm thinking this is a bigger bucket than "highlights". I see two problems being solved here:

  1. we want a way to "give me all the things at this position"
    • I propose this lives at vim.get_at_pos(pos, filter) which returns a dict of all the various things that may decorate a buffer position. (virtual text? decorations? etc.)
      • doesn't need to implement everything initially, we can add more later.
      • (future?) filter arg could be similar to that of vim.lsp.get_active_clients()
  2. display the result in a nice way
    • Not sure what to do with this. Perhaps we should start with just a command, like :Inspect (could also claim zS, in analogy to scriptease)
      • If it's meant to be interactive, not programmatically used, shouldn't it be a command?
    • The idea is, we want to have this useful thing, but I'm not sure we want a bunch of foo.show_x everywhere with randomly different behavior. At least, not yet? Edit:
      • vim.inspect_pos()
      • vim.show_pos()

@clason
Copy link
Member

clason commented Dec 13, 2022

Just a note: It'd be good to distinguish here between LSP semantic token type and token modifiers. (The exact source of these highlights is important information.)

@folke
Copy link
Member Author

folke commented Dec 13, 2022

For (2) it could be useful to also expose the functionality as a function where the caller can specify the (buf, row, col) and possible filter. The :Inspect command would then use the defaults.

@folke
Copy link
Member Author

folke commented Dec 13, 2022

Just a note: It'd be good to distinguish here between LSP semantic token type and token modifiers. (The exact source of these highlights is important information.)

yes, for sure! Haven't looked closely yet at the new Semantic Tokens API. Will look into it and add the changes

@folke
Copy link
Member Author

folke commented Dec 13, 2022

@justinmk where do you propose to add vim.get_at_pos and vim.show_at_pos? Also the nvim_create_user_command for :Inspect. I mean code wise. _editor.lua, inspect.lua, or in a separate file like inspector.lua, debug.lua?

@folke folke force-pushed the highlight_show branch 3 times, most recently from ad15e88 to 543d53b Compare December 13, 2022 17:15
@folke folke changed the title feat: vim.highlight.show shows the highlights under the cursor feat: vim.inspector to get/show items at a given buffer position Dec 13, 2022
@max397574
Copy link
Contributor

max397574 commented Dec 13, 2022

not sure
but wouldn't it make sense to make the columns 1-indexed?
so it would work with the functions listed under :h api-indexing (most notably nvim_win_get_cursor)
edit:
"work with" in the sense of not having to add a - 1 all the time

@folke
Copy link
Member Author

folke commented Dec 13, 2022

@max397574 wasn't sure what the concensus is right now. Maybe @justinmk can chime in on this?

@folke folke force-pushed the highlight_show branch 2 times, most recently from a5f6b82 to ccefbd3 Compare December 13, 2022 17:36
@folke folke force-pushed the highlight_show branch 5 times, most recently from 4ade9ca to fbbb847 Compare December 13, 2022 20:50
@folke folke requested a review from justinmk December 13, 2022 21:02
@justinmk
Copy link
Member

put the nvim_create_user_command somewhere. What would be the best place for this? _editor.lua? plugin/inspector.lua?

I suggest runtime/plugin/nvim.lua for now.

wouldn't it make sense to make the columns 1-indexed? so it would work with the functions listed under :h api-indexing (most notably nvim_win_get_cursor)

confused by the question because :h api-index mentions that nvim_win_get_cursor uses mark-like indexing (1-indexed row, 0-indexed col). (Not sure why nvim_win_get_cursor does that, because typically editor functions like getcurpos() are (1,1)-indexed).

@clason
Copy link
Member

clason commented Dec 13, 2022

I don't think it's necessary to duplicate the semantic tokens under the extmarks category. Modifiers should also have the leading @ (since that's the highlight name).

@folke
Copy link
Member Author

folke commented Dec 13, 2022

@clason wasn't sure about the extmarks. Might make sense to include them there too, since they are effectively extmarks, but that's indeed duplication. Treesitter is different since those extmarks are ephemeral, so they are not visible as an extmark. But you're right. Will exclude the semantic token ones.

I still haven't fully looked into the semantic tokens. Can a modifier be used as a hl group on its own? Or is it always in combination with the token type? Like @variable.declaration?

@folke
Copy link
Member Author

folke commented Dec 13, 2022

@justinmk api indexing is normally 0-0 based, but some functions are indeed 1-0 mark based. Editor vim.fn functions are 1-1 based.

Currently I used 0-0 api indexing, because i thought that's what all the new things use but i might be wrong.

Treesitter, semantic tokens etc all use api indexing as well, so 0-0 based.

@clason what do you think?

@jdrouhard
Copy link
Contributor

@clason what do you think? What indexing do the treesitter and semantic token APIs use?

Semantic tokens API is 0-0 based

@jdrouhard
Copy link
Contributor

I still haven't fully looked into the semantic tokens. Can a modifier be used as a hl group on its own? Or is it always in combination with the token type? Like @variable.declaration?

Currently they are added as their own highlight group, but eventually we’ll be updating the way they work to somehow allow combinations of types with modifiers (potentially like @variable.declaration), but that is not currently part of the functionality.

@folke folke force-pushed the highlight_show branch 6 times, most recently from b06d0fc to 120ecd6 Compare December 17, 2022 11:26
@folke
Copy link
Member Author

folke commented Dec 17, 2022

@clason updated!

@clason
Copy link
Member

clason commented Dec 17, 2022

I wants it, I merges it -- further changes can be made in the follow-up PR.

Noice job, @folke!

@clason clason merged commit 1c47949 into neovim:master Dec 17, 2022
@dundargoc dundargoc removed the request for review from justinmk December 17, 2022 12:44
@folke
Copy link
Member Author

folke commented Dec 17, 2022

@clason awesome, thanks!

@Dich0tomy
Copy link

Neat stuff. But aren't core commands supposed to start with a small letter? :inspect(!) instead of :Inspect(!)?

@clason
Copy link
Member

clason commented Dec 18, 2022

Yes, but this is not a core command. It's provided by a (bundled) runtime plugin, same as :Man.

@justinmk
Copy link
Member

justinmk commented Jan 2, 2023

Inspect might be a good addition to the default mouse right-click menu.

@zeertzjq
Copy link
Member

zeertzjq commented Jan 3, 2023

Inspect might be a good addition to the default mouse right-click menu.

:Inspect is created by runtime/plugin/nvim.lua, which is loaded after user config, and is not loaded with nvim -u NONE. If the menu item is added as a default menu item it may cause errors with nvim -u NONE, but if the menu item is also created by runtime/plugin/nvim.lua the user cannot remove it in their config like other default menu items.

@vlada-dudr
Copy link

I was curious what happens if I do set ve=all and try to :Inspect virtual text. Sadly nothing. Wouldn't it be nice addition?

@wsdjeg

This comment was marked as outdated.

@neovim neovim deleted a comment from Cloudef Aug 1, 2023
@neovim neovim locked as resolved and limited conversation to collaborators Aug 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
lua stdlib
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants