I tried it in Python and new problem is if user change the Module. Key-press selects the current line, but if user will switch to other Module (in same or other library), Libre changes the frame with Basic code to some “new” frame and I didn’t discover how to add new listener to “new” frame.
I run py code from external editor. Run LibreOffice with socket for Python, run Basic editor, and then this code. It will color the background of Basic IDE and key-press will select the current line. If you change the Module (for example in Object Catalog), then listeners from “old” frame are removed (event WindowHidden in ListenerWindow), but I don’t know how to detect “new” frame with Basic code from “new” Module.
import uno, unohelper
from com.sun.star.awt import XWindowListener
from com.sun.star.awt import WindowEvent
from com.sun.star.awt import XKeyListener
from com.sun.star.awt import KeyEvent
from com.sun.star.lang import EventObject
IDE=None # frame with Basic Code in Basic Editor
IDEb=False # for faster recursion in findIDE()
IDE1=None # object of IDE with writable properties
KEYlistener=None # listener for IDE
IDEparent=None # parent of IDE
WINDOWlistener=None # listener for IDEparent
def connectLibre():
    """start connection with LibreOffice"""
    try:
        localContext=uno.getComponentContext()
        resolver=localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)
        ctx=resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
    except:
        ctx=None
    if ctx==None:
        print("!!! Failed to connect LibreOffice !!!")
        import sys
        sys.exit()
    else:
        return ctx
def mri(obj):
    """MRI"""
    m=createUnoService("mytools.Mri")
    m.inspect(obj)
def createUnoService(sName):
    """Basic: CreateUnoService()"""
    localContext=uno.getComponentContext()
    resolver=localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)
    ctx=resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
    return ctx.ServiceManager.createInstanceWithContext(sName, ctx)
def hasUnoInterfaces(obj, *interfaces):
    """Basic: HasUnoInterfaces()"""
    return set(interfaces).issubset(t.typeName for t in obj.Types)
def rgb(r, g, b):
    """Basic: RGB()"""
    return 256*256*r+256*g+b
def findIDE(obj):
    """find frame with Basic Code"""
    global IDE, IDEb
    n=obj.AccessibleChildCount
    if IDEb: # IDE is already found
        return
    if obj.AccessibleRole==61: # frame with Basic Code found
        IDE=obj
        IDEb=True
        return
    if n>0: # has child
        i=0
        while i<n: # test children
            if IDEb: # IDE is already found
                return
            o=obj.getAccessibleChild(i)
            if not isinstance(o, type(None)):
                findIDE(o.AccessibleContext)
            i+=1
def setBackground(color):
    """set background color of frame with Basic Code"""
    global IDE1
    IDE1.Background=color
def IDEjob():
    """set keyboard listener to frame with Basic Code"""
    global IDE, IDEb, IDE1, IDEparent, WINDOWlistener, KEYlistener
    ctx=connectLibre()
    StarDesktop=ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
    for oComp in StarDesktop.Components:
        if hasUnoInterfaces(oComp, "com.sun.star.lang.XServiceInfo"):
            if oComp.supportsService("com.sun.star.script.BasicIDE"):
                findIDE(oComp.CurrentController.ComponentWindow.AccessibleContext) # set global variable IDE, that is frame with Basic Code
                if not isinstance(IDE, type(None)): # Basic Editor is open
                    # set key listener
                    IDE1=IDE.AccessibleParent.AccessibleContext.getAccessibleChild(IDE.AccessibleIndexInParent)
                    KEYlistener=ListenerKey()
                    IDE1.addKeyListener(KEYlistener)
                    # set window listener
                    IDEparent=IDE.AccessibleParent
                    WINDOWlistener=ListenerWindow()
                    IDEparent.addWindowListener(WINDOWlistener)
                    setBackground(rgb(255, 255, 235)) # change background that means keyboard listener is active
class ListenerWindow(unohelper.Base, XWindowListener):
    """window listener"""
    def __init__(self):
        pass
    def windowResized(self, evt: WindowEvent):
        pass
    def windowMoved(self, evt: WindowEvent):
        pass
    def windowShown(self, evt: EventObject):
        setBackground(rgb(255, 215, 215)) # change background of IDE if WINDOWlistener isn't removed
        return
    def windowHidden(self, evt: EventObject):
        global IDE1, IDEparent, WINDOWlistener, KEYlistener
        # remove listeners
        IDE1.removeKeyListener(KEYlistener)
        IDEparent.removeWindowListener(WINDOWlistener)
        setBackground(rgb(255, 255, 255))
        return
    def disposing(self, evt: EventObject):
        pass
class ListenerKey(unohelper.Base, XKeyListener):
    """keyboard listener"""
    def __init__(self):
        pass
    def keyPressed(self, evt: KeyEvent):
        pass
    def keyReleased(self, evt: KeyEvent):
        o=evt.Source.AccessibleContext
        iLines=o.AccessibleChildCount # count of lines with Basic code
        i=0
        while i<iLines:
            oLine=o.getAccessibleChild(i)
            if oLine.CaretPosition!=-1: # line with cursor
                oLine.setSelection(0, oLine.CaretPosition) # select current line
                break
            i+=1
        return
    def disposing(self, evt: EventObject):
        pass
IDEjob()
I don’t know how to end the communication with LibreOffice and Python editor, when I close LibreOffice, it stays run but it is invisible and I must end it via Ctrl+Alt+Del.
Tested in Libre 7.6.1.2 Win10