Skip to content

Commit

Permalink
fix(cmdline): use real cursors on Neovim >= 0.10
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Jun 4, 2024
1 parent b3f08e6 commit 5b5fa91
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 14 deletions.
1 change: 1 addition & 0 deletions lua/noice/message/router.lua
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ function M.check_redraw()
M._need_redraw = false
Util.redraw()
end
require("noice.ui.cmdline").fix_cursor()
end
end

Expand Down
5 changes: 4 additions & 1 deletion lua/noice/text/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ local Markdown = require("noice.text.markdown")

---@class NoiceText: NuiText
---@field super NuiText
---@field enabled? boolean
---@field on_render? fun(text: NoiceText, buf:number, line: number, byte:number, col:number)
---@overload fun(content:string, highlight?:string|NoiceExtmark):NoiceText
---@diagnostic disable-next-line: undefined-field
Expand Down Expand Up @@ -111,7 +112,9 @@ function NoiceText:highlight(bufnr, ns_id, linenr, byte_start)
extmark.col = nil
end

NoiceText.super.highlight(self, bufnr, ns_id, linenr, byte_start)
if self.enabled ~= false then
NoiceText.super.highlight(self, bufnr, ns_id, linenr, byte_start)
end

if self.on_render then
self.on_render(self, bufnr, linenr, byte_start_orig, col_start)
Expand Down
44 changes: 32 additions & 12 deletions lua/noice/ui/cmdline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ M.events = {

---@type NoiceCmdline?
M.active = nil
M.real_cursor = vim.api.nvim__redraw ~= nil

---@alias NoiceCmdlineFormatter fun(cmdline: NoiceCmdline): {icon?:string, offset?:number, view?:NoiceViewOptions}

Expand Down Expand Up @@ -142,6 +143,7 @@ function Cmdline:format(message, text_only)
if not text_only then
local cursor = NoiceText.cursor(-self:length() + self.state.pos)
cursor.on_render = M.on_render
cursor.enabled = not M.real_cursor
message:append(cursor)
end
end
Expand Down Expand Up @@ -211,10 +213,31 @@ end
---@class CmdlinePosition
---@field win number Window containing the cmdline
---@field buf number Buffer containing the cmdline
---@field cursor number
---@field bufpos {row:number, col:number} (1-0)-indexed position of the cmdline in the buffer
---@field screenpos {row:number, col:number} (1-0)-indexed screen position of the cmdline
M.position = nil

function M.fix_cursor()
local win = M.position.win
local cursor = M.position.cursor
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_win_set_cursor(win, { 1, cursor })
vim.api.nvim_win_call(win, function()
local width = vim.api.nvim_win_get_width(win)
local leftcol = math.max(cursor - width + 1, 0)
vim.fn.winrestview({ leftcol = leftcol })
end)
if M.real_cursor then
vim.cmd.redrawstatus()
vim.api.nvim__redraw({
cursor = true,
win = win,
})
end
end
end

---@param buf number
---@param line number
---@param byte number
Expand All @@ -227,19 +250,12 @@ function M.on_render(_, buf, line, byte)
local cmdline_start = byte - (M.last():length() - M.last().offset)

local cursor = byte - M.last():length() + M.last().state.pos
vim.schedule(function()
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_win_set_cursor(win, { 1, cursor })
vim.api.nvim_win_call(win, function()
local width = vim.api.nvim_win_get_width(win)
local leftcol = math.max(cursor - width + 1, 0)
vim.fn.winrestview({ leftcol = leftcol })
end)
end
end)

pcall(M.fix_cursor)

local pos = vim.fn.screenpos(win, line, cmdline_start)
M.position = {
cursor = cursor,
buf = buf,
win = win,
bufpos = {
Expand All @@ -265,11 +281,15 @@ function M.update()

if cmdline then
cmdline:format(M.message)
Hacks.hide_cursor()
if not M.real_cursor then
Hacks.hide_cursor()
end
Manager.add(M.message)
else
Manager.remove(M.message)
Hacks.show_cursor()
if not M.real_cursor then
Hacks.show_cursor()
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion lua/noice/util/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ end

function M.is_search()
local cmdline = require("noice.ui.cmdline")
local c = cmdline.last()
local c = cmdline.active
if c and (c.state.firstc == "/" or c.state.firstc == "?") then
return true
end
Expand Down

0 comments on commit 5b5fa91

Please sign in to comment.