1
0
mirror of https://github.com/jiriks74/presence.nvim synced 2024-11-23 20:37:50 +01:00

Support Discord Rich Presence on Windows

This commit is contained in:
Andrew Kwon 2021-03-28 11:23:39 -07:00
parent c61fd0f7ae
commit 1f1f2f3253
2 changed files with 57 additions and 27 deletions

@ -20,10 +20,10 @@ local struct = require("deps.struct")
-- Initialize a new Discord RPC client -- Initialize a new Discord RPC client
function Discord:init(options) function Discord:init(options)
self.log = options.logger self.log = options.logger
self.ipc_path = options.ipc_path
self.client_id = options.client_id self.client_id = options.client_id
self.ipc_socket = options.ipc_socket
self.pipe = vim.loop.new_pipe(true) self.pipe = vim.loop.new_pipe(false)
return self return self
end end
@ -33,10 +33,10 @@ end
-- https://github.com/discord/discord-rpc/blob/master/documentation/hard-mode.md#notes -- https://github.com/discord/discord-rpc/blob/master/documentation/hard-mode.md#notes
function Discord:connect(on_connect) function Discord:connect(on_connect)
if self.pipe:is_closing() then if self.pipe:is_closing() then
self.pipe = vim.loop.new_pipe(true) self.pipe = vim.loop.new_pipe(false)
end end
self.pipe:connect(self.ipc_path.."/discord-ipc-0", on_connect) self.pipe:connect(self.ipc_socket, on_connect)
end end
function Discord:is_connected() function Discord:is_connected()
@ -142,7 +142,7 @@ function Discord:set_activity(activity, on_response)
nonce = self.generate_uuid(), nonce = self.generate_uuid(),
args = { args = {
activity = activity, activity = activity,
pid = vim.loop:getpid(), pid = vim.loop:os_getpid(),
}, },
} }

@ -58,6 +58,14 @@ Presence.socket = vim.v.servername
Presence.workspace = nil Presence.workspace = nil
Presence.workspaces = {} Presence.workspaces = {}
-- Get the operating system name (eh should be good enough)
-- http://www.lua.org/manual/5.3/manual.html#pdf-package.config
local separator = package.config:sub(1,1)
Presence.os = {
name = separator == [[\]] and "windows" or "unix",
path_separator = separator,
}
local log = require("lib.log") local log = require("lib.log")
local msgpack = require("deps.msgpack") local msgpack = require("deps.msgpack")
local serpent = require("deps.serpent") local serpent = require("deps.serpent")
@ -90,7 +98,7 @@ function Presence:setup(options)
self.discord = Discord:init({ self.discord = Discord:init({
logger = self.log, logger = self.log,
client_id = options.client_id, client_id = options.client_id,
ipc_path = self.get_ipc_path(), ipc_socket = self:get_discord_socket(),
}) })
-- Seed instance id using unique socket address -- Seed instance id using unique socket address
@ -167,16 +175,16 @@ function Presence:cancel()
end end
-- Call a command on a remote Neovim instance at the provided IPC path -- Call a command on a remote Neovim instance at the provided IPC path
function Presence:call_remote_nvim_instance(ipc_path, command) function Presence:call_remote_nvim_instance(socket, command)
local remote_nvim_instance = vim.loop.new_pipe(true) local remote_nvim_instance = vim.loop.new_pipe(true)
remote_nvim_instance:connect(ipc_path, function() remote_nvim_instance:connect(socket, function()
self.log:debug(string.format("Connected to remote nvim instance at %s", ipc_path)) self.log:debug(string.format("Connected to remote nvim instance at %s", socket))
local packed = msgpack.pack({ 0, 0, "nvim_command", { command } }) local packed = msgpack.pack({ 0, 0, "nvim_command", { command } })
remote_nvim_instance:write(packed, function() remote_nvim_instance:write(packed, function()
self.log:debug(string.format("Wrote to remote nvim instance: %s", ipc_path)) self.log:debug(string.format("Wrote to remote nvim instance: %s", socket))
end) end)
end) end)
end end
@ -247,7 +255,13 @@ function Presence:authorize(on_done)
end end
-- Find the the IPC path in temp runtime directories -- Find the the IPC path in temp runtime directories
function Presence.get_ipc_path() function Presence:get_discord_socket()
local sock_name = "discord-ipc-0"
if self.os.name == "windows" then
return [[\\.\pipe\]]..sock_name
end
local env_vars = { local env_vars = {
"TEMP", "TEMP",
"TMP", "TMP",
@ -259,7 +273,7 @@ function Presence.get_ipc_path()
local var = env_vars[i] local var = env_vars[i]
local path = vim.loop.os_getenv(var) local path = vim.loop.os_getenv(var)
if path then if path then
return path return path..sock_name
end end
end end
@ -292,17 +306,22 @@ function Presence:get_project_name(file_path)
return nil return nil
end end
return self.get_filename(project_path), project_path -- Since git always uses forward slashes, replace with backslash in Windows
if self.os.name == "windows" then
project_path = project_path:gsub("/", [[\]])
end
return self.get_filename(project_path, self.os.path_separator), project_path
end end
-- Get the name of the parent directory for the given path -- Get the name of the parent directory for the given path
function Presence.get_dir_path(path) function Presence.get_dir_path(path, path_separator)
return path:match("^(.+/.+)/.*$") return path:match(string.format("^(.+%s.+)%s.*$", path_separator, path_separator))
end end
-- Get the name of the file for the given path -- Get the name of the file for the given path
function Presence.get_filename(path) function Presence.get_filename(path, path_separator)
return path:match("^.+/(.+)$") return path:match(string.format("^.+%s(.+)$", path_separator))
end end
-- Get the file extension for the given filename -- Get the file extension for the given filename
@ -312,21 +331,31 @@ end
-- Get all active local nvim unix domain socket addresses -- Get all active local nvim unix domain socket addresses
function Presence:get_nvim_socket_addrs(on_done) function Presence:get_nvim_socket_addrs(on_done)
self.log:debug("Getting nvim socket addresses...")
-- TODO: Find a better way to get paths of remote Neovim sockets lol -- TODO: Find a better way to get paths of remote Neovim sockets lol
local cmd = table.concat({ local commands = {
unix = table.concat({
"netstat -u", "netstat -u",
[[grep --color=never "nvim.*/0"]], [[grep --color=never "nvim.*/0"]],
[[awk -F "[ :]+" '{print $9}']], [[awk -F "[ :]+" '{print $9}']],
"sort", "sort",
"uniq", "uniq",
}, "|") }, "|"),
windows = {
"powershell.exe",
"-Command",
[[(Get-ChildItem \\.\pipe\).FullName | findstr 'nvim']],
},
}
local cmd = commands[self.os.name]
local sockets = {} local sockets = {}
local function handle_data(_, data) local function handle_data(_, data)
if not data then return end if not data then return end
for i = 1, #data do for i = 1, #data do
local socket = data[i] local socket = vim.trim(data[i])
if socket ~= "" and socket ~= self.socket then if socket ~= "" and socket ~= self.socket then
table.insert(sockets, socket) table.insert(sockets, socket)
end end
@ -342,6 +371,7 @@ function Presence:get_nvim_socket_addrs(on_done)
end end
local function handle_exit() local function handle_exit()
self.log:debug(string.format("Got nvim socket addresses: %s", vim.inspect(sockets)))
on_done(sockets) on_done(sockets)
end end
@ -388,9 +418,9 @@ function Presence:update_for_buffer(buffer, should_debounce)
self.log:debug(string.format("Setting activity for %s...", buffer)) self.log:debug(string.format("Setting activity for %s...", buffer))
-- Parse vim buffer -- Parse vim buffer
local filename = self.get_filename(buffer) local filename = self.get_filename(buffer, self.os.path_separator)
local parent_dirpath = self.get_dir_path(buffer, self.os.path_separator)
local extension = self.get_file_extension(filename) local extension = self.get_file_extension(filename)
local parent_dirpath = self.get_dir_path(buffer)
-- Determine image text and asset key -- Determine image text and asset key
local name = filename local name = filename