hluk / copyq-commands

Useful commands for CopyQ clipboard manager.
328 stars 72 forks source link

how to know if my current copied clip exist in my old clips?? #67

Closed firefoxOnFire closed 1 year ago

firefoxOnFire commented 1 year ago

I am getting current clip using var clip = str(clipboard()) and working on that. But in long run I come across same clip which is flooding my work with duplicates.

So is there any method to know that my current clip exist in my old clips?? Thanks.

marlarius commented 1 year ago

Something along this. It will check if the topmost (last copied) item already exists in the current tab.

copyq:
const n = count()
const data = []
const myitem = str(read(0))
for(let i=1; i<n; i++) {
  const item = str(read(i))
  data.push(item)
  if(data.includes(myitem)) {
    popup(`The item ${item} exists at position ${i+1}`)
    break
  }
}
firefoxOnFire commented 1 year ago

Something along this. It will check if the topmost (last copied) item already exists in the current tab.

copyq:
const n = count()
const data = []
const myitem = str(read(0))
for(let i=1; i<n; i++) {
  const item = str(read(i))
  data.push(item)
  if(data.includes(myitem)) {
    popup(`The item ${item} exists at position ${i+1}`)
    break
  }
}

This will not cause problem in performance? Because it will go over all the clips?? No inbuilt api to know? Or that will do the same under hood?

marlarius commented 1 year ago

I don't know your exact use case but copyq should automatically reject duplicates and instead move it to the top. I posted an issue about this not long ago and it was fixed in a recent version.

https://github.com/hluk/CopyQ/issues/2228#issuecomment-1386739120

However, make sure your have the latest version.

BTW I have 200 items in my history and my script above doesn't seem to cause performance problems.

I have a powerful computer so it might be different for you. Why not just try it?

firefoxOnFire commented 1 year ago

I don't know your exact use case but copyq should automatically reject duplicates and instead move it to the top. I posted an issue about this not long ago and it was fixed in a recent version.

hluk/CopyQ#2228 (comment)

However, make sure your have the latest version.

BTW I have 200 items in my history and my script above doesn't seem to cause performance problems.

I have a powerful computer so it might be different for you. Why not just try it?

Reading the items in batches (less read() calls) would also improve the performance because the above version can be slow with many items.

He literally warns this. And my command is automatic. And having 1000+ clips. So it will cause problem.

Any way to know if the changed clip is moved top instead copying again(because this is how duplicate is being handled by CopyQ ), so i can reject those.???

marlarius commented 1 year ago

As you might know, CopyQ clips are just files in a specific folder. If you delete a file, the clip will disappear immediately.

So another approach would be to make a short script that delete duplicate files in the folder. Even for thousands of files, this would take milliseconds.

Edit: well not milliseconds. A second for about 1500 files. But probably still better than doing it inside copyq.

Edit 2: That was for a simple bash script. I then tried with fdupes: It took 377 msec for 10571 files! So my original estimate turned out to hold.

Edit 3: jdupes are even faster than fdupes. It took 237 msec for the same set of CopyQ files. In quick mode, it took only 150 msec.

And remember that you can call external scripts and commands from CopyQ.

hluk commented 1 year ago

Probably the fastest way to do this is:

copyq:
const clip = str(clipboard());

// https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function escapeRegex(string) {
    return string.replace(/[\-\\^$*+?.()|[\]{}]/g, '\\$&');
}

const re = new RegExp(`^${escapeRegex(clip)}$`);
const sel = new ItemSelection().select(re);
if (sel.length == 0) {
    popup('No items with the current clipboard text');
} else {
    popup('Indexes with the current clipboard text', sel.rows());
}

This always searches all the items but does the matching on server side which should be fast (i.e. item data is never send to the script client process).

firefoxOnFire commented 1 year ago

Probably the fastest way to do this is:

copyq:
const clip = str(clipboard());

// https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function escapeRegex(string) {
    return string.replace(/[\-\\^$*+?.()|[\]{}]/g, '\\$&');
}

const re = new RegExp(`^${escapeRegex(clip)}$`);
const sel = new ItemSelection().select(re);
if (sel.length == 0) {
    popup('No items with the current clipboard text');
} else {
    popup('Indexes with the current clipboard text', sel.rows());
}

This always searches all the items but does the matching on server side which should be fast (i.e. item data is never send to the script client process).

Thanks. This worked.