3

I'm trying to create a script which processes selected text from the gui (any number of apps, like browser, text editor, etc) and then replaces the selected text with the processed text automatically using one keyboard command.

I can get xsel to replace the clipboard or primary buffer, but I don't want to have to paste with another keyboard shortcut, if possible.

Workflow:

  • Select text
  • Hit key command
  • Bash script processes text
  • Bash script pastes text into gui editor, replacing selection (<-- This is what I can't figure out)
  • Fin

I've read that xsel allows pasting, but as far as I can tell, it only allows outputting text to cli (not really pasting) or redirecting to something else. This may be what I need, but I don't understand how to do it (i.e., to what do I redirect the output to get it to automatically replace selected text in the gui?)

Thanks!

Further info:

  • I'm using Xubuntu 19.10
  • I just want to replace with simple text (e.g. change lowercase to upper case)
  • Let's keep this simple - how do I (using a keycommand) take text from a bash script and paste it into a gui text editor/area where the cursor currently is, replacing selected text if there is any?
10
  • More details will definitely help. I understand your wish but there are some information missing which won't allow me to fully understand what you are trying to achieve. Will the script put the text in a new editor? The same editor? (replacing the selection you said). What I guess is you are trying to do something with the text, like using Bold, Italic and other format. But... Is it for a specific ofimatic output? For a language? Is it for including html tags with the text? Please provide any details which help to throw light to your question, so we can figure out a solution. Mar 4, 2020 at 16:44
  • To start with, which version of Linux have you installed (Ubuntu server, Ubuntu desktop, Kubuntu, Lubuntu, Xubuntu, Ubuntu MATE, et al.) , and which release number? Are you using virtualization, and if so, which package? Please click edit and add that vital information to your question so all the facts we need are in the question. Please do not use Add Comment.
    – K7AAY
    Mar 4, 2020 at 16:45
  • As mentioned, I want to replace the text that is selected in the current app (obviously in some sort of text editing box/widget/editor, wherever editable text is).
    – jfacemyer
    Mar 4, 2020 at 17:13
  • Well I'd say selenium is your tool of choice. I don't think that a "normal" tool knows where and how to find a window position of a GUI (even if it is fixed). But then again, I might be wrong. Interesting question!
    – s1mmel
    Mar 4, 2020 at 17:18
  • 2
    Easiest solution is probably faking ctrl+v with xdotool at the end of your script.
    – danzel
    Mar 4, 2020 at 17:59

3 Answers 3

4

While bash and xdotool will definitely handle a simple case like this, this is exactly the sort of thing AutoKey was designed to do.

In AutoKey, you can define a simple script written in Python using the AutoKey API to do this. This can be assigned to a hotkey and will run whenever that hotkey is pressed. It would look something like this (untested.)

field = clipboard.get_selection()
field = field.lower()
clipboard.fill_selection(field)
keyboard.send_keys("<ctrl>+v")

which gets the selected text into a variable, converts it to lower case, puts it back in the clipboard, and then pastes it back into the current selection where it originally came from. (If your application window is a terminal, then you'd have to use Ctrl+Shift+v instead.)

Doing it this way has several advantages: It's arguably easier to do than modifying your keyboard. You can easily change the hotkey in the AutoKey GUI. You can define a window filter so the hotkey only works in the windows of your choice. You can turn this functionality on and off at will. And, since you have the entire power of Python at your disposal, you do almost anything else you can think of.

If you had just wanted to substitute one phrase for another, an AutoKey phrase would have done that without writing a single line of code, but since you needed to manipulate the text, a script was required.

Note: Debian and derivative distributions (Ubuntu ...) currently provide a very old version of AutoKey. This is fixed in Debian testing and will be fixed in Ubuntu 20.04. For now, you can easily install the package with these instructions.

For assistance, visit our support forum.

1
  • Interesting... I'll look at this sometime, I had already resolved the issue using xdotool before coming back here to accept the answer, but this may help someone else too.
    – jfacemyer
    Mar 16, 2020 at 20:44
2

Since you are using Xorg and ctrl+v ist almost universally the shortcut for paste, the easiest solution is xdotool (available from the official repositories):

xdotool key --clearmodifiers "ctrl+v"

The --clearmodifiers flag attempts to clear all modifiers (ctrl,alt...) before issuing the key presses and restores them afterwards. This is useful when you invoke your script via a keyboard shortcut, because otherwise the application will also see the modifiers you pressed for your shortcut, and e.g. ctrl+alt+v may result in a different command.

Sometimes, this can result in a race condition when you release the modifiers before xdotool restores them, making them stuck. In that case, just press and release the stuck modifiers to unstick them.

xdotool can do a lot more. Read man xdotool to get an overview. It is also often used in combination with xbindkeys, which lets you configure keyboard shortcuts more versatilely than e.g. gnome and also enables you to bind actions to mouse buttons.

1
  • This answer is perfect...I especially like that you didn't try to solve problems I didn't ask to be solved :)
    – jfacemyer
    Mar 16, 2020 at 20:41
2

I agree with Joe that AutoKey would be perfect for what you want to do. I thought I'd include another example script. This one uses string formatting to also change the selected text to lower case (you could have it do whatever you like instead of changing case):

selection = clipboard.get_selection()
keyboard.send_keys("%s" % selection.lower())

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .