Jump to content

ClipSaver - save & convert images from clipboard history in various formats

Recommended Posts

Latest release: v2.3.5


Hey guys,


Thought I'd share this little workflow. I found myself often needing to dump out the last N clipboard images from Alfred's history to disk. It was tedious before, find the right item, copy it back to the pasteboard, paste into Preview, save as PNG, give it a non-overlapping name, etc. So I created this to make it semi-automatic. Shouldn't need anything special, but please let me know if you run into any trouble.


Feedback welcome! One thing for sure I would like some advice on is whether the Script Filter (Python) could be turned back into a List Comprehension which from what I've read is more efficient. I couldn't figure out how to do that and also dynamically update the database rows (e.g. converting "/" to " / " so that Alfred's word matching would match correctly, picking a nicer generic icon when app name==null etc). @deanishe if you have time I'm sure you know the answer to this... :) 








Download Latest Release:




Edited by luckman212
Link to comment

Just to clarify what I was asking about above with the List Comprehensions, I'm talking about this.


Populating the list using List Comprehension

items = []
with database(dbpath) as db:
    rows = db.execute("SELECT foo...)
    items = [{ "title": r[1],
               "arg": r[0]
             } for r in rows ]

Populating the list using a loop and append (this is the current method used)

items = []
with database(db_path) as db:
    rows = db.execute("SELECT bar...)
    for r in rows:
      if r[2] == None:
        (...do stuff...)
        (...do other stuff...)
      items.append({ "title": r[1],
                     "arg": r[0]

My question is, is there a way to use the List Comprehension method while still allowing for the if/then/else code to execute?

Link to comment
2 hours ago, luckman212 said:

My question is, is there a way to use the List Comprehension method while still allowing for the if/then/else code to execute?


Not in this case, no. But forget about it. The difference in performance is absolutely miniscule and list comprehensions should be used sparingly. Readable code is more important that the tiny bit of speed you get from replacing a loop with a list comprehension.


2 hours ago, luckman212 said:

if r[2] == None:


if r[2] is None: is the more idiomatic way to test for None.

Link to comment
  • luckman212 changed the title to ClipSaver v2.0.0 - save image(s) from clipboard history to various formats
  • 1 month later...
  • luckman212 changed the title to ClipSaver v2.0.4 - save image(s) from clipboard history to various formats
  • 7 months later...

Ok, let me see if I can help.


1. Can you post a screenshot or copy/paste the output of your Alfred debugger console?


2. Please post a screenshot of the workflow's Environment Variables area.


3. What version of Alfred and macOS are you running?


4. And finally, can you open a Terminal and type "python3 -VV" and paste that output here as well?

Link to comment
  • 2 months later...

Any idea why the list of images returned by this workflow would be different than Alfred's Clipboard History feature? When I take a screenshot to the clipboard, it appears in Alfred's results but not in this workflows results. Not sure what other info to provide to help me troubleshoot.

Link to comment

@luckman212 Thanks for the reply. Yes, it does show results, but only partial results compared to Alfred's Clipboard History feature.


No errors in the debug window, but I looked at the database folder as configured in the workflow, and I found a subfolder "clipboard.alfdb.data" with two types of files: tiff and plist, where each plist is a reference to a file in my screen shots folder. This workflow seems to be showing the tiffs, but not the items referenced in the plists. Alfred's Clipboard History shows both. I hope that explanation makes sense and is helpful!

Edited by evanfuchs
Link to comment

@evanfuchs I may be misunderstanding, sorry if that's the case, but—the purpose of this workflow is to only show/save IMAGES. So it is expected that the workflow's results will be limited to the TIFFs only, and will be different from Alfred's clipboard history which would contain all items: files, text etc. Are you expecting something different?

Link to comment

I am talking about images only. It seems some items in Alfred’s history are not stored directly in that location, but rather as references (plists) to images in another location. Alfred shows all the images (those actually in the folder and those referenced) but this workflow doesn’t seem to see the referenced images. I don’t know enough about Alfred works under the hood to explain further. Just an observation. 

Link to comment

The workflow reads directly from Alfred's SQLite database, so it's very unexpected that the results would be different from what you see in Alfred's native UI. I am not in front of my computer now, but I'll update this post later with some diagnostic commands to run, hopefully that may shed some light on what's going on here.

Link to comment

@evanfuchs Ok let's start with some basics:


Open a Terminal and try entering in the following commands. Please copy & paste the results to a pastebin.



cd "$HOME/Library/Application Support/Alfred/Databases"

ls -l clipboard.alfdb.data

sqlite3 -header clipboard.alfdb 'SELECT * FROM clipboard WHERE dataType == 1'



Finally, open Alfred and select the Workflows tab, then open the Debugger console (⌘D) and trigger ClipSaver. Copy and paste the JSON output to a separate pastebin.

Edited by luckman212
Link to comment
On 2/26/2023 at 12:26 AM, luckman212 said:

@oorbx What does your Debug console output look like in Alfred? Please post it- same steps that I was looking to see from Evan Fuchs above


Hey there, sorry i dont know how to work and share pastebin. I paste there, but i dont know whats next.


Thats why i paste to here:


Last login: Sun Feb 26 09:11:38 on ttys000
xxx@MacBook-xPro ~ % cd "$HOME/Library/Application Support/Alfred/Databases"

xxx@MacBook-xPro Databases % ls -l clipboard.alfdb.data
total 24
-rw-r--r--@ 1 xxx  staff  335 26 feb 09:11 23cb2faaa08dc4b7aa34cbac2d28d4ba425b0709.plist
-rw-r--r--@ 1 xxx  staff  245 25 feb 21:47 2890925619460226d9da225abed2e2bae052c769.plist
-rw-r--r--@ 1 xxx  staff  244 25 feb 22:07 348bfa64dacc725130316704bc58ace684e4c291.plist
xxx@MacBook-xPro Databases % sqlite3 -header clipboard.alfdb 'SELECT * FROM
clipboard WHERE dataType == 1'
xxx@MacBook-xPro Databases %



[09:15:51.908] Logging Started...
[09:16:18.154] ClipSaver[Script Filter] Queuing argument '(null)'
[09:16:18.190] ClipSaver[Script Filter] Script with argv '(null)' finished
[09:16:18.196] ClipSaver[Script Filter] {"variables": {"uidSeed": "1677399378.185623"}, "skipknowledge": true, "items": [{"title": "No image clips found", "subtitle": "clipboard history may be empty", "icon": {"path": "error.png"}, "valid": false}]}



Edited by oorbx
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...