mirror of
https://github.com/jiriks74/presence.nvim
synced 2024-11-23 20:37:50 +01:00
Have snappier multi-window updates via focus events
- Fix multi-window presence - Update on FocusGained events - Add BufAdd handler and properly cancel on WinLeave
This commit is contained in:
parent
9c761d486b
commit
12d177985b
@ -3,9 +3,12 @@ function presence#SetAutoCmds()
|
|||||||
augroup presence_events
|
augroup presence_events
|
||||||
autocmd!
|
autocmd!
|
||||||
if exists("g:presence_auto_update") && g:presence_auto_update
|
if exists("g:presence_auto_update") && g:presence_auto_update
|
||||||
autocmd BufEnter * lua package.loaded.presence:update()
|
autocmd FocusGained * lua package.loaded.presence:handle_focus_gained()
|
||||||
autocmd TextChanged * lua package.loaded.presence:update(nil, true)
|
autocmd TextChanged * lua package.loaded.presence:handle_text_changed()
|
||||||
autocmd VimLeavePre * lua package.loaded.presence:unregister_self()
|
autocmd VimLeavePre * lua package.loaded.presence:handle_vim_leave_pre()
|
||||||
|
autocmd WinEnter * lua package.loaded.presence:handle_win_enter()
|
||||||
|
autocmd WinLeave * lua package.loaded.presence:handle_win_leave()
|
||||||
|
autocmd BufAdd * lua package.loaded.presence:handle_buf_add()
|
||||||
endif
|
endif
|
||||||
augroup END
|
augroup END
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -4,4 +4,5 @@ return {
|
|||||||
["NERD_tree_"] = "NERDTree",
|
["NERD_tree_"] = "NERDTree",
|
||||||
["[defx] default-"] = "Defx",
|
["[defx] default-"] = "Defx",
|
||||||
["netrw"] = "Netrw",
|
["netrw"] = "Netrw",
|
||||||
|
["TelescopePrompt"] = "Telescope"
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,7 @@ function Presence:setup(options)
|
|||||||
local seed_nums = {}
|
local seed_nums = {}
|
||||||
self.socket:gsub(".", function(c) table.insert(seed_nums, c:byte()) end)
|
self.socket:gsub(".", function(c) table.insert(seed_nums, c:byte()) end)
|
||||||
self.id = self.discord.generate_uuid(tonumber(table.concat(seed_nums)) / os.clock())
|
self.id = self.discord.generate_uuid(tonumber(table.concat(seed_nums)) / os.clock())
|
||||||
|
self.log:debug(string.format("Using id %s", self.id))
|
||||||
|
|
||||||
-- Ensure auto-update config is reflected in its global var setting
|
-- Ensure auto-update config is reflected in its global var setting
|
||||||
vim.api.nvim_set_var("presence_auto_update", options.auto_update)
|
vim.api.nvim_set_var("presence_auto_update", options.auto_update)
|
||||||
@ -138,16 +139,23 @@ function Presence:setup(options)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- To ensure consistent option values, coalesce true and false values to 1 and 0
|
||||||
|
function Presence.coalesce_option(value)
|
||||||
|
if type(value) == "boolean" then
|
||||||
|
return value and 1 or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
-- Set option using either vim global or setup table
|
-- Set option using either vim global or setup table
|
||||||
function Presence:set_option(option, default, validate)
|
function Presence:set_option(option, default, validate)
|
||||||
|
default = self.coalesce_option(default)
|
||||||
validate = validate == nil and true or validate
|
validate = validate == nil and true or validate
|
||||||
|
|
||||||
local g_variable = string.format("presence_%s", option)
|
local g_variable = string.format("presence_%s", option)
|
||||||
|
|
||||||
-- Coalesce boolean options to integer 0 or 1
|
self.options[option] = self.coalesce_option(self.options[option])
|
||||||
if type(self.options[option]) == "boolean" then
|
|
||||||
self.options[option] = self.options[option] and 1 or 0
|
|
||||||
end
|
|
||||||
|
|
||||||
if validate then
|
if validate then
|
||||||
-- Warn on any duplicate user-defined options
|
-- Warn on any duplicate user-defined options
|
||||||
@ -297,17 +305,17 @@ function Presence:get_discord_socket()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Gets the file path of the current vim buffer
|
-- Gets the file path of the current vim buffer
|
||||||
function Presence.get_current_buffer(on_buffer)
|
function Presence.get_current_buffer()
|
||||||
vim.schedule(function()
|
local current_buffer = vim.api.nvim_get_current_buf()
|
||||||
local current_buffer = vim.api.nvim_get_current_buf()
|
return vim.api.nvim_buf_get_name(current_buffer)
|
||||||
local buffer = vim.api.nvim_buf_get_name(current_buffer)
|
|
||||||
|
|
||||||
on_buffer(buffer)
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Gets the current project name
|
-- Gets the current project name
|
||||||
function Presence:get_project_name(file_path)
|
function Presence:get_project_name(file_path)
|
||||||
|
if not file_path then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
-- Escape quotes in the file path
|
-- Escape quotes in the file path
|
||||||
file_path = file_path:gsub([["]], [[\"]])
|
file_path = file_path:gsub([["]], [[\"]])
|
||||||
|
|
||||||
@ -356,24 +364,26 @@ end
|
|||||||
|
|
||||||
-- Get the status text for the current buffer
|
-- Get the status text for the current buffer
|
||||||
function Presence:get_status_text(filename)
|
function Presence:get_status_text(filename)
|
||||||
|
local file_explorer = file_explorers[vim.bo.filetype:match "[^%d]+"]
|
||||||
|
or file_explorers[(filename or ""):match "[^%d]+"]
|
||||||
|
local plugin_manager = plugin_managers[vim.bo.filetype]
|
||||||
|
|
||||||
|
if file_explorer then
|
||||||
|
return string.format(self.options.file_explorer_text, file_explorer)
|
||||||
|
elseif plugin_manager then
|
||||||
|
return string.format(self.options.plugin_manager_text, plugin_manager)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not filename or filename == "" then return nil end
|
||||||
|
|
||||||
if vim.bo.modifiable and not vim.bo.readonly then
|
if vim.bo.modifiable and not vim.bo.readonly then
|
||||||
if vim.bo.filetype == "gitcommit" then
|
if vim.bo.filetype == "gitcommit" then
|
||||||
return string.format(self.options.git_commit_text, filename)
|
return string.format(self.options.git_commit_text, filename)
|
||||||
else
|
elseif filename then
|
||||||
return string.format(self.options.editing_text, filename)
|
return string.format(self.options.editing_text, filename)
|
||||||
end
|
end
|
||||||
else
|
elseif filename then
|
||||||
local file_explorer = file_explorers[vim.bo.filetype:match "[^%d]+"]
|
return string.format(self.options.reading_text, filename)
|
||||||
or file_explorers[filename:match "[^%d]+"]
|
|
||||||
local plugin_manager = plugin_managers[vim.bo.filetype]
|
|
||||||
|
|
||||||
if file_explorer then
|
|
||||||
return string.format(self.options.file_explorer_text, file_explorer)
|
|
||||||
elseif plugin_manager then
|
|
||||||
return string.format(self.options.plugin_manager_text, plugin_manager)
|
|
||||||
else
|
|
||||||
return string.format(self.options.reading_text, filename)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -461,6 +471,12 @@ end
|
|||||||
|
|
||||||
-- Update Rich Presence for the provided vim buffer
|
-- Update Rich Presence for the provided vim buffer
|
||||||
function Presence:update_for_buffer(buffer, should_debounce)
|
function Presence:update_for_buffer(buffer, should_debounce)
|
||||||
|
-- Avoid unnecessary updates if the previous activity was for the current buffer
|
||||||
|
-- (allow same-buffer updates when line numbers are enabled)
|
||||||
|
if self.options.enable_line_number == 0 and self.last_activity.file == buffer then
|
||||||
|
self.log:debug(string.format("Activity already set for %s, skipping...", buffer))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local activity_set_at = os.time()
|
local activity_set_at = os.time()
|
||||||
-- If we shouldn't debounce and we trigger an activity, keep this value the same.
|
-- If we shouldn't debounce and we trigger an activity, keep this value the same.
|
||||||
@ -472,7 +488,7 @@ function Presence:update_for_buffer(buffer, should_debounce)
|
|||||||
-- Parse vim buffer
|
-- Parse vim buffer
|
||||||
local filename = self.get_filename(buffer, self.os.path_separator)
|
local filename = self.get_filename(buffer, self.os.path_separator)
|
||||||
local parent_dirpath = self.get_dir_path(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 = filename and self.get_file_extension(filename) or nil
|
||||||
|
|
||||||
self.log:debug(string.format("Parsed filename %s with %s extension", filename, extension or "no"))
|
self.log:debug(string.format("Parsed filename %s with %s extension", filename, extension or "no"))
|
||||||
|
|
||||||
@ -498,6 +514,9 @@ function Presence:update_for_buffer(buffer, should_debounce)
|
|||||||
}
|
}
|
||||||
|
|
||||||
local status_text = self:get_status_text(filename)
|
local status_text = self:get_status_text(filename)
|
||||||
|
if not status_text then
|
||||||
|
return self.log:debug("No status text for the given buffer, skipping...")
|
||||||
|
end
|
||||||
|
|
||||||
local activity = {
|
local activity = {
|
||||||
state = status_text,
|
state = status_text,
|
||||||
@ -521,6 +540,7 @@ function Presence:update_for_buffer(buffer, should_debounce)
|
|||||||
|
|
||||||
self.workspace = nil
|
self.workspace = nil
|
||||||
self.last_activity = {
|
self.last_activity = {
|
||||||
|
id = self.id,
|
||||||
file = buffer,
|
file = buffer,
|
||||||
set_at = activity_set_at,
|
set_at = activity_set_at,
|
||||||
relative_set_at = relative_activity_set_at,
|
relative_set_at = relative_activity_set_at,
|
||||||
@ -544,6 +564,7 @@ function Presence:update_for_buffer(buffer, should_debounce)
|
|||||||
|
|
||||||
self.workspace = project_path
|
self.workspace = project_path
|
||||||
self.last_activity = {
|
self.last_activity = {
|
||||||
|
id = self.id,
|
||||||
file = buffer,
|
file = buffer,
|
||||||
set_at = activity_set_at,
|
set_at = activity_set_at,
|
||||||
relative_set_at = relative_activity_set_at,
|
relative_set_at = relative_activity_set_at,
|
||||||
@ -567,6 +588,7 @@ function Presence:update_for_buffer(buffer, should_debounce)
|
|||||||
|
|
||||||
self.workspace = nil
|
self.workspace = nil
|
||||||
self.last_activity = {
|
self.last_activity = {
|
||||||
|
id = self.id,
|
||||||
file = buffer,
|
file = buffer,
|
||||||
set_at = activity_set_at,
|
set_at = activity_set_at,
|
||||||
relative_set_at = relative_activity_set_at,
|
relative_set_at = relative_activity_set_at,
|
||||||
@ -588,8 +610,10 @@ function Presence:update_for_buffer(buffer, should_debounce)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Sync activity to all peers
|
-- Sync activity to all peers
|
||||||
|
self.log:debug("Sync activity to all peers...")
|
||||||
self:sync_self_activity()
|
self:sync_self_activity()
|
||||||
|
|
||||||
|
self.log:debug("Setting Discord activity...")
|
||||||
self.discord:set_activity(activity, function(err)
|
self.discord:set_activity(activity, function(err)
|
||||||
if err then
|
if err then
|
||||||
self.log:error("Failed to set activity in Discord: "..err)
|
self.log:error("Failed to set activity in Discord: "..err)
|
||||||
@ -623,16 +647,16 @@ Presence.update = Presence.discord_event(function(self, buffer, should_debounce)
|
|||||||
if buffer then
|
if buffer then
|
||||||
self:update_for_buffer(buffer, should_debounce)
|
self:update_for_buffer(buffer, should_debounce)
|
||||||
else
|
else
|
||||||
self.get_current_buffer(function(current_buffer)
|
vim.schedule(function()
|
||||||
if not current_buffer or current_buffer == "" then
|
self:update_for_buffer(self.get_current_buffer(), should_debounce)
|
||||||
return self.log:debug("Current buffer not named, skipping...")
|
|
||||||
end
|
|
||||||
|
|
||||||
self:update_for_buffer(current_buffer, should_debounce)
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
--------------------------------------------------
|
||||||
|
-- Presence peer-to-peer API
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
-- Register some remote peer
|
-- Register some remote peer
|
||||||
function Presence:register_peer(id, socket)
|
function Presence:register_peer(id, socket)
|
||||||
self.log:debug(string.format("Registering peer %s...", id))
|
self.log:debug(string.format("Registering peer %s...", id))
|
||||||
@ -813,4 +837,84 @@ function Presence:stop()
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------
|
||||||
|
-- Presence event handlers
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
-- FocusGained events force-update the presence for the current buffer unless it's a quickfix window
|
||||||
|
function Presence:handle_focus_gained()
|
||||||
|
self.log:debug("Handling FocusGained event...")
|
||||||
|
|
||||||
|
if vim.bo.filetype == "qf" then
|
||||||
|
self.log:debug("Skipping presence update for quickfix window...")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self:update()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TextChanged events debounce current buffer presence updates
|
||||||
|
function Presence:handle_text_changed()
|
||||||
|
self.log:debug("Handling TextChanged event...")
|
||||||
|
self:update(nil, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- VimLeavePre events unregister the leaving instance to all peers and sets activity for the first peer
|
||||||
|
function Presence:handle_vim_leave_pre()
|
||||||
|
self.log:debug("Handling VimLeavePre event...")
|
||||||
|
self:unregister_self()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- WinEnter events force-update the current buffer presence unless it's a quickfix window
|
||||||
|
function Presence:handle_win_enter()
|
||||||
|
self.log:debug("Handling WinEnter event...")
|
||||||
|
|
||||||
|
vim.schedule(function()
|
||||||
|
if vim.bo.filetype == "qf" then
|
||||||
|
self.log:debug("Skipping presence update for quickfix window...")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self:update()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- WinLeave events cancel the current buffer presence
|
||||||
|
function Presence:handle_win_leave()
|
||||||
|
self.log:debug("Handling WinLeave event...")
|
||||||
|
|
||||||
|
local current_window = vim.api.nvim_get_current_win()
|
||||||
|
|
||||||
|
vim.schedule(function()
|
||||||
|
-- Avoid canceling presence when switching to a quickfix window
|
||||||
|
if vim.bo.filetype == "qf" then
|
||||||
|
self.log:debug("Not canceling presence due to switching to quickfix window...")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Avoid canceling presence when switching between windows
|
||||||
|
if current_window ~= vim.api.nvim_get_current_win() then
|
||||||
|
self.log:debug("Not canceling presence due to switching to a window within the same instance...")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.log:debug("Canceling presence due to leaving window...")
|
||||||
|
self:cancel()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- WinLeave events cancel the current buffer presence
|
||||||
|
function Presence:handle_buf_add()
|
||||||
|
self.log:debug("Handling BufAdd event...")
|
||||||
|
|
||||||
|
vim.schedule(function()
|
||||||
|
if vim.bo.filetype == "qf" then
|
||||||
|
self.log:debug("Skipping presence update for quickfix window...")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self:update()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
return Presence
|
return Presence
|
||||||
|
Loading…
x
Reference in New Issue
Block a user