Closed Qwash closed 7 years ago
It's true that commands are not very user-friendly. When it comes to customizing them you need to change the code (visible only if "Show Advanced" is checked).
Copy/paste following code to command list in Comand dialog. The newly added command replaces text in clipboard.
[Command]
Automatic=true
Command="
copyq:
// Replace this text ...
var replaceWhat = 'http://example.com/'
// .. with this text.
var replaceWith = 'http://test.org/'
var text = str(input())
if ( text.indexOf(replaceWhat) != -1 ) {
var newText = text.replace(replaceWhat, replaceWith)
// Copy replaced text back to clipboard.
copy(newText)
// Change data to save in item list.
setData(mimeText, newText)
removeData(mimeHtml)
// Notify user.
popup(
'Clipboard Replaced',
'Replaced \"' + text + '\" with \"' + newText + '\"')
}"
Icon=\xf0d0
Input=text/plain
Name=Replace Clipboard
Here is bit more complicated but more powerful version which uses regexp to match text content and replace it.
[Command]
Automatic=true
Command="
copyq:
// Replace this regexp ...
var replaceWhat = /^http:\\/\\/example\\.com\\/(.*\\.rar)/
// .. with this text.
var replaceWith = 'http://test.org/$1'
var text = str(input())
if ( text.match(replaceWhat) ) {
var newText = text.replace(replaceWhat, replaceWith)
// Copy replaced text back to clipboard.
copy(newText)
// Change data to save in item list.
setData(mimeText, newText)
removeData(mimeHtml)
// Notify user.
popup(
'Clipboard Replaced',
'Replaced \"' + text + '\" with \"' + newText + '\"')
}"
Icon=\xf0d0
Input=text/plain
Name=Replace Clipboard
[1]: Is it possible to replace many strings in one command using your first example (without using regexp)
something like replace('http://example.com/
' or 'test1' or 'test2') with 'NewString'
[2]: to remove the string I set var replaceWith = '' Is thats the best way to achieve that or there is a better way to remove specific string from the clipboard
ad 1. AFAIK this is not easy in JavaScript without using regexps. You usually replace all occurrences with regex in form /.../g
(g
flag is required).
ad 2. Yes, that's the way to remove sub-strings.
[*] Is its a bad idea to have this command (the first example) repeated 3 or 4 times every command with different vars?
[*]
if ( text.indexOf(replaceWhat) != -1 )
What is the purpose of this line? would I still need it if I set
^https?://
for the command "content"
[*] CQ is using JavaScript for commands or what is this language?
The language is Qt Script -- it's ECMAScript dialect, very similar to JavaScript. In most cases it shouldn't a problem if you use Mozilla's reference.
The purpose of the conditional is to change clipboard content only when needed. It's same as:
var newText = text.replace(replaceWhat, replaceWith)
if (text != newText) {
// Change clipboard ...
}
Repeating the code can be bad. To modify the code you would need to go through all commands that use it. But currently there is no easy way to re-use a code e.g. from a function defined outside commands. It might be a good idea to add this as feature but sharing commands could become problematic.
You can move the big part of the code to a file:
// File: c:/copyq/replace_clipboard_text.js
var text = str(input())
if ( text.indexOf(replaceWhat) != -1 ) {
var newText = text.replace(replaceWhat, replaceWith)
// Copy replaced text back to clipboard.
copy(newText)
// Change data to save in item list.
setData(mimeText, newText)
removeData(mimeHtml)
// Notify user.
popup(
'Clipboard Replaced',
'Replaced "' + text + '" with "' + newText + '"')
}
and use only following code in command.
var replaceWhat = 'http://test.org/'
var replaceWith = 'http://test.org/'
var script = File('c:/copyq/replace_clipboard_text.js')
if ( script.openReadOnly() )
throw 'Failed to open script ' + script.fileName() + ': ' script.errorString()
eval(script.readAll())
I'll try add a function in CopyQ to simplify this.
Your solution saved my time, I'm very thankful for your time and your help :heart: last thing, I wonder if it's possible to run an app with the item as args after replacing it something like (using your first solution)
copy(newText) run('C:\Test.exe newText')
I'm currently achieving this using an external tool, it would be great to drop it and depend only on your app :)
Here is the way to run external applications from script:
// Variable result stores information about the app after it finishes.
var result = execute('C:/Test.exe', newText)
// Check exit code.
if (result.exit_code != 0)
popup('Test.exe exited with non-zero code: ' + result.exit_code)
// Check standard error output.
if (result.stderr)
popup('Test.exe error output: ' + str(result.stderr))
// Check standard output.
if (result.stdout)
popup('Test.exe output: ' + str(result.stdout))
Alternatively you can change the whole command (remove the copyq: ...
) and have only:
C:/Test.exe %1
(%1
is clipboard text or text of selected items if the command is run from context menu or app shortcut)
I have a problem with the args I want to pass quotation marks in the args but it always launched with wrong args (additional slash) as example, if you add an "in menu" command as the following
C:/0.exe %1
and selected the following item in the tab
/A "TEST" /B
When execute 0.exe it always launch with the following args
C:\0.exe
"/A \"TEST\" /B"
instead of
C:\0.exe /A "TEST" /B
Yes, the item text is passed as single argument. If you want to handle it differently, try using:
cmd /c "C:/Test.exe %1"
I forgot to add "Insert code" mark in my last comment, please check it again.
I'm not sure what you mean now. Doesn't the command from my previous comment already solve this?
No, the problem isn't the text being passed as a single argument, I think I can workaround this by closing the quotation marks that the app pass it automatically in the start and in the end.
The problem is the slashes that appears when the var have quotation marks and spaces,
Define a var as '/A" "testing" "/B"'
and try to launch an app with this var as an arg,
instead of launched with "/A "testing" "/B"
additional slashes will be added >> "/A \"Testing\" /B"
(I temporary solved this by passing the clipboard to external launcher that add the /A and /B in the start and in the and of the args automaticaly and then launch a predefined app with those args) I will stick to this solution if there is no simple way to do that
AFAIK, applications on Windows can parse arguments in different ways.
Probably the safest way is to pass the item content, not as an argument, but on standard input so application can just read the data.
You helped me so much! Many thanks to you :)
@Qwash No problem :). Thanks for using the app.
I'll try add a function in CopyQ to simplify this.
@hluk , I'm wondering if you ever got around to adding this as a CopyQ function? Sorry for resurrecting this old thread.
I'll try add a function in CopyQ to simplify this.
@hluk , I'm wondering if you ever got around to adding this as a CopyQ function? Sorry for resurrecting this old thread.
Honestly, I'm not sure. This was long time ago. :grin:
The API in CopyQ and the underlying scripting language improved since then.
Can you be more specific which functionality is required?
The language is Qt Script -- it's ECMAScript dialect, very similar to JavaScript. In most cases it shouldn't a problem if you use Mozilla's reference.
The purpose of the conditional is to change clipboard content only when needed. It's same as:
var newText = text.replace(replaceWhat, replaceWith) if (text != newText) { // Change clipboard ... }
Repeating the code can be bad. To modify the code you would need to go through all commands that use it. But currently there is no easy way to re-use a code e.g. from a function defined outside commands. It might be a good idea to add this as feature but sharing commands could become problematic.
You can move the big part of the code to a file:
// File: c:/copyq/replace_clipboard_text.js var text = str(input()) if ( text.indexOf(replaceWhat) != -1 ) { var newText = text.replace(replaceWhat, replaceWith) // Copy replaced text back to clipboard. copy(newText) // Change data to save in item list. setData(mimeText, newText) removeData(mimeHtml) // Notify user. popup( 'Clipboard Replaced', 'Replaced "' + text + '" with "' + newText + '"') }
and use only following code in command.
var replaceWhat = 'http://test.org/' var replaceWith = 'http://test.org/' var script = File('c:/copyq/replace_clipboard_text.js') if ( script.openReadOnly() ) throw 'Failed to open script ' + script.fileName() + ': ' script.errorString() eval(script.readAll())
I'll try add a function in CopyQ to simplify this.
I think they were referring to this.
Quick question: what would a command look like that could wrap the selected text in quotation marks? Actually, I think I have that part figured about, what I'm having trouble with is turning it into a 'toggle' function, meaning remove the quotes if they are there.
[1]: When I copy
http://example.com/example.rar
I want copq to auto replace it withhttp://test.org/example.rar
I want to replacehttp://example.com/*.rar
withhttp://test.org/(the previous name).rar
[2]: I want CopyQ to check if clipboard contains a string like "TEST" then replace "TEST" with "ANYSTRING" (I will save this for feature needs as an example and try to edit it to fit my needs)
I couldn't understand the scripting language please help
PS: When adding new commands you can see a list of premade commands, this is very helpful, maybe adding "replace string" command to the this list could be a good idea