Skip to content
Rónán Carrigan edited this page Mar 15, 2022 · 20 revisions

Examples of use cases for nvim-notify

These examples assume that you have set nvim-notify as your vim.notify handler

vim.notify = require("notify")

Output of Command

Uses jobstart to run asynchronously.

local function notify_output(command, opts)
  local output = ""
  local notification
  local notify = function(msg, level)
    local notify_opts = vim.tbl_extend(
      "keep",
      opts or {},
      { title = table.concat(command, " "), replace = notification }
    )
    notification = vim.notify(msg, level, notify_opts)
  end
  local on_data = function(_, data)
    output = output .. table.concat(data, "\n")
    notify(output, "info")
  end
  vim.fn.jobstart(command, {
    on_stdout = on_data,
    on_stderr = on_data,
    on_exit = function(_, code)
      if #output == 0 then
        notify("No output of command, exit code: " .. code, "warn")
      end
    end,
  })
end

notify_output({ "echo", "hello world" })

LSP Status Updates

local client_notifs = {}

local spinner_frames = { "", "", "", "", "", "", "", "" }

local function update_spinner(client_id, token)
  local notif_data = client_notifs[client_id][token]

  if notif_data and notif_data.spinner then
    local new_spinner = (notif_data.spinner + 1) % #spinner_frames

    local new_notif = vim.notify(nil, nil, {
      hidden = true,
      icon = spinner_frames[new_spinner],
      replace = notif_data.notification,
    })

    client_notifs[client_id][token] = {
      notification = new_notif,
      spinner = new_spinner,
    }

    vim.defer_fn(function()
      update_spinner(client_id, token)
    end, 100)
  end
end

local function format_title(title, client)
  return client.name .. (#title > 0 and ": " .. title or "")
end

local function format_message(message, percentage)
  return (percentage and percentage .. "%\t" or "") .. (message or "")
end

vim.lsp.handlers["$/progress"] = function(_, result, ctx)
  local client_id = ctx.client_id

  local val = result.value

  if not val.kind then
    return
  end
  if not client_notifs[client_id] then
    client_notifs[client_id] = {}
  end

  local notif_data = client_notifs[client_id][result.token]

  if val.kind == "begin" then
    local message = format_message(val.message, val.percentage)

    local notification = vim.notify(message, "info", {
      title = format_title(val.title, vim.lsp.get_client_by_id(client_id)),
      icon = spinner_frames[1],
      timeout = false,
      hidden = false,
    })

    client_notifs[client_id][result.token] = {
      notification = notification,
      spinner = 1,
    }

    update_spinner(client_id, result.token)
  elseif val.kind == "report" and notif_data then
    local new_notif = vim.notify(format_message(val.message, val.percentage), "info", {
      replace = notif_data.notification,
      hidden = false,
    })

    client_notifs[client_id][result.token] = {
      notification = new_notif,
      spinner = notif_data.spinner,
    }
  elseif val.kind == "end" and notif_data then
    local new_notif =
      vim.notify(val.message and format_message(val.message) or "Complete", "info", {
        icon = "",
        replace = notif_data.notification,
        timeout = 3000,
      })

    client_notifs[client_id][result.token] = {
      notification = new_notif,
    }
  end
end
Clone this wiki locally