Processing clipboard text through a script in between copy and paste
I want to intercept the paste event and run any text through my script. The use case is like this (assume I have a script somewhere which accepts text on stdin and turns 'world' into 'potato', writing on stdout).
- Highlight some text 'hello world!' with the cursor
- Middle-mouse click to paste from the selection buffer, and 'hello potato!' appears
There should be no manual step between 1 and 2, i.e. I want a hook on the paste event (or perhaps on the copy event) so that the text is processed automatically. I don't have anything malicious in mind; it's just about auto-formatting some source code when copying/pasting from/to the web.
My question concerns the selection buffer (middle-mouse clipboard), but I guess the question applies to other clipboard text in general too.
Solution 1:
You can use clipnotify
to get notified of clipboard changes without polling. From the project page:
while clipnotify; do
[an event happened, do something with the selection]
done
The tool is only a few lines of C code that uses the XFIXES functionality.
Solution 2:
You can use the following Bash function. Copy it to your ~/.bashrc
and source it as . ~/.bashrc
from a terminal.
cngstr(){
echo `xclip -o` | sed -e "s#$1#$2#g" | xclip
}
Usage
- Highlight any text by selecting it with mouse. As usual the selected text can be pasted using the mouse middle click.
-
Run in terminal:
$ cngstr "string" "replacement"
Next when you paste using mouse middle click, the word(s) "string" in your selection will be replaced with "replacement".
Example
Say your selection is "hello world!". Next you run in terminal,
cngstr world potato
Use ""
for a string consisting of more than one word. Next when you paste using the mouse middle clip, "hello potato!" will appear. See the screenshots.
How it works
-
xclip -o
prints the selection to standard output which is being piped tosed
here. - Next
sed
is replacing the strings taking input from the user. - Finally the modified contents are being passed to
xclip
which put it in the primary selection and becomes available for pasting by a mouse middle click.
I think xclip
comes with the default Ubuntu distribution. Otherwise install it through apt-get
:
sudo apt-get install xclip
Extra Information
Make the modified contents available to clipboard also
If you want the modified contents also be available to the clipboard so that Ctrl+V also works as well, add the following line in the above script.
echo `xclip -o` | xclip -selection c
The above line will pass the contents of the primary selection to the clipboard. The modified function will look like:
cngstr(){
echo `xclip -o` | sed -e "s#$1#$2#g" | xclip
echo `xclip -o` | xclip -selection c
}
A Bash function that can modify contents of the clipboard (i.e., copied using Ctrl+C or from the right click menu) and make the modified string available to the primary selection as well as to the clipboard.
cngstr1(){
echo `xclip -o -selection c` | sed -e "s#$1#$2#g" | xclip
echo `xclip -o` | xclip -selection c
}
xclip -o
prints the contents of the primary selection by default. Use -selection c
to print the contents of the clipboard. See man xclip
for more.
You can combine these two functions in a script using a switch case,
#!/bin/sh
string="$2"
replacement="$3"
cngstr(){
echo `xclip -o` | sed -e "s#$1#$2#g" | xclip
echo `xclip -o` | xclip -selection c
}
cngstr1(){
echo `xclip -o -selection c` | sed -e "s#$1#$2#g" | xclip
echo `xclip -o` | xclip -selection c
}
if [ $# -lt 2 ]
then
echo "Usage : $0 [c|p] \"string\" \"replacement\" "
exit
fi
case "$1" in
c) cngstr1 "$string" "$replacement"
;;
p) cngstr "$string" "$replacement"
;;
*) echo "Usage : $0 [c|p] \"string\" \"replacement\" "
;;
esac
Usage
./script.sh [c|p] "string" "replacement"
Use option
c
for altering contents copied using the clipboard i.e., contents copied using Ctrl+C or from the right click menu.Use option
p
for altering the contents copied using the primary selection.