minimal extui fuzzy finder for neovim

fix(view): extmark priority

- add priority to extmarks
- use end_row +1 instead of line_hl
- override `:mark()` opts with `{ hl_mode = "combine", invalide = true }`

+43 -39
+43 -39
lua/artio/view.lua
··· 368 end 369 370 local view_ns = vim.api.nvim_create_namespace("artio:view:ns") 371 - ---@type vim.api.keyset.set_extmark 372 - local ext_match_opts = { 373 - hl_group = "ArtioMatch", 374 - hl_mode = "combine", 375 - invalidate = true, 376 } 377 378 ---@param line integer 0-based ··· 380 ---@param opts vim.api.keyset.set_extmark 381 ---@return integer 382 function View:mark(line, col, opts) 383 local ok, result 384 vim._with({ noautocmd = true }, function() 385 ok, result = pcall(vim.api.nvim_buf_set_extmark, ext.bufs.cmd, view_ns, line, col, opts) 386 end) 387 if not ok then 388 - vim.notify(("Failed to add extmark %d:%d"):format(line, col), vim.log.levels.ERROR) 389 return -1 390 end 391 ··· 394 395 function View:drawprompt() 396 if promptlen > 0 and prompthl_id > 0 then 397 - self:mark(promptidx, 0, { hl_group = prompthl_id, end_col = promptlen }) 398 self:mark(promptidx, 0, { 399 virt_text = { 400 { ··· 403 }, 404 }, 405 virt_text_pos = "eol_right_align", 406 - hl_mode = "combine", 407 - invalidate = true, 408 }) 409 end 410 end ··· 480 local icon_indent = has_icon and (#icons[i][1] + icon_pad) or 0 481 482 if has_icon and icons[i][2] then 483 - self:mark( 484 - cmdline.srow + i - 1, 485 - indent, 486 - vim.tbl_extend("force", ext_match_opts, { 487 - end_col = indent + icon_indent, 488 - hl_group = icons[i][2], 489 - }) 490 - ) 491 end 492 493 local line_hls = custom_hls[i] 494 if line_hls then 495 for j = 1, #line_hls do 496 local hl = line_hls[j] 497 - self:mark( 498 - cmdline.srow + i - 1, 499 - indent + icon_indent + hl[1][1], 500 - vim.tbl_extend("force", ext_match_opts, { 501 - end_col = indent + icon_indent + hl[1][2], 502 - hl_group = hl[2], 503 - }) 504 - ) 505 end 506 end 507 508 if marks[i] then 509 self:mark(cmdline.srow + i - 1, indent - 1, { 510 virt_text = { { self.picker.opts.marker, "ArtioMarker" } }, 511 - hl_mode = "combine", 512 virt_text_pos = "overlay", 513 - invalidate = true, 514 }) 515 end 516 517 if hls[i] then 518 for j = 1, #hls[i] do 519 local col = indent + icon_indent + hls[i][j] 520 - self:mark(cmdline.srow + i - 1, col, vim.tbl_extend("force", ext_match_opts, { end_col = col + 1 })) 521 end 522 end 523 end ··· 544 return 545 end 546 547 - do 548 - local extid = self:mark(row, 0, { 549 - virt_text = { { self.picker.opts.pointer, "ArtioPointer" } }, 550 - hl_mode = "combine", 551 - virt_text_pos = "overlay", 552 - line_hl_group = "ArtioSel", 553 - invalidate = true, 554 - }) 555 - if extid ~= -1 then 556 - self.select_ext = extid 557 - end 558 end 559 end 560
··· 368 end 369 370 local view_ns = vim.api.nvim_create_namespace("artio:view:ns") 371 + local ext_priority = { 372 + prompt = 1, 373 + info = 2, 374 + select = 4, 375 + marker = 8, 376 + hl = 16, 377 + icon = 32, 378 + match = 64, 379 } 380 381 ---@param line integer 0-based ··· 383 ---@param opts vim.api.keyset.set_extmark 384 ---@return integer 385 function View:mark(line, col, opts) 386 + opts.hl_mode = "combine" 387 + opts.invalidate = true 388 + 389 local ok, result 390 vim._with({ noautocmd = true }, function() 391 ok, result = pcall(vim.api.nvim_buf_set_extmark, ext.bufs.cmd, view_ns, line, col, opts) 392 end) 393 if not ok then 394 + vim.notify(("Failed to add extmark %d:%d\n\t%s"):format(line, col, result), vim.log.levels.ERROR) 395 return -1 396 end 397 ··· 400 401 function View:drawprompt() 402 if promptlen > 0 and prompthl_id > 0 then 403 + self:mark(promptidx, 0, { hl_group = prompthl_id, end_col = promptlen, priority = ext_priority.prompt }) 404 self:mark(promptidx, 0, { 405 virt_text = { 406 { ··· 409 }, 410 }, 411 virt_text_pos = "eol_right_align", 412 + priority = ext_priority.info, 413 }) 414 end 415 end ··· 485 local icon_indent = has_icon and (#icons[i][1] + icon_pad) or 0 486 487 if has_icon and icons[i][2] then 488 + self:mark(cmdline.srow + i - 1, indent, { 489 + end_col = indent + icon_indent, 490 + hl_group = icons[i][2], 491 + priority = ext_priority.icon, 492 + }) 493 end 494 495 local line_hls = custom_hls[i] 496 if line_hls then 497 for j = 1, #line_hls do 498 local hl = line_hls[j] 499 + self:mark(cmdline.srow + i - 1, indent + icon_indent + hl[1][1], { 500 + end_col = indent + icon_indent + hl[1][2], 501 + hl_group = hl[2], 502 + priority = ext_priority.hl, 503 + }) 504 end 505 end 506 507 if marks[i] then 508 self:mark(cmdline.srow + i - 1, indent - 1, { 509 virt_text = { { self.picker.opts.marker, "ArtioMarker" } }, 510 virt_text_pos = "overlay", 511 + priority = ext_priority.marker, 512 }) 513 end 514 515 if hls[i] then 516 for j = 1, #hls[i] do 517 local col = indent + icon_indent + hls[i][j] 518 + self:mark(cmdline.srow + i - 1, col, { 519 + hl_group = "ArtioMatch", 520 + end_col = col + 1, 521 + priority = ext_priority.match, 522 + }) 523 end 524 end 525 end ··· 546 return 547 end 548 549 + local extid = self:mark(row, 0, { 550 + virt_text = { { self.picker.opts.pointer, "ArtioPointer" } }, 551 + virt_text_pos = "overlay", 552 + 553 + hl_group = "ArtioSel", 554 + hl_eol = true, 555 + end_row = row + 1, 556 + end_col = 0, 557 + 558 + priority = ext_priority.select, 559 + }) 560 + if extid ~= -1 then 561 + self.select_ext = extid 562 end 563 end 564