Skip to content

Commit

Permalink
feat: rewrite ghost text
Browse files Browse the repository at this point in the history
  • Loading branch information
max397574 committed Jul 14, 2024
1 parent 9d4fd1d commit bb96537
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 41 deletions.
4 changes: 2 additions & 2 deletions docs/config.norg
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ version: 1.1.1
virtual text which shows a preview of the entry.
#tangle
@code lua
--- Whether to show ghost text
---@field ghost_text boolean
--- Configuration of ghost text
---@field ghost_text { enabled: boolean, position: "inline"|"overlay" }
@end

** Menu
Expand Down
5 changes: 4 additions & 1 deletion lua/neocomplete/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ config.defaults = {
Value = "󰎠",
Variable = "󰫧",
},
ghost_text = true,
ghost_text = {
enabled = true,
position = "overlay",
},
},
snippet_expansion = function(snippet_body)
vim.snippet.expand(snippet_body)
Expand Down
93 changes: 59 additions & 34 deletions lua/neocomplete/ghost_text.lua
Original file line number Diff line number Diff line change
@@ -1,41 +1,66 @@
local ghost_text = {}
local Ghost_text = {}

local ns = vim.api.nvim_create_namespace("neocomplete.ghost_text")
function Ghost_text.new()
local self = setmetatable({}, { __index = Ghost_text })
self.ns = vim.api.nvim_create_namespace("neocomplete.ghost_text")
---@type neocomplete.entry?
self.entry = nil
---@type integer?
self.win = nil
---@type integer?
self.extmark_id = nil
self.config = require("neocomplete.config").options.ui.ghost_text
vim.api.nvim_set_decoration_provider(self.ns, {
on_win = function(_, win)
return win == self.win
end,
on_line = function()
if self.extmark_id then
vim.api.nvim_buf_del_extmark(vim.api.nvim_get_current_buf(), self.ns, self.extmark_id)
self.extmark_id = nil
end
if (not self.config.enabled) or not self.entry then
return
end
local word = self.entry:get_insert_word()
local offset = self.entry:get_offset()
local cursor = vim.api.nvim_win_get_cursor(self.win)
local text_after_filter = word:sub(cursor[2] - offset + 1)
if self.config.position == "inline" then
self.extmark_id =
vim.api.nvim_buf_set_extmark(vim.api.nvim_get_current_buf(), self.ns, cursor[1] - 1, cursor[2], {
virt_text = { { text_after_filter, "@neocomplete.ghost_text" } },
virt_text_pos = "inline",
})
elseif self.config.position == "overlay" then
self.extmark_id =
vim.api.nvim_buf_set_extmark(vim.api.nvim_get_current_buf(), self.ns, cursor[1] - 1, cursor[2], {
virt_text = { { text_after_filter, "@neocomplete.ghost_text" } },
virt_text_pos = "overlay",
ephemeral = true,
})
end
end,
})
return self
end

---@param entry neocomplete.entry
---@param offset integer
function ghost_text.show(entry, offset)
-- TODO: allow multiline text
vim.api.nvim_buf_clear_namespace(vim.api.nvim_get_current_buf(), ns, 0, -1)
local cursor = vim.api.nvim_win_get_cursor(0)
local select_behavior = require("neocomplete.config").options.selection_behavior
if select_behavior == "select" then
local text = entry:get_insert_text()
local text_after_filter = text:sub(offset + 1)
vim.api.nvim_buf_set_extmark(vim.api.nvim_get_current_buf(), ns, cursor[1] - 1, cursor[2], {
virt_text = { { text_after_filter, "@neocomplete.ghost_text" } },
virt_text_pos = "inline",
})
elseif select_behavior == "insert" then
vim.o.ul = vim.o.ul
-- TODO: allow going back to original (filter) text
local word = entry:get_insert_word()
local unblock = require("neocomplete").core:block()
-- vim.api.nvim_buf_set_text(0, cursor[1] - 1, cursor[2] - offset, cursor[1] - 1, cursor[2], { word })
-- vim.api.nvim_win_set_cursor(0, { cursor[1], cursor[2] - offset + #word })
vim.api.nvim_feedkeys(vim.keycode(string.rep("<BS>", offset) .. word), "i", false)
unblock()
local text = entry:get_insert_text()
local text_after_word = text:sub(#word + 1)
vim.api.nvim_buf_set_extmark(vim.api.nvim_get_current_buf(), ns, cursor[1] - 1, cursor[2], {
virt_text = { { text_after_word, "@neocomplete.ghost_text" } },
virt_text_pos = "inline",
})
function Ghost_text:show(entry, window)
local changed = self.entry ~= entry
self.entry = entry
self.win = window
if changed then
vim.cmd.redraw({ bang = true })
end
end

function ghost_text.hide()
vim.api.nvim_buf_clear_namespace(vim.api.nvim_get_current_buf(), ns, 0, -1)
function Ghost_text:hide()
self.entry = nil
self.win = nil
if self.extmark_id then
vim.api.nvim_buf_del_extmark(vim.api.nvim_get_current_buf(), self.ns, self.extmark_id)
self.extmark_id = nil
end
end

return ghost_text
return Ghost_text
2 changes: 1 addition & 1 deletion lua/neocomplete/menu/draw.lua
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,6 @@ return function(self)
end

if entry and self.config.ui.ghost_text then
require("neocomplete.ghost_text").show(entry, #prefix)
-- require("neocomplete.ghost_text").show(entry, #prefix)
end
end
6 changes: 5 additions & 1 deletion lua/neocomplete/menu/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function Menu.new()
self.index = 0
self.menu_window = require("neocomplete.utils.window").new()
self.docs_window = require("neocomplete.utils.window").new()
self.ghost_text = require("neocomplete.ghost_text").new()
return self
end

Expand All @@ -33,7 +34,7 @@ end
function Menu.close(self)
self.menu_window:close()
self.docs_window:close()
require("neocomplete.ghost_text").hide()
self.ghost_text:hide()
end

---@param menu neocomplete.menu
Expand Down Expand Up @@ -126,6 +127,7 @@ function Menu:select_next(count)
draw_docs(self, self:get_active_entry(), self.config.ui.docs_view)
self:draw()
self.menu_window:draw_scrollbar()
self.ghost_text:show(self:get_active_entry(), vim.api.nvim_get_current_win())
end

function Menu:select_prev(count)
Expand All @@ -138,6 +140,7 @@ function Menu:select_prev(count)
draw_docs(self, self:get_active_entry(), self.config.ui.docs_view)
self:draw()
self.menu_window:draw_scrollbar()
self.ghost_text:show(self:get_active_entry(), vim.api.nvim_get_current_win())
end

function Menu:open(entries, offset)
Expand All @@ -154,6 +157,7 @@ function Menu:open(entries, offset)
self:draw()
self.menu_window:draw_scrollbar()
self.menu_window:set_scroll(self.index, -1)
self.ghost_text:show(self:get_active_entry(), vim.api.nvim_get_current_win())
end

function Menu:get_active_entry()
Expand Down
4 changes: 2 additions & 2 deletions lua/neocomplete/types/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
---@field docs_view neocomplete.config.ui.docs
--- The icons for the different compltion item kinds
---@field type_icons neocomplete.config.ui.type_icons
--- Whether to show ghost text
---@field ghost_text boolean
--- Configuration of ghost text
---@field ghost_text { enabled: boolean, position: "inline"|"overlay" }
--- Configuration of the completion menu of neocomplete.nvim
---@class neocomplete.config.ui.menu
--- Maximum height of the menu
Expand Down

0 comments on commit bb96537

Please sign in to comment.