FFFF mini.nvim/lua/mini/map.lua at main · yurihbm/mini.nvim · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
1698 lines (1463 loc) · 66.6 KB

map.lua

File metadata and controls

1698 lines (1463 loc) · 66.6 KB
-- Update when necessary. Not ideal, because it won't react on `n/N/*`, etc.
-- See https://github.com/neovim/neovim/issues/18879
local gr = vim.api.nvim_create_augroup('MiniMapBuiltinSearch', {})
local opts = { group = gr, pattern = 'hlsearch', callback = H.on_integration_update, desc = "On 'hlsearch' update" }
vim.api.nvim_create_autocmd('OptionSet', opts)
-- - NOTE: beware of possible https://github.com/neovim/neovim/issues/21469
vim.cmd([[
silent! call dictwatcherdel(v:, 'hlsearch', 'MiniMapOnHLSearchChanged')
function! MiniMapOnHLSearchChanged(d,k,z)
lua MiniMap.refresh(nil, { lines = false, scrollbar = false })
endfunction
call dictwatcheradd(v:, 'hlsearch', 'MiniMapOnHLSearchChanged')
]])
local search_hl = hl_groups.search
return function()
-- Do nothing of search is not active
if vim.v.hlsearch == 0 or not vim.o.hlsearch then return {} end
-- Do nothing if not inside source buffer (can happen in map buffer, for example)
if not H.is_source_buffer() then return {} end
-- Save window view to later restore, as the only way to get positions of
-- search matches seems to be consecutive application of `search()` and
-- retrieving cursor position.
local win_view = vim.fn.winsaveview()
vim.api.nvim_win_set_cursor(0, { 1, 0 })
local search_count = vim.fn.searchcount({ recompute = true, maxcount = 0 })
local search_pattern = vim.fn.getreg('/')
local line_hl = {}
for _ = 1, (search_count.total or 0) do
vim.fn.search(search_pattern)
table.insert(line_hl, { line = vim.fn.line('.'), hl_group = search_hl })
end
vim.fn.winrestview(win_view)
return line_hl
end
end
--- Builtin diagnostic
---
--- Highlight lines with matches of current diagnostic items. Items are computed
--- with |vim.diagnostic.get()| for current (source) buffer.
---
--- It prompts integration highlighting update on every |DiagnosticChanged| event.
--- Diagnostic items with higher severity (see |vim.diagnostic.severity|) have
--- higher highlight priority (errors will be shown over all others, etc.).
---
---@param hl_groups table|nil Table defining highlight groups. Supplied fields
--- also define which diagnostic severity to highlight.
--- Can have the following fields:
--- - <error> - highlight group for error items.
--- Default: |hl-DiagnosticFloatingError|.
--- - <warn> - highlight group for warning items. Default: `nil` (not shown).
--- - <info> - highlight group for info items. Default: `nil` (not shown).
--- - <hint> - highlight group for hint items. Default: `nil` (not shown).
---
---@usage >lua
--- -- Show all diagnostic levels
--- local map = require('mini.map')
--- local diagnostic_integration = map.gen_integration.diagnostic({
--- error = 'DiagnosticFloatingError',
--- warn = 'DiagnosticFloatingWarn',
--- info = 'DiagnosticFloatingInfo',
--- hint = 'DiagnosticFloatingHint',
--- })
--- map.setup({ integrations = { diagnostic_integration } })
--- <
MiniMap.gen_integration.diagnostic = function(hl_groups)
if hl_groups == nil then hl_groups = { error = 'DiagnosticFloatingError' } end
-- Precompute ordered array of supported levels. Using keys of
-- `severity_highlights` is not enough because higher severity should be
-- processed later in order to appear on top.
local severity_level_names = vim.tbl_filter(
function(x) return vim.tbl_contains(vim.tbl_keys(hl_groups), x) end,
{ 'error', 'warn', 'info', 'hint' }
)
local severity_data = vim.tbl_map(
function(x) return { severity = vim.diagnostic.severity[x:upper()], hl_group = hl_groups[x] } end,
severity_level_names
)
-- Refresh map when needed
local augroup = vim.api.nvim_create_augroup('MiniMapDiagnostics', {})
vim.api.nvim_create_autocmd(
'DiagnosticChanged',
{ group = augroup, callback = H.on_integration_update, desc = 'On DiagnosticChanged' }
)
return function()
local line_hl = {}
local diagnostic_arr = vim.diagnostic.get(MiniMap.current.buf_data.source)
for _, data in ipairs(severity_data) do
local severity_diagnostic_arr = vim.tbl_filter(function(x) return x.severity == data.severity end, diagnostic_arr)
for _, diag in ipairs(severity_diagnostic_arr) do
-- Add all diagnostic lines to highlight
for i = diag.lnum, diag.end_lnum do
table.insert(line_hl, { line = i + 1, hl_group = data.hl_group })
end
end
end
return line_hl
end
end
--- General diff hunks from |mini.diff|
---
--- Highlight lines which are part of current diff.
--- Requires 'mini.diff' as dependency.
---
---@param hl_groups table|nil Table defining highlight groups. If `nil` (not
--- supplied), this status is not highlighted. Can have the following fields:
--- - <add> - group name for "add" hunks. Default: "MiniDiffSignAdd".
--- - <change> - group name for "change" hunks. Default: "MiniDiffSignChange".
--- - <delete> - group name for "delete" hunks. Default: "MiniDiffSignDelete".
MiniMap.gen_integration.diff = function(hl_groups)
if hl_groups == nil then
hl_groups = { add = 'MiniDiffSignAdd', change = 'MiniDiffSignChange', delete = 'MiniDiffSignDelete' }
end
local augroup = vim.api.nvim_create_augroup('MiniMapDiff', {})
vim.api.nvim_create_autocmd(
'User',
{ group = augroup, pattern = 'MiniDiffUpdated', callback = H.on_integration_update, desc = 'On MiniDiffUpdated' }
)
return function()
local has_diff, diff = pcall(require, 'mini.diff')
if not has_diff or diff == nil then return {} end
local has_buf_data, buf_data = pcall(diff.get_buf_data, MiniMap.current.buf_data.source)
if not has_buf_data or buf_data == nil then return {} end
return H.hunks_to_line_hl(buf_data.hunks, hl_groups)
end
end
--- Hunks from 'lewis6991/gitsigns.nvim'
---
--- Highlight lines which have non-trivial Git status.
--- Requires [lewis6991/gitsigns.nvim](https://github.com/lewis6991/gitsigns.nvim).
---
---@param hl_groups table|nil Table defining highlight groups. If `nil` (not
--- supplied), this status is not highlighted. Can have the following fields:
--- - <add> - group name for added lines. Default: "GitSignsAdd".
--- - <change> - group name for changed lines. Default: "GitSignsChange".
--- - <delete> - group name for deleted lines. Default: "GitSignsDelete".
MiniMap.gen_integration.gitsigns = function(hl_groups)
if hl_groups == nil then hl_groups = { add = 'GitSignsAdd', change = 'GitSignsChange', delete = 'GitSignsDelete' } end
local augroup = vim.api.nvim_create_augroup('MiniMapGitsigns', {})
vim.api.nvim_create_autocmd(
'User',
{ group = augroup, pattern = 'GitSignsUpdate', callback = H.on_integration_update, desc = 'On GitSignsUpdate' }
)
return function()
local has_gitsigns, gitsigns = pcall(require, 'gitsigns')
if not has_gitsigns or gitsigns == nil then return {} end
local has_hunks, hunks = pcall(gitsigns.get_hunks, MiniMap.current.buf_data.source)
if not has_hunks or hunks == nil then return {} end
local diff_hunks = {}
for _, h in ipairs(hunks) do
--stylua: ignore
table.insert( diff_hunks, {
type = h.type,
buf_start = h.added.start, buf_count = h.added.count,
ref_start = h.removed.start, ref_count = h.removed.count,
})
end
return H.hunks_to_line_hl(diff_hunks, hl_groups)
end
end
-- Helper data ================================================================
-- Module default config
H.default_config = vim.deepcopy(MiniMap.config)
-- Cache for various operations
H.cache = {
-- Data about previous window. Used for focus related computations.
previous_win = {},
-- Table with information used for latest buffer lines encoding. Used for
-- quick conversion between source and map coordinates.
encode_data = {},
-- Table with information about scrollbar. Used for quick scrollbar related
-- computations.
scrollbar_data = { view = {}, line = nil },
-- Number of cursor movements inside map buffer since focusing. Needed to not
-- update source buffer view just after focusing.
n_map_cursor_moves = 0,
}
H.ns_id = {
integrations = vim.api.nvim_create_namespace('MiniMapIntegrations'),
scroll_view = vim.api.nvim_create_namespace('MiniMapScrollView'),
scroll_line = vim.api.nvim_create_namespace('MiniMapScrollLine'),
}
--stylua: ignore start
H.block_symbols = {}
H.block_symbols['1x2'] = { ' ', '▌', '▐', '█', resolution = { row = 1, col = 2 } }
H.block_symbols['2x1'] = { ' ', '▀', '▄', '█', resolution = { row = 2, col = 1 } }
H.block_symbols['2x2'] = {
' ', '▘', '▝', '▀', '▖', '▌', '▞', '▛', '▗', '▚', '▐', '▜', '▄', '▙', '▟', '█',
resolution = { row = 2, col = 2 },
}
H.block_symbols['3x2'] = {
' ', '🬀', '🬁', '🬂', '🬃', '🬄', '🬅', '🬆', '🬇', '🬈', '🬉', '🬊', '🬋', '🬌', '🬍', '🬎',
'🬏', '🬐', '🬑', '🬒', '🬓', '▌', '🬔', '🬕', '🬖', '🬗', '🬘', '🬙', '🬚', '🬛', '🬜', '🬝',
'🬞', '🬟', '🬠', '🬡', '🬢', '🬣', '🬤', '🬥', '🬦', '🬧', '▐', '🬨', '🬩', '🬪', '🬫', '🬬',
'🬭', '🬮', '🬯', '🬰', '🬱', '🬲', '🬳', '🬴', '🬵', '🬶', '🬷', '🬸', '🬹', '🬺', '🬻', '█',
resolution = { row = 3, col = 2 },
}
H.dot_symbols = {}
H.dot_symbols['4x2'] = {
'⠀', '⠁', '⠈', '⠉', '⠂', '⠃', '⠊', '⠋', '⠐', '⠑', '⠘', '⠙', '⠒', '⠓', '⠚', '⠛',
'⠄', '⠅', '⠌', '⠍', '⠆', '⠇', '⠎', '⠏', '⠔', '⠕', '⠜', '⠝', '⠖', '⠗', '⠞', '⠟',
'⠠', '⠡', '⠨', '⠩', '⠢', '⠣', '⠪', '⠫', '⠰', '⠱', '⠸', '⠹', '⠲', '⠳', '⠺', '⠻',
'⠤', '⠥', '⠬', '⠭', '⠦', '⠧', '⠮', '⠯', '⠴', '⠵', '⠼', '⠽', '⠶', '⠷', '⠾', '⠿',
'⡀', '⡁', '⡈', '⡉', '⡂', '⡃', '⡊', '⡋', '⡐', '⡑', '⡘', '⡙', '⡒', '⡓', '⡚', '⡛',
'⡄', '⡅', '⡌', '⡍', '⡆', '⡇', '⡎', '⡏', '⡔', '⡕', '⡜', '⡝', '⡖', '⡗', '⡞', '⡟',
'⡠', '⡡', '⡨', '⡩', '⡢', '⡣', '⡪', '⡫', '⡰', '⡱', '⡸', '⡹', '⡲', '⡳', '⡺', '⡻',
'⡤', '⡥', '⡬', '⡭', '⡦', '⡧', '⡮', '⡯', '⡴', '⡵', '⡼', '⡽', '⡶', '⡷', '⡾', '⡿',
'⢀', '⢁', '⢈', '⢉', '⢂', '⢃', '⢊', '⢋', '⢐', '⢑', '⢘', '⢙', '⢒', '⢓', '⢚', '⢛',
'⢄', '⢅', '⢌', '⢍', '⢆', '⢇', '⢎', '⢏', '⢔', '⢕', '⢜', '⢝', '⢖', '⢗', '⢞', '⢟',
'⢠', '⢡', ' 3B30 ;⢨', '⢩', '⢢', '⢣', '⢪', '⢫', '⢰', '⢱', '⢸', '⢹', '⢲', '⢳', '⢺', '⢻',
'⢤', '⢥', '⢬', '⢭', '⢦', '⢧', '⢮', '⢯', '⢴', '⢵', '⢼', '⢽', '⢶', '⢷', '⢾', '⢿',
'⣀', '⣁', '⣈', '⣉', '⣂', '⣃', '⣊', '⣋', '⣐', '⣑', '⣘', '⣙', '⣒', '⣓', '⣚', '⣛',
'⣄', '⣅', '⣌', '⣍', '⣆', '⣇', '⣎', '⣏', '⣔', '⣕', '⣜', '⣝', '⣖', '⣗', '⣞', '⣟',
'⣠', '⣡', '⣨', '⣩', '⣢', '⣣', '⣪', '⣫', '⣰', '⣱', '⣸', '⣹', '⣲', '⣳', '⣺', '⣻',
'⣤', '⣥', '⣬', '⣭', '⣦', '⣧', '⣮', '⣯', '⣴', '⣵', '⣼', '⣽', '⣶', '⣷', '⣾', '⣿',
resolution = { row = 4, col = 2 },
}
0