Control Spotify from Neovim: one step closer to the Neovimux distribution all Emacs users fear...
- Make calls to the Spotify Web API with
local response = require("spotify.api").call(endpoint, method, body)
- ...I guess that's it
Let's cut to the chase.
- Create a Spotify developer app with a redirect URI of http://localhost:8888/callback and copy the Client ID and Client Secret.
- Add the following somewhere in your Neovim config:
require("spotify").setup({ client_id = "CLIENT_ID", client_secret = "CLIENT_SECRET", })
- Create a function you find useful:
local function new_spotify_playlist() local playlists_endpoint = "/me/playlists" local method = "post" local playlist_body = { name = "spotify.nvim", description = "omg i created this with spotify.nvim???", public = true } return require("spotify.api").call(playlists_endpoint, method, playlist_body) end
- Bind your function to a keymap:
vim.keymap.set("n", "<leader>mnp", function() local new_playlist = new_spotify_playlist() vim.notify(vim.inspect(new_playlist)) end)
- Repeat steps 3 and 4.
return {
"mmuldo/spotify.nvim",
dependencies = {
"nvim-lua/plenary.nvim"
},
config = function()
-- if you're a security freak.
-- i'm just spitballing here:
local client_secret = vim.fn.system("pass spotify.nvim/client-secret")
require("spotify").setup({
client_id = "CLIENT_ID",
client_secret = client_secret
})
end
}
This plugin provides a means of interacting with the Spotify Web API in Neovim. I'd like to see someone make such a thing in VSC*de!
The idea is as follows. Calling
require("spotify").setup({
client_id = "CLIENT_ID",
client_secret = "CLIENT_SECRET",
})
handles all the Spotify auth shenanigans. After running the setup, you can then run something of the form
local response = require("spotify.api").call(endpoint, method, body)
which will handle any auth token refreshing if necessary and then query the specified API endpoint.
If you're curious, the answer is yes: I did in fact recently watch the
Pharell Williams Lego Movie and I
did in fact enjoy it. It did in fact remind me what a good producer/musician he
is and it did in fact result in me throwing on a Spotify playlist of songs he's
produced
while working one day. It was in fact chock-full of bangers which did in fact
require me to hit the three-fingered mac swipe over to my Spotify window, add
the track to my Liked Songs playlist, and three-fingered swipe back to my
Neovim window many, many times during my work session.
This did in fact impede my flow state and did in fact cause me to take more
time than usual to complete my work.
I did in fact come to the conlusion the the solution was in fact to waste
many more hours of time learning about the Spotify Web API's auth workflows
and integrating the API into Neovim all so that I could map
require("spotify.api").like_current_track()
to a keybinding, enabling
me to add Spotify tracks to my Liked Songs playlist without having to leave
Neovim. That did in fact all happen.
I'm sure you already have ideas for features that could be implemented for this plugin. For one, I think it could beautifully integrate with telescope to enable searching for and playing things on Spotify from within Neovim. That said, Spotify is vast in its use cases. Personally, I tend to listen to albums all the way through; in that case, creating an album-search picker would suit me. You, on the other hand, might prefer listening to a song and then subsequently letting Spotify play the song's radio; in that case, a track-search picker followed by a track-radio player would be suitable.
Because of these endless possibilities, I think the best future for this plugin
is to be feature-scarce: just a require("spotify.api").call
function with a
few other functions to serve as examples.
Instead of requesting new features, users are encouraged to define their own
custom Spotify API calls within their configuration--and obviously share
their config to inspire others!
Create a Spotify developer account if you haven't already, goto your dashboard, and click "Create App".
Fill out the form and for "Redirect URIs" add
You can use another port if you would like, but be sure to specify the
auth_redirect_uri_port
parameter in the setup
function.
-- /path/to/lazy/plugins/spotify.lua
local function get_device_id()
local device_id
local devices = require("spotify.api").call("/me/player/devices").devices
local active_devices = vim.tbl_filter(function(device) return device.is_active end, devices)
if #active_devices > 0 then
device_id = active_devices[1].id
elseif #devices > 0 then
device_id = devices[1].id
else
vim.notify("no spotify devices found", vim.log.levels.WARN)
device_id = nil
end
return device_id
end
local function play_produced_by_neputunes_playlist()
local device_id = get_device_id()
if not device_id then
vim.notify("open spotify first!", vim.log.levels.ERROR)
return
end
require("spotify.api").call("/me/player/play?device_id=" .. device_id, "put", {
context_uri = "spotify:playlist:3gC3qkmGsyEMIfgsiynDPP"
})
print("playing \"Produced by: The Neptunes\"")
end
return {
"mmuldo/spotify.nvim",
dependencies = {
"nvim-lua/plenary.nvim"
},
config = function()
require("spotify").setup({
client_id = "CLIENT_ID",
client_secret = "CLIENT_SECRET"
})
vim.keymap.set("n", "<leader>mpn", play_produced_by_neputunes_playlist)
vim.keymap.set("n", "<leader>mc", require("spotify.api").currently_playing)
vim.keymap.set("n", "<leader>ml", require("spotify.api").like_current_track)
end
}
:h spotify.nvim