Merge pull request #832 from jgmdev/autocomplete-update
Update autocomplete with changes needed for latest LSP plugin.
This commit is contained in:
commit
af6a06bc8b
|
@ -19,7 +19,6 @@ config.line_height = 1.2
|
||||||
config.indent_size = 2
|
config.indent_size = 2
|
||||||
config.tab_type = "soft"
|
config.tab_type = "soft"
|
||||||
config.line_limit = 80
|
config.line_limit = 80
|
||||||
config.max_symbols = 4000
|
|
||||||
config.max_project_files = 2000
|
config.max_project_files = 2000
|
||||||
config.transitions = true
|
config.transitions = true
|
||||||
config.animation_rate = 1.0
|
config.animation_rate = 1.0
|
||||||
|
|
|
@ -11,12 +11,16 @@ local DocView = require "core.docview"
|
||||||
local Doc = require "core.doc"
|
local Doc = require "core.doc"
|
||||||
|
|
||||||
config.plugins.autocomplete = common.merge({
|
config.plugins.autocomplete = common.merge({
|
||||||
-- Amount of characters that need to be written for autocomplete
|
-- Amount of characters that need to be written for autocomplete
|
||||||
min_len = 3,
|
min_len = 3,
|
||||||
-- The max amount of visible items
|
-- The max amount of visible items
|
||||||
max_height = 6,
|
max_height = 6,
|
||||||
-- The max amount of scrollable items
|
-- The max amount of scrollable items
|
||||||
max_suggestions = 100,
|
max_suggestions = 100,
|
||||||
|
-- Maximum amount of symbols to cache per document
|
||||||
|
max_symbols = 4000,
|
||||||
|
-- Font size of the description box
|
||||||
|
desc_font_size = 12
|
||||||
}, config.plugins.autocomplete)
|
}, config.plugins.autocomplete)
|
||||||
|
|
||||||
local autocomplete = {}
|
local autocomplete = {}
|
||||||
|
@ -33,7 +37,7 @@ local triggered_manually = false
|
||||||
|
|
||||||
local mt = { __tostring = function(t) return t.text end }
|
local mt = { __tostring = function(t) return t.text end }
|
||||||
|
|
||||||
function autocomplete.add(t, triggered_manually)
|
function autocomplete.add(t, manually_triggered)
|
||||||
local items = {}
|
local items = {}
|
||||||
for text, info in pairs(t.items) do
|
for text, info in pairs(t.items) do
|
||||||
if type(info) == "table" then
|
if type(info) == "table" then
|
||||||
|
@ -43,9 +47,10 @@ function autocomplete.add(t, triggered_manually)
|
||||||
{
|
{
|
||||||
text = text,
|
text = text,
|
||||||
info = info.info,
|
info = info.info,
|
||||||
desc = info.desc, -- Description shown on item selected
|
desc = info.desc, -- Description shown on item selected
|
||||||
cb = info.cb, -- A callback called once when item is selected
|
onhover = info.onhover, -- A callback called once when item is hovered
|
||||||
data = info.data -- Optional data that can be used on cb
|
onselect = info.onselect, -- A callback called when item is selected
|
||||||
|
data = info.data -- Optional data that can be used on cb
|
||||||
},
|
},
|
||||||
mt
|
mt
|
||||||
)
|
)
|
||||||
|
@ -56,7 +61,7 @@ function autocomplete.add(t, triggered_manually)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not triggered_manually then
|
if not manually_triggered then
|
||||||
autocomplete.map[t.name] = { files = t.files or ".*", items = items }
|
autocomplete.map[t.name] = { files = t.files or ".*", items = items }
|
||||||
else
|
else
|
||||||
autocomplete.map_manually[t.name] = { files = t.files or ".*", items = items }
|
autocomplete.map_manually[t.name] = { files = t.files or ".*", items = items }
|
||||||
|
@ -66,7 +71,7 @@ end
|
||||||
--
|
--
|
||||||
-- Thread that scans open document symbols and cache them
|
-- Thread that scans open document symbols and cache them
|
||||||
--
|
--
|
||||||
local max_symbols = config.max_symbols
|
local max_symbols = config.plugins.autocomplete.max_symbols
|
||||||
|
|
||||||
core.add_thread(function()
|
core.add_thread(function()
|
||||||
local cache = setmetatable({}, { __mode = "k" })
|
local cache = setmetatable({}, { __mode = "k" })
|
||||||
|
@ -85,7 +90,9 @@ core.add_thread(function()
|
||||||
doc.disable_symbols = true
|
doc.disable_symbols = true
|
||||||
core.status_view:show_message("!", style.accent,
|
core.status_view:show_message("!", style.accent,
|
||||||
"Too many symbols in document "..doc.filename..
|
"Too many symbols in document "..doc.filename..
|
||||||
": stopping auto-complete for this document according to config.max_symbols.")
|
": stopping auto-complete for this document according to "..
|
||||||
|
"config.plugins.autocomplete.max_symbols."
|
||||||
|
)
|
||||||
collectgarbage('collect')
|
collectgarbage('collect')
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
|
@ -159,16 +166,6 @@ local function reset_suggestions()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function in_table(value, table_array)
|
|
||||||
for i, element in pairs(table_array) do
|
|
||||||
if element == value then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local function update_suggestions()
|
local function update_suggestions()
|
||||||
local doc = core.active_view.doc
|
local doc = core.active_view.doc
|
||||||
local filename = doc and doc.filename or ""
|
local filename = doc and doc.filename or ""
|
||||||
|
@ -199,6 +196,7 @@ local function update_suggestions()
|
||||||
j = j + 1
|
j = j + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
suggestions_idx = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_partial_symbol()
|
local function get_partial_symbol()
|
||||||
|
@ -249,6 +247,11 @@ local function get_suggestions_rect(av)
|
||||||
max_width = 150
|
max_width = 150
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- if portion not visiable to right, reposition to DocView right margin
|
||||||
|
if (x - av.position.x) + max_width > av.size.x then
|
||||||
|
x = (av.size.x + av.position.x) - max_width - (style.padding.x * 2)
|
||||||
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
x - style.padding.x,
|
x - style.padding.x,
|
||||||
y - style.padding.y,
|
y - style.padding.y,
|
||||||
|
@ -256,20 +259,99 @@ local function get_suggestions_rect(av)
|
||||||
max_items * (th + style.padding.y) + style.padding.y
|
max_items * (th + style.padding.y) + style.padding.y
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function wrap_line(line, max_chars)
|
||||||
|
if #line > max_chars then
|
||||||
|
local lines = {}
|
||||||
|
local line_len = #line
|
||||||
|
local new_line = ""
|
||||||
|
local prev_char = ""
|
||||||
|
local position = 0
|
||||||
|
local indent = line:match("^%s+")
|
||||||
|
for char in line:gmatch(".") do
|
||||||
|
position = position + 1
|
||||||
|
if #new_line < max_chars then
|
||||||
|
new_line = new_line .. char
|
||||||
|
prev_char = char
|
||||||
|
if position >= line_len then
|
||||||
|
table.insert(lines, new_line)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if
|
||||||
|
not prev_char:match("%s")
|
||||||
|
and
|
||||||
|
not string.sub(line, position+1, 1):match("%s")
|
||||||
|
and
|
||||||
|
position < line_len
|
||||||
|
then
|
||||||
|
new_line = new_line .. "-"
|
||||||
|
end
|
||||||
|
table.insert(lines, new_line)
|
||||||
|
if indent then
|
||||||
|
new_line = indent .. char
|
||||||
|
else
|
||||||
|
new_line = char
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return lines
|
||||||
|
end
|
||||||
|
return line
|
||||||
|
end
|
||||||
|
|
||||||
|
local previous_scale = SCALE
|
||||||
|
local desc_font = style.code_font:copy(
|
||||||
|
config.plugins.autocomplete.desc_font_size * SCALE
|
||||||
|
)
|
||||||
local function draw_description_box(text, av, sx, sy, sw, sh)
|
local function draw_description_box(text, av, sx, sy, sw, sh)
|
||||||
|
if previous_scale ~= SCALE then
|
||||||
|
desc_font = style.code_font:copy(
|
||||||
|
config.plugins.autocomplete.desc_font_size * SCALE
|
||||||
|
)
|
||||||
|
previous_scale = SCALE
|
||||||
|
end
|
||||||
|
|
||||||
|
local font = desc_font
|
||||||
|
local lh = font:get_height()
|
||||||
|
local y = sy + style.padding.y
|
||||||
|
local x = sx + sw + style.padding.x / 4
|
||||||
local width = 0
|
local width = 0
|
||||||
|
local char_width = font:get_width(" ")
|
||||||
|
local draw_left = false;
|
||||||
|
|
||||||
|
local max_chars = 0
|
||||||
|
if sx - av.position.x < av.size.x - (sx - av.position.x) - sw then
|
||||||
|
max_chars = (((av.size.x+av.position.x) - x) / char_width) - 5
|
||||||
|
else
|
||||||
|
draw_left = true;
|
||||||
|
max_chars = (
|
||||||
|
(sx - av.position.x - (style.padding.x / 4) - style.scrollbar_size)
|
||||||
|
/ char_width
|
||||||
|
) - 5
|
||||||
|
end
|
||||||
|
|
||||||
local lines = {}
|
local lines = {}
|
||||||
for line in string.gmatch(text.."\n", "(.-)\n") do
|
for line in string.gmatch(text.."\n", "(.-)\n") do
|
||||||
width = math.max(width, style.font:get_width(line))
|
local wrapper_lines = wrap_line(line, max_chars)
|
||||||
table.insert(lines, line)
|
if type(wrapper_lines) == "table" then
|
||||||
|
for _, wrapped_line in pairs(wrapper_lines) do
|
||||||
|
width = math.max(width, font:get_width(wrapped_line))
|
||||||
|
table.insert(lines, wrapped_line)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
width = math.max(width, font:get_width(line))
|
||||||
|
table.insert(lines, line)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local height = #lines * style.font:get_height()
|
if draw_left then
|
||||||
|
x = sx - (style.padding.x / 4) - width - (style.padding.x * 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local height = #lines * font:get_height()
|
||||||
|
|
||||||
-- draw background rect
|
-- draw background rect
|
||||||
renderer.draw_rect(
|
renderer.draw_rect(
|
||||||
sx + sw + style.padding.x / 4,
|
x,
|
||||||
sy,
|
sy,
|
||||||
width + style.padding.x * 2,
|
width + style.padding.x * 2,
|
||||||
height + style.padding.y * 2,
|
height + style.padding.y * 2,
|
||||||
|
@ -277,13 +359,10 @@ local function draw_description_box(text, av, sx, sy, sw, sh)
|
||||||
)
|
)
|
||||||
|
|
||||||
-- draw text
|
-- draw text
|
||||||
local lh = style.font:get_height()
|
|
||||||
local y = sy + style.padding.y
|
|
||||||
local x = sx + sw + style.padding.x / 4
|
|
||||||
|
|
||||||
for _, line in pairs(lines) do
|
for _, line in pairs(lines) do
|
||||||
common.draw_text(
|
common.draw_text(
|
||||||
style.font, style.text, line, "left", x + style.padding.x, y, width, lh
|
font, style.text, line, "left",
|
||||||
|
x + style.padding.x, y, width, lh
|
||||||
)
|
)
|
||||||
y = y + lh
|
y = y + lh
|
||||||
end
|
end
|
||||||
|
@ -320,10 +399,9 @@ local function draw_suggestions_box(av)
|
||||||
end
|
end
|
||||||
y = y + lh
|
y = y + lh
|
||||||
if suggestions_idx == i then
|
if suggestions_idx == i then
|
||||||
if s.cb then
|
if s.onhover then
|
||||||
s.cb(suggestions_idx, s)
|
s.onhover(suggestions_idx, s)
|
||||||
s.cb = nil
|
s.onhover = nil
|
||||||
s.data = nil
|
|
||||||
end
|
end
|
||||||
if s.desc and #s.desc > 0 then
|
if s.desc and #s.desc > 0 then
|
||||||
draw_description_box(s.desc, av, rx, ry, rw, rh)
|
draw_description_box(s.desc, av, rx, ry, rw, rh)
|
||||||
|
@ -487,10 +565,17 @@ command.add(predicate, {
|
||||||
["autocomplete:complete"] = function()
|
["autocomplete:complete"] = function()
|
||||||
local doc = core.active_view.doc
|
local doc = core.active_view.doc
|
||||||
local line, col = doc:get_selection()
|
local line, col = doc:get_selection()
|
||||||
local text = suggestions[suggestions_idx].text
|
local item = suggestions[suggestions_idx]
|
||||||
doc:insert(line, col, text)
|
local text = item.text
|
||||||
doc:remove(line, col, line, col - #partial)
|
local inserted = false
|
||||||
doc:set_selection(line, col + #text - #partial)
|
if item.onselect then
|
||||||
|
inserted = item.onselect(suggestions_idx, item)
|
||||||
|
end
|
||||||
|
if not inserted then
|
||||||
|
doc:insert(line, col, text)
|
||||||
|
doc:remove(line, col, line, col - #partial)
|
||||||
|
doc:set_selection(line, col + #text - #partial)
|
||||||
|
end
|
||||||
reset_suggestions()
|
reset_suggestions()
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue