667 lines
22 KiB
Lua
667 lines
22 KiB
Lua
-- mod-version:3
|
|
local core = require "core"
|
|
local command = require "core.command"
|
|
local common = require "core.common"
|
|
local config = require "core.config"
|
|
local style = require "core.style"
|
|
local DocView = require "core.docview"
|
|
local Highlighter = require "core.doc.highlighter"
|
|
local Object = require "core.object"
|
|
local Scrollbar = require "core.scrollbar"
|
|
|
|
-- Sample configurations:
|
|
-- full width:
|
|
-- config.plugins.minimap.highlight_width = 100
|
|
-- config.plugins.minimap.gutter_width = 0
|
|
-- left side:
|
|
-- config.plugins.minimap.highlight_align = 'left'
|
|
-- config.plugins.minimap.highlight_width = 3
|
|
-- config.plugins.minimap.gutter_width = 4
|
|
-- right side:
|
|
-- config.plugins.minimap.highlight_align = 'right'
|
|
-- config.plugins.minimap.highlight_width = 5
|
|
-- config.plugins.minimap.gutter_width = 0
|
|
|
|
-- General plugin settings
|
|
config.plugins.minimap = common.merge({
|
|
enabled = true,
|
|
width = 100,
|
|
instant_scroll = false,
|
|
syntax_highlight = true,
|
|
scale = 1,
|
|
-- number of spaces needed to split a token
|
|
spaces_to_split = 2,
|
|
-- hide on small docs (can be true, false or min number of lines)
|
|
avoid_small_docs = false,
|
|
-- how many spaces one tab is equivalent to
|
|
tab_width = 4,
|
|
draw_background = true,
|
|
-- you can override these colors
|
|
selection_color = nil,
|
|
caret_color = nil,
|
|
-- If other plugins provide per-line highlights,
|
|
-- this controls the placement. (e.g. gitdiff_highlight)
|
|
highlight_align = 'left',
|
|
highlight_width = 3,
|
|
gutter_width = 5,
|
|
-- The config specification used by the settings gui
|
|
config_spec = {
|
|
name = "Mini Map",
|
|
{
|
|
label = "Enabled",
|
|
description = "Activate the minimap by default.",
|
|
path = "enabled",
|
|
type = "toggle",
|
|
default = true
|
|
},
|
|
{
|
|
label = "Width",
|
|
description = "Width of the minimap in pixels.",
|
|
path = "width",
|
|
type = "number",
|
|
default = 100,
|
|
min = 50,
|
|
max = 1000
|
|
},
|
|
{
|
|
label = "Instant Scroll",
|
|
description = "When enabled disables the scrolling animation.",
|
|
path = "instant_scroll",
|
|
type = "toggle",
|
|
default = false
|
|
},
|
|
{
|
|
label = "Syntax Highlighting",
|
|
description = "Disable to improve performance.",
|
|
path = "syntax_highlight",
|
|
type = "toggle",
|
|
default = true
|
|
},
|
|
{
|
|
label = "Scale",
|
|
description = "Size of the minimap using a scaling factor.",
|
|
path = "scale",
|
|
type = "number",
|
|
default = 1,
|
|
min = 0.5,
|
|
max = 10,
|
|
step = 0.1
|
|
},
|
|
{
|
|
label = "Spaces to split",
|
|
description = "Number of spaces needed to split a token.",
|
|
path = "spaces_to_split",
|
|
type = "number",
|
|
default = 2,
|
|
min = 1
|
|
},
|
|
{
|
|
label = "Hide for small Docs",
|
|
description = "Hide the minimap when a Doc is small enough.",
|
|
path = "avoid_small_docs",
|
|
type = "toggle",
|
|
default = false
|
|
},
|
|
{
|
|
label = "Small Docs definition",
|
|
description = "Size of a Doc to be considered small. Use 0 to automatically decide.",
|
|
path = "avoid_small_docs_len",
|
|
type = "number",
|
|
default = 0,
|
|
min = 0,
|
|
on_apply = function(value)
|
|
if value == 0 then
|
|
config.plugins.minimap.avoid_small_docs = true
|
|
else
|
|
config.plugins.minimap.avoid_small_docs = value
|
|
end
|
|
end
|
|
},
|
|
{
|
|
label = "Tabs Width",
|
|
description = "The amount of spaces that represent a tab.",
|
|
path = "tab_width",
|
|
type = "number",
|
|
default = 4,
|
|
min = 1,
|
|
max = 8
|
|
},
|
|
{
|
|
label = "Draw Background",
|
|
description = "When disabled makes the minimap transparent.",
|
|
path = "draw_background",
|
|
type = "toggle",
|
|
default = true
|
|
},
|
|
{
|
|
label = "Selection Color",
|
|
description = "Background color of selected text in html notation eg: #FFFFFF. Leave empty to use default.",
|
|
path = "selection_color_html",
|
|
type = "string",
|
|
on_apply = function(value)
|
|
if value and value:match("#%x%x%x%x%x%x") then
|
|
config.plugins.minimap.selection_color = { common.color(value) }
|
|
else
|
|
config.plugins.minimap.selection_color = nil
|
|
end
|
|
end
|
|
},
|
|
{
|
|
label = "Caret Color",
|
|
description = "Background color of active line in html notation eg: #FFFFFF. Leave empty to use default.",
|
|
path = "caret_color_html",
|
|
type = "string",
|
|
on_apply = function(value)
|
|
if value and value:match("#%x%x%x%x%x%x") then
|
|
config.plugins.minimap.caret_color = { common.color(value) }
|
|
else
|
|
config.plugins.minimap.caret_color = nil
|
|
end
|
|
end
|
|
},
|
|
{
|
|
label = "Highlight Alignment",
|
|
path = "highlight_align",
|
|
type = "selection",
|
|
default = "left",
|
|
values = {
|
|
{"Left", "left"},
|
|
{"Right", "right"}
|
|
}
|
|
},
|
|
{
|
|
label = "Highlight Width",
|
|
path = "highlight_width",
|
|
type = "number",
|
|
default = 3,
|
|
min = 0,
|
|
max = 50
|
|
},
|
|
{
|
|
label = "Gutter Width",
|
|
description = "Left padding of the minimap.",
|
|
path = "gutter_width",
|
|
type = "number",
|
|
default = 5,
|
|
min = 0,
|
|
max = 50
|
|
},
|
|
}
|
|
}, config.plugins.minimap)
|
|
|
|
|
|
-- contains the settings values that require a cache reset if changed
|
|
local cached_settings = {
|
|
color_scheme_canary = nil,
|
|
syntax_highlight = nil,
|
|
spaces_to_split = nil,
|
|
scale = nil,
|
|
width = nil,
|
|
}
|
|
|
|
-- Configure size for rendering each char in the minimap
|
|
local char_spacing
|
|
local char_height
|
|
local line_spacing
|
|
|
|
-- cache for the location of the rects for each Doc
|
|
local highlighter_cache
|
|
local function reset_cache()
|
|
highlighter_cache = setmetatable({}, { __mode = "k" })
|
|
cached_settings = {
|
|
color_scheme_canary = style.syntax["normal"],
|
|
syntax_highlight = config.plugins.minimap.syntax_highlight,
|
|
spaces_to_split = config.plugins.minimap.spaces_to_split,
|
|
scale = config.plugins.minimap.scale,
|
|
width = config.plugins.minimap.width,
|
|
}
|
|
char_spacing = 0.8 * SCALE * config.plugins.minimap.scale
|
|
-- keep y aligned to pixels
|
|
char_height = math.max(1, math.floor(1 * SCALE * config.plugins.minimap.scale + 0.5))
|
|
line_spacing = math.max(1, math.floor(2 * SCALE * config.plugins.minimap.scale + 0.5))
|
|
end
|
|
reset_cache()
|
|
|
|
|
|
local function reset_cache_if_needed()
|
|
if
|
|
cached_settings.color_scheme_canary ~= style.syntax["normal"]
|
|
or cached_settings.syntax_highlight ~= config.plugins.minimap.syntax_highlight
|
|
or cached_settings.spaces_to_split ~= config.plugins.minimap.spaces_to_split
|
|
or cached_settings.scale ~= config.plugins.minimap.scale
|
|
or cached_settings.width ~= config.plugins.minimap.width
|
|
then
|
|
reset_cache()
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Move cache to make space for new lines
|
|
local prev_insert_notify = Highlighter.insert_notify
|
|
function Highlighter:insert_notify(line, n, ...)
|
|
prev_insert_notify(self, line, n, ...)
|
|
local blanks = { }
|
|
if not highlighter_cache[self] then
|
|
highlighter_cache[self] = {}
|
|
else
|
|
local to = math.min(line + n, #self.doc.lines)
|
|
for i=#self.doc.lines+n,to,-1 do
|
|
highlighter_cache[self][i] = highlighter_cache[self][i - n]
|
|
end
|
|
for i=line,to do
|
|
highlighter_cache[self][i] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- Close the cache gap created by removed lines
|
|
local prev_remove_notify = Highlighter.remove_notify
|
|
function Highlighter:remove_notify(line, n, ...)
|
|
prev_remove_notify(self, line, n, ...)
|
|
if not highlighter_cache[self] then
|
|
highlighter_cache[self] = {}
|
|
else
|
|
local to = math.max(line + n, #self.doc.lines)
|
|
for i=line,to do
|
|
highlighter_cache[self][i] = highlighter_cache[self][i + n]
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- Remove changed lines from the cache
|
|
local prev_tokenize_line = Highlighter.tokenize_line
|
|
function Highlighter:tokenize_line(idx, state, ...)
|
|
local res = prev_tokenize_line(self, idx, state, ...)
|
|
if not highlighter_cache[self] then
|
|
highlighter_cache[self] = {}
|
|
end
|
|
highlighter_cache[self][idx] = nil
|
|
return res
|
|
end
|
|
|
|
-- Ask the Highlighter to retokenize the lines we have in cache
|
|
local prev_invalidate = Highlighter.invalidate
|
|
function Highlighter:invalidate(idx, ...)
|
|
local cache = highlighter_cache[self]
|
|
if cache then
|
|
self.max_wanted_line = math.max(self.max_wanted_line, #cache)
|
|
end
|
|
return prev_invalidate(self, idx, ...)
|
|
end
|
|
|
|
|
|
-- Remove cache on Highlighter reset (for example on syntax change)
|
|
local prev_soft_reset = Highlighter.soft_reset
|
|
function Highlighter:soft_reset(...)
|
|
prev_soft_reset(self, ...)
|
|
highlighter_cache[self] = {}
|
|
end
|
|
|
|
|
|
local MiniMap = Scrollbar:extend()
|
|
|
|
|
|
function MiniMap:new(dv)
|
|
MiniMap.super.new(self, { direction = "v", alignment = "e" })
|
|
self.dv = dv
|
|
self.enabled = nil
|
|
end
|
|
|
|
|
|
function MiniMap:line_highlight_color(line_index)
|
|
-- other plugins can override this, and return a color
|
|
end
|
|
|
|
|
|
function MiniMap:is_minimap_enabled()
|
|
if self.enabled ~= nil then return self.enabled end
|
|
if not config.plugins.minimap.enabled then return false end
|
|
if config.plugins.minimap.avoid_small_docs then
|
|
local last_line = #self.dv.doc.lines
|
|
if type(config.plugins.minimap.avoid_small_docs) == "number" then
|
|
return last_line > config.plugins.minimap.avoid_small_docs
|
|
else
|
|
local docview = self.dv
|
|
local _, y = docview:get_line_screen_position(last_line, #docview.doc.lines[last_line])
|
|
y = y + docview.scroll.y - docview.position.y + docview:get_line_height()
|
|
return y > docview.size.y
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
|
|
function MiniMap:get_minimap_dimensions()
|
|
local x, y, w, h = self:get_track_rect()
|
|
local _, cy, _, cy2 = self.dv:get_content_bounds()
|
|
local lh = self.dv:get_line_height()
|
|
|
|
local visible_lines_start = math.max(1, math.floor(cy / lh))
|
|
local visible_lines_count = math.max(1, (cy2 - cy) / lh)
|
|
local minimap_lines_start = 1
|
|
local minimap_lines_count = math.floor(h / line_spacing)
|
|
local line_count = #self.dv.doc.lines
|
|
|
|
local is_file_too_large = line_count > 1 and line_count > minimap_lines_count
|
|
if is_file_too_large then
|
|
local scroll_pos = (visible_lines_start - 1) /
|
|
(line_count - visible_lines_count - 1)
|
|
scroll_pos = math.min(1.0, scroll_pos) -- 0..1, procent of visual area scrolled
|
|
|
|
local thumb_height = visible_lines_count * line_spacing
|
|
local scroll_pos_pixels = scroll_pos * (h - thumb_height)
|
|
|
|
minimap_lines_start = visible_lines_start -
|
|
math.floor(scroll_pos_pixels / line_spacing)
|
|
minimap_lines_start = math.max(1, minimap_lines_start)
|
|
end
|
|
return visible_lines_start, visible_lines_count, minimap_lines_start, minimap_lines_count, is_file_too_large
|
|
end
|
|
|
|
|
|
function MiniMap:_get_track_rect_normal()
|
|
if not self:is_minimap_enabled() then return MiniMap.super._get_track_rect_normal(self) end
|
|
return self.dv.size.x + self.dv.position.x - config.plugins.minimap.width, self.dv.position.y, config.plugins.minimap.width, self.dv.size.y
|
|
end
|
|
|
|
|
|
function MiniMap:get_active_margin() if self:is_minimap_enabled() then return 0 else return MiniMap.super.get_active_margin(self) end end
|
|
|
|
|
|
function MiniMap:_get_thumb_rect_normal()
|
|
if not self:is_minimap_enabled() then return MiniMap.super._get_thumb_rect_normal(self) end
|
|
local visible_lines_start, visible_lines_count, minimap_lines_start, minimap_lines_count, is_file_too_large = self:get_minimap_dimensions()
|
|
local visible_y = self.dv.position.y + (visible_lines_start - 1) * line_spacing
|
|
if is_file_too_large then
|
|
local line_count = #self.dv.doc.lines
|
|
local scroll_pos = (visible_lines_start - 1) /
|
|
(line_count - visible_lines_count - 1)
|
|
scroll_pos = math.min(1.0, scroll_pos) -- 0..1, procent of visual area scrolled
|
|
|
|
local thumb_height = visible_lines_count * line_spacing
|
|
local scroll_pos_pixels = scroll_pos * (self.dv.size.y - thumb_height)
|
|
visible_y = self.dv.position.y + scroll_pos_pixels
|
|
end
|
|
return self.dv.size.x + self.dv.position.x - config.plugins.minimap.width, visible_y, config.plugins.minimap.width, visible_lines_count * line_spacing
|
|
end
|
|
|
|
|
|
function MiniMap:on_mouse_pressed(button, x, y, clicks)
|
|
local percent = MiniMap.super.on_mouse_pressed(self, button, x, y, clicks)
|
|
if not self:is_minimap_enabled() or not percent then return percent end
|
|
local _, visible_lines_count, minimap_lines_start, minimap_lines_count, is_file_too_large = self:get_minimap_dimensions()
|
|
local _, _, w, h = self:get_track_rect()
|
|
local tx, ty, tw, th = self:get_thumb_rect()
|
|
if y >= ty and y < ty + th then self.drag_start_offset = (y - ty) - th / 2 return self.percent end
|
|
self.drag_start_offset = 0
|
|
self.hovering.thumb = x >= tx and x < tx + tw and y >= ty and y < ty + th
|
|
self.dragging = self.hovering.thumb
|
|
local lh = self.dv:get_line_height()
|
|
percent = math.max(0.0, math.min((y - self.dv.position.y) / h, 1.0))
|
|
return (((percent * minimap_lines_count) + minimap_lines_start) * lh / self.dv:get_scrollable_size()) - (visible_lines_count / #self.dv.doc.lines / 2)
|
|
end
|
|
|
|
|
|
function MiniMap:on_mouse_moved(x, y, dx, dy)
|
|
local percent = MiniMap.super.on_mouse_moved(self, x, y, dx, dy)
|
|
if not self:is_minimap_enabled() or type(percent) ~= "number" then return percent end
|
|
local _, visible_lines_count, minimap_lines_start, minimap_lines_count, is_file_too_large = self:get_minimap_dimensions()
|
|
local lh = self.dv:get_line_height()
|
|
local _, _, w, h = self:get_track_rect()
|
|
local tx, ty, tw, th = self:get_thumb_rect()
|
|
if x >= tx and x < tx + tw and y >= ty and y < ty + th then self.hovering.thumb = true end
|
|
if not self.hovering.thumb then return self.percent end
|
|
y = y - self.drag_start_offset
|
|
percent = math.max(0.0, math.min((y - self.dv.position.y) / h, 1.0))
|
|
return (((percent * minimap_lines_count) + minimap_lines_start) * lh / self.dv:get_scrollable_size()) - (visible_lines_count / #self.dv.doc.lines / 2)
|
|
end
|
|
|
|
function MiniMap:draw_thumb()
|
|
local color = self.hovering.thumb and style.scrollbar2 or style.scrollbar
|
|
local x, y, w, h = self:get_thumb_rect()
|
|
renderer.draw_rect(x, y, w, h, color)
|
|
end
|
|
|
|
function MiniMap:draw()
|
|
if not self:is_minimap_enabled() then return MiniMap.super.draw(self) end
|
|
local dv = self.dv
|
|
local x, y, w, h = self:get_track_rect()
|
|
|
|
local highlight = dv.hovered_scrollbar or dv.dragging_scrollbar
|
|
local visual_color = highlight and style.scrollbar2 or style.scrollbar
|
|
|
|
local visible_lines_start, visible_lines_count,
|
|
minimap_lines_start, minimap_lines_count = self:get_minimap_dimensions()
|
|
|
|
if config.plugins.minimap.draw_background then
|
|
renderer.draw_rect(x, y, w, h, style.minimap_background or style.background)
|
|
end
|
|
self:draw_thumb()
|
|
|
|
-- highlight the selected lines, and the line with the caret on it
|
|
local selection_color = config.plugins.minimap.selection_color or style.dim
|
|
local caret_color = config.plugins.minimap.caret_color or style.caret
|
|
|
|
for i, line1, col1, line2, col2 in dv.doc:get_selections() do
|
|
local selection1_y = y + (line1 - minimap_lines_start) * line_spacing
|
|
local selection2_y = y + (line2 - minimap_lines_start) * line_spacing
|
|
local selection_min_y = math.min(selection1_y, selection2_y)
|
|
local selection_h = math.abs(selection2_y - selection1_y)+1
|
|
renderer.draw_rect(x, selection_min_y, w, selection_h, selection_color)
|
|
renderer.draw_rect(x, selection1_y, w, line_spacing, caret_color)
|
|
end
|
|
|
|
local highlight_align = config.plugins.minimap.highlight_align
|
|
local highlight_width = config.plugins.minimap.highlight_width
|
|
local gutter_width = config.plugins.minimap.gutter_width
|
|
|
|
-- time to draw the actual code, setup some local vars that are used in both highlighted and plain rendering.
|
|
local line_y = y
|
|
|
|
-- when not using syntax highlighted rendering, just use the normal color but dim it 50%.
|
|
local color = style.syntax["normal"]
|
|
color = {color[1], color[2], color[3], color[4] * 0.5}
|
|
|
|
-- we try to "batch" characters so that they can be rendered as just one rectangle instead of one for each.
|
|
local batch_width = 0
|
|
local batch_start = x
|
|
local last_batch_end = -1
|
|
local minimap_cutoff_x = config.plugins.minimap.width * SCALE
|
|
local batch_syntax_type = nil
|
|
local function flush_batch(type, cache)
|
|
if batch_width > 0 then
|
|
local lastidx = #cache
|
|
local old_color = color
|
|
color = style.syntax[type]
|
|
if config.plugins.minimap.syntax_highlight and color ~= nil then
|
|
-- fetch and dim colors
|
|
color = {color[1], color[2], color[3], (color[4] or 255) * 0.5}
|
|
else
|
|
color = old_color
|
|
end
|
|
if #cache >= 3 then
|
|
local last_color = cache[lastidx]
|
|
if
|
|
last_batch_end == batch_start -- no space skipped
|
|
and (
|
|
batch_syntax_type == type -- and same syntax
|
|
or ( -- or same color
|
|
last_color[1] == color[1]
|
|
and last_color[2] == color[2]
|
|
and last_color[3] == color[3]
|
|
and last_color[4] == color[4]
|
|
)
|
|
)
|
|
then
|
|
batch_start = cache[lastidx - 2]
|
|
batch_width = cache[lastidx - 1] + batch_width
|
|
lastidx = lastidx - 3
|
|
end
|
|
end
|
|
cache[lastidx + 1] = batch_start
|
|
cache[lastidx + 2] = batch_width
|
|
cache[lastidx + 3] = color
|
|
end
|
|
batch_syntax_type = type
|
|
batch_start = batch_start + batch_width
|
|
last_batch_end = batch_start
|
|
batch_width = 0
|
|
end
|
|
|
|
local highlight_x
|
|
if highlight_align == 'left' then
|
|
highlight_x = x
|
|
else
|
|
highlight_x = x + w - highlight_width
|
|
end
|
|
local function render_highlight(idx, line_y)
|
|
local highlight_color = self:line_highlight_color(idx)
|
|
if highlight_color then
|
|
renderer.draw_rect(highlight_x, line_y, highlight_width, line_spacing, highlight_color)
|
|
end
|
|
end
|
|
|
|
local endidx = math.min(minimap_lines_start + minimap_lines_count, #self.dv.doc.lines)
|
|
|
|
reset_cache_if_needed()
|
|
|
|
if not highlighter_cache[dv.doc.highlighter] then
|
|
highlighter_cache[dv.doc.highlighter] = {}
|
|
end
|
|
|
|
-- per line
|
|
for idx = minimap_lines_start, endidx do
|
|
batch_syntax_type = nil
|
|
batch_start = 0
|
|
batch_width = 0
|
|
last_batch_end = -1
|
|
|
|
render_highlight(idx, line_y)
|
|
local cache = highlighter_cache[dv.doc.highlighter][idx]
|
|
if not highlighter_cache[dv.doc.highlighter][idx] then -- need to cache
|
|
highlighter_cache[dv.doc.highlighter][idx] = {}
|
|
cache = highlighter_cache[dv.doc.highlighter][idx]
|
|
-- per token
|
|
for _, type, text in dv.doc.highlighter:each_token(idx) do
|
|
if not config.plugins.minimap.syntax_highlight then
|
|
type = nil
|
|
end
|
|
local start = 1
|
|
while true do
|
|
-- find text followed spaces followed by newline
|
|
local s, e, w, eol = string.ufind(text, "[^%s]*()[ \t]*()\n?", start)
|
|
if not s then break end
|
|
local nchars = w - s
|
|
start = e + 1
|
|
batch_width = batch_width + char_spacing * nchars
|
|
|
|
local nspaces = 0
|
|
for i=w,e do
|
|
local whitespace = string.sub(text, i, i)
|
|
if whitespace == "\t" then
|
|
nspaces = nspaces + config.plugins.minimap.tab_width
|
|
elseif whitespace == " " then
|
|
nspaces = nspaces + 1
|
|
end
|
|
end
|
|
-- not enough spaces; consider them part of the batch
|
|
if nspaces < config.plugins.minimap.spaces_to_split then
|
|
batch_width = batch_width + nspaces * char_spacing
|
|
end
|
|
-- line has ended or no more space in the minimap;
|
|
-- we can go to the next line
|
|
if eol <= w or batch_start + batch_width > minimap_cutoff_x then
|
|
if batch_width > 0 then
|
|
flush_batch(type, cache)
|
|
end
|
|
break
|
|
end
|
|
-- enough spaces to split the batch
|
|
if nspaces >= config.plugins.minimap.spaces_to_split then
|
|
flush_batch(type, cache)
|
|
batch_start = batch_start + nspaces * char_spacing
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- draw from cache
|
|
for i=1,#cache,3 do
|
|
local batch_start = cache[i ] + x + gutter_width
|
|
local batch_width = cache[i + 1]
|
|
local color = cache[i + 2]
|
|
renderer.draw_rect(batch_start, line_y, batch_width, char_height, color)
|
|
end
|
|
line_y = line_y + line_spacing
|
|
end
|
|
end
|
|
|
|
|
|
local old_docview_new = DocView.new
|
|
function DocView:new(doc)
|
|
old_docview_new(self, doc)
|
|
if self:is(DocView) then self.v_scrollbar = MiniMap(self) end
|
|
end
|
|
|
|
local old_docview_scroll_to_make_visible = DocView.scroll_to_make_visible
|
|
function DocView:scroll_to_make_visible(line, col, ...)
|
|
if
|
|
not self:is(DocView) or not self.v_scrollbar:is(MiniMap)
|
|
or
|
|
not self.v_scrollbar:is_minimap_enabled()
|
|
then
|
|
return old_docview_scroll_to_make_visible(self, line, col, ...)
|
|
end
|
|
local old_size = self.size.x
|
|
self.size.x = math.max(0, self.size.x - config.plugins.minimap.width)
|
|
local result = old_docview_scroll_to_make_visible(self, line, col, ...)
|
|
self.size.x = old_size
|
|
return result
|
|
end
|
|
|
|
|
|
local function get_all_docviews(node, t)
|
|
t = t or {}
|
|
if not node then return end
|
|
if node.type == "leaf" then
|
|
for i,v in ipairs(node.views) do
|
|
if v:is(DocView) then
|
|
table.insert(t, v)
|
|
end
|
|
end
|
|
end
|
|
get_all_docviews(node.a, t)
|
|
get_all_docviews(node.b, t)
|
|
return t
|
|
end
|
|
|
|
|
|
command.add(nil, {
|
|
["minimap:toggle-visibility"] = function()
|
|
config.plugins.minimap.enabled = not config.plugins.minimap.enabled
|
|
for i,v in ipairs(get_all_docviews(core.root_view.root_node)) do
|
|
v.v_scrollbar.enabled = nil
|
|
end
|
|
end,
|
|
["minimap:toggle-syntax-highlighting"] = function()
|
|
config.plugins.minimap.syntax_highlight = not config.plugins.minimap.syntax_highlight
|
|
end
|
|
})
|
|
|
|
command.add("core.docview!", {
|
|
["minimap:toggle-visibility-for-current-view"] = function(dv)
|
|
local sb = dv.v_scrollbar
|
|
if sb.enabled ~= nil then
|
|
sb.enabled = not sb.enabled
|
|
else
|
|
sb.enabled = not config.plugins.minimap.enabled
|
|
end
|
|
end
|
|
})
|
|
|
|
return MiniMap
|
|
|