Skip to content

Lightweight Neovim plugin that shows what’s playing in Apple Music or Spotify with a floating panel, statusline helper, controls, and artwork rendering.

License

Notifications You must be signed in to change notification settings

Ferouk/nowplaying.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NowPlaying.nvim 🎶

GitHub stars GitHub issues GitHub contributors

Lightweight Neovim plugin that shows what's playing in Apple Music or Spotify on macOS, with controls, notifications, floating panel, and artwork rendering.

Features ✨

  • AppleScript-powered Apple Music and Spotify support.
  • Panel with artwork, metadata, progress bar, and key hints.
  • Commands for play/pause, next/previous, volume, seek, and refresh.
  • Optional track-change notifications (vim.notify).
  • Statusline helper (require("player").statusline()).
  • Real artwork rendering via image.nvim.

Preview 📸

Panel (playing) Panel (playing)

Floating panel with artwork, metadata, progress, and controls while a track is playing.

Panel (paused) Panel (paused)

Panel showing paused state.

Notification Notification on track change

Track-change toast via vim.notify.

Statusline (playing) Statusline (playing)

Statusline snippet showing playing icon/text.

Statusline (paused) Statusline (paused)

Statusline snippet showing paused icon/text.

Requirements 📦

  • macOS with Apple Music or Spotify installed.
  • osascript available (default on macOS).
  • curl for downloading Spotify artwork to cache (optional; only required if artwork is enabled).
  • ImageMagick (optional; only required if artwork is enabled).
  • image.nvim (optional; only required if artwork is enabled).

Installation 🧰

Lazy.nvim

Without image.nvim dependency:

{
  "Ferouk/nowplaying.nvim",
  config = function()
    require("player").setup()
  end,
}

With image.nvim dependency (if artwork is enabled):

{
  "Ferouk/nowplaying.nvim",
  dependencies = {
    {
      "3rd/image.nvim",
      opts = { backend = "kitty" }, -- or "ueberzug" / "sixel" check your terminal compatibility
    },
  },
  config = function()
    require("player").setup()
  end,
}

Packer.nvim:

Without image.nvim dependency:

use({
  "Ferouk/nowplaying.nvim",
  config = function()
    require("player").setup()
  end,
})

With image.nvim dependency (if artwork is enabled):

use({
  "Ferouk/nowplaying.nvim",
  requires = {
    {
      "3rd/image.nvim",
      config = function()
        require("image").setup({ backend = "kitty" }) -- or "ueberzug" / "sixel" check your terminal compatibility
      end,
    },
  },
  config = function()
    require("player").setup()
  end,
})

Commands ⌨️

  • :NowPlayingPlayPause toggle playback
  • :NowPlayingNext / :NowPlayingPrev next/previous track
  • :NowPlayingVolUp / :NowPlayingVolDown volume ±5%
  • :NowPlayingSeekForward / :NowPlayingSeekBackward seek ±5s
  • :NowPlayingTogglePanel open/close the panel
  • :NowPlayingNotify show current track via vim.notify
  • :NowPlayingRefresh refresh state and redraw UI

Panel keymaps: p play/pause, n next, b previous, +/= volume up, - volume down, l/> seek forward, h/< seek backward, r refresh, q close.

Configuration 🛠️

require("player").setup({
  player_priority = { "apple_music", "spotify" }, -- default order
  poll = {
    enabled = true,
    interval_ms = 5000,
  },
  notify = {
    enabled = false, -- default: off
    timeout = 2500,
    elements = {
      track_title = true,
      artist = true,
      album = true,
      status_icon = true,
      player = true,
    },
  },
  statusline = {
    elements = {
      track_title = true,
      artist = true,
      album = true,
      status_icon = true, -- ▶/⏸
      player = true,
    },
    separator = " - ",
    max_length = 50, -- truncate to display width
  },
  panel = {
    enabled = true,
    border = "rounded",
    width = nil, -- set to number for fixed width; nil auto/fallback
    height = nil, -- set to number for fixed height; nil auto
    elements = {
      track_title = true,
      artist = true,
      album = true,
      progress_bar = true,
      volume = true,
      controls = true,
      artwork = {
        enabled = false,
        cache_dir = vim.fn.stdpath("cache") .. "/nowplaying.nvim",
        download = false, -- download Spotify artwork URLs to cache
        width = 20,
        height = 10,
      },
    },
  },
  auto_switch = true, -- fall back to next provider when inactive
  log_level = "warn",
})

Visibility: toggle any true/false field under panel.elements, notify.elements, or statusline.elements. Default is all true except artwork in panel.

Statusline / Winbar 📏

-- LuaLine/Heirline/etc.
local nowplaying = require("player").statusline

Lualine

local nowplaying = require("player").statusline

require("lualine").setup({
  sections = {
    lualine_c = { nowplaying },
  },
})

Heirline

local statusline = require("player").statusline

require("heirline").setup({
  statusline = {
    statusline,
    -- add other components here
  },
})

Artwork 🖼️

Album artwork is rendered as real images in the panel using image.nvim. Spotify artwork can be downloaded and cached when panel.elements.artwork.download = true; Apple Music artwork is extracted to cache_dir.

Planned Work 🔜

  • Linux support (MPRIS backend)
  • Windows support (media session/PowerShell backend)

Credits 🙌

Artwork rendering powered by image.nvim by @3rd.

License 📄

GPL-3.0-only. (See LICENSE)

About

Lightweight Neovim plugin that shows what’s playing in Apple Music or Spotify with a floating panel, statusline helper, controls, and artwork rendering.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Languages