-1

I am trying to understand the behavior I am seeing from running my script below and how I can get my desired outcome. Basically I'm using keyboard.add_word_listener() to run a function when the string "test" is typed. It should select the tab trigger key plus the "test" text and then copy it, and then replace it with bbbb and then the copied text.

But if you look at the gif, it doesn't highlight the text. The "bbbb" gets inserted to the left of the "test" text. But it should have replaced the "test" text since it sends ctrl+shift+left which should select the previously entered text. The strange thing is the text still gets copied to the clipboard even though it doesn't look like it got selected. And for some reason it gets pasted in a separate line in the beginning. I don't understand how that is possible. It works on macOS but not Windows.

I also tried replacing ctrl+shift+left,ctrl+shift+left with shift+home but the result is the same.

enter image description here

The script:

import keyboard 
import time

def test():
    keyboard.send("ctrl+shift+left,ctrl+shift+left")
    time.sleep(1)
    keyboard.send("ctrl+c")
    time.sleep(1)
    keyboard.send("b,b,b,b")
    time.sleep(1)
    keyboard.send("ctrl+v")

keyboard.add_word_listener("test",test,['tab'],False,1)

keyboard.wait()
Cave Johnson
  • 6,499
  • 5
  • 38
  • 57
  • Is that Sublime Text? Notepad and other plain text editors should behave the same; test with a few of those to rule out specific Sublime Text (mis)behavior. – Jongware Jun 17 '20 at 08:13
  • @usr2564301 That was Visual Studio Code. I just tried it with Notepad++ and Notepad and it was almost the same except the pasted string (the last ctrl+v) showed up in the next line instead of being inserted into the first line. Which is even more confusing. I would expect it to paste between the bbbb and test. – Cave Johnson Jun 18 '20 at 04:12
  • But I still don't understand why "test" wasn't selected/highlighted even though it was copied into the clipboard by ctrl+c. There was no visual indication that it was highlighted. – Cave Johnson Jun 18 '20 at 04:15
  • It might just be an issue with the keyboard library – Cave Johnson Jun 18 '20 at 04:20
  • @KodosJohnson Just so you know, I've tried to debug your code last night, and found the same result. However, nothing was actually being copied when I tested it. Whatever already was in my clipboard was the thing that was pasted each time. – Hampus Larsson Jun 18 '20 at 08:35

1 Answers1

0

I've been scratching my head about why this doesn't work for a while now and I've found a way to make it work.

When you call keyboard.send that method parses the given hotkeys, and tries to send a scan_code for each key that you've specified.

It parses the keys via the keyboard.parse_hotkey method. If we call that method ourselves, we can see what codes we get back:

>>> keyboard.parse_hotkey("ctrl+shift+left")
(((29, 57373), (42, 54), (75,)),)

Here we can see that both ctrl and shift has two codes, each for their right/left counterparts.

As you've discovered as well as me, is if you try to call a hotkey like shift+home the button-combination seems to be working correctly, because your position on the document seems to change. However, it seems like the way (at least on my end) the system handles the calls to shift doesn't work when you call just one of the shift codes.

We can change the hotkey to include both of the codes by calling them individually in the hotkey:

>>> keyboard.parse_hotkey("ctrl+right shift+left shift+left")
(((29, 57373), (54,), (42,), (75,)),)

If we update your code, to include the above hotkey instead, we can see that the expected behavior is happening:

import keyboard
def test():
    keyboard.send("ctrl+right shift+left shift+left")
    keyboard.send("ctrl+c")
    keyboard.send("b,b,b,b")
    keyboard.send("ctrl+v")

keyboard.add_word_listener("test", test, ['tab'], False, 1)
keyboard.wait()

At the time of writing I don't really know exactly why the above code works while your original code doesn't.

Hampus Larsson
  • 3,050
  • 2
  • 14
  • 20
  • Thank you, I tried your code but it didn't seem like it selected the "test" trigger word. Ideally it would select the "test" trigger word and copy it. So when I type "test" and press tab, I should see "bbbbtest" but I am seeing "testbbbb" with a tab at the end. – Cave Johnson Jun 20 '20 at 17:06
  • @KodosJohnson I cannot replicate the behavior you've explained with my code. The result of the above code is always `'bbbbtest\t'` on my side, with `'test\t'` being the contents of the clipboard. Are you sure that it's the actual code that's messing up here? I found that VS-code didn't behave _at_ _all_ the same as Notepad++ or regular notepad, and added it's own newlines and replaced input based on what other files I had open. – Hampus Larsson Jun 22 '20 at 08:56
  • @KodosJohnson I also suspect an [XY-Problem](https://en.wikipedia.org/wiki/XY_problem) here. Could you please expand on what the "end goal" of this is? – Hampus Larsson Jun 22 '20 at 08:59