-
Notifications
You must be signed in to change notification settings - Fork 0
Skip duplicate activity events with same file and cursor #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,13 @@ local pending_heartbeats = {} | |
| -- Last heartbeat time per file (for debouncing) | ||
| local last_heartbeat_time = {} | ||
|
|
||
| -- Last activity state (for duplicate detection) | ||
| local last_activity = { | ||
| file_path = nil, | ||
| line_number = nil, | ||
| cursor_position = nil, | ||
| } | ||
|
|
||
| -- Autocmd group | ||
| local augroup = nil | ||
|
|
||
|
|
@@ -82,6 +89,38 @@ local function should_send_heartbeat(file_path, is_write) | |
| return false | ||
| end | ||
|
|
||
| --- Check if activity is a duplicate (same file and cursor position) | ||
| ---@param file_path string File path | ||
| ---@param line_number number Line number (1-indexed) | ||
| ---@param cursor_position number Cursor column (0-indexed) | ||
| ---@param is_write boolean Whether this is a write event | ||
| ---@return boolean True if duplicate (should skip) | ||
| local function is_duplicate_activity(file_path, line_number, cursor_position, is_write) | ||
| -- Write events are never considered duplicates | ||
| if is_write then | ||
| return false | ||
| end | ||
|
|
||
| -- Check if same as last activity | ||
| if last_activity.file_path == file_path | ||
| and last_activity.line_number == line_number | ||
| and last_activity.cursor_position == cursor_position then | ||
| return true | ||
| end | ||
|
|
||
| return false | ||
| end | ||
|
|
||
| --- Update last activity state | ||
| ---@param file_path string File path | ||
| ---@param line_number number Line number (1-indexed) | ||
| ---@param cursor_position number Cursor column (0-indexed) | ||
| local function update_last_activity(file_path, line_number, cursor_position) | ||
| last_activity.file_path = file_path | ||
| last_activity.line_number = line_number | ||
| last_activity.cursor_position = cursor_position | ||
| end | ||
|
|
||
| --- Create heartbeat data for current buffer | ||
| ---@param bufnr number Buffer number | ||
| ---@param is_write boolean Whether this is a write event | ||
|
|
@@ -147,6 +186,20 @@ local function on_event(is_write) | |
|
|
||
| local file_path = vim.api.nvim_buf_get_name(bufnr) | ||
|
|
||
| -- Get cursor position for duplicate detection | ||
| local cursor = vim.api.nvim_win_get_cursor(0) | ||
| local line_number = cursor[1] | ||
| local cursor_position = cursor[2] | ||
|
|
||
| -- Skip duplicate events (same file and cursor position) | ||
| if is_duplicate_activity(file_path, line_number, cursor_position, is_write) then | ||
| return | ||
| end | ||
|
|
||
| -- Update last activity state immediately after duplicate check | ||
| -- This ensures we track the latest position even if debounce blocks sending | ||
| update_last_activity(file_path, line_number, cursor_position) | ||
|
|
||
| if not should_send_heartbeat(file_path, is_write) then | ||
| return | ||
| end | ||
|
|
@@ -223,6 +276,11 @@ end | |
| --- Clear debounce cache | ||
| function M.clear_cache() | ||
| last_heartbeat_time = {} | ||
| last_activity = { | ||
| file_path = nil, | ||
| line_number = nil, | ||
| cursor_position = nil, | ||
| } | ||
|
Comment on lines
+279
to
+283
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The table structure used to reset |
||
| end | ||
|
|
||
| return M | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -142,6 +142,13 @@ describe('shelltime.heartbeat', function() | |
| heartbeat.clear_cache() | ||
| end) | ||
| end) | ||
|
|
||
| it('should reset last activity state for duplicate detection', function() | ||
| -- clear_cache should reset both debounce and duplicate tracking | ||
| heartbeat.clear_cache() | ||
| -- After clearing, the next event should not be considered duplicate | ||
| assert.equals(0, heartbeat.get_pending_count()) | ||
| end) | ||
|
Comment on lines
+146
to
+151
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test case is intended to verify that A more effective test would:
This would properly confirm that the duplicate detection state was cleared and the functionality works as intended. |
||
| end) | ||
|
|
||
| describe('module exports', function() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditional logic to check for duplicate activity can be simplified. The pattern
if condition then return true end return falseis more verbose than necessary and can be replaced by directly returning the result of the boolean expression. This makes the code more concise and idiomatic.