Documentation

Clipboard

Automatic clipboard history (text, images, files) with OCR and deduplication.

Copy anything, anywhere. It appears in the Stream by the time you open Gisti.

What gets captured

  • Text: plain and formatted, with the source app recorded. Copied URLs are captured as plain text like anything else; there’s no separate link type. See Formatting is kept below.
  • Images: copied images and screenshots; OCR runs automatically, so image text is searchable.
  • Spreadsheet ranges: a range of cells copied from Numbers, Excel or Google Sheets is saved as the delimited text that comes with it, and formatted views show it as a table. Numbers is the awkward one – it advertises an image for the range and then writes no bytes for it, so the text sitting beside that promise is what there is to keep.
  • Files: copy one or more files or folders in Finder; their path(s) are saved as a clip, titled with the filename (or a count like “2 folders, 3 files” for multiple). Copying that clip again puts the files back on the clipboard, so pasting into Finder or an upload field gives you the files – not their paths as text. If a file has moved or been deleted since, the clip is copied as text instead.

How it behaves

  • The clipboard is polled 5 times a second (interval configurable in advanced.yaml).

  • Deduplication by content hash: copying the same thing twice moves one element up instead of creating a second one. The hash is taken after case and surrounding whitespace are set aside, so TODO, todo and the same word with a stray space or line break around it are all one element – and the element keeps the text of the copy that created it, so the row still reads TODO after you copy todo. The row keeps a count of how often that has happened – shown as ×4 next to the time, and counting copies you make from Gisti too, so it answers “what do I actually reuse”. Every route that hands a record over whole counts: a multi-selection, a topic card, Open in source app, dragging a row into another app, and C inside a record’s card when nothing is selected. A drag counts when the other app actually takes it, so one let go over the desktop counts nothing. A selection, the OCR text, a crop or a decoded view is something made from the record and doesn’t – which is also why a picture in a mixed multi-selection copied with C doesn’t count (what it contributes there is its OCR text); dragged, the same selection goes out as files, picture included, and every record counts. Holding C down counts once, not once per key repeat, and the badge stops growing at ×99+ so it can’t push the time out of the row – hover it for the real number. Content arriving by a route that never touches the clipboard – a gisti://capture, the Share extension, the browser extension – starts its count at zero and moves the row up without counting: nothing was copied.

    The number is pasteboard trips and nothing else, so it can be read literally. A clip that arrived by being copied in another app starts at ×1, which is why the badge only appears from the second trip on. Notes and chats are written or held here rather than copied in, so they start at zero and every count on them is one you made – ×4 on a saved snippet is four copies. A screenshot starts at ×1 because taking it puts the picture on the clipboard as well.

  • Invisible whitespace is flagged: a clip – or a note – that starts or ends with a space or a newline gets a small marker. It costs nothing to ignore and saves the paste that breaks a terminal command or a search field. Notes get it because most of them are somebody else’s text kept as a note; one typed into the panel is trimmed as it is saved and never carries the marker. Turn it off with ui.showWhitespaceMarker in advanced.yaml.

  • Colors show a swatch: a clip that is a color, or a palette of them, is drawn in the row instead of being another indistinguishable #3A7BD5. The same goes for a note that is nothing but colors – a palette kept as a note is still a palette. See Formatted views.

  • History limit: set the maximum number of clips in Settings → Clipboard; the oldest fall off quietly. Favorites survive cleanup. Copied images count against the separate images limit (Settings → Screenshots → Max images), not the clipboard one.

  • Source app is stored with every clip, and you can open the app it came from ( O).

  • Pause any time: the Monitoring toggle in Settings → Clipboard (also in the menu-bar menu) stops capture without quitting Gisti. Everything already saved stays; nothing new is recorded until you switch it back on.

Formatting is kept

Copy a formatted paragraph out of a document and paste it back from Gisti: it arrives with its formatting. The clip carries both representations, so a document takes the formatted one and a terminal or code editor takes the plain text – the same way the original copy behaved. Open in source app puts it on the clipboard the same way, since that is C plus an app launch.

  • Copy without formatting: C, in the list and inside an open card alike, or the entry in the actions menu ( K). Both only do something on clips that actually carry formatting.
  • Editing a clip drops its formatting. The stored version describes the text as it was; keeping it after an edit would paste something other than what you see.
  • RTF is preferred to HTML when a copy carries both. The two describe the same paragraph, but RTF does it in a fraction of the bytes, and it is the representation a document editor takes most cleanly.
  • Large ones are stored as plain text. RTF for a paragraph is a small multiple of its text, but the HTML a browser puts on the clipboard for the same paragraph – Google Docs, Notion – routinely runs to hundreds of kilobytes. Above clipboard.maxRichTextBytes (128 KB by default, in advanced.yaml) the clip keeps its text and loses its formatting. Set it to 0 to never store formatting at all.

Search, semantic search and formatted views all work on the plain text, so none of this changes what you can find.

Passwords are skipped automatically

You don’t have to configure anything for this. Password managers mark a copied secret on the pasteboard with the cross-app nspasteboard.org types – Concealed for a password, Transient for something meant to live for a moment, AutoGenerated for content produced by a clipboard utility rather than by you. Gisti checks for those markers before reading anything and skips the copy entirely: it never reaches the history, the previews, or the semantic index.

That covers 1Password, Bitwarden, KeePassXC, Apple Passwords and everything else that follows the convention. Managers that use a private marker of their own instead are covered by the type list in advanced.yaml – 1Password’s legacy type, KeeWeb and a few clipping tools are listed there out of the box, and you can add any other.

Ignore rules

Three independent ways to keep something out of the history. All of them skip the copy entirely – nothing is stored, not even briefly.

By app

Settings → Clipboard → Clipboard apps takes a list of apps. The picker lists every app installed on your Mac, not just ones that have already copied something.

The row shows which way the list is pointing – Ignore · 3 apps or Only these · 3 apps – and the switch at the top of the list is what flips it:

  • Ignore – record everything except copies from the listed apps.
  • Only these – record nothing but copies from the listed apps. Useful if you only want clips from your editor and terminal. Two things to know: an empty list in this mode records nothing at all, and copies whose source app can’t be determined are skipped too.

It is the same list in both modes – flipping the switch changes what the list means, never what is in it, so you can go back and forth without collecting the apps again.

By pasteboard type

clipboard.ignorePasteboardTypes in advanced.yaml. Apps that mark their copies with a private type can be excluded by that type, which is more reliable than by app name.

By content

clipboard.ignoreRegexps in advanced.yaml – regular expressions matched against the copied text (and against the paths of copied files). Anything that matches is never recorded. This is the one to use for secrets that no app marks for you: a key pasted out of a .env, a token in a terminal, an API key in a config file.

clipboard:
  ignoreRegexps:
    - "sk-[A-Za-z0-9]{20,}"
    - "ghp_[A-Za-z0-9]{36}"
    - "-----BEGIN [A-Z ]*PRIVATE KEY-----"

The rules follow the text rather than the pasteboard. A picked color, the text-only capture (T on the capture overlay) and the text Gisti reads inside a picture – one copied from another app, or a screenshot you took – are held to the same list. A picture whose recognized text matches is removed whole, not just stripped of its text: the picture is the readable form of the thing the rule is about. Recognition finishes a moment after the record appears, so such a row can show up briefly before it goes.

The system clipboard is left alone in every case – you asked for the copy, and these rules speak for the history.

Only the first 256 KB of a copy are scanned. An invalid pattern is skipped and the rest keep working.

Clearing

Clear History (Settings → Storage) clears whichever kinds you tick – notes, clipboard, images, chats – and has an Also clear the system clipboard checkbox. Without it the last thing you copied survives the clear: the history is empty, but V in any app still produces it.

Deleting a single clip that is currently on the system clipboard clears it there too – the toast says so when that happens.

Esc

Type to search every page of the manual.