Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/lua/bugabinga/pivi/dialog.lua

Raw
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,
}