Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve CommandView and autocomplete scroll behavior #1732

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 29 additions & 9 deletions data/core/commandview.lua
@@ -1,5 +1,6 @@
local core = require "core"
local common = require "core.common"
local config = require "core.config"
local style = require "core.style"
local Doc = require "core.doc"
local DocView = require "core.docview"
Expand All @@ -20,8 +21,6 @@ local CommandView = DocView:extend()

CommandView.context = "application"

local max_suggestions = 10

local noop = function() end

---@class core.commandview.state
Expand Down Expand Up @@ -50,6 +49,7 @@ local default_state = {
function CommandView:new()
CommandView.super.new(self, SingleLineDoc())
self.suggestion_idx = 1
self.suggestions_offset = 1
self.suggestions = {}
self.suggestions_height = 0
self.last_change_id = 0
Expand Down Expand Up @@ -128,6 +128,24 @@ function CommandView:move_suggestion_idx(dir)
end
end

local function get_suggestions_offset()
local max_visible = math.min(config.max_visible_commands, #self.suggestions)
if dir > 0 then
if self.suggestions_offset + max_visible < self.suggestion_idx + 1 then
return self.suggestion_idx - max_visible + 1
elseif self.suggestions_offset > self.suggestion_idx then
return self.suggestion_idx
end
else
if self.suggestions_offset > self.suggestion_idx then
return self.suggestion_idx
elseif self.suggestions_offset + max_visible < self.suggestion_idx + 1 then
return self.suggestion_idx - max_visible + 1
end
end
return self.suggestions_offset
end

if self.state.show_suggestions then
local n = self.suggestion_idx + dir
self.suggestion_idx = overflow_suggestion_idx(n, #self.suggestions)
Expand All @@ -151,6 +169,8 @@ function CommandView:move_suggestion_idx(dir)
self.last_change_id = self.doc:get_change_id()
self.state.suggest(self:get_text())
end

self.suggestions_offset = get_suggestions_offset()
end


Expand Down Expand Up @@ -261,6 +281,7 @@ function CommandView:update_suggestions()
end
self.suggestions = res
self.suggestion_idx = 1
self.suggestions_offset = 1
end


Expand Down Expand Up @@ -300,11 +321,11 @@ function CommandView:update()

-- update suggestions box height
local lh = self:get_suggestion_line_height()
local dest = self.state.show_suggestions and math.min(#self.suggestions, max_suggestions) * lh or 0
local dest = self.state.show_suggestions and math.min(#self.suggestions, config.max_visible_commands) * lh or 0
self:move_towards("suggestions_height", dest, nil, "commandview")

-- update suggestion cursor offset
local dest = math.min(self.suggestion_idx, max_suggestions) * self:get_suggestion_line_height()
local dest = (self.suggestion_idx - self.suggestions_offset + 1) * self:get_suggestion_line_height()
self:move_towards("selection_offset", dest, nil, "commandview")

-- update size based on whether this is the active_view
Expand Down Expand Up @@ -340,6 +361,7 @@ local function draw_suggestions_box(self)
local h = math.ceil(self.suggestions_height)
local rx, ry, rw, rh = self.position.x, self.position.y - h - dh, self.size.x, h

core.push_clip_rect(rx, ry, rw, rh)
-- draw suggestions background
if #self.suggestions > 0 then
renderer.draw_rect(rx, ry, rw, rh, style.background3)
Expand All @@ -349,14 +371,12 @@ local function draw_suggestions_box(self)
end

-- draw suggestion text
local offset = math.max(self.suggestion_idx - max_suggestions, 0)
local last = math.min(offset + max_suggestions, #self.suggestions)
core.push_clip_rect(rx, ry, rw, rh)
local first = 1 + offset
local first = math.max(self.suggestions_offset, 1)
local last = math.min(self.suggestions_offset + config.max_visible_commands, #self.suggestions)
for i=first, last do
local item = self.suggestions[i]
local color = (i == self.suggestion_idx) and style.accent or style.text
local y = self.position.y - (i - offset) * lh - dh
local y = self.position.y - (i - first + 1) * lh - dh
common.draw_text(self:get_font(), color, item.text, nil, x, y, 0, lh)

if item.info then
Expand Down
6 changes: 6 additions & 0 deletions data/core/config.lua
Expand Up @@ -112,6 +112,12 @@ config.max_undos = 10000
---@type number
config.max_tabs = 8

---The maximum number of entries shown at a time in the command palette.
---
---The default is 10.
---@type integer
config.max_visible_commands = 10

---Shows/hides the tab bar when there is only one tab open.
---
---The tab bar is always shown by default.
Expand Down
23 changes: 20 additions & 3 deletions data/plugins/autocomplete.lua
Expand Up @@ -282,12 +282,14 @@ end)


local partial = ""
local suggestions_offset = 1
local suggestions_idx = 1
local suggestions = {}
local last_line, last_col


local function reset_suggestions()
suggestions_offset = 1
suggestions_idx = 1
suggestions = {}

Expand Down Expand Up @@ -369,6 +371,7 @@ local function update_suggestions()
end
end
suggestions_idx = 1
suggestions_offset = 1
end

local function get_partial_symbol()
Expand Down Expand Up @@ -565,8 +568,8 @@ local function draw_suggestions_box(av)
local font = av:get_font()
local lh = font:get_height() + style.padding.y
local y = ry + style.padding.y / 2
local show_count = #suggestions <= ah and #suggestions or ah
local start_index = suggestions_idx > ah and (suggestions_idx-(ah-1)) or 1
local show_count = math.min(#suggestions, ah)
local start_index = suggestions_offset
local hide_info = config.plugins.autocomplete.hide_info

for i=start_index, start_index+show_count-1, 1 do
Expand Down Expand Up @@ -819,7 +822,7 @@ command.add(predicate, {
local current_partial = get_partial_symbol()
local sz = #current_partial

for idx, line1, col1, line2, col2 in doc:get_selections(true) do
for _, line1, col1, line2, _ in doc:get_selections(true) do
local n = col1 - 1
local line = doc.lines[line1]
for i = 1, sz + 1 do
Expand All @@ -840,10 +843,24 @@ command.add(predicate, {

["autocomplete:previous"] = function()
suggestions_idx = (suggestions_idx - 2) % #suggestions + 1

local ah = math.min(config.plugins.autocomplete.max_height, #suggestions)
if suggestions_offset > suggestions_idx then
suggestions_offset = suggestions_idx
elseif suggestions_offset + ah < suggestions_idx + 1 then
suggestions_offset = suggestions_idx - ah + 1
end
end,

["autocomplete:next"] = function()
suggestions_idx = (suggestions_idx % #suggestions) + 1

local ah = math.min(config.plugins.autocomplete.max_height, #suggestions)
if suggestions_offset + ah < suggestions_idx + 1 then
suggestions_offset = suggestions_idx - ah + 1
elseif suggestions_offset > suggestions_idx then
suggestions_offset = suggestions_idx
end
end,

["autocomplete:cycle"] = function()
Expand Down