mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(lua): ensure inspect_pos() only shows visible highlight extmarks
Problem:  Unpaired marks are shown with `filter.extmarks == true`, which
          should only return visible highlights. Misleading `end_col`
          included in `inspect_pos()` for unpaired mark; it is set to
          `start_col + 1` which would be a visible highlight, which it is
          not. Custom "is_here" filter used to get extmarks overlapping a
          position.
Solution: Exclude unpaired highlight extmarks with `filter.extmarks == true`.
          Set `end_col` to `start_col` for an unpaired mark. Supply
          appropriate arguments to nvim_buf_get_extmarks() to return
          overlapping extmarks; exclude marks whose end is at `{row, col}`
          with `filter.extmarks == true`.
			
			
This commit is contained in:
		 Luuk van Baal
					Luuk van Baal
				
			
				
					committed by
					
						 Christian Clason
						Christian Clason
					
				
			
			
				
	
			
			
			 Christian Clason
						Christian Clason
					
				
			
						parent
						
							1369d86812
						
					
				
				
					commit
					d40481322a
				
			| @@ -104,30 +104,32 @@ function vim.inspect_pos(bufnr, row, col, filter) | ||||
|  | ||||
|   --- Convert an extmark tuple into a table | ||||
|   local function to_map(extmark) | ||||
|     extmark = { | ||||
|     local opts = resolve_hl(extmark[4]) | ||||
|     return { | ||||
|       id = extmark[1], | ||||
|       row = extmark[2], | ||||
|       col = extmark[3], | ||||
|       opts = resolve_hl(extmark[4]), | ||||
|       end_row = opts.end_row or extmark[2], | ||||
|       end_col = opts.end_col or extmark[3], | ||||
|       opts = opts, | ||||
|       ns_id = opts.ns_id, | ||||
|       ns = nsmap[opts.ns_id] or '', | ||||
|     } | ||||
|     extmark.ns_id = extmark.opts.ns_id | ||||
|     extmark.ns = nsmap[extmark.ns_id] or '' | ||||
|     extmark.end_row = extmark.opts.end_row or extmark.row -- inclusive | ||||
|     extmark.end_col = extmark.opts.end_col or (extmark.col + 1) -- exclusive | ||||
|     return extmark | ||||
|   end | ||||
|  | ||||
|   --- Check if an extmark overlaps this position | ||||
|   local function is_here(extmark) | ||||
|     return (row >= extmark.row and row <= extmark.end_row) -- within the rows of the extmark | ||||
|       and (row > extmark.row or col >= extmark.col) -- either not the first row, or in range of the col | ||||
|       and (row < extmark.end_row or col < extmark.end_col) -- either not in the last row or in range of the col | ||||
|   --- Exclude end_col and unpaired marks from the overlapping marks, unless | ||||
|   --- filter.extmarks == 'all' (a highlight is drawn until end_col - 1). | ||||
|   local function exclude_end_col(extmark) | ||||
|     return filter.extmarks == 'all' or row < extmark.end_row or col < extmark.end_col | ||||
|   end | ||||
|  | ||||
|   -- all extmarks at this position | ||||
|   local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, -1, 0, -1, { details = true }) | ||||
|   -- All overlapping extmarks at this position: | ||||
|   local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, -1, { row, col }, { row, col }, { | ||||
|     details = true, | ||||
|     overlap = true, | ||||
|   }) | ||||
|   extmarks = vim.tbl_map(to_map, extmarks) | ||||
|   extmarks = vim.tbl_filter(is_here, extmarks) | ||||
|   extmarks = vim.tbl_filter(exclude_end_col, extmarks) | ||||
|  | ||||
|   if filter.semantic_tokens then | ||||
|     results.semantic_tokens = vim.tbl_filter(function(extmark) | ||||
|   | ||||
| @@ -12,23 +12,25 @@ describe('vim.inspect_pos', function() | ||||
|   end) | ||||
|  | ||||
|   it('it returns items', function() | ||||
|     local buf, ns1, ns2, items, other_buf_syntax = exec_lua(function() | ||||
|     local buf, ns1, ns2 = exec_lua(function() | ||||
|       local buf = vim.api.nvim_create_buf(true, false) | ||||
|       local buf1 = vim.api.nvim_create_buf(true, false) | ||||
|       _G.buf1 = vim.api.nvim_create_buf(true, false) | ||||
|       local ns1 = vim.api.nvim_create_namespace('ns1') | ||||
|       local ns2 = vim.api.nvim_create_namespace('') | ||||
|       vim.api.nvim_set_current_buf(buf) | ||||
|       vim.api.nvim_buf_set_lines(0, 0, -1, false, { 'local a = 123' }) | ||||
|       vim.api.nvim_buf_set_lines(buf1, 0, -1, false, { '--commentline' }) | ||||
|       vim.api.nvim_buf_set_lines(_G.buf1, 0, -1, false, { '--commentline' }) | ||||
|       vim.bo[buf].filetype = 'lua' | ||||
|       vim.bo[buf1].filetype = 'lua' | ||||
|       vim.bo[_G.buf1].filetype = 'lua' | ||||
|       vim.api.nvim_buf_set_extmark(buf, ns1, 0, 10, { hl_group = 'Normal' }) | ||||
|       vim.api.nvim_buf_set_extmark(buf, ns2, 0, 10, { hl_group = 'Normal' }) | ||||
|       vim.api.nvim_buf_set_extmark(buf, ns1, 0, 10, { hl_group = 'Normal', end_col = 10 }) | ||||
|       vim.api.nvim_buf_set_extmark(buf, ns2, 0, 10, { hl_group = 'Normal', end_col = 11 }) | ||||
|       vim.cmd('syntax on') | ||||
|       return buf, ns1, ns2, vim.inspect_pos(0, 0, 10), vim.inspect_pos(buf1, 0, 10).syntax | ||||
|       return buf, ns1, ns2 | ||||
|     end) | ||||
|  | ||||
|     eq('', eval('v:errmsg')) | ||||
|     -- Only visible highlights with `filter.extmarks == true` | ||||
|     eq({ | ||||
|       buffer = buf, | ||||
|       col = 10, | ||||
| @@ -39,6 +41,37 @@ describe('vim.inspect_pos', function() | ||||
|           end_col = 11, | ||||
|           end_row = 0, | ||||
|           id = 1, | ||||
|           ns = '', | ||||
|           ns_id = ns2, | ||||
|           opts = { | ||||
|             end_row = 0, | ||||
|             end_col = 11, | ||||
|             hl_eol = false, | ||||
|             hl_group = 'Normal', | ||||
|             hl_group_link = 'Normal', | ||||
|             ns_id = ns2, | ||||
|             priority = 4096, | ||||
|             right_gravity = true, | ||||
|             end_right_gravity = false, | ||||
|           }, | ||||
|           row = 0, | ||||
|         }, | ||||
|       }, | ||||
|       treesitter = {}, | ||||
|       semantic_tokens = {}, | ||||
|       syntax = { { hl_group = 'luaNumber', hl_group_link = 'Constant' } }, | ||||
|     }, exec_lua('return vim.inspect_pos(0, 0, 10)')) | ||||
|     -- All extmarks with `filters.extmarks == 'all'` | ||||
|     eq({ | ||||
|       buffer = buf, | ||||
|       col = 10, | ||||
|       row = 0, | ||||
|       extmarks = { | ||||
|         { | ||||
|           col = 10, | ||||
|           end_col = 10, | ||||
|           end_row = 0, | ||||
|           id = 1, | ||||
|           ns = 'ns1', | ||||
|           ns_id = ns1, | ||||
|           opts = { | ||||
| @@ -59,32 +92,47 @@ describe('vim.inspect_pos', function() | ||||
|           ns = '', | ||||
|           ns_id = ns2, | ||||
|           opts = { | ||||
|             end_row = 0, | ||||
|             end_col = 11, | ||||
|             hl_eol = false, | ||||
|             hl_group = 'Normal', | ||||
|             hl_group_link = 'Normal', | ||||
|             ns_id = ns2, | ||||
|             priority = 4096, | ||||
|             right_gravity = true, | ||||
|             end_right_gravity = false, | ||||
|           }, | ||||
|           row = 0, | ||||
|         }, | ||||
|         { | ||||
|           col = 10, | ||||
|           end_col = 10, | ||||
|           end_row = 0, | ||||
|           id = 2, | ||||
|           ns = 'ns1', | ||||
|           ns_id = ns1, | ||||
|           opts = { | ||||
|             end_row = 0, | ||||
|             end_col = 10, | ||||
|             hl_eol = false, | ||||
|             hl_group = 'Normal', | ||||
|             hl_group_link = 'Normal', | ||||
|             ns_id = ns1, | ||||
|             priority = 4096, | ||||
|             right_gravity = true, | ||||
|             end_right_gravity = false, | ||||
|           }, | ||||
|           row = 0, | ||||
|         }, | ||||
|       }, | ||||
|       treesitter = {}, | ||||
|       semantic_tokens = {}, | ||||
|       syntax = { | ||||
|         { | ||||
|           hl_group = 'luaNumber', | ||||
|           hl_group_link = 'Constant', | ||||
|         }, | ||||
|       }, | ||||
|     }, items) | ||||
|  | ||||
|       syntax = { { hl_group = 'luaNumber', hl_group_link = 'Constant' } }, | ||||
|     }, exec_lua('return vim.inspect_pos(0, 0, 10, { extmarks = "all" })')) | ||||
|     -- Syntax from other buffer. | ||||
|     eq({ | ||||
|       { | ||||
|         hl_group = 'luaComment', | ||||
|         hl_group_link = 'Comment', | ||||
|       }, | ||||
|     }, other_buf_syntax) | ||||
|       { hl_group = 'luaComment', hl_group_link = 'Comment' }, | ||||
|     }, exec_lua('return vim.inspect_pos(_G.buf1, 0, 10).syntax')) | ||||
|   end) | ||||
| end) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user