local publish = require 'bugabinga.pivi.publish' local NOTIFY_LEVELS = { info = vim.log.levels.INFO, warning = vim.log.levels.WARN, error = vim.log.levels.ERROR, } local widgets = {} local statuses = {} local value_response = function( id, value ) if value == nil then return { type = 'extension_ui_response', id = id, cancelled = true, } end return { type = 'extension_ui_response', id = id, value = value, } end --- Maps one extension UI request to a native Neovim surface. --- Dialog methods answer with the request's own identifier; fire and forget --- methods answer with nothing. --- @param request table the `extension_ui_request` frame --- @param respond fun(response: table) sends an `extension_ui_response` --- @return boolean handled local handle = function( request, respond ) if type( request ) ~= 'table' or request.type ~= 'extension_ui_request' then return false end local method = request.method if method == 'select' then vim.ui.select( request.options or {}, { prompt = request.title, }, function( choice ) respond( value_response( request.id, choice ) ) end ) return true end if method == 'confirm' then local message = request.message and ( request.title .. '\n' .. request.message ) or request.title vim.ui.select( { 'yes', 'no', }, { prompt = message, }, function( choice ) if choice == nil then respond { type = 'extension_ui_response', id = request.id, cancelled = true, } return end respond { type = 'extension_ui_response', id = request.id, confirmed = choice == 'yes', } end ) return true end if method == 'input' then vim.ui.input( { prompt = request.title, default = request.placeholder, }, function( value ) respond( value_response( request.id, value ) ) end ) return true end if method == 'editor' then vim.ui.input( { prompt = request.title, default = request.prefill, }, function( value ) respond( value_response( request.id, value ) ) end ) return true end if method == 'notify' then vim.notify( request.message or '', NOTIFY_LEVELS[request.notifyType] or vim.log.levels.INFO ) return true end if method == 'setStatus' then statuses[request.statusKey] = request.statusText publish.activity { kind = 'status', key = request.statusKey, text = request.statusText, } return true end if method == 'setWidget' then widgets[request.widgetKey] = request.widgetLines publish.activity { kind = 'widget', key = request.widgetKey, lines = request.widgetLines, } return true end if method == 'setTitle' then pcall( function() vim.o.titlestring = request.title or '' end ) return true end if method == 'set_editor_text' then publish.activity { kind = 'editor_text', text = request.text, } return true end return false end local status_entries = function() return vim.deepcopy( statuses ) end local widget_entries = function() return vim.deepcopy( widgets ) end local reset = function() widgets = {} statuses = {} end return { handle = handle, statuses = status_entries, widgets = widget_entries, reset = reset, }