From 254fd92adbb75a1e82c24eacabfbd1fdb88c0d36 Mon Sep 17 00:00:00 2001 From: Ade Attwood Date: Fri, 2 Sep 2022 20:48:30 +0100 Subject: [PATCH] feat: make the completion candidates type more consistent The API for `window.set_items` took to many variable types. It would take a table in multiple different formats and a string. Now it will only take a table in a single format and a string. It will convert the string into the table format by splitting it on new lines. The table format is an array of tables that must have a `content` key that will be the text that is displayed in the completion window. The table can have any other data that is ignored. ```lua local items = { { content = "Item one" }, { content = "Item two" } } ``` The `set_items` function will only display the `content` key in the completion window, it will not do any sorting or filtering, that must be done before passing the data to the `set_items` function. --- lua/ivy/controller.lua | 3 ++- lua/ivy/window.lua | 48 ++++++++++++++++++++---------------------- plugin/ivy.lua | 4 ++-- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/lua/ivy/controller.lua b/lua/ivy/controller.lua index ff11426..be93ef6 100644 --- a/lua/ivy/controller.lua +++ b/lua/ivy/controller.lua @@ -11,7 +11,8 @@ controller.run = function(name, items, callback) controller.items = items window.initialize() - window.set_items { "-- Loading ---" } + + window.set_items { { content = "-- Loading ---" } } vim.api.nvim_buf_set_name(window.get_buffer(), name) controller.input "" diff --git a/lua/ivy/window.lua b/lua/ivy/window.lua index addefc1..5db6d20 100644 --- a/lua/ivy/window.lua +++ b/lua/ivy/window.lua @@ -13,26 +13,12 @@ local chars = { } local function string_to_table(lines) - local items = {} + local matches = {} for line in lines:gmatch "[^\r\n]+" do - table.insert(items, line) + table.insert(matches, { content = line }) end - return items -end - -local function set_items_string(buffer, lines) - vim.api.nvim_buf_set_lines(buffer, 0, 9999, false, string_to_table(lines)) -end - -local function set_items_array(buffer, lines) - if type(lines[1]) == "string" then - vim.api.nvim_buf_set_lines(buffer, 0, 9999, false, lines) - else - for i = 1, #lines do - vim.api.nvim_buf_set_lines(buffer, i - 1, 9999, false, { lines[i][2] }) - end - end + return matches end local window = {} @@ -112,16 +98,28 @@ window.update = function() end window.set_items = function(items) - if #items == 0 then - vim.api.nvim_buf_set_lines(window.get_buffer(), 0, 9999, false, { "-- No Items --" }) - elseif type(items) == "string" then - set_items_string(window.get_buffer(), items) - elseif type(items) == "table" then - set_items_array(window.get_buffer(), items) + if type(items) == "string" then + items = string_to_table(items) end - local line_count = vim.api.nvim_buf_line_count(window.buffer) - window.index = line_count - 1 + -- TODO(ade): Validate the items are in the correct format. This also need to + -- come with some descriptive messages and possible help. + + -- Display no items text if there are no items to dispaly + if #items == 0 then + items = { { content = "-- No Items --" } } + end + + local items_length = #items + window.index = items_length - 1 + + for index = 1, items_length do + vim.api.nvim_buf_set_lines(window.buffer, index - 1, -1, false, { items[index].content }) + end + + -- Limit the results window size to 10 so when there are lots of results the + -- window does not take up the hole terminal + local line_count = items_length - 1 if line_count > 10 then line_count = 10 end diff --git a/plugin/ivy.lua b/plugin/ivy.lua index e5f1233..e6351d3 100644 --- a/plugin/ivy.lua +++ b/plugin/ivy.lua @@ -30,13 +30,13 @@ vim.api.nvim_create_user_command("IvyBuffers", function() if vim.api.nvim_buf_is_loaded(buffer) and #buffer_name > 0 then local score = libivy.ivy_match(input, buffer_name) if score > -200 or #input == 0 then - table.insert(list, { score, buffer_name }) + table.insert(list, { score = score, content = buffer_name }) end end end table.sort(list, function(a, b) - return a[1] < b[1] + return a.score < b.score end) return list