Skip to content

Add global shortcut to paste the 2nd most recent history item - #716

Open
nj-io wants to merge 1 commit into
Clipy:developfrom
nj-io:feat/paste-nth-history-item
Open

Add global shortcut to paste the 2nd most recent history item#716
nj-io wants to merge 1 commit into
Clipy:developfrom
nj-io:feat/paste-nth-history-item

Conversation

@nj-io

@nj-io nj-io commented Sep 7, 2026

Copy link
Copy Markdown

Summary

Adds a global shortcut that pastes the 2nd most recent history item directly, without opening the menu. It appears as a new "Paste 2nd Item" recorder in the Shortcuts preference pane, alongside Clear History. Unset by default, so nothing is registered until a combo is recorded.

Motivation: the common multi-clip workflow is "copy A, copy B, paste B, paste A". Today that needs the History hotkey plus a digit, with numeric key equivalents enabled. This makes it one keystroke. Related discussion in #295, where a commenter noted that most of the time the item they want is the 2nd one.

Behaviour

  • Ordering matches the history menu: newest first, by createdAt or updateAt depending on "Reorder clips after pasting".
  • Pasting re-records the item as the newest entry, so repeated presses alternate between the two most recent clips.
  • Beeps if there is no 2nd item.
  • The plain-text and delete modifier actions are not applied on this path, since the hotkey's own modifiers are still held when it fires and would collide.

Known limitation

Pressing the shortcut twice within about 500ms pastes the same item twice instead of alternating. ClipService polls NSPasteboard.changeCount on a 500ms timer, so the history order has not been updated yet when the second press reads it. Making the reorder synchronous, or tracking a cursor in memory, would fix it. Both felt out of scope here, and I am happy to follow up if you have a preference on the approach.

Implementation

  • PasteService.pasteHistoryItem(at:) is index-based, so further positions can be added without new plumbing.
  • HotKeyService registration is extracted into a shared register(identifier:keyCombo:handler:) helper, now that Clear History and this shortcut have the same shape.
  • New AppStorageKeys.pasteSecondHistoryItemKeyCombo, defaulting to nil.
  • Firebase event paste_second_history_item, logged only when a paste actually happens.
  • Xib: the Shortcuts pane grows by one row and existing rows shift up.
  • Tests added to HotKeyServiceTests and AppStorageValuesTests.

Localised .strings for the new label are not included, so it falls back to the Base English until translators pick it up.

Testing

  • CI green: build plus the full test suite.
  • Verified by hand on macOS 26.2 with a local debug build. The new row records a combo, the shortcut pastes the 2nd item, and repeated presses alternate as described.

Adds a "Paste 2nd Item" recorder to the Shortcuts preference pane. The
hotkey pastes the second entry of the history list directly, without
opening the menu. Ordering follows the history menu, so it respects the
"reorder clips after pasting" setting.

PasteService gains pasteHistoryItem(at:), which is index-based so
further positions can be wired up later. Modifier actions (plain text,
delete) are skipped on this path because the hotkey's own modifiers are
still held when it fires.

HotKeyService registration is extracted into a shared helper now that a
second non-menu hotkey uses the same shape.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant